summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawit Pornkitprasan <p.pawit@gmail.com>2011-08-25 18:45:44 +0700
committerPawit Pornkitprasan <p.pawit@gmail.com>2011-08-26 07:34:36 +0700
commitc4ac9e2cbf5521f857b1255f1ee48d9713e7ba78 (patch)
treebc69ce1cd9515327bebc9742b06a8bba1d48a3cc
parent259752f4761b3464b1e3ad7dc224cf514dd9d7c3 (diff)
downloaddevice_samsung_aries-common-c4ac9e2cbf5521f857b1255f1ee48d9713e7ba78.zip
device_samsung_aries-common-c4ac9e2cbf5521f857b1255f1ee48d9713e7ba78.tar.gz
device_samsung_aries-common-c4ac9e2cbf5521f857b1255f1ee48d9713e7ba78.tar.bz2
libaudio: Improve FM Radio
- Set the volume control of the Si4709 chip (I891574d6 originally did this) - Set the playback path to HP, HP_NO_MIC, SPK as appropriate (allows WM8994 to apply its analog gain) - Turn off FM Radio properly to allow WM8994 to be turned off after disabling FM Radio (fixes battery drain and routing problems which caused FM Radio to be mute if you listen to FM, listen to music and listen to FM again.) Change-Id: Id04aaddc6de5ffe1c0826bea33fc8ec633afd419
-rw-r--r--libaudio/AudioHardware.cpp60
-rw-r--r--libaudio/AudioHardware.h7
2 files changed, 60 insertions, 7 deletions
diff --git a/libaudio/AudioHardware.cpp b/libaudio/AudioHardware.cpp
index 939c54c..c2efbd1 100644
--- a/libaudio/AudioHardware.cpp
+++ b/libaudio/AudioHardware.cpp
@@ -40,6 +40,10 @@ extern "C" {
#include "alsa_audio.h"
}
+#ifdef HAVE_FM_RADIO
+#define Si4709_IOC_MAGIC 0xFA
+#define Si4709_IOC_VOLUME_SET _IOW(Si4709_IOC_MAGIC, 15, __u8)
+#endif
namespace android {
@@ -92,6 +96,9 @@ AudioHardware::AudioHardware() :
mSecRilLibHandle(NULL),
mRilClient(0),
mActivatedCP(false),
+#ifdef HAVE_FM_RADIO
+ mFmFd(-1),
+#endif
mDriverOp(DRV_NONE)
{
loadRILD();
@@ -523,6 +530,10 @@ status_t AudioHardware::setParameters(const String8& keyValuePairs)
LOGV("AudioHardware::setParameters() FM Radio is ON, calling setFMRadioPath_l()");
setFMRadioPath_l(mOutput->device());
}
+
+ if (mFmFd < 0) {
+ mFmFd = open("/dev/radio0", O_RDWR);
+ }
}
param.remove(key);
@@ -532,22 +543,27 @@ status_t AudioHardware::setParameters(const String8& keyValuePairs)
LOGV("AudioHardware::setParameters() Turning FM Radio OFF");
if (mMixer != NULL) {
+ // Disable FM radio flag to allow the codec to be turned off
+ // (the flag is automatically set by the kernel driver when FM is enabled)
+ // No need to turn off the FM Radio path as the kernel driver will handle that
TRACE_DRIVER_IN(DRV_MIXER_GET)
- struct mixer_ctl *ctl= mixer_get_control(mMixer, "FM Radio Path", 0);
+ struct mixer_ctl *ctl = mixer_get_control(mMixer, "Codec Status", 0);
TRACE_DRIVER_OUT
if (ctl != NULL) {
TRACE_DRIVER_IN(DRV_MIXER_SEL)
- mixer_ctl_select(ctl, "FMR_MIX_OFF");
- TRACE_DRIVER_OUT
-
- TRACE_DRIVER_IN(DRV_MIXER_SEL)
- mixer_ctl_select(ctl, "FMR_OFF");
+ mixer_ctl_select(ctl, "FMR_FLAG_CLEAR");
TRACE_DRIVER_OUT
}
+
closeMixer_l();
closePcmOut_l();
}
+
+ if (mFmFd > 0) {
+ close(mFmFd);
+ mFmFd = -1;
+ }
}
param.remove(key);
#endif
@@ -645,6 +661,21 @@ status_t AudioHardware::setMasterVolume(float volume)
return -1;
}
+#ifdef HAVE_FM_RADIO
+status_t AudioHardware::setFmVolume(float v)
+{
+ if (mFmFd > 0) {
+ __u8 fmVolume = (AudioSystem::logToLinear(v) + 5) / 7;
+ LOGD("%s %f %d", __func__, v, (int) fmVolume);
+ if (ioctl(mFmFd, Si4709_IOC_VOLUME_SET, &fmVolume) < 0) {
+ LOGE("set_volume_fm error.");
+ return -EIO;
+ }
+ }
+ return NO_ERROR;
+}
+#endif
+
static const int kDumpLockRetries = 50;
static const int kDumpLockSleep = 20000;
@@ -828,7 +859,22 @@ status_t AudioHardware::setFMRadioPath_l(uint32_t device)
mixer_ctl_select(ctl, fmpath);
TRACE_DRIVER_OUT
} else {
- LOGE("setFMRadioPath_l() could not get mixer ctl");
+ LOGE("setFMRadioPath_l() could not get FM Radio Path mixer ctl");
+ }
+
+ TRACE_DRIVER_IN(DRV_MIXER_GET)
+ ctl = mixer_get_control(mMixer, "Playback Path", 0);
+ TRACE_DRIVER_OUT
+
+ const char *route = getOutputRouteFromDevice(device);
+ LOGV("setFMRadioPath_l() Playpack Path, (%s)", route);
+ if (ctl) {
+ TRACE_DRIVER_IN(DRV_MIXER_SEL)
+ mixer_ctl_select(ctl, route);
+ TRACE_DRIVER_OUT
+ }
+ else {
+ LOGE("setFMRadioPath_l() could not get Playback Path mixer ctl");
}
} else {
LOGE("setFMRadioPath_l() mixer is not open");
diff --git a/libaudio/AudioHardware.h b/libaudio/AudioHardware.h
index 71f11e7..b50e273 100644
--- a/libaudio/AudioHardware.h
+++ b/libaudio/AudioHardware.h
@@ -86,6 +86,9 @@ public:
virtual status_t setVoiceVolume(float volume);
virtual status_t setMasterVolume(float volume);
+#ifdef HAVE_FM_RADIO
+ virtual status_t setFmVolume(float volume);
+#endif
virtual status_t setMode(int mode);
@@ -177,6 +180,10 @@ private:
void loadRILD(void);
status_t connectRILDIfRequired(void);
+#ifdef HAVE_FM_RADIO
+ int mFmFd;
+#endif
+
// trace driver operations for dump
int mDriverOp;