Bug 749053 - FM radio support: hal implementation, r=jlebar

Hal interface by Steven Lee (slee), gonk backend by Michael Wu (mwu).
This commit is contained in:
Steven Lee 2012-09-19 11:17:13 -04:00
parent 7a94fba3ec
commit 928a3692d4
9 changed files with 1424 additions and 1 deletions

View File

@ -781,5 +781,208 @@ SetProcessPriority(int aPid, ProcessPriority aPriority)
}
}
static StaticAutoPtr<ObserverList<FMRadioOperationInformation> > sFMRadioObservers;
static void
InitializeFMRadioObserver()
{
if (!sFMRadioObservers) {
sFMRadioObservers = new ObserverList<FMRadioOperationInformation>;
ClearOnShutdown(&sFMRadioObservers);
}
}
void
RegisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
AssertMainThread();
InitializeFMRadioObserver();
sFMRadioObservers->AddObserver(aFMRadioObserver);
}
void
UnregisterFMRadioObserver(FMRadioObserver* aFMRadioObserver) {
AssertMainThread();
InitializeFMRadioObserver();
sFMRadioObservers->RemoveObserver(aFMRadioObserver);
}
void
NotifyFMRadioStatus(const FMRadioOperationInformation& aFMRadioState) {
InitializeFMRadioObserver();
sFMRadioObservers->Broadcast(aFMRadioState);
}
void
EnableFMRadio(const FMRadioSettings& aInfo) {
AssertMainThread();
PROXY_IF_SANDBOXED(EnableFMRadio(aInfo));
}
void
DisableFMRadio() {
AssertMainThread();
PROXY_IF_SANDBOXED(DisableFMRadio());
}
void
FMRadioSeek(const FMRadioSeekDirection& aDirection) {
AssertMainThread();
PROXY_IF_SANDBOXED(FMRadioSeek(aDirection));
}
void
GetFMRadioSettings(FMRadioSettings* aInfo) {
AssertMainThread();
PROXY_IF_SANDBOXED(GetFMRadioSettings(aInfo));
}
void
SetFMRadioFrequency(const uint32_t aFrequency) {
AssertMainThread();
PROXY_IF_SANDBOXED(SetFMRadioFrequency(aFrequency));
}
uint32_t
GetFMRadioFrequency() {
AssertMainThread();
RETURN_PROXY_IF_SANDBOXED(GetFMRadioFrequency());
}
bool
IsFMRadioOn() {
AssertMainThread();
RETURN_PROXY_IF_SANDBOXED(IsFMRadioOn());
}
uint32_t
GetFMRadioSignalStrength() {
AssertMainThread();
RETURN_PROXY_IF_SANDBOXED(GetFMRadioSignalStrength());
}
void
CancelFMRadioSeek() {
AssertMainThread();
PROXY_IF_SANDBOXED(CancelFMRadioSeek());
}
FMRadioSettings
GetFMBandSettings(FMRadioCountry aCountry) {
FMRadioSettings settings;
switch (aCountry) {
case FM_RADIO_COUNTRY_US:
case FM_RADIO_COUNTRY_EU:
settings.upperLimit() = 108000;
settings.lowerLimit() = 87800;
settings.spaceType() = 200;
settings.preEmphasis() = 75;
break;
case FM_RADIO_COUNTRY_JP_STANDARD:
settings.upperLimit() = 76000;
settings.lowerLimit() = 90000;
settings.spaceType() = 100;
settings.preEmphasis() = 50;
break;
case FM_RADIO_COUNTRY_CY:
case FM_RADIO_COUNTRY_DE:
case FM_RADIO_COUNTRY_DK:
case FM_RADIO_COUNTRY_ES:
case FM_RADIO_COUNTRY_FI:
case FM_RADIO_COUNTRY_FR:
case FM_RADIO_COUNTRY_HU:
case FM_RADIO_COUNTRY_IR:
case FM_RADIO_COUNTRY_IT:
case FM_RADIO_COUNTRY_KW:
case FM_RADIO_COUNTRY_LT:
case FM_RADIO_COUNTRY_ML:
case FM_RADIO_COUNTRY_NO:
case FM_RADIO_COUNTRY_OM:
case FM_RADIO_COUNTRY_PG:
case FM_RADIO_COUNTRY_NL:
case FM_RADIO_COUNTRY_CZ:
case FM_RADIO_COUNTRY_UK:
case FM_RADIO_COUNTRY_RW:
case FM_RADIO_COUNTRY_SN:
case FM_RADIO_COUNTRY_SI:
case FM_RADIO_COUNTRY_ZA:
case FM_RADIO_COUNTRY_SE:
case FM_RADIO_COUNTRY_CH:
case FM_RADIO_COUNTRY_TW:
case FM_RADIO_COUNTRY_UA:
settings.upperLimit() = 108000;
settings.lowerLimit() = 87500;
settings.spaceType() = 100;
settings.preEmphasis() = 50;
break;
case FM_RADIO_COUNTRY_VA:
case FM_RADIO_COUNTRY_MA:
case FM_RADIO_COUNTRY_TR:
settings.upperLimit() = 10800;
settings.lowerLimit() = 87500;
settings.spaceType() = 100;
settings.preEmphasis() = 75;
break;
case FM_RADIO_COUNTRY_AU:
case FM_RADIO_COUNTRY_BD:
settings.upperLimit() = 108000;
settings.lowerLimit() = 87500;
settings.spaceType() = 200;
settings.preEmphasis() = 75;
break;
case FM_RADIO_COUNTRY_AW:
case FM_RADIO_COUNTRY_BS:
case FM_RADIO_COUNTRY_CO:
case FM_RADIO_COUNTRY_KR:
settings.upperLimit() = 108000;
settings.lowerLimit() = 88000;
settings.spaceType() = 200;
settings.preEmphasis() = 75;
break;
case FM_RADIO_COUNTRY_EC:
settings.upperLimit() = 108000;
settings.lowerLimit() = 88000;
settings.spaceType() = 200;
settings.preEmphasis() = 0;
break;
case FM_RADIO_COUNTRY_GM:
settings.upperLimit() = 108000;
settings.lowerLimit() = 88000;
settings.spaceType() = 0;
settings.preEmphasis() = 75;
break;
case FM_RADIO_COUNTRY_QA:
settings.upperLimit() = 108000;
settings.lowerLimit() = 88000;
settings.spaceType() = 200;
settings.preEmphasis() = 50;
break;
case FM_RADIO_COUNTRY_SG:
settings.upperLimit() = 108000;
settings.lowerLimit() = 88000;
settings.spaceType() = 200;
settings.preEmphasis() = 50;
break;
case FM_RADIO_COUNTRY_IN:
settings.upperLimit() = 100000;
settings.lowerLimit() = 108000;
settings.spaceType() = 100;
settings.preEmphasis() = 50;
break;
case FM_RADIO_COUNTRY_NZ:
settings.upperLimit() = 100000;
settings.lowerLimit() = 88000;
settings.spaceType() = 50;
settings.preEmphasis() = 50;
break;
case FM_RADIO_COUNTRY_USER_DEFINED:
break;
default:
MOZ_ASSERT(0);
break;
};
return settings;
}
} // namespace hal
} // namespace mozilla

