AudioHardware.cpp revision 58cf88a5a91d82ae2fb3e23365eaa4524a9cd089
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" 422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include "a1026.h" 432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#define LOG_SND_RPC 0 // Set to 1 to log sound RPC's 462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#define TX_PATH (1) 472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_CURRENT = 256; 492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HANDSET = 0; 502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_SPEAKER = 1; 512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_BT = 3; 522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_CARKIT = 4; 532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_BT_EC_OFF = 45; 542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HEADSET = 2; 552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER = 10; 562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_FM_HEADSET = 9; 572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_FM_SPEAKER = 11; 582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_NO_MIC_HEADSET = 8; 592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_TTY_FULL = 5; 60da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurentstatic const uint32_t SND_DEVICE_HANDSET_BACK_MIC = 20; 61da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurentstatic const uint32_t SND_DEVICE_SPEAKER_BACK_MIC = 21; 62da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurentstatic const uint32_t SND_DEVICE_NO_MIC_HEADSET_BACK_MIC = 28; 6358cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivistatic const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC = 30; 642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandnamespace android { 652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int support_a1026 = 1; 662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int fd_a1026 = -1; 672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int old_pathid = -1; 682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int new_pathid = -1; 690f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatic int curr_out_device = -1; 700f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatic int curr_mic_device = -1; 712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int voice_started = 0; 722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int fd_fm_device = -1; 7310254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivistatic int stream_volume = -300; 74739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi// use VR mode on inputs: 1 == VR mode enabled when selected, 0 = VR mode disabled when selected 7508516fe50b023532d5a3010050970de28e14621bIliyan Malchevstatic int vr_mode_enabled; 76739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivistatic bool vr_mode_change = false; 77739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivistatic int vr_uses_ns = 0; 78739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivistatic int enable1026 = 1; 7910254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi 802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandint errCount = 0; 810f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatic void * acoustic; 822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandconst uint32_t AudioHardware::inputSamplingRates[] = { 832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland}; 855d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks 865d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks// ID string for audio wakelock 875d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparksstatic const char kOutputWakelockStr[] = "AudioHardwareQSD"; 885d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks 892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 912aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioHardware() : 920f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mA1026Init(false), mInit(false), mMicMute(true), 930f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothNrec(true), mBluetoothIdTx(0), 94da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mBluetoothIdRx(0), mOutput(0), 95da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mNoiseSuppressionState(A1026_NS_STATE_AUTO) 962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 970f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int (*snd_get_num)(); 980f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int (*snd_get_bt_endpoint)(msm_bt_endpoint *); 990f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int (*set_acoustic_parameters)(); 1000f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1010f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent struct msm_bt_endpoint *ept; 1020f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland doA1026_init(); 1040f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1050f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acoustic =:: dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW); 1060f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (acoustic == NULL ) { 1070f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not open libhtc_acoustic.so"); 1080f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent /* this is not really an error on non-htc devices... */ 1090f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mNumBTEndpoints = 0; 1100f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mInit = true; 1110f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return; 1120f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1130f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters"); 1140f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if ((*set_acoustic_parameters) == 0 ) { 1150f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not open set_acoustic_parameters()"); 1160f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return; 1170f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1180f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1190f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int rc = set_acoustic_parameters(); 1200f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (rc < 0) { 1210f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not set acoustic parameters to share memory: %d", rc); 1220f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1230f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1240f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num"); 1250f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if ((*snd_get_num) == 0 ) { 1260f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not open snd_get_num()"); 1270f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1280f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1290f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mNumBTEndpoints = snd_get_num(); 1300f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGD("mNumBTEndpoints = %d", mNumBTEndpoints); 1310f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBTEndpoints = new msm_bt_endpoint[mNumBTEndpoints]; 1320f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mInit = true; 1330f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGV("constructed %d SND endpoints)", mNumBTEndpoints); 1340f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent ept = mBTEndpoints; 1350f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snd_get_bt_endpoint = (int (*)(msm_bt_endpoint *))::dlsym(acoustic, "snd_get_bt_endpoint"); 1360f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if ((*snd_get_bt_endpoint) == 0 ) { 1370f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Could not open snd_get_bt_endpoint()"); 1380f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return; 1390f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1400f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snd_get_bt_endpoint(mBTEndpoints); 1410f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 1420f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent for (int i = 0; i < mNumBTEndpoints; i++) { 1430f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("BT name %s (tx,rx)=(%d,%d)", mBTEndpoints[i].name, mBTEndpoints[i].tx, mBTEndpoints[i].rx); 1440f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 1450f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 146d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent // reset voice mode in case media_server crashed and restarted while in call 147d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent int fd = open("/dev/msm_audio_ctl", O_RDWR); 148d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent if (fd >= 0) { 149d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent ioctl(fd, AUDIO_STOP_VOICE, NULL); 150d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent close(fd); 151d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent } 152d1dc8c30a969ec3539fc21b940789b2f23197756Eric Laurent 153739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi vr_mode_change = false; 15408516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_enabled = 0; 155739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi enable1026 = 1; 156739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi char value[PROPERTY_VALUE_MAX]; 157739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // Check the system property to enable or not the special recording modes 158739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi property_get("media.a1026.enableA1026", value, "1"); 159739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi enable1026 = atoi(value); 160739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("Enable mode selection for A1026 is %d", enable1026); 161739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // Check the system property for which VR mode to use 162739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi property_get("media.a1026.nsForVoiceRec", value, "0"); 163739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi vr_uses_ns = atoi(value); 164739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("Using Noise Suppression for Voice Rec is %d", vr_uses_ns); 165739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 1662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInit = true; 1672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 1682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1692aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::~AudioHardware() 1702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (size_t index = 0; index < mInputs.size(); index++) { 1722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland closeInputStream((AudioStreamIn*)mInputs[index]); 1732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.clear(); 1752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland closeOutputStream((AudioStreamOut*)mOutput); 1762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInit = false; 1772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 1782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::initCheck() 1802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mInit ? NO_ERROR : NO_INIT; 1822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 1832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1842aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioStreamOut* AudioHardware::openOutputStream( 1852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status) 1862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland { // scope for the lock 1882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 1892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // only one output stream allowed 1912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) { 1922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 1932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = INVALID_OPERATION; 1942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 1962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // create new output stream 1992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 2002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t lStatus = out->set(this, devices, format, channels, sampleRate); 2012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 2022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = lStatus; 2032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lStatus == NO_ERROR) { 2052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput = out; 2062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 2072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete out; 2082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mOutput; 2112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandvoid AudioHardware::closeOutputStream(AudioStreamOut* out) { 2142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 2152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput == 0 || mOutput != out) { 2162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Attempt to close invalid output stream"); 2172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else { 2192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete mOutput; 2202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput = 0; 2212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2242aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioStreamIn* AudioHardware::openInputStream( 2252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status, 2262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioSystem::audio_in_acoustics acoustic_flags) 2272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // check for valid input source 2292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) { 2302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 2312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.lock(); 2342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 2362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t lStatus = in->set(this, devices, format, channels, sampleRate, acoustic_flags); 2372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 2382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = lStatus; 2392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lStatus != NO_ERROR) { 2412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 2422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete in; 2432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 2442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.add(in); 2472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 2482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return in; 2502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandvoid AudioHardware::closeInputStream(AudioStreamIn* in) { 2532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 2542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t index = mInputs.indexOf((AudioStreamInMSM72xx *)in); 2562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (index < 0) { 2572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Attempt to close invalid input stream"); 2582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 2592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 2602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete mInputs[index]; 2612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.lock(); 2622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.removeAt(index); 2632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMode(int mode) 2672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 268739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // VR mode is never used in a call and must be cleared when entering the IN_CALL mode 269739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (mode == AudioSystem::MODE_IN_CALL) { 27008516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_enabled = 0; 271739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 272739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 2732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = AudioHardwareBase::setMode(mode); 2742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status == NO_ERROR) { 2752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // make sure that doAudioRouteOrMute() is called by doRouting() 2762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // even if the new device selected is the same as current one. 2772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mCurSndDevice = -1; 2782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 2802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandbool AudioHardware::checkOutputStandby() 2832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) 2852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mOutput->checkStandby()) 2862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return false; 2872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return true; 2892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2903cb8864598e72c04859f410bb03f242cf3965dbeHK Chenstatic status_t set_mic_mute(bool _mute) 2912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2923cb8864598e72c04859f410bb03f242cf3965dbeHK Chen uint32_t mute = _mute; 2933cb8864598e72c04859f410bb03f242cf3965dbeHK Chen int fd = -1; 2942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 2952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 2962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl device\n"); 2972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 2982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Setting mic mute to %d\n", mute); 3003cb8864598e72c04859f410bb03f242cf3965dbeHK Chen if (ioctl(fd, AUDIO_SET_MUTE, &mute)) { 3012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot set mic mute on current device\n"); 3022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 3032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 3042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 3062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMicMute(bool state) 3102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 3122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return setMicMute_nosync(state); 3132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// always call with mutex held 3162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMicMute_nosync(bool state) 3172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mMicMute != state) { 3192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mMicMute = state; 3202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return set_mic_mute(mMicMute); //always set current TX device 3212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::getMicMute(bool* state) 3262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *state = mMicMute; 3282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setParameters(const String8& keyValuePairs) 3322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 3342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 3352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key; 3362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NREC_KEY[] = "bt_headset_nrec"; 3372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NAME_KEY[] = "bt_headset_name"; 3382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NREC_VALUE_ON[] = "on"; 3392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("setParameters() %s", keyValuePairs.string()); 3422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (keyValuePairs.length() == 0) return BAD_VALUE; 3442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland key = String8(BT_NREC_KEY); 3462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 3472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (value == BT_NREC_VALUE_ON) { 3482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothNrec = true; 3492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 3502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothNrec = false; 3512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Turning noise reduction and echo cancellation off for BT " 3522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland "headset"); 3532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland key = String8(BT_NAME_KEY); 3562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 3570f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdTx = 0; 3580f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdRx = 0; 3590f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent for (int i = 0; i < mNumBTEndpoints; i++) { 3600f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!strcasecmp(value.string(), mBTEndpoints[i].name)) { 3610f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdTx = mBTEndpoints[i].tx; 3620f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mBluetoothIdRx = mBTEndpoints[i].rx; 3632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Using custom acoustic parameters for %s", value.string()); 3642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 3652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3670f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (mBluetoothIdTx == 0) { 3682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Using default acoustic parameters " 3692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland "(%s not in acoustic database)", value.string()); 3702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3710f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent doRouting(NULL); 3722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 373da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent key = String8("noise_suppression"); 374da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (param.get(key, value) == NO_ERROR) { 375da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (support_a1026 == 1) { 376da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent int noiseSuppressionState; 377da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (value == "off") { 378da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_OFF; 379da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (value == "auto") { 380da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_AUTO; 381da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (value == "far_talk") { 382da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_FT; 383da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (value == "close_talk") { 384da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent noiseSuppressionState = A1026_NS_STATE_CT; 385da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else { 386da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return BAD_VALUE; 387da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 388da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 389da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (noiseSuppressionState != mNoiseSuppressionState) { 390da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (!mA1026Init) { 391da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGW("Audience A1026 not initialized.\n"); 392da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return INVALID_OPERATION; 393da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 394da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 395da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (fd_a1026 < 0) { 396da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent fd_a1026 = open("/dev/audience_a1026", O_RDWR); 397da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (fd_a1026 < 0) { 398da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGE("Cannot open audience_a1026 device (%d)\n", fd_a1026); 399da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return -1; 400da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 401da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 402da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGV("Setting noise suppression %s", value.string()); 403da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mA1026Lock.lock(); 404da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent int rc = ioctl(fd_a1026, A1026_SET_NS_STATE, &noiseSuppressionState); 405da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (!rc) { 406da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mNoiseSuppressionState = noiseSuppressionState; 407da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else { 408da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGE("Failed to set noise suppression %s", value.string()); 409da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 410da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mA1026Lock.unlock(); 411da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 412da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else { 413da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return INVALID_OPERATION; 414da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 415da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 416da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 4172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 4182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 4192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4202aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::getParameters(const String8& keys) 4212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 422da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent AudioParameter request = AudioParameter(keys); 423da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent AudioParameter reply = AudioParameter(); 424da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent String8 value; 425da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent String8 key; 426da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 427da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGV("getParameters() %s", keys.string()); 428da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 429da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent key = "noise_suppression"; 430da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent if (request.get(key, value) == NO_ERROR) { 431da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent switch(mNoiseSuppressionState) { 432da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_OFF: 433da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "off"; 434da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 435da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_AUTO: 436da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "auto"; 437da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 438da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_FT: 439da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "far_talk"; 440da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 441da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case A1026_NS_STATE_CT: 442da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent value = "close_talk"; 443da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent break; 444da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 445da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent reply.add(key, value); 446da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } 447da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent 448da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent return reply.toString(); 4492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 4502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic unsigned calculate_audpre_table_index(unsigned index) 4532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 4542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (index) { 4552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 48000: return SAMP_RATE_INDX_48000; 4562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 44100: return SAMP_RATE_INDX_44100; 4572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 32000: return SAMP_RATE_INDX_32000; 4582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 24000: return SAMP_RATE_INDX_24000; 4592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 22050: return SAMP_RATE_INDX_22050; 4602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 16000: return SAMP_RATE_INDX_16000; 4612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 12000: return SAMP_RATE_INDX_12000; 4622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 11025: return SAMP_RATE_INDX_11025; 4632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 8000: return SAMP_RATE_INDX_8000; 4642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: return -1; 4652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 4672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandsize_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 4682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 4692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (format != AudioSystem::PCM_16_BIT) { 4702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("getInputBufferSize bad format: %d", format); 4712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 4722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (channelCount < 1 || channelCount > 2) { 4742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("getInputBufferSize bad channel count: %d", channelCount); 4752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 4762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 2048*channelCount; 4792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 4802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic status_t set_volume_rpc(uint32_t volume) 4822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 4832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int fd = -1; 4842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 4852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 4862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl device\n"); 4872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland volume *= 20; //percentage 4902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Setting in-call volume to %d\n", volume); 4912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_SET_VOLUME, &volume)) { 4922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Cannot set volume on current device\n"); 4932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 4952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 4962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 4972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setVoiceVolume(float v) 4992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (v < 0.0) { 5012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 5022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland v = 0.0; 5032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (v > 1.0) { 5042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 5052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland v = 1.0; 5062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int vol = lrint(v * 5.0); 5092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("setVoiceVolume(%f)\n", v); 5102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol); 5112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 5132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland set_volume_rpc(vol); //always set current device 5142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 5152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMasterVolume(float v) 5182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 5202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int vol = ceil(v * 5.0); 5212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Set master volume to %d.\n", vol); 5222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // We return an error code here to let the audioflinger do in-software 5232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // volume on top of the maximum volume that we set through the SND API. 5242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // return error - software mixer will handle it 5252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 5262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic status_t do_route_audio_dev_ctrl(uint32_t device, bool inCall) 5292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int out_device = 0, mic_device = 0; 5312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int fd = 0; 5322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == SND_DEVICE_CURRENT) 5342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Incall; 5352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // hack -- kernel needs to put these in include file 5372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Switching audio device to "); 5382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == SND_DEVICE_HANDSET) { 5392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HANDSET_SPKR; 5402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HANDSET_MIC; 5412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Handset"); 5422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if ((device == SND_DEVICE_BT) || (device == SND_DEVICE_BT_EC_OFF)) { 5432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = BT_SCO_SPKR; 5442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = BT_SCO_MIC; 5452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("BT Headset"); 546da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (device == SND_DEVICE_SPEAKER || 547da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent device == SND_DEVICE_SPEAKER_BACK_MIC) { 5482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = SPKR_PHONE_MONO; 5492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = SPKR_PHONE_MIC; 5502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Speakerphone"); 5512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_HEADSET) { 5522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HEADSET_SPKR_STEREO; 5532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 5542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo Headset"); 5552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_HEADSET_AND_SPEAKER) { 5562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = SPKR_PHONE_HEADSET_STEREO; 5572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 5582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo Headset + Speaker"); 55958cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi } else if (device == SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC) { 56058cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi out_device = SPKR_PHONE_HEADSET_STEREO; 56158cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi mic_device = SPKR_PHONE_MIC; 56258cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi LOGD("Stereo Headset + Speaker and back mic"); 5632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_NO_MIC_HEADSET) { 5642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HEADSET_SPKR_STEREO; 5652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HANDSET_MIC; 5662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("No microphone Wired Headset"); 567da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (device == SND_DEVICE_NO_MIC_HEADSET_BACK_MIC) { 568da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent out_device = HEADSET_SPKR_STEREO; 569da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mic_device = SPKR_PHONE_MIC; 570da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGD("No microphone Wired Headset and back mic"); 571da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent } else if (device == SND_DEVICE_HANDSET_BACK_MIC) { 572da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent out_device = HANDSET_SPKR; 573da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent mic_device = SPKR_PHONE_MIC; 574da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent LOGD("Handset and back mic"); 5752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_FM_HEADSET) { 5762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = FM_HEADSET; 5772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 5782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo FM headset"); 5792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_FM_SPEAKER) { 5802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = FM_SPKR; 5812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 5822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo FM speaker"); 5832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 5842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("unknown device %d", device); 5852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 5862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#if 0 //Add for FM support 5892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (out_device == FM_HEADSET || 5902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device == FM_SPKR) { 5912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_fm_device < 0) { 5922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_fm_device = open("/dev/msm_htc_fm", O_RDWR); 5932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_fm_device < 0) { 5942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_htc_fm device"); 5952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 5962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Opened msm_htc_fm for FM radio"); 5982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (fd_fm_device >= 0) { 6002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_fm_device); 6012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_fm_device = -1; 6022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Closed msm_htc_fm after FM radio"); 6032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#endif 6052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 6072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 6082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl"); 6092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_SWITCH_DEVICE, &out_device)) { 6122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot switch audio device"); 6132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 6142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_SWITCH_DEVICE, &mic_device)) { 6172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot switch mic device"); 6182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 6192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6210f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent curr_out_device = out_device; 6220f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent curr_mic_device = mic_device; 6232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6242aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandIncall: 6252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (inCall == true && !voice_started) { 6262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 6272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 6282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 6302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl"); 6312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_START_VOICE, NULL)) { 6352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot start voice"); 6362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 6372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Voice Started!!"); 6402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland voice_started = 1; 6412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else if (inCall == false && voice_started) { 6432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 6442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 6452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 6472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl"); 6482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_STOP_VOICE, NULL)) { 6522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot stop voice"); 6532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 6542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Voice Stopped!!"); 6572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland voice_started = 0; 6582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 6612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 6622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 6632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// always call with mutex held 6662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doAudioRouteOrMute(uint32_t device) 6672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 668f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (support_a1026 == 1) 669f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi doAudience_A1026_Control(mMode, mRecordState, device); 670f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi 6712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == (uint32_t)SND_DEVICE_BT || device == (uint32_t)SND_DEVICE_CARKIT) { 6720f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!mBluetoothNrec) { 6732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland device = SND_DEVICE_BT_EC_OFF; 6742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return do_route_audio_dev_ctrl(device, mMode == AudioSystem::MODE_IN_CALL); 6772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 6782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_mMode(void) 6802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 6812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mMode; 6822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 6832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_mRoutes(void) 6852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 6862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mRoutes[mMode]; 6872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 6882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::set_mRecordState(bool onoff) 6902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 6912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRecordState = onoff; 6922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 6932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 6942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doA1026_init(void) 6962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 6972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct a1026img fwimg; 6982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char char_tmp = 0; 69908516fe50b023532d5a3010050970de28e14621bIliyan Malchev unsigned char local_vpimg_buf[A1026_MAX_FW_SIZE], *ptr = local_vpimg_buf; 70008516fe50b023532d5a3010050970de28e14621bIliyan Malchev int rc = 0, fw_fd = -1; 70108516fe50b023532d5a3010050970de28e14621bIliyan Malchev ssize_t nr; 70208516fe50b023532d5a3010050970de28e14621bIliyan Malchev size_t remaining; 70308516fe50b023532d5a3010050970de28e14621bIliyan Malchev struct stat fw_stat; 7042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 70508516fe50b023532d5a3010050970de28e14621bIliyan Malchev static const char *const fn = "/system/etc/vpimg"; 70608516fe50b023532d5a3010050970de28e14621bIliyan Malchev static const char *const path = "/dev/audience_a1026"; 70708516fe50b023532d5a3010050970de28e14621bIliyan Malchev 70808516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (fd_a1026 < 0) 70908516fe50b023532d5a3010050970de28e14621bIliyan Malchev fd_a1026 = open(path, O_RDWR | O_NONBLOCK, 0); 7102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 71208516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGE("Cannot open %s %d\n", path, fd_a1026); 71308516fe50b023532d5a3010050970de28e14621bIliyan Malchev support_a1026 = 0; 71408516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto open_drv_err; 7152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 71708516fe50b023532d5a3010050970de28e14621bIliyan Malchev fw_fd = open(fn, O_RDONLY); 71808516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (fw_fd < 0) { 7192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Fail to open %s\n", fn); 7202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto ld_img_error; 721956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } else LOGI("open a1026 firmware success\n"); 7222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 72308516fe50b023532d5a3010050970de28e14621bIliyan Malchev rc = fstat(fw_fd, &fw_stat); 72408516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (rc < 0) { 72508516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGE("Cannot stat file %s: %s\n", fn, strerror(errno)); 72608516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto ld_img_error; 72708516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 72808516fe50b023532d5a3010050970de28e14621bIliyan Malchev 72908516fe50b023532d5a3010050970de28e14621bIliyan Malchev remaining = (int)fw_stat.st_size; 7302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 73108516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGI("Firmware %s size %d\n", fn, remaining); 73208516fe50b023532d5a3010050970de28e14621bIliyan Malchev 73308516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (remaining > sizeof(local_vpimg_buf)) { 73408516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGE("File %s size %d exceeds internal limit %d\n", 73508516fe50b023532d5a3010050970de28e14621bIliyan Malchev fn, remaining, sizeof(local_vpimg_buf)); 73608516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto ld_img_error; 7372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 73908516fe50b023532d5a3010050970de28e14621bIliyan Malchev while (remaining) { 74008516fe50b023532d5a3010050970de28e14621bIliyan Malchev nr = read(fw_fd, ptr, remaining); 74108516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (nr < 0) { 74208516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGE("Error reading firmware: %s\n", strerror(errno)); 74308516fe50b023532d5a3010050970de28e14621bIliyan Malchev goto ld_img_error; 74408516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 74508516fe50b023532d5a3010050970de28e14621bIliyan Malchev else if (!nr) { 74608516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (remaining) 74708516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGW("EOF reading firmware %s while %d bytes remain\n", 74808516fe50b023532d5a3010050970de28e14621bIliyan Malchev fn, remaining); 74908516fe50b023532d5a3010050970de28e14621bIliyan Malchev break; 75008516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 75108516fe50b023532d5a3010050970de28e14621bIliyan Malchev remaining -= nr; 75208516fe50b023532d5a3010050970de28e14621bIliyan Malchev ptr += nr; 75308516fe50b023532d5a3010050970de28e14621bIliyan Malchev } 75408516fe50b023532d5a3010050970de28e14621bIliyan Malchev 75508516fe50b023532d5a3010050970de28e14621bIliyan Malchev close (fw_fd); 75608516fe50b023532d5a3010050970de28e14621bIliyan Malchev fw_fd = -1; 75708516fe50b023532d5a3010050970de28e14621bIliyan Malchev 7582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fwimg.buf = local_vpimg_buf; 75908516fe50b023532d5a3010050970de28e14621bIliyan Malchev fwimg.img_size = (int)(fw_stat.st_size - remaining); 76008516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGI("Total %d bytes put to user space buffer.\n", fwimg.img_size); 7612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland rc = ioctl(fd_a1026, A1026_BOOTUP_INIT, &fwimg); 7632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!rc) { 7642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("audience_a1026 init OK\n"); 7652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Init = 1; 7662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else 7672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("audience_a1026 init failed\n"); 7682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandld_img_error: 77008516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (fw_fd >= 0) 77108516fe50b023532d5a3010050970de28e14621bIliyan Malchev close(fw_fd); 7722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_a1026); 7732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandopen_drv_err: 7742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = -1; 7752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return rc; 7762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 7772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_snd_dev(void) 7792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 7802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 7817161d052ce69228825bd5deca3bfa4a213a99f06HK Chen return mCurSndDevice; 7822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 7832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7840f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatus_t AudioHardware::updateBT(void) 7850f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent{ 7860f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int fd = 0; 7870f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent uint32_t id[2]; 7880f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 7890f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent fd = open("/dev/msm_audio_ctl", O_RDWR); 7900f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (fd < 0) { 7910f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Cannot open msm_audio_ctl"); 7920f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return -1; 7930f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 7940f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int rc = 0; 795956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent if (mBluetoothIdRx != 0) { 7960f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent id[0] = mBluetoothIdRx; 7970f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent id[1] = curr_out_device; 7980f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("(mBluetoothIdRx, curr_out_device) = (%d, %d)", mBluetoothIdRx, curr_out_device); 7990f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent rc = ioctl(fd, AUDIO_UPDATE_ACDB, &id); 8000f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (rc) { 8010f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Cannot update RX ACDB %d, rc=%d", mBluetoothIdRx, rc); 8020f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent close(fd); 8030f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return -1; 8040f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } else 8050f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGD("update TX ACDB %d success", mBluetoothIdRx); 8060f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 8070f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 808956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent if (mBluetoothIdTx != 0) { 8090f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent id[0] = mBluetoothIdTx; 8100f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent id[1] = curr_mic_device; 8110f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("(mBluetoothIdTx, curr_out_device) = (%d, %d)", mBluetoothIdTx, curr_out_device); 8120f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent rc = ioctl(fd, AUDIO_UPDATE_ACDB, &id); 8130f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (rc) { 8140f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Cannot update TX ACDB %d, rc = %d", mBluetoothIdTx, rc); 8150f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent close(fd); 8160f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return -1; 8170f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } else 8180f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGD("update TX ACDB %d success", mBluetoothIdTx); 8190f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 8200f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent close(fd); 8210f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return 0; 8220f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent} 8230f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 8240f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent// always call with mutex held 8250f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurentstatus_t AudioHardware::updateACDB(void) 8260f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent{ 82763af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi 8280f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int fd = 0; 8290f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int acdb_id = -1; 8300f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent uint32_t id[2]; 8310f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 8320f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent fd = open("/dev/msm_audio_ctl", O_RDWR); 8330f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (fd < 0) { 8340f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Cannot open msm_audio_ctl"); 8350f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return -1; 8360f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 8370f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 8380f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (mMode == AudioSystem::MODE_IN_CALL) { 8390f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGD("skip update ACDB due to in-call"); 8400f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent close(fd); 8410f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return 0; 8420f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 8430f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 8440f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent //update RX acdb parameters. 8450f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!checkOutputStandby()) { 8460f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent switch (mCurSndDevice) { 8470f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HEADSET: 8480f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_NO_MIC_HEADSET: 849da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 8500f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_HEADSET: 8510f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_HEADSET_PLAYBACK; 8520f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 8530f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_SPEAKER: 8540f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_SPEAKER: 855da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_SPEAKER_BACK_MIC: 8560f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_SPKR_PLAYBACK; 8570f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 8580f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HEADSET_AND_SPEAKER: 85958cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 8600f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_HEADSET_RINGTONE_PLAYBACK; 8610f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 8620f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent default: 8630f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 8640f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 8650f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 8660f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (acdb_id != -1) { 8670f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent id[0] = acdb_id; 8680f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent id[1] = curr_out_device; 8690f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (ioctl(fd, AUDIO_UPDATE_ACDB, &id)) { 8700f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Cannot update RX ACDB %d", acdb_id); 8710f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent close(fd); 8720f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return -1; 8730f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } else 8740f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGD("update RX ACDB %d success", acdb_id); 8750f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 8760f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 8770f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent //update TX acdb parameters. 8780f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = -1; 8790f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (mRecordState) { 8800f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent switch (mCurSndDevice) { 8810f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HEADSET: 8820f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_HEADSET: 8830f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_FM_SPEAKER: 88458cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 8850f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent acdb_id = ACDB_ID_EXT_MIC_REC; 8860f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 8870f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_HANDSET: 8880f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_NO_MIC_HEADSET: 8890f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent case SND_DEVICE_SPEAKER: 89008516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled == 0) { 89163af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi acdb_id = ACDB_ID_INT_MIC_REC; 89263af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi } else { 89363af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi acdb_id = ACDB_ID_INT_MIC_VR; 89463af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi } 89563af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi break; 896da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_SPEAKER_BACK_MIC: 897da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 898da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_HANDSET_BACK_MIC: 89958cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 90063af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi acdb_id = ACDB_ID_CAMCORDER; 9010f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 9020f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent default: 9030f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 9040f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 9050f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 9060f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (acdb_id != -1) { 9070f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent id[0] = acdb_id; 9080f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent id[1] = curr_mic_device; 9090f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (ioctl(fd, AUDIO_UPDATE_ACDB, &id)) { 9100f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("Cannot update TX ACDB %d", acdb_id); 9110f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent close(fd); 9120f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return -1; 9130f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } else 9140f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGD("update TX ACDB %d success", acdb_id); 9150f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 9160f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent close(fd); 9170f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent return 0; 9180f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent} 9190f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 9202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doAudience_A1026_Control(int Mode, bool Record, uint32_t Routes) 9212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 9222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int rc = 0; 9230f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent int retry = 4; 9242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mA1026Init) { 9262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Audience A1026 not initialized.\n"); 9272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_INIT; 9282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 9312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = open("/dev/audience_a1026", O_RDWR); 9322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 9332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open audience_a1026 device (%d)\n", fd_a1026); 9342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 9352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.lock(); 9392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((Mode < AudioSystem::MODE_CURRENT) || (Mode >= AudioSystem::NUM_MODES)) { 9412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Illegal value: doAudience_A1026_Control(%d, %u, %u)", Mode, Record, Routes); 9422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.unlock(); 9432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 9442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (Mode == AudioSystem::MODE_IN_CALL) { 9472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (Record == 1) { 9482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 9492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HANDSET: 9502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_NO_MIC_HEADSET: 951da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent //TODO: what do we do for camcorder when in call? 952da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 953da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_HANDSET_BACK_MIC: 9544bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_RECEIVER; 95563af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_RECEIVER"); 9562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 9572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET: 9582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET_AND_SPEAKER: 9592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_HEADSET: 9602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_SPEAKER: 96158cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 9624bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_HEADSET; 96363af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_HEADSET"); 9642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 9652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_SPEAKER: 966da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent //TODO: what do we do for camcorder when in call? 967da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent case SND_DEVICE_SPEAKER_BACK_MIC: 9684bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_SPEAKER; 96963af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_SPEAKER"); 9702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 9712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT: 9722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT_EC_OFF: 9734bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_INCALL_BT; 97463af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_BT"); 9752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 9762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: 9772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 9782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 9802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 9812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HANDSET: 9822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_NO_MIC_HEADSET: 9832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_RECEIVER; /* NS CT mode, Dual MIC */ 98463af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_RECEIVER"); 9852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 9862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET: 9872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET_AND_SPEAKER: 9882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_HEADSET: 9892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_SPEAKER: 9902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_HEADSET; /* NS disable, Headset MIC */ 99163af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_HEADSET"); 9922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 9932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_SPEAKER: 9942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_SPEAKER; /* NS FT mode, Main MIC */ 99563af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_SPEAKER"); 9962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 9972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT: 9982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT_EC_OFF: 9992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_BT; /* QCOM NS, BT MIC */ 100063af0f3cbd387e97bcaca82d1e22787c224d6430Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_INCALL_BT"); 10012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 10022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: 10032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 10042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (Record == 1) { 10072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 1008ba36d4fa33072ef14183365fffd289762c26905eJean-Michel Trivi case SND_DEVICE_SPEAKER: 1009ba36d4fa33072ef14183365fffd289762c26905eJean-Michel Trivi // default output is speaker, recording from phone mic, user RECEIVER configuration 1010739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HANDSET: 1011739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_NO_MIC_HEADSET: 101208516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled) { 1013739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (vr_uses_ns) { 10144bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NS_RECEIVER; 1015739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NS_RECEIVER"); 1016739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 10174bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NO_NS_RECEIVER; 1018739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_RECEIVER"); 1019739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1020739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 10212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_RECORD_RECEIVER; /* INT-MIC Recording: NS disable, Main MIC */ 1022739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_RECORD_RECEIVER"); 1023739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 10242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1025739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HEADSET: 1026739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER: 1027739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_FM_HEADSET: 1028739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_FM_SPEAKER: 102908516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled) { 1030739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (vr_uses_ns) { 10314bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NS_HEADSET; 1032739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NS_HEADSET"); 1033739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 10344bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NO_NS_HEADSET; 1035739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_HEADSET"); 1036739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1037739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 1038739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi new_pathid = A1026_PATH_RECORD_HEADSET; /* EXT-MIC Recording: NS disable, Headset MIC */ 1039739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_RECORD_HEADSET"); 1040739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1041739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi break; 1042739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_SPEAKER_BACK_MIC: 1043739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_NO_MIC_HEADSET_BACK_MIC: 1044739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_HANDSET_BACK_MIC: 104558cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi case SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC: 1046da9d5ab10524c32d7949363a10fde1bec5fdf9faEric Laurent new_pathid = A1026_PATH_CAMCORDER; /* CAM-Coder: NS FT mode, Back MIC */ 1047f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_CAMCORDER"); 10482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1049739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_BT: 1050739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi case SND_DEVICE_BT_EC_OFF: 105108516fe50b023532d5a3010050970de28e14621bIliyan Malchev if (vr_mode_enabled) { 1052739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (vr_uses_ns) { 10534bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NS_BT; 1054739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NS_BT"); 1055739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 10564bcd5b16c66bc5c2bffe232f15f5cb83aea18318Jean-Michel Trivi new_pathid = A1026_PATH_VR_NO_NS_BT; 1057739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_VR_NO_NS_BT"); 1058739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1059739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 1060739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi new_pathid = A1026_PATH_RECORD_BT; /* BT MIC */ 1061739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi LOGV("A1026 control: new path is A1026_PATH_RECORD_BT"); 1062739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 10632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 1064739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi default: 10652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 10662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else { 10692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_SUSPEND; 10702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (old_pathid != new_pathid) { 10732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland //LOGI("A1026: do ioctl(A1026_SET_CONFIG) to %d\n", new_pathid); 10740f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent do { 10750f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent rc = ioctl(fd_a1026, A1026_SET_CONFIG, &new_pathid); 10760f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!rc) { 10770f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent old_pathid = new_pathid; 10780f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent break; 10790f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 10800f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } while (--retry); 10810f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent 10820f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (rc < 0) { 10830f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("A1026 do hard reset to recover from error!\n"); 10840f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent rc = doA1026_init(); /* A1026 needs to do hard reset! */ 10850f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (!rc) { 10862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland rc = ioctl(fd_a1026, A1026_SET_CONFIG, &new_pathid); 10872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!rc) 10882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland old_pathid = new_pathid; 10892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else 10900f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("A1026 Fatal Error!\n"); 10910f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } else 10920f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent LOGE("A1026 Fatal Error: Re-init A1026 Failed\n"); 10930f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent } 10942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.unlock(); 10972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_a1026); 10982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = -1; 10992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return rc; 11012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 11022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doRouting(AudioStreamInMSM72xx *input) 11052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1106f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi Mutex::Autolock lock(mLock); 1107f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi uint32_t outputDevices = mOutput->devices(); 11082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t ret = NO_ERROR; 1109f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi int sndDevice = -1; 11102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1111f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (input != NULL) { 1112f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi uint32_t inputDevice = input->devices(); 1113f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("do input routing device %x\n", inputDevice); 1114f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (inputDevice != 0) { 1115f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 1116f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Bluetooth PCM\n"); 1117f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_BT; 1118f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 1119f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 1120956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 1121f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Wired Headset and Speaker\n"); 1122f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 1123956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } else { 1124f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Wired Headset\n"); 1125f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET; 1126f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 1127f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (inputDevice & AudioSystem::DEVICE_IN_BACK_MIC) { 112858cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi if (outputDevices & (AudioSystem:: DEVICE_OUT_WIRED_HEADSET) && 112958cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi (outputDevices & AudioSystem:: DEVICE_OUT_SPEAKER)) { 113058cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi LOGI("Routing audio to Wired Headset and Speaker with back mic\n"); 113158cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER_BACK_MIC; 113258cf88a5a91d82ae2fb3e23365eaa4524a9cd089Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 1133f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Speakerphone with back mic\n"); 1134f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_SPEAKER_BACK_MIC; 1135f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices == AudioSystem::DEVICE_OUT_EARPIECE) { 1136f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Handset with back mic\n"); 1137f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HANDSET_BACK_MIC; 1138f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 1139f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Headset with back mic\n"); 1140f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_NO_MIC_HEADSET_BACK_MIC; 1141f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 1142f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 1143f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 1144f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Speakerphone\n"); 1145f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_SPEAKER; 1146f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 1147f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Speakerphone\n"); 1148f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_NO_MIC_HEADSET; 1149f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 1150f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Handset\n"); 1151f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HANDSET; 1152956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1153956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1154956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1155f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi // if inputDevice == 0, restore output routing 1156f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 1157956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent 1158f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (sndDevice == -1) { 1159f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & (outputDevices - 1)) { 1160f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) { 1161f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGW("Hardware does not support requested route combination (%#X)," 1162f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi " picking closest possible route...", outputDevices); 1163956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } 1164f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 1165956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent 1166f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & 1167dd65e38951ed174f9d3d34886795438440f7eea0Eric Laurent (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { 1168f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Bluetooth PCM\n"); 1169f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_BT; 1170f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 1171f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Bluetooth PCM\n"); 1172f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_CARKIT; 1173f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 1174f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 1175f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Wired Headset and Speaker\n"); 1176956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 1177f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 1178f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 1179f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); 1180f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 1181956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent } else { 1182f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); 1183f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_NO_MIC_HEADSET; 11842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1185f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 1186f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Wired Headset\n"); 1187f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HEADSET; 1188f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 1189f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Speakerphone\n"); 1190f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_SPEAKER; 1191f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 1192f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi LOGI("Routing audio to Handset\n"); 1193f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi sndDevice = SND_DEVICE_HANDSET; 11942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1195f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } 11962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1197f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if ((vr_mode_change) || (sndDevice != -1 && sndDevice != mCurSndDevice)) { 1198f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi ret = doAudioRouteOrMute(sndDevice); 1199f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi mCurSndDevice = sndDevice; 1200f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi if (mMode == AudioSystem::MODE_IN_CALL && mBluetoothIdTx != 0 1201f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi && sndDevice == (int)SND_DEVICE_BT) { 1202956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent updateBT(); 1203f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi } else { 1204f8d3aebe4c19283eb34fb89e5932b3399d3bd753Jean-Michel Trivi updateACDB(); 12052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return ret; 12092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::checkMicMute() 12122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 12132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 12142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mMode != AudioSystem::MODE_IN_CALL) { 12152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland setMicMute_nosync(true); 12162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 12192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 12222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 12232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 12242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 12252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 12262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioHardware::dumpInternals\n"); 12272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 12282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 12302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 12322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12330f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snprintf(buffer, SIZE, "\tmBluetoothIdtx: %d\n", mBluetoothIdTx); 12340f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent result.append(buffer); 12350f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent snprintf(buffer, SIZE, "\tmBluetoothIdrx: %d\n", mBluetoothIdRx); 12362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 12382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 12392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::dump(int fd, const Vector<String16>& args) 12422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 12432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland dumpInternals(fd, args); 12442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (size_t index = 0; index < mInputs.size(); index++) { 12452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs[index]->dump(fd, args); 12462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) { 12492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput->dump(fd, args); 12502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 12522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlanduint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) 12552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 12562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t i; 12572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t prevDelta; 12582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t delta; 12592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { 12612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delta = abs(sampleRate - inputSamplingRates[i]); 12622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (delta > prevDelta) break; 12632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // i is always > 0 here 12652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return inputSamplingRates[i-1]; 12662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 12692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12702aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 12712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0) 12722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 12732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::set( 12762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 12772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 12782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int lFormat = pFormat ? *pFormat : 0; 12792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t lChannels = pChannels ? *pChannels : 0; 12802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t lRate = pRate ? *pRate : 0; 12812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware = hw; 12832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // fix up defaults 12852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lFormat == 0) lFormat = format(); 12862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lChannels == 0) lChannels = channels(); 12872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lRate == 0) lRate = sampleRate(); 12882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // check values 12902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((lFormat != format()) || 12912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (lChannels != channels()) || 12922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (lRate != sampleRate())) { 12932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat) *pFormat = format(); 12942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels) *pChannels = channels(); 12952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate) *pRate = sampleRate(); 12962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 12972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat) *pFormat = lFormat; 13002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels) *pChannels = lChannels; 13012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate) *pRate = lRate; 13022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = devices; 13042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 13062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 13072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13082aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 13092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 13102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) close(mFd); 13112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 13122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 13142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 13152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 13162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_INIT; 13172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland size_t count = bytes; 13182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const uint8_t* p = static_cast<const uint8_t*>(buffer); 13192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mStandby) { 13212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // open driver 13232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("open pcm_out driver"); 13242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ::open("/dev/msm_pcm_out", O_RDWR); 13252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 13262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errCount++ < 10) { 13272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 13282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 13302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = status; 13322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // configuration 13342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get config"); 13352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct msm_audio_config config; 13362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 13372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 13382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot read pcm_out config"); 13392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 13402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set pcm_out config"); 13432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.channel_count = AudioSystem::popCount(channels()); 13442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.sample_rate = sampleRate(); 13452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_size = bufferSize(); 13462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 13472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.codec_type = CODEC_TYPE_PCM; 13482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 13492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 13502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot set config"); 13512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 13522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_size: %u", config.buffer_size); 13552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_count: %u", config.buffer_count); 13562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("channel_count: %u", config.channel_count); 13572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("sample_rate: %u", config.sample_rate); 13582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 135931923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen status = ioctl(mFd, AUDIO_START, 0); 136031923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen if (status < 0) { 136131923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen LOGE("Cannot start pcm playback"); 136231923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen goto Error; 13632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 136410254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi 136510254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi status = ioctl(mFd, AUDIO_SET_VOLUME, &stream_volume); 136610254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi if (status < 0) { 136710254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi LOGE("Cannot start pcm playback"); 136810254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi goto Error; 136910254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi } 137010254cc35f5cb7ebe2c7ef452815486cb8e92a33Jean-Michel Trivi 13715d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks LOGV("acquire wakelock"); 13725d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks acquire_wake_lock(PARTIAL_WAKE_LOCK, kOutputWakelockStr); 137331923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen mStandby = false; 13740f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent Mutex::Autolock lock(mHardware->mLock); 13750f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mHardware->updateACDB(); 13762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland while (count) { 13792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t written = ::write(mFd, p, count); 13802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (written >= 0) { 13812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland count -= written; 13822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland p += written; 13832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 13842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errno != EAGAIN) return written; 13852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRetryCount++; 13862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("EAGAIN - retry"); 13872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return bytes; 13912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13922aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandError: 13932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 13942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 13952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 13962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // Simulate audio output timing in case of error 13982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland usleep(bytes * 1000000 / frameSize() / sampleRate()); 13992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 14012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::standby() 14042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 14062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mStandby && mFd >= 0) { 14072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 14082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 14095d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks LOGV("release wakelock"); 14105d89308f2e1252eff2743bf823bf558dbb0de2faDave Sparks release_wake_lock(kOutputWakelockStr); 14112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mStandby = true; 14132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("AudioHardware pcm playback is going to standby."); 14142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 14152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 14182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 14202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 14212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 14222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioStreamOutMSM72xx::dump\n"); 14232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 14242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 14262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 14282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 14302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 14322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 14342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 14362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 14382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 14402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 14412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 14422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 14432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandbool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 14462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mStandby; 14482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) 14522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 14542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 14552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 14562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int device; 14572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); 14582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.getInt(key, device) == NO_ERROR) { 14602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = device; 14612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set output routing %x", mDevices); 14622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = mHardware->doRouting(NULL); 14632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.remove(key); 14642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.size()) { 14672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 14682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 14702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14722aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) 14732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keys); 14752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 14762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 14772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 14792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get routing %x", mDevices); 14802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.addInt(key, (int)mDevices); 14812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 14822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); 14842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return param.toString(); 14852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 14892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14902aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 14912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), 14922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), 14932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE), 14942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) 14952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 14962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 14972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 14982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::set( 14992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, 15002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioSystem::audio_in_acoustics acoustic_flags) 15012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 15022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) { 15032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pFormat = AUDIO_HW_IN_FORMAT; 15042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 15052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate == 0) { 15072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 15082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t rate = hw->getInputSampleRate(*pRate); 15102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (rate != *pRate) { 15112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pRate = rate; 15122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 15132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO && 15162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels != AudioSystem::CHANNEL_IN_STEREO)) { 15172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AUDIO_HW_IN_CHANNELS; 15182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 15192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware = hw; 15222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); 15242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 15252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Audio record already open"); 15262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -EPERM; 15272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // open audio input device 15302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 15312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 15322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 15332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 15342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = status; 15362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // configuration 15382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get config"); 15392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct msm_audio_config config; 15402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 15412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 15422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot read config"); 15432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 15442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set config"); 15472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.channel_count = AudioSystem::popCount(*pChannels); 15482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.sample_rate = *pRate; 15492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_size = bufferSize(); 15502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_count = 2; 15512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.codec_type = CODEC_TYPE_PCM; 15522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 15532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 15542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot set config"); 15552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) { 15562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (config.channel_count == 1) { 15572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AudioSystem::CHANNEL_IN_MONO; 15582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 15592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AudioSystem::CHANNEL_IN_STEREO; 15602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pRate = config.sample_rate; 15622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 15642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("confirm config"); 15672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 15682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 15692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot read config"); 15702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 15712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_size: %u", config.buffer_size); 15732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_count: %u", config.buffer_count); 15742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("channel_count: %u", config.channel_count); 15752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("sample_rate: %u", config.sample_rate); 15762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = devices; 15782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFormat = AUDIO_HW_IN_FORMAT; 15792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mChannels = *pChannels; 15802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mSampleRate = config.sample_rate; 15812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBufferSize = config.buffer_size; 15822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland //mHardware->setMicMute_nosync(false); 15842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mState = AUDIO_INPUT_OPENED; 15852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 15872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15882aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandError: 15892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 15902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 15912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 15922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 15932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 15942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 15952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 15962aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 15972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 15982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx destructor"); 15992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland standby(); 16002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 16032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 16052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mHardware) return -1; 16062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland size_t count = bytes; 16082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint8_t* p = static_cast<uint8_t*>(buffer); 16092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mState < AUDIO_INPUT_OPENED) { 16112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mHardware->mLock); 16122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) { 16132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 16142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16170f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (mState < AUDIO_INPUT_STARTED) { 16182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware->set_mRecordState(1); 1619956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent if (support_a1026 == 1) { 1620956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent mHardware->doAudience_A1026_Control(mHardware->get_mMode(), 1, mHardware->get_snd_dev()); 16212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(mFd, AUDIO_START, 0)) { 16232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Error starting record"); 16242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 16252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("AUDIO_START: start kernel pcm_in driver."); 16272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mState = AUDIO_INPUT_STARTED; 16280f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent Mutex::Autolock lock(mHardware->mLock); 16290f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent mHardware->updateACDB(); 16302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland while (count) { 16332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t bytesRead = ::read(mFd, buffer, count); 16342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (bytesRead >= 0) { 16352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland count -= bytesRead; 16362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland p += bytesRead; 16372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 16382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errno != EAGAIN) return bytesRead; 16392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRetryCount++; 16402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("EAGAIN - retrying"); 16412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return bytes; 16442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::standby() 16472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1648956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent if (mHardware) { 16492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware->set_mRecordState(0); 16500f2f4d0a60cf93a7a281e217408a4249715f5748Eric Laurent if (support_a1026 == 1) { 1651956f7ba5ee0f087c91b5fefd2718dae30f8c1e29Eric Laurent mHardware->doAudience_A1026_Control(mHardware->get_mMode(), 0, mHardware->get_snd_dev()); 16522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mHardware) return -1; 16562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mState > AUDIO_INPUT_CLOSED) { 16572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 16582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 16592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 16602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland //mHardware->checkMicMute(); 16622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mState = AUDIO_INPUT_CLOSED; 16632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 16642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("AudioHardware PCM record is going to standby."); 16652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 16662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 16692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 16712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 16722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 16732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioStreamInMSM72xx::dump\n"); 16742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 16752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 16772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 16792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 16812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 16832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 16852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmState: %d\n", mState); 16872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 16892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 16902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 16912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 16922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 16932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 16942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs) 16952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 16962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 16972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 16982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int device; 1699255bdedb2d7ebf4b14690776ff652df1de97fe95Eric Laurent String8 key = String8(KEY_A1026_VR_MODE); 1700739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi int enabled; 17012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string()); 17022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1703739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // reading voice recognition mode parameter 1704255bdedb2d7ebf4b14690776ff652df1de97fe95Eric Laurent if (param.getInt(key, enabled) == NO_ERROR) { 170508516fe50b023532d5a3010050970de28e14621bIliyan Malchev LOGV("set vr_mode_enabled to %d", enabled); 170608516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_change = (vr_mode_enabled != enabled); 1707739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi if (enable1026) { 170808516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_enabled = enabled; 1709739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } else { 171008516fe50b023532d5a3010050970de28e14621bIliyan Malchev vr_mode_enabled = 0; 1711739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1712739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi param.remove(key); 1713739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi } 1714739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi 1715739de5f36523862a7caa15590bd6b680b6cd2854Jean-Michel Trivi // reading routing parameter 1716255bdedb2d7ebf4b14690776ff652df1de97fe95Eric Laurent key = String8(AudioParameter::keyRouting); 17172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.getInt(key, device) == NO_ERROR) { 17182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set input routing %x", device); 17192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device & (device - 1)) { 17202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 17212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 17222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = device; 17232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = mHardware->doRouting(this); 17242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.remove(key); 17262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.size()) { 17292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 17302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 17322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 17332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17342aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys) 17352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 17362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keys); 17372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 17382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 17392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 17412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get routing %x", mDevices); 17422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.addInt(key, (int)mDevices); 17432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 17442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string()); 17462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return param.toString(); 17472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 17482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 17502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandextern "C" AudioHardwareInterface* createAudioHardware(void) { 17522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return new AudioHardware(); 17532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 17542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 17552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland}; // namespace android 1756