mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-23 10:54:33 +00:00
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:
parent
9cf7fe3bbd
commit
45a49905cb
203
hal/Hal.cpp
203
hal/Hal.cpp
@ -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
|
||||
|
67
hal/Hal.h
67
hal/Hal.h
@ -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
|
||||
|
||||
|
115
hal/HalTypes.h
115
hal/HalTypes.h
@ -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
|
||||
|
@ -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 #}
|
||||
|
||||
|
61
hal/fallback/FallbackFMRadio.cpp
Normal file
61
hal/fallback/FallbackFMRadio.cpp
Normal 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
324
hal/gonk/GonkFMRadio.cpp
Normal 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
484
hal/gonk/tavarua.h
Normal 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 */
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user