View File

@ -437,6 +437,73 @@ bool SetAlarm(int32_t aSeconds, int32_t aNanoseconds);
*/
void SetProcessPriority(int aPid, hal::ProcessPriority aPriority);
/**
* Register an observer for the FM radio.
*/
void RegisterFMRadioObserver(hal::FMRadioObserver* aRadioObserver);
/**
* Unregister the observer for the FM radio.
*/
void UnregisterFMRadioObserver(hal::FMRadioObserver* aRadioObserver);
/**
* Notify observers that a call to EnableFMRadio, DisableFMRadio, or FMRadioSeek
* has completed, and indicate what the call returned.
*/
void NotifyFMRadioStatus(const hal::FMRadioOperationInformation& aRadioState);
/**
* Enable the FM radio and configure it according to the settings in aInfo.
*/
void EnableFMRadio(const hal::FMRadioSettings& aInfo);
/**
* Disable the FM radio.
*/
void DisableFMRadio();
/**
* Seek to an available FM radio station.
*
*/
void FMRadioSeek(const hal::FMRadioSeekDirection& aDirection);
/**
* Get the current FM radio settings.
*/
void GetFMRadioSettings(hal::FMRadioSettings* aInfo);
/**
* Set the FM radio's frequency.
*/
void SetFMRadioFrequency(const uint32_t frequency);
/**
* Get the FM radio's frequency.
*/
uint32_t GetFMRadioFrequency();
/**
* Get FM radio power state
*/
bool IsFMRadioOn();
/**
* Get FM radio signal strength
*/
uint32_t GetFMRadioSignalStrength();
/**
* Cancel FM radio seeking
*/
void CancelFMRadioSeek();
/**
* Get FM radio band settings by country.
*/
hal::FMRadioSettings GetFMBandSettings(hal::FMRadioCountry aCountry);
} // namespace MOZ_HAL_NAMESPACE
} // namespace mozilla

View File

@ -81,6 +81,82 @@ enum SystemTimeChange {
SYS_TIME_CHANGE_GUARD
};
class FMRadioOperationInformation;
enum FMRadioOperation {
FM_RADIO_OPERATION_UNKNOWN = -1,
FM_RADIO_OPERATION_ENABLE,
FM_RADIO_OPERATION_DISABLE,
FM_RADIO_OPERATION_SEEK,
NUM_FM_RADIO_OPERATION
};
enum FMRadioOperationStatus {
FM_RADIO_OPERATION_STATUS_UNKNOWN = -1,
FM_RADIO_OPERATION_STATUS_SUCCESS,
FM_RADIO_OPERATION_STATUS_FAIL,
NUM_FM_RADIO_OPERATION_STATUS
};
enum FMRadioSeekDirection {
FM_RADIO_SEEK_DIRECTION_UNKNOWN = -1,
FM_RADIO_SEEK_DIRECTION_UP,
FM_RADIO_SEEK_DIRECTION_DOWN,
NUM_FM_RADIO_SEEK_DIRECTION
};
enum FMRadioCountry {
FM_RADIO_COUNTRY_UNKNOWN = -1,
FM_RADIO_COUNTRY_US, //USA
FM_RADIO_COUNTRY_EU,
FM_RADIO_COUNTRY_JP_STANDARD,
FM_RADIO_COUNTRY_JP_WIDE,
FM_RADIO_COUNTRY_DE, //Germany
FM_RADIO_COUNTRY_AW, //Aruba
FM_RADIO_COUNTRY_AU, //Australlia
FM_RADIO_COUNTRY_BS, //Bahamas
FM_RADIO_COUNTRY_BD, //Bangladesh
FM_RADIO_COUNTRY_CY, //Cyprus
FM_RADIO_COUNTRY_VA, //Vatican
FM_RADIO_COUNTRY_CO, //Colombia
FM_RADIO_COUNTRY_KR, //Korea
FM_RADIO_COUNTRY_DK, //Denmark
FM_RADIO_COUNTRY_EC, //Ecuador
FM_RADIO_COUNTRY_ES, //Spain
FM_RADIO_COUNTRY_FI, //Finland
FM_RADIO_COUNTRY_FR, //France
FM_RADIO_COUNTRY_GM, //Gambia
FM_RADIO_COUNTRY_HU, //Hungary
FM_RADIO_COUNTRY_IN, //India
FM_RADIO_COUNTRY_IR, //Iran
FM_RADIO_COUNTRY_IT, //Italy
FM_RADIO_COUNTRY_KW, //Kuwait
FM_RADIO_COUNTRY_LT, //Lithuania
FM_RADIO_COUNTRY_ML, //Mali
FM_RADIO_COUNTRY_MA, //Morocco
FM_RADIO_COUNTRY_NO, //Norway
FM_RADIO_COUNTRY_NZ, //New Zealand
FM_RADIO_COUNTRY_OM, //Oman
FM_RADIO_COUNTRY_PG, //Papua New Guinea
FM_RADIO_COUNTRY_NL, //Netherlands
FM_RADIO_COUNTRY_QA, //Qatar
FM_RADIO_COUNTRY_CZ, //Czech Republic
FM_RADIO_COUNTRY_UK, //United Kingdom of Great Britain and Northern Ireland
FM_RADIO_COUNTRY_RW, //Rwandese Republic
FM_RADIO_COUNTRY_SN, //Senegal
FM_RADIO_COUNTRY_SG, //Singapore
FM_RADIO_COUNTRY_SI, //Slovenia
FM_RADIO_COUNTRY_ZA, //South Africa
FM_RADIO_COUNTRY_SE, //Sweden
FM_RADIO_COUNTRY_CH, //Switzerland
FM_RADIO_COUNTRY_TW, //Taiwan
FM_RADIO_COUNTRY_TR, //Turkey
FM_RADIO_COUNTRY_UA, //Ukraine
FM_RADIO_COUNTRY_USER_DEFINED,
NUM_FM_RADIO_COUNTRY
};
typedef Observer<FMRadioOperationInformation> FMRadioObserver;
} // namespace hal
} // namespace mozilla
@ -163,6 +239,45 @@ struct ParamTraits<mozilla::hal::SystemTimeChange>
mozilla::hal::SYS_TIME_CHANGE_GUARD>
{};
/**
* Serializer for FMRadioOperation
*/
template <>
struct ParamTraits<mozilla::hal::FMRadioOperation>:
public EnumSerializer<mozilla::hal::FMRadioOperation,
mozilla::hal::FM_RADIO_OPERATION_UNKNOWN,
mozilla::hal::NUM_FM_RADIO_OPERATION>
{};
/**
* Serializer for FMRadioOperationStatus
*/
template <>
struct ParamTraits<mozilla::hal::FMRadioOperationStatus>:
public EnumSerializer<mozilla::hal::FMRadioOperationStatus,
mozilla::hal::FM_RADIO_OPERATION_STATUS_UNKNOWN,
mozilla::hal::NUM_FM_RADIO_OPERATION_STATUS>
{};
/**
* Serializer for FMRadioSeekDirection
*/
template <>
struct ParamTraits<mozilla::hal::FMRadioSeekDirection>:
public EnumSerializer<mozilla::hal::FMRadioSeekDirection,
mozilla::hal::FM_RADIO_SEEK_DIRECTION_UNKNOWN,
mozilla::hal::NUM_FM_RADIO_SEEK_DIRECTION>
{};
/**
* Serializer for FMRadioCountry
**/
template <>
struct ParamTraits<mozilla::hal::FMRadioCountry>:
public EnumSerializer<mozilla::hal::FMRadioCountry,
mozilla::hal::FM_RADIO_COUNTRY_UNKNOWN,
mozilla::hal::NUM_FM_RADIO_COUNTRY>
{};
} // namespace IPC
#endif // mozilla_hal_Types_h

