Bug 852497 - Add a standard V4L2 mode to GonkFMRadio.cpp, r=dhylands

This commit is contained in:
Michael Wu 2013-11-14 15:02:30 -05:00
parent 493777b207
commit 354c63f3e7

View File

@ -37,6 +37,7 @@ static bool sRadioEnabled;
static pthread_t sRadioThread;
static hal::FMRadioSettings sRadioSettings;
static int sTavaruaVersion;
static bool sTavaruaMode;
static int
setControl(uint32_t id, int32_t value)
@ -148,6 +149,7 @@ initTavaruaRadio(hal::FMRadioSettings &aInfo)
struct v4l2_tuner tuner = {0};
tuner.rangelow = (aInfo.lowerLimit() * 10000) / 625;
tuner.rangehigh = (aInfo.upperLimit() * 10000) / 625;
tuner.audmode = V4L2_TUNER_MODE_STEREO;
rc = ioctl(fd, VIDIOC_S_TUNER, &tuner);
if (rc < 0) {
HAL_LOG(("Unable to adjust band limits"));
@ -220,6 +222,8 @@ runTavaruaRadio(void *)
break;
}
/* The tavarua driver reports a number of things asynchronously.
* In those cases, the status update comes from this thread. */
for (unsigned int i = 0; i < buffer.bytesused; i++) {
switch (buf[i]) {
case TAVARUA_EVT_RADIO_READY:
@ -230,6 +234,7 @@ runTavaruaRadio(void *)
hal::FM_RADIO_OPERATION_STATUS_SUCCESS));
}
break;
case TAVARUA_EVT_SEEK_COMPLETE:
NS_DispatchToMainThread(new RadioUpdate(hal::FM_RADIO_OPERATION_SEEK,
hal::FM_RADIO_OPERATION_STATUS_SUCCESS));
@ -270,6 +275,7 @@ EnableFMRadio(const hal::FMRadioSettings& aInfo)
return;
}
sTavaruaMode = !strcmp((char *)cap.driver, "radio-tavarua");
HAL_LOG(("Radio: %s (%s)\n", cap.driver, cap.card));
if (!(cap.capabilities & V4L2_CAP_RADIO)) {
@ -281,13 +287,32 @@ EnableFMRadio(const hal::FMRadioSettings& aInfo)
HAL_LOG(("/dev/radio0 doesn't support the tuner interface"));
return;
}
sRadioFD = fd.forget();
sRadioSettings = aInfo;
// Tavarua specific start
sTavaruaVersion = cap.version;
pthread_create(&sRadioThread, nullptr, runTavaruaRadio, nullptr);
// Tavarua specific end
if (sTavaruaMode) {
sRadioFD = fd.forget();
sTavaruaVersion = cap.version;
pthread_create(&sRadioThread, nullptr, runTavaruaRadio, nullptr);
return;
}
struct v4l2_tuner tuner = {0};
tuner.type = V4L2_TUNER_RADIO;
tuner.rangelow = (aInfo.lowerLimit() * 10000) / 625;
tuner.rangehigh = (aInfo.upperLimit() * 10000) / 625;
tuner.audmode = V4L2_TUNER_MODE_STEREO;
rc = ioctl(fd, VIDIOC_S_TUNER, &tuner);
if (rc < 0) {
HAL_LOG(("Unable to adjust band limits"));
}
sRadioFD = fd.forget();
sRadioEnabled = true;
hal::FMRadioOperationInformation info;
info.operation() = hal::FM_RADIO_OPERATION_ENABLE;
info.status() = hal::FM_RADIO_OPERATION_STATUS_SUCCESS;
hal::NotifyFMRadioStatus(info);
}
void
@ -298,14 +323,14 @@ DisableFMRadio()
sRadioEnabled = false;
// Tavarua specific start
int rc = setControl(V4L2_CID_PRIVATE_TAVARUA_STATE, FM_OFF);
if (rc < 0) {
HAL_LOG(("Unable to turn off radio"));
}
// Tavarua specific end
if (sTavaruaMode) {
int rc = setControl(V4L2_CID_PRIVATE_TAVARUA_STATE, FM_OFF);
if (rc < 0) {
HAL_LOG(("Unable to turn off radio"));
}
pthread_join(sRadioThread, nullptr);
pthread_join(sRadioThread, nullptr);
}
close(sRadioFD);
@ -321,11 +346,32 @@ FMRadioSeek(const hal::FMRadioSeekDirection& aDirection)
struct v4l2_hw_freq_seek seek = {0};
seek.type = V4L2_TUNER_RADIO;
seek.seek_upward = aDirection == hal::FMRadioSeekDirection::FM_RADIO_SEEK_DIRECTION_UP;
/* ICS and older don't have the spacing field */
#if ANDROID_VERSION == 15
seek.reserved[0] = sRadioSettings.spaceType() * 1000;
#else
seek.spacing = sRadioSettings.spaceType() * 1000;
#endif
int rc = ioctl(sRadioFD, VIDIOC_S_HW_FREQ_SEEK, &seek);
if (sTavaruaMode && rc >= 0)
return;
hal::FMRadioOperationInformation info;
info.operation() = hal::FM_RADIO_OPERATION_SEEK;
info.status() = rc < 0 ? hal::FM_RADIO_OPERATION_STATUS_FAIL :
hal::FM_RADIO_OPERATION_STATUS_SUCCESS;
hal::NotifyFMRadioStatus(info);
if (rc < 0) {
HAL_LOG(("Could not initiate hardware seek"));
return;
}
info.operation() = hal::FM_RADIO_OPERATION_TUNE;
info.status() = hal::FM_RADIO_OPERATION_STATUS_SUCCESS;
hal::NotifyFMRadioStatus(info);
}
void
@ -356,6 +402,15 @@ SetFMRadioFrequency(const uint32_t frequency)
int rc = ioctl(sRadioFD, VIDIOC_S_FREQUENCY, &freq);
if (rc < 0)
HAL_LOG(("Could not set radio frequency"));
if (sTavaruaMode && rc >= 0)
return;
hal::FMRadioOperationInformation info;
info.operation() = hal::FM_RADIO_OPERATION_TUNE;
info.status() = rc < 0 ? hal::FM_RADIO_OPERATION_STATUS_FAIL :
hal::FM_RADIO_OPERATION_STATUS_SUCCESS;
hal::NotifyFMRadioStatus(info);
}
uint32_t