12aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland/* 28dd179b07f00e35208dd4cf48e14264717e8d5a0Jean-Baptiste Queru** Copyright 2008, The Android Open-Source Project 32aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** 42aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** Licensed under the Apache License, Version 2.0 (the "License"); 52aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** you may not use this file except in compliance with the License. 62aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** You may obtain a copy of the License at 72aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** 82aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** http://www.apache.org/licenses/LICENSE-2.0 92aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** 102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** Unless required by applicable law or agreed to in writing, software 112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** distributed under the License is distributed on an "AS IS" BASIS, 122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** See the License for the specific language governing permissions and 142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** limitations under the License. 152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland*/ 162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <math.h> 182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent//#define LOG_NDEBUG 0 202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#define LOG_TAG "AudioHardwareQSD" 212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <utils/Log.h> 222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <utils/String8.h> 235d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks#include <hardware_legacy/power.h> 242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <stdio.h> 262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <unistd.h> 272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <sys/ioctl.h> 282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <sys/types.h> 292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <sys/stat.h> 302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <dlfcn.h> 312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <fcntl.h> 322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 33739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi#include <cutils/properties.h> // for property_get for the voice recognition mode switch 34739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// hardware specific functions 362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include "AudioHardware.h" 382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <media/AudioRecord.h> 391119793f2bc460d6417fedb54c7a51c48ded56deJean-Michel Trivi#include <media/mediarecorder.h> 402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandextern "C" { 422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include "msm_audio.h" 439ab0b5b1f3244f261fcda2ead8fcdd5fe5d714b6Iliyan Malchev#include <linux/a1026.h> 44f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev#include <linux/tpa2018d1.h> 452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#define LOG_SND_RPC 0 // Set to 1 to log sound RPC's 482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#define TX_PATH (1) 492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_CURRENT = 256; 512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HANDSET = 0; 522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_SPEAKER = 1; 532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_BT = 3; 542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_CARKIT = 4; 552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_BT_EC_OFF = 45; 562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HEADSET = 2; 572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER = 10; 582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_FM_HEADSET = 9; 592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_FM_SPEAKER = 11; 602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_NO_MIC_HEADSET = 8; 612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_TTY_FULL = 5; 6217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurentstatic const uint32_t SND_DEVICE_TTY_VCO = 6; 6317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurentstatic const uint32_t SND_DEVICE_TTY_HCO = 7; 64da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurentstatic const uint32_t SND_DEVICE_HANDSET_BACK_MIC = 20; 65da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurentstatic const uint32_t SND_DEVICE_SPEAKER_BACK_MIC = 21; 66da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurentstatic const uint32_t SND_DEVICE_NO_MIC_HEADSET_BACK_MIC = 28; 6758cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivistatic const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC = 30; 682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandnamespace android { 692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int support_a1026 = 1; 70f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatic bool support_tpa2018d1 = true; 712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int fd_a1026 = -1; 722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int old_pathid = -1; 732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int new_pathid = -1; 740f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatic int curr_out_device = -1; 750f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatic int curr_mic_device = -1; 762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int voice_started = 0; 772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int fd_fm_device = -1; 7810254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivistatic int stream_volume = -300; 79739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi// use VR mode on inputs: 1 == VR mode enabled when selected, 0 = VR mode disabled when selected 8008516fe50b023532d5a3010050970de28e14621bIliyan Malchevstatic int vr_mode_enabled; 81739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivistatic bool vr_mode_change = false; 82739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivistatic int vr_uses_ns = 0; 83f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatic int alt_enable = 0; 84f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatic int hac_enable = 0; 859ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi// enable or disable 2-mic noise suppression in call on receiver mode 86739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivistatic int enable1026 = 1; 879ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi//FIXME add new settings in A1026 driver for an incall no ns mode, based on the current vr no ns 889ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi#define A1026_PATH_INCALL_NO_NS_RECEIVER A1026_PATH_VR_NO_NS_RECEIVER 8910254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi 902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandint errCount = 0; 910f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatic void * acoustic; 922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandconst uint32_t AudioHardware::inputSamplingRates[] = { 932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland}; 955d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks 965d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks// ID string for audio wakelock 972176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurentstatic const char kOutputWakelockStr[] = "AudioHardwareQSDOut"; 982176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurentstatic const char kInputWakelockStr[] = "AudioHardwareQSDIn"; 995d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks 1002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 1012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1022aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioHardware() : 1030f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mA1026Init(false), mInit(false), mMicMute(true), 104f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mBluetoothNrec(true), 105f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mHACSetting(false), 106f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mBluetoothIdTx(0), mBluetoothIdRx(0), 107f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mOutput(0), 1083964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent mNoiseSuppressionState(A1026_NS_STATE_AUTO), 10917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent mVoiceVolume(VOICE_VOLUME_MAX), mTTYMode(TTY_MODE_OFF) 1102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1110f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int (*snd_get_num)(); 1120f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int (*snd_get_bt_endpoint)(msm_bt_endpoint *); 1130f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int (*set_acoustic_parameters)(); 114f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int (*set_tpa2018d1_parameters)(); 1150f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1160f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent struct msm_bt_endpoint *ept; 1170f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland doA1026_init(); 1190f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1200f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acoustic =:: dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW); 1210f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (acoustic == NULL ) { 122f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Could not open libhtc_acoustic.so"); 1230f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent /* this is not really an error on non-htc devices... */ 1240f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mNumBTEndpoints = 0; 1250f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mInit = true; 1260f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return; 1270f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1280f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters"); 1290f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if ((*set_acoustic_parameters) == 0 ) { 130c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Could not open set_acoustic_parameters()"); 1310f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return; 1320f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1330f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 134f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev set_tpa2018d1_parameters = (int (*)(void))::dlsym(acoustic, "set_tpa2018d1_parameters"); 135f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if ((*set_tpa2018d1_parameters) == 0) { 136f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("set_tpa2018d1_parameters() not present"); 137f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev support_tpa2018d1 = false; 138f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 139f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1400f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int rc = set_acoustic_parameters(); 1410f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (rc < 0) { 142f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Could not set acoustic parameters to share memory: %d", rc); 1430f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1440f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 145f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (support_tpa2018d1) { 146f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev rc = set_tpa2018d1_parameters(); 147f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (rc < 0) { 148f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev support_tpa2018d1 = false; 149f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("speaker amplifier tpa2018 is not supported\n"); 150f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 151f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 152f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1530f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num"); 1540f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if ((*snd_get_num) == 0 ) { 155f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Could not open snd_get_num()"); 1560f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1570f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1580f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mNumBTEndpoints = snd_get_num(); 15922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("mNumBTEndpoints = %d", mNumBTEndpoints); 1600f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBTEndpoints = new msm_bt_endpoint[mNumBTEndpoints]; 1610f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mInit = true; 16222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("constructed %d SND endpoints)", mNumBTEndpoints); 1630f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent ept = mBTEndpoints; 1640f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snd_get_bt_endpoint = (int (*)(msm_bt_endpoint *))::dlsym(acoustic, "snd_get_bt_endpoint"); 1650f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if ((*snd_get_bt_endpoint) == 0 ) { 166c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Could not open snd_get_bt_endpoint()"); 1670f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return; 1680f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1690f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snd_get_bt_endpoint(mBTEndpoints); 1700f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1710f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent for (int i = 0; i < mNumBTEndpoints; i++) { 17222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("BT name %s (tx,rx)=(%d,%d)", mBTEndpoints[i].name, mBTEndpoints[i].tx, mBTEndpoints[i].rx); 1730f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1740f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 175d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent // reset voice mode in case media_server crashed and restarted while in call 176d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent int fd = open("/dev/msm_audio_ctl", O_RDWR); 177d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent if (fd >= 0) { 178d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent ioctl(fd, AUDIO_STOP_VOICE, NULL); 179d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent close(fd); 180d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent } 181d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent 182739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi vr_mode_change = false; 18308516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_enabled = 0; 184739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi enable1026 = 1; 185739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi char value[PROPERTY_VALUE_MAX]; 186739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // Check the system property to enable or not the special recording modes 187739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi property_get("media.a1026.enableA1026", value, "1"); 188739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi enable1026 = atoi(value); 18922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("Enable mode selection for A1026 is %d", enable1026); 190739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // Check the system property for which VR mode to use 191739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi property_get("media.a1026.nsForVoiceRec", value, "0"); 192739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi vr_uses_ns = atoi(value); 19322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("Using Noise Suppression for Voice Rec is %d", vr_uses_ns); 194739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 195f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev // Check the system property for enable or not the ALT function 196f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev property_get("htc.audio.alt.enable", value, "0"); 197f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev alt_enable = atoi(value); 19822f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("Enable ALT function: %d", alt_enable); 199f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 200f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev // Check the system property for enable or not the HAC function 201f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev property_get("htc.audio.hac.enable", value, "0"); 202f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev hac_enable = atoi(value); 20322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("Enable HAC function: %d", hac_enable); 204f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 2052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInit = true; 2062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2082aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::~AudioHardware() 2092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (size_t index = 0; index < mInputs.size(); index++) { 2112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland closeInputStream((AudioStreamIn*)mInputs[index]); 2122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.clear(); 2142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland closeOutputStream((AudioStreamOut*)mOutput); 2152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInit = false; 2162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::initCheck() 2192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mInit ? NO_ERROR : NO_INIT; 2212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2232aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioStreamOut* AudioHardware::openOutputStream( 2242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status) 2252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland { // scope for the lock 2272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 2282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // only one output stream allowed 2302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) { 2312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 2322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = INVALID_OPERATION; 2332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 2352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // create new output stream 2382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 2392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t lStatus = out->set(this, devices, format, channels, sampleRate); 2402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 2412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = lStatus; 2422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lStatus == NO_ERROR) { 2442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput = out; 2452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 2462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete out; 2472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mOutput; 2502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandvoid AudioHardware::closeOutputStream(AudioStreamOut* out) { 2532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 2542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput == 0 || mOutput != out) { 2553fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Attempt to close invalid output stream"); 2562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else { 2582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete mOutput; 2592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput = 0; 2602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2632aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioStreamIn* AudioHardware::openInputStream( 2642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status, 2652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioSystem::audio_in_acoustics acoustic_flags) 2662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // check for valid input source 2682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) { 2692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 2702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.lock(); 2732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 2752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t lStatus = in->set(this, devices, format, channels, sampleRate, acoustic_flags); 2762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 2772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = lStatus; 2782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lStatus != NO_ERROR) { 2802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 2812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete in; 2822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 2832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.add(in); 2862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 2872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return in; 2892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandvoid AudioHardware::closeInputStream(AudioStreamIn* in) { 2922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 2932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t index = mInputs.indexOf((AudioStreamInMSM72xx *)in); 2952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (index < 0) { 2963fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Attempt to close invalid input stream"); 2972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 2982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 2992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete mInputs[index]; 3002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.lock(); 3012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.removeAt(index); 3022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMode(int mode) 3062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 307739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // VR mode is never used in a call and must be cleared when entering the IN_CALL mode 308739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (mode == AudioSystem::MODE_IN_CALL) { 30908516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_enabled = 0; 310739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 311739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 312f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (support_tpa2018d1) 313f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev do_tpa2018_control(mode); 314f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 3158dc5375b4d5131e3b1f77874e87fff4cf18f2e4fEric Laurent int prevMode = mMode; 3162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = AudioHardwareBase::setMode(mode); 3172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status == NO_ERROR) { 3182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // make sure that doAudioRouteOrMute() is called by doRouting() 3198dc5375b4d5131e3b1f77874e87fff4cf18f2e4fEric Laurent // when entering or exiting in call mode even if the new device 3208dc5375b4d5131e3b1f77874e87fff4cf18f2e4fEric Laurent // selected is the same as current one. 3218dc5375b4d5131e3b1f77874e87fff4cf18f2e4fEric Laurent if (((prevMode != AudioSystem::MODE_IN_CALL) && (mMode == AudioSystem::MODE_IN_CALL)) || 3228dc5375b4d5131e3b1f77874e87fff4cf18f2e4fEric Laurent ((prevMode == AudioSystem::MODE_IN_CALL) && (mMode != AudioSystem::MODE_IN_CALL))) { 3238dc5375b4d5131e3b1f77874e87fff4cf18f2e4fEric Laurent clearCurDevice(); 3248dc5375b4d5131e3b1f77874e87fff4cf18f2e4fEric Laurent } 3252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3268dc5375b4d5131e3b1f77874e87fff4cf18f2e4fEric Laurent 3272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 3282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandbool AudioHardware::checkOutputStandby() 3312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) 3332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mOutput->checkStandby()) 3342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return false; 3352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return true; 3372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3383cb8864598e72c04859f410bb03f242cf3965dbeHK Chenstatic status_t set_mic_mute(bool _mute) 3392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3403cb8864598e72c04859f410bb03f242cf3965dbeHK Chen uint32_t mute = _mute; 3413cb8864598e72c04859f410bb03f242cf3965dbeHK Chen int fd = -1; 3422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 3432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 344c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open msm_audio_ctl device\n"); 3452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 3462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 347f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Setting mic mute to %d\n", mute); 3483cb8864598e72c04859f410bb03f242cf3965dbeHK Chen if (ioctl(fd, AUDIO_SET_MUTE, &mute)) { 349c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot set mic mute on current device\n"); 3502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 3512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 3522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 3542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMicMute(bool state) 3582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 3602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return setMicMute_nosync(state); 3612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// always call with mutex held 3642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMicMute_nosync(bool state) 3652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mMicMute != state) { 3672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mMicMute = state; 3682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return set_mic_mute(mMicMute); //always set current TX device 3692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::getMicMute(bool* state) 3742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *state = mMicMute; 3762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setParameters(const String8& keyValuePairs) 3802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 3822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 3832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key; 3842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NREC_KEY[] = "bt_headset_nrec"; 3852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NAME_KEY[] = "bt_headset_name"; 386f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev const char HAC_KEY[] = "HACSetting"; 3872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NREC_VALUE_ON[] = "on"; 388f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev const char HAC_VALUE_ON[] = "ON"; 3892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 39122f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("setParameters() %s", keyValuePairs.string()); 3922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (keyValuePairs.length() == 0) return BAD_VALUE; 3942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 395f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if(hac_enable) { 396f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev key = String8(HAC_KEY); 397f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (param.get(key, value) == NO_ERROR) { 398f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (value == HAC_VALUE_ON) { 399f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mHACSetting = true; 400f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Enable HAC"); 401f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } else { 402f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mHACSetting = false; 403f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Disable HAC"); 404f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 405f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 406f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 407f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 4082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland key = String8(BT_NREC_KEY); 4092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 4102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (value == BT_NREC_VALUE_ON) { 4112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothNrec = true; 4122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 4132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothNrec = false; 414f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Turning noise reduction and echo cancellation off for BT " 4152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland "headset"); 4162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland key = String8(BT_NAME_KEY); 4192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 4200f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdTx = 0; 4210f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdRx = 0; 4220f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent for (int i = 0; i < mNumBTEndpoints; i++) { 4230f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!strcasecmp(value.string(), mBTEndpoints[i].name)) { 4240f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdTx = mBTEndpoints[i].tx; 4250f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdRx = mBTEndpoints[i].rx; 426f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Using custom acoustic parameters for %s", value.string()); 4272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 4282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4300f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (mBluetoothIdTx == 0) { 431f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Using default acoustic parameters " 4322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland "(%s not in acoustic database)", value.string()); 4332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 43411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent doRouting(); 4352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 436da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent key = String8("noise_suppression"); 437da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (param.get(key, value) == NO_ERROR) { 438da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (support_a1026 == 1) { 439da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent int noiseSuppressionState; 440da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (value == "off") { 441da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_OFF; 442da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (value == "auto") { 443da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_AUTO; 444da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (value == "far_talk") { 445da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_FT; 446da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (value == "close_talk") { 447da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_CT; 448da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else { 449da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return BAD_VALUE; 450da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 451da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 452da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (noiseSuppressionState != mNoiseSuppressionState) { 453da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (!mA1026Init) { 4543fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Audience A1026 not initialized.\n"); 455da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return INVALID_OPERATION; 456da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 457da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 45811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mA1026Lock.lock(); 459da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (fd_a1026 < 0) { 460da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent fd_a1026 = open("/dev/audience_a1026", O_RDWR); 461da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (fd_a1026 < 0) { 462c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open audience_a1026 device (%d)\n", fd_a1026); 46311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mA1026Lock.unlock(); 464da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return -1; 465da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 466da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 46722f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("Setting noise suppression %s", value.string()); 46811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent 469da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent int rc = ioctl(fd_a1026, A1026_SET_NS_STATE, &noiseSuppressionState); 470da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (!rc) { 471da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mNoiseSuppressionState = noiseSuppressionState; 472da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else { 473c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Failed to set noise suppression %s", value.string()); 474da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 47511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent close(fd_a1026); 476d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi fd_a1026 = -1; 477da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mA1026Lock.unlock(); 478da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 479da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else { 480da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return INVALID_OPERATION; 481da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 482da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 483da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 48417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent key = String8("tty_mode"); 48517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if (param.get(key, value) == NO_ERROR) { 48617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent int ttyMode; 48717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if (value == "tty_off") { 48817b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent ttyMode = TTY_MODE_OFF; 48917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (value == "tty_full") { 49017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent ttyMode = TTY_MODE_FULL; 49117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (value == "tty_vco") { 49217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent ttyMode = TTY_MODE_VCO; 49317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (value == "tty_hco") { 49417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent ttyMode = TTY_MODE_HCO; 49517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else { 49617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent return BAD_VALUE; 49717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 49817b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent 49917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if (ttyMode != mTTYMode) { 50022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("new tty mode %d", ttyMode); 50117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent mTTYMode = ttyMode; 502c08cbb26e57c8c3521391947e676cbdb6e81603bEric Laurent doRouting(); 50317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 50417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 50517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent 5062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 5072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5092aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::getParameters(const String8& keys) 5102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 511da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent AudioParameter request = AudioParameter(keys); 512da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent AudioParameter reply = AudioParameter(); 513da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent String8 value; 514da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent String8 key; 515da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 51622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("getParameters() %s", keys.string()); 517da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 518da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent key = "noise_suppression"; 519da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (request.get(key, value) == NO_ERROR) { 520da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent switch(mNoiseSuppressionState) { 521da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_OFF: 522da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "off"; 523da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 524da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_AUTO: 525da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "auto"; 526da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 527da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_FT: 528da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "far_talk"; 529da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 530da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_CT: 531da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "close_talk"; 532da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 533da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 534da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent reply.add(key, value); 535da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 536da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 537da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return reply.toString(); 5382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic unsigned calculate_audpre_table_index(unsigned index) 5422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (index) { 5442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 48000: return SAMP_RATE_INDX_48000; 5452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 44100: return SAMP_RATE_INDX_44100; 5462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 32000: return SAMP_RATE_INDX_32000; 5472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 24000: return SAMP_RATE_INDX_24000; 5482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 22050: return SAMP_RATE_INDX_22050; 5492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 16000: return SAMP_RATE_INDX_16000; 5502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 12000: return SAMP_RATE_INDX_12000; 5512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 11025: return SAMP_RATE_INDX_11025; 5522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 8000: return SAMP_RATE_INDX_8000; 5532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: return -1; 5542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 556f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent 557f2236a59c89b93062490d2c236ffebe57173af6eEric Laurentsize_t AudioHardware::getBufferSize(uint32_t sampleRate, int channelCount) 558f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent{ 559f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent size_t bufSize; 560f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent 561f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent if (sampleRate < 11025) { 562f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent bufSize = 256; 563f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent } else if (sampleRate < 22050) { 564f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent bufSize = 512; 565f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent } else if (sampleRate < 32000) { 566f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent bufSize = 768; 567f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent } else if (sampleRate < 44100) { 568f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent bufSize = 1024; 569f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent } else { 570f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent bufSize = 1536; 571f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent } 572f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent 573f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent return bufSize*channelCount; 574f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent} 575f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent 576f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent 5772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandsize_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 5782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (format != AudioSystem::PCM_16_BIT) { 5803fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("getInputBufferSize bad format: %d", format); 5812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 5822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (channelCount < 1 || channelCount > 2) { 5843fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("getInputBufferSize bad channel count: %d", channelCount); 5852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 5862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 587f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent if (sampleRate < 8000 || sampleRate > 48000) { 5883fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("getInputBufferSize bad sample rate: %d", sampleRate); 589f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent return 0; 590f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent } 5912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 592f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent return getBufferSize(sampleRate, channelCount); 5932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic status_t set_volume_rpc(uint32_t volume) 5962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int fd = -1; 5982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 5992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 600c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open msm_audio_ctl device\n"); 6012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland volume *= 20; //percentage 604f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Setting in-call volume to %d\n", volume); 6052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_SET_VOLUME, &volume)) { 6063fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Cannot set volume on current device\n"); 6072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 6092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 6102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 6112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setVoiceVolume(float v) 6132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 6142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (v < 0.0) { 6153fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0", v); 6162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland v = 0.0; 6172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (v > 1.0) { 6183fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0", v); 6192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland v = 1.0; 6202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6223964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent int vol = lrint(v * VOICE_VOLUME_MAX); 6232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 625ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent if (mHACSetting && hac_enable && mCurSndDevice == (int) SND_DEVICE_HANDSET) { 626f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("HAC enable: Setting in-call volume to maximum.\n"); 627ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent set_volume_rpc(VOICE_VOLUME_MAX); 628ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent } else { 6295a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("voice volume %d (range is 0 to %d)", vol, VOICE_VOLUME_MAX); 630ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent set_volume_rpc(vol); //always set current device 631ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent } 6323964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent mVoiceVolume = vol; 6332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 6342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 6352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMasterVolume(float v) 6372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 6385a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Set master volume to %f", v); 6392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // We return an error code here to let the audioflinger do in-software 6402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // volume on top of the maximum volume that we set through the SND API. 6412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // return error - software mixer will handle it 6422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 6442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6457fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivistatic status_t do_route_audio_dev_ctrl(uint32_t device, bool inCall, uint32_t rx_acdb_id, uint32_t tx_acdb_id) 6462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 6477fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t out_device = 0, mic_device = 0; 6487fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t path[2]; 6492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int fd = 0; 6502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == SND_DEVICE_CURRENT) 6522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Incall; 6532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // hack -- kernel needs to put these in include file 655f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Switching audio device to "); 6562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == SND_DEVICE_HANDSET) { 6572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HANDSET_SPKR; 6582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HANDSET_MIC; 659f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Handset"); 6602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if ((device == SND_DEVICE_BT) || (device == SND_DEVICE_BT_EC_OFF)) { 6612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = BT_SCO_SPKR; 6622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = BT_SCO_MIC; 663f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("BT Headset"); 664da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (device == SND_DEVICE_SPEAKER || 665da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent device == SND_DEVICE_SPEAKER_BACK_MIC) { 6662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = SPKR_PHONE_MONO; 6672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = SPKR_PHONE_MIC; 668f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Speakerphone"); 6692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_HEADSET) { 6702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HEADSET_SPKR_STEREO; 6712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 672f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Stereo Headset"); 6732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_HEADSET_AND_SPEAKER) { 6742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = SPKR_PHONE_HEADSET_STEREO; 6752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 676f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Stereo Headset + Speaker"); 67758cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi } else if (device == SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC) { 67858cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi out_device = SPKR_PHONE_HEADSET_STEREO; 67958cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi mic_device = SPKR_PHONE_MIC; 680f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Stereo Headset + Speaker and back mic"); 6812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_NO_MIC_HEADSET) { 6822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HEADSET_SPKR_STEREO; 6832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HANDSET_MIC; 684f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("No microphone Wired Headset"); 685da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (device == SND_DEVICE_NO_MIC_HEADSET_BACK_MIC) { 686da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent out_device = HEADSET_SPKR_STEREO; 687da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mic_device = SPKR_PHONE_MIC; 688f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("No microphone Wired Headset and back mic"); 689da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (device == SND_DEVICE_HANDSET_BACK_MIC) { 690da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent out_device = HANDSET_SPKR; 691da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mic_device = SPKR_PHONE_MIC; 692f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Handset and back mic"); 6932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_FM_HEADSET) { 6942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = FM_HEADSET; 6952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 696f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Stereo FM headset"); 6972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_FM_SPEAKER) { 6982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = FM_SPKR; 6992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 700f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Stereo FM speaker"); 701c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent } else if (device == SND_DEVICE_CARKIT) { 702c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent out_device = BT_SCO_SPKR; 703c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent mic_device = BT_SCO_MIC; 704f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Carkit"); 70517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (device == SND_DEVICE_TTY_FULL) { 70617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent out_device = TTY_HEADSET_SPKR; 70717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent mic_device = TTY_HEADSET_MIC; 708f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("TTY FULL headset"); 70917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (device == SND_DEVICE_TTY_VCO) { 71017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent out_device = TTY_HEADSET_SPKR; 711b26d493deaa9897cc6f34577aa5c9c1ff0655129Eric Laurent mic_device = SPKR_PHONE_MIC; 712f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("TTY VCO headset"); 71317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (device == SND_DEVICE_TTY_HCO) { 71417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent out_device = SPKR_PHONE_MONO; 71517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent mic_device = TTY_HEADSET_MIC; 716f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("TTY HCO headset"); 7172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 718c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("unknown device %d", device); 71917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent return -1; 7202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#if 0 //Add for FM support 7232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (out_device == FM_HEADSET || 7242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device == FM_SPKR) { 7252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_fm_device < 0) { 7262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_fm_device = open("/dev/msm_htc_fm", O_RDWR); 7272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_fm_device < 0) { 728c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open msm_htc_fm device"); 7292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 731f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Opened msm_htc_fm for FM radio"); 7322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (fd_fm_device >= 0) { 7342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_fm_device); 7352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_fm_device = -1; 736f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Closed msm_htc_fm after FM radio"); 7372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#endif 7392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 7412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 742c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open msm_audio_ctl"); 7432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7457fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi path[0] = out_device; 7467fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi path[1] = rx_acdb_id; 7477fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (ioctl(fd, AUDIO_SWITCH_DEVICE, &path)) { 748c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot switch audio device"); 7492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 7502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7527fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi path[0] = mic_device; 7537fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi path[1] = tx_acdb_id; 7547fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (ioctl(fd, AUDIO_SWITCH_DEVICE, &path)) { 755c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot switch mic device"); 7562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 7572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7590f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent curr_out_device = out_device; 7600f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent curr_mic_device = mic_device; 7612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7622aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandIncall: 7632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (inCall == true && !voice_started) { 764f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (fd < 0) { 7652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 7662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 768c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open msm_audio_ctl"); 7692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7721e6baec54e051e7359aca7521d0919c6a6a91172Eric Laurent path[0] = rx_acdb_id; 7731e6baec54e051e7359aca7521d0919c6a6a91172Eric Laurent path[1] = tx_acdb_id; 7741e6baec54e051e7359aca7521d0919c6a6a91172Eric Laurent if (ioctl(fd, AUDIO_START_VOICE, &path)) { 775c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot start voice"); 7761e6baec54e051e7359aca7521d0919c6a6a91172Eric Laurent close(fd); 7771e6baec54e051e7359aca7521d0919c6a6a91172Eric Laurent return -1; 7782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 779f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Voice Started!!"); 7802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland voice_started = 1; 7812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else if (inCall == false && voice_started) { 7832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 7842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 7852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 787c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open msm_audio_ctl"); 7882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_STOP_VOICE, NULL)) { 792c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot stop voice"); 7932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 7942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 796f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Voice Stopped!!"); 7972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland voice_started = 0; 7982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 8012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 8022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// always call with mutex held 8062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doAudioRouteOrMute(uint32_t device) 8072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8087fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t rx_acdb_id = 0; 8097fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t tx_acdb_id = 0; 8107fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi 811f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (support_a1026 == 1) 812f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi doAudience_A1026_Control(mMode, mRecordState, device); 813f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi 8146727fbd4be7d7cd0acfb55b7461f9d9a23225f60Eric Laurent if (device == (uint32_t)SND_DEVICE_BT) { 8150f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!mBluetoothNrec) { 8162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland device = SND_DEVICE_BT_EC_OFF; 8172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8197fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi 8202176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent 821a526b0683dba50dac8a37ed45e3a08536044e973Jean-Michel Trivi if (device == (int) SND_DEVICE_BT) { 822f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (mBluetoothIdTx != 0) { 8232d319172300af10e139818ea367c4afc14c616f5Eric Laurent rx_acdb_id = mBluetoothIdRx; 8242d319172300af10e139818ea367c4afc14c616f5Eric Laurent tx_acdb_id = mBluetoothIdTx; 825c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent } else { 826c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent /* use default BT entry defined in AudioBTID.csv */ 827c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent rx_acdb_id = mBTEndpoints[0].rx; 828c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent tx_acdb_id = mBTEndpoints[0].tx; 829f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Update ACDB ID to default BT setting\n"); 830f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 831a526b0683dba50dac8a37ed45e3a08536044e973Jean-Michel Trivi } else if (device == (int) SND_DEVICE_CARKIT 832a526b0683dba50dac8a37ed45e3a08536044e973Jean-Michel Trivi || device == (int) SND_DEVICE_BT_EC_OFF) { 833f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (mBluetoothIdTx != 0) { 834f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev rx_acdb_id = mBluetoothIdRx; 835f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev tx_acdb_id = mBluetoothIdTx; 836c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent } else { 837c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent /* use default carkit entry defined in AudioBTID.csv */ 838c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent rx_acdb_id = mBTEndpoints[1].rx; 839c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent tx_acdb_id = mBTEndpoints[1].tx; 840f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Update ACDB ID to default carkit setting"); 841f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 8426af540e6c360750623644c6b25e3d97590990694Eric Laurent } else if (mMode == AudioSystem::MODE_IN_CALL 8436af540e6c360750623644c6b25e3d97590990694Eric Laurent && hac_enable && mHACSetting && 8446af540e6c360750623644c6b25e3d97590990694Eric Laurent device == (int) SND_DEVICE_HANDSET) { 845f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Update acdb id to hac profile."); 846f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev rx_acdb_id = ACDB_ID_HAC_HANDSET_SPKR; 847f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev tx_acdb_id = ACDB_ID_HAC_HANDSET_MIC; 848f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } else { 849f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (!checkOutputStandby() || mMode != AudioSystem::MODE_IN_CALL) 8507fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi rx_acdb_id = getACDB(MOD_PLAY, device); 8517fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (mRecordState) 8527fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi tx_acdb_id = getACDB(MOD_REC, device); 8537fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi } 85422f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("doAudioRouteOrMute: rx acdb %d, tx acdb %d\n", rx_acdb_id, tx_acdb_id); 8557fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi 8567fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi return do_route_audio_dev_ctrl(device, mMode == AudioSystem::MODE_IN_CALL, rx_acdb_id, tx_acdb_id); 8572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_mMode(void) 8602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mMode; 8622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_mRoutes(void) 8652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mRoutes[mMode]; 8672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::set_mRecordState(bool onoff) 8702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRecordState = onoff; 8722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 8732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 875f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatus_t AudioHardware::get_batt_temp(int *batt_temp) 876f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev{ 877f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int fd, len; 878f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev const char *fn = 879ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent "/sys/devices/platform/ds2784-battery/power_supply/battery/temp"; 880f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev char get_batt_temp[6] = { 0 }; 881f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 882f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if ((fd = open(fn, O_RDONLY)) < 0) { 883c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("%s: cannot open %s: %s\n", __FUNCTION__, fn, strerror(errno)); 884f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return UNKNOWN_ERROR; 885f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 886f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 887f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if ((len = read(fd, get_batt_temp, sizeof(get_batt_temp))) <= 1) { 888c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("read battery temp fail: %s\n", strerror(errno)); 889f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev close(fd); 890f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return BAD_VALUE; 891f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 892f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 893f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev *batt_temp = strtol(get_batt_temp, NULL, 10); 894f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev close(fd); 895f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return NO_ERROR; 896f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev} 897f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 898d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi/* 899d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi * Note: upon exiting doA1026_init(), fd_a1026 will be -1 900d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi */ 9012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doA1026_init(void) 9022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 9032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct a1026img fwimg; 9042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char char_tmp = 0; 90508516fe50b023532d5a3010050970de28e14621bIliyan Malchev unsigned char local_vpimg_buf[A1026_MAX_FW_SIZE], *ptr = local_vpimg_buf; 90608516fe50b023532d5a3010050970de28e14621bIliyan Malchev int rc = 0, fw_fd = -1; 90708516fe50b023532d5a3010050970de28e14621bIliyan Malchev ssize_t nr; 90808516fe50b023532d5a3010050970de28e14621bIliyan Malchev size_t remaining; 90908516fe50b023532d5a3010050970de28e14621bIliyan Malchev struct stat fw_stat; 9102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 91108516fe50b023532d5a3010050970de28e14621bIliyan Malchev static const char *const fn = "/system/etc/vpimg"; 91208516fe50b023532d5a3010050970de28e14621bIliyan Malchev static const char *const path = "/dev/audience_a1026"; 91308516fe50b023532d5a3010050970de28e14621bIliyan Malchev 91408516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (fd_a1026 < 0) 91508516fe50b023532d5a3010050970de28e14621bIliyan Malchev fd_a1026 = open(path, O_RDWR | O_NONBLOCK, 0); 9162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 918c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open %s %d\n", path, fd_a1026); 91908516fe50b023532d5a3010050970de28e14621bIliyan Malchev support_a1026 = 0; 92008516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto open_drv_err; 9212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 92308516fe50b023532d5a3010050970de28e14621bIliyan Malchev fw_fd = open(fn, O_RDONLY); 92408516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (fw_fd < 0) { 925c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Fail to open %s\n", fn); 9262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto ld_img_error; 927637d2d047afc8033f91357725474b32b74173c65Joe Onorato } else { 928f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("open %s success\n", fn); 929637d2d047afc8033f91357725474b32b74173c65Joe Onorato } 9302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 93108516fe50b023532d5a3010050970de28e14621bIliyan Malchev rc = fstat(fw_fd, &fw_stat); 93208516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (rc < 0) { 933c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot stat file %s: %s\n", fn, strerror(errno)); 93408516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto ld_img_error; 93508516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 93608516fe50b023532d5a3010050970de28e14621bIliyan Malchev 93708516fe50b023532d5a3010050970de28e14621bIliyan Malchev remaining = (int)fw_stat.st_size; 9382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 939f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Firmware %s size %d\n", fn, remaining); 94008516fe50b023532d5a3010050970de28e14621bIliyan Malchev 94108516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (remaining > sizeof(local_vpimg_buf)) { 942c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("File %s size %d exceeds internal limit %d\n", 94308516fe50b023532d5a3010050970de28e14621bIliyan Malchev fn, remaining, sizeof(local_vpimg_buf)); 94408516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto ld_img_error; 9452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 94708516fe50b023532d5a3010050970de28e14621bIliyan Malchev while (remaining) { 94808516fe50b023532d5a3010050970de28e14621bIliyan Malchev nr = read(fw_fd, ptr, remaining); 94908516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (nr < 0) { 950c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Error reading firmware: %s\n", strerror(errno)); 95108516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto ld_img_error; 95208516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 95308516fe50b023532d5a3010050970de28e14621bIliyan Malchev else if (!nr) { 95408516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (remaining) 9553fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("EOF reading firmware %s while %d bytes remain\n", 95608516fe50b023532d5a3010050970de28e14621bIliyan Malchev fn, remaining); 95708516fe50b023532d5a3010050970de28e14621bIliyan Malchev break; 95808516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 95908516fe50b023532d5a3010050970de28e14621bIliyan Malchev remaining -= nr; 96008516fe50b023532d5a3010050970de28e14621bIliyan Malchev ptr += nr; 96108516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 96208516fe50b023532d5a3010050970de28e14621bIliyan Malchev 96308516fe50b023532d5a3010050970de28e14621bIliyan Malchev close (fw_fd); 96408516fe50b023532d5a3010050970de28e14621bIliyan Malchev fw_fd = -1; 96508516fe50b023532d5a3010050970de28e14621bIliyan Malchev 9662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fwimg.buf = local_vpimg_buf; 96708516fe50b023532d5a3010050970de28e14621bIliyan Malchev fwimg.img_size = (int)(fw_stat.st_size - remaining); 968f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Total %d bytes put to user space buffer.\n", fwimg.img_size); 9692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland rc = ioctl(fd_a1026, A1026_BOOTUP_INIT, &fwimg); 9712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!rc) { 972f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("audience_a1026 init OK\n"); 9732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Init = 1; 9742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else 975c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("audience_a1026 init failed\n"); 9762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandld_img_error: 97808516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (fw_fd >= 0) 97908516fe50b023532d5a3010050970de28e14621bIliyan Malchev close(fw_fd); 9802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_a1026); 9812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandopen_drv_err: 9822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = -1; 9832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return rc; 9842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 9852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_snd_dev(void) 9872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 9882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 9897161d052ce69228825bd5deca3bfa4a213a99f06HK Chen return mCurSndDevice; 9902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 9912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9927fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Triviuint32_t AudioHardware::getACDB(int mode, int device) 9930f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent{ 9947fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t acdb_id = 0; 995f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int batt_temp = 0; 9960f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (mMode == AudioSystem::MODE_IN_CALL) { 997f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("skip update ACDB due to in-call"); 9980f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return 0; 9990f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 10000f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 10017fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (mode == MOD_PLAY) { 10027fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi switch (device) { 10030f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HEADSET: 10040f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_NO_MIC_HEADSET: 1005da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 10060f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_HEADSET: 10070f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_HEADSET_PLAYBACK; 10080f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10090f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_SPEAKER: 10100f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_SPEAKER: 1011da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_SPEAKER_BACK_MIC: 10120f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_SPKR_PLAYBACK; 1013f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if(alt_enable) { 1014f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Enable ALT for speaker\n"); 10156727fbd4be7d7cd0acfb55b7461f9d9a23225f60Eric Laurent if (get_batt_temp(&batt_temp) == NO_ERROR) { 1016f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (batt_temp < 50) 1017f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev acdb_id = ACDB_ID_ALT_SPKR_PLAYBACK; 1018f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("ALT batt temp = %d\n", batt_temp); 1019f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 1020f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 10210f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10220f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HEADSET_AND_SPEAKER: 102358cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 10240f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_HEADSET_RINGTONE_PLAYBACK; 10250f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10260f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent default: 10270f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10280f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 10297fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi } else if (mode == MOD_REC) { 10307fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi switch (device) { 10310f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HEADSET: 10320f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_HEADSET: 10330f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_SPEAKER: 103458cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 10350f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_EXT_MIC_REC; 10360f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10370f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HANDSET: 10380f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_NO_MIC_HEADSET: 10390f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_SPEAKER: 104008516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled == 0) { 104163af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi acdb_id = ACDB_ID_INT_MIC_REC; 104263af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi } else { 104363af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi acdb_id = ACDB_ID_INT_MIC_VR; 104463af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi } 104563af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi break; 1046da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_SPEAKER_BACK_MIC: 1047da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 1048da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_HANDSET_BACK_MIC: 104958cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 105063af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi acdb_id = ACDB_ID_CAMCORDER; 10510f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10520f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent default: 10530f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10540f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 10550f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 105622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("getACDB, return ID %d\n", acdb_id); 10577fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi return acdb_id; 10580f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent} 10590f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1060f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatus_t AudioHardware::do_tpa2018_control(int mode) 1061f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev{ 1062f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (curr_out_device == HANDSET_SPKR || 1063f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev curr_out_device == SPKR_PHONE_MONO || 1064f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev curr_out_device == HEADSET_SPKR_STEREO || 1065f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev curr_out_device == SPKR_PHONE_HEADSET_STEREO || 1066f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev curr_out_device == FM_SPKR) { 1067f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1068f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int fd, rc; 1069f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int retry = 3; 1070f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1071f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev switch (mode) { 1072f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev case AudioSystem::MODE_NORMAL: 1073f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mode = TPA2018_MODE_PLAYBACK; 1074f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev break; 1075f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev case AudioSystem::MODE_RINGTONE: 1076f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mode = TPA2018_MODE_RINGTONE; 1077f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev break; 1078f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev case AudioSystem::MODE_IN_CALL: 1079f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mode = TPA2018_MODE_VOICE_CALL; 1080f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev break; 1081f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev default: 1082f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return 0; 1083f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 1084f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1085f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev fd = open("/dev/tpa2018d1", O_RDWR); 1086f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (fd < 0) { 1087c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("can't open /dev/tpa2018d1 %d", fd); 1088f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return -1; 1089f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 1090f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1091f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev do { 1092f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev rc = ioctl(fd, TPA2018_SET_MODE, &mode); 1093f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (!rc) 1094f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev break; 1095f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } while (--retry); 1096f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1097f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (rc < 0) { 1098c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("ioctl TPA2018_SET_MODE failed: %s", strerror(errno)); 1099f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } else 1100f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("Update TPA2018_SET_MODE to mode %d success", mode); 1101f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1102f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev close(fd); 1103f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 1104f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return 0; 1105f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev} 11067fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi 11072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doAudience_A1026_Control(int Mode, bool Record, uint32_t Routes) 11082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 11092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int rc = 0; 11100f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int retry = 4; 11112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mA1026Init) { 11133fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Audience A1026 not initialized.\n"); 111411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent return NO_INIT; 11152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 111711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mA1026Lock.lock(); 11182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 11192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = open("/dev/audience_a1026", O_RDWR); 11202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 1121c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open audience_a1026 device (%d)\n", fd_a1026); 112211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mA1026Lock.unlock(); 11232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 112411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } 11252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((Mode < AudioSystem::MODE_CURRENT) || (Mode >= AudioSystem::NUM_MODES)) { 11283fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Illegal value: doAudience_A1026_Control(%d, %u, %u)", Mode, Record, Routes); 11292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.unlock(); 11302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 11312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (Mode == AudioSystem::MODE_IN_CALL) { 11342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (Record == 1) { 11352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 11362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HANDSET: 11372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_NO_MIC_HEADSET: 1138da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent //TODO: what do we do for camcorder when in call? 1139da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 1140da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_HANDSET_BACK_MIC: 114117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case SND_DEVICE_TTY_VCO: 11429ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi if (enable1026) { 11434bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_RECEIVER; 114422f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_RECEIVER"); 11459ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi } else { 11469ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_NO_NS_RECEIVER; 114722f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_NO_NS_RECEIVER"); 11489ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi } 11499ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi break; 11509ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET: 11519ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 11529ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_FM_HEADSET: 11539ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_FM_SPEAKER: 11549ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 11554bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_HEADSET; 115622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_HEADSET"); 11572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_SPEAKER: 1159da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent //TODO: what do we do for camcorder when in call? 1160da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_SPEAKER_BACK_MIC: 11614bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_SPEAKER; 116222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_SPEAKER"); 11632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT: 11652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT_EC_OFF: 1166c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent case SND_DEVICE_CARKIT: 11674bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_BT; 116822f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_BT"); 11692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1170e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev case SND_DEVICE_TTY_HCO: 1171e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev case SND_DEVICE_TTY_FULL: 1172e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev new_pathid = A1026_PATH_INCALL_TTY; 117322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_TTY"); 1174e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev break; 11752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: 11762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 11792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 11802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HANDSET: 11812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_NO_MIC_HEADSET: 118217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case SND_DEVICE_TTY_VCO: 11839ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi if (enable1026) { 11849ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_RECEIVER; /* NS CT mode, Dual MIC */ 118522f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_RECEIVER"); 11869ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi } else { 11879ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_NO_NS_RECEIVER; 118822f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_NO_NS_RECEIVER"); 11899ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi } 11909ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi break; 11919ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET: 11929ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 11939ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_FM_HEADSET: 11949ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_FM_SPEAKER: 11952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_HEADSET; /* NS disable, Headset MIC */ 119622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_HEADSET"); 11972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_SPEAKER: 11992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_SPEAKER; /* NS FT mode, Main MIC */ 120022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_SPEAKER"); 12012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 12022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT: 12032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT_EC_OFF: 1204c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent case SND_DEVICE_CARKIT: 12052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_BT; /* QCOM NS, BT MIC */ 120622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_BT"); 12072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1208e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev case SND_DEVICE_TTY_HCO: 1209e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev case SND_DEVICE_TTY_FULL: 1210e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev new_pathid = A1026_PATH_INCALL_TTY; 121122f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_INCALL_TTY"); 1212e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev break; 12132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: 12142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 12152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (Record == 1) { 12182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 1219ba36d4fa33072ef14183365fffd289762c26905eJean-Michel Trivi case SND_DEVICE_SPEAKER: 1220ba36d4fa33072ef14183365fffd289762c26905eJean-Michel Trivi // default output is speaker, recording from phone mic, user RECEIVER configuration 1221739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HANDSET: 1222739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_NO_MIC_HEADSET: 122308516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled) { 1224739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (vr_uses_ns) { 12254bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NS_RECEIVER; 122622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_VR_NS_RECEIVER"); 1227739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 12284bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NO_NS_RECEIVER; 122922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_RECEIVER"); 1230739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1231739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 12329ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi new_pathid = A1026_PATH_RECORD_RECEIVER; /* INT-MIC Recording: NS disable, Main MIC */ 123322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_RECORD_RECEIVER"); 1234739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 12352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1236739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HEADSET: 1237739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 1238739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_FM_HEADSET: 1239739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_FM_SPEAKER: 124008516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled) { 1241739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (vr_uses_ns) { 12424bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NS_HEADSET; 124322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_VR_NS_HEADSET"); 1244739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 12454bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NO_NS_HEADSET; 124622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_HEADSET"); 1247739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1248739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 1249739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi new_pathid = A1026_PATH_RECORD_HEADSET; /* EXT-MIC Recording: NS disable, Headset MIC */ 125022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_RECORD_HEADSET"); 1251739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1252739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi break; 1253739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_SPEAKER_BACK_MIC: 1254739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 1255739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HANDSET_BACK_MIC: 125658cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 1257da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent new_pathid = A1026_PATH_CAMCORDER; /* CAM-Coder: NS FT mode, Back MIC */ 125822f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_CAMCORDER"); 12592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1260739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_BT: 1261739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_BT_EC_OFF: 1262c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent case SND_DEVICE_CARKIT: 126308516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled) { 1264739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (vr_uses_ns) { 12654bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NS_BT; 126622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_VR_NS_BT"); 1267739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 12684bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NO_NS_BT; 126922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_BT"); 1270739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1271739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 1272739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi new_pathid = A1026_PATH_RECORD_BT; /* BT MIC */ 127322f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_RECORD_BT"); 1274739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 12752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1276739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi default: 12772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 12782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else { 12812176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent switch (Routes) { 12822176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent case SND_DEVICE_BT: 12832176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent case SND_DEVICE_BT_EC_OFF: 12842176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent case SND_DEVICE_CARKIT: 12852176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent new_pathid = A1026_PATH_RECORD_BT; /* BT MIC */ 128622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("A1026 control: new path is A1026_PATH_RECORD_BT"); 12872176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent break; 12882176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent default: 12892176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent new_pathid = A1026_PATH_SUSPEND; 12902176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent break; 12912176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent } 12922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (old_pathid != new_pathid) { 12955a182ec3e8b87b6538b4b492cb993239a677915fSteve Block //ALOGI("A1026: do ioctl(A1026_SET_CONFIG) to %d\n", new_pathid); 12960f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent do { 12970f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent rc = ioctl(fd_a1026, A1026_SET_CONFIG, &new_pathid); 12980f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!rc) { 12990f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent old_pathid = new_pathid; 13000f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 13010f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 13020f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } while (--retry); 13030f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 13040f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (rc < 0) { 13053fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("A1026 do hard reset to recover from error!\n"); 13060f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent rc = doA1026_init(); /* A1026 needs to do hard reset! */ 13070f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!rc) { 1308d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi /* after doA1026_init(), fd_a1026 is -1*/ 1309d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi fd_a1026 = open("/dev/audience_a1026", O_RDWR); 1310d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi if (fd_a1026 < 0) { 1311c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("A1026 Fatal Error: unable to open A1026 after hard reset\n"); 1312d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi } else { 1313d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi rc = ioctl(fd_a1026, A1026_SET_CONFIG, &new_pathid); 1314d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi if (!rc) { 1315d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi old_pathid = new_pathid; 1316d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi } else { 1317c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("A1026 Fatal Error: unable to A1026_SET_CONFIG after hard reset\n"); 1318d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi } 1319d666d60c2b157bee1aaf2233c253778929bd7d49Jean-Michel Trivi } 13200f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } else 1321c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("A1026 Fatal Error: Re-init A1026 Failed\n"); 13220f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 13232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1325fe306807b0fe36243d9e7eca094d5e20a0667016Jean-Michel Trivi if (fd_a1026 >= 0) { 1326fe306807b0fe36243d9e7eca094d5e20a0667016Jean-Michel Trivi close(fd_a1026); 1327fe306807b0fe36243d9e7eca094d5e20a0667016Jean-Michel Trivi } 13282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = -1; 132911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mA1026Lock.unlock(); 13302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return rc; 13322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 13332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 133511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurentstatus_t AudioHardware::doRouting() 13362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1337f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi Mutex::Autolock lock(mLock); 1338f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi uint32_t outputDevices = mOutput->devices(); 13392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t ret = NO_ERROR; 134011c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent AudioStreamInMSM72xx *input = getActiveInput_l(); 134111c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent uint32_t inputDevice = (input == NULL) ? 0 : input->devices(); 1342f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi int sndDevice = -1; 13432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 134417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if (mMode == AudioSystem::MODE_IN_CALL && mTTYMode != TTY_MODE_OFF) { 134517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) || 134617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) { 134717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent switch (mTTYMode) { 134817b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case TTY_MODE_FULL: 134917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent sndDevice = SND_DEVICE_TTY_FULL; 135017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent break; 135117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case TTY_MODE_VCO: 135217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent sndDevice = SND_DEVICE_TTY_VCO; 135317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent break; 135417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case TTY_MODE_HCO: 135517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent sndDevice = SND_DEVICE_TTY_HCO; 135617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent break; 135717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 135817b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 135917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 136017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent 1361c08cbb26e57c8c3521391947e676cbdb6e81603bEric Laurent if (sndDevice == -1 && inputDevice != 0) { 13625a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("do input routing device %x\n", inputDevice); 1363710f4558c4f660e59551b1ed13c5106f9e460a59Eric Laurent if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 13645a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Bluetooth PCM\n"); 1365710f4558c4f660e59551b1ed13c5106f9e460a59Eric Laurent sndDevice = SND_DEVICE_BT; 1366710f4558c4f660e59551b1ed13c5106f9e460a59Eric Laurent } else if (inputDevice & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 13675a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Bluetooth car kit\n"); 1368710f4558c4f660e59551b1ed13c5106f9e460a59Eric Laurent sndDevice = SND_DEVICE_CARKIT; 1369710f4558c4f660e59551b1ed13c5106f9e460a59Eric Laurent } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 1370710f4558c4f660e59551b1ed13c5106f9e460a59Eric Laurent if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 1371710f4558c4f660e59551b1ed13c5106f9e460a59Eric Laurent (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 13725a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Wired Headset and Speaker\n"); 1373710f4558c4f660e59551b1ed13c5106f9e460a59Eric Laurent sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 1374f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 13755a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Wired Headset\n"); 137611c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_HEADSET; 137711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } 137811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else if (inputDevice & AudioSystem::DEVICE_IN_BACK_MIC) { 137911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent if (outputDevices & (AudioSystem:: DEVICE_OUT_WIRED_HEADSET) && 138011c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent (outputDevices & AudioSystem:: DEVICE_OUT_SPEAKER)) { 13815a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Wired Headset and Speaker with back mic\n"); 138211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC; 138311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 13845a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Speakerphone with back mic\n"); 138511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_SPEAKER_BACK_MIC; 138611c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else if (outputDevices == AudioSystem::DEVICE_OUT_EARPIECE) { 13875a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Handset with back mic\n"); 138811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_HANDSET_BACK_MIC; 138911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else { 13905a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Headset with back mic\n"); 139111c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_NO_MIC_HEADSET_BACK_MIC; 139211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } 139311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else { 139411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 13955a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Speakerphone\n"); 139611c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_SPEAKER; 139711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else if (outputDevices == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 13985a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Speakerphone\n"); 139911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_NO_MIC_HEADSET; 140011c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } else { 14015a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Handset\n"); 140211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent sndDevice = SND_DEVICE_HANDSET; 1403956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1404956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1405f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 140611c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent // if inputDevice == 0, restore output routing 1407956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent 1408f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (sndDevice == -1) { 1409f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & (outputDevices - 1)) { 1410f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) { 14113fb19cd0b6534ef9d36f8ac0c5ddbdc73ed92a26Steve Block ALOGW("Hardware does not support requested route combination (%#X)," 1412f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi " picking closest possible route...", outputDevices); 1413956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1414f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 1415956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent 1416f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & 1417dd65e38951ed174f9d3d34886795438440f7eea0Eric Laurent (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { 14185a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Bluetooth PCM\n"); 1419f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_BT; 1420f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 14215a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Bluetooth PCM\n"); 1422f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_CARKIT; 1423f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 1424f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 14255a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Wired Headset and Speaker\n"); 1426956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 1427f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 1428f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 14295a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); 1430f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 1431956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } else { 14325a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); 1433f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_NO_MIC_HEADSET; 14342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1435f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 14365a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Wired Headset\n"); 1437f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET; 1438f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 14395a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Speakerphone\n"); 1440f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_SPEAKER; 1441f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 14425a182ec3e8b87b6538b4b492cb993239a677915fSteve Block ALOGI("Routing audio to Handset\n"); 1443f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HANDSET; 14442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1445f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 14462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1447f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if ((vr_mode_change) || (sndDevice != -1 && sndDevice != mCurSndDevice)) { 1448f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi ret = doAudioRouteOrMute(sndDevice); 1449f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi mCurSndDevice = sndDevice; 14503964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent if (mMode == AudioSystem::MODE_IN_CALL) { 1451ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent if (mHACSetting && hac_enable && mCurSndDevice == (int) SND_DEVICE_HANDSET) { 1452f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("HAC enable: Setting in-call volume to maximum.\n"); 1453ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent set_volume_rpc(VOICE_VOLUME_MAX); 1454ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent } else { 1455ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent set_volume_rpc(mVoiceVolume); 1456ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent } 14573964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent } 14582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return ret; 14612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::checkMicMute() 14642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 14662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mMode != AudioSystem::MODE_IN_CALL) { 14672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland setMicMute_nosync(true); 14682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 14712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 14742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 14762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 14772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 14782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioHardware::dumpInternals\n"); 14792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 14802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 14822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 14842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14850f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snprintf(buffer, SIZE, "\tmBluetoothIdtx: %d\n", mBluetoothIdTx); 14860f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent result.append(buffer); 14870f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snprintf(buffer, SIZE, "\tmBluetoothIdrx: %d\n", mBluetoothIdRx); 14882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 14902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 14912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::dump(int fd, const Vector<String16>& args) 14942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland dumpInternals(fd, args); 14962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (size_t index = 0; index < mInputs.size(); index++) { 14972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs[index]->dump(fd, args); 14982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) { 15012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput->dump(fd, args); 15022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 15042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 15052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlanduint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) 15072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 15082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t i; 15092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t prevDelta; 15102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t delta; 15112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { 15132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delta = abs(sampleRate - inputSamplingRates[i]); 15142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (delta > prevDelta) break; 15152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // i is always > 0 here 15172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return inputSamplingRates[i-1]; 15182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 15192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 152011c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent// getActiveInput_l() must be called with mLock held 152111c6a166fa684a2e44d22a142aad106f74a9409fEric LaurentAudioHardware::AudioStreamInMSM72xx *AudioHardware::getActiveInput_l() 152211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent{ 152311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent for (size_t i = 0; i < mInputs.size(); i++) { 152411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent // return first input found not being in standby mode 152511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent // as only one input can be in this state 1526e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (!mInputs[i]->checkStandby()) { 152711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent return mInputs[i]; 152811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } 152911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent } 153011c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent 153111c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent return NULL; 153211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent} 15332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 15342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15352aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 1536f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), 1537f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent mDevices(0), mChannels(AUDIO_HW_OUT_CHANNELS), mSampleRate(AUDIO_HW_OUT_SAMPLERATE), 1538f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent mBufferSize(AUDIO_HW_OUT_BUFSZ) 15392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 15402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 15412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::set( 15432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 15442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 15452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int lFormat = pFormat ? *pFormat : 0; 15462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t lChannels = pChannels ? *pChannels : 0; 15472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t lRate = pRate ? *pRate : 0; 15482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware = hw; 1550f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent mDevices = devices; 15512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // fix up defaults 15532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lFormat == 0) lFormat = format(); 15542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lChannels == 0) lChannels = channels(); 15552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lRate == 0) lRate = sampleRate(); 15562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // check values 15582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((lFormat != format()) || 15592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (lChannels != channels()) || 15602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (lRate != sampleRate())) { 15612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat) *pFormat = format(); 15622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels) *pChannels = channels(); 15632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate) *pRate = sampleRate(); 15642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 15652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat) *pFormat = lFormat; 15682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels) *pChannels = lChannels; 15692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate) *pRate = lRate; 15702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1571f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent mChannels = lChannels; 1572f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent mSampleRate = lRate; 1573f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent mBufferSize = hw->getBufferSize(lRate, AudioSystem::popCount(lChannels)); 15742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 15762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 15772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15782aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 15792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 15802176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent standby(); 15812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 15822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 15842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1585f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block // ALOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 15862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_INIT; 15872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland size_t count = bytes; 15882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const uint8_t* p = static_cast<const uint8_t*>(buffer); 15892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mStandby) { 15912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 159222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("acquire output wakelock"); 1593b508a4857b07898fb8322a858c4ee9624bcf1180Iliyan Malchev acquire_wake_lock(PARTIAL_WAKE_LOCK, kOutputWakelockStr); 1594b508a4857b07898fb8322a858c4ee9624bcf1180Iliyan Malchev 15952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // open driver 159622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("open pcm_out driver"); 15972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ::open("/dev/msm_pcm_out", O_RDWR); 15982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 15992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errCount++ < 10) { 1600c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 16012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1602e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent release_wake_lock(kOutputWakelockStr); 16032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 16042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = status; 1606e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mStandby = false; 16072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // configuration 160922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("get config"); 16102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct msm_audio_config config; 16112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 16122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 1613c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot read pcm_out config"); 16142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 16152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 161722f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("set pcm_out config"); 16182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.channel_count = AudioSystem::popCount(channels()); 1619f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent config.sample_rate = mSampleRate; 1620f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent config.buffer_size = mBufferSize; 16212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 16222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.codec_type = CODEC_TYPE_PCM; 16232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 16242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 1625c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot set config"); 16262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 16272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 162922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("buffer_size: %u", config.buffer_size); 163022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("buffer_count: %u", config.buffer_count); 163122f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("channel_count: %u", config.channel_count); 163222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("sample_rate: %u", config.sample_rate); 16332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16347fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t acdb_id = mHardware->getACDB(MOD_PLAY, mHardware->get_snd_dev()); 16357fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi status = ioctl(mFd, AUDIO_START, &acdb_id); 163631923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen if (status < 0) { 1637c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot start pcm playback"); 163831923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen goto Error; 16392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 164010254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi 164110254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi status = ioctl(mFd, AUDIO_SET_VOLUME, &stream_volume); 164210254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi if (status < 0) { 1643c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot start pcm playback"); 164410254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi goto Error; 164510254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi } 16462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland while (count) { 16492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t written = ::write(mFd, p, count); 16502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (written >= 0) { 16512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland count -= written; 16522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland p += written; 16532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 1654e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (errno != EAGAIN) { 1655e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent status = written; 1656e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent goto Error; 1657e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent } 16582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRetryCount++; 1659f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("EAGAIN - retry"); 16602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return bytes; 16642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16652aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandError: 1666e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 1667e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent standby(); 1668e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 16692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // Simulate audio output timing in case of error 1670e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent usleep((((bytes * 1000) / frameSize()) * 1000) / sampleRate()); 16712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 16722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::standby() 16752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1676e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (!mStandby) { 1677f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("AudioHardware pcm playback is going to standby."); 1678e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (mFd >= 0) { 1679e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent ::close(mFd); 1680e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mFd = -1; 1681e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent } 168222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("release output wakelock"); 16835d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks release_wake_lock(kOutputWakelockStr); 1684e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mStandby = true; 16852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1686e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent return NO_ERROR; 16872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 16902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 16922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 16932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 16942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioStreamOutMSM72xx::dump\n"); 16952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 16962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 16982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 17002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 17012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 17022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 17032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 17042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 17052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 17062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 17072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 17082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 17092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 17102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 17112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 17122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 17132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 17142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 17152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 17162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1717e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 17182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandbool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 17192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 17202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mStandby; 17212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 17222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) 17252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 17262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 17272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 17282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 17292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int device; 173022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); 17312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.getInt(key, device) == NO_ERROR) { 17332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = device; 173422f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("set output routing %x", mDevices); 173511c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent status = mHardware->doRouting(); 17362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.remove(key); 17372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.size()) { 17402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 17412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 17432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 17442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17452aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) 17462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 17472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keys); 17482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 17492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 17502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 175222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("get routing %x", mDevices); 17532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.addInt(key, (int)mDevices); 17542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 175622f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); 17572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return param.toString(); 17582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 17592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17603b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurentstatus_t AudioHardware::AudioStreamOutMSM72xx::getRenderPosition(uint32_t *dspFrames) 17613b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurent{ 17623b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurent //TODO: enable when supported by driver 17633b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurent return INVALID_OPERATION; 17643b9744cccd99fd9f32ae3b99fbc8d6898b118a43Eric Laurent} 17652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 17672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17682aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 1769e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mHardware(0), mFd(-1), mStandby(true), mRetryCount(0), 17702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), 1771f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFSZ), 17722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) 17732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 17742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 17752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::set( 17772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, 17782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioSystem::audio_in_acoustics acoustic_flags) 17792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 17802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) { 17812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pFormat = AUDIO_HW_IN_FORMAT; 17822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 17832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate == 0) { 17852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 17862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t rate = hw->getInputSampleRate(*pRate); 17882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (rate != *pRate) { 17892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pRate = rate; 17902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 17912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO && 17942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels != AudioSystem::CHANNEL_IN_STEREO)) { 17952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AUDIO_HW_IN_CHANNELS; 17962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 17972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware = hw; 18002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 180122f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); 18022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 1803c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Audio record already open"); 18042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -EPERM; 18052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1807f2236a59c89b93062490d2c236ffebe57173af6eEric Laurent mBufferSize = hw->getBufferSize(*pRate, AudioSystem::popCount(*pChannels)); 18082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = devices; 18092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFormat = AUDIO_HW_IN_FORMAT; 18102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mChannels = *pChannels; 1811e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mSampleRate = *pRate; 18122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 18142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 18162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18172aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 18182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 181922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamInMSM72xx destructor"); 18202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland standby(); 18212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 18222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 18242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 182522f2554680715d1ea993409217a4a21f652ef130Steve Block// ALOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 18262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mHardware) return -1; 18272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland size_t count = bytes; 18292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint8_t* p = static_cast<uint8_t*>(buffer); 1830e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent status_t status = NO_ERROR; 18312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1832e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (mStandby) { 1833e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent { // scope for the lock 1834e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent Mutex::Autolock lock(mHardware->mLock); 183522f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("acquire input wakelock"); 1836e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent acquire_wake_lock(PARTIAL_WAKE_LOCK, kInputWakelockStr); 1837e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent // open audio input device 1838e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent status = ::open("/dev/msm_pcm_in", O_RDWR); 1839e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (status < 0) { 1840c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 184122f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("release input wakelock"); 1842e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent release_wake_lock(kInputWakelockStr); 1843e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent goto Error; 1844e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent } 1845e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mFd = status; 1846e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mStandby = false; 1847e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 1848e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent // configuration 184922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("get config"); 1850e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent struct msm_audio_config config; 1851e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 1852e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (status < 0) { 1853c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot read config"); 1854e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent goto Error; 1855e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent } 1856e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 185722f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("set config"); 1858e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent config.channel_count = AudioSystem::popCount(mChannels); 1859e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent config.sample_rate = mSampleRate; 1860e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent config.buffer_size = mBufferSize; 1861e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent config.buffer_count = 2; 1862e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent config.codec_type = CODEC_TYPE_PCM; 1863e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 1864e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (status < 0) { 1865c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Cannot set config"); 1866e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent goto Error; 1867e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent } 1868e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 186922f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("buffer_size: %u", config.buffer_size); 187022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("buffer_count: %u", config.buffer_count); 187122f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("channel_count: %u", config.channel_count); 187222f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("sample_rate: %u", config.sample_rate); 18732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware->set_mRecordState(1); 187611c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent // make sure a1026 config is re-applied even is input device is not changed 187711c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mHardware->clearCurDevice(); 187811c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent mHardware->doRouting(); 187911c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent 18807fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t acdb_id = mHardware->getACDB(MOD_REC, mHardware->get_snd_dev()); 18817fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (ioctl(mFd, AUDIO_START, &acdb_id)) { 1882c3dee7890047bad1136078f0f6e2b6d1a9a24947Steve Block ALOGE("Error starting record"); 1883e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent goto Error; 18842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland while (count) { 18882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t bytesRead = ::read(mFd, buffer, count); 18892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (bytesRead >= 0) { 18902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland count -= bytesRead; 18912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland p += bytesRead; 18922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 1893e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (errno != EAGAIN) { 1894e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent status = bytesRead; 1895e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent goto Error; 1896e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent } 18972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRetryCount++; 1898f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("EAGAIN - retrying"); 18992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 19002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 19012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return bytes; 1902e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 1903e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric LaurentError: 1904e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent standby(); 1905e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 1906e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent // Simulate audio input timing in case of error 1907e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent usleep((((bytes * 1000) / frameSize()) * 1000) / sampleRate()); 1908e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 1909e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent return status; 19102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 19112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::standby() 19132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1914e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (!mStandby) { 1915f9452ed4a7c7bbde537f3f2690fc124e5a1beaffSteve Block ALOGD("AudioHardware PCM record is going to standby."); 19162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 19172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 19182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 19192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 192022f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("release input wakelock"); 19212176dbc34c87e6855a912920f6868f8d211d12b4Eric Laurent release_wake_lock(kInputWakelockStr); 192211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent 1923e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mStandby = true; 192411c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent 1925e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent if (!mHardware) return -1; 1926e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 1927e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mHardware->set_mRecordState(0); 1928e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent // make sure a1026 config is re-applied even is input device is not changed 1929e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mHardware->clearCurDevice(); 1930e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent mHardware->doRouting(); 1931e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent } 193211c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent 19332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 19342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 19352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1936e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurentbool AudioHardware::AudioStreamInMSM72xx::checkStandby() 1937e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent{ 1938e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent return mStandby; 1939e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent} 1940e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent 19412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 19422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 19432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 19442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 19452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 19462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioStreamInMSM72xx::dump\n"); 19472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 19482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 19492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 19502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 19512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 19522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 19532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 19542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 19552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 19562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 19572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 19582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 1959e784e44a0402aa4e9489e0b9f2f3d3685cf76a93Eric Laurent snprintf(buffer, SIZE, "\tmStandby: %d\n", mStandby); 19602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 19612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 19622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 19632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 19642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 19652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 19662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs) 19682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 19692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 19702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 19712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int device; 19721119793f2bc460d6417fedb54c7a51c48ded56deJean-Michel Trivi String8 key = String8(AudioParameter::keyInputSource); 19731119793f2bc460d6417fedb54c7a51c48ded56deJean-Michel Trivi int source; 197422f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string()); 19752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19761119793f2bc460d6417fedb54c7a51c48ded56deJean-Michel Trivi // reading input source for voice recognition mode parameter 19771119793f2bc460d6417fedb54c7a51c48ded56deJean-Michel Trivi if (param.getInt(key, source) == NO_ERROR) { 197822f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("set input source %d", source); 19791119793f2bc460d6417fedb54c7a51c48ded56deJean-Michel Trivi int uses_vr = (source == AUDIO_SOURCE_VOICE_RECOGNITION); 19801119793f2bc460d6417fedb54c7a51c48ded56deJean-Michel Trivi vr_mode_change = (vr_mode_enabled != uses_vr); 19811119793f2bc460d6417fedb54c7a51c48ded56deJean-Michel Trivi vr_mode_enabled = uses_vr; 1982739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi param.remove(key); 1983739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1984739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 1985739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // reading routing parameter 1986255bdedb2d7ebf4b14690776ff652df1de97fe95Eric Laurent key = String8(AudioParameter::keyRouting); 19872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.getInt(key, device) == NO_ERROR) { 198822f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("set input routing %x", device); 19892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device & (device - 1)) { 19902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 19912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 19922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = device; 199311c6a166fa684a2e44d22a142aad106f74a9409fEric Laurent status = mHardware->doRouting(); 19942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 19952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.remove(key); 19962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 19972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.size()) { 19992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 20002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 20012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 20022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 20032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 20042aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys) 20052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 20062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keys); 20072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 20082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 20092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 20102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 201122f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("get routing %x", mDevices); 20122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.addInt(key, (int)mDevices); 20132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 20142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 201522f2554680715d1ea993409217a4a21f652ef130Steve Block ALOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string()); 20162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return param.toString(); 20172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 20182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 20192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 20202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 20212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandextern "C" AudioHardwareInterface* createAudioHardware(void) { 20222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return new AudioHardware(); 20232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 20242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 20252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland}; // namespace android 2026