View File

@ -57,6 +57,7 @@ CPPSRCS += \
GonkSensor.cpp \
UeventPoller.cpp \
GonkSwitch.cpp \
GonkFMRadio.cpp \
$(NULL)
else ifeq (Linux,$(OS_TARGET))
CPPSRCS += \
@ -125,6 +126,7 @@ CPPSRCS += \
FallbackSwitch.cpp \
FallbackScreenPower.cpp \
FallbackProcessPriority.cpp \
FallbackFMRadio.cpp \
$(NULL)
endif #}

View File

@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Hal.h"
namespace mozilla {
namespace hal_impl {
void
EnableFMRadio(const hal::FMRadioSettings& aInfo)
{}
void
DisableFMRadio()
{}
void
FMRadioSeek(const hal::FMRadioSeekDirection& aDirection)
{}
void
GetFMRadioSettings(hal::FMRadioSettings* aInfo)
{
aInfo->country() = hal::FM_RADIO_COUNTRY_UNKNOWN;
aInfo->upperLimit() = 0;
aInfo->lowerLimit() = 0;
aInfo->spaceType() = 0;
aInfo->preEmphasis() = 0;
}
void
SetFMRadioFrequency(const uint32_t frequency)
{}
uint32_t
GetFMRadioFrequency()
{
return 0;
}
bool
IsFMRadioOn()
{
return false;
}
uint32_t
GetFMRadioSignalStrength()
{
return 0;
}
void
CancelFMRadioSeek()
{}
} // hal_impl
} // namespace mozilla

324
hal/gonk/GonkFMRadio.cpp Normal file
View File

