AudioHardware.cpp revision e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44
12aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland/* 22aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland** Copyright 2008, Google Inc. 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 192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland//#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> 392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandextern "C" { 412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include "msm_audio.h" 429ab0b5b1f3244f261fcda2ead8fcdd5fe5d714b6Iliyan Malchev#include <linux/a1026.h> 43f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev#include <linux/tpa2018d1.h> 442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#define LOG_SND_RPC 0 // Set to 1 to log sound RPC's 472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#define TX_PATH (1) 482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_CURRENT = 256; 502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HANDSET = 0; 512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_SPEAKER = 1; 522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_BT = 3; 532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_CARKIT = 4; 542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_BT_EC_OFF = 45; 552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HEADSET = 2; 562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER = 10; 572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_FM_HEADSET = 9; 582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_FM_SPEAKER = 11; 592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_NO_MIC_HEADSET = 8; 602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_TTY_FULL = 5; 6117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurentstatic const uint32_t SND_DEVICE_TTY_VCO = 6; 6217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurentstatic const uint32_t SND_DEVICE_TTY_HCO = 7; 63da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurentstatic const uint32_t SND_DEVICE_HANDSET_BACK_MIC = 20; 64da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurentstatic const uint32_t SND_DEVICE_SPEAKER_BACK_MIC = 21; 65da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurentstatic const uint32_t SND_DEVICE_NO_MIC_HEADSET_BACK_MIC = 28; 6658cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivistatic const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC = 30; 672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandnamespace android { 682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int support_a1026 = 1; 69f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatic bool support_tpa2018d1 = true; 702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int fd_a1026 = -1; 712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int old_pathid = -1; 722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int new_pathid = -1; 730f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatic int curr_out_device = -1; 740f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatic int curr_mic_device = -1; 752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int voice_started = 0; 762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int fd_fm_device = -1; 7710254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivistatic int stream_volume = -300; 78739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi// use VR mode on inputs: 1 == VR mode enabled when selected, 0 = VR mode disabled when selected 7908516fe50b023532d5a3010050970de28e14621bIliyan Malchevstatic int vr_mode_enabled; 80739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivistatic bool vr_mode_change = false; 81739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivistatic int vr_uses_ns = 0; 82f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatic int alt_enable = 0; 83f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatic int hac_enable = 0; 849ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi// enable or disable 2-mic noise suppression in call on receiver mode 85739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivistatic int enable1026 = 1; 869ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi//FIXME add new settings in A1026 driver for an incall no ns mode, based on the current vr no ns 879ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi#define A1026_PATH_INCALL_NO_NS_RECEIVER A1026_PATH_VR_NO_NS_RECEIVER 8810254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi 892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandint errCount = 0; 900f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatic void * acoustic; 912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandconst uint32_t AudioHardware::inputSamplingRates[] = { 922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland}; 945d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks 955d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks// ID string for audio wakelock 965d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparksstatic const char kOutputWakelockStr[] = "AudioHardwareQSD"; 975d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks 982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1002aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioHardware() : 1010f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mA1026Init(false), mInit(false), mMicMute(true), 102f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mBluetoothNrec(true), 103f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mHACSetting(false), 104f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mBluetoothIdTx(0), mBluetoothIdRx(0), 105f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mOutput(0), 1063964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent mNoiseSuppressionState(A1026_NS_STATE_AUTO), 10717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent mVoiceVolume(VOICE_VOLUME_MAX), mTTYMode(TTY_MODE_OFF) 1082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1090f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int (*snd_get_num)(); 1100f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int (*snd_get_bt_endpoint)(msm_bt_endpoint *); 1110f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int (*set_acoustic_parameters)(); 112f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int (*set_tpa2018d1_parameters)(); 1130f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1140f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent struct msm_bt_endpoint *ept; 1150f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland doA1026_init(); 1170f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1180f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acoustic =:: dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW); 1190f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (acoustic == NULL ) { 1200f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not open libhtc_acoustic.so"); 1210f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent /* this is not really an error on non-htc devices... */ 1220f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mNumBTEndpoints = 0; 1230f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mInit = true; 1240f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return; 1250f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1260f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters"); 1270f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if ((*set_acoustic_parameters) == 0 ) { 1280f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not open set_acoustic_parameters()"); 1290f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return; 1300f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1310f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 132f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev set_tpa2018d1_parameters = (int (*)(void))::dlsym(acoustic, "set_tpa2018d1_parameters"); 133f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if ((*set_tpa2018d1_parameters) == 0) { 134f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGI("set_tpa2018d1_parameters() not present"); 135f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev support_tpa2018d1 = false; 136f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 137f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1380f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int rc = set_acoustic_parameters(); 1390f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (rc < 0) { 1400f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not set acoustic parameters to share memory: %d", rc); 1410f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1420f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 143f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (support_tpa2018d1) { 144f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev rc = set_tpa2018d1_parameters(); 145f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (rc < 0) { 146f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev support_tpa2018d1 = false; 147f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGE("speaker amplifier tpa2018 is not supported\n"); 148f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 149f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 150f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1510f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num"); 1520f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if ((*snd_get_num) == 0 ) { 1530f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not open snd_get_num()"); 1540f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1550f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1560f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mNumBTEndpoints = snd_get_num(); 1570f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGD("mNumBTEndpoints = %d", mNumBTEndpoints); 1580f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBTEndpoints = new msm_bt_endpoint[mNumBTEndpoints]; 1590f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mInit = true; 1600f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGV("constructed %d SND endpoints)", mNumBTEndpoints); 1610f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent ept = mBTEndpoints; 1620f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snd_get_bt_endpoint = (int (*)(msm_bt_endpoint *))::dlsym(acoustic, "snd_get_bt_endpoint"); 1630f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if ((*snd_get_bt_endpoint) == 0 ) { 1640f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not open snd_get_bt_endpoint()"); 1650f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return; 1660f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1670f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snd_get_bt_endpoint(mBTEndpoints); 1680f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1690f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent for (int i = 0; i < mNumBTEndpoints; i++) { 1700f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("BT name %s (tx,rx)=(%d,%d)", mBTEndpoints[i].name, mBTEndpoints[i].tx, mBTEndpoints[i].rx); 1710f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1720f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 173d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent // reset voice mode in case media_server crashed and restarted while in call 174d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent int fd = open("/dev/msm_audio_ctl", O_RDWR); 175d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent if (fd >= 0) { 176d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent ioctl(fd, AUDIO_STOP_VOICE, NULL); 177d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent close(fd); 178d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent } 179d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent 180739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi vr_mode_change = false; 18108516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_enabled = 0; 182739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi enable1026 = 1; 183739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi char value[PROPERTY_VALUE_MAX]; 184739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // Check the system property to enable or not the special recording modes 185739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi property_get("media.a1026.enableA1026", value, "1"); 186739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi enable1026 = atoi(value); 187739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("Enable mode selection for A1026 is %d", enable1026); 188739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // Check the system property for which VR mode to use 189739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi property_get("media.a1026.nsForVoiceRec", value, "0"); 190739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi vr_uses_ns = atoi(value); 191739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("Using Noise Suppression for Voice Rec is %d", vr_uses_ns); 192739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 193f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev // Check the system property for enable or not the ALT function 194f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev property_get("htc.audio.alt.enable", value, "0"); 195f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev alt_enable = atoi(value); 196f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGV("Enable ALT function: %d", alt_enable); 197f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 198f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev // Check the system property for enable or not the HAC function 199f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev property_get("htc.audio.hac.enable", value, "0"); 200f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev hac_enable = atoi(value); 201f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGV("Enable HAC function: %d", hac_enable); 202f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 2032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInit = true; 2042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2062aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::~AudioHardware() 2072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (size_t index = 0; index < mInputs.size(); index++) { 2092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland closeInputStream((AudioStreamIn*)mInputs[index]); 2102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.clear(); 2122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland closeOutputStream((AudioStreamOut*)mOutput); 2132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInit = false; 2142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::initCheck() 2172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mInit ? NO_ERROR : NO_INIT; 2192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2212aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioStreamOut* AudioHardware::openOutputStream( 2222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status) 2232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland { // scope for the lock 2252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 2262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // only one output stream allowed 2282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) { 2292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 2302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = INVALID_OPERATION; 2312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 2332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // create new output stream 2362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 2372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t lStatus = out->set(this, devices, format, channels, sampleRate); 2382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 2392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = lStatus; 2402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lStatus == NO_ERROR) { 2422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput = out; 2432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 2442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete out; 2452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mOutput; 2482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandvoid AudioHardware::closeOutputStream(AudioStreamOut* out) { 2512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 2522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput == 0 || mOutput != out) { 2532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Attempt to close invalid output stream"); 2542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else { 2562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete mOutput; 2572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput = 0; 2582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2612aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioStreamIn* AudioHardware::openInputStream( 2622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status, 2632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioSystem::audio_in_acoustics acoustic_flags) 2642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // check for valid input source 2662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) { 2672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 2682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.lock(); 2712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 2732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t lStatus = in->set(this, devices, format, channels, sampleRate, acoustic_flags); 2742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 2752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = lStatus; 2762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lStatus != NO_ERROR) { 2782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 2792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete in; 2802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 2812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.add(in); 2842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 2852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return in; 2872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandvoid AudioHardware::closeInputStream(AudioStreamIn* in) { 2902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 2912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t index = mInputs.indexOf((AudioStreamInMSM72xx *)in); 2932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (index < 0) { 2942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Attempt to close invalid input stream"); 2952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 2962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 2972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete mInputs[index]; 2982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.lock(); 2992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.removeAt(index); 3002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMode(int mode) 3042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 305739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // VR mode is never used in a call and must be cleared when entering the IN_CALL mode 306739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (mode == AudioSystem::MODE_IN_CALL) { 30708516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_enabled = 0; 308739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 309739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 310f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (support_tpa2018d1) 311f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev do_tpa2018_control(mode); 312f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 3132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = AudioHardwareBase::setMode(mode); 3142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status == NO_ERROR) { 3152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // make sure that doAudioRouteOrMute() is called by doRouting() 3162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // even if the new device selected is the same as current one. 3172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mCurSndDevice = -1; 3182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 3202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandbool AudioHardware::checkOutputStandby() 3232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) 3252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mOutput->checkStandby()) 3262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return false; 3272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return true; 3292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3303cb8864598e72c04859f410bb03f242cf3965dbeHK Chenstatic status_t set_mic_mute(bool _mute) 3312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3323cb8864598e72c04859f410bb03f242cf3965dbeHK Chen uint32_t mute = _mute; 3333cb8864598e72c04859f410bb03f242cf3965dbeHK Chen int fd = -1; 3342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 3352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 3362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl device\n"); 3372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 3382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Setting mic mute to %d\n", mute); 3403cb8864598e72c04859f410bb03f242cf3965dbeHK Chen if (ioctl(fd, AUDIO_SET_MUTE, &mute)) { 3412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot set mic mute on current device\n"); 3422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 3432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 3442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 3462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMicMute(bool state) 3502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 3522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return setMicMute_nosync(state); 3532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// always call with mutex held 3562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMicMute_nosync(bool state) 3572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mMicMute != state) { 3592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mMicMute = state; 3602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return set_mic_mute(mMicMute); //always set current TX device 3612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::getMicMute(bool* state) 3662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *state = mMicMute; 3682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setParameters(const String8& keyValuePairs) 3722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 3742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 3752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key; 3762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NREC_KEY[] = "bt_headset_nrec"; 3772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NAME_KEY[] = "bt_headset_name"; 378f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev const char HAC_KEY[] = "HACSetting"; 3792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NREC_VALUE_ON[] = "on"; 380f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev const char HAC_VALUE_ON[] = "ON"; 3812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("setParameters() %s", keyValuePairs.string()); 3842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (keyValuePairs.length() == 0) return BAD_VALUE; 3862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 387f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if(hac_enable) { 388f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev key = String8(HAC_KEY); 389f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (param.get(key, value) == NO_ERROR) { 390f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (value == HAC_VALUE_ON) { 391f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mHACSetting = true; 392f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGD("Enable HAC"); 393f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } else { 394f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mHACSetting = false; 395f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGD("Disable HAC"); 396f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 397f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 398f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 399f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 4002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland key = String8(BT_NREC_KEY); 4012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 4022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (value == BT_NREC_VALUE_ON) { 4032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothNrec = true; 4042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 4052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothNrec = false; 4062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Turning noise reduction and echo cancellation off for BT " 4072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland "headset"); 4082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland key = String8(BT_NAME_KEY); 4112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 4120f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdTx = 0; 4130f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdRx = 0; 4140f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent for (int i = 0; i < mNumBTEndpoints; i++) { 4150f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!strcasecmp(value.string(), mBTEndpoints[i].name)) { 4160f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdTx = mBTEndpoints[i].tx; 4170f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdRx = mBTEndpoints[i].rx; 4182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Using custom acoustic parameters for %s", value.string()); 4192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 4202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4220f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (mBluetoothIdTx == 0) { 4232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Using default acoustic parameters " 4242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland "(%s not in acoustic database)", value.string()); 4252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4260f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent doRouting(NULL); 4272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 428da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent key = String8("noise_suppression"); 429da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (param.get(key, value) == NO_ERROR) { 430da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (support_a1026 == 1) { 431da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent int noiseSuppressionState; 432da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (value == "off") { 433da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_OFF; 434da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (value == "auto") { 435da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_AUTO; 436da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (value == "far_talk") { 437da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_FT; 438da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (value == "close_talk") { 439da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_CT; 440da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else { 441da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return BAD_VALUE; 442da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 443da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 444da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (noiseSuppressionState != mNoiseSuppressionState) { 445da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (!mA1026Init) { 446da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGW("Audience A1026 not initialized.\n"); 447da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return INVALID_OPERATION; 448da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 449da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 450da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (fd_a1026 < 0) { 451da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent fd_a1026 = open("/dev/audience_a1026", O_RDWR); 452da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (fd_a1026 < 0) { 453da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGE("Cannot open audience_a1026 device (%d)\n", fd_a1026); 454da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return -1; 455da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 456da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 457da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGV("Setting noise suppression %s", value.string()); 458da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mA1026Lock.lock(); 459da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent int rc = ioctl(fd_a1026, A1026_SET_NS_STATE, &noiseSuppressionState); 460da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (!rc) { 461da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mNoiseSuppressionState = noiseSuppressionState; 462da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else { 463da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGE("Failed to set noise suppression %s", value.string()); 464da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 465da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mA1026Lock.unlock(); 466da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 467da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else { 468da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return INVALID_OPERATION; 469da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 470da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 471da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 47217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent key = String8("tty_mode"); 47317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if (param.get(key, value) == NO_ERROR) { 47417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent int ttyMode; 47517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if (value == "tty_off") { 47617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent ttyMode = TTY_MODE_OFF; 47717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (value == "tty_full") { 47817b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent ttyMode = TTY_MODE_FULL; 47917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (value == "tty_vco") { 48017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent ttyMode = TTY_MODE_VCO; 48117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (value == "tty_hco") { 48217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent ttyMode = TTY_MODE_HCO; 48317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else { 48417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent return BAD_VALUE; 48517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 48617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent 48717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if (ttyMode != mTTYMode) { 48817b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent LOGV("new tty mode %d", ttyMode); 48917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent mTTYMode = ttyMode; 49017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent doRouting(NULL); 49117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 49217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 49317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent 4942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 4952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 4962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4972aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::getParameters(const String8& keys) 4982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 499da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent AudioParameter request = AudioParameter(keys); 500da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent AudioParameter reply = AudioParameter(); 501da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent String8 value; 502da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent String8 key; 503da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 504da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGV("getParameters() %s", keys.string()); 505da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 506da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent key = "noise_suppression"; 507da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (request.get(key, value) == NO_ERROR) { 508da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent switch(mNoiseSuppressionState) { 509da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_OFF: 510da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "off"; 511da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 512da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_AUTO: 513da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "auto"; 514da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 515da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_FT: 516da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "far_talk"; 517da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 518da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_CT: 519da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "close_talk"; 520da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 521da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 522da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent reply.add(key, value); 523da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 524da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 525da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return reply.toString(); 5262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic unsigned calculate_audpre_table_index(unsigned index) 5302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (index) { 5322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 48000: return SAMP_RATE_INDX_48000; 5332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 44100: return SAMP_RATE_INDX_44100; 5342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 32000: return SAMP_RATE_INDX_32000; 5352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 24000: return SAMP_RATE_INDX_24000; 5362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 22050: return SAMP_RATE_INDX_22050; 5372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 16000: return SAMP_RATE_INDX_16000; 5382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 12000: return SAMP_RATE_INDX_12000; 5392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 11025: return SAMP_RATE_INDX_11025; 5402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 8000: return SAMP_RATE_INDX_8000; 5412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: return -1; 5422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandsize_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 5452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (format != AudioSystem::PCM_16_BIT) { 5472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("getInputBufferSize bad format: %d", format); 5482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 5492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (channelCount < 1 || channelCount > 2) { 5512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("getInputBufferSize bad channel count: %d", channelCount); 5522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 5532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 555a4fe0167c6cad83d88b3bc56efa1ffad85b345b5Eric Laurent return AUDIO_KERNEL_PCM_IN_BUFFERSIZE*channelCount; 5562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic status_t set_volume_rpc(uint32_t volume) 5592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int fd = -1; 5612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 5622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 5632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl device\n"); 5642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 5652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland volume *= 20; //percentage 5672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Setting in-call volume to %d\n", volume); 5682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_SET_VOLUME, &volume)) { 5692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Cannot set volume on current device\n"); 5702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 5722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 5732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setVoiceVolume(float v) 5762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (v < 0.0) { 5782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 5792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland v = 0.0; 5802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (v > 1.0) { 5812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 5822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland v = 1.0; 5832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5853964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent int vol = lrint(v * VOICE_VOLUME_MAX); 5862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 588ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent if (mHACSetting && hac_enable && mCurSndDevice == (int) SND_DEVICE_HANDSET) { 589ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent LOGD("HAC enable: Setting in-call volume to maximum.\n"); 590ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent set_volume_rpc(VOICE_VOLUME_MAX); 591ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent } else { 592ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent LOGD("setVoiceVolume(%f)\n", v); 593ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent LOGI("Setting in-call volume to %d (available range is 0 to %d)\n", vol, VOICE_VOLUME_MAX); 594ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent set_volume_rpc(vol); //always set current device 595ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent } 5963964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent mVoiceVolume = vol; 5972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 5982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMasterVolume(float v) 6012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 6023964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent LOGI("Set master volume to %f.\n", v); 6032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // We return an error code here to let the audioflinger do in-software 6042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // volume on top of the maximum volume that we set through the SND API. 6052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // return error - software mixer will handle it 6062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 6082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6097fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivistatic status_t do_route_audio_dev_ctrl(uint32_t device, bool inCall, uint32_t rx_acdb_id, uint32_t tx_acdb_id) 6102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 6117fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t out_device = 0, mic_device = 0; 6127fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t path[2]; 6132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int fd = 0; 6142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == SND_DEVICE_CURRENT) 6162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Incall; 6172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // hack -- kernel needs to put these in include file 6192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Switching audio device to "); 6202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == SND_DEVICE_HANDSET) { 6212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HANDSET_SPKR; 6222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HANDSET_MIC; 6232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Handset"); 6242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if ((device == SND_DEVICE_BT) || (device == SND_DEVICE_BT_EC_OFF)) { 6252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = BT_SCO_SPKR; 6262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = BT_SCO_MIC; 6272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("BT Headset"); 628da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (device == SND_DEVICE_SPEAKER || 629da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent device == SND_DEVICE_SPEAKER_BACK_MIC) { 6302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = SPKR_PHONE_MONO; 6312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = SPKR_PHONE_MIC; 6322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Speakerphone"); 6332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_HEADSET) { 6342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HEADSET_SPKR_STEREO; 6352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 6362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo Headset"); 6372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_HEADSET_AND_SPEAKER) { 6382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = SPKR_PHONE_HEADSET_STEREO; 6392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 6402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo Headset + Speaker"); 64158cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi } else if (device == SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC) { 64258cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi out_device = SPKR_PHONE_HEADSET_STEREO; 64358cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi mic_device = SPKR_PHONE_MIC; 64458cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi LOGD("Stereo Headset + Speaker and back mic"); 6452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_NO_MIC_HEADSET) { 6462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HEADSET_SPKR_STEREO; 6472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HANDSET_MIC; 6482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("No microphone Wired Headset"); 649da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (device == SND_DEVICE_NO_MIC_HEADSET_BACK_MIC) { 650da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent out_device = HEADSET_SPKR_STEREO; 651da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mic_device = SPKR_PHONE_MIC; 652da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGD("No microphone Wired Headset and back mic"); 653da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (device == SND_DEVICE_HANDSET_BACK_MIC) { 654da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent out_device = HANDSET_SPKR; 655da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mic_device = SPKR_PHONE_MIC; 656da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGD("Handset and back mic"); 6572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_FM_HEADSET) { 6582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = FM_HEADSET; 6592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 6602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo FM headset"); 6612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_FM_SPEAKER) { 6622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = FM_SPKR; 6632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 6642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo FM speaker"); 665c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent } else if (device == SND_DEVICE_CARKIT) { 666c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent out_device = BT_SCO_SPKR; 667c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent mic_device = BT_SCO_MIC; 668c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent LOGD("Carkit"); 66917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (device == SND_DEVICE_TTY_FULL) { 67017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent out_device = TTY_HEADSET_SPKR; 67117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent mic_device = TTY_HEADSET_MIC; 67217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent LOGD("TTY FULL headset"); 67317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (device == SND_DEVICE_TTY_VCO) { 67417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent out_device = TTY_HEADSET_SPKR; 67517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent mic_device = HANDSET_MIC; 67617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent LOGD("TTY VCO headset"); 67717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } else if (device == SND_DEVICE_TTY_HCO) { 67817b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent out_device = SPKR_PHONE_MONO; 67917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent mic_device = TTY_HEADSET_MIC; 68017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent LOGD("TTY HCO headset"); 6812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 68217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent LOGE("unknown device %d", device); 68317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent return -1; 6842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#if 0 //Add for FM support 6872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (out_device == FM_HEADSET || 6882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device == FM_SPKR) { 6892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_fm_device < 0) { 6902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_fm_device = open("/dev/msm_htc_fm", O_RDWR); 6912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_fm_device < 0) { 6922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_htc_fm device"); 6932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Opened msm_htc_fm for FM radio"); 6962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (fd_fm_device >= 0) { 6982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_fm_device); 6992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_fm_device = -1; 7002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Closed msm_htc_fm after FM radio"); 7012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#endif 7032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 7052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 7062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl"); 7072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7097fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi path[0] = out_device; 7107fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi path[1] = rx_acdb_id; 7117fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (ioctl(fd, AUDIO_SWITCH_DEVICE, &path)) { 7122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot switch audio device"); 7132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 7142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7167fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi path[0] = mic_device; 7177fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi path[1] = tx_acdb_id; 7187fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (ioctl(fd, AUDIO_SWITCH_DEVICE, &path)) { 7192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot switch mic device"); 7202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 7212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7230f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent curr_out_device = out_device; 7240f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent curr_mic_device = mic_device; 7252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7262aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandIncall: 7272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (inCall == true && !voice_started) { 728f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (fd < 0) { 7292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 7302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 7322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl"); 7332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 736f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (rx_acdb_id == ACDB_ID_HAC_HANDSET_SPKR && 737f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev tx_acdb_id == ACDB_ID_HAC_HANDSET_MIC) { 738f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev path[0] = rx_acdb_id; 739f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev path[1] = tx_acdb_id; 740f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (ioctl(fd, AUDIO_START_VOICE, &path)) { 741f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGE("Cannot start voice"); 742f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev close(fd); 743f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return -1; 744f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 745f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } else { 746f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (ioctl(fd, AUDIO_START_VOICE, NULL)) { 747f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGE("Cannot start voice"); 748f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev close(fd); 749f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return -1; 750f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 7512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Voice Started!!"); 7532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland voice_started = 1; 7542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else if (inCall == false && voice_started) { 7562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 7572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 7582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 7602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl"); 7612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_STOP_VOICE, NULL)) { 7652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot stop voice"); 7662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 7672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 7682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Voice Stopped!!"); 7702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland voice_started = 0; 7712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 7742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 7752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 7762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// always call with mutex held 7792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doAudioRouteOrMute(uint32_t device) 7802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 7817fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t rx_acdb_id = 0; 7827fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t tx_acdb_id = 0; 7837fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi 784f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (support_a1026 == 1) 785f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi doAudience_A1026_Control(mMode, mRecordState, device); 786f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi 7872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == (uint32_t)SND_DEVICE_BT || device == (uint32_t)SND_DEVICE_CARKIT) { 7880f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!mBluetoothNrec) { 7892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland device = SND_DEVICE_BT_EC_OFF; 7902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7927fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi 793f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (mMode == AudioSystem::MODE_IN_CALL 794f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev && (device == (int) SND_DEVICE_BT 795f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev || device == (int) SND_DEVICE_BT_EC_OFF)) { 796f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (mBluetoothIdTx != 0) { 7972d319172300af10e139818ea367c4afc14c616f5Eric Laurent rx_acdb_id = mBluetoothIdRx; 7982d319172300af10e139818ea367c4afc14c616f5Eric Laurent tx_acdb_id = mBluetoothIdTx; 799c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent } else { 800c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent /* use default BT entry defined in AudioBTID.csv */ 801c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent rx_acdb_id = mBTEndpoints[0].rx; 802c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent tx_acdb_id = mBTEndpoints[0].tx; 803c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent LOGD("Update ACDB ID to default BT setting\n"); 804f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 805f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } else if (mMode == AudioSystem::MODE_IN_CALL 806f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev && device == (int) SND_DEVICE_CARKIT) { 807f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (mBluetoothIdTx != 0) { 808f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev rx_acdb_id = mBluetoothIdRx; 809f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev tx_acdb_id = mBluetoothIdTx; 810c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent } else { 811c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent /* use default carkit entry defined in AudioBTID.csv */ 812c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent rx_acdb_id = mBTEndpoints[1].rx; 813c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent tx_acdb_id = mBTEndpoints[1].tx; 814c9bee51bef9f5376838aa90e8c9c53f47265e54cEric Laurent LOGD("Update ACDB ID to default carkit setting"); 815f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 816f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } else if (mMode == AudioSystem::MODE_IN_CALL && hac_enable && mHACSetting) { 817f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGE("Update acdb id to hac profile."); 818f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev rx_acdb_id = ACDB_ID_HAC_HANDSET_SPKR; 819f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev tx_acdb_id = ACDB_ID_HAC_HANDSET_MIC; 820f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } else { 821f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (!checkOutputStandby() || mMode != AudioSystem::MODE_IN_CALL) 8227fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi rx_acdb_id = getACDB(MOD_PLAY, device); 8237fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (mRecordState) 8247fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi tx_acdb_id = getACDB(MOD_REC, device); 8257fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi } 8267fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi LOGV("doAudioRouteOrMute: rx acdb %d, tx acdb %d\n", rx_acdb_id, tx_acdb_id); 8277fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi 8287fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi return do_route_audio_dev_ctrl(device, mMode == AudioSystem::MODE_IN_CALL, rx_acdb_id, tx_acdb_id); 8292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_mMode(void) 8322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mMode; 8342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_mRoutes(void) 8372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mRoutes[mMode]; 8392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::set_mRecordState(bool onoff) 8422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRecordState = onoff; 8442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 8452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 847f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatus_t AudioHardware::get_batt_temp(int *batt_temp) 848f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev{ 849f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int fd, len; 850f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev const char *fn = 851ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent "/sys/devices/platform/ds2784-battery/power_supply/battery/temp"; 852f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev char get_batt_temp[6] = { 0 }; 853f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 854f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if ((fd = open(fn, O_RDONLY)) < 0) { 855f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGE("%s: cannot open %s: %s\n", __FUNCTION__, fn, strerror(errno)); 856f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return UNKNOWN_ERROR; 857f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 858f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 859f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if ((len = read(fd, get_batt_temp, sizeof(get_batt_temp))) <= 1) { 860f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGE("read battery temp fail: %s\n", strerror(errno)); 861f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev close(fd); 862f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return BAD_VALUE; 863f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 864f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 865f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev *batt_temp = strtol(get_batt_temp, NULL, 10); 866f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev close(fd); 867f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return NO_ERROR; 868f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev} 869f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 8702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doA1026_init(void) 8712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct a1026img fwimg; 8732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char char_tmp = 0; 87408516fe50b023532d5a3010050970de28e14621bIliyan Malchev unsigned char local_vpimg_buf[A1026_MAX_FW_SIZE], *ptr = local_vpimg_buf; 87508516fe50b023532d5a3010050970de28e14621bIliyan Malchev int rc = 0, fw_fd = -1; 87608516fe50b023532d5a3010050970de28e14621bIliyan Malchev ssize_t nr; 87708516fe50b023532d5a3010050970de28e14621bIliyan Malchev size_t remaining; 87808516fe50b023532d5a3010050970de28e14621bIliyan Malchev struct stat fw_stat; 8792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 88008516fe50b023532d5a3010050970de28e14621bIliyan Malchev static const char *const fn = "/system/etc/vpimg"; 88108516fe50b023532d5a3010050970de28e14621bIliyan Malchev static const char *const path = "/dev/audience_a1026"; 88208516fe50b023532d5a3010050970de28e14621bIliyan Malchev 88308516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (fd_a1026 < 0) 88408516fe50b023532d5a3010050970de28e14621bIliyan Malchev fd_a1026 = open(path, O_RDWR | O_NONBLOCK, 0); 8852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 88708516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGE("Cannot open %s %d\n", path, fd_a1026); 88808516fe50b023532d5a3010050970de28e14621bIliyan Malchev support_a1026 = 0; 88908516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto open_drv_err; 8902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 89208516fe50b023532d5a3010050970de28e14621bIliyan Malchev fw_fd = open(fn, O_RDONLY); 89308516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (fw_fd < 0) { 8942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Fail to open %s\n", fn); 8952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto ld_img_error; 8967fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi } else LOGI("open %s success\n", fn); 8972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 89808516fe50b023532d5a3010050970de28e14621bIliyan Malchev rc = fstat(fw_fd, &fw_stat); 89908516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (rc < 0) { 90008516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGE("Cannot stat file %s: %s\n", fn, strerror(errno)); 90108516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto ld_img_error; 90208516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 90308516fe50b023532d5a3010050970de28e14621bIliyan Malchev 90408516fe50b023532d5a3010050970de28e14621bIliyan Malchev remaining = (int)fw_stat.st_size; 9052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 90608516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGI("Firmware %s size %d\n", fn, remaining); 90708516fe50b023532d5a3010050970de28e14621bIliyan Malchev 90808516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (remaining > sizeof(local_vpimg_buf)) { 90908516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGE("File %s size %d exceeds internal limit %d\n", 91008516fe50b023532d5a3010050970de28e14621bIliyan Malchev fn, remaining, sizeof(local_vpimg_buf)); 91108516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto ld_img_error; 9122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 91408516fe50b023532d5a3010050970de28e14621bIliyan Malchev while (remaining) { 91508516fe50b023532d5a3010050970de28e14621bIliyan Malchev nr = read(fw_fd, ptr, remaining); 91608516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (nr < 0) { 91708516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGE("Error reading firmware: %s\n", strerror(errno)); 91808516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto ld_img_error; 91908516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 92008516fe50b023532d5a3010050970de28e14621bIliyan Malchev else if (!nr) { 92108516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (remaining) 92208516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGW("EOF reading firmware %s while %d bytes remain\n", 92308516fe50b023532d5a3010050970de28e14621bIliyan Malchev fn, remaining); 92408516fe50b023532d5a3010050970de28e14621bIliyan Malchev break; 92508516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 92608516fe50b023532d5a3010050970de28e14621bIliyan Malchev remaining -= nr; 92708516fe50b023532d5a3010050970de28e14621bIliyan Malchev ptr += nr; 92808516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 92908516fe50b023532d5a3010050970de28e14621bIliyan Malchev 93008516fe50b023532d5a3010050970de28e14621bIliyan Malchev close (fw_fd); 93108516fe50b023532d5a3010050970de28e14621bIliyan Malchev fw_fd = -1; 93208516fe50b023532d5a3010050970de28e14621bIliyan Malchev 9332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fwimg.buf = local_vpimg_buf; 93408516fe50b023532d5a3010050970de28e14621bIliyan Malchev fwimg.img_size = (int)(fw_stat.st_size - remaining); 93508516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGI("Total %d bytes put to user space buffer.\n", fwimg.img_size); 9362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland rc = ioctl(fd_a1026, A1026_BOOTUP_INIT, &fwimg); 9382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!rc) { 9392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("audience_a1026 init OK\n"); 9402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Init = 1; 9412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else 9422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("audience_a1026 init failed\n"); 9432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandld_img_error: 94508516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (fw_fd >= 0) 94608516fe50b023532d5a3010050970de28e14621bIliyan Malchev close(fw_fd); 9472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_a1026); 9482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandopen_drv_err: 9492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = -1; 9502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return rc; 9512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 9522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_snd_dev(void) 9542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 9552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 9567161d052ce69228825bd5deca3bfa4a213a99f06HK Chen return mCurSndDevice; 9572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 9582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9597fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Triviuint32_t AudioHardware::getACDB(int mode, int device) 9600f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent{ 9617fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t acdb_id = 0; 962f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int batt_temp = 0; 9630f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (mMode == AudioSystem::MODE_IN_CALL) { 9640f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGD("skip update ACDB due to in-call"); 9650f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return 0; 9660f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 9670f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 9687fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (mode == MOD_PLAY) { 9697fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi switch (device) { 9700f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HEADSET: 9710f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_NO_MIC_HEADSET: 972da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 9730f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_HEADSET: 9740f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_HEADSET_PLAYBACK; 9750f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 9760f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_SPEAKER: 9770f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_SPEAKER: 978da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_SPEAKER_BACK_MIC: 9790f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_SPKR_PLAYBACK; 980f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if(alt_enable) { 981f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGD("Enable ALT for speaker\n"); 982f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (get_batt_temp(&batt_temp)) { 983f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (batt_temp < 50) 984f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev acdb_id = ACDB_ID_ALT_SPKR_PLAYBACK; 985f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGD("ALT batt temp = %d\n", batt_temp); 986f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 987f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 9880f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 9890f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HEADSET_AND_SPEAKER: 99058cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 9910f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_HEADSET_RINGTONE_PLAYBACK; 9920f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 9930f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent default: 9940f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 9950f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 9967fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi } else if (mode == MOD_REC) { 9977fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi switch (device) { 9980f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HEADSET: 9990f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_HEADSET: 10000f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_SPEAKER: 100158cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 10020f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_EXT_MIC_REC; 10030f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10040f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HANDSET: 10050f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_NO_MIC_HEADSET: 10060f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_SPEAKER: 100708516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled == 0) { 100863af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi acdb_id = ACDB_ID_INT_MIC_REC; 100963af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi } else { 101063af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi acdb_id = ACDB_ID_INT_MIC_VR; 101163af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi } 101263af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi break; 1013da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_SPEAKER_BACK_MIC: 1014da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 1015da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_HANDSET_BACK_MIC: 101658cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 101763af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi acdb_id = ACDB_ID_CAMCORDER; 10180f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10190f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent default: 10200f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10210f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 10220f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 10237fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi LOGV("getACDB, return ID %d\n", acdb_id); 10247fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi return acdb_id; 10250f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent} 10260f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1027f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchevstatus_t AudioHardware::do_tpa2018_control(int mode) 1028f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev{ 1029f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (curr_out_device == HANDSET_SPKR || 1030f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev curr_out_device == SPKR_PHONE_MONO || 1031f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev curr_out_device == HEADSET_SPKR_STEREO || 1032f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev curr_out_device == SPKR_PHONE_HEADSET_STEREO || 1033f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev curr_out_device == FM_SPKR) { 1034f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1035f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int fd, rc; 1036f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev int retry = 3; 1037f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1038f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev switch (mode) { 1039f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev case AudioSystem::MODE_NORMAL: 1040f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mode = TPA2018_MODE_PLAYBACK; 1041f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev break; 1042f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev case AudioSystem::MODE_RINGTONE: 1043f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mode = TPA2018_MODE_RINGTONE; 1044f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev break; 1045f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev case AudioSystem::MODE_IN_CALL: 1046f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev mode = TPA2018_MODE_VOICE_CALL; 1047f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev break; 1048f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev default: 1049f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return 0; 1050f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 1051f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1052f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev fd = open("/dev/tpa2018d1", O_RDWR); 1053f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (fd < 0) { 1054f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGE("can't open /dev/tpa2018d1 %d", fd); 1055f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return -1; 1056f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 1057f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1058f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev do { 1059f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev rc = ioctl(fd, TPA2018_SET_MODE, &mode); 1060f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (!rc) 1061f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev break; 1062f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } while (--retry); 1063f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1064f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev if (rc < 0) { 1065f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGE("ioctl TPA2018_SET_MODE failed: %s", strerror(errno)); 1066f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } else 1067f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGD("Update TPA2018_SET_MODE to mode %d success", mode); 1068f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev 1069f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev close(fd); 1070f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev } 1071f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev return 0; 1072f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev} 10737fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi 10742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doAudience_A1026_Control(int Mode, bool Record, uint32_t Routes) 10752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 10762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int rc = 0; 10770f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int retry = 4; 10782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mA1026Init) { 10802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Audience A1026 not initialized.\n"); 10812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_INIT; 10822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 10852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = open("/dev/audience_a1026", O_RDWR); 10862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 10872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open audience_a1026 device (%d)\n", fd_a1026); 10882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 10892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.lock(); 10932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((Mode < AudioSystem::MODE_CURRENT) || (Mode >= AudioSystem::NUM_MODES)) { 10952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Illegal value: doAudience_A1026_Control(%d, %u, %u)", Mode, Record, Routes); 10962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.unlock(); 10972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 10982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (Mode == AudioSystem::MODE_IN_CALL) { 11012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (Record == 1) { 11022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 11032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HANDSET: 11042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_NO_MIC_HEADSET: 1105da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent //TODO: what do we do for camcorder when in call? 1106da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 1107da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_HANDSET_BACK_MIC: 110817b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case SND_DEVICE_TTY_VCO: 11099ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi if (enable1026) { 11104bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_RECEIVER; 111163af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_RECEIVER"); 11129ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi } else { 11139ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_NO_NS_RECEIVER; 11149ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_NO_NS_RECEIVER"); 11159ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi } 11169ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi break; 11179ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET: 11189ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 11199ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_FM_HEADSET: 11209ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_FM_SPEAKER: 11219ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 11224bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_HEADSET; 112363af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_HEADSET"); 11242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_SPEAKER: 1126da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent //TODO: what do we do for camcorder when in call? 1127da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_SPEAKER_BACK_MIC: 11284bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_SPEAKER; 112963af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_SPEAKER"); 11302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT: 11322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT_EC_OFF: 1133c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent case SND_DEVICE_CARKIT: 11344bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_BT; 113563af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_BT"); 11362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1137e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev case SND_DEVICE_TTY_HCO: 1138e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev case SND_DEVICE_TTY_FULL: 1139e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev new_pathid = A1026_PATH_INCALL_TTY; 1140e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev LOGV("A1026 control: new path is A1026_PATH_INCALL_TTY"); 1141e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev break; 11422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: 11432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 11462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 11472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HANDSET: 11482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_NO_MIC_HEADSET: 114917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case SND_DEVICE_TTY_VCO: 11509ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi if (enable1026) { 11519ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_RECEIVER; /* NS CT mode, Dual MIC */ 115263af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_RECEIVER"); 11539ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi } else { 11549ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_NO_NS_RECEIVER; 11559ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_NO_NS_RECEIVER"); 11569ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi } 11579ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi break; 11589ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET: 11599ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 11609ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_FM_HEADSET: 11619ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi case SND_DEVICE_FM_SPEAKER: 11622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_HEADSET; /* NS disable, Headset MIC */ 116363af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_HEADSET"); 11642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_SPEAKER: 11662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_SPEAKER; /* NS FT mode, Main MIC */ 116763af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_SPEAKER"); 11682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT: 11702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT_EC_OFF: 1171c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent case SND_DEVICE_CARKIT: 11722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_BT; /* QCOM NS, BT MIC */ 117363af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_BT"); 11742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1175e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev case SND_DEVICE_TTY_HCO: 1176e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev case SND_DEVICE_TTY_FULL: 1177e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev new_pathid = A1026_PATH_INCALL_TTY; 1178e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev LOGV("A1026 control: new path is A1026_PATH_INCALL_TTY"); 1179e7af7ee40e27869a0cbbe4a5c91cbe6719fdfd44Iliyan Malchev break; 11802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: 11812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 11822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (Record == 1) { 11852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 1186ba36d4fa33072ef14183365fffd289762c26905eJean-Michel Trivi case SND_DEVICE_SPEAKER: 1187ba36d4fa33072ef14183365fffd289762c26905eJean-Michel Trivi // default output is speaker, recording from phone mic, user RECEIVER configuration 1188739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HANDSET: 1189739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_NO_MIC_HEADSET: 119008516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled) { 1191739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (vr_uses_ns) { 11924bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NS_RECEIVER; 1193739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NS_RECEIVER"); 1194739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 11954bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NO_NS_RECEIVER; 1196739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_RECEIVER"); 1197739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1198739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 11999ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi new_pathid = A1026_PATH_RECORD_RECEIVER; /* INT-MIC Recording: NS disable, Main MIC */ 1200739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_RECORD_RECEIVER"); 1201739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 12022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1203739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HEADSET: 1204739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 1205739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_FM_HEADSET: 1206739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_FM_SPEAKER: 120708516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled) { 1208739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (vr_uses_ns) { 12094bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NS_HEADSET; 1210739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NS_HEADSET"); 1211739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 12124bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NO_NS_HEADSET; 1213739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_HEADSET"); 1214739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1215739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 1216739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi new_pathid = A1026_PATH_RECORD_HEADSET; /* EXT-MIC Recording: NS disable, Headset MIC */ 1217739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_RECORD_HEADSET"); 1218739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1219739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi break; 1220739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_SPEAKER_BACK_MIC: 1221739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 1222739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HANDSET_BACK_MIC: 122358cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 1224da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent new_pathid = A1026_PATH_CAMCORDER; /* CAM-Coder: NS FT mode, Back MIC */ 1225f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_CAMCORDER"); 12262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1227739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_BT: 1228739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_BT_EC_OFF: 1229c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent case SND_DEVICE_CARKIT: 123008516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled) { 1231739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (vr_uses_ns) { 12324bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NS_BT; 1233739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NS_BT"); 1234739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 12354bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NO_NS_BT; 1236739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_BT"); 1237739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1238739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 1239739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi new_pathid = A1026_PATH_RECORD_BT; /* BT MIC */ 1240739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_RECORD_BT"); 1241739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 12422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1243739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi default: 12442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 12452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else { 12482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_SUSPEND; 12492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (old_pathid != new_pathid) { 12522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland //LOGI("A1026: do ioctl(A1026_SET_CONFIG) to %d\n", new_pathid); 12530f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent do { 12540f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent rc = ioctl(fd_a1026, A1026_SET_CONFIG, &new_pathid); 12550f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!rc) { 12560f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent old_pathid = new_pathid; 12570f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 12580f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 12590f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } while (--retry); 12600f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 12610f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (rc < 0) { 12620f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("A1026 do hard reset to recover from error!\n"); 12630f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent rc = doA1026_init(); /* A1026 needs to do hard reset! */ 12640f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!rc) { 12652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland rc = ioctl(fd_a1026, A1026_SET_CONFIG, &new_pathid); 12662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!rc) 12672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland old_pathid = new_pathid; 12682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else 12690f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("A1026 Fatal Error!\n"); 12700f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } else 12710f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("A1026 Fatal Error: Re-init A1026 Failed\n"); 12720f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 12732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.unlock(); 12762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_a1026); 12772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = -1; 12782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return rc; 12802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doRouting(AudioStreamInMSM72xx *input) 12842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1285f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi Mutex::Autolock lock(mLock); 1286f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi uint32_t outputDevices = mOutput->devices(); 12872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t ret = NO_ERROR; 1288f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi int sndDevice = -1; 12892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 129017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if (mMode == AudioSystem::MODE_IN_CALL && mTTYMode != TTY_MODE_OFF) { 129117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) || 129217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) { 129317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent switch (mTTYMode) { 129417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case TTY_MODE_FULL: 129517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent sndDevice = SND_DEVICE_TTY_FULL; 129617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent break; 129717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case TTY_MODE_VCO: 129817b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent sndDevice = SND_DEVICE_TTY_VCO; 129917b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent break; 130017b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent case TTY_MODE_HCO: 130117b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent sndDevice = SND_DEVICE_TTY_HCO; 130217b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent break; 130317b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 130417b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 130517b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent } 130617b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent 130717b4d724c2d8f3b70ae94ab523f584940d1c175aEric Laurent if (sndDevice == -1 && input != NULL) { 1308f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi uint32_t inputDevice = input->devices(); 1309f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("do input routing device %x\n", inputDevice); 1310f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (inputDevice != 0) { 1311f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 1312f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Bluetooth PCM\n"); 1313f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_BT; 1314c42d5b9bd789034e4e10679b24a7bd38e68f4556Eric Laurent } else if (inputDevice & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 1315f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev LOGI("Routing audio to Bluetooth car kit\n"); 1316f92ef8fe452d3f8742d3aa680d1a443f571f028dIliyan Malchev sndDevice = SND_DEVICE_CARKIT; 1317f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 1318f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 1319956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 1320f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Wired Headset and Speaker\n"); 1321f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 1322956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } else { 1323f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Wired Headset\n"); 1324f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET; 1325f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 1326f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (inputDevice & AudioSystem::DEVICE_IN_BACK_MIC) { 132758cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi if (outputDevices & (AudioSystem:: DEVICE_OUT_WIRED_HEADSET) && 132858cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi (outputDevices & AudioSystem:: DEVICE_OUT_SPEAKER)) { 132958cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi LOGI("Routing audio to Wired Headset and Speaker with back mic\n"); 133058cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC; 133158cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 1332f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Speakerphone with back mic\n"); 1333f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_SPEAKER_BACK_MIC; 1334f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices == AudioSystem::DEVICE_OUT_EARPIECE) { 1335f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Handset with back mic\n"); 1336f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HANDSET_BACK_MIC; 1337f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 1338f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Headset with back mic\n"); 1339f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_NO_MIC_HEADSET_BACK_MIC; 1340f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 1341f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 1342f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 1343f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Speakerphone\n"); 1344f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_SPEAKER; 1345f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 1346f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Speakerphone\n"); 1347f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_NO_MIC_HEADSET; 1348f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 1349f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Handset\n"); 1350f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HANDSET; 1351956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1352956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1353956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1354f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi // if inputDevice == 0, restore output routing 1355f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 1356956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent 1357f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (sndDevice == -1) { 1358f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & (outputDevices - 1)) { 1359f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) { 1360f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGW("Hardware does not support requested route combination (%#X)," 1361f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi " picking closest possible route...", outputDevices); 1362956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1363f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 1364956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent 1365f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & 1366dd65e38951ed174f9d3d34886795438440f7eea0Eric Laurent (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { 1367f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Bluetooth PCM\n"); 1368f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_BT; 1369f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 1370f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Bluetooth PCM\n"); 1371f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_CARKIT; 1372f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 1373f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 1374f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Wired Headset and Speaker\n"); 1375956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 1376f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 1377f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 1378f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); 1379f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 1380956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } else { 1381f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); 1382f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_NO_MIC_HEADSET; 13832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1384f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 1385f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Wired Headset\n"); 1386f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET; 1387f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 1388f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Speakerphone\n"); 1389f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_SPEAKER; 1390f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 1391f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Handset\n"); 1392f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HANDSET; 13932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1394f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 13952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1396f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if ((vr_mode_change) || (sndDevice != -1 && sndDevice != mCurSndDevice)) { 1397f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi ret = doAudioRouteOrMute(sndDevice); 1398f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi mCurSndDevice = sndDevice; 13993964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent if (mMode == AudioSystem::MODE_IN_CALL) { 1400ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent if (mHACSetting && hac_enable && mCurSndDevice == (int) SND_DEVICE_HANDSET) { 1401ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent LOGD("HAC enable: Setting in-call volume to maximum.\n"); 1402ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent set_volume_rpc(VOICE_VOLUME_MAX); 1403ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent } else { 1404ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent set_volume_rpc(mVoiceVolume); 1405ec78ad65a1110fe007c3bdaba824f66bbfe522e3Eric Laurent } 14063964d4ed448b00791bc1b574913be24f44b45f0fEric Laurent } 14072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return ret; 14102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::checkMicMute() 14132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 14152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mMode != AudioSystem::MODE_IN_CALL) { 14162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland setMicMute_nosync(true); 14172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 14202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 14232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 14252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 14262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 14272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioHardware::dumpInternals\n"); 14282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 14292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 14312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 14332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14340f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snprintf(buffer, SIZE, "\tmBluetoothIdtx: %d\n", mBluetoothIdTx); 14350f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent result.append(buffer); 14360f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snprintf(buffer, SIZE, "\tmBluetoothIdrx: %d\n", mBluetoothIdRx); 14372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 14392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 14402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::dump(int fd, const Vector<String16>& args) 14432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland dumpInternals(fd, args); 14452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (size_t index = 0; index < mInputs.size(); index++) { 14462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs[index]->dump(fd, args); 14472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) { 14502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput->dump(fd, args); 14512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 14532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlanduint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) 14562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t i; 14582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t prevDelta; 14592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t delta; 14602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { 14622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delta = abs(sampleRate - inputSamplingRates[i]); 14632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (delta > prevDelta) break; 14642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // i is always > 0 here 14662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return inputSamplingRates[i-1]; 14672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 14702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14712aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 14722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0) 14732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::set( 14772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 14782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int lFormat = pFormat ? *pFormat : 0; 14802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t lChannels = pChannels ? *pChannels : 0; 14812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t lRate = pRate ? *pRate : 0; 14822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware = hw; 14842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // fix up defaults 14862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lFormat == 0) lFormat = format(); 14872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lChannels == 0) lChannels = channels(); 14882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lRate == 0) lRate = sampleRate(); 14892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // check values 14912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((lFormat != format()) || 14922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (lChannels != channels()) || 14932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (lRate != sampleRate())) { 14942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat) *pFormat = format(); 14952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels) *pChannels = channels(); 14962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate) *pRate = sampleRate(); 14972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 14982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat) *pFormat = lFormat; 15012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels) *pChannels = lChannels; 15022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate) *pRate = lRate; 15032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = devices; 15052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 15072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 15082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15092aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 15102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 15112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) close(mFd); 15122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 15132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 15152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 15162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 15172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_INIT; 15182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland size_t count = bytes; 15192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const uint8_t* p = static_cast<const uint8_t*>(buffer); 15202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mStandby) { 15222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // open driver 15242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("open pcm_out driver"); 15252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ::open("/dev/msm_pcm_out", O_RDWR); 15262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 15272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errCount++ < 10) { 15282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 15292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 15312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = status; 15332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // configuration 15352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get config"); 15362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct msm_audio_config config; 15372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 15382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 15392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot read pcm_out config"); 15402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 15412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set pcm_out config"); 15442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.channel_count = AudioSystem::popCount(channels()); 15452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.sample_rate = sampleRate(); 15462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_size = bufferSize(); 15472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 15482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.codec_type = CODEC_TYPE_PCM; 15492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 15502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 15512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot set config"); 15522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 15532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_size: %u", config.buffer_size); 15562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_count: %u", config.buffer_count); 15572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("channel_count: %u", config.channel_count); 15582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("sample_rate: %u", config.sample_rate); 15592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15607fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t acdb_id = mHardware->getACDB(MOD_PLAY, mHardware->get_snd_dev()); 15617fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi status = ioctl(mFd, AUDIO_START, &acdb_id); 156231923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen if (status < 0) { 156331923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen LOGE("Cannot start pcm playback"); 156431923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen goto Error; 15652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 156610254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi 156710254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi status = ioctl(mFd, AUDIO_SET_VOLUME, &stream_volume); 156810254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi if (status < 0) { 156910254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi LOGE("Cannot start pcm playback"); 157010254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi goto Error; 157110254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi } 157210254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi 15735d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks LOGV("acquire wakelock"); 15745d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks acquire_wake_lock(PARTIAL_WAKE_LOCK, kOutputWakelockStr); 157531923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen mStandby = false; 15762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland while (count) { 15792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t written = ::write(mFd, p, count); 15802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (written >= 0) { 15812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland count -= written; 15822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland p += written; 15832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 15842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errno != EAGAIN) return written; 15852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRetryCount++; 15862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("EAGAIN - retry"); 15872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return bytes; 15912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15922aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandError: 15932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 15942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 15952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 15962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // Simulate audio output timing in case of error 15982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland usleep(bytes * 1000000 / frameSize() / sampleRate()); 15992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 16012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::standby() 16042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 16062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mStandby && mFd >= 0) { 16072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 16082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 16095d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks LOGV("release wakelock"); 16105d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks release_wake_lock(kOutputWakelockStr); 16112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mStandby = true; 16132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("AudioHardware pcm playback is going to standby."); 16142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 16152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 16182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 16202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 16212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 16222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioStreamOutMSM72xx::dump\n"); 16232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 16242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 16262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 16282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 16302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 16322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 16342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 16362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 16382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 16402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 16422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 16432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandbool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 16462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mStandby; 16482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) 16522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 16542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 16552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 16562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int device; 16572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); 16582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.getInt(key, device) == NO_ERROR) { 16602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = device; 16612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set output routing %x", mDevices); 16622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = mHardware->doRouting(NULL); 16632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.remove(key); 16642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.size()) { 16672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 16682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 16702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16722aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) 16732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keys); 16752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 16762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 16772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 16792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get routing %x", mDevices); 16802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.addInt(key, (int)mDevices); 16812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); 16842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return param.toString(); 16852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 16892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16902aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 16912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), 16922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), 1693a4fe0167c6cad83d88b3bc56efa1ffad85b345b5Eric Laurent mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_KERNEL_PCM_IN_BUFFERSIZE), 16942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) 16952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::set( 16992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, 17002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioSystem::audio_in_acoustics acoustic_flags) 17012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 17022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) { 17032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pFormat = AUDIO_HW_IN_FORMAT; 17042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 17052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate == 0) { 17072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 17082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t rate = hw->getInputSampleRate(*pRate); 17102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (rate != *pRate) { 17112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pRate = rate; 17122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 17132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO && 17162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels != AudioSystem::CHANNEL_IN_STEREO)) { 17172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AUDIO_HW_IN_CHANNELS; 17182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 17192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware = hw; 17222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); 17242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 17252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Audio record already open"); 17262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -EPERM; 17272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // open audio input device 17302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 17312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 17322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 17332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 17342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = status; 17362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // configuration 17382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get config"); 17392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct msm_audio_config config; 17402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 17412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 17422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot read config"); 17432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 17442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set config"); 17472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.channel_count = AudioSystem::popCount(*pChannels); 17482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.sample_rate = *pRate; 17492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_size = bufferSize(); 17502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_count = 2; 17512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.codec_type = CODEC_TYPE_PCM; 17522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 17532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 17542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot set config"); 17552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) { 17562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (config.channel_count == 1) { 17572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AudioSystem::CHANNEL_IN_MONO; 17582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 17592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AudioSystem::CHANNEL_IN_STEREO; 17602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pRate = config.sample_rate; 17622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 17642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("confirm config"); 17672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 17682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 17692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot read config"); 17702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 17712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_size: %u", config.buffer_size); 17732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_count: %u", config.buffer_count); 17742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("channel_count: %u", config.channel_count); 17752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("sample_rate: %u", config.sample_rate); 17762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = devices; 17782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFormat = AUDIO_HW_IN_FORMAT; 17792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mChannels = *pChannels; 17802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mSampleRate = config.sample_rate; 17812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBufferSize = config.buffer_size; 17822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland //mHardware->setMicMute_nosync(false); 17842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mState = AUDIO_INPUT_OPENED; 17852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 17872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17882aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandError: 17892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 17902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 17912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 17922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 17942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 17952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17962aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 17972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 17982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx destructor"); 17992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland standby(); 18002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 18012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 18032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 18042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 18052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mHardware) return -1; 18062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland size_t count = bytes; 18082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint8_t* p = static_cast<uint8_t*>(buffer); 18092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mState < AUDIO_INPUT_OPENED) { 18112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mHardware->mLock); 18122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) { 18132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 18142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18170f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (mState < AUDIO_INPUT_STARTED) { 18182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware->set_mRecordState(1); 1819956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent if (support_a1026 == 1) { 1820956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent mHardware->doAudience_A1026_Control(mHardware->get_mMode(), 1, mHardware->get_snd_dev()); 18212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18227fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi uint32_t acdb_id = mHardware->getACDB(MOD_REC, mHardware->get_snd_dev()); 18237fbea5ceecbfb87b9210f6e4ee08191ed1352addJean-Michel Trivi if (ioctl(mFd, AUDIO_START, &acdb_id)) { 18242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Error starting record"); 18252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 18262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("AUDIO_START: start kernel pcm_in driver."); 18282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mState = AUDIO_INPUT_STARTED; 18292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland while (count) { 18322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t bytesRead = ::read(mFd, buffer, count); 18332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (bytesRead >= 0) { 18342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland count -= bytesRead; 18352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland p += bytesRead; 18362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 18372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errno != EAGAIN) return bytesRead; 18382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRetryCount++; 18392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("EAGAIN - retrying"); 18402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return bytes; 18432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 18442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::standby() 18462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1847956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent if (mHardware) { 18482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware->set_mRecordState(0); 18490f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (support_a1026 == 1) { 1850956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent mHardware->doAudience_A1026_Control(mHardware->get_mMode(), 0, mHardware->get_snd_dev()); 18512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mHardware) return -1; 18552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mState > AUDIO_INPUT_CLOSED) { 18562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 18572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 18582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 18592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland //mHardware->checkMicMute(); 18612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mState = AUDIO_INPUT_CLOSED; 18622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 18632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("AudioHardware PCM record is going to standby."); 18642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 18652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 18662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 18682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 18692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 18702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 18712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 18722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioStreamInMSM72xx::dump\n"); 18732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 18742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 18752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 18762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 18772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 18782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 18792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 18802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 18812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 18822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 18832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 18842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 18852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmState: %d\n", mState); 18862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 18872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 18882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 18892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 18902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 18912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 18922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 18932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs) 18942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 18952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 18962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 18972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int device; 1898255bdedb2d7ebf4b14690776ff652df1de97fe95Eric Laurent String8 key = String8(KEY_A1026_VR_MODE); 1899739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi int enabled; 19002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string()); 19012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1902739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // reading voice recognition mode parameter 1903255bdedb2d7ebf4b14690776ff652df1de97fe95Eric Laurent if (param.getInt(key, enabled) == NO_ERROR) { 190408516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGV("set vr_mode_enabled to %d", enabled); 190508516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_change = (vr_mode_enabled != enabled); 19069ffa86825c57c8bf82669b438bd0e8feb865d4b7Jean-Michel Trivi vr_mode_enabled = enabled; 1907739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi param.remove(key); 1908739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1909739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 1910739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // reading routing parameter 1911255bdedb2d7ebf4b14690776ff652df1de97fe95Eric Laurent key = String8(AudioParameter::keyRouting); 19122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.getInt(key, device) == NO_ERROR) { 19132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set input routing %x", device); 19142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device & (device - 1)) { 19152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 19162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 19172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = device; 19182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = mHardware->doRouting(this); 19192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 19202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.remove(key); 19212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 19222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.size()) { 19242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 19252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 19262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 19272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 19282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19292aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys) 19302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 19312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keys); 19322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 19332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 19342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 19362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get routing %x", mDevices); 19372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.addInt(key, (int)mDevices); 19382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 19392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string()); 19412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return param.toString(); 19422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 19432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 19452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandextern "C" AudioHardwareInterface* createAudioHardware(void) { 19472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return new AudioHardware(); 19482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 19492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 19502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland}; // namespace android 1951