AudioHardware.cpp revision 7161d052ce69228825bd5deca3bfa4a213a99f06
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> 232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <stdio.h> 252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <unistd.h> 262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <sys/ioctl.h> 272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <sys/types.h> 282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <sys/stat.h> 292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <dlfcn.h> 302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <fcntl.h> 312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// hardware specific functions 332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include "AudioHardware.h" 352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include <media/AudioRecord.h> 362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandextern "C" { 382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include "msm_audio.h" 392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#include "a1026.h" 402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandenum audio_routes { 432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_EARPIECE = (1 << 0), 442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_SPEAKER = (1 << 1), 452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_BLUETOOTH_SCO = (1 << 2), 462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_HEADSET = (1 << 3), 472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_BLUETOOTH_A2DP = (1 << 4), 482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_NO_MIC_HEADSET = (1 << 5), 492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_TTY = (1 << 6), 502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_FM_HEADSET = (1 << 7), 512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_FM_SPEAKER = (1 << 8), 522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ROUTE_ALL = -1UL, 532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland}; 542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#define LOG_SND_RPC 0 // Set to 1 to log sound RPC's 562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#define TX_PATH (1) 572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_CURRENT = 256; 592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HANDSET = 0; 602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_SPEAKER = 1; 612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_BT = 3; 622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_CARKIT = 4; 632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_BT_EC_OFF = 45; 642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HEADSET = 2; 652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_HEADSET_AND_SPEAKER = 10; 662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_FM_HEADSET = 9; 672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_FM_SPEAKER = 11; 682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_NO_MIC_HEADSET = 8; 692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic const uint32_t SND_DEVICE_TTY_FULL = 5; 702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandnamespace android { 712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int support_a1026 = 1; 722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int fd_a1026 = -1; 732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int old_pathid = -1; 742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int new_pathid = -1; 752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int cur_rx_device = 0; 762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int cur_tx_device = 0; 772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int voice_started = 0; 782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic int fd_fm_device = -1; 792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandint errCount = 0; 802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandconst uint32_t AudioHardware::inputSamplingRates[] = { 812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland}; 832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 852aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioHardware() : 862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInit(false), mMicMute(true), mBluetoothNrec(true), mBluetoothId(0), 872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Init(false), 882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput(0) 892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland doA1026_init(); 912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInit = true; 922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 942aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::~AudioHardware() 952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (size_t index = 0; index < mInputs.size(); index++) { 972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland closeInputStream((AudioStreamIn*)mInputs[index]); 982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.clear(); 1002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland closeOutputStream((AudioStreamOut*)mOutput); 1012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInit = false; 1022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 1032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::initCheck() 1052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mInit ? NO_ERROR : NO_INIT; 1072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 1082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1092aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioStreamOut* AudioHardware::openOutputStream( 1102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status) 1112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland { // scope for the lock 1132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 1142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // only one output stream allowed 1162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) { 1172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 1182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = INVALID_OPERATION; 1192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 1212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // create new output stream 1242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 1252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t lStatus = out->set(this, devices, format, channels, sampleRate); 1262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 1272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = lStatus; 1282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lStatus == NO_ERROR) { 1302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput = out; 1312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 1322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete out; 1332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mOutput; 1362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 1372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandvoid AudioHardware::closeOutputStream(AudioStreamOut* out) { 1392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 1402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput == 0 || mOutput != out) { 1412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Attempt to close invalid output stream"); 1422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else { 1442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete mOutput; 1452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput = 0; 1462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 1482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1492aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioStreamIn* AudioHardware::openInputStream( 1502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status, 1512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioSystem::audio_in_acoustics acoustic_flags) 1522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // check for valid input source 1542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) { 1552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 1562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.lock(); 1592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 1612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t lStatus = in->set(this, devices, format, channels, sampleRate, acoustic_flags); 1622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status) { 1632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *status = lStatus; 1642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lStatus != NO_ERROR) { 1662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 1672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete in; 1682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 1692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.add(in); 1722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 1732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return in; 1752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 1762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandvoid AudioHardware::closeInputStream(AudioStreamIn* in) { 1782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 1792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t index = mInputs.indexOf((AudioStreamInMSM72xx *)in); 1812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (index < 0) { 1822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Attempt to close invalid input stream"); 1832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 1842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.unlock(); 1852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delete mInputs[index]; 1862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mLock.lock(); 1872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs.removeAt(index); 1882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 1902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 1912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMode(int mode) 1922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 1932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = AudioHardwareBase::setMode(mode); 1942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status == NO_ERROR) { 1952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // make sure that doAudioRouteOrMute() is called by doRouting() 1962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // even if the new device selected is the same as current one. 1972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mCurSndDevice = -1; 1982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 1992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 2002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandbool AudioHardware::checkOutputStandby() 2032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) 2052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mOutput->checkStandby()) 2062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return false; 2072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return true; 2092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic status_t set_mic_mute(bool mute) 2112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int fd = -1, arg; 2132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct msm_mute_info info; 2142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 2152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 2162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl device\n"); 2172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 2182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Setting mic mute to %d\n", mute); 2202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland info.path = TX_PATH; 2212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland info.mute = mute; 2222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_SET_MUTE, &info)) { 2232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot set mic mute on current device\n"); 2242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 2252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 2262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 2282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 2292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMicMute(bool state) 2322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 2342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return setMicMute_nosync(state); 2352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// always call with mutex held 2382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMicMute_nosync(bool state) 2392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mMicMute != state) { 2412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mMicMute = state; 2422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return set_mic_mute(mMicMute); //always set current TX device 2432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 2452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::getMicMute(bool* state) 2482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *state = mMicMute; 2502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 2512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setParameters(const String8& keyValuePairs) 2542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 2552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 2562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 2572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key; 2582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NREC_KEY[] = "bt_headset_nrec"; 2592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NAME_KEY[] = "bt_headset_name"; 2602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const char BT_NREC_VALUE_ON[] = "on"; 2612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("setParameters() %s", keyValuePairs.string()); 2642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (keyValuePairs.length() == 0) return BAD_VALUE; 2662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland key = String8(BT_NREC_KEY); 2682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 2692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (value == BT_NREC_VALUE_ON) { 2702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothNrec = true; 2712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 2722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothNrec = false; 2732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Turning noise reduction and echo cancellation off for BT " 2742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland "headset"); 2752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland key = String8(BT_NAME_KEY); 2782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 2792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothId = 0; 2802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#if 0 2812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (int i = 0; i < mNumSndEndpoints; i++) { 2822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!strcasecmp(value.string(), mSndEndpoints[i].name)) { 2832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBluetoothId = mSndEndpoints[i].id; 2842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Using custom acoustic parameters for %s", value.string()); 2852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 2862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#endif 2892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mBluetoothId == 0) { 2902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Using default acoustic parameters " 2912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland "(%s not in acoustic database)", value.string()); 2922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland doRouting(NULL); 2932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 2952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 2962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 2972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 2982aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::getParameters(const String8& keys) 2992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keys); 3012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return param.toString(); 3022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic unsigned calculate_audpre_table_index(unsigned index) 3062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (index) { 3082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 48000: return SAMP_RATE_INDX_48000; 3092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 44100: return SAMP_RATE_INDX_44100; 3102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 32000: return SAMP_RATE_INDX_32000; 3112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 24000: return SAMP_RATE_INDX_24000; 3122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 22050: return SAMP_RATE_INDX_22050; 3132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 16000: return SAMP_RATE_INDX_16000; 3142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 12000: return SAMP_RATE_INDX_12000; 3152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 11025: return SAMP_RATE_INDX_11025; 3162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case 8000: return SAMP_RATE_INDX_8000; 3172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: return -1; 3182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandsize_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 3212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (format != AudioSystem::PCM_16_BIT) { 3232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("getInputBufferSize bad format: %d", format); 3242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 3252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (channelCount < 1 || channelCount > 2) { 3272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("getInputBufferSize bad channel count: %d", channelCount); 3282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 3292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 2048*channelCount; 3322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic status_t set_volume_rpc(uint32_t volume) 3352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int fd = -1; 3372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 3382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 3392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl device\n"); 3402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 3412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland volume *= 20; //percentage 3432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Setting in-call volume to %d\n", volume); 3442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_SET_VOLUME, &volume)) { 3452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Cannot set volume on current device\n"); 3462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 3482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setVoiceVolume(float v) 3522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (v < 0.0) { 3542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 3552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland v = 0.0; 3562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (v > 1.0) { 3572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 3582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland v = 1.0; 3592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 3602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int vol = lrint(v * 5.0); 3622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("setVoiceVolume(%f)\n", v); 3632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol); 3642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 3662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland set_volume_rpc(vol); //always set current device 3672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 3682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::setMasterVolume(float v) 3712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 3732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int vol = ceil(v * 5.0); 3742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Set master volume to %d.\n", vol); 3752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // We return an error code here to let the audioflinger do in-software 3762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // volume on top of the maximum volume that we set through the SND API. 3772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // return error - software mixer will handle it 3782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 3792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 3802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatic status_t do_route_audio_dev_ctrl(uint32_t device, bool inCall) 3822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 3832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int out_device = 0, mic_device = 0; 3842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int fd = 0; 3852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == SND_DEVICE_CURRENT) 3872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Incall; 3882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 3892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // hack -- kernel needs to put these in include file 3902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Switching audio device to "); 3912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == SND_DEVICE_HANDSET) { 3922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HANDSET_SPKR; 3932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HANDSET_MIC; 3942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Handset"); 3952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if ((device == SND_DEVICE_BT) || (device == SND_DEVICE_BT_EC_OFF)) { 3962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = BT_SCO_SPKR; 3972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = BT_SCO_MIC; 3982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("BT Headset"); 3992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_SPEAKER) { 4002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = SPKR_PHONE_MONO; 4012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = SPKR_PHONE_MIC; 4022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Speakerphone"); 4032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_HEADSET) { 4042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HEADSET_SPKR_STEREO; 4052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 4062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo Headset"); 4072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_HEADSET_AND_SPEAKER) { 4082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = SPKR_PHONE_HEADSET_STEREO; 4092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 4102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo Headset + Speaker"); 4112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_NO_MIC_HEADSET) { 4122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = HEADSET_SPKR_STEREO; 4132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HANDSET_MIC; 4142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("No microphone Wired Headset"); 4152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_FM_HEADSET) { 4162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = FM_HEADSET; 4172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 4182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo FM headset"); 4192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (device == SND_DEVICE_FM_SPEAKER) { 4202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device = FM_SPKR; 4212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mic_device = HEADSET_MIC; 4222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Stereo FM speaker"); 4232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 4242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("unknown device %d", device); 4252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#if 0 //Add for FM support 4292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (out_device == FM_HEADSET || 4302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland out_device == FM_SPKR) { 4312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_fm_device < 0) { 4322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_fm_device = open("/dev/msm_htc_fm", O_RDWR); 4332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_fm_device < 0) { 4342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_htc_fm device"); 4352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Opened msm_htc_fm for FM radio"); 4382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (fd_fm_device >= 0) { 4402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_fm_device); 4412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_fm_device = -1; 4422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Closed msm_htc_fm after FM radio"); 4432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland#endif 4452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 4472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 4482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl"); 4492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_SWITCH_DEVICE, &out_device)) { 4532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot switch audio device"); 4542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 4552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_SWITCH_DEVICE, &mic_device)) { 4582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot switch mic device"); 4592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 4602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4632aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandIncall: 4642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (inCall == true && !voice_started) { 4652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 4662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 4672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 4692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl"); 4702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_START_VOICE, NULL)) { 4742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot start voice"); 4752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 4762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Voice Started!!"); 4792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland voice_started = 1; 4802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else if (inCall == false && voice_started) { 4822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 4832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd = open("/dev/msm_audio_ctl", O_RDWR); 4842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd < 0) { 4862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open msm_audio_ctl"); 4872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(fd, AUDIO_STOP_VOICE, NULL)) { 4912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot stop voice"); 4922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 4932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 4942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGD("Voice Stopped!!"); 4962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland voice_started = 0; 4972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 4982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 4992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd); 5002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 5012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// always call with mutex held 5052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doAudioRouteOrMute(uint32_t device) 5062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (support_a1026 == 1) 5082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland doAudience_A1026_Control(mMode, mRecordState, device); 5092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device == (uint32_t)SND_DEVICE_BT || device == (uint32_t)SND_DEVICE_CARKIT) { 5112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mBluetoothId) { 5122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland device = mBluetoothId; 5132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (!mBluetoothNrec) { 5142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland device = SND_DEVICE_BT_EC_OFF; 5152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return do_route_audio_dev_ctrl(device, mMode == AudioSystem::MODE_IN_CALL); 5182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_mMode(void) 5212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mMode; 5232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_mRoutes(void) 5262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mRoutes[mMode]; 5282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::set_mRecordState(bool onoff) 5312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRecordState = onoff; 5332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return 0; 5342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doA1026_init(void) 5372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct a1026img fwimg; 5392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char *fn = NULL, *path = NULL; 5402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char char_tmp = 0; 5412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int rc = 0, count = 0; 5422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland unsigned char local_vpimg_buf[32*1024]; 5432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland FILE *fp; 5442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fn = "/system/etc/vpimg"; 5462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland path = "/dev/audience_a1026"; 5472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 5492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = open(path, O_RDWR|O_NONBLOCK, 0); 5502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 5512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open %s %d\n", path, fd_a1026); 5522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland support_a1026 = 0; 5532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto open_drv_err; 5542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fp = fopen(fn, "rb"); 5582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!fp) { 5592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Fail to open %s\n", fn); 5602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto ld_img_error; 5612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else LOGI("open %s success\n", fn); 5622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland memset(local_vpimg_buf, 0, sizeof(local_vpimg_buf)); 5642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland while(!feof(fp)) { 5662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fread(&char_tmp, sizeof(unsigned char), 1, fp); 5672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland local_vpimg_buf[count++] = char_tmp; 5682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 5692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fclose(fp); 5702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Total %d bytes put to user space buffer.\n", --count); 5722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fwimg.buf = local_vpimg_buf; 5732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fwimg.img_size = count; 5742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland rc = ioctl(fd_a1026, A1026_BOOTUP_INIT, &fwimg); 5762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!rc) { 5772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("audience_a1026 init OK\n"); 5782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Init = 1; 5792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else 5802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("audience_a1026 init failed\n"); 5812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandld_img_error: 5832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_a1026); 5842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandopen_drv_err: 5852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = -1; 5862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return rc; 5872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::get_snd_dev(void) 5907161d052ce69228825bd5deca3bfa4a213a99f06HK Chen 5912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 5937161d052ce69228825bd5deca3bfa4a213a99f06HK Chen return mCurSndDevice; 5942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 5952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 5962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doAudience_A1026_Control(int Mode, bool Record, uint32_t Routes) 5972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 5982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int rc = 0; 5992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mA1026Init) { 6012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Audience A1026 not initialized.\n"); 6022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_INIT; 6032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 6062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = open("/dev/audience_a1026", O_RDWR); 6072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (fd_a1026 < 0) { 6082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open audience_a1026 device (%d)\n", fd_a1026); 6092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 6102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.lock(); 6142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((Mode < AudioSystem::MODE_CURRENT) || (Mode >= AudioSystem::NUM_MODES)) { 6162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Illegal value: doAudience_A1026_Control(%d, %u, %u)", Mode, Record, Routes); 6172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.unlock(); 6182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 6192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (Mode == AudioSystem::MODE_IN_CALL) { 6222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (Record == 1) { 6232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 6242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HANDSET: 6252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_NO_MIC_HEADSET: 6262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_VR_RECEIVER; 6272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET: 6292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET_AND_SPEAKER: 6302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_HEADSET: 6312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_SPEAKER: 6322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_VR_HEADSET; 6332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_SPEAKER: 6352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_VR_SPEAKER; 6362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT: 6382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT_EC_OFF: 6392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_VR_BT; 6402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: 6422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 6452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 6462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HANDSET: 6472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_NO_MIC_HEADSET: 6482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_RECEIVER; /* NS CT mode, Dual MIC */ 6492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET: 6512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET_AND_SPEAKER: 6522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_HEADSET: 6532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_SPEAKER: 6542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_HEADSET; /* NS disable, Headset MIC */ 6552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_SPEAKER: 6572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_SPEAKER; /* NS FT mode, Main MIC */ 6582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT: 6602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT_EC_OFF: 6612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_INCALL_BT; /* QCOM NS, BT MIC */ 6622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: 6642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (Record == 1) { 6682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland switch (Routes) { 6692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HANDSET: 6702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_NO_MIC_HEADSET: 6712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_RECORD_RECEIVER; /* INT-MIC Recording: NS disable, Main MIC */ 6722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET: 6742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_HEADSET_AND_SPEAKER: 6752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_HEADSET: 6762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_FM_SPEAKER: 6772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_RECORD_HEADSET; /* EXT-MIC Recording: NS disable, Headset MIC */ 6782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_SPEAKER: 6802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_RECORD_SPEAKER; /* CAM-Coder: NS FT mode, Main MIC */ 6812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT: 6832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland case SND_DEVICE_BT_EC_OFF: 6842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_RECORD_BT; /* BT MIC */ 6852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland default: 6872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland break; 6882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else { 6912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland new_pathid = A1026_PATH_SUSPEND; 6922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 6932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 6942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (old_pathid != new_pathid) { 6952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland //LOGI("A1026: do ioctl(A1026_SET_CONFIG) to %d\n", new_pathid); 6962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland rc = ioctl(fd_a1026, A1026_SET_CONFIG, &new_pathid); 6972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!rc) 6982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland old_pathid = new_pathid; 6992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland else 7002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 7012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7032aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandError: 7042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mA1026Lock.unlock(); 7052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland close(fd_a1026); 7062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland fd_a1026 = -1; 7072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return rc; 7092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 7102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::doRouting(AudioStreamInMSM72xx *input) 7132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 7142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 7152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t outputDevices = mOutput->devices(); 7162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t ret = NO_ERROR; 7172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int audProcess = (ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 7182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int sndDevice = -1; 7192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (input != NULL) { 7212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t inputDevice = input->devices(); 7222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("do input routing device %x\n", inputDevice); 7232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (inputDevice != 0) { 7242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 7252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Bluetooth PCM\n"); 7262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_BT; 7272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 7282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 7292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 7302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Wired Headset and Speaker\n"); 7312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 7322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 7332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 7342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Wired Headset\n"); 7352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_HEADSET; 7362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 7382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 7392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Speakerphone\n"); 7402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_SPEAKER; 7412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 7422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 7432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Handset\n"); 7442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_HANDSET; 7452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // if inputDevice == 0, restore output routing 7492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (sndDevice == -1) { 7522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (outputDevices & (outputDevices - 1)) { 7532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) { 7542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("Hardware does not support requested route combination (%#X)," 7552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland " picking closest possible route...", outputDevices); 7562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 7592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (outputDevices & AudioSystem::DEVICE_OUT_TTY) { 7602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to TTY\n"); 7612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_TTY_FULL; 7622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (outputDevices & 7632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { 7642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Bluetooth PCM\n"); 7652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_BT; 7662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 7672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Bluetooth PCM\n"); 7682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_CARKIT; 7692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 7702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 7712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Wired Headset and Speaker\n"); 7722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 7732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 7742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (outputDevices & AudioSystem::DEVICE_OUT_FM_SPEAKER) { 7752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to FM Speakerphone (%d,%x)\n", mMode, outputDevices); 7762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_FM_SPEAKER; 7772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_DISABLE); 7782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (outputDevices & AudioSystem::DEVICE_OUT_FM_HEADPHONE) { 7792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 7802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to FM Headset and Speaker (%d,%x)\n", mMode, outputDevices); 7812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 7822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 7832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 7842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to FM Headset (%d,%x)\n", mMode, outputDevices); 7852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_FM_HEADSET; 7862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 7882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 7892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); 7902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 7912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 7922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 7932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); 7942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_NO_MIC_HEADSET; 7952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 7962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 7972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Wired Headset\n"); 7982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_HEADSET; 7992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 8002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Speakerphone\n"); 8012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_SPEAKER; 8022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 8032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 8042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("Routing audio to Handset\n"); 8052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland sndDevice = SND_DEVICE_HANDSET; 8062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (sndDevice != -1 && sndDevice != mCurSndDevice) { 8102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ret = doAudioRouteOrMute(sndDevice); 8112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mCurSndDevice = sndDevice; 8122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return ret; 8152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::checkMicMute() 8182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mLock); 8202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mMode != AudioSystem::MODE_IN_CALL) { 8212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland setMicMute_nosync(true); 8222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 8252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 8282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 8302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 8312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 8322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioHardware::dumpInternals\n"); 8332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 8342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 8352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 8362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 8372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 8382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 8392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); 8402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 8412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 8422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 8432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::dump(int fd, const Vector<String16>& args) 8462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland dumpInternals(fd, args); 8482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (size_t index = 0; index < mInputs.size(); index++) { 8492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mInputs[index]->dump(fd, args); 8502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mOutput) { 8532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mOutput->dump(fd, args); 8542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 8562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlanduint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) 8592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t i; 8612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t prevDelta; 8622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t delta; 8632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { 8652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland delta = abs(sampleRate - inputSamplingRates[i]); 8662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (delta > prevDelta) break; 8672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 8682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // i is always > 0 here 8692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return inputSamplingRates[i-1]; 8702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 8732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8742aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 8752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0) 8762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 8782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::set( 8802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 8812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 8822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int lFormat = pFormat ? *pFormat : 0; 8832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t lChannels = pChannels ? *pChannels : 0; 8842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t lRate = pRate ? *pRate : 0; 8852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware = hw; 8872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // fix up defaults 8892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lFormat == 0) lFormat = format(); 8902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lChannels == 0) lChannels = channels(); 8912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (lRate == 0) lRate = sampleRate(); 8922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 8932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // check values 8942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if ((lFormat != format()) || 8952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (lChannels != channels()) || 8962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland (lRate != sampleRate())) { 8972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat) *pFormat = format(); 8982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels) *pChannels = channels(); 8992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate) *pRate = sampleRate(); 9002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 9012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat) *pFormat = lFormat; 9042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels) *pChannels = lChannels; 9052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate) *pRate = lRate; 9062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = devices; 9082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 9102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 9112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9122aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 9132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 9142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) close(mFd); 9152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 9162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 9182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 9192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 9202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_INIT; 9212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland size_t count = bytes; 9222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const uint8_t* p = static_cast<const uint8_t*>(buffer); 9232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mStandby) { 9252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // open driver 9272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("open pcm_out driver"); 9282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ::open("/dev/msm_pcm_out", O_RDWR); 9292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 9302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errCount++ < 10) { 9312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 9322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 9342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = status; 9362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // configuration 9382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get config"); 9392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct msm_audio_config config; 9402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 9412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 9422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot read pcm_out config"); 9432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 9442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set pcm_out config"); 9472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.channel_count = AudioSystem::popCount(channels()); 9482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.sample_rate = sampleRate(); 9492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_size = bufferSize(); 9502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 9512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.codec_type = CODEC_TYPE_PCM; 9522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 9532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 9542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot set config"); 9552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 9562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_size: %u", config.buffer_size); 9592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_count: %u", config.buffer_count); 9602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("channel_count: %u", config.channel_count); 9612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("sample_rate: %u", config.sample_rate); 9622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 96331923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen status = ioctl(mFd, AUDIO_START, 0); 96431923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen if (status < 0) { 96531923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen LOGE("Cannot start pcm playback"); 96631923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen goto Error; 9672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 96831923bb6797ec304d26395acf6d946ab8e44aa6eHK Chen mStandby = false; 9692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland while (count) { 9722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t written = ::write(mFd, p, count); 9732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (written >= 0) { 9742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland count -= written; 9752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland p += written; 9762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 9772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errno != EAGAIN) return written; 9782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRetryCount++; 9792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("EAGAIN - retry"); 9802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return bytes; 9842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9852aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandError: 9862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 9872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 9882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 9892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 9902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // Simulate audio output timing in case of error 9912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland usleep(bytes * 1000000 / frameSize() / sampleRate()); 9922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 9942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 9952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 9962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::standby() 9972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 9982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 9992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mStandby && mFd >= 0) { 10002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 10012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 10022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mStandby = true; 10042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("AudioHardware pcm playback is going to standby."); 10052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 10062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 10072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 10092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 10102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 10112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 10122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 10132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioStreamOutMSM72xx::dump\n"); 10142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 10152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 10162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 10172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 10182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 10192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 10202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 10212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 10222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 10232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 10242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 10252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 10262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 10272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 10282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 10292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 10302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 10312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 10322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 10332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 10342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 10352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandbool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 10372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 10382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return mStandby; 10392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 10402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) 10432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 10442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 10452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 10462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 10472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int device; 10482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); 10492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.getInt(key, device) == NO_ERROR) { 10512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = device; 10522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set output routing %x", mDevices); 10532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = mHardware->doRouting(NULL); 10542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.remove(key); 10552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.size()) { 10582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 10592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 10612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 10622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10632aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) 10642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 10652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keys); 10662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 10672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 10682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 10702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get routing %x", mDevices); 10712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.addInt(key, (int)mDevices); 10722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); 10752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return param.toString(); 10762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 10772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 10802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10812aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 10822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), 10832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), 10842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE), 10852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) 10862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 10872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 10882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 10892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::set( 10902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, 10912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioSystem::audio_in_acoustics acoustic_flags) 10922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 10932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) { 10942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pFormat = AUDIO_HW_IN_FORMAT; 10952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 10962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 10972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pRate == 0) { 10982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 10992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint32_t rate = hw->getInputSampleRate(*pRate); 11012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (rate != *pRate) { 11022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pRate = rate; 11032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 11042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO && 11072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels != AudioSystem::CHANNEL_IN_STEREO)) { 11082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AUDIO_HW_IN_CHANNELS; 11092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return BAD_VALUE; 11102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware = hw; 11132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); 11152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 11162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Audio record already open"); 11172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -EPERM; 11182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // open audio input device 11212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 11222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 11232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 11242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 11252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = status; 11272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland // configuration 11292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get config"); 11302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland struct msm_audio_config config; 11312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 11322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 11332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot read config"); 11342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 11352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set config"); 11382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.channel_count = AudioSystem::popCount(*pChannels); 11392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.sample_rate = *pRate; 11402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_size = bufferSize(); 11412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.buffer_count = 2; 11422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland config.codec_type = CODEC_TYPE_PCM; 11432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 11442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 11452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot set config"); 11462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) { 11472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (config.channel_count == 1) { 11482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AudioSystem::CHANNEL_IN_MONO; 11492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 11502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pChannels = AudioSystem::CHANNEL_IN_STEREO; 11512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland *pRate = config.sample_rate; 11532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 11552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("confirm config"); 11582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 11592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (status < 0) { 11602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Cannot read config"); 11612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland goto Error; 11622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_size: %u", config.buffer_size); 11642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("buffer_count: %u", config.buffer_count); 11652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("channel_count: %u", config.channel_count); 11662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("sample_rate: %u", config.sample_rate); 11672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = devices; 11692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFormat = AUDIO_HW_IN_FORMAT; 11702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mChannels = *pChannels; 11712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mSampleRate = config.sample_rate; 11722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mBufferSize = config.buffer_size; 11732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland //mHardware->setMicMute_nosync(false); 11752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mState = AUDIO_INPUT_OPENED; 11762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 11782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11792aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandError: 11802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 11812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 11822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 11832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 11842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 11852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 11862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11872aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandAudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 11882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 11892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx destructor"); 11902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland standby(); 11912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 11922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 11942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 11952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 11962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mHardware) return -1; 11972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 11982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland size_t count = bytes; 11992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland uint8_t* p = static_cast<uint8_t*>(buffer); 12002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mState < AUDIO_INPUT_OPENED) { 12022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland Mutex::Autolock lock(mHardware->mLock); 12032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) { 12042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 12052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (support_a1026 == 1) { 12092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mHardware) { 12102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware->set_mRecordState(1); 12112aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware->doAudience_A1026_Control(mHardware->get_mMode(), 1, mHardware->get_snd_dev()); 12122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mState < AUDIO_INPUT_STARTED) { 12162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (ioctl(mFd, AUDIO_START, 0)) { 12172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGE("Error starting record"); 12182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return -1; 12192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("AUDIO_START: start kernel pcm_in driver."); 12212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mState = AUDIO_INPUT_STARTED; 12222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland while (count) { 12252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ssize_t bytesRead = ::read(mFd, buffer, count); 12262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (bytesRead >= 0) { 12272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland count -= bytesRead; 12282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland p += bytesRead; 12292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 12302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (errno != EAGAIN) return bytesRead; 12312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mRetryCount++; 12322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGW("EAGAIN - retrying"); 12332aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12342aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12352aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return bytes; 12362aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12372aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12382aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::standby() 12392aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 12402aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (support_a1026 == 1) { 12412aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mHardware) { 12422aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware->set_mRecordState(0); 12432aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mHardware->doAudience_A1026_Control(mHardware->get_mMode(), 0, mHardware->get_snd_dev()); 12442aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12452aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12462aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12472aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (!mHardware) return -1; 12482aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mState > AUDIO_INPUT_CLOSED) { 12492aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (mFd >= 0) { 12502aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::close(mFd); 12512aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mFd = -1; 12522aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12532aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland //mHardware->checkMicMute(); 12542aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mState = AUDIO_INPUT_CLOSED; 12552aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 12562aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGI("AudioHardware PCM record is going to standby."); 12572aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 12582aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12592aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12602aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 12612aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 12622aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland const size_t SIZE = 256; 12632aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland char buffer[SIZE]; 12642aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 result; 12652aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append("AudioStreamInMSM72xx::dump\n"); 12662aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 12672aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12682aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 12692aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12702aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 12712aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12722aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tformat: %d\n", format()); 12732aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12742aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 12752aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12762aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 12772aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12782aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmState: %d\n", mState); 12792aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12802aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 12812aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland result.append(buffer); 12822aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland ::write(fd, result.string(), result.size()); 12832aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return NO_ERROR; 12842aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 12852aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12862aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandstatus_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs) 12872aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 12882aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keyValuePairs); 12892aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 12902aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status_t status = NO_ERROR; 12912aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland int device; 12922aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string()); 12932aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 12942aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.getInt(key, device) == NO_ERROR) { 12952aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("set input routing %x", device); 12962aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (device & (device - 1)) { 12972aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 12982aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } else { 12992aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland mDevices = device; 13002aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = mHardware->doRouting(this); 13012aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13022aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.remove(key); 13032aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13042aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13052aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.size()) { 13062aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland status = BAD_VALUE; 13072aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13082aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return status; 13092aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 13102aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13112aec439308494aa1607e7c1bb32e99863fe32dc6Brian SwetlandString8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys) 13122aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland{ 13132aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland AudioParameter param = AudioParameter(keys); 13142aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 value; 13152aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland String8 key = String8(AudioParameter::keyRouting); 13162aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13172aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland if (param.get(key, value) == NO_ERROR) { 13182aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("get routing %x", mDevices); 13192aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland param.addInt(key, (int)mDevices); 13202aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland } 13212aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13222aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland LOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string()); 13232aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return param.toString(); 13242aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 13252aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13262aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland// ---------------------------------------------------------------------------- 13272aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13282aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetlandextern "C" AudioHardwareInterface* createAudioHardware(void) { 13292aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland return new AudioHardware(); 13302aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland} 13312aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland 13322aec439308494aa1607e7c1bb32e99863fe32dc6Brian Swetland}; // namespace android 1333