@ -0,0 +1,324 @@
/* Copyright 2012 Mozilla Foundation and Mozilla contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Hal.h"
#include "tavarua.h"
#include "nsThreadUtils.h"
#include "mozilla/FileUtils.h"
#include <errno.h>
#include <fcntl.h>
#include <linux/videodev2.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
namespace mozilla {
namespace hal_impl {
uint32_t GetFMRadioFrequency();
static int sRadioFD;
static bool sRadioEnabled;
static pthread_t sMonitorThread;
static int
setControl(uint32_t id, int32_t value)
{
struct v4l2_control control;
control.id = id;
control.value = value;
return ioctl(sRadioFD, VIDIOC_S_CTRL, &control);
}
class RadioUpdate : public nsRunnable {
hal::FMRadioOperation mOp;
public:
RadioUpdate(hal::FMRadioOperation op)
: mOp(op)
{}
NS_IMETHOD Run() {
hal::FMRadioOperationInformation info;
info.operation() = mOp;
info.status() = hal::FM_RADIO_OPERATION_STATUS_SUCCESS;
info.frequency() = GetFMRadioFrequency();
hal::NotifyFMRadioStatus(info);
return NS_OK;
}
};
static void *
pollTavaruaRadio(void *)
{
uint8_t buf[128];
struct v4l2_buffer buffer = {0};
buffer.index = 1;
buffer.type = V4L2_BUF_TYPE_PRIVATE;
buffer.length = sizeof(buf);
buffer.m.userptr = (long unsigned int)buf;
while (sRadioEnabled) {
int rc = ioctl(sRadioFD, VIDIOC_DQBUF, &buffer);
if (rc)
return NULL;
for (unsigned int i = 0; i < buffer.bytesused; i++) {
switch (buf[i]) {
case TAVARUA_EVT_RADIO_READY:
NS_DispatchToMainThread(new RadioUpdate(hal::FM_RADIO_OPERATION_ENABLE));
break;
case TAVARUA_EVT_SEEK_COMPLETE:
NS_DispatchToMainThread(new RadioUpdate(hal::FM_RADIO_OPERATION_SEEK));
break;
default:
break;
}
}
}
return NULL;
}
void
EnableFMRadio(const hal::FMRadioSettings& aInfo)
{
if (sRadioEnabled) {
HAL_LOG(("Radio already enabled!"));
return;
}
mozilla::ScopedClose fd(open("/dev/radio0", O_RDWR));
if (fd < 0) {
HAL_LOG(("Unable to open radio device"));
return;
}
struct v4l2_capability cap;
int rc = ioctl(fd, VIDIOC_QUERYCAP, &cap);
if (rc < 0) {
HAL_LOG(("Unable to query radio device"));
return;
}
HAL_LOG(("Radio: %s (%s)\n", cap.driver, cap.card));
if (!(cap.capabilities & V4L2_CAP_RADIO)) {
HAL_LOG(("/dev/radio0 isn't a radio"));
return;
}
if (!(cap.capabilities & V4L2_CAP_TUNER)) {
HAL_LOG(("/dev/radio0 doesn't support the tuner interface"));
return;
}
sRadioFD = fd;
// Tavarua specific start
char command[64];
snprintf(command, sizeof(command), "/system/bin/fm_qsoc_patches %d 0", cap.version);
rc = system(command);
if (rc) {
HAL_LOG(("Unable to initialize radio"));
return;
}
rc = setControl(V4L2_CID_PRIVATE_TAVARUA_STATE, FM_RECV);
if (rc < 0) {
HAL_LOG(("Unable to turn on radio |%s|", strerror(errno)));
return;
}
int preEmphasis = aInfo.preEmphasis() <= 50;
rc = setControl(V4L2_CID_PRIVATE_TAVARUA_EMPHASIS, preEmphasis);
if (rc) {
HAL_LOG(("Unable to configure preemphasis"));
return;
}
rc = setControl(V4L2_CID_PRIVATE_TAVARUA_RDS_STD, 0);
if (rc) {
HAL_LOG(("Unable to configure RDS"));
return;
}
int spacing;
switch (aInfo.spaceType()) {
case 50:
spacing = FM_CH_SPACE_50KHZ;
break;
case 100:
spacing = FM_CH_SPACE_100KHZ;
break;
case 200:
spacing = FM_CH_SPACE_200KHZ;
break;
default:
HAL_LOG(("Unsupported space value - %d", aInfo.spaceType()));
return;
}
rc = setControl(V4L2_CID_PRIVATE_TAVARUA_SPACING, spacing);
if (rc) {
HAL_LOG(("Unable to configure spacing"));
return;
}
/*
* Frequency conversions
*
* HAL uses units of 1k for frequencies
* V4L2 uses units of 62.5kHz
* Multiplying by (10000 / 625) converts from HAL units to V4L2.
*/
struct v4l2_tuner tuner = {0};
tuner.rangelow = (aInfo.lowerLimit() * 10000) / 625;
tuner.rangehigh = (aInfo.upperLimit() * 10000) / 625;
rc = ioctl(fd, VIDIOC_S_TUNER, &tuner);
if (rc < 0) {
HAL_LOG(("Unable to adjust band limits"));
return;
}
rc = setControl(V4L2_CID_PRIVATE_TAVARUA_REGION, TAVARUA_REGION_OTHER);
if (rc < 0) {
HAL_LOG(("Unable to configure region"));
return;
}
rc = setControl(V4L2_CID_PRIVATE_TAVARUA_SET_AUDIO_PATH, FM_DIGITAL_PATH);
if (rc < 0) {
HAL_LOG(("Unable to set audio path"));
return;
}
pthread_create(&sMonitorThread, NULL, pollTavaruaRadio, NULL);
// Tavarua specific end
fd.forget();
sRadioEnabled = true;
}
void
DisableFMRadio()
{
if (!sRadioEnabled)
return;
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
pthread_join(sMonitorThread, NULL);
close(sRadioFD);
hal::FMRadioOperationInformation info;
info.operation() = hal::FM_RADIO_OPERATION_DISABLE;
info.status() = hal::FM_RADIO_OPERATION_STATUS_SUCCESS;
hal::NotifyFMRadioStatus(info);
}
void
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;
int rc = ioctl(sRadioFD, VIDIOC_S_HW_FREQ_SEEK, &seek);
if (rc < 0) {
HAL_LOG(("Could not initiate hardware seek"));
return;
}
}
void
GetFMRadioSettings(hal::FMRadioSettings* aInfo)
{
if (!sRadioEnabled) {
return;
}
struct v4l2_tuner tuner = {0};
int rc = ioctl(sRadioFD, VIDIOC_G_TUNER, &tuner);
if (rc < 0) {
HAL_LOG(("Could not query fm radio for settings"));
return;
}
aInfo->upperLimit() = (tuner.rangehigh * 625) / 10000;
aInfo->lowerLimit() = (tuner.rangelow * 625) / 10000;
}
void
SetFMRadioFrequency(const uint32_t frequency)
{
struct v4l2_frequency freq = {0};
freq.type = V4L2_TUNER_RADIO;
freq.frequency = (frequency * 10000) / 625;
int rc = ioctl(sRadioFD, VIDIOC_S_FREQUENCY, &freq);
if (rc < 0)
HAL_LOG(("Could not set radio frequency"));
}
uint32_t
GetFMRadioFrequency()
{
if (!sRadioEnabled)
return 0;
struct v4l2_frequency freq;
int rc = ioctl(sRadioFD, VIDIOC_G_FREQUENCY, &freq);
if (rc < 0) {
HAL_LOG(("Could not get radio frequency"));
return 0;
}
return (freq.frequency * 625) / 10000;
}
bool
IsFMRadioOn()
{
return sRadioEnabled;
}
uint32_t
GetFMRadioSignalStrength()
{
struct v4l2_tuner tuner = {0};
int rc = ioctl(sRadioFD, VIDIOC_G_TUNER, &tuner);
if (rc < 0) {
HAL_LOG(("Could not query fm radio for signal strength"));
return 0;
}
return tuner.signal;
}
void
CancelFMRadioSeek()
{}
} // hal_impl
} // namespace mozilla

484
hal/gonk/tavarua.h Normal file
View File

@ -0,0 +1,484 @@
#ifndef __LINUX_TAVARUA_H
#define __LINUX_TAVARUA_H
/* This is a Linux header generated by "make headers_install" */
#include <stdint.h>
#include <linux/ioctl.h>
#include <linux/videodev2.h>
#undef FM_DEBUG
/* constants */
#define RDS_BLOCKS_NUM (4)
#define BYTES_PER_BLOCK (3)
#define MAX_PS_LENGTH (96)
#define MAX_RT_LENGTH (64)
#define XFRDAT0 (0x20)
#define XFRDAT1 (0x21)
#define XFRDAT2 (0x22)
#define INTDET_PEEK_MSB (0x88)
#define INTDET_PEEK_LSB (0x26)
#define RMSSI_PEEK_MSB (0x88)
#define RMSSI_PEEK_LSB (0xA8)
#define MPX_DCC_BYPASS_POKE_MSB (0x88)
#define MPX_DCC_BYPASS_POKE_LSB (0xC0)
#define MPX_DCC_PEEK_MSB_REG1 (0x88)
#define MPX_DCC_PEEK_LSB_REG1 (0xC2)
#define MPX_DCC_PEEK_MSB_REG2 (0x88)
#define MPX_DCC_PEEK_LSB_REG2 (0xC3)
#define MPX_DCC_PEEK_MSB_REG3 (0x88)
#define MPX_DCC_PEEK_LSB_REG3 (0xC4)
#define ON_CHANNEL_TH_MSB (0x0B)
#define ON_CHANNEL_TH_LSB (0xA8)
#define OFF_CHANNEL_TH_MSB (0x0B)
#define OFF_CHANNEL_TH_LSB (0xAC)
#define ENF_200Khz (1)
#define SRCH200KHZ_OFFSET (7)
#define SRCH_MASK (1 << SRCH200KHZ_OFFSET)
/* Standard buffer size */
#define STD_BUF_SIZE (128)
/* Search direction */
#define SRCH_DIR_UP (0)
#define SRCH_DIR_DOWN (1)
/* control options */
#define CTRL_ON (1)
#define CTRL_OFF (0)
#define US_LOW_BAND (87.5)
#define US_HIGH_BAND (108)
/* constant for Tx */
#define MASK_PI (0x0000FFFF)
#define MASK_PI_MSB (0x0000FF00)
#define MASK_PI_LSB (0x000000FF)
#define MASK_PTY (0x0000001F)
#define MASK_TXREPCOUNT (0x0000000F)
#undef FMDBG
#ifdef FM_DEBUG
#define FMDBG(fmt, args...) printk(KERN_INFO "tavarua_radio: " fmt, ##args)
#else
#define FMDBG(fmt, args...)
#endif
#undef FMDERR
#define FMDERR(fmt, args...) printk(KERN_INFO "tavarua_radio: " fmt, ##args)
#undef FMDBG_I2C
#ifdef FM_DEBUG_I2C
#define FMDBG_I2C(fmt, args...) printk(KERN_INFO "fm_i2c: " fmt, ##args)
#else
#define FMDBG_I2C(fmt, args...)
#endif
/* function declarations */
/* FM Core audio paths. */
#define TAVARUA_AUDIO_OUT_ANALOG_OFF (0)
#define TAVARUA_AUDIO_OUT_ANALOG_ON (1)
#define TAVARUA_AUDIO_OUT_DIGITAL_OFF (0)
#define TAVARUA_AUDIO_OUT_DIGITAL_ON (1)
int tavarua_set_audio_path(int digital_on, int analog_on);
/* defines and enums*/
#define MARIMBA_A0 0x01010013
#define MARIMBA_2_1 0x02010204
#define BAHAMA_1_0 0x0302010A
#define BAHAMA_2_0 0x04020205
#define WAIT_TIMEOUT 2000
#define RADIO_INIT_TIME 15
#define TAVARUA_DELAY 10
/*
* The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW,
* 62.5 kHz otherwise.
* The tuner is able to have a channel spacing of 50, 100 or 200 kHz.
* tuner->capability is therefore set to V4L2_TUNER_CAP_LOW
* The FREQ_MUL is then: 1 MHz / 62.5 Hz = 16000
*/
#define FREQ_MUL (1000000 / 62.5)
enum v4l2_cid_private_tavarua_t {
V4L2_CID_PRIVATE_TAVARUA_SRCHMODE = (V4L2_CID_PRIVATE_BASE + 1),
V4L2_CID_PRIVATE_TAVARUA_SCANDWELL,
V4L2_CID_PRIVATE_TAVARUA_SRCHON,
V4L2_CID_PRIVATE_TAVARUA_STATE,
V4L2_CID_PRIVATE_TAVARUA_TRANSMIT_MODE,
V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK,
V4L2_CID_PRIVATE_TAVARUA_REGION,
V4L2_CID_PRIVATE_TAVARUA_SIGNAL_TH,
V4L2_CID_PRIVATE_TAVARUA_SRCH_PTY,
V4L2_CID_PRIVATE_TAVARUA_SRCH_PI,
V4L2_CID_PRIVATE_TAVARUA_SRCH_CNT,
V4L2_CID_PRIVATE_TAVARUA_EMPHASIS,
V4L2_CID_PRIVATE_TAVARUA_RDS_STD,
V4L2_CID_PRIVATE_TAVARUA_SPACING,
V4L2_CID_PRIVATE_TAVARUA_RDSON,
V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_PROC,
V4L2_CID_PRIVATE_TAVARUA_LP_MODE,
V4L2_CID_PRIVATE_TAVARUA_ANTENNA,
V4L2_CID_PRIVATE_TAVARUA_RDSD_BUF,
V4L2_CID_PRIVATE_TAVARUA_PSALL,
/*v4l2 Tx controls*/
V4L2_CID_PRIVATE_TAVARUA_TX_SETPSREPEATCOUNT,
V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_PS_NAME,
V4L2_CID_PRIVATE_TAVARUA_STOP_RDS_TX_RT,
V4L2_CID_PRIVATE_TAVARUA_IOVERC,
V4L2_CID_PRIVATE_TAVARUA_INTDET,
V4L2_CID_PRIVATE_TAVARUA_MPX_DCC,
V4L2_CID_PRIVATE_TAVARUA_AF_JUMP,
V4L2_CID_PRIVATE_TAVARUA_RSSI_DELTA,
V4L2_CID_PRIVATE_TAVARUA_HLSI,
/*
* Here we have IOCTl's that are specific to IRIS
* (V4L2_CID_PRIVATE_BASE + 0x1E to V4L2_CID_PRIVATE_BASE + 0x28)
*/
V4L2_CID_PRIVATE_SOFT_MUTE,/* 0x800001E*/
V4L2_CID_PRIVATE_RIVA_ACCS_ADDR,
V4L2_CID_PRIVATE_RIVA_ACCS_LEN,
V4L2_CID_PRIVATE_RIVA_PEEK,
V4L2_CID_PRIVATE_RIVA_POKE,
V4L2_CID_PRIVATE_SSBI_ACCS_ADDR,
V4L2_CID_PRIVATE_SSBI_PEEK,
V4L2_CID_PRIVATE_SSBI_POKE,
V4L2_CID_PRIVATE_TX_TONE,
V4L2_CID_PRIVATE_RDS_GRP_COUNTERS,
V4L2_CID_PRIVATE_SET_NOTCH_FILTER,/* 0x8000028 */
V4L2_CID_PRIVATE_TAVARUA_SET_AUDIO_PATH,/* 0x8000029 */
V4L2_CID_PRIVATE_TAVARUA_DO_CALIBRATION,/* 0x800002A : IRIS */
V4L2_CID_PRIVATE_TAVARUA_SRCH_ALGORITHM,/* 0x800002B */
V4L2_CID_PRIVATE_IRIS_GET_SINR, /* 0x800002C : IRIS */
V4L2_CID_PRIVATE_INTF_LOW_THRESHOLD, /* 0x800002D */
V4L2_CID_PRIVATE_INTF_HIGH_THRESHOLD, /* 0x800002E */
V4L2_CID_PRIVATE_SINR_THRESHOLD, /* 0x800002F : IRIS */
V4L2_CID_PRIVATE_SINR_SAMPLES, /* 0x8000030 : IRIS */
};
enum tavarua_buf_t {
TAVARUA_BUF_SRCH_LIST,
TAVARUA_BUF_EVENTS,
TAVARUA_BUF_RT_RDS,
TAVARUA_BUF_PS_RDS,
TAVARUA_BUF_RAW_RDS,
TAVARUA_BUF_AF_LIST,
TAVARUA_BUF_MAX
};
enum tavarua_xfr_t {
TAVARUA_XFR_SYNC,
TAVARUA_XFR_ERROR,
TAVARUA_XFR_SRCH_LIST,
TAVARUA_XFR_RT_RDS,
TAVARUA_XFR_PS_RDS,
TAVARUA_XFR_AF_LIST,
TAVARUA_XFR_MAX
};
enum channel_spacing {
FM_CH_SPACE_200KHZ,
FM_CH_SPACE_100KHZ,
FM_CH_SPACE_50KHZ
};
enum step_size {
NO_SRCH200khz,
ENF_SRCH200khz
};
enum emphasis {
EMP_75,
EMP_50
};
enum rds_std {
RBDS_STD,
RDS_STD
};
/* offsets */
#define RAW_RDS 0x0F
#define RDS_BLOCK 3
/* registers*/
#define MARIMBA_XO_BUFF_CNTRL 0x07
#define RADIO_REGISTERS 0x30
#define XFR_REG_NUM 16
#define STATUS_REG_NUM 3
/* TX constants */
#define HEADER_SIZE 4
#define TX_ON 0x80
#define TAVARUA_TX_RT RDS_RT_0
#define TAVARUA_TX_PS RDS_PS_0
enum register_t {
STATUS_REG1 = 0,
STATUS_REG2,
STATUS_REG3,
RDCTRL,
FREQ,
TUNECTRL,
SRCHRDS1,
SRCHRDS2,
SRCHCTRL,
IOCTRL,
RDSCTRL,
ADVCTRL,
AUDIOCTRL,
RMSSI,
IOVERC,
AUDIOIND = 0x1E,
XFRCTRL,
FM_CTL0 = 0xFF,
LEAKAGE_CNTRL = 0xFE,
};
#define BAHAMA_RBIAS_CTL1 0x07
#define BAHAMA_FM_MODE_REG 0xFD
#define BAHAMA_FM_CTL1_REG 0xFE
#define BAHAMA_FM_CTL0_REG 0xFF
#define BAHAMA_FM_MODE_NORMAL 0x00
#define BAHAMA_LDO_DREG_CTL0 0xF0
#define BAHAMA_LDO_AREG_CTL0 0xF4
/* Radio Control */
#define RDCTRL_STATE_OFFSET 0
#define RDCTRL_STATE_MASK (3 << RDCTRL_STATE_OFFSET)
#define RDCTRL_BAND_OFFSET 2
#define RDCTRL_BAND_MASK (1 << RDCTRL_BAND_OFFSET)
#define RDCTRL_CHSPACE_OFFSET 3
#define RDCTRL_CHSPACE_MASK (3 << RDCTRL_CHSPACE_OFFSET)
#define RDCTRL_DEEMPHASIS_OFFSET 5
#define RDCTRL_DEEMPHASIS_MASK (1 << RDCTRL_DEEMPHASIS_OFFSET)
#define RDCTRL_HLSI_OFFSET 6
#define RDCTRL_HLSI_MASK (3 << RDCTRL_HLSI_OFFSET)
#define RDSAF_OFFSET 6
#define RDSAF_MASK (1 << RDSAF_OFFSET)
/* Tune Control */
#define TUNE_STATION 0x01
#define ADD_OFFSET (1 << 1)
#define SIGSTATE (1 << 5)
#define MOSTSTATE (1 << 6)
#define RDSSYNC (1 << 7)
/* Search Control */
#define SRCH_MODE_OFFSET 0
#define SRCH_MODE_MASK (7 << SRCH_MODE_OFFSET)
#define SRCH_DIR_OFFSET 3
#define SRCH_DIR_MASK (1 << SRCH_DIR_OFFSET)
#define SRCH_DWELL_OFFSET 4
#define SRCH_DWELL_MASK (7 << SRCH_DWELL_OFFSET)
#define SRCH_STATE_OFFSET 7
#define SRCH_STATE_MASK (1 << SRCH_STATE_OFFSET)
/* I/O Control */
#define IOC_HRD_MUTE 0x03
#define IOC_SFT_MUTE (1 << 2)
#define IOC_MON_STR (1 << 3)
#define IOC_SIG_BLND (1 << 4)
#define IOC_INTF_BLND (1 << 5)
#define IOC_ANTENNA (1 << 6)
#define IOC_ANTENNA_OFFSET 6
#define IOC_ANTENNA_MASK (1 << IOC_ANTENNA_OFFSET)
/* RDS Control */
#define RDS_ON 0x01
#define RDSCTRL_STANDARD_OFFSET 1
#define RDSCTRL_STANDARD_MASK (1 << RDSCTRL_STANDARD_OFFSET)
/* Advanced features controls */
#define RDSRTEN (1 << 3)
#define RDSPSEN (1 << 4)
/* Audio path control */
#define AUDIORX_ANALOG_OFFSET 0
#define AUDIORX_ANALOG_MASK (1 << AUDIORX_ANALOG_OFFSET)
#define AUDIORX_DIGITAL_OFFSET 1
#define AUDIORX_DIGITAL_MASK (1 << AUDIORX_DIGITAL_OFFSET)
#define AUDIOTX_OFFSET 2
#define AUDIOTX_MASK (1 << AUDIOTX_OFFSET)
#define I2SCTRL_OFFSET 3
#define I2SCTRL_MASK (1 << I2SCTRL_OFFSET)
/* Search options */
enum search_t {
SEEK,
SCAN,
SCAN_FOR_STRONG,
SCAN_FOR_WEAK,
RDS_SEEK_PTY,
RDS_SCAN_PTY,
RDS_SEEK_PI,
RDS_AF_JUMP,
};
enum audio_path {
FM_DIGITAL_PATH,
FM_ANALOG_PATH
};
#define SRCH_MODE 0x07
#define SRCH_DIR 0x08 /* 0-up 1-down */
#define SCAN_DWELL 0x70
#define SRCH_ON 0x80
/* RDS CONFIG */
#define RDS_CONFIG_PSALL 0x01
#define FM_ENABLE 0x22
#define SET_REG_FIELD(reg, val, offset, mask) \
(reg = (reg & ~mask) | (((val) << offset) & mask))
#define GET_REG_FIELD(reg, offset, mask) ((reg & mask) >> offset)
#define RSH_DATA(val, offset) ((val) >> (offset))
#define LSH_DATA(val, offset) ((val) << (offset))
#define GET_ABS_VAL(val) ((val) & (0xFF))
enum radio_state_t {
FM_OFF,
FM_RECV,
FM_TRANS,
FM_RESET,
};
#define XFRCTRL_WRITE (1 << 7)
/* Interrupt status */
/* interrupt register 1 */
#define READY (1 << 0) /* Radio ready after powerup or reset */
#define TUNE (1 << 1) /* Tune completed */
#define SEARCH (1 << 2) /* Search completed (read FREQ) */
#define SCANNEXT (1 << 3) /* Scanning for next station */
#define SIGNAL (1 << 4) /* Signal indicator change (read SIGSTATE) */
#define INTF (1 << 5) /* Interference cnt has fallen outside range */
#define SYNC (1 << 6) /* RDS sync state change (read RDSSYNC) */
#define AUDIO (1 << 7) /* Audio Control indicator (read AUDIOIND) */
/* interrupt register 2 */
#define RDSDAT (1 << 0) /* New unread RDS data group available */
#define BLOCKB (1 << 1) /* Block-B match condition exists */
#define PROGID (1 << 2) /* Block-A or Block-C matched stored PI value*/
#define RDSPS (1 << 3) /* New RDS Program Service Table available */
#define RDSRT (1 << 4) /* New RDS Radio Text available */
#define RDSAF (1 << 5) /* New RDS AF List available */
#define TXRDSDAT (1 << 6) /* Transmitted an RDS group */
#define TXRDSDONE (1 << 7) /* RDS raw group one-shot transmit completed */
/* interrupt register 3 */
#define TRANSFER (1 << 0) /* Data transfer (XFR) completed */
#define RDSPROC (1 << 1) /* Dynamic RDS Processing complete */
#define ERROR (1 << 7) /* Err occurred.Read code to determine cause */
#define FM_TX_PWR_LVL_0 0 /* Lowest power lvl that can be set for Tx */
#define FM_TX_PWR_LVL_MAX 7 /* Max power lvl for Tx */
/* Transfer */
enum tavarua_xfr_ctrl_t {
RDS_PS_0 = 0x01,
RDS_PS_1,
RDS_PS_2,
RDS_PS_3,
RDS_PS_4,
RDS_PS_5,
RDS_PS_6,
RDS_RT_0,
RDS_RT_1,
RDS_RT_2,
RDS_RT_3,
RDS_RT_4,
RDS_AF_0,
RDS_AF_1,
RDS_CONFIG,
RDS_TX_GROUPS,
RDS_COUNT_0,
RDS_COUNT_1,
RDS_COUNT_2,
RADIO_CONFIG,
RX_CONFIG,
RX_TIMERS,
RX_STATIONS_0,
RX_STATIONS_1,
INT_CTRL,
ERROR_CODE,
CHIPID,
CAL_DAT_0 = 0x20,
CAL_DAT_1,
CAL_DAT_2,
CAL_DAT_3,
CAL_CFG_0,
CAL_CFG_1,
DIG_INTF_0,
DIG_INTF_1,
DIG_AGC_0,
DIG_AGC_1,
DIG_AGC_2,
DIG_AUDIO_0,
DIG_AUDIO_1,
DIG_AUDIO_2,
DIG_AUDIO_3,
DIG_AUDIO_4,
DIG_RXRDS,
DIG_DCC,
DIG_SPUR,
DIG_MPXDCC,
DIG_PILOT,
DIG_DEMOD,
DIG_MOST,
DIG_TX_0,
DIG_TX_1,
PHY_TXGAIN = 0x3B,
PHY_CONFIG,
PHY_TXBLOCK,
PHY_TCB,
XFR_PEEK_MODE = 0x40,
XFR_POKE_MODE = 0xC0,
TAVARUA_XFR_CTRL_MAX
};
enum tavarua_evt_t {
TAVARUA_EVT_RADIO_READY,
TAVARUA_EVT_TUNE_SUCC,
TAVARUA_EVT_SEEK_COMPLETE,
TAVARUA_EVT_SCAN_NEXT,
TAVARUA_EVT_NEW_RAW_RDS,
TAVARUA_EVT_NEW_RT_RDS,
TAVARUA_EVT_NEW_PS_RDS,
TAVARUA_EVT_ERROR,
TAVARUA_EVT_BELOW_TH,
TAVARUA_EVT_ABOVE_TH,
TAVARUA_EVT_STEREO,
TAVARUA_EVT_MONO,
TAVARUA_EVT_RDS_AVAIL,
TAVARUA_EVT_RDS_NOT_AVAIL,
TAVARUA_EVT_NEW_SRCH_LIST,
TAVARUA_EVT_NEW_AF_LIST,
TAVARUA_EVT_TXRDSDAT,
TAVARUA_EVT_TXRDSDONE,
TAVARUA_EVT_RADIO_DISABLED
};
enum tavarua_region_t {
TAVARUA_REGION_US,
TAVARUA_REGION_EU,
TAVARUA_REGION_JAPAN,
TAVARUA_REGION_JAPAN_WIDE,
TAVARUA_REGION_OTHER
};
#endif /* __LINUX_TAVARUA_H */

View File

@ -25,6 +25,10 @@ using mozilla::hal::ProcessPriority;
using nsIntRect;
using PRTime;
using mozilla::hal::SystemTimeChange;
using mozilla::hal::FMRadioCountry;
using mozilla::hal::FMRadioOperation;
using mozilla::hal::FMRadioOperationStatus;
using mozilla::hal::FMRadioSeekDirection;
namespace mozilla {
@ -74,6 +78,20 @@ struct ScreenConfiguration {
uint32_t pixelDepth;
};
struct FMRadioOperationInformation {
FMRadioOperation operation;
FMRadioOperationStatus status;
uint32_t frequency;
};
struct FMRadioSettings {
FMRadioCountry country;
uint32_t upperLimit;
uint32_t lowerLimit;
uint32_t spaceType;
uint32_t preEmphasis;
};
} // namespace hal
namespace hal_sandbox {
@ -88,6 +106,7 @@ child:
NotifyScreenConfigurationChange(ScreenConfiguration aScreenOrientation);
NotifySwitchChange(SwitchEvent aEvent);
NotifySystemTimeChange(SystemTimeChange aReason);
NotifyFMRadioStatus(FMRadioOperationInformation aInfo);
parent:
Vibrate(uint32_t[] pattern, uint64_t[] id, PBrowser browser);
@ -146,10 +165,24 @@ parent:
SetProcessPriority(int aPid, ProcessPriority aPriority);
EnableFMRadio(FMRadioSettings aSettings);
DisableFMRadio();
FMRadioSeek(FMRadioSeekDirection aDirection);
sync GetFMRadioSettings()
returns (FMRadioSettings settings);
SetFMRadioFrequency(uint32_t frequency);
sync GetFMRadioFrequency()
returns (uint32_t frequency);
sync IsFMRadioOn()
returns (bool radioOn);
sync GetFMRadioSignalStrength()
returns (uint32_t strength);
CancelFMRadioSeek();
child:
NotifySensorChange(SensorData aSensorData);
parent:
parent:
EnableSensorNotifications(SensorType aSensor);
DisableSensorNotifications(SensorType aSensor);

View File

@ -295,6 +295,66 @@ SetProcessPriority(int aPid, ProcessPriority aPriority)
Hal()->SendSetProcessPriority(aPid, aPriority);
}
void
EnableFMRadio(const hal::FMRadioSettings& aSettings)
{
Hal()->SendEnableFMRadio(aSettings);
}
void
DisableFMRadio()
{
Hal()->SendDisableFMRadio();
}
void
FMRadioSeek(const hal::FMRadioSeekDirection& aDirection)
{
Hal()->SendFMRadioSeek(aDirection);
}
void
GetFMRadioSettings(FMRadioSettings* aSettings)
{
Hal()->SendGetFMRadioSettings(aSettings);
}
void
SetFMRadioFrequency(const uint32_t aFrequency)
{
Hal()->SendSetFMRadioFrequency(aFrequency);
}
uint32_t
GetFMRadioFrequency()
{
uint32_t frequency;
Hal()->SendGetFMRadioFrequency(&frequency);
return frequency;
}
bool
IsFMRadioOn()
{
bool FMRadioOn;
Hal()->SendIsFMRadioOn(&FMRadioOn);
return FMRadioOn;
}
uint32_t
GetFMRadioSignalStrength()
{
uint32_t strength;
Hal()->SendGetFMRadioSignalStrength(&strength);
return strength;
}
void
CancelFMRadioSeek()
{
Hal()->SendCancelFMRadioSeek();
}
class HalParent : public PHalParent
, public BatteryObserver
, public NetworkObserver
@ -665,6 +725,74 @@ public:
{
unused << SendNotifySystemTimeChange(aReason);
}
virtual bool
RecvEnableFMRadio(const hal::FMRadioSettings& aSettings)
{
hal::EnableFMRadio(aSettings);
return true;
}
virtual bool
RecvDisableFMRadio()
{
hal::DisableFMRadio();
return true;
}
virtual bool
RecvFMRadioSeek(const hal::FMRadioSeekDirection& aDirection)
{
hal::FMRadioSeek(aDirection);
return true;
}
virtual bool
RecvGetFMRadioSettings(hal::FMRadioSettings* aSettings)
{
hal::GetFMRadioSettings(aSettings);
return true;
}
virtual bool
RecvSetFMRadioFrequency(const uint32_t& aFrequency)
{
hal::SetFMRadioFrequency(aFrequency);
return true;
}
virtual bool
RecvGetFMRadioFrequency(uint32_t* aFrequency)
{
*aFrequency = hal::GetFMRadioFrequency();
return true;
}
void Notify(const hal::FMRadioOperationInformation& aRadioStatus)
{
unused << SendNotifyFMRadioStatus(aRadioStatus);
}
virtual bool
RecvIsFMRadioOn(bool* radioOn)
{
*radioOn = hal::IsFMRadioOn();
return true;
}
virtual bool
RecvGetFMRadioSignalStrength(uint32_t* strength)
{
*strength = hal::GetFMRadioSignalStrength();
return true;
}
virtual bool
RecvCancelFMRadioSeek()
{
hal::CancelFMRadioSeek();
return true;
}
};
class HalChild : public PHalChild {
@ -707,6 +835,12 @@ public:
hal::NotifySystemTimeChange(aReason);
return true;
}
virtual bool
RecvNotifyFMRadioStatus(const FMRadioOperationInformation& aRadioStatus) {
hal::NotifyFMRadioStatus(aRadioStatus);
return true;
}
};
bool