diff --git a/.gitmodules b/.gitmodules index d9113f3c9d2..d52316791b2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "packages/addons/unofficial"] path = packages/addons/unofficial - url = https://github.com/OpenELEC/unofficial-addons.git + url = https://github.com/jernejsk/unofficial-addons.git diff --git a/README.md b/README.md index 5dbd76c1a58..39456f8a052 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,23 @@ +#Orange Pi 2 development + +**This is unofficial and should be usable, however expect bugs** + +**WARNING: Current code is using Allwinner's CedarX blobs which have license issues (https://linux-sunxi.org/CedarX)** + +**Current Status** +* video is HW decoded +* direct rendering +* HW deinterlacing +* WMV1, WMV2, VP6 and VP9 codecs, although supported by CedarX, are SW decoded (nothing can be done to improve this) +* taking screenshots doesn't work +* VSync is commented out, because of big frame drop (needs some code reorganization) +* used boot time resolution (can be changed via script.bin or kernel parameters) + +Any help appreciated via pull requests or [Orange Pi forum](http://www.orangepi.org/orangepibbsen/forum.php?mod=viewthread&tid=648) + +Latest prebuilt images can be found [here](http://www.orangepi.org/orangepibbsen/forum.php?mod=viewthread&tid=1075) + + [OpenELEC](http://www.openelec.tv) # OpenELEC - Open Embedded Linux Entertainment Center diff --git a/distributions/OpenELEC/options b/distributions/OpenELEC/options index 9d65a6f93da..84a1fc2f13a 100644 --- a/distributions/OpenELEC/options +++ b/distributions/OpenELEC/options @@ -208,7 +208,7 @@ DISTRO_SRC="http://sources.openelec.tv/$OPENELEC_VERSION" # Addon Server Url - ADDON_SERVER_URL="http://addons.openelec.tv" + ADDON_SERVER_URL="http://down.nu/repository/official" # set the addon dirs ADDON_PATH="$ADDON_VERSION/$PROJECT/$TARGET_ARCH" diff --git a/packages/addons/official/repository/repository.unofficial.addon.pro/sources/addon.xml b/packages/addons/official/repository/repository.unofficial.addon.pro/sources/addon.xml index 4b2661642e3..e58c27ba080 100644 --- a/packages/addons/official/repository/repository.unofficial.addon.pro/sources/addon.xml +++ b/packages/addons/official/repository/repository.unofficial.addon.pro/sources/addon.xml @@ -1,19 +1,19 @@ + name="Orange Pi OpenELEC Add-ons (unofficial)"> - http://unofficial.addon.pro/addons/7.0/@PROJECT@/@ARCH@/addons.xml - http://unofficial.addon.pro/addons/7.0/@PROJECT@/@ARCH@/addons.xml.md5 - http://unofficial.addon.pro/addons/7.0/@PROJECT@/@ARCH@ + http://down.nu/repository/unofficial/7.0/@PROJECT@/@ARCH@/addons.xml + http://down.nu/repository/unofficial/7.0/@PROJECT@/@ARCH@/addons.xml.md5 + http://down.nu/repository/unofficial/7.0/@PROJECT@/@ARCH@ - OpenELEC Add-ons (unofficial) - The OpenELEC unofficial repository contains community provided add-ons. These add-ons are not supported by OpenELEC staff. Please check the OpenELEC or Kodi forums for community support threads and ask the add-on author to submit fixes via GitHub. + Orange Pi OpenELEC Add-ons (unofficial) + The Orange Pi OpenELEC unofficial repository contains community provided add-ons. These add-ons are not supported by OpenELEC staff. Please check the OpenELEC or Kodi forums for community support threads and ask the add-on author to submit fixes via GitHub. Add-ons in this repository are not maintained or supported by OpenELEC staff. all diff --git a/packages/addons/unofficial b/packages/addons/unofficial index e1344bf6ab4..d94eff2153f 160000 --- a/packages/addons/unofficial +++ b/packages/addons/unofficial @@ -1 +1 @@ -Subproject commit e1344bf6ab469706ed533b619107d5aca142fbff +Subproject commit d94eff2153f97ff3b94c2d7bc908c416b2a0afd5 diff --git a/packages/devel/ccache/package.mk b/packages/devel/ccache/package.mk index 341b4e4a590..91ecc25b810 100644 --- a/packages/devel/ccache/package.mk +++ b/packages/devel/ccache/package.mk @@ -21,6 +21,7 @@ PKG_VERSION="3.3.3" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" +PKG_SITE="https://ccache.samba.org/" PKG_SITE="http://ccache.samba.org/" PKG_URL="https://samba.org/ftp/ccache/$PKG_NAME-$PKG_VERSION.tar.bz2" PKG_DEPENDS_HOST="make:host" diff --git a/packages/devel/libcec/package.mk b/packages/devel/libcec/package.mk index ad323a22e17..5d2e03cd636 100644 --- a/packages/devel/libcec/package.mk +++ b/packages/devel/libcec/package.mk @@ -49,6 +49,12 @@ else EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DHAVE_AMLOGIC_API=0" fi +if [ "$KODIPLAYER_DRIVER" = "cedarx" ]; then + EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DHAVE_SUNXI_LIB=1" +else + EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DHAVE_SUNXI_LIB=0" +fi + configure_target() { if [ "$KODIPLAYER_DRIVER" = "bcm2835-firmware" ]; then export CXXFLAGS="$CXXFLAGS \ diff --git a/packages/devel/libcec/patches/libcec-04-sunxi-support.patch b/packages/devel/libcec/patches/libcec-04-sunxi-support.patch new file mode 100644 index 00000000000..e77d795ad42 --- /dev/null +++ b/packages/devel/libcec/patches/libcec-04-sunxi-support.patch @@ -0,0 +1,805 @@ +diff -Nur a/include/cectypes.h b/include/cectypes.h +--- a/include/cectypes.h 2016-06-13 21:27:29.406425322 +0200 ++++ b/include/cectypes.h 2016-06-13 21:31:55.586417939 +0200 +@@ -330,6 +330,16 @@ + #define CEC_AMLOGIC_VIRTUAL_COM "Amlogic" + + /*! ++ * the path to use for the Sunxi CEC device ++ */ ++#define CEC_SUNXI_PATH "/dev/sunxi_hdmi_cec" ++ ++/*! ++ * the name of the virtual COM port to use for the Sunxi CEC wire ++ */ ++#define CEC_SUNXI_VIRTUAL_COM "Sunxi" ++ ++/*! + * Mimimum client version + */ + #define CEC_MIN_LIB_VERSION 3 +@@ -899,7 +909,8 @@ + ADAPTERTYPE_TDA995x = 0x200, + ADAPTERTYPE_EXYNOS = 0x300, + ADAPTERTYPE_IMX = 0x400, +- ADAPTERTYPE_AMLOGIC = 0x500 ++ ADAPTERTYPE_AMLOGIC = 0x500, ++ ADAPTERTYPE_SUNXI = 0x600 + } cec_adapter_type; + + /** force exporting through swig */ +diff -Nur a/README.md b/README.md +--- a/README.md 2016-06-13 21:27:29.406425322 +0200 ++++ b/README.md 2016-06-13 21:39:13.943072447 +0200 +@@ -70,6 +70,12 @@ + cmake -DHAVE_TDA995X_API=1 .. + ``` + ++### Sunxi ++To compile in support for Sunxi devices, you have to pass the argument -DHAVE_SUNXI_LIB=1 to cmake: ++``` ++cmake -DHAVE_SUNXI_API=1 .. ++``` ++ + ## Apple OS X + + To compile libCEC on OS X, you'll need the following dependencies: +diff -Nur a/src/libcec/adapter/AdapterFactory.cpp b/src/libcec/adapter/AdapterFactory.cpp +--- a/src/libcec/adapter/AdapterFactory.cpp 2016-06-13 21:27:29.406425322 +0200 ++++ b/src/libcec/adapter/AdapterFactory.cpp 2016-06-13 21:37:09.966409219 +0200 +@@ -68,6 +68,11 @@ + #include "Amlogic/AmlogicCECAdapterCommunication.h" + #endif + ++#if defined(HAVE_SUNXI_API) ++#include "Sunxi/SunxiCECAdapterDetection.h" ++#include "Sunxi/SunxiCECAdapterCommunication.h" ++#endif ++ + using namespace CEC; + + int8_t CAdapterFactory::FindAdapters(cec_adapter *deviceList, uint8_t iBufSize, const char *strDevicePath /* = NULL */) +@@ -163,8 +168,20 @@ + } + #endif + ++#if defined(HAVE_SUNXI_API) ++ if (iAdaptersFound < iBufSize && CSunxiCECAdapterDetection::FindAdapter() && ++ (!strDevicePath || !strcmp(strDevicePath, CEC_SUNXI_VIRTUAL_COM))) ++ { ++ snprintf(deviceList[iAdaptersFound].strComPath, sizeof(deviceList[iAdaptersFound].strComPath), CEC_SUNXI_PATH); ++ snprintf(deviceList[iAdaptersFound].strComName, sizeof(deviceList[iAdaptersFound].strComName), CEC_SUNXI_VIRTUAL_COM); ++ deviceList[iAdaptersFound].iVendorId = SUNXI_ADAPTER_VID; ++ deviceList[iAdaptersFound].iProductId = SUNXI_ADAPTER_PID; ++ deviceList[iAdaptersFound].adapterType = ADAPTERTYPE_SUNXI; ++ iAdaptersFound++; ++ } ++#endif + +-#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API) ++#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API) && !defined(HAVE_SUNXI_API) + #error "libCEC doesn't have support for any type of adapter. please check your build system or configuration" + #endif + +@@ -198,11 +215,16 @@ + return new CAmlogicCECAdapterCommunication(m_lib->m_cec); + #endif + ++#if defined(HAVE_SUNXI_API) ++ if (!strcmp(strPort, CEC_SUNXI_VIRTUAL_COM)) ++ return new CSunxiCECAdapterCommunication(m_lib->m_cec); ++#endif ++ + #if defined(HAVE_P8_USB) + return new CUSBCECAdapterCommunication(m_lib->m_cec, strPort, iBaudRate); + #endif + +-#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API) ++#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_IMX_API) && !defined(HAVE_AMLOGIC_API) && !defined(HAVE_SUNXI_API) + return NULL; + #endif + } +diff -Nur a/src/libcec/adapter/Sunxi/AdapterMessageQueue.h b/src/libcec/adapter/Sunxi/AdapterMessageQueue.h +--- a/src/libcec/adapter/Sunxi/AdapterMessageQueue.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/libcec/adapter/Sunxi/AdapterMessageQueue.h 2016-06-13 21:47:43.009724994 +0200 +@@ -0,0 +1,134 @@ ++#pragma once ++/* ++ * This file is part of the libCEC(R) library. ++ * ++ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved. ++ * libCEC(R) is an original work, containing original code. ++ * ++ * libCEC(R) is a trademark of Pulse-Eight Limited. ++ * ++ * This program is dual-licensed; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * ++ * Alternatively, you can license this library under a commercial license, ++ * please contact Pulse-Eight Licensing for more information. ++ * ++ * For more information contact: ++ * Pulse-Eight Licensing ++ * http://www.pulse-eight.com/ ++ * http://www.pulse-eight.net/ ++ */ ++ ++#include ++ ++namespace CEC ++{ ++ using namespace PLATFORM; ++ ++ class CAdapterMessageQueueEntry ++ { ++ public: ++ CAdapterMessageQueueEntry(const cec_command &command) ++ : m_bWaiting(true), m_retval((uint32_t)-1), m_bSucceeded(false) ++ { ++ m_hash = hashValue( ++ uint32_t(command.opcode_set ? command.opcode : CEC_OPCODE_NONE), ++ command.initiator, command.destination); ++ } ++ ++ virtual ~CAdapterMessageQueueEntry(void) {} ++ ++ /*! ++ * @brief Query result from worker thread ++ */ ++ uint32_t Result() const ++ { ++ return m_retval; ++ } ++ ++ /*! ++ * @brief Signal waiting threads ++ */ ++ void Broadcast(void) ++ { ++ CLockObject lock(m_mutex); ++ m_condition.Broadcast(); ++ } ++ ++ /*! ++ * @brief Signal waiting thread(s) when message matches this entry ++ */ ++ bool CheckMatch(uint32_t opcode, cec_logical_address initiator, ++ cec_logical_address destination, uint32_t response) ++ { ++ uint32_t hash = hashValue(opcode, initiator, destination); ++ ++ if (hash == m_hash) ++ { ++ CLockObject lock(m_mutex); ++ ++ m_retval = response; ++ m_bSucceeded = true; ++ m_condition.Signal(); ++ return true; ++ } ++ ++ return false; ++ } ++ ++ /*! ++ * @brief Wait for a response to this command. ++ * @param iTimeout The timeout to use while waiting. ++ * @return True when a response was received before the timeout passed, false otherwise. ++ */ ++ bool Wait(uint32_t iTimeout) ++ { ++ CLockObject lock(m_mutex); ++ ++ bool bReturn = m_bSucceeded ? true : m_condition.Wait(m_mutex, m_bSucceeded, iTimeout); ++ m_bWaiting = false; ++ return bReturn; ++ } ++ ++ /*! ++ * @return True while a thread is waiting for a signal or isn't waiting yet, false otherwise. ++ */ ++ bool IsWaiting(void) ++ { ++ CLockObject lock(m_mutex); ++ return m_bWaiting; ++ } ++ ++ /*! ++ * @return Hash value for given cec_command ++ */ ++ static uint32_t hashValue(uint32_t opcode, ++ cec_logical_address initiator, ++ cec_logical_address destination) ++ { ++ return 1 | ((uint32_t)initiator << 8) | ++ ((uint32_t)destination << 16) | ((uint32_t)opcode << 16); ++ } ++ ++ private: ++ bool m_bWaiting; /**< true while a thread is waiting or when it hasn't started waiting yet */ ++ PLATFORM::CCondition m_condition; /**< the condition to wait on */ ++ PLATFORM::CMutex m_mutex; /**< mutex for changes to this class */ ++ uint32_t m_hash; ++ uint32_t m_retval; ++ bool m_bSucceeded; ++ }; ++ ++}; +diff -Nur a/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.cpp b/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.cpp +--- a/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.cpp 2016-06-13 21:47:00.099726185 +0200 +@@ -0,0 +1,278 @@ ++/* ++ * This file is part of the libCEC(R) library. ++ * ++ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved. ++ * libCEC(R) is an original work, containing original code. ++ * ++ * libCEC(R) is a trademark of Pulse-Eight Limited. ++ * ++ * Sunxi adpater port is Copyright (C) 2016 by Joachim Damm ++ * based on IMX adpater port Copyright (C) 2013 by Stephan Rafin ++ * ++ * You can redistribute this file and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * ++ */ ++ ++#include "env.h" ++ ++#if defined(HAVE_SUNXI_API) ++#include "SunxiCECAdapterCommunication.h" ++ ++#include "CECTypeUtils.h" ++#include "LibCEC.h" ++#include ++#include ++#include ++ ++/* ++ * Ioctl definitions from kernel header ++ */ ++#define HDMICEC_IOC_MAGIC 'H' ++#define HDMICEC_IOC_SETLOGICALADDRESS _IOW(HDMICEC_IOC_MAGIC, 1, unsigned char) ++#define HDMICEC_IOC_STARTDEVICE _IO(HDMICEC_IOC_MAGIC, 2) ++#define HDMICEC_IOC_STOPDEVICE _IO(HDMICEC_IOC_MAGIC, 3) ++#define HDMICEC_IOC_GETPHYADDRESS _IOR(HDMICEC_IOC_MAGIC, 4, unsigned char[4]) ++ ++#define MAX_CEC_MESSAGE_LEN 17 ++ ++#define MESSAGE_TYPE_RECEIVE_SUCCESS 1 ++#define MESSAGE_TYPE_NOACK 2 ++#define MESSAGE_TYPE_DISCONNECTED 3 ++#define MESSAGE_TYPE_CONNECTED 4 ++#define MESSAGE_TYPE_SEND_SUCCESS 5 ++ ++typedef struct hdmi_cec_event{ ++ int event_type; ++ int msg_len; ++ unsigned char msg[MAX_CEC_MESSAGE_LEN]; ++}hdmi_cec_event; ++ ++ ++using namespace std; ++using namespace CEC; ++using namespace PLATFORM; ++ ++#include "AdapterMessageQueue.h" ++ ++#define LIB_CEC m_callback->GetLib() ++ ++// these are defined in nxp private header file ++#define CEC_MSG_SUCCESS 0x00 /*Message transmisson Succeed*/ ++#define CEC_CSP_OFF_STATE 0x80 /*CSP in Off State*/ ++#define CEC_BAD_REQ_SERVICE 0x81 /*Bad .req service*/ ++#define CEC_MSG_FAIL_UNABLE_TO_ACCESS 0x82 /*Message transmisson failed: Unable to access CEC line*/ ++#define CEC_MSG_FAIL_ARBITRATION_ERROR 0x83 /*Message transmisson failed: Arbitration error*/ ++#define CEC_MSG_FAIL_BIT_TIMMING_ERROR 0x84 /*Message transmisson failed: Bit timming error*/ ++#define CEC_MSG_FAIL_DEST_NOT_ACK 0x85 /*Message transmisson failed: Destination Address not aknowledged*/ ++#define CEC_MSG_FAIL_DATA_NOT_ACK 0x86 /*Message transmisson failed: Databyte not acknowledged*/ ++ ++ ++CSunxiCECAdapterCommunication::CSunxiCECAdapterCommunication(IAdapterCommunicationCallback *callback) : ++ IAdapterCommunication(callback)/*, ++ m_bLogicalAddressChanged(false)*/ ++{ ++ CLockObject lock(m_mutex); ++ ++ m_iNextMessage = 0; ++ //m_logicalAddresses.Clear(); ++ m_logicalAddress = CECDEVICE_UNKNOWN; ++ m_dev = new CCDevSocket(CEC_SUNXI_PATH); ++ //m_dev = new CCDevSocket("/dev/sunxi_hdmi_cec"); ++} ++ ++CSunxiCECAdapterCommunication::~CSunxiCECAdapterCommunication(void) ++{ ++ Close(); ++ ++ CLockObject lock(m_mutex); ++ delete m_dev; ++ m_dev = 0; ++} ++ ++bool CSunxiCECAdapterCommunication::IsOpen(void) ++{ ++ return IsInitialised() && m_dev->IsOpen(); ++} ++ ++bool CSunxiCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChecks), bool bStartListening) ++{ ++ if (m_dev->Open(iTimeoutMs)) ++ { ++ if (!bStartListening || CreateThread()) { ++ if (m_dev->Ioctl(HDMICEC_IOC_STARTDEVICE, NULL) != 0) { ++ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__); ++ } ++ return true; ++ } ++ m_dev->Close(); ++ } ++ ++ return false; ++} ++ ++ ++void CSunxiCECAdapterCommunication::Close(void) ++{ ++ StopThread(0); ++ if (m_dev->Ioctl(HDMICEC_IOC_STOPDEVICE, NULL) != 0) { ++ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to stop device\n", __func__); ++ } ++ m_dev->Close(); ++} ++ ++ ++std::string CSunxiCECAdapterCommunication::GetError(void) const ++{ ++ std::string strError(m_strError); ++ return strError; ++} ++ ++ ++cec_adapter_message_state CSunxiCECAdapterCommunication::Write( ++ const cec_command &data, bool &UNUSED(bRetry), uint8_t UNUSED(iLineTimeout), bool UNUSED(bIsReply)) ++{ ++ //cec_frame frame; ++ unsigned char message[MAX_CEC_MESSAGE_LEN]; ++ int msg_len = 1; ++ cec_adapter_message_state rc = ADAPTER_MESSAGE_STATE_ERROR; ++ ++ if ((size_t)data.parameters.size + data.opcode_set + 1 > sizeof(message)) ++ { ++ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: data size too large !", __func__); ++ return ADAPTER_MESSAGE_STATE_ERROR; ++ } ++ ++ message[0] = (data.initiator << 4) | (data.destination & 0x0f); ++ if (data.opcode_set) ++ { ++ message[1] = data.opcode; ++ msg_len++; ++ memcpy(&message[2], data.parameters.data, data.parameters.size); ++ msg_len+=data.parameters.size; ++ } ++ ++ if (m_dev->Write(message, msg_len) == msg_len) ++ { ++ rc = ADAPTER_MESSAGE_STATE_SENT_ACKED; ++ } ++ else ++ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: sent command error !", __func__); ++ ++ return rc; ++} ++ ++ ++uint16_t CSunxiCECAdapterCommunication::GetFirmwareVersion(void) ++{ ++ /* FIXME add ioctl ? */ ++ return 0; ++} ++ ++ ++cec_vendor_id CSunxiCECAdapterCommunication::GetVendorId(void) ++{ ++ return CEC_VENDOR_UNKNOWN; ++} ++ ++ ++uint16_t CSunxiCECAdapterCommunication::GetPhysicalAddress(void) ++{ ++ uint32_t info; ++ ++ if (m_dev->Ioctl(HDMICEC_IOC_GETPHYADDRESS, &info) != 0) ++ { ++ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_GETPHYADDRESS failed !", __func__); ++ return CEC_INVALID_PHYSICAL_ADDRESS; ++ } ++ ++ return info; ++} ++ ++ ++cec_logical_addresses CSunxiCECAdapterCommunication::GetLogicalAddresses(void) ++{ ++ cec_logical_addresses addresses; ++ addresses.Clear(); ++ ++ CLockObject lock(m_mutex); ++ if ( m_logicalAddress != CECDEVICE_UNKNOWN) ++ addresses.Set(m_logicalAddress); ++ ++ return addresses; ++} ++ ++ ++bool CSunxiCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses) ++{ ++ int log_addr = addresses.primary; ++ ++ CLockObject lock(m_mutex); ++ if (m_logicalAddress == log_addr) ++ return true; ++ ++ if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)log_addr) != 0) ++ { ++ LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__); ++ return false; ++ } ++ ++ m_logicalAddress = (cec_logical_address)log_addr; ++ return true; ++} ++ ++ ++void *CSunxiCECAdapterCommunication::Process(void) ++{ ++ hdmi_cec_event event; ++ int ret; ++ cec_logical_address initiator, destination; ++ ++ while (!IsStopped()) ++ { ++ ret = m_dev->Read((char *)&event, sizeof(event), 5000); ++ if (ret > 0) ++ { ++ ++ initiator = cec_logical_address(event.msg[0] >> 4); ++ destination = cec_logical_address(event.msg[0] & 0x0f); ++ ++ //LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read data : type : %d initiator %d dest %d", __func__, event.event_type, initiator, destination); ++ if (event.event_type == MESSAGE_TYPE_RECEIVE_SUCCESS) ++ /* Message received */ ++ { ++ cec_command cmd; ++ ++ cec_command::Format( ++ cmd, initiator, destination, ++ ( event.msg_len > 1 ) ? cec_opcode(event.msg[1]) : CEC_OPCODE_NONE); ++ ++ for( uint8_t i = 2; i < event.msg_len; i++ ) ++ cmd.parameters.PushBack(event.msg[i]); ++ ++ if (!IsStopped()) ++ m_callback->OnCommandReceived(cmd); ++ } ++ /* We are not interested in other events */ ++ } /*else { ++ LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read returned %d", __func__, ret); ++ }*/ ++ ++ } ++ ++ return 0; ++} ++ ++#endif // HAVE_SUNXI_API +diff -Nur a/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.h b/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.h +--- a/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/libcec/adapter/Sunxi/SunxiCECAdapterCommunication.h 2016-06-13 22:58:00.642941346 +0200 +@@ -0,0 +1,115 @@ ++#pragma once ++/* ++ * This file is part of the libCEC(R) library. ++ * ++ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved. ++ * libCEC(R) is an original work, containing original code. ++ * ++ * libCEC(R) is a trademark of Pulse-Eight Limited. ++ * ++ * Sunxi adpater port is Copyright (C) 2016 by Joachim Damm ++ * based on IMX adpater port Copyright (C) 2013 by Stephan Rafin ++ * ++ * You can redistribute this file and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * ++ */ ++ ++#if defined(HAVE_SUNXI_API) ++ ++#include ++#include ++#include ++#include "adapter/AdapterCommunication.h" ++#include ++ ++#define SUNXI_ADAPTER_VID 0x0471 /*FIXME TBD*/ ++#define SUNXI_ADAPTER_PID 0x1002 ++ ++ ++ ++namespace PLATFORM ++{ ++ class CCDevSocket; ++}; ++ ++ ++namespace CEC ++{ ++ class CAdapterMessageQueueEntry; ++ ++ class CSunxiCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::CThread ++ { ++ public: ++ /*! ++ * @brief Create a new USB-CEC communication handler. ++ * @param callback The callback to use for incoming CEC commands. ++ */ ++ CSunxiCECAdapterCommunication(IAdapterCommunicationCallback *callback); ++ virtual ~CSunxiCECAdapterCommunication(void); ++ ++ /** @name IAdapterCommunication implementation */ ++ ///{ ++ bool Open(uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT, bool bSkipChecks = false, bool bStartListening = true); ++ void Close(void); ++ bool IsOpen(void); ++ std::string GetError(void) const; ++ cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply); ++ ++ bool SetLineTimeout(uint8_t UNUSED(iTimeout)) { return true; } ++ bool StartBootloader(void) { return false; } ++ bool SetLogicalAddresses(const cec_logical_addresses &addresses); ++ cec_logical_addresses GetLogicalAddresses(void); ++ bool PingAdapter(void) { return IsInitialised(); } ++ uint16_t GetFirmwareVersion(void); ++ uint32_t GetFirmwareBuildDate(void) { return 0; } ++ bool IsRunningLatestFirmware(void) { return true; } ++ bool PersistConfiguration(const libcec_configuration & UNUSED(configuration)) { return false; } ++ bool GetConfiguration(libcec_configuration & UNUSED(configuration)) { return false; } ++ std::string GetPortName(void) { return std::string("Sunxi"); } ++ uint16_t GetPhysicalAddress(void); ++ bool SetControlledMode(bool UNUSED(controlled)) { return true; } ++ cec_vendor_id GetVendorId(void); ++ bool SupportsSourceLogicalAddress(const cec_logical_address address) { return address > CECDEVICE_TV && address <= CECDEVICE_BROADCAST; } ++ cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_SUNXI; } ++ uint16_t GetAdapterVendorId(void) const { return SUNXI_ADAPTER_VID; } ++ uint16_t GetAdapterProductId(void) const { return SUNXI_ADAPTER_PID; } ++ void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {} ++ ///} ++ ++ /** @name PLATFORM::CThread implementation */ ++ ///{ ++ void *Process(void); ++ ///} ++ ++ private: ++ bool IsInitialised(void) const { return m_dev != 0; }; ++ ++ std::string m_strError; /**< current error message */ ++ ++ //cec_logical_addresses m_logicalAddresses; ++ cec_logical_address m_logicalAddress; ++ ++ PLATFORM::CMutex m_mutex; ++ PLATFORM::CCDevSocket *m_dev; /**< the device connection */ ++ ++ PLATFORM::CMutex m_messageMutex; ++ uint32_t m_iNextMessage; ++ std::map m_messages; ++ }; ++ ++}; ++ ++#endif +diff -Nur a/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.cpp b/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.cpp +--- a/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.cpp 2016-06-13 21:28:56.213089581 +0200 +@@ -0,0 +1,43 @@ ++/* ++ * This file is part of the libCEC(R) library. ++ * ++ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved. ++ * libCEC(R) is an original work, containing original code. ++ * ++ * libCEC(R) is a trademark of Pulse-Eight Limited. ++ * ++ * Sunxi adpater port is Copyright (C) 2016 by Joachim Damm ++ * based on IMX adpater port Copyright (C) 2013 by Stephan Rafin ++ * ++ * You can redistribute this file and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * ++ */ ++ ++#include "env.h" ++#include ++ ++#if defined(HAVE_SUNXI_API) ++#include "SunxiCECAdapterDetection.h" ++ ++ ++using namespace CEC; ++ ++bool CSunxiCECAdapterDetection::FindAdapter(void) ++{ ++ return access(CEC_SUNXI_PATH, 0) == 0; ++} ++ ++#endif +diff -Nur a/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.h b/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.h +--- a/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/libcec/adapter/Sunxi/SunxiCECAdapterDetection.h 2016-06-13 21:28:56.213089581 +0200 +@@ -0,0 +1,37 @@ ++#pragma once ++/* ++ * This file is part of the libCEC(R) library. ++ * ++ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved. ++ * libCEC(R) is an original work, containing original code. ++ * ++ * libCEC(R) is a trademark of Pulse-Eight Limited. ++ * ++ * Sunxi adpater port is Copyright (C) 2013 by Joachim Damm ++ * based on IMX adpater port Copyright (C) 2013 by Stephan Rafin ++ * ++ * You can redistribute this file and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * ++ */ ++ ++namespace CEC ++{ ++ class CSunxiCECAdapterDetection ++ { ++ public: ++ static bool FindAdapter(void); ++ }; ++} +diff -Nur a/src/libcec/CECTypeUtils.h b/src/libcec/CECTypeUtils.h +--- a/src/libcec/CECTypeUtils.h 2016-06-13 21:27:29.386425322 +0200 ++++ b/src/libcec/CECTypeUtils.h 2016-06-13 21:33:04.353082699 +0200 +@@ -767,6 +767,8 @@ + return "TDA995x"; + case ADAPTERTYPE_IMX: + return "i.MX"; ++ case ADAPTERTYPE_SUNXI: ++ return "Sunxi"; + default: + return "unknown"; + } +diff -Nur a/src/libcec/cmake/CheckPlatformSupport.cmake b/src/libcec/cmake/CheckPlatformSupport.cmake +--- a/src/libcec/cmake/CheckPlatformSupport.cmake 2016-06-13 21:27:29.406425322 +0200 ++++ b/src/libcec/cmake/CheckPlatformSupport.cmake 2016-06-13 22:49:15.126289255 +0200 +@@ -142,6 +142,19 @@ + else() + set(HAVE_AMLOGIC_API 0) + endif() ++ ++ # Sunxi ++ if (${HAVE_SUNXI_LIB}) ++ set(LIB_INFO "${LIB_INFO}, Sunxi") ++ set(HAVE_SUNXI_API 1) ++ set(CEC_SOURCES_ADAPTER_SUNXI adapter/Sunxi/SunxiCECAdapterDetection.cpp ++ adapter/Sunxi/SunxiCECAdapterCommunication.cpp) ++ source_group("Source Files\\adapter\\Sunxi" FILES ${CEC_SOURCES_ADAPTER_SUNXI}) ++ list(APPEND CEC_SOURCES ${CEC_SOURCES_ADAPTER_SUNXI}) ++ else() ++ set(HAVE_SUNXI_API 0) ++ endif() ++ + endif() + + # rt +diff -Nur a/src/libcec/cmake/DisplayPlatformSupport.cmake b/src/libcec/cmake/DisplayPlatformSupport.cmake +--- a/src/libcec/cmake/DisplayPlatformSupport.cmake 2016-06-13 21:27:29.406425322 +0200 ++++ b/src/libcec/cmake/DisplayPlatformSupport.cmake 2016-06-13 21:38:48.466406487 +0200 +@@ -56,6 +56,12 @@ + message(STATUS "Amlogic support: no") + endif() + ++if (HAVE_SUNXI_API) ++ message(STATUS "Sunxi support: yes") ++else() ++ message(STATUS "Sunxi support: no") ++endif() ++ + if (HAVE_PYTHON) + message(STATUS "Python support: version ${PYTHONLIBS_VERSION_STRING} (${PYTHON_VERSION})") + else() +diff -Nur a/src/libcec/CMakeLists.txt b/src/libcec/CMakeLists.txt +--- a/src/libcec/CMakeLists.txt 2016-06-13 21:27:29.406425322 +0200 ++++ b/src/libcec/CMakeLists.txt 2016-06-13 21:28:56.209756247 +0200 +@@ -99,6 +99,9 @@ + adapter/RPi/RPiCECAdapterMessageQueue.h + adapter/RPi/RPiCECAdapterCommunication.h + adapter/RPi/RPiCECAdapterDetection.h ++ adapter/Sunxi/AdapterMessageQueue.h ++ adapter/Sunxi/SunxiCECAdapterCommunication.h ++ adapter/Sunxi/SunxiCECAdapterDetection.h + CECInputBuffer.h + platform/util/baudrate.h + platform/util/edid.h +diff -Nur a/src/libcec/env.h.in b/src/libcec/env.h.in +--- a/src/libcec/env.h.in 2016-06-13 21:27:29.406425322 +0200 ++++ b/src/libcec/env.h.in 2016-06-13 21:28:56.213089581 +0200 +@@ -72,6 +72,9 @@ + /* Define to 1 for Amlogic support */ + #cmakedefine HAVE_AMLOGIC_API @HAVE_AMLOGIC_API@ + ++/* Define to 1 for Sunxi support */ ++#cmakedefine HAVE_SUNXI_API @HAVE_SUNXI_API@ ++ + /* Define to 1 for nVidia EDID parsing support (on selected models) */ + #cmakedefine HAVE_NVIDIA_EDID_PARSER @HAVE_NVIDIA_EDID_PARSER@ + diff --git a/packages/graphics/sunxi-mali/package.mk b/packages/graphics/sunxi-mali/package.mk new file mode 100644 index 00000000000..be2c66862cd --- /dev/null +++ b/packages/graphics/sunxi-mali/package.mk @@ -0,0 +1,49 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +PKG_NAME="sunxi-mali" +PKG_VERSION="20160229" +PKG_REV="1" +PKG_ARCH="arm" +PKG_LICENSE="nonfree" +PKG_SITE="https://github.com/WhiteWind/sunxi-mali-proprietary" +PKG_URL="http://down.nu/packages/$PKG_NAME-$PKG_VERSION.tar.xz" +PKG_DEPENDS_TARGET="toolchain" +PKG_PRIORITY="optional" +PKG_SECTION="graphics" +PKG_SHORTDESC="sunxi-mali: OpenGL-ES and Mali driver for Mali 400 GPUs" +PKG_LONGDESC="sunxi-mali: OpenGL-ES and Mali driver for Mali 400 GPUs" + +PKG_IS_ADDON="no" +PKG_AUTORECONF="no" + +make_target() { + : # nothing todo +} + +makeinstall_target() { + mkdir -p $SYSROOT_PREFIX/usr/include + cp -PR src/include/* $SYSROOT_PREFIX/usr/include + + mkdir -p $SYSROOT_PREFIX/usr/lib + cp -PR src/lib/*.so* $SYSROOT_PREFIX/usr/lib + + mkdir -p $INSTALL/usr/lib + cp -PR src/lib/*.so* $INSTALL/usr/lib +} + diff --git a/packages/linux-drivers/mt7601u/package.mk b/packages/linux-drivers/mt7601u/package.mk new file mode 100644 index 00000000000..39b485f1c6e --- /dev/null +++ b/packages/linux-drivers/mt7601u/package.mk @@ -0,0 +1,56 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +PKG_NAME="mt7601u" +PKG_VERSION="e65aed5" +PKG_REV="1" +PKG_ARCH="any" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/porjo/mt7601" +PKG_URL="http://down.nu/packages/$PKG_NAME-$PKG_VERSION.tar.xz" +PKG_DEPENDS_TARGET="toolchain linux" +PKG_NEED_UNPACK="$LINUX_DEPENDS" +PKG_PRIORITY="optional" +PKG_SECTION="driver" +PKG_SHORTDESC="Mediatek MT7601U Linux 3.x driver" +PKG_LONGDESC="Mediatek MT7601U Linux 3.x driver" + +PKG_IS_ADDON="no" +PKG_AUTORECONF="no" + +pre_make_target() { + unset LDFLAGS +} + +make_target() { + sed -i '200s|.*LINUX_SRC.*|LINUX_SRC = '$(kernel_path)'|' src/Makefile + sed -i '203s|.*LINUX_SRC_MODULE.*|LINUX_SRC_MODULE = '$INSTALL'/lib/modules/'$(get_module_dir)'/kernel/drivers/net/wireless/|' src/Makefile + sed -i '204s|.*CROSS_COMPILE.*|CROSS_COMPILE = $(TARGET_PREFIX)|' src/Makefile + sed -i '205i ARCH = $(TARGET_ARCH)' src/Makefile + sed -i '206i export ARCH' src/Makefile + sed -i '207i export CROSS_COMPILE' src/Makefile + make -C src osdrv +} + +makeinstall_target() { + mkdir -p $INSTALL/lib/modules/$(get_module_dir)/$PKG_NAME + cp src/os/linux/mt7601Usta.ko $INSTALL/lib/modules/$(get_module_dir)/$PKG_NAME + + mkdir -p $INSTALL/lib/firmware/mt7601u + cp src/RT2870STA.dat $INSTALL/lib/firmware/mt7601u/mt7601u_sta.dat +} diff --git a/packages/linux-drivers/mt7601u/patches/mt7601u-000-build-fix.patch b/packages/linux-drivers/mt7601u/patches/mt7601u-000-build-fix.patch new file mode 100644 index 00000000000..2d348d1bb85 --- /dev/null +++ b/packages/linux-drivers/mt7601u/patches/mt7601u-000-build-fix.patch @@ -0,0 +1,12 @@ +diff -Nur a/src/include/os/rt_linux.h b/src/include/os/rt_linux.h +--- a/src/include/os/rt_linux.h 2015-10-04 22:56:40.000000000 +0200 ++++ b/src/include/os/rt_linux.h 2016-02-01 22:11:19.837259634 +0100 +@@ -279,7 +279,7 @@ + + typedef struct _OS_FS_INFO_ + { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) + uid_t fsuid; + gid_t fsgid; + #else diff --git a/packages/linux-drivers/mt7601u/patches/mt7601u-001-wlan-interface.patch b/packages/linux-drivers/mt7601u/patches/mt7601u-001-wlan-interface.patch new file mode 100644 index 00000000000..c23e5c6d149 --- /dev/null +++ b/packages/linux-drivers/mt7601u/patches/mt7601u-001-wlan-interface.patch @@ -0,0 +1,13 @@ +--- a/src/include/rtmp_def.h 2016-02-16 11:23:49.000000000 +0100 ++++ b/src/include/rtmp_def.h 2016-04-18 21:57:18.566527968 +0200 +@@ -1601,8 +1601,8 @@ + #define INF_MAIN_DEV_NAME "wlan" + #define INF_MBSSID_DEV_NAME "wlan" + #else +-#define INF_MAIN_DEV_NAME "ra" +-#define INF_MBSSID_DEV_NAME "ra" ++#define INF_MAIN_DEV_NAME "wlan" ++#define INF_MBSSID_DEV_NAME "wlan" + #endif /* ANDROID_SUPPORT */ + #define INF_WDS_DEV_NAME "wds" + #define INF_APCLI_DEV_NAME "apcli" diff --git a/packages/linux-drivers/mt7601u/patches/mt7601u-002-firmware-path.patch b/packages/linux-drivers/mt7601u/patches/mt7601u-002-firmware-path.patch new file mode 100644 index 00000000000..355ddce4b89 --- /dev/null +++ b/packages/linux-drivers/mt7601u/patches/mt7601u-002-firmware-path.patch @@ -0,0 +1,24 @@ +diff -Nur a/src/include/os/rt_drv.h b/src/include/os/rt_drv.h +--- a/src/include/os/rt_drv.h 2016-02-16 11:23:49.000000000 +0100 ++++ b/src/include/os/rt_drv.h 2016-04-18 21:59:18.653191304 +0200 +@@ -56,7 +56,7 @@ + #ifdef CONFIG_STA_SUPPORT + + #ifdef RTMP_MAC_USB +-#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat" ++#define STA_PROFILE_PATH "/lib/firmware/mt7601u/mt7601u_sta.dat" + #define STA_DRIVER_VERSION "3.0.0.3" + #ifdef MULTIPLE_CARD_SUPPORT + #define CARD_INFO_PATH "/etc/Wireless/RT2870STA/RT2870STACard.dat" +diff -Nur a/src/include/os/rt_linux.h b/src/include/os/rt_linux.h +--- a/src/include/os/rt_linux.h 2016-02-16 11:23:49.000000000 +0100 ++++ b/src/include/os/rt_linux.h 2016-04-18 21:59:26.406524422 +0200 +@@ -127,7 +127,7 @@ + #ifdef CONFIG_STA_SUPPORT + + #ifdef RTMP_MAC_USB +-#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat" ++#define STA_PROFILE_PATH "/lib/firmware/mt7601u/mt7601u_sta.dat" + #define STA_DRIVER_VERSION "3.0.0.3" + #ifdef MULTIPLE_CARD_SUPPORT + #define CARD_INFO_PATH "/etc/Wireless/RT2870STA/RT2870STACard.dat" diff --git a/packages/linux-drivers/mt7610u/package.mk b/packages/linux-drivers/mt7610u/package.mk index 5281b0ab6ef..559c3dd2f32 100644 --- a/packages/linux-drivers/mt7610u/package.mk +++ b/packages/linux-drivers/mt7610u/package.mk @@ -35,6 +35,11 @@ PKG_LONGDESC="Mediatek mt7610u Linux driver" PKG_IS_ADDON="no" PKG_AUTORECONF="no" +pre_make_target() { + unset LDFLAGS +} + + make_target() { sed -i '198s|.*LINUX_SRC.*|LINUX_SRC = '$(kernel_path)'|' Makefile diff --git a/packages/linux-firmware/wlan-firmware/package.mk b/packages/linux-firmware/wlan-firmware/package.mk index 2c881add55b..f5ff326600d 100644 --- a/packages/linux-firmware/wlan-firmware/package.mk +++ b/packages/linux-firmware/wlan-firmware/package.mk @@ -17,12 +17,12 @@ ################################################################################ PKG_NAME="wlan-firmware" -PKG_VERSION="3da1769" +PKG_VERSION="2613630" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="Free-to-use" -PKG_SITE="https://github.com/OpenELEC/wlan-firmware" -PKG_GIT_URL="https://github.com/OpenELEC/wlan-firmware.git" +PKG_SITE="https://github.com/jernejsk/wlan-firmware" +PKG_GIT_URL="https://github.com/jernejsk/wlan-firmware.git" PKG_GIT_BRANCH="master" PKG_DEPENDS_TARGET="toolchain brcm_patchram" PKG_PRIORITY="optional" diff --git a/packages/linux/package.mk b/packages/linux/package.mk index 83eb65a120a..06d63e0df24 100644 --- a/packages/linux/package.mk +++ b/packages/linux/package.mk @@ -44,6 +44,12 @@ case "$LINUX" in PKG_GIT_URL="https://github.com/raspberrypi/linux.git" PKG_GIT_BRANCH="rpi-4.4.y" ;; + sun8i) + PKG_VERSION="5ea667f" + PKG_GIT_URL="https://github.com/jernejsk/linux.git" + PKG_GIT_BRANCH="master" + PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET sunxi-tools:host sunxi-sys-utils" + ;; *) PKG_VERSION="4.4.45" PKG_URL="http://www.kernel.org/pub/linux/kernel/v4.x/$PKG_NAME-$PKG_VERSION.tar.xz" @@ -130,6 +136,14 @@ pre_make_target() { make_target() { LDFLAGS="" make modules LDFLAGS="" make INSTALL_MOD_PATH=$INSTALL DEPMOD="$ROOT/$TOOLCHAIN/bin/depmod" modules_install + + if [ "$LINUX" = "sun8i" ]; then + for all_fex in $PROJECT_DIR/$PROJECT/sys_config/*.fex; do + fex=$(basename $all_fex) + fex2bin $all_fex $fex + done + fi + rm -f $INSTALL/lib/modules/*/build rm -f $INSTALL/lib/modules/*/source @@ -159,6 +173,9 @@ makeinstall_target() { for dtb in arch/$TARGET_KERNEL_ARCH/boot/dts/*.dtb; do cp $dtb $INSTALL/usr/share/bootloader 2>/dev/null || : done + for fex in *.fex; do + cp $fex $INSTALL/usr/share/bootloader 2>/dev/null || : + done elif [ "$BOOTLOADER" = "bcm2835-firmware" ]; then mkdir -p $INSTALL/usr/share/bootloader/overlays cp -p arch/$TARGET_KERNEL_ARCH/boot/dts/*.dtb $INSTALL/usr/share/bootloader diff --git a/packages/mediacenter/kodi/config/guisettings.xml b/packages/mediacenter/kodi/config/guisettings.xml index 8599258e30d..b5634ac6a33 100755 --- a/packages/mediacenter/kodi/config/guisettings.xml +++ b/packages/mediacenter/kodi/config/guisettings.xml @@ -1,4 +1,7 @@ + + ALSA:sysdefault:CARD=sndhdmi + /storage/screenshots/ diff --git a/packages/mediacenter/kodi/package.mk b/packages/mediacenter/kodi/package.mk index 8d51494ca88..f5d9fb48065 100644 --- a/packages/mediacenter/kodi/package.mk +++ b/packages/mediacenter/kodi/package.mk @@ -217,6 +217,8 @@ if [ ! "$KODIPLAYER_DRIVER" = default ]; then PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET gpu-viv-g2d" elif [ "$KODIPLAYER_DRIVER" = libamcodec ]; then KODI_CODEC="--enable-codec=amcodec" + elif [ "$KODIPLAYER_DRIVER" = cedarx ]; then + KODI_CODEC="--enable-codec=cedarx" else KODI_OPENMAX="--disable-openmax" fi diff --git a/packages/multimedia/cedarx/package.mk b/packages/multimedia/cedarx/package.mk new file mode 100644 index 00000000000..3db72763395 --- /dev/null +++ b/packages/multimedia/cedarx/package.mk @@ -0,0 +1,49 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +PKG_NAME="cedarx" +PKG_VERSION="20150512" +PKG_REV="1" +PKG_ARCH="arm" +PKG_LICENSE="nonfree" +PKG_SITE="http://www.allwinnertech.com/" +PKG_URL="http://down.nu/packages/$PKG_NAME-$PKG_VERSION.tar.xz" +PKG_DEPENDS_TARGET="toolchain" +PKG_PRIORITY="optional" +PKG_SECTION="multimedia" +PKG_SHORTDESC="CedarX library" +PKG_LONGDESC="CedarX library uses VPU for video decoding" + +PKG_IS_ADDON="no" +PKG_AUTORECONF="no" + +make_target() { + : # nothing to do +} + +makeinstall_target() { + mkdir -p $SYSROOT_PREFIX/usr/include/cedarx + cp -PR include/* $SYSROOT_PREFIX/usr/include/cedarx + + mkdir -p $SYSROOT_PREFIX/usr/lib + cp -PR lib/*.so* $SYSROOT_PREFIX/usr/lib + + mkdir -p $INSTALL/usr/lib + cp -PR lib/*.so* $INSTALL/usr/lib +} + diff --git a/packages/sysutils/busybox/config/suspend-modules.conf b/packages/sysutils/busybox/config/suspend-modules.conf index 54ee22373b3..80c9efbaafc 100644 --- a/packages/sysutils/busybox/config/suspend-modules.conf +++ b/packages/sysutils/busybox/config/suspend-modules.conf @@ -1 +1 @@ -SUSPEND_MODULES="jme asix anysee rtl8192se imon r8712u cx23885 cdc_acm ddbridge brcmfmac 8812au" +SUSPEND_MODULES="jme asix anysee rtl8192se imon r8712u cx23885 cdc_acm ddbridge brcmfmac 8812au 8189es" diff --git a/packages/sysutils/eventlircd/udev.d/98-eventlircd.rules b/packages/sysutils/eventlircd/udev.d/98-eventlircd.rules index e153d5086d1..34fbdfad071 100644 --- a/packages/sysutils/eventlircd/udev.d/98-eventlircd.rules +++ b/packages/sysutils/eventlircd/udev.d/98-eventlircd.rules @@ -74,6 +74,11 @@ SUBSYSTEMS=="input", ATTRS{name}=="gpio_keypad", \ ENV{eventlircd_enable}="true", \ ENV{eventlircd_evmap}="default.evmap" +# Sunxi (power button) +SUBSYSTEMS=="input", ATTRS{name}=="sunxi-gpiokey", \ + ENV{eventlircd_enable}="true", \ + ENV{eventlircd_evmap}="default.evmap" + #------------------------------------------------------------------------------- # Ask eventlircd to handle USB HID devices that show up as event devices and are # known to be remote controls. For simplicity, the event map file names have the diff --git a/packages/sysutils/kmod/package.mk b/packages/sysutils/kmod/package.mk index 6eb47d2f789..d2c5175218c 100644 --- a/packages/sysutils/kmod/package.mk +++ b/packages/sysutils/kmod/package.mk @@ -22,7 +22,7 @@ PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="http://git.profusion.mobi/cgit.cgi/kmod.git/" -PKG_URL="http://ftp.kernel.org/pub/linux/utils/kernel/kmod/$PKG_NAME-$PKG_VERSION.tar.xz" +PKG_URL="https://kernel.org/pub/linux/utils/kernel/kmod/$PKG_NAME-$PKG_VERSION.tar.xz" PKG_DEPENDS_TARGET="toolchain" PKG_PRIORITY="optional" PKG_SECTION="system" diff --git a/packages/sysutils/lcdproc/patches/lcdproc-i2c-lcdconf.patch b/packages/sysutils/lcdproc/patches/lcdproc-i2c-lcdconf.patch new file mode 100644 index 00000000000..eadebc583b3 --- /dev/null +++ b/packages/sysutils/lcdproc/patches/lcdproc-i2c-lcdconf.patch @@ -0,0 +1,322 @@ +diff -Naur adocs/lcdproc-user/drivers/hd44780.docbook b/docs/lcdproc-user/drivers/hd44780.docbook +--- a/docs/lcdproc-user/drivers/hd44780.docbook 2014-02-18 08:36:35.000000000 +1100 ++++ b/docs/lcdproc-user/drivers/hd44780.docbook 2015-09-20 18:51:23.000000000 +1000 +@@ -2516,6 +2516,61 @@ + DelayBus=false + DelayMult=1 + Keypad=no ++#i2c_line_RS=0x10 ++#i2c_line_RW=0x20 ++#i2c_line_EN=0x40 ++#i2c_line_BL=0x80 ++#i2c_line_D4=0x01 ++#i2c_line_D5=0x02 ++#i2c_line_D6=0x04 ++#i2c_line_D7=0x08 ++# BacklightInvert=yes ++# The Backlight Invert is used if a 0 turns the backlight on, and 1 turns it off, i.e. npn transistor ++]]> ++ ++ ++ ++ ++If your port expander has different wiring you can re-assign the pins in the config file ++ ++ ++ ++HD44780: Configuration for I<superscript>2</superscript>C with port expander ++Alternative Wiring ++ ++ ++ ++ ++ ++ ++HD44780: Configuration for I<superscript>2</superscript>C with port expander ++alternative config ++ ++ + + +diff -Naur a/server/drivers/hd44780-i2c.c b/server/drivers/hd44780-i2c.c +--- a/server/drivers/hd44780-i2c.c 2014-02-18 08:36:35.000000000 +1100 ++++ b/server/drivers/hd44780-i2c.c 2015-09-20 18:51:23.000000000 +1000 +@@ -13,17 +13,38 @@ + * 1997 Matthias Prinke + * + * The connections are: +- * PCF8574AP LCD +- * P0 (4) D4 (11) +- * P1 (5) D5 (12) +- * P2 (6) D6 (13) +- * P3 (7) D7 (14) +- * P4 (9) RS (4) +- * P5 (10) RW (5) +- * P6 (11) EN (6) ++ * PCF8574AP Bit LCD ++ * P0 (4) 0x01 D4 (11) ++ * P1 (5) 0x02 D5 (12) ++ * P2 (6) 0x04 D6 (13) ++ * P3 (7) 0x08 D7 (14) ++ * P4 (9) 0x10 RS (4) ++ * P5 (10) 0x20 RW (5) ++ * P6 (11) 0x40 EN (6) ++ * P7 (12) 0x80 /backlight (optional, active-low) + * +- * Backlight +- * P7 (12) /backlight (optional, active-low) ++ * Configuration: ++ \verbatim ++ alternative wiring example: ++ PCF8574AP: P0 P1 P2 P3 P4 P5 P6 P7 ++ | | | | | | | | ++ HD44780: RS RW EN BL D4 D5 D6 D7 ++ ++ in LCDd.conf we then need to define ++ i2c_line_RS=0x01 ++ i2c_line_RW=0x02 ++ i2c_line_EN=0x04 ++ i2c_line_BL=0x80 ++ i2c_line_D4=0x10 ++ i2c_line_D5=0x20 ++ i2c_line_D6=0x40 ++ i2c_line_D7=0x80 ++ Backlight=yes ++ BacklightInvert=yes ++ ++ The Backlight Invert is used if a 0 turns the backlight on, and 1 turns it off, i.e. npn transistor ++\endverbatim ++ + * + * Configuration: + * device=/dev/i2c-0 # the device file of the i2c bus +@@ -89,6 +110,11 @@ + #define RW 0x20 + #define EN 0x40 + #define BL 0x80 ++#define D4 0x01 ++#define D5 0x02 ++#define D6 0x04 ++#define D7 0x08 ++#define BL_INVERT 0 + // note that the above bits are all meant for the data port of PCF8574 + + #define I2C_ADDR_MASK 0x7f +@@ -145,14 +171,34 @@ + PrivateData *p = (PrivateData*) drvthis->private_data; + HD44780_functions *hd44780_functions = p->hd44780_functions; + +- int enableLines = EN; +- char device[256] = DEFAULT_DEVICE; ++ p->i2c_backlight_invert = drvthis->config_get_bool(drvthis->name, "BacklightInvert", 0, BL_INVERT); ++ p->i2c_line_RS = drvthis->config_get_int(drvthis->name, "i2c_line_RS", 0, RS); ++ p->i2c_line_RW = drvthis->config_get_int(drvthis->name, "i2c_line_RW", 0, RW); ++ p->i2c_line_EN = drvthis->config_get_int(drvthis->name, "i2c_line_EN", 0, EN); ++ p->i2c_line_BL = drvthis->config_get_int(drvthis->name, "i2c_line_BL", 0, BL); ++ p->i2c_line_D4 = drvthis->config_get_int(drvthis->name, "i2c_line_D4", 0, D4); ++ p->i2c_line_D5 = drvthis->config_get_int(drvthis->name, "i2c_line_D5", 0, D5); ++ p->i2c_line_D6 = drvthis->config_get_int(drvthis->name, "i2c_line_D6", 0, D6); ++ p->i2c_line_D7 = drvthis->config_get_int(drvthis->name, "i2c_line_D7", 0, D7); ++ ++ report(RPT_INFO, "HD44780: I2C: Init using D4 and D5, and or'd lines, invert", p->i2c_line_RS); ++ report(RPT_INFO, "HD44780: I2C: Pin RS mapped to 0x%02X", p->i2c_line_RS); ++ report(RPT_INFO, "HD44780: I2C: Pin RW mapped to 0x%02X", p->i2c_line_RW); ++ report(RPT_INFO, "HD44780: I2C: Pin EN mapped to 0x%02X", p->i2c_line_EN); ++ report(RPT_INFO, "HD44780: I2C: Pin BL mapped to 0x%02X", p->i2c_line_BL); ++ report(RPT_INFO, "HD44780: I2C: Pin D4 mapped to 0x%02X", p->i2c_line_D4); ++ report(RPT_INFO, "HD44780: I2C: Pin D5 mapped to 0x%02X", p->i2c_line_D5); ++ report(RPT_INFO, "HD44780: I2C: Pin D6 mapped to 0x%02X", p->i2c_line_D6); ++ report(RPT_INFO, "HD44780: I2C: Pin D7 mapped to 0x%02X", p->i2c_line_D7); ++ report(RPT_INFO, "HD44780: I2C: Invert Backlight %d", p->i2c_backlight_invert); ++ ++ char device[256] = DEFAULT_DEVICE; + #ifdef HAVE_DEV_IICBUS_IIC_H + struct iiccmd cmd; + bzero(&cmd, sizeof(cmd)); + #endif + +- p->backlight_bit = BL; ++ p->backlight_bit = p->i2c_line_BL; + + /* READ CONFIG FILE */ + +@@ -209,44 +255,49 @@ + + // powerup the lcd now + /* We'll now send 0x03 a couple of times, +- * which is in fact (FUNCSET | IF_8BIT) >> 4 */ +- i2c_out(p, 0x03); ++ * which is in fact (FUNCSET | IF_8BIT) >> 4 ++ */ ++ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5); + if (p->delayBus) + hd44780_functions->uPause(p, 1); + +- i2c_out(p, enableLines | 0x03); ++ i2c_out(p, p->i2c_line_EN | p->i2c_line_D4 | p->i2c_line_D5); + if (p->delayBus) + hd44780_functions->uPause(p, 1); +- i2c_out(p, 0x03); ++ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5); + hd44780_functions->uPause(p, 15000); + +- i2c_out(p, enableLines | 0x03); ++ i2c_out(p, p->i2c_line_EN | p->i2c_line_D4 | p->i2c_line_D5); + if (p->delayBus) + hd44780_functions->uPause(p, 1); +- i2c_out(p, 0x03); ++ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5); + hd44780_functions->uPause(p, 5000); + +- i2c_out(p, enableLines | 0x03); ++ i2c_out(p, p->i2c_line_EN | p->i2c_line_D4 | p->i2c_line_D5); + if (p->delayBus) + hd44780_functions->uPause(p, 1); +- i2c_out(p, 0x03); ++ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5); + hd44780_functions->uPause(p, 100); + +- i2c_out(p, enableLines | 0x03); ++ i2c_out(p, p->i2c_line_EN | p->i2c_line_D4 | p->i2c_line_D5); + if (p->delayBus) + hd44780_functions->uPause(p, 1); +- i2c_out(p, 0x03); ++ i2c_out(p, p->i2c_line_D4 | p->i2c_line_D5); + hd44780_functions->uPause(p, 100); + + // now in 8-bit mode... set 4-bit mode +- i2c_out(p, 0x02); ++ /* ++ OLD (FUNCSET | IF_4BIT) >> 4 0x02 ++ ALT (FUNCSET | IF_4BIT) 0x20 ++ */ ++ i2c_out(p, p->i2c_line_D5); + if (p->delayBus) + hd44780_functions->uPause(p, 1); + +- i2c_out(p, enableLines | 0x02); ++ i2c_out(p, p->i2c_line_EN | p->i2c_line_D5); + if (p->delayBus) + hd44780_functions->uPause(p, 1); +- i2c_out(p, 0x02); ++ i2c_out(p, p->i2c_line_D5); + hd44780_functions->uPause(p, 100); + + // Set up two-line, small character (5x8) mode +@@ -279,23 +330,28 @@ + void + i2c_HD44780_senddata(PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) + { +- unsigned char enableLines = 0, portControl = 0; +- unsigned char h = (ch >> 4) & 0x0f; // high and low nibbles +- unsigned char l = ch & 0x0f; +- ++ unsigned char portControl = 0; ++ unsigned char h=0; ++ unsigned char l=0; ++ if( ch & 0x80 ) h |= p->i2c_line_D7; ++ if( ch & 0x40 ) h |= p->i2c_line_D6; ++ if( ch & 0x20 ) h |= p->i2c_line_D5; ++ if( ch & 0x10 ) h |= p->i2c_line_D4; ++ if( ch & 0x08 ) l |= p->i2c_line_D7; ++ if( ch & 0x04 ) l |= p->i2c_line_D6; ++ if( ch & 0x02 ) l |= p->i2c_line_D5; ++ if( ch & 0x01 ) l |= p->i2c_line_D4; + if (flags == RS_INSTR) + portControl = 0; + else //if (flags == RS_DATA) +- portControl = RS; ++ portControl = p->i2c_line_RS; + + portControl |= p->backlight_bit; + +- enableLines = EN; +- + i2c_out(p, portControl | h); + if (p->delayBus) + p->hd44780_functions->uPause(p, 1); +- i2c_out(p, enableLines | portControl | h); ++ i2c_out(p, p->i2c_line_EN | portControl | h); + if (p->delayBus) + p->hd44780_functions->uPause(p, 1); + i2c_out(p, portControl | h); +@@ -303,7 +359,7 @@ + i2c_out(p, portControl | l); + if (p->delayBus) + p->hd44780_functions->uPause(p, 1); +- i2c_out(p, enableLines | portControl | l); ++ i2c_out(p, p->i2c_line_EN | portControl | l); + if (p->delayBus) + p->hd44780_functions->uPause(p, 1); + i2c_out(p, portControl | l); +@@ -317,7 +373,9 @@ + */ + void i2c_HD44780_backlight(PrivateData *p, unsigned char state) + { +- p->backlight_bit = ((!p->have_backlight||state) ? 0 : BL); +- ++ if ( p->i2c_backlight_invert == 0 ) ++ p->backlight_bit = ((!p->have_backlight||state) ? 0 : p->i2c_line_BL); ++ else // Inverted backlight - npn transistor ++ p->backlight_bit = ((p->have_backlight && state) ? p->i2c_line_BL : 0); + i2c_out(p, p->backlight_bit); + } +diff -Naur a/server/drivers/hd44780-low.h b/server/drivers/hd44780-low.h +--- a/server/drivers/hd44780-low.h 2016-01-14 10:45:52.473989654 +1100 ++++ b/server/drivers/hd44780-low.h 2015-09-20 18:51:23.000000000 +1000 +@@ -26,7 +26,7 @@ + #endif + + #ifdef HAVE_LIBFTDI +-# include ++# include + #endif + + /** \name Symbolic names for connection types +@@ -155,6 +155,21 @@ + int ftdi_line_backlight; + #endif + ++#ifdef HAVE_I2C ++ /* libi2c-based connection types */ ++ ++ int i2c_backlight_invert; ++ int i2c_line_RS; ++ int i2c_line_RW; ++ int i2c_line_EN; ++ int i2c_line_BL; ++ int i2c_line_D4; ++ int i2c_line_D5; ++ int i2c_line_D6; ++ int i2c_line_D7; ++ ++#endif ++ + #ifdef WITH_ETHLCD + int sock; /**< socket for TCP devices */ + #endif diff --git a/packages/sysutils/sunxi-sys-utils/bin/emmc_install.sh b/packages/sysutils/sunxi-sys-utils/bin/emmc_install.sh new file mode 100755 index 00000000000..abc9599c0d7 --- /dev/null +++ b/packages/sysutils/sunxi-sys-utils/bin/emmc_install.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +DISK=/dev/mmcblk1 +TMP=/tmp/mnt/ +TMPCFG=/tmp/boot.cfg + +SYSTEM_SIZE=512 +STORAGE_SIZE=32 # STORAGE_SIZE must be >= 32 ! + +DISK_SIZE=$(( $SYSTEM_SIZE + $STORAGE_SIZE + 4 )) + +. $SYSTEM_ROOT/usr/lib/openelec/sunxi-system-type + +echo "" +echo -e "\033[36m===============================" +echo "Installing OpenELEC to eMMC" +echo -e "===============================\033[37m" +echo "" + +if [ ! -b /dev/mmcblk1 ]; then + echo "Error: eMMC not found." + exit 1 +fi + +echo "" +echo -n "WARNING: ALL DATA ON eMMC WILL BE ERASED !, Continue (y/N)? " +read -n 1 ANSWER + +if [ ! "${ANSWER}" = "y" ] ; then + echo "Canceled.." + exit 0 +fi +echo "" + +umount ${DISK}* > /dev/null 2>&1 + +echo "Erasing eMMC ..." +dd if=/dev/zero of="$DISK" bs=1M count="$DISK_SIZE" conv=fsync > /dev/null 2>&1 +sync + +SYSTEM_PART_END=$(( $SYSTEM_SIZE * 1024 * 1024 / 512 + 2048 )) + +echo "Creating partition table" +parted -s "$DISK" mklabel msdos + +echo "Creating first partition" +parted -s "$DISK" -a min unit s mkpart primary fat32 2048 $SYSTEM_PART_END +parted -s "$DISK" set 1 boot on +sync + +STORAGE_PART_START=$(( $SYSTEM_PART_END + 2048 )) +STORAGE_PART_END=$(( $STORAGE_PART_START + (( $STORAGE_SIZE * 1024 * 1024 / 512 )) )) + +echo "Creating second partition" +parted -s "$DISK" -a min unit s mkpart primary ext4 $STORAGE_PART_START $STORAGE_PART_END +sync + +partprobe -s $DISK > /dev/null 2>&1 + +echo "Creating filesystems" +mkfs.vfat -n EMMCBOOT ${DISK}p1 > /dev/null 2>&1 +mkfs.ext4 -L emmclinux ${DISK}p2 > /dev/null 2>&1 +sync + +echo "Installing bootloader" +dd if=/usr/share/bootloader/uboot-sunxi-${SYSTEM_TYPE}.bin of="$DISK" bs=1k seek=8 conv=fsync > /dev/null 2>&1 + +echo "Copying files on first partition" + +mkdir ${TMP} + +mount -t vfat ${DISK}p1 ${TMP} + +cp /flash/* ${TMP}/ + +umount ${TMP} + +echo "Populating second partition" +mount -t ext4 ${DISK}p2 ${TMP} +touch ${TMP}/.please_resize_me +umount ${TMP} + +echo "Done" diff --git a/packages/sysutils/sunxi-sys-utils/package.mk b/packages/sysutils/sunxi-sys-utils/package.mk new file mode 100644 index 00000000000..9b6dff8e048 --- /dev/null +++ b/packages/sysutils/sunxi-sys-utils/package.mk @@ -0,0 +1,51 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2016 Stephan Raue (stephan@openelec.tv) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +PKG_NAME="sunxi-sys-utils" +PKG_VERSION="1.0" +PKG_REV="1" +PKG_ARCH="arm" +PKG_LICENSE="GPL" +PKG_SITE="http://github.com/jernejsk/OpenELEC-OPi2" +PKG_URL="" +PKG_DEPENDS_TARGET="toolchain sunxi-tools" +PKG_PRIORITY="optional" +PKG_SECTION="system" +PKG_SHORTDESC="Sunxi system utilities" +PKG_LONGDESC="Sunxi utilities for driver loading and eMMC installation" +PKG_IS_ADDON="no" +PKG_AUTORECONF="no" + +make_target() { + $CC $PKG_DIR/src/read_fex.c -o read_fex +} + +makeinstall_target() { + mkdir -p $INSTALL/usr/bin + cp $PKG_DIR/bin/* $INSTALL/usr/bin + cp read_fex $INSTALL/usr/bin + + mkdir -p $INSTALL/usr/lib/openelec + cp $PKG_DIR/scripts/* $INSTALL/usr/lib/openelec +} + +post_install() { + enable_service sunxi-bt-load.service + enable_service sunxi-poweroff.service + enable_service sunxi-suspend.service +} diff --git a/packages/sysutils/sunxi-sys-utils/scripts/bt_init b/packages/sysutils/sunxi-sys-utils/scripts/bt_init new file mode 100755 index 00000000000..3ba406cb02d --- /dev/null +++ b/packages/sysutils/sunxi-sys-utils/scripts/bt_init @@ -0,0 +1,31 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2016 Jernej Škrabec (jernej.skrabec@siol.net) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +# check if bluetooth is enabled +value=`read_fex bt_para bt_used` +if [ "$value" == "1" ]; then + # for now we know to handle only ap6212 + echo "0" > /sys/class/rfkill/rfkill0/state + echo "1" > /sys/class/rfkill/rfkill0/state + # assert RTS on UART + echo " " > /dev/ttyS1 + # load firmware and start it + hciattach /dev/ttyS1 bcm43xx 1500000 +fi diff --git a/packages/sysutils/sunxi-sys-utils/scripts/sunxi-system-type b/packages/sysutils/sunxi-sys-utils/scripts/sunxi-system-type new file mode 100755 index 00000000000..0271bc292d7 --- /dev/null +++ b/packages/sysutils/sunxi-sys-utils/scripts/sunxi-system-type @@ -0,0 +1,33 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2015 Stephan Raue (stephan@openelec.tv) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +# parse command line arguments (old way) +for arg in $(cat /proc/cmdline); do + case $arg in + board=*) + export SYSTEM_TYPE="${arg#*=}" + ;; + esac +done + +# read script.bin setting (new way) +if [ -z "$SYSTEM_TYPE" ]; then + SYSTEM_TYPE=`$SYSTEM_ROOT/usr/bin/read_fex product machine` +fi \ No newline at end of file diff --git a/packages/sysutils/sunxi-sys-utils/src/read_fex.c b/packages/sysutils/sunxi-sys-utils/src/read_fex.c new file mode 100644 index 00000000000..b602991a6db --- /dev/null +++ b/packages/sysutils/sunxi-sys-utils/src/read_fex.c @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2016 Jernej Škrabec + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + */ + +#include +#include +#include + +/* + * Definitions are taken from arch/arch/mach-sunxi/include/mach/sys_config.h + * which is released under GPL2+ and has following copyrights: + * (C) Copyright 2010-2015 + * Allwinner Technology Co., Ltd. + * Kevin + */ + +struct gpio_config { + uint32_t gpio; + uint32_t mul_sel; + uint32_t pull; + uint32_t drv_level; + uint32_t data; +}; + +enum { + SCIRPT_ITEM_VALUE_TYPE_INVALID = 0, + SCIRPT_ITEM_VALUE_TYPE_INT, + SCIRPT_ITEM_VALUE_TYPE_STR, + SCIRPT_ITEM_VALUE_TYPE_PIO, +}; + +typedef union { + int val; + char *str; + struct gpio_config gpio; +} script_item_u; + +const char *scriptfile = "/sys/class/script/get_item"; + +int main(int argc, char** argv) +{ + FILE *pFile; + script_item_u item; + size_t count; + uint32_t type; + int res = 0; + char buffer[1024]; + + if (argc != 3) + return -1; + + pFile = fopen(scriptfile, "w"); + if (pFile == NULL) + return -1; + + if (fprintf(pFile, "%s %s", argv[1], argv[2]) < 0) { + fclose(pFile); + return -1; + } + + fclose(pFile); + + pFile = fopen(scriptfile, "rb"); + if (pFile == NULL) + return -1; + + count = fread(&item, 1, sizeof(item), pFile); + if (count != sizeof(item)) { + fclose(pFile); + return -1; + } + + count = fread(&type, 1, sizeof(type), pFile); + if (count != sizeof(type)) { + fclose(pFile); + return -1; + } + + switch (type) { + case SCIRPT_ITEM_VALUE_TYPE_INT: + printf("%d", item.val); + break; + case SCIRPT_ITEM_VALUE_TYPE_STR: + while ((count = fread(buffer, 1, sizeof(buffer) - 1, pFile)) > 0) { + if (ferror(pFile)) { + res = -1; + break; + } + buffer[count] = '\0'; + printf("%s", buffer); + } + break; + default: + res = -1; + break; + } + + fclose(pFile); + + return res; +} \ No newline at end of file diff --git a/packages/sysutils/sunxi-sys-utils/system.d/sunxi-bt-load.service b/packages/sysutils/sunxi-sys-utils/system.d/sunxi-bt-load.service new file mode 100644 index 00000000000..ffdfffc9db6 --- /dev/null +++ b/packages/sysutils/sunxi-sys-utils/system.d/sunxi-bt-load.service @@ -0,0 +1,11 @@ +[Unit] +Description=bluetooth firmware loader +After=network.target + +[Service] +Type=simple +RemainAfterExit=yes +ExecStart=-/bin/sh -c ". /etc/profile; exec /bin/sh /usr/lib/openelec/bt_init" + +[Install] +WantedBy=network.target diff --git a/packages/sysutils/sunxi-sys-utils/system.d/sunxi-poweroff.service b/packages/sysutils/sunxi-sys-utils/system.d/sunxi-poweroff.service new file mode 100644 index 00000000000..9a2f9a8a60b --- /dev/null +++ b/packages/sysutils/sunxi-sys-utils/system.d/sunxi-poweroff.service @@ -0,0 +1,15 @@ +[Unit] +Description=sunxi poweroff service +Before=systemd-poweroff.service +After=kodi-poweroff.service +DefaultDependencies=no + +[Service] +Type=oneshot +Environment=HOME=/storage +ExecStart=-/bin/sh -c "echo 1 > /sys/class/leds/green_led/brightness" +StandardError=null +RemainAfterExit=yes + +[Install] +WantedBy=poweroff.target diff --git a/packages/sysutils/sunxi-sys-utils/system.d/sunxi-suspend.service b/packages/sysutils/sunxi-sys-utils/system.d/sunxi-suspend.service new file mode 100644 index 00000000000..4feab66c70b --- /dev/null +++ b/packages/sysutils/sunxi-sys-utils/system.d/sunxi-suspend.service @@ -0,0 +1,13 @@ +[Unit] +Description=sunxi suspend service +Before=sleep.target +StopWhenUnneeded=yes + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=-/bin/sh -c "echo 1 > /sys/class/leds/green_led/brightness; echo 1 > /sys/class/leds/red_led/brightness" +ExecStop=-/bin/sh -c "echo 0 > /sys/class/leds/green_led/brightness; echo 0 > /sys/class/leds/red_led/brightness" + +[Install] +WantedBy=sleep.target diff --git a/packages/tools/sunxi-tools/package.mk b/packages/tools/sunxi-tools/package.mk new file mode 100644 index 00000000000..81ed33b3362 --- /dev/null +++ b/packages/tools/sunxi-tools/package.mk @@ -0,0 +1,57 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2014 Stephan Raue (stephan@openelec.tv) +# +# OpenELEC is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# OpenELEC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenELEC. If not, see . +################################################################################ + +PKG_NAME="sunxi-tools" +PKG_VERSION="b7e092e" +PKG_REV="1" +PKG_ARCH="any" +PKG_LICENSE="GPL" +PKG_SITE="https://github.com/linux-sunxi/sunxi-tools" +PKG_GIT_URL="https://github.com/linux-sunxi/sunxi-tools.git" +PKG_GIT_BRANCH="master" +PKG_DEPENDS_HOST="" +PKG_PRIORITY="optional" +PKG_SECTION="tools" +PKG_SHORTDESC="sunxi-tools: Tools to help hacking Allwinner based devices." +PKG_LONGDESC="sunxi-tools: Tools to help hacking Allwinner based devices." + +PKG_IS_ADDON="no" +PKG_AUTORECONF="no" + +make_host() { + make clean + make fex2bin +} + +make_target() { + make clean + make CC="$TARGET_CC" fex2bin + make CC="$TARGET_CC" bin2fex +} + +makeinstall_host() { + cp -PR fex2bin $ROOT/$TOOLCHAIN/bin/ + cp -PR sunxi-fexc $ROOT/$TOOLCHAIN/bin/ +} + +makeinstall_target() { + mkdir -p $INSTALL/usr/bin + cp -PR fex2bin $INSTALL/usr/bin + cp -PR bin2fex $INSTALL/usr/bin + cp -PR sunxi-fexc $INSTALL/usr/bin +} diff --git a/packages/tools/u-boot/package.mk b/packages/tools/u-boot/package.mk index 086ea98e377..d8c424cd15f 100644 --- a/packages/tools/u-boot/package.mk +++ b/packages/tools/u-boot/package.mk @@ -26,6 +26,10 @@ elif [ "$UBOOT_VERSION" = "imx6-cuboxi" ]; then PKG_SITE="http://imx.solid-run.com/wiki/index.php?title=Building_the_kernel_and_u-boot_for_the_CuBox-i_and_the_HummingBoard" PKG_GIT_URL="https://github.com/SolidRun/u-boot-imx6.git" PKG_GIT_BRANCH="imx6" +elif [ "$UBOOT_VERSION" = "sunxi" ]; then + PKG_VERSION="2017.01" + PKG_SITE="http://www.denx.de/wiki/U-Boot/WebHome" + PKG_URL="ftp://ftp.denx.de/pub/u-boot/$PKG_NAME-$PKG_VERSION.tar.bz2" else exit 0 fi @@ -40,6 +44,10 @@ PKG_LONGDESC="Das U-Boot is a cross-platform bootloader for embedded systems, us PKG_IS_ADDON="no" PKG_AUTORECONF="no" +if [ "$UBOOT_VERSION" = "sunxi" ]; then + PKG_DEPENDS_TARGET="$PKG_DEPENDS_TARGET Python:host" +fi + pre_configure_target() { if [ -z "$UBOOT_CONFIG" ]; then echo "$TARGET_PLATFORM does not define any u-boot configuration, aborting." @@ -65,10 +73,6 @@ make_target() { done for UBOOT_TARGET in $UBOOT_CONFIG; do - make CROSS_COMPILE="$TARGET_PREFIX" ARCH="$TARGET_ARCH" mrproper - make CROSS_COMPILE="$TARGET_PREFIX" ARCH="$TARGET_ARCH" $UBOOT_TARGET - make CROSS_COMPILE="$TARGET_PREFIX" ARCH="$TARGET_ARCH" HOSTCC="$HOST_CC" HOSTSTRIP="true" - # rename files in case of multiple targets if [ $UBOOT_TARGET_CNT -gt 1 ]; then if [ "$UBOOT_TARGET" = "mx6_cubox-i_config" ]; then @@ -77,14 +81,49 @@ make_target() { TARGET_NAME="matrix" elif [ "$UBOOT_TARGET" = "udoo_config" ]; then TARGET_NAME="udoo" + elif [ "$UBOOT_TARGET" = "orangepi_2_defconfig" ]; then + TARGET_NAME="opi2" + elif [ "$UBOOT_TARGET" = "orangepi_pc_defconfig" ]; then + TARGET_NAME="opipc" + elif [ "$UBOOT_TARGET" = "orangepi_plus_defconfig" ]; then + TARGET_NAME="opiplus" + elif [ "$UBOOT_TARGET" = "orangepi_one_defconfig" ]; then + TARGET_NAME="opione" + elif [ "$UBOOT_TARGET" = "orangepi_lite_defconfig" ]; then + TARGET_NAME="opilite" + elif [ "$UBOOT_TARGET" = "Sinovoip_BPI_M2_plus_defconfig" ]; then + TARGET_NAME="bpim2p" + elif [ "$UBOOT_TARGET" = "orangepi_plus2e_defconfig" ]; then + TARGET_NAME="opiplus2e" + elif [ "$UBOOT_TARGET" = "orangepi_pc_plus_defconfig" ]; then + TARGET_NAME="opipcplus" + elif [ "$UBOOT_TARGET" = "Sinovoip_BPI_M3_defconfig" ]; then + TARGET_NAME="bpim3" + elif [ "$UBOOT_TARGET" = "beelink_x2_defconfig" ]; then + TARGET_NAME="bx2" else TARGET_NAME="undef" fi + fi + + if [ -f "$PROJECT_DIR/$PROJECT/logo/splash-$TARGET_NAME.bmp" ]; then + LOGOIMG="$PROJECT_DIR/$PROJECT/logo/splash-$TARGET_NAME.bmp" + elif [ -f "$PROJECT_DIR/$PROJECT/logo/splash.bmp" ]; then + LOGOIMG="$PROJECT_DIR/$PROJECT/logo/splash.bmp" + fi + + make CROSS_COMPILE="$TARGET_PREFIX" ARCH="$TARGET_ARCH" mrproper + make CROSS_COMPILE="$TARGET_PREFIX" ARCH="$TARGET_ARCH" $UBOOT_TARGET + make CROSS_COMPILE="$TARGET_PREFIX" ARCH="$TARGET_ARCH" HOSTCC="$HOST_CC" HOSTSTRIP="true" LOGO_BMP="$LOGOIMG" + if [ $UBOOT_TARGET_CNT -gt 1 ]; then [ -f u-boot.img ] && mv u-boot.img u-boot-$TARGET_NAME.img || : [ -f u-boot.imx ] && mv u-boot.imx u-boot-$TARGET_NAME.imx || : + [ -f u-boot-sunxi-with-spl.bin ] && mv u-boot-sunxi-with-spl.bin uboot-sunxi-$TARGET_NAME.bin || : [ -f SPL ] && mv SPL SPL-$TARGET_NAME || : fi + + [ -f u-boot-sunxi-with-spl.bin ] && mv u-boot-sunxi-with-spl.bin uboot-sunxi-bpim3.bin || : done } @@ -111,7 +150,12 @@ makeinstall_target() { mkdir -p $INSTALL/usr/share/bootloader cp ./u-boot*.imx $INSTALL/usr/share/bootloader 2>/dev/null || : - cp ./u-boot*.img $INSTALL/usr/share/bootloader 2>/dev/null || : + #NOTE: sunxi u-boot build folder contains intermediate .img files which are not needed + if [ -f ./uboot-sunxi-opi2.bin -o -f ./uboot-sunxi-bpim3.bin ]; then + cp ./uboot-sunxi-*.bin $INSTALL/usr/share/bootloader 2>/dev/null + else + cp ./u-boot*.img $INSTALL/usr/share/bootloader 2>/dev/null || : + fi cp ./SPL* $INSTALL/usr/share/bootloader 2>/dev/null || : cp ./$UBOOT_CONFIGFILE $INSTALL/usr/share/bootloader 2>/dev/null || : diff --git a/packages/tools/u-boot/patches/u-boot-002-gcc5-use_gcc_inline_version_instead_c99.patch b/packages/tools/u-boot/patches/2011.03-rc1/u-boot-2011.03-rc1-9998-gcc5-use_gcc_inline_version_instead_c99.patch similarity index 100% rename from packages/tools/u-boot/patches/u-boot-002-gcc5-use_gcc_inline_version_instead_c99.patch rename to packages/tools/u-boot/patches/2011.03-rc1/u-boot-2011.03-rc1-9998-gcc5-use_gcc_inline_version_instead_c99.patch diff --git a/packages/tools/u-boot/patches/u-boot-003-gcc5-no-unalligned-access.patch b/packages/tools/u-boot/patches/2011.03-rc1/u-boot-2011.03-rc1-9999-gcc5-no-unalligned-access.patch similarity index 100% rename from packages/tools/u-boot/patches/u-boot-003-gcc5-no-unalligned-access.patch rename to packages/tools/u-boot/patches/2011.03-rc1/u-boot-2011.03-rc1-9999-gcc5-no-unalligned-access.patch diff --git a/packages/tools/u-boot/patches/imx6-cuboxi/u-boot-imx6-cuboxi-001-gcc5-use_gcc_inline_version_instead_c99.patch b/packages/tools/u-boot/patches/imx6-cuboxi/u-boot-imx6-cuboxi-001-gcc5-use_gcc_inline_version_instead_c99.patch new file mode 100644 index 00000000000..4a5e0de4ea4 --- /dev/null +++ b/packages/tools/u-boot/patches/imx6-cuboxi/u-boot-imx6-cuboxi-001-gcc5-use_gcc_inline_version_instead_c99.patch @@ -0,0 +1,56 @@ +[RFC 08/10] inline: use the gcc inline version instead of the c99 one. + +Jeroen Hofstee jeroen at myspectrum.nl +Sat May 31 22:32:22 CEST 2014 +Previous message: [U-Boot] [RFC 07/10] ARM: make gd a function a function for clang +Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] +--- +This fixes errors like: + +make[1]: Entering directory `/home/jeroen/software/u-boot/arch/arm/cpu/armv7/omap-common' +arm-linux-gnueabi-ld.bfd -r -o libomap-common.o reset.o timer.o utils.o +timer.o: In function `get_tbclk': +/home/jeroen/software/u-boot/include/asm/io.h:81: multiple definition of `__raw_writesb' +reset.o:/home/jeroen/software/u-boot/include/asm/io.h:81: first defined here +timer.o: In function `__udelay': +/home/jeroen/software/u-boot/include/asm/io.h:88: multiple definition of `__raw_writesw' +reset.o:/home/jeroen/software/u-boot/include/asm/io.h:88: first defined here +timer.o: In function `get_ticks': +/home/jeroen/software/u-boot/include/asm/io.h:95: multiple definition of `__raw_writesl' +reset.o:/home/jeroen/software/u-boot/include/asm/io.h:95: first defined here +timer.o: In function `__raw_readsb': +/home/jeroen/software/u-boot/include/asm/io.h:102: multiple definition of `__raw_readsb' +reset.o:/home/jeroen/software/u-boot/include/asm/io.h:102: first defined here +timer.o: In function `__raw_readsw': +/home/jeroen/software/u-boot/include/asm/io.h:109: multiple definition of `__raw_readsw' +reset.o:/home/jeroen/software/u-boot/include/asm/io.h:109: first defined here +timer.o: In function `__raw_readsl': +/home/jeroen/software/u-boot/include/asm/io.h:116: multiple definition of `__raw_readsl' +reset.o:/home/jeroen/software/u-boot/include/asm/io.h:116: first defined here +make[1]: *** [libomap-common.o] Error 1 +make[1]: Leaving directory `/home/jeroen/software/u-boot/arch/arm/cpu/armv7/omap-common' +make: *** [arch/arm/cpu/armv7/omap-common/libomap-common.o] Error 2 +--- + include/linux/compiler-gcc.h | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h +index 9896e54..99c6dcc 100644 +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -44,9 +44,10 @@ + */ + #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ + !defined(CONFIG_OPTIMIZE_INLINING) || (__GNUC__ < 4) +-# define inline inline __attribute__((always_inline)) +-# define __inline__ __inline__ __attribute__((always_inline)) +-# define __inline __inline __attribute__((always_inline)) ++/* XXX: check __GNUC_STDC_INLINE__, fix line length */ ++# define inline inline __attribute__((always_inline)) __attribute__((__gnu_inline__)) ++# define __inline__ __inline__ __attribute__((always_inline)) __attribute__((__gnu_inline__)) ++# define __inline __inline __attribute__((always_inline)) __attribute__((__gnu_inline__)) + #endif + + #define __deprecated __attribute__((deprecated)) +-- +1.8.3.2 diff --git a/packages/tools/u-boot/patches/imx6-cuboxi/u-boot-imx6-cuboxi-002-gcc5-no-unalligned-access.patch b/packages/tools/u-boot/patches/imx6-cuboxi/u-boot-imx6-cuboxi-002-gcc5-no-unalligned-access.patch new file mode 100644 index 00000000000..0c184eadf33 --- /dev/null +++ b/packages/tools/u-boot/patches/imx6-cuboxi/u-boot-imx6-cuboxi-002-gcc5-no-unalligned-access.patch @@ -0,0 +1,19 @@ +from https://raw.githubusercontent.com/schnitzeltony/meta-gumstix-community/master/recipes-bsp/u-boot/u-boot-overo/0013-arm-Switch-to-mno-unaligned-access-when-supported-by.patch + +--- a/arch/arm/cpu/armv7/config.mk 2015-11-22 20:44:42.744557427 +0100 ++++ b/arch/arm/cpu/armv7/config.mk 2015-11-22 20:45:26.381024395 +0100 +@@ -18,9 +18,12 @@ PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARMV7 + PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) + PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT) + +-# SEE README.arm-unaligned-accesses ++# On supported platforms we set the bit which causes us to trap on unaligned ++# memory access. This is the opposite of what the compiler expects to be ++# the default so we must pass in -mno-unaligned-access so that it is aware ++# of our decision. + PF_NO_UNALIGNED := $(call cc-option, -mno-unaligned-access,) +-PLATFORM_NO_UNALIGNED := $(PF_NO_UNALIGNED) ++PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED) + + ifneq ($(CONFIG_IMX_CONFIG),) + ifdef CONFIG_SPL diff --git a/packages/tools/u-boot/release b/packages/tools/u-boot/release index 80fa3a1cfb5..95bc9fc39a8 100755 --- a/packages/tools/u-boot/release +++ b/packages/tools/u-boot/release @@ -28,10 +28,16 @@ mkdir -p $RELEASE_DIR/3rdparty/bootloader cp -PR $BUILD/u-boot-*/$UBOOT_CONFIGFILE $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : cp -PR $BUILD/u-boot-*/SPL* $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : cp -PR $BUILD/u-boot-*/u-boot*.imx $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : - cp -PR $BUILD/u-boot-*/u-boot*.img $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : + #NOTE: sunxi u-boot build folder contains intermediate .img files which are not needed + if [ -f $BUILD/u-boot-*/uboot-sunxi-opi2.bin -o -f $BUILD/u-boot-*/uboot-sunxi-bpim3.bin ]; then + cp -PR $BUILD/u-boot-*/uboot-sunxi-*.bin $RELEASE_DIR/3rdparty/bootloader 2>/dev/null + else + cp -PR $BUILD/u-boot-*/u-boot*.img $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : + fi cp -PR $PROJECT_DIR/$PROJECT/bootloader/uEnv*.txt $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : cp -PR $HOME/.openelec/bootloader/* $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : cp -PR $HOME/.openelec/projects/$PROJECT/bootloader/* $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : cp -PR $BUILD/linux-*/arch/$TARGET_KERNEL_ARCH/boot/dts/*.dtb $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : + cp -PR $BUILD/linux-*/*.fex $RELEASE_DIR/3rdparty/bootloader 2>/dev/null || : diff --git a/packages/tools/u-boot/scripts/update.sh b/packages/tools/u-boot/scripts/update.sh index f224fc1860a..c66afcb0708 100755 --- a/packages/tools/u-boot/scripts/update.sh +++ b/packages/tools/u-boot/scripts/update.sh @@ -33,9 +33,14 @@ if [ -z "$BOOT_DISK" ]; then fi SYSTEM_TYPE="" +PROJECT="" if [ -f $SYSTEM_ROOT/usr/lib/openelec/imx6-system-type ]; then . $SYSTEM_ROOT/usr/lib/openelec/imx6-system-type fi +if [ -f $SYSTEM_ROOT/usr/lib/openelec/sunxi-system-type ]; then + PROJECT="sunxi" + . $SYSTEM_ROOT/usr/lib/openelec/sunxi-system-type +fi # mount $BOOT_ROOT r/w mount -o remount,rw $BOOT_ROOT @@ -50,7 +55,14 @@ fi done # update bootloader files - if [ "$SYSTEM_TYPE" = "matrix" ]; then + if [ "$PROJECT" = "sunxi" ]; then + if [ -f $SYSTEM_ROOT/usr/share/bootloader/${SYSTEM_TYPE}.fex ]; then + echo "*** updating Allwinner configuration file ..." + cp -p $SYSTEM_ROOT/usr/share/bootloader/${SYSTEM_TYPE}.fex $BOOT_ROOT/script.bin + fi + echo "*** updating u-boot image for board $SYSTEM_TYPE ..." + dd if=$SYSTEM_ROOT/usr/share/bootloader/uboot-sunxi-${SYSTEM_TYPE}.bin of="$BOOT_DISK" bs=1k seek=8 conv=fsync > /dev/null 2>&1 + elif [ "$SYSTEM_TYPE" = "matrix" ]; then if [ -f $SYSTEM_ROOT/usr/share/bootloader/u-boot-$SYSTEM_TYPE.imx ]; then echo "*** updating u-boot image in eMMC ..." # clean up u-boot parameters @@ -89,7 +101,8 @@ fi cp -p $SYSTEM_ROOT/usr/share/bootloader/uEnv-$SYSTEM_TYPE.txt $BOOT_ROOT/uEnv.txt elif [ -f $SYSTEM_ROOT/usr/share/bootloader/uEnv.txt -a ! -f $BOOT_ROOT/uEnv.txt ]; then cp -p $SYSTEM_ROOT/usr/share/bootloader/uEnv.txt $BOOT_ROOT - elif [ -f $SYSTEM_ROOT/usr/share/bootloader/boot.scr -a ! -f $BOOT_ROOT/boot.scr ]; then + #elif [ -f $SYSTEM_ROOT/usr/share/bootloader/boot.scr -a ! -f $BOOT_ROOT/boot.scr ]; then + elif [ -f $SYSTEM_ROOT/usr/share/bootloader/boot.scr ]; then cp -p $SYSTEM_ROOT/usr/share/bootloader/boot.scr $BOOT_ROOT fi diff --git a/packages/x11/font/liberation-fonts-ttf/package.mk b/packages/x11/font/liberation-fonts-ttf/package.mk index 5d161760e8f..5694378e584 100644 --- a/packages/x11/font/liberation-fonts-ttf/package.mk +++ b/packages/x11/font/liberation-fonts-ttf/package.mk @@ -22,7 +22,7 @@ PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="OFL1_1" PKG_SITE="https://www.redhat.com/promo/fonts/" -PKG_URL="https://fedorahosted.org/releases/l/i/liberation-fonts/$PKG_NAME-$PKG_VERSION.tar.gz" +PKG_URL="https://releases.pagure.org/liberation-fonts/$PKG_NAME-$PKG_VERSION.tar.gz" PKG_DEPENDS_TARGET="toolchain util-macros" PKG_PRIORITY="optional" PKG_SECTION="x11/fonts" diff --git a/projects/H3/bootloader/boot.cfg b/projects/H3/bootloader/boot.cfg new file mode 100644 index 00000000000..e3c67b4ec97 --- /dev/null +++ b/projects/H3/bootloader/boot.cfg @@ -0,0 +1,6 @@ +setenv machid 1029 +setenv bootm_boot_mode sec +setenv bootargs console=ttyS0,115200 boot=/dev/mmcblk0p1 disk=/dev/mmcblk0p2 consoleblank=0 +fatload mmc 0 0x43000000 script.bin +fatload mmc 0 0x42000000 KERNEL +bootm 0x42000000 diff --git a/projects/H3/filesystem/usr/lib/modules-load.d/cec.conf b/projects/H3/filesystem/usr/lib/modules-load.d/cec.conf new file mode 100644 index 00000000000..1af29491933 --- /dev/null +++ b/projects/H3/filesystem/usr/lib/modules-load.d/cec.conf @@ -0,0 +1 @@ +hdmi_cec diff --git a/projects/H3/filesystem/usr/lib/modules-load.d/mali.conf b/projects/H3/filesystem/usr/lib/modules-load.d/mali.conf new file mode 100644 index 00000000000..29c66fc8c8f --- /dev/null +++ b/projects/H3/filesystem/usr/lib/modules-load.d/mali.conf @@ -0,0 +1 @@ +mali diff --git a/projects/H3/filesystem/usr/lib/systemd/system/serial-console.service b/projects/H3/filesystem/usr/lib/systemd/system/serial-console.service new file mode 100644 index 00000000000..5dffa1a8431 --- /dev/null +++ b/projects/H3/filesystem/usr/lib/systemd/system/serial-console.service @@ -0,0 +1,22 @@ +[Unit] +Description=Debug Shell on /dev/console +DefaultDependencies=no +ConditionKernelCommandLine=console + +[Service] +WorkingDirectory=/storage +Environment="ENV=/etc/profile" +ExecStart=/bin/sh +Restart=always +RestartSec=0 +StandardInput=tty +TTYPath=/dev/console +TTYReset=yes +TTYVHangup=yes +KillMode=process +IgnoreSIGPIPE=no +# bash ignores SIGTERM +KillSignal=SIGHUP + +[Install] +WantedBy=sysinit.target diff --git a/projects/H3/filesystem/usr/share/alsa/cards/audio-hub.conf b/projects/H3/filesystem/usr/share/alsa/cards/audio-hub.conf new file mode 100644 index 00000000000..05f5b55fc09 --- /dev/null +++ b/projects/H3/filesystem/usr/share/alsa/cards/audio-hub.conf @@ -0,0 +1,15 @@ +# +# Configuration for H3 audiohub - /usr/share/alsa/cards/audiohub.conf +# + + + +audio-hub.pcm.rear.0 { + @args [ CARD ] + @args.CARD { + type string + } + type hw + card $CARD + device 0 +} diff --git a/projects/H3/filesystem/usr/share/alsa/cards/audiocodec.conf b/projects/H3/filesystem/usr/share/alsa/cards/audiocodec.conf new file mode 100644 index 00000000000..8d7ef41f1d6 --- /dev/null +++ b/projects/H3/filesystem/usr/share/alsa/cards/audiocodec.conf @@ -0,0 +1,15 @@ +# +# Configuration for H3 analog output - /usr/share/alsa/cards/audiocodec.conf +# + + + +audiocodec.pcm.front.0 { + @args [ CARD ] + @args.CARD { + type string + } + type hw + card $CARD + device 0 +} diff --git a/projects/H3/filesystem/usr/share/alsa/cards/snddaudio.conf b/projects/H3/filesystem/usr/share/alsa/cards/snddaudio.conf new file mode 100644 index 00000000000..5f5db84bb8e --- /dev/null +++ b/projects/H3/filesystem/usr/share/alsa/cards/snddaudio.conf @@ -0,0 +1,15 @@ +# +# Configuration for H3 snddaudio - /usr/share/alsa/cards/snddaudio.conf +# + + + +snddaudio.pcm.side.0 { + @args [ CARD ] + @args.CARD { + type string + } + type hw + card $CARD + device 0 +} diff --git a/projects/H3/filesystem/usr/share/alsa/cards/sndhdmi.conf b/projects/H3/filesystem/usr/share/alsa/cards/sndhdmi.conf new file mode 100644 index 00000000000..6ace4877a0d --- /dev/null +++ b/projects/H3/filesystem/usr/share/alsa/cards/sndhdmi.conf @@ -0,0 +1,32 @@ +# +# Configuration for H3 HDMI output - /usr/share/alsa/cards/sndhdmi.conf +# + + + +sndhdmi.pcm.hdmi.0 { + @args [ CARD AES0 AES1 AES2 AES3 ] + @args.CARD { type string } + @args.AES0 { type integer } + @args.AES1 { type integer } + @args.AES2 { type integer } + @args.AES3 { type integer } + type hooks + slave.pcm { + type hw + card $CARD + } + hooks.0 { + type ctl_elems + hook_args [ + { + interface PCM + name "IEC958 Playback Default" + lock true + preserve true + optional true + value [ $AES0 $AES1 $AES2 $AES3 ] + } + ] + } +} diff --git a/projects/H3/filesystem/usr/share/alsa/cards/sndspdif.conf b/projects/H3/filesystem/usr/share/alsa/cards/sndspdif.conf new file mode 100644 index 00000000000..1a4ad4d1a8e --- /dev/null +++ b/projects/H3/filesystem/usr/share/alsa/cards/sndspdif.conf @@ -0,0 +1,32 @@ +# +# Configuration for H3 SPDIF output - /usr/share/alsa/cards/sndspdif.conf +# + + + +sndspdif.pcm.iec958.0 { + @args [ CARD AES0 AES1 AES2 AES3 ] + @args.CARD { type string } + @args.AES0 { type integer } + @args.AES1 { type integer } + @args.AES2 { type integer } + @args.AES3 { type integer } + type hooks + slave.pcm { + type hw + card $CARD + } + hooks.0 { + type ctl_elems + hook_args [ + { + interface MIXER + name "IEC958 Playback Default" + lock true + preserve true + optional true + value [ $AES0 $AES1 $AES2 $AES3 ] + } + ] + } +} diff --git a/projects/H3/kodi/advancedsettings.xml b/projects/H3/kodi/advancedsettings.xml new file mode 100644 index 00000000000..46c4ea5d3eb --- /dev/null +++ b/projects/H3/kodi/advancedsettings.xml @@ -0,0 +1,23 @@ + + + + echo "$(cat /sys/devices/virtual/thermal/thermal_zone0/temp)C" + + false + + 720 + 540 + + + + + 30 + + + + 4.0 + + + diff --git a/projects/H3/linux/linux.arm.conf b/projects/H3/linux/linux.arm.conf new file mode 100644 index 00000000000..2a4204c9032 --- /dev/null +++ b/projects/H3/linux/linux.arm.conf @@ -0,0 +1,3555 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 3.4.113 Kernel Configuration +# +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_KTIME_SCALAR=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_LOCKBREAK=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPUFREQ=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_NEED_MACH_IO_H=y +CONFIG_NEED_MACH_MEMORY_H=y +CONFIG_GENERIC_BUG=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_HAVE_IRQ_WORK=y +CONFIG_IRQ_WORK=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_DEFAULT_HOSTNAME="@DISTRONAME@" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_FHANDLE=y +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y +CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y +CONFIG_CGROUP_MEM_RES_CTLR_KMEM=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_CFS_BANDWIDTH is not set +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_USER_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +# CONFIG_SCHED_AUTOGROUP is not set +CONFIG_MM_OWNER=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE=" " +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_PANIC_TIMEOUT=0 +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +# CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_JUMP_LABEL=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_THROTTLING is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +CONFIG_LDM_PARTITION=y +# CONFIG_LDM_DEBUG is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CFQ_GROUP_IOSCHED is not set +CONFIG_IOSCHED_BFQ=y +CONFIG_CGROUP_BFQIO=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_BFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="bfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +CONFIG_UNINLINE_SPIN_UNLOCK=y +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +CONFIG_ARCH_SUNXI=y +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_PRIMA2 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_PICOXCELL is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P64X0 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_VT8500 is not set +# CONFIG_ARCH_ZYNQ is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set + +# +# System MMU +# +CONFIG_SUNXI_CONSISTENT_DMA_SIZE=12 +CONFIG_ARCH_SUN8I=y +# CONFIG_ARCH_SUN9I is not set +# CONFIG_ARCH_SUN8IW1 is not set +# CONFIG_ARCH_SUN8IW3 is not set +# CONFIG_ARCH_SUN8IW5 is not set +# CONFIG_ARCH_SUN8IW6 is not set +CONFIG_ARCH_SUN8IW7=y +# CONFIG_ARCH_SUN8IW8 is not set +# CONFIG_ARCH_SUN8IW9 is not set +CONFIG_ARCH_SUN8IW7P1=y +# CONFIG_FPGA_V4_PLATFORM is not set +# CONFIG_FPGA_V7_PLATFORM is not set +CONFIG_EVB_PLATFORM=y + +# +# Power management +# + +# +# Common Features Selection +# + +# +# Boot Options +# +# CONFIG_SUNXI_TRUSTZONE is not set +CONFIG_HOMLET_PLATFORM=y +# CONFIG_SUNXI_BOOTUP_EXTEND is not set +# CONFIG_SUNXI_OOPS_HOOK is not set +# CONFIG_MEM_512M_DEBUG is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +CONFIG_ARM_THUMBEE=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_NR_BANKS=8 +CONFIG_CPU_HAS_PMU=y +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_ARM_ERRATA_742230 is not set +# CONFIG_ARM_ERRATA_742231 is not set +# CONFIG_ARM_ERRATA_643719 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_743622 is not set +# CONFIG_ARM_ERRATA_751472 is not set +# CONFIG_ARM_ERRATA_754322 is not set +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_764369 is not set +# CONFIG_ARM_ERRATA_775420 is not set +CONFIG_ARM_GIC=y +# CONFIG_FIQ_DEBUGGER is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +# CONFIG_DISABLE_CPU_SCHED_DOMAIN_BALANCE is not set +CONFIG_HAVE_ARM_SCU=y +CONFIG_ARM_ARCH_TIMER=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_ARCH_NR_GPIO=2048 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_HZ=100 +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HW_PERF_EVENTS=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_CLEANCACHE is not set +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_SECCOMP is not set +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y + +# +# Boot options +# +# CONFIG_USE_OF is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="root=/dev/ram0 rdinit=/init initcall_debug=0 console=ttyS0,115200" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_CMDLINE_EXTEND is not set +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_AUTO_ZRELADDR is not set + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_FANTASYS is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_INTERACTIVE=y +# CONFIG_CPU_FREQ_GOV_AUTO_HOTPLUG is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_INPUT_EVNT_NOTIFY=y + +# +# ARM CPU frequency scaling drivers +# +CONFIG_ARM_SUNXI_CPUFREQ=y +# CONFIG_ARM_EXYNOS4210_CPUFREQ is not set +# CONFIG_ARM_EXYNOS4X12_CPUFREQ is not set +# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set + +# +# CPU Idle +# +# CONFIG_CPU_IDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_WAKELOCK is not set +CONFIG_SCENELOCK=y +CONFIG_USER_SCENELOCK=y +# CONFIG_HIBERNATION is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +# CONFIG_PM_TEST_SUSPEND is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_APM_EMULATION=y +CONFIG_PM_CLK=y +CONFIG_CPU_PM=y +CONFIG_SUSPEND_TIME=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=m +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_LRO=y +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_TUNNEL is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_SUBTREES is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_ANDROID_PARANOID_NETWORK is not set +# CONFIG_NET_ACTIVITY_STATS is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +# CONFIG_NETFILTER_NETLINK_ACCT is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +# CONFIG_NF_CONNTRACK_MARK is not set +# CONFIG_NF_CONNTRACK_PROCFS is not set +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_FTP=m +# CONFIG_NF_CONNTRACK_H323 is not set +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +# CONFIG_NF_CONNTRACK_SNMP is not set +# CONFIG_NF_CONNTRACK_PPTP is not set +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SIP=m +# CONFIG_NF_CONNTRACK_TFTP is not set +CONFIG_NF_CT_NETLINK=m +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +# CONFIG_NETFILTER_XT_MARK is not set +# CONFIG_NETFILTER_XT_CONNMARK is not set + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set +# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set +# CONFIG_NETFILTER_XT_MATCH_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ECN is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_HL is not set +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set +# CONFIG_NETFILTER_XT_MATCH_MAC is not set +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +CONFIG_NETFILTER_XT_MATCH_OWNER=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_QUOTA2 is not set +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set +# CONFIG_NETFILTER_XT_MATCH_TIME is not set +# CONFIG_NETFILTER_XT_MATCH_U32 is not set +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_RPFILTER is not set +# CONFIG_IP_NF_MATCH_TTL is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_REJECT_SKERR is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_REDIRECT is not set +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +# CONFIG_NF_NAT_TFTP is not set +# CONFIG_NF_NAT_AMANDA is not set +# CONFIG_NF_NAT_PPTP is not set +# CONFIG_NF_NAT_H323 is not set +CONFIG_NF_NAT_SIP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_CONNTRACK_IPV6=m +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=y +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RPFILTER is not set +# CONFIG_IP6_NF_MATCH_RT is not set +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +# CONFIG_IP6_NF_TARGET_REJECT_SKERR is not set +# CONFIG_IP6_NF_MANGLE is not set +# CONFIG_IP6_NF_RAW is not set +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +CONFIG_STP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_NET_DSA=y +# CONFIG_NET_DSA_TAG_DSA is not set +# CONFIG_NET_DSA_TAG_EDSA is not set +# CONFIG_NET_DSA_TAG_TRAILER is not set +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=m +CONFIG_LLC2=m +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_PHONET is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +# CONFIG_OPENVSWITCH is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_NETPRIO_CGROUP is not set +CONFIG_BQL=y +CONFIG_HAVE_BPF_JIT=y +CONFIG_BPF_JIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +# CONFIG_BT_BNEP is not set +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_RTKH5=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +# CONFIG_BT_HCIVHCI is not set +CONFIG_BT_LPM=m +CONFIG_RTL_BT_LPM=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +# CONFIG_BT_WILINK is not set +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +CONFIG_CFG80211_INTERNAL_REGDB=y +CONFIG_CFG80211_WEXT=y +# CONFIG_WIRELESS_EXT_SYSFS is not set +# CONFIG_LIB80211 is not set +# CONFIG_CFG80211_ALLOW_RECONNECT is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_RC_PID is not set +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set +# CONFIG_NFC is not set + +# +# Device Drivers +# +CONFIG_SUNXI_ARISC=y + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_FW_LOADER_USER_HELPER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_SPI=y +CONFIG_DMA_SHARED_BUFFER=y +CONFIG_CMA=y +# CONFIG_CMA_DEBUG is not set + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=16 +CONFIG_CMA_RESERVE_BASE=0x43400000 +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_ALIGNMENT=0 +CONFIG_CMA_AREAS=7 +CONFIG_SYNC=y +CONFIG_SW_SYNC=y +# CONFIG_SW_SYNC_USER is not set + +# +# Bus devices +# +CONFIG_SUNXI_MBUS=y +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_CRYPTOLOOP=y + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set + +# +# Misc devices +# +# CONFIG_SUNXI_VIBRATOR is not set +# CONFIG_SUN8I_VIBRATOR is not set +# CONFIG_SENSORS_LIS3LV02D is not set +# CONFIG_AD525X_DPOT is not set +# CONFIG_ATMEL_PWM is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +# CONFIG_UID_STAT is not set +# CONFIG_BMP085 is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_WL127X_RFKILL is not set +# CONFIG_SUNXI_BROM_READ is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +CONFIG_EEPROM_93CX6=m +# CONFIG_EEPROM_93XX46 is not set +# CONFIG_IWMC3200TOP is not set + +# +# Texas Instruments shared transport line discipline +# +CONFIG_TI_ST=m +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set +# CONFIG_SW_3G_MODULE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +# CONFIG_BONDING is not set +# CONFIG_DUMMY is not set +# CONFIG_EQUALIZER is not set +CONFIG_MII=y +# CONFIG_NET_TEAM is not set +CONFIG_MACVLAN=m +# CONFIG_MACVTAP is not set +CONFIG_NETCONSOLE=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_TUN=y +# CONFIG_VETH is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +# CONFIG_NET_DSA_MV88E6XXX is not set +# CONFIG_NET_DSA_MV88E6060 is not set +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set +# CONFIG_NET_DSA_MV88E6131 is not set +# CONFIG_NET_DSA_MV88E6123_61_65 is not set +CONFIG_ETHERNET=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_CALXEDA_XGMAC is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_ETHOC is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +CONFIG_NET_VENDOR_SUNXI=y +CONFIG_SUNXI_GETH=y +CONFIG_GETH_SCRIPT_SYS=y +CONFIG_GETH_CLK_SYS=y +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_AMD_PHY is not set +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_NATIONAL_PHY is not set +# CONFIG_STE10XP is not set +# CONFIG_LSI_ET1011C_PHY is not set +# CONFIG_MICREL_PHY is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MICREL_KS8995MA is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_MPPE=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPPOE=m +# CONFIG_PPPOLAC is not set +# CONFIG_PPPOPNS is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_SLIP is not set +CONFIG_SLHC=m + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_QF9700=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_CDC_EEM is not set +# CONFIG_USB_NET_CDC_NCM is not set +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +# CONFIG_USB_NET_GL620A is not set +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_PLUSB is not set +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_USB_NET_CX82310_ETH is not set +# CONFIG_USB_NET_KALMIA is not set +# CONFIG_USB_NET_QMI_WWAN is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_NET_INT51X1 is not set +CONFIG_USB_IPHETH=m +# CONFIG_USB_SIERRA_NET is not set +# CONFIG_USB_VL600 is not set +CONFIG_WLAN=y +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set +CONFIG_LIBERTAS_THINFIRM_USB=m +# CONFIG_AT76C50X_USB is not set +CONFIG_USB_ZD1201=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +# CONFIG_MAC80211_HWSIM is not set +# CONFIG_WIFI_CONTROL_FUNC is not set +# CONFIG_WAKE_ON_WLAN is not set +CONFIG_ATH_COMMON=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +CONFIG_ATH9K_AHB=y +# CONFIG_ATH9K_DEBUGFS is not set +# CONFIG_ATH9K_DFS_CERTIFIED is not set +# CONFIG_ATH9K_LEGACY_RATE_CONTROL is not set +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +CONFIG_CARL9170_WPC=y +CONFIG_ATH6KL=m +# CONFIG_ATH6KL_SDIO is not set +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BCMDHD=m +CONFIG_BCMDHD_FW_PATH="/lib/firmware/brcm/fw_bcmdhd.bin" +CONFIG_BCMDHD_NVRAM_PATH="/lib/firmware/brcm/nvram_ap6212.txt" +CONFIG_BCMDHD_DISABLE_WOWLAN=y +CONFIG_BCMDHD_SDIO=y +CONFIG_BCMDHD_OOB=y +# CONFIG_BCMDHD_SDIO_IRQ is not set +CONFIG_BRCMUTIL=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +# CONFIG_BRCMDBG is not set +# CONFIG_HOSTAP is not set +# CONFIG_IWM is not set +# CONFIG_LIBERTAS is not set +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +# CONFIG_P54_SPI is not set +CONFIG_P54_LEDS=y +CONFIG_RT2X00=m +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +# CONFIG_RT2X00_DEBUG is not set +# CONFIG_RTL8192CU is not set +# CONFIG_WL1251 is not set +# CONFIG_WL12XX_MENU is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_MWIFIEX is not set +CONFIG_RTL8188EU=m +CONFIG_RTL8189ES=m +CONFIG_RTL8189FS=m +# CONFIG_RTL8723BS is not set +# CONFIG_RTL8723BS_VQ0 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=y +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_APMPOWER is not set +# CONFIG_INPUT_KEYRESET is not set +CONFIG_INPUT_SW_DEVICE=m + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_SAMSUNG is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_OMAP4 is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_SUNXI is not set +# CONFIG_IR_RX_SUNXI is not set +# CONFIG_IR_TX_SUNXI is not set +CONFIG_SUNXI_GPIO_KEY=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +# CONFIG_JOYSTICK_ANALOG is not set +# CONFIG_JOYSTICK_A3D is not set +# CONFIG_JOYSTICK_ADI is not set +# CONFIG_JOYSTICK_COBRA is not set +# CONFIG_JOYSTICK_GF2K is not set +# CONFIG_JOYSTICK_GRIP is not set +# CONFIG_JOYSTICK_GRIP_MP is not set +# CONFIG_JOYSTICK_GUILLEMOT is not set +# CONFIG_JOYSTICK_INTERACT is not set +# CONFIG_JOYSTICK_SIDEWINDER is not set +# CONFIG_JOYSTICK_TMDC is not set +# CONFIG_JOYSTICK_IFORCE is not set +# CONFIG_JOYSTICK_WARRIOR is not set +# CONFIG_JOYSTICK_MAGELLAN is not set +# CONFIG_JOYSTICK_SPACEORB is not set +# CONFIG_JOYSTICK_SPACEBALL is not set +# CONFIG_JOYSTICK_STINGER is not set +# CONFIG_JOYSTICK_TWIDJOY is not set +# CONFIG_JOYSTICK_ZHENHUA is not set +# CONFIG_JOYSTICK_AS5011 is not set +# CONFIG_JOYSTICK_JOYDUMP is not set +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_EGALAX is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_ILI210X is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +# CONFIG_TOUCHSCREEN_USB_PANJIT is not set +CONFIG_TOUCHSCREEN_USB_3M=y +# CONFIG_TOUCHSCREEN_USB_ITM is not set +# CONFIG_TOUCHSCREEN_USB_ETURBO is not set +# CONFIG_TOUCHSCREEN_USB_GUNZE is not set +# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set +# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set +# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set +# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set +# CONFIG_TOUCHSCREEN_USB_GOTOP is not set +# CONFIG_TOUCHSCREEN_USB_JASTEC is not set +# CONFIG_TOUCHSCREEN_USB_ELO is not set +# CONFIG_TOUCHSCREEN_USB_E2I is not set +# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set +# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set +# CONFIG_TOUCHSCREEN_USB_NEXIO is not set +# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_GT82X is not set +# CONFIG_TOUCHSCREEN_SUN6I_TS is not set +# CONFIG_TOUCHSCREEN_FT5X_TS is not set +# CONFIG_TOUCHSCREEN_GT9XX_TS is not set +# CONFIG_TOUCHSCREEN_GT9XXF_TS is not set +# CONFIG_TOUCHSCREEN_GSLX680 is not set +# CONFIG_TOUCHSCREEN_GSLX680NEW is not set +# CONFIG_TOUCHSCREEN_AW5X06_TS is not set +# CONFIG_TOUCHSCREEN_GT818_TS is not set +# CONFIG_TOUCHSCREEN_TU_TS is not set +# CONFIG_TOUCHSCREEN_ICN83XX_TS is not set +CONFIG_INPUT_MISC=y +# CONFIG_E_COMPASS_L3M303D is not set +# CONFIG_E_COMPASS_FXOS8700 is not set +# CONFIG_E_COMPASS_AKM8963 is not set +# CONFIG_GYR_L3GD20 is not set +# CONFIG_GYR_BMG160 is not set +# CONFIG_INPUT_LTR501ALS is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +# CONFIG_INPUT_MMA8450 is not set +# CONFIG_INPUT_MPU3050 is not set +# CONFIG_INPUT_GP2A is not set +# CONFIG_INPUT_GPIO_TILT_POLLED is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_KEYCHORD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_KXTJ9 is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=y +# CONFIG_INPUT_GPIO is not set +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_SHAFT_ENCODER is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_CONSOLE_POLL=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +CONFIG_SERIAL_SUNXI=y +CONFIG_SERIAL_SUNXI_CONSOLE=y +# CONFIG_SERIAL_DEBUG is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_DCC_TTY is not set +# CONFIG_RAMOOPS is not set +# CONFIG_SUNXI_D7S is not set +# CONFIG_IR_CUT is not set +# CONFIG_SUNXI_CMATESET is not set +# CONFIG_SUNXI_ARISC_TEST is not set +# CONFIG_SUNXI_MODULE is not set +# CONFIG_SUNXI_TIMER_TEST is not set +# CONFIG_SUNXI_DMA_TEST is not set +# CONFIG_SUNXI_SCR is not set +CONFIG_SUNXI_DI=y +CONFIG_SUNXI_SOC_INFO=y +# CONFIG_ID is not set +# CONFIG_RESET_KEY is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_COMPAT is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=m + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_MUX_GPIO is not set +# CONFIG_I2C_MUX_PCA9541 is not set +# CONFIG_I2C_MUX_PCA954x is not set +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_SIMTEC is not set +CONFIG_I2C_SUNXI=y +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_GPIO is not set +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +CONFIG_SPI_SUNXI=y +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +CONFIG_SPI_SPIDEV=y +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_HSI is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +# CONFIG_DEBUG_PINCTRL is not set +CONFIG_PINCTRL_SUNXI=y +# CONFIG_PINCTRL_SUNXI_DEBUG is not set +# CONFIG_SUNXI_PINCTRL_TEST is not set +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_GENERIC_PLATFORM is not set + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_GPIO_SUNXI is not set +CONFIG_W1=m +CONFIG_W1_SUNXI=m + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS1WM is not set +CONFIG_W1_MASTER_GPIO=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2433_CRC=y +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_APM_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_BATTERY_ANDROID is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_CHARGER_SMB347 is not set +CONFIG_HWMON=y +CONFIG_HWMON_VID=m +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +CONFIG_SENSORS_KIONIX=m +CONFIG_SENSORS_MMA7660=m +CONFIG_SENSORS_MMA865x=m +CONFIG_SENSORS_MMA8452=m +CONFIG_SENSORS_AFA750=m +CONFIG_SENSORS_BMA250=m +CONFIG_SENSORS_LIS3DH_ACC=m +CONFIG_SENSORS_LIS3DE_ACC=m +CONFIG_SENSORS_AD7314=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADCXX=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7411=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_ASC7621=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS620=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_GPIO_FAN=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_JC42=m +CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM73=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LTC4151=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LTC4261=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_LM95245=m +CONFIG_SENSORS_MAX1111=m +CONFIG_SENSORS_MAX16065=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX1668=m +CONFIG_SENSORS_MAX6639=m +CONFIG_SENSORS_MAX6642=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MCP3021=m +CONFIG_SENSORS_NTC_THERMISTOR=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCF8591=m +CONFIG_PMBUS=m +CONFIG_SENSORS_PMBUS=m +CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_LM25066=m +CONFIG_SENSORS_LTC2978=m +CONFIG_SENSORS_MAX16064=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_ZL6100=m +# CONFIG_DA380 is not set +CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SMM665=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_EMC1403=m +CONFIG_SENSORS_EMC2103=m +CONFIG_SENSORS_EMC6W201=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SCH56XX_COMMON=m +CONFIG_SENSORS_SCH5627=m +CONFIG_SENSORS_SCH5636=m +CONFIG_SENSORS_ADS1015=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_ADS7871=m +CONFIG_SENSORS_AMC6821=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP102=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +# CONFIG_SENSORS_W83795 is not set +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m + +# +# INA219 drivers +# +# CONFIG_SENSORS_INA219 is not set +# CONFIG_SENSORS_DUMMY_ACC is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +# CONFIG_FAIR_SHARE is not set +CONFIG_STEP_WISE=y +# CONFIG_USER_SPACE is not set +# CONFIG_SUNXI_THERMAL_DYNAMIC is not set +# CONFIG_CPU_THERMAL is not set +CONFIG_CPU_BUDGET_THERMAL=y +CONFIG_SUNXI_THERMAL=y +CONFIG_SUNXI_BUDGET_COOLING=y +# CONFIG_SUNXI_BUDGET_COOLING_VFTBL is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_CORE is not set +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +CONFIG_SUNXI_WDT=y + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=m +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_ACX00 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +CONFIG_MFD_WL1273_CORE=m +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_REGULATOR is not set +# CONFIG_PWM is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_DVB_CORE=m +CONFIG_DVB_NET=y +CONFIG_VIDEO_MEDIA=m + +# +# Multimedia drivers +# +CONFIG_RC_CORE=y +CONFIG_LIRC=y +CONFIG_RC_MAP=y +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_RC5_SZ_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_LIRC_CODEC=y +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_IMON=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_REDRAT3=m +CONFIG_IR_STREAMZAP=m +CONFIG_RC_LOOPBACK=m +CONFIG_IR_GPIO_CIR=m +CONFIG_IR_SUNXI=y +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER_CUSTOMISE=y + +# +# Customize TV tuners +# +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR_I2C=y + +# +# Audio decoders, processors and mixers +# +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m + +# +# RDS decoders +# + +# +# Video decoders +# +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_CX25840=m + +# +# MPEG video encoders +# +CONFIG_VIDEO_CX2341X=m + +# +# Video encoders +# + +# +# Camera sensor devices +# +CONFIG_VIDEO_MT9V011=m + +# +# Flash devices +# + +# +# Video improvement chips +# + +# +# Miscelaneous helper chips +# +# CONFIG_VIDEO_VIVI is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_EM28XX_RC=y +CONFIG_VIDEO_TLG2300=m +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_RC=y +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_TM6000=m +CONFIG_VIDEO_TM6000_ALSA=m +CONFIG_VIDEO_TM6000_DVB=m +CONFIG_VIDEO_USBVISION=m +CONFIG_USB_ET61X251=m +CONFIG_USB_SN9C102=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_VIDEO_CPIA2=m +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_V4L_PLATFORM_DRIVERS=y +# CONFIG_VIDEO_TIMBERDALE is not set +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_IMX074=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9T031=m +CONFIG_SOC_CAMERA_MT9T112=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_RJ54N1=m +CONFIG_SOC_CAMERA_TW9910=m +# CONFIG_SOC_CAMERA_PLATFORM is not set +CONFIG_SOC_CAMERA_OV2640=m +CONFIG_SOC_CAMERA_OV5642=m +CONFIG_SOC_CAMERA_OV6650=m +CONFIG_SOC_CAMERA_OV772X=m +CONFIG_SOC_CAMERA_OV9640=m +CONFIG_SOC_CAMERA_OV9740=m +# CONFIG_VIDEO_SH_MOBILE_CSI2 is not set +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +CONFIG_VIDEO_SUNXI_VFE=m +CONFIG_CSI_VFE=m +# CONFIG_V4L_MEM2MEM_DRIVERS is not set +# CONFIG_AW_TSC is not set +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_SI470X=y +CONFIG_USB_SI470X=m +CONFIG_I2C_SI470X=m +CONFIG_USB_MR800=m +CONFIG_USB_DSBR=m +CONFIG_I2C_SI4713=m +CONFIG_RADIO_SI4713=m +CONFIG_USB_KEENE=m +CONFIG_RADIO_TEA5764=m +CONFIG_RADIO_SAA7706H=m +CONFIG_RADIO_TEF6862=m +CONFIG_RADIO_WL1273=m + +# +# Texas Instruments WL128x FM driver (ST based) +# +CONFIG_RADIO_WL128X=m +CONFIG_DVB_MAX_ADAPTERS=8 +# CONFIG_DVB_DYNAMIC_MINORS is not set +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_TTPCI_EEPROM=m + +# +# Supported USB Adapters +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_FRIIO=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_IT913X=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_USB_RTL2832U=m +CONFIG_SMS_SIANO_MDTV=m + +# +# Siano module components +# +CONFIG_SMS_USB_DRV=m +# CONFIG_SMS_SDIO_DRV is not set + +# +# Supported FlexCopII (B2C2) Adapters +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_B2C2_FLEXCOP_DEBUG=y + +# +# Supported DVB Frontends +# +CONFIG_DVB_FE_CUSTOMISE=y + +# +# Customise DVB Frontends +# + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV6110x=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_TDA18271C2DD=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_M88DS3103=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_MB86A16=m +CONFIG_DVB_TDA10071=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_S5H1432=m +CONFIG_DVB_DRXD=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_DIB9000=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +CONFIG_DVB_HD29L2=m +CONFIG_DVB_STV0367=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_RTL2830=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_S5H1411=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_S921=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_MB86A20S=m + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_A8293=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_TDA665x=m +CONFIG_DVB_IX2505V=m +CONFIG_DVB_IT913X_FE=m +CONFIG_DVB_M88RS2000=m + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set +CONFIG_VIDEO_ENCODER_DECODER_SUNXI=y + +# +# Graphics support +# +# CONFIG_DRM is not set +CONFIG_ION=y +CONFIG_ION_SUNXI=y +CONFIG_ION_SUNXI_RESERVE_LIST="160M@0,256M@0,130M@1,200M@1" +CONFIG_MALI=m +CONFIG_MALI400=m +# CONFIG_MALI450 is not set +# CONFIG_MALI400_DEBUG is not set +# CONFIG_MALI400_PROFILING is not set +CONFIG_MALI400_UMP=y +# CONFIG_MALI400_POWER_PERFORMANCE_POLICY is not set +CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH=y +# CONFIG_MALI_SHARED_INTERRUPTS is not set +# CONFIG_MALI_PMU_PARALLEL_POWER_UP is not set +# CONFIG_MALI_QUIET is not set +CONFIG_UMP=m +# CONFIG_UMP_DEBUG is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_WMT_GE_ROPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# + +# +# Video support for sunxi +# +CONFIG_FB_CONSOLE_SUNXI=y +CONFIG_DISP2_SUNXI=y +CONFIG_HDMI_DISP2_SUNXI=y +CONFIG_TV_DISP2_SUNXI=y +# CONFIG_HDMI_EP952 is not set +# CONFIG_DISP2_SUNXI_BOOT_COLORBAR is not set +CONFIG_DISP2_SUNXI_DEBUG=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_TMIO is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_EXYNOS_VIDEO is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +CONFIG_SND_HRTIMER=y +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_SOC=y +CONFIG_SND_SOC_DMAENGINE_PCM=y +CONFIG_SND_SUNXI_SOC_AUDIOCODEC=y +CONFIG_SND_SUNXI_SOC_PUBLUC_MACHINE=y +CONFIG_SND_SUN8IW7_SNDCODEC=y +CONFIG_SND_SUNXI_SOC_DAUDIO0_INTERFACE=m +CONFIG_SND_SUNXI_SOC_DAUDIO0_PUBLIC_MACHINE=m +CONFIG_SND_SUNXI_SOC_DAUDIO1_INTERFACE=m +CONFIG_SND_SUNXI_SOC_DAUDIO1_PUBLIC_MACHINE=m +CONFIG_SND_SUNXI_SOC_HDMIAUDIO=y +CONFIG_SND_SUN8IW7_HDMIPCM=y +CONFIG_SND_SUNXI_SOC_SPDIF=y +CONFIG_SND_SUNXI_SOC_AUDIOHUB_INTERFACE=y +CONFIG_SND_SUN8IW7_AUDIOHUB=y +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_RT3261 is not set +# CONFIG_SND_RT_EFFECT is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_BATTERY_STRENGTH is not set +CONFIG_HIDRAW=y +CONFIG_UHID=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_REMOTE_WAKEUP is not set +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +# CONFIG_HID_ACRUX is not set +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +# CONFIG_HID_PRODIKEYS is not set +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELECOM is not set +CONFIG_HID_EZKEY=y +# CONFIG_HID_HOLTEK is not set +# CONFIG_HID_KEYTOUCH is not set +CONFIG_HID_KYE=y +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +CONFIG_HID_GYRATION=y +CONFIG_HID_TWINHAN=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LCPOWER=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_LOGITECH_DJ=y +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_LOGIWHEELS_FF=y +# CONFIG_HID_MAGICMOUSE is not set +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NTRIG is not set +CONFIG_HID_ORTEK=y +CONFIG_HID_OUYA=m +CONFIG_HID_PANTHERLORD=y +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PETALYNX=y +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_PRIMAX is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_SAITEK is not set +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y +CONFIG_HID_SPEEDLINK=y +CONFIG_HID_SPINELPLUS=m +CONFIG_HID_SUNPLUS=y +# CONFIG_HID_GREENASIA is not set +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TIVO=y +CONFIG_HID_TOPSEED=y +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +CONFIG_HID_WIIMOTE=m +CONFIG_HID_WIIMOTE_EXT=y +# CONFIG_HID_ZEROPLUS is not set +CONFIG_HID_ZYDACRON=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_SUNXI is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_PLATFORM is not set +CONFIG_USB_EHCI_HCD_PLATFORM=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_SUNXI_HCD=y +CONFIG_USB_SUNXI_HCD0=y +CONFIG_USB_SUNXI_HCI=y +CONFIG_USB_SUNXI_EHCI0=y +CONFIG_USB_SUNXI_EHCI1=y +CONFIG_USB_SUNXI_OHCI0=y +CONFIG_USB_SUNXI_OHCI1=y +CONFIG_USB_SUNXI_EHCI2=y +CONFIG_USB_SUNXI_OHCI2=y +CONFIG_USB_SUNXI_EHCI3=y +CONFIG_USB_SUNXI_OHCI3=y +CONFIG_USB_SUNXI_HSIC=y +# CONFIG_SW_USB_3G is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_RENESAS_USBHS is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_REALTEK=y +CONFIG_REALTEK_AUTOPM=y +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_ONETOUCH=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_STORAGE_ENE_UB6250=y +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_EZUSB is not set +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +CONFIG_USB_SERIAL_CH341=m +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +CONFIG_USB_SERIAL_CP210X=m +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=m +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_F81232 is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +CONFIG_USB_SERIAL_IUU=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_METRO is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_MOTOROLA is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_OTI6858 is not set +# CONFIG_USB_SERIAL_QCAUX is not set +# CONFIG_USB_SERIAL_QUALCOMM is not set +# CONFIG_USB_SERIAL_SPCP8X5 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIEMENS_MPI is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_SYMBOL is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_OPTICON is not set +# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set +# CONFIG_USB_SERIAL_ZIO is not set +# CONFIG_USB_SERIAL_SSU100 is not set +# CONFIG_USB_SERIAL_DEBUG is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 +# CONFIG_USB_FUSB300 is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_NET2272 is not set +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_SUNXI_UDC0=y +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_USB_SUNXI_USB=y +CONFIG_USB_SUNXI_USB_MANAGER=y +# CONFIG_USB_SUNXI_USB0_NULL is not set +# CONFIG_USB_SUNXI_USB0_DEVICE_ONLY is not set +# CONFIG_USB_SUNXI_USB0_HOST_ONLY is not set +CONFIG_USB_SUNXI_USB0_OTG=y +CONFIG_USB_SUNXI_USB_DEBUG=y +CONFIG_USB_SUNXI_HOST=y +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y +# CONFIG_MMC_CLKGATE is not set +# CONFIG_MMC_EMBEDDED_SDIO is not set +CONFIG_MMC_PARANOID_SD_INIT=y + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set +# CONFIG_FATFS_FS_SUPPORT is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SDHCI_PXAV3 is not set +# CONFIG_MMC_SDHCI_PXAV2 is not set +# CONFIG_MMC_DW is not set +CONFIG_MMC_SUNXI=y +# CONFIG_MMC_DEBUG_SUNXI is not set +CONFIG_MMC_PRE_DBGLVL_SUNXI=0 +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_SUNXI_LEDS=y +# CONFIG_SUNXI_LEDS_COM is not set +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_PCA9633 is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_RENESAS_TPU is not set +# CONFIG_LEDS_TCA6507 is not set +# CONFIG_LEDS_OT200 is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_SWITCH is not set +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SUNXI=y +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +# CONFIG_DW_DMAC is not set +CONFIG_TIMB_DMA=m +CONFIG_DMA_ENGINE=y +CONFIG_DMA_VIRTUAL_CHANNELS=y + +# +# DMA Clients +# +# CONFIG_ASYNC_TX_DMA is not set +CONFIG_SUNXI_DMA=y +# CONFIG_DMATEST is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_BALLOON is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_STAGING=y +# CONFIG_USBIP_CORE is not set +CONFIG_W35UND=m +# CONFIG_PRISM2_USB is not set +# CONFIG_ECHO is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_RTLLIB is not set +CONFIG_R8712U=m +CONFIG_RTS5139=m +# CONFIG_RTS5139_DEBUG is not set +# CONFIG_TRANZPORT is not set +# CONFIG_LINE6_USB is not set +# CONFIG_USB_SERIAL_QUATECH2 is not set +# CONFIG_USB_SERIAL_QUATECH_USB2 is not set +CONFIG_VT6656=m +# CONFIG_IIO is not set +# CONFIG_ZSMALLOC is not set +# CONFIG_FB_SM7XX is not set +# CONFIG_USB_ENESTORAGE is not set +# CONFIG_BCM_WIMAX is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +CONFIG_STAGING_MEDIA=y +CONFIG_DVB_AS102=m +CONFIG_EASYCAP=m +# CONFIG_EASYCAP_DEBUG is not set +CONFIG_LIRC_STAGING=y +CONFIG_LIRC_IGORPLUGUSB=m +# CONFIG_LIRC_IMON is not set +# CONFIG_LIRC_SASEM is not set +# CONFIG_LIRC_SERIAL is not set +# CONFIG_LIRC_SIR is not set +# CONFIG_LIRC_TTUSBIR is not set +CONFIG_LIRC_XBOX=m +# CONFIG_LIRC_ZILOG is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_PHONE is not set +# CONFIG_USB_WPAN_HCD is not set +# CONFIG_SUNXIOOPS is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +# CONFIG_COMMON_CLK_DISABLE_UNUSED is not set +CONFIG_COMMON_CLK_ENABLE_SYNCBOOT=y +CONFIG_COMMON_CLK_ENABLE_SYNCBOOT_EARLY=y +CONFIG_COMMON_CLK_DEBUG=y + +# +# SUNXI Clock Configuration +# +CONFIG_SUNXI_CLK_DEFAULT_INIT=y +CONFIG_SUNXI_CLK_AHB_FROM_PLL6=y +CONFIG_PLL6AHB1_CLK_DFT_VALUE=200000000 +CONFIG_AHB1_CLK_DFT_VALUE=200000000 +CONFIG_APB1_CLK_DFT_VALUE=100000000 + +# +# Hardware Spinlock drivers +# +CONFIG_CLKSRC_MMIO=y +CONFIG_SUNXI_TIMER=y +# CONFIG_IOMMU_SUPPORT is not set + +# +# Remoteproc drivers (EXPERIMENTAL) +# + +# +# Rpmsg drivers (EXPERIMENTAL) +# +# CONFIG_VIRT_DRIVERS is not set +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +CONFIG_DEVFREQ_GOV_USERSPACE=y + +# +# DEVFREQ Drivers +# +CONFIG_DEVFREQ_DRAM_FREQ=y +# CONFIG_DRAM_FREQ_BSP_TEST is not set +# CONFIG_GATOR_PERF is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +CONFIG_BTRFS_FS=m +# CONFIG_BTRFS_FS_POSIX_ACL is not set +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +# CONFIG_QUOTA is not set +# CONFIG_QUOTA_NETLINK_INTERFACE is not set +CONFIG_QUOTACTL=y +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=y +CONFIG_CUSE=y +CONFIG_GENERIC_ACL=y + +# +# Caches +# +CONFIG_FSCACHE=y +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +# CONFIG_FSCACHE_OBJECT_LIST is not set +CONFIG_CACHEFILES=y +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=y +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_FAT_PRE_FALLOCATE is not set +# CONFIG_NTFS_FS is not set +# CONFIG_FATFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=y +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_XATTR is not set +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFS_FSCACHE is not set +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_DFS_UPCALL is not set +# CONFIG_CIFS_FSCACHE is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y +# CONFIG_FS_BLOCK_COMPAT is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=7 +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOCKUP_DETECTOR=y +# CONFIG_HARDLOCKUP_DETECTOR_NMI is not set +CONFIG_HARDLOCKUP_DETECTOR_OTHER_CPU=y +CONFIG_HARDLOCKUP_DETECTOR=y +# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_DETECT_HUNG_TASK is not set +# CONFIG_SCHED_DEBUG is not set +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_ATOMIC_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +CONFIG_BOOT_PRINTK_DELAY=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=20 +CONFIG_RCU_CPU_STALL_VERBOSE=y +CONFIG_RCU_CPU_STALL_INFO=y +# CONFIG_RCU_TRACE is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_LKDTM is not set +# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_EVENT_POWER_TRACING_DEPRECATED=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +CONFIG_SCHED_TRACER=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_FUNCTION_PROFILER=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_RING_BUFFER_BENCHMARK is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KGDB_KDB=y +CONFIG_KDB_KEYBOARD=y +# CONFIG_TEST_KSTRTOX is not set +CONFIG_STRICT_DEVMEM=y +CONFIG_ARM_UNWIND=y +CONFIG_OLD_MCOUNT=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_RODATA is not set +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_SUNXI_UART0=y +# CONFIG_DEBUG_SUNXI_UART1 is not set +# CONFIG_DEBUG_SUNXI_UART2 is not set +# CONFIG_DEBUG_LL_UART_NONE is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_SEMIHOSTING is not set +CONFIG_EARLY_PRINTK=y + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_ENCRYPTED_KEYS is not set +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_TRUSTED_LITTLE_KERNEL is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_AUTHENC=y +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_GHASH is not set +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_USER_API=m +CONFIG_CRYPTO_USER_API_HASH=m +CONFIG_CRYPTO_USER_API_SKCIPHER=m +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_SUNXI=m +# CONFIG_ASYMMETRIC_KEY_TYPE is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +CONFIG_CRC_ITU_T=y +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +# CONFIG_CRC8 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_AVERAGE=y +# CONFIG_CORDIC is not set diff --git a/projects/H3/logo/splash-bpim2p.bmp b/projects/H3/logo/splash-bpim2p.bmp new file mode 100644 index 00000000000..5e1b295cbc9 Binary files /dev/null and b/projects/H3/logo/splash-bpim2p.bmp differ diff --git a/projects/H3/logo/splash.bmp b/projects/H3/logo/splash.bmp new file mode 100644 index 00000000000..9e45ccbc914 Binary files /dev/null and b/projects/H3/logo/splash.bmp differ diff --git a/projects/H3/options b/projects/H3/options new file mode 100644 index 00000000000..ca5aa3cebb2 --- /dev/null +++ b/projects/H3/options @@ -0,0 +1,144 @@ +################################################################################ +# setup system defaults +################################################################################ + + # The TARGET_CPU variable controls which processor should be targeted for + # generated code. + case $TARGET_ARCH in + arm) + # TARGET_CPU: + # arm2 arm250 arm3 arm6 arm60 arm600 arm610 arm620 arm7 arm7m arm7d + # arm7dm arm7di arm7dmi arm70 arm700 arm700i arm710 arm710c + # arm7100 arm720 arm7500 arm7500fe arm7tdmi arm7tdmi-s arm710t + # arm720t arm740t strongarm strongarm110 strongarm1100 + # strongarm1110 arm8 arm810 arm9 arm9e arm920 arm920t arm922t + # arm946e-s arm966e-s arm968e-s arm926ej-s arm940t arm9tdmi + # arm10tdmi arm1020t arm1026ej-s arm10e arm1020e arm1022e + # arm1136j-s arm1136jf-s mpcore mpcorenovfp arm1156t2-s + # arm1176jz-s arm1176jzf-s cortex-a8 cortex-a9 cortex-r4 + # cortex-r4f cortex-m3 cortex-m1 xscale iwmmxt iwmmxt2 ep9312. + TARGET_CPU="cortex-a7" + + # TARGET_FLOAT: + # Specifies which floating-point ABI to use. Permissible values are: + # soft softfp hard + TARGET_FLOAT="hard" + + # TARGET_FPU: + # This specifies what floating point hardware (or hardware emulation) is + # available on the target. Permissible names are: + # fpa fpe2 fpe3 maverick vfp vfpv3 vfpv3-fp16 vfpv3-d16 vfpv3-d16-fp16 + # vfpv3xd vfpv3xd-fp16 neon neon-fp16 vfpv4 vfpv4-d16 fpv4-sp-d16 + # neon-vfpv4. + TARGET_FPU="neon-vfpv4" + ;; + esac + + # Bootloader to use (syslinux / u-boot / bcm2835-bootloader) + BOOTLOADER="u-boot" + + # u-boot version to use (default) + UBOOT_VERSION="sunxi" + + # Configuration for u-boot + UBOOT_CONFIG="orangepi_2_defconfig" + UBOOT_CONFIG="$UBOOT_CONFIG orangepi_pc_defconfig" + UBOOT_CONFIG="$UBOOT_CONFIG orangepi_plus_defconfig" + UBOOT_CONFIG="$UBOOT_CONFIG orangepi_one_defconfig" + UBOOT_CONFIG="$UBOOT_CONFIG orangepi_lite_defconfig" + UBOOT_CONFIG="$UBOOT_CONFIG Sinovoip_BPI_M2_plus_defconfig" + UBOOT_CONFIG="$UBOOT_CONFIG orangepi_plus2e_defconfig" + UBOOT_CONFIG="$UBOOT_CONFIG orangepi_pc_plus_defconfig" + UBOOT_CONFIG="$UBOOT_CONFIG beelink_x2_defconfig" + + # Target Configfile for u-boot + UBOOT_CONFIGFILE="boot.scr" + + # Kernel target for u-boot (default 'uImage' if BOOTLOADER=u-boot) (uImage / zImage) + KERNEL_TARGET="uImage" + + # Kernel extra targets to build + KERNEL_UBOOT_EXTRA_TARGET="" + + # Kernel to use. values can be: + # default: default mainline kernel + LINUX="sun8i" + +################################################################################ +# setup build defaults +################################################################################ + + # Build optimizations (size/normal) + OPTIMIZATIONS="size" + + # Project CFLAGS + PROJECT_CFLAGS="" + + # LTO (Link Time Optimization) support + LTO_SUPPORT="yes" + + # GOLD (Google Linker) support + GOLD_SUPPORT="yes" + + # SquashFS compression method (gzip / lzo / xz) + SQUASHFS_COMPRESSION="lzo" + + +################################################################################ +# setup project defaults +################################################################################ + + # build and install ALSA Audio support (yes / no) + ALSA_SUPPORT="yes" + + # OpenGL(X) implementation to use (no / mesa) + OPENGL="no" + + # OpenGL-ES implementation to use (no / bcm2835-driver / gpu-viv-bin-mx6q) + OPENGLES="sunxi-mali" + + # include uvesafb support (yes / no) + UVESAFB_SUPPORT="no" + + # Displayserver to use (x11 / no) + DISPLAYSERVER="no" + + # Windowmanager to use (ratpoison / fluxbox / none) + WINDOWMANAGER="none" + + # Xorg Graphic drivers to use (all / i915,i965,r200,r300,r600,nvidia) + # Space separated list is supported, + # e.g. GRAPHIC_DRIVERS="i915 i965 r300 r600 radeonsi nvidia" + GRAPHIC_DRIVERS="" + + # KODI Player implementation to use (default / bcm2835-driver / libfslvpuwrap) + KODIPLAYER_DRIVER="cedarx" + + # Modules to install in initramfs for early boot + INITRAMFS_MODULES="" + + # additional Firmware to use (dvb-firmware, misc-firmware, wlan-firmware) + # Space separated list is supported, + # e.g. FIRMWARE="dvb-firmware misc-firmware wlan-firmware" + FIRMWARE="misc-firmware wlan-firmware dvb-firmware" + + # build and install ATV IR remote support (yes / no) + ATVCLIENT_SUPPORT="no" + + # build and install IRServer IR/LCD support (yes / no) + IRSERVER_SUPPORT="no" + + # build with swap support (yes / no) + SWAP_SUPPORT="yes" + + # swap support enabled per default (yes / no) + SWAP_ENABLED_DEFAULT="no" + + # swapfile size if SWAP_SUPPORT=yes in MB + SWAPFILESIZE="128" + + # build with installer (yes / no) + INSTALLER_SUPPORT="no" + + # additional drivers + ADDITIONAL_DRIVERS+=" mt7601u" diff --git a/projects/H3/patches/OpenELEC-settings/OpenELEC-settings-00-change-update-url.patch b/projects/H3/patches/OpenELEC-settings/OpenELEC-settings-00-change-update-url.patch new file mode 100644 index 00000000000..6ac9cac53b3 --- /dev/null +++ b/projects/H3/patches/OpenELEC-settings/OpenELEC-settings-00-change-update-url.patch @@ -0,0 +1,14 @@ +diff -Nur a/src/defaults.py b/src/defaults.py +--- a/src/defaults.py 2016-02-28 14:45:01.000000000 +0100 ++++ b/src/defaults.py 2016-05-02 23:29:36.809471401 +0200 +@@ -82,8 +82,8 @@ + 'ENABLED': True, + 'KERNEL_CMD': '/proc/cmdline', + 'SET_CLOCK_CMD': '/sbin/hwclock --systohc --utc', +- 'UPDATE_REQUEST_URL': 'http://update.openelec.tv/updates.php', +- 'UPDATE_DOWNLOAD_URL': 'http://%s.openelec.tv/%s', ++ 'UPDATE_REQUEST_URL': 'http://down.nu/update.php', ++ 'UPDATE_DOWNLOAD_URL': 'http://down.nu/%s/%s', + 'LOCAL_UPDATE_DIR': '/storage/.update/', + 'GET_CPU_FLAG': "cat /proc/cpuinfo | grep -q 'flags.* lm ' && echo '1' || echo '0'", + 'XBMC_RESET_FILE': '%s/reset_xbmc' % CONFIG_CACHE, diff --git a/projects/H3/patches/RTL8192EU/RTL8192EU-00-build-fix.patch b/projects/H3/patches/RTL8192EU/RTL8192EU-00-build-fix.patch new file mode 100644 index 00000000000..4eb44809220 --- /dev/null +++ b/projects/H3/patches/RTL8192EU/RTL8192EU-00-build-fix.patch @@ -0,0 +1,25 @@ +diff -Nur a/include/ieee80211.h b/include/ieee80211.h +--- a/include/ieee80211.h 2015-11-12 05:41:45.000000000 +0100 ++++ b/include/ieee80211.h 2016-01-18 18:57:55.919989259 +0100 +@@ -1314,18 +1314,18 @@ + (((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \ + (((Addr[5]) & 0xff) == 0xff)) + #else +-extern __inline int is_multicast_mac_addr(const u8 *addr) ++static __inline int is_multicast_mac_addr(const u8 *addr) + { + return ((addr[0] != 0xff) && (0x01 & addr[0])); + } + +-extern __inline int is_broadcast_mac_addr(const u8 *addr) ++static __inline int is_broadcast_mac_addr(const u8 *addr) + { + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); + } + +-extern __inline int is_zero_mac_addr(const u8 *addr) ++static __inline int is_zero_mac_addr(const u8 *addr) + { + return ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && \ + (addr[3] == 0x00) && (addr[4] == 0x00) && (addr[5] == 0x00)); diff --git a/projects/H3/patches/RTL8812AU/RTL8812AU-00-build-fix.patch b/projects/H3/patches/RTL8812AU/RTL8812AU-00-build-fix.patch new file mode 100644 index 00000000000..706318b883d --- /dev/null +++ b/projects/H3/patches/RTL8812AU/RTL8812AU-00-build-fix.patch @@ -0,0 +1,12 @@ +diff -Nur a/include/ieee80211.h b/include/ieee80211.h +--- a/include/ieee80211.h 2016-04-19 18:42:01.000000000 +0200 ++++ b/include/ieee80211.h 2016-04-19 18:46:08.596497819 +0200 +@@ -1399,7 +1399,7 @@ + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); + } + +-extern __inline int is_zero_mac_addr(const u8 *addr) ++static __inline int is_zero_mac_addr(const u8 *addr) + { + return ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && \ + (addr[3] == 0x00) && (addr[4] == 0x00) && (addr[5] == 0x00)); diff --git a/projects/H3/patches/kodi/kodi-000-windowing-support.patch b/projects/H3/patches/kodi/kodi-000-windowing-support.patch new file mode 100644 index 00000000000..dcd34197b56 --- /dev/null +++ b/projects/H3/patches/kodi/kodi-000-windowing-support.patch @@ -0,0 +1,688 @@ +diff -Nur a/xbmc/windowing/egl/EGLNativeTypeSunxi.cpp win/xbmc/windowing/egl/EGLNativeTypeSunxi.cpp +--- a/xbmc/windowing/egl/EGLNativeTypeSunxi.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ win/xbmc/windowing/egl/EGLNativeTypeSunxi.cpp 2016-05-24 21:10:08.186817913 +0200 +@@ -0,0 +1,589 @@ ++/* ++ * Copyright (C) 2011-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "EGLNativeTypeSunxi.h" ++#include "guilib/gui3d.h" ++#include "utils/StringUtils.h" ++#include "utils/SysfsUtils.h" ++#include "utils/log.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define DISP_GET_OUTPUT_TYPE 0x09 ++#define DISP_VSYNC_EVENT_EN 0x0B ++#define DISP_BLANK 0x0C ++#define DISP_DEVICE_SWITCH 0x0F ++#define DISP_GET_OUTPUT 0x10 ++#define DISP_HDMI_SUPPORT_MODE 0xC4 ++ ++typedef enum ++{ ++ DISP_TV_MOD_480I = 0, ++ DISP_TV_MOD_576I = 1, ++ DISP_TV_MOD_480P = 2, ++ DISP_TV_MOD_576P = 3, ++ DISP_TV_MOD_720P_50HZ = 4, ++ DISP_TV_MOD_720P_60HZ = 5, ++ DISP_TV_MOD_1080I_50HZ = 6, ++ DISP_TV_MOD_1080I_60HZ = 7, ++ DISP_TV_MOD_1080P_24HZ = 8, ++ DISP_TV_MOD_1080P_50HZ = 9, ++ DISP_TV_MOD_1080P_60HZ = 0xa, ++ DISP_TV_MOD_PAL = 0xb, ++ DISP_TV_MOD_PAL_SVIDEO = 0xc, ++ DISP_TV_MOD_NTSC = 0xe, ++ DISP_TV_MOD_NTSC_SVIDEO = 0xf, ++ DISP_TV_MOD_PAL_M = 0x11, ++ DISP_TV_MOD_PAL_M_SVIDEO = 0x12, ++ DISP_TV_MOD_PAL_NC = 0x14, ++ DISP_TV_MOD_PAL_NC_SVIDEO = 0x15, ++ DISP_TV_MOD_1080P_24HZ_3D_FP = 0x17, ++ DISP_TV_MOD_720P_50HZ_3D_FP = 0x18, ++ DISP_TV_MOD_720P_60HZ_3D_FP = 0x19, ++ DISP_TV_MOD_1080P_25HZ = 0x1a, ++ DISP_TV_MOD_1080P_30HZ = 0x1b, ++ DISP_TV_MOD_3840_2160P_30HZ = 0x1c, ++ DISP_TV_MOD_3840_2160P_25HZ = 0x1d, ++ DISP_TV_MOD_3840_2160P_24HZ = 0x1e, ++ DISP_TV_MODE_NUM = 0x1f, ++} disp_tv_mode; ++ ++typedef struct ++{ ++ unsigned int type; ++ unsigned int mode; ++} disp_output; ++ ++static const unsigned long supportedModes[] = ++{ ++ DISP_TV_MOD_480I, ++ DISP_TV_MOD_576I, ++ DISP_TV_MOD_480P, ++ DISP_TV_MOD_576P, ++ DISP_TV_MOD_720P_50HZ, ++ DISP_TV_MOD_720P_60HZ, ++ DISP_TV_MOD_1080I_50HZ, ++ DISP_TV_MOD_1080I_60HZ, ++ DISP_TV_MOD_1080P_24HZ, ++ DISP_TV_MOD_1080P_50HZ, ++ DISP_TV_MOD_1080P_60HZ, ++ DISP_TV_MOD_1080P_25HZ, ++ DISP_TV_MOD_1080P_30HZ, ++ DISP_TV_MOD_3840_2160P_24HZ, ++ DISP_TV_MOD_3840_2160P_25HZ, ++ DISP_TV_MOD_3840_2160P_30HZ ++}; ++ ++CEGLNativeTypeSunxi::CEGLNativeTypeSunxi() ++{ ++ m_nativeWindow = NULL; ++ m_disp = -1; ++ ++ // assume HDMI at first ++ m_screenid = 0; ++} ++ ++CEGLNativeTypeSunxi::~CEGLNativeTypeSunxi() ++{ ++} ++ ++bool CEGLNativeTypeSunxi::CheckCompatibility() ++{ ++ std::string name; ++ std::string modalias = "/sys/class/graphics/fb0/device/modalias"; ++ ++ SysfsUtils::GetString(modalias, name); ++ StringUtils::Trim(name); ++ if (name == "platform:disp") ++ return true; ++ return false; ++} ++ ++void CEGLNativeTypeSunxi::Initialize() ++{ ++ unsigned long args[4]; ++ disp_output para; ++ ++ if((m_disp = open("/dev/disp", O_RDWR)) == -1) ++ { ++ CLog::Log(LOGERROR, "%s - Can't open display. Nothing will work!\n", __FUNCTION__); ++ return; ++ } ++ ++ args[0] = 0; ++ args[1] = (unsigned long)(¶); ++ ioctl(m_disp, DISP_GET_OUTPUT, args); ++ ++ m_screenid = (para.type == 0) ? 1 : 0; ++ ++ CLog::Log(LOGNOTICE, "%s - Screen ID %d is selected\n", __FUNCTION__, m_screenid); ++ ++ args[0] = m_screenid; ++ args[1] = 1; ++ ++ ioctl(m_disp, DISP_VSYNC_EVENT_EN, args); ++} ++void CEGLNativeTypeSunxi::Destroy() ++{ ++ if(m_disp != -1) ++ { ++ close(m_disp); ++ m_disp = -1; ++ } ++} ++ ++bool CEGLNativeTypeSunxi::CreateNativeDisplay() ++{ ++ m_nativeDisplay = EGL_DEFAULT_DISPLAY; ++ return true; ++} ++ ++bool CEGLNativeTypeSunxi::CreateNativeWindow() ++{ ++ RESOLUTION_INFO res; ++ EGLNativeWindowType nativeWindow = new struct mali_native_window; ++ ++ if (!nativeWindow) ++ return false; ++ ++ if (m_disp == -1) ++ return false; ++ ++ if (!GetNativeResolution(&res)) ++ return false; ++ ++ nativeWindow->width = res.iScreenWidth; ++ nativeWindow->height = res.iScreenHeight; ++ m_nativeWindow = nativeWindow; ++ ++ return true; ++} ++ ++bool CEGLNativeTypeSunxi::GetNativeDisplay(XBNativeDisplayType **nativeDisplay) const ++{ ++ if (!nativeDisplay) ++ return false; ++ ++ *nativeDisplay = (XBNativeDisplayType*) &m_nativeDisplay; ++ return true; ++} ++ ++bool CEGLNativeTypeSunxi::GetNativeWindow(XBNativeWindowType **nativeWindow) const ++{ ++ if (!nativeWindow) ++ return false; ++ ++ *nativeWindow = (XBNativeWindowType*) &m_nativeWindow; ++ return true; ++} ++ ++bool CEGLNativeTypeSunxi::DestroyNativeDisplay() ++{ ++ return true; ++} ++ ++bool CEGLNativeTypeSunxi::DestroyNativeWindow() ++{ ++ delete (EGLNativeWindowType)m_nativeWindow, m_nativeWindow = NULL; ++ ++ return true; ++} ++ ++bool CEGLNativeTypeSunxi::GetNativeResolution(RESOLUTION_INFO *res) const ++{ ++ unsigned long args[4]; ++ disp_output para; ++ ++ args[0] = m_screenid; ++ args[1] = (unsigned long)(¶); ++ ioctl(m_disp, DISP_GET_OUTPUT, args); ++ ++ if(!ModeToResolution(para.mode, res)) ++ return false; ++ ++ return res->iWidth > 0 && res->iHeight> 0; ++} ++ ++bool CEGLNativeTypeSunxi::SetNativeResolution(const RESOLUTION_INFO &res) ++{ ++ if(m_screenid == 1) ++ return false; ++ ++ switch((int)(0.5 + res.fRefreshRate)) ++ { ++ case 60: ++ switch(res.iScreenHeight) ++ { ++ case 480: ++ if (res.dwFlags & D3DPRESENTFLAG_INTERLACED) ++ SetDisplayResolution(DISP_TV_MOD_480I); ++ else ++ SetDisplayResolution(DISP_TV_MOD_480P); ++ break; ++ default: ++ case 720: ++ SetDisplayResolution(DISP_TV_MOD_720P_60HZ); ++ break; ++ case 1080: ++ if (res.dwFlags & D3DPRESENTFLAG_INTERLACED) ++ SetDisplayResolution(DISP_TV_MOD_1080I_60HZ); ++ else ++ SetDisplayResolution(DISP_TV_MOD_1080P_60HZ); ++ break; ++ } ++ break; ++ default: ++ case 50: ++ switch(res.iScreenHeight) ++ { ++ case 576: ++ if (res.dwFlags & D3DPRESENTFLAG_INTERLACED) ++ SetDisplayResolution(DISP_TV_MOD_576I); ++ else ++ SetDisplayResolution(DISP_TV_MOD_576P); ++ break; ++ case 720: ++ SetDisplayResolution(DISP_TV_MOD_720P_50HZ); ++ break; ++ default: ++ case 1080: ++ if (res.dwFlags & D3DPRESENTFLAG_INTERLACED) ++ SetDisplayResolution(DISP_TV_MOD_1080I_50HZ); ++ else ++ SetDisplayResolution(DISP_TV_MOD_1080P_50HZ); ++ break; ++ } ++ break; ++ case 30: ++ switch(res.iScreenHeight) ++ { ++ default: ++ case 1080: ++ SetDisplayResolution(DISP_TV_MOD_1080P_30HZ); ++ break; ++ case 2160: ++ SetDisplayResolution(DISP_TV_MOD_3840_2160P_30HZ); ++ break; ++ } ++ break; ++ case 25: ++ switch(res.iScreenHeight) ++ { ++ default: ++ case 1080: ++ SetDisplayResolution(DISP_TV_MOD_1080P_25HZ); ++ break; ++ case 2160: ++ SetDisplayResolution(DISP_TV_MOD_3840_2160P_25HZ); ++ break; ++ } ++ break; ++ case 24: ++ switch(res.iScreenHeight) ++ { ++ default: ++ case 1080: ++ SetDisplayResolution(DISP_TV_MOD_1080P_24HZ); ++ break; ++ case 2160: ++ SetDisplayResolution(DISP_TV_MOD_3840_2160P_24HZ); ++ break; ++ } ++ break; ++ } ++ ++ if (m_nativeWindow) ++ { ++ ((EGLNativeWindowType)m_nativeWindow)->width = res.iScreenWidth; ++ ((EGLNativeWindowType)m_nativeWindow)->height = res.iScreenHeight; ++ } ++ ++ return true; ++} ++ ++bool CEGLNativeTypeSunxi::ProbeResolutions(std::vector &resolutions) ++{ ++ if(m_screenid == 0) ++ { ++ unsigned long args[4]; ++ ++ args[0] = m_screenid; ++ args[2] = 0; ++ args[3] = 0; ++ ++ for(unsigned int i = 0; i < sizeof(supportedModes) / sizeof(supportedModes[0]); i++) ++ { ++ args[1] = supportedModes[i]; ++ if(ioctl(m_disp, DISP_HDMI_SUPPORT_MODE, args)) ++ { ++ RESOLUTION_INFO res; ++ ++ ModeToResolution(supportedModes[i], &res); ++ resolutions.push_back(res); ++ } ++ } ++ } ++ else ++ { ++ RESOLUTION_INFO res; ++ ++ if(GetNativeResolution(&res)) ++ resolutions.push_back(res); ++ } ++ ++ return resolutions.size() > 0; ++} ++ ++bool CEGLNativeTypeSunxi::GetPreferredResolution(RESOLUTION_INFO *res) const ++{ ++ // check display/mode, it gets defaulted at boot ++ if (!GetNativeResolution(res)) ++ { ++ // set sane defaults if we get nothing ++ if(m_screenid == 0) ++ ModeToResolution(DISP_TV_MOD_1080P_60HZ, res); ++ else ++ ModeToResolution(DISP_TV_MOD_NTSC, res); ++ } ++ ++ return true; ++} ++ ++bool CEGLNativeTypeSunxi::ShowWindow(bool show) ++{ ++ unsigned long args[4]; ++ ++ args[0] = m_screenid; ++ args[1] = show ? 0 : 1; ++ ++ return ioctl(m_disp, DISP_BLANK, args) == 0; ++} ++ ++bool CEGLNativeTypeSunxi::SetDisplayResolution(unsigned int mode) ++{ ++ unsigned long args[4]; ++ RESOLUTION_INFO res; ++ ++ args[0] = m_screenid; ++ args[1] = ioctl(m_disp, DISP_GET_OUTPUT_TYPE, args); ++ args[2] = mode; ++ if(ioctl(m_disp, DISP_DEVICE_SWITCH, args) != 0) ++ return false; ++ ++ ModeToResolution(mode, &res); ++ SetFramebufferResolution(res.iScreenWidth, res.iScreenHeight); ++ ++ return true; ++} ++ ++void CEGLNativeTypeSunxi::SetFramebufferResolution(int width, int height) const ++{ ++ int fd0; ++ std::string framebuffer = "/dev/fb0"; ++ ++ if ((fd0 = open(framebuffer.c_str(), O_RDWR)) >= 0) ++ { ++ struct fb_var_screeninfo vinfo; ++ if (ioctl(fd0, FBIOGET_VSCREENINFO, &vinfo) == 0) ++ { ++ vinfo.xres = width; ++ vinfo.yres = height; ++ vinfo.xres_virtual = width; ++ vinfo.yres_virtual = height * 2; ++ vinfo.bits_per_pixel = 32; ++ vinfo.activate = FB_ACTIVATE_ALL; ++ ioctl(fd0, FBIOPUT_VSCREENINFO, &vinfo); ++ } ++ close(fd0); ++ } ++} ++ ++bool CEGLNativeTypeSunxi::ModeToResolution(unsigned int mode, RESOLUTION_INFO *res) const ++{ ++ ++ if (!res) ++ return false; ++ ++ res->iWidth = 0; ++ res->iHeight= 0; ++ ++ switch(mode) ++ { ++ case DISP_TV_MOD_480I: ++ res->iWidth = 720; ++ res->iHeight= 480; ++ res->iScreenWidth = 720; ++ res->iScreenHeight= 480; ++ res->fRefreshRate = 60; ++ res->dwFlags = D3DPRESENTFLAG_INTERLACED; ++ break; ++ case DISP_TV_MOD_576I: ++ res->iWidth = 720; ++ res->iHeight= 576; ++ res->iScreenWidth = 720; ++ res->iScreenHeight= 576; ++ res->fRefreshRate = 50; ++ res->dwFlags = D3DPRESENTFLAG_INTERLACED; ++ break; ++ case DISP_TV_MOD_480P: ++ res->iWidth = 720; ++ res->iHeight= 480; ++ res->iScreenWidth = 720; ++ res->iScreenHeight= 480; ++ res->fRefreshRate = 60; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_576P: ++ res->iWidth = 720; ++ res->iHeight= 576; ++ res->iScreenWidth = 720; ++ res->iScreenHeight= 576; ++ res->fRefreshRate = 50; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_720P_50HZ: ++ res->iWidth = 1280; ++ res->iHeight= 720; ++ res->iScreenWidth = 1280; ++ res->iScreenHeight= 720; ++ res->fRefreshRate = 50; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_720P_60HZ: ++ res->iWidth = 1280; ++ res->iHeight= 720; ++ res->iScreenWidth = 1280; ++ res->iScreenHeight= 720; ++ res->fRefreshRate = 60; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_1080I_50HZ: ++ res->iWidth = 1920; ++ res->iHeight= 1080; ++ res->iScreenWidth = 1920; ++ res->iScreenHeight= 1080; ++ res->fRefreshRate = 50; ++ res->dwFlags = D3DPRESENTFLAG_INTERLACED; ++ break; ++ case DISP_TV_MOD_1080I_60HZ: ++ res->iWidth = 1920; ++ res->iHeight= 1080; ++ res->iScreenWidth = 1920; ++ res->iScreenHeight= 1080; ++ res->fRefreshRate = 60; ++ res->dwFlags = D3DPRESENTFLAG_INTERLACED; ++ break; ++ case DISP_TV_MOD_1080P_24HZ: ++ res->iWidth = 1920; ++ res->iHeight= 1080; ++ res->iScreenWidth = 1920; ++ res->iScreenHeight= 1080; ++ res->fRefreshRate = 24; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_1080P_50HZ: ++ res->iWidth = 1920; ++ res->iHeight= 1080; ++ res->iScreenWidth = 1920; ++ res->iScreenHeight= 1080; ++ res->fRefreshRate = 50; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_1080P_60HZ: ++ res->iWidth = 1920; ++ res->iHeight= 1080; ++ res->iScreenWidth = 1920; ++ res->iScreenHeight= 1080; ++ res->fRefreshRate = 60; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_1080P_25HZ: ++ res->iWidth = 1920; ++ res->iHeight= 1080; ++ res->iScreenWidth = 1920; ++ res->iScreenHeight= 1080; ++ res->fRefreshRate = 25; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_1080P_30HZ: ++ res->iWidth = 1920; ++ res->iHeight= 1080; ++ res->iScreenWidth = 1920; ++ res->iScreenHeight= 1080; ++ res->fRefreshRate = 30; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_3840_2160P_30HZ: ++ res->iWidth = 3840; ++ res->iHeight= 2160; ++ res->iScreenWidth = 3840; ++ res->iScreenHeight= 2160; ++ res->fRefreshRate = 30; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_3840_2160P_25HZ: ++ res->iWidth = 3840; ++ res->iHeight= 2160; ++ res->iScreenWidth = 3840; ++ res->iScreenHeight= 2160; ++ res->fRefreshRate = 25; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_3840_2160P_24HZ: ++ res->iWidth = 3840; ++ res->iHeight= 2160; ++ res->iScreenWidth = 3840; ++ res->iScreenHeight= 2160; ++ res->fRefreshRate = 24; ++ res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE; ++ break; ++ case DISP_TV_MOD_PAL: ++ res->iWidth = 720; ++ res->iHeight= 576; ++ res->iScreenWidth = 720; ++ res->iScreenHeight= 576; ++ res->fRefreshRate = 50; ++ res->dwFlags = D3DPRESENTFLAG_INTERLACED; ++ break; ++ case DISP_TV_MOD_NTSC: ++ res->iWidth = 720; ++ res->iHeight= 480; ++ res->iScreenWidth = 720; ++ res->iScreenHeight= 480; ++ res->fRefreshRate = 60; ++ res->dwFlags = D3DPRESENTFLAG_INTERLACED; ++ break; ++ default: ++ return false; ++ } ++ ++ res->iScreen = 0; ++ res->bFullScreen = true; ++ res->iSubtitles = (int)(0.965 * res->iHeight); ++ res->fPixelRatio = 1.0f; ++ res->strMode = StringUtils::Format("%dx%d @ %.2f%s - Full Screen", res->iScreenWidth, res->iScreenHeight, res->fRefreshRate, ++ res->dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : ""); ++ ++ return true; ++} +diff -Nur a/xbmc/windowing/egl/EGLNativeTypeSunxi.h win/xbmc/windowing/egl/EGLNativeTypeSunxi.h +--- a/xbmc/windowing/egl/EGLNativeTypeSunxi.h 1970-01-01 01:00:00.000000000 +0100 ++++ win/xbmc/windowing/egl/EGLNativeTypeSunxi.h 2016-05-04 18:26:44.483202125 +0200 +@@ -0,0 +1,59 @@ ++#pragma once ++ ++/* ++ * Copyright (C) 2011-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "EGLNativeType.h" ++ ++class CEGLNativeTypeSunxi : public CEGLNativeType ++{ ++public: ++ CEGLNativeTypeSunxi(); ++ virtual ~CEGLNativeTypeSunxi(); ++ virtual std::string GetNativeName() const { return "sunxi"; }; ++ virtual bool CheckCompatibility(); ++ virtual void Initialize(); ++ virtual void Destroy(); ++ virtual int GetQuirks() { return EGL_QUIRK_NONE; }; ++ ++ virtual bool CreateNativeDisplay(); ++ virtual bool CreateNativeWindow(); ++ virtual bool GetNativeDisplay(XBNativeDisplayType **nativeDisplay) const; ++ virtual bool GetNativeWindow(XBNativeWindowType **nativeWindow) const; ++ ++ virtual bool DestroyNativeWindow(); ++ virtual bool DestroyNativeDisplay(); ++ ++ virtual bool GetNativeResolution(RESOLUTION_INFO *res) const; ++ virtual bool SetNativeResolution(const RESOLUTION_INFO &res); ++ virtual bool ProbeResolutions(std::vector &resolutions); ++ virtual bool GetPreferredResolution(RESOLUTION_INFO *res) const; ++ ++ virtual bool ShowWindow(bool show); ++ ++protected: ++ int m_disp; ++ unsigned long m_screenid; ++ bool SetDisplayResolution(unsigned int mode); ++ ++private: ++ void SetFramebufferResolution(int width, int height) const; ++ bool ModeToResolution(unsigned int mode, RESOLUTION_INFO *res) const; ++}; +diff -Nur a/xbmc/windowing/egl/EGLWrapper.cpp win/xbmc/windowing/egl/EGLWrapper.cpp +--- a/xbmc/windowing/egl/EGLWrapper.cpp 2016-04-15 18:52:10.000000000 +0200 ++++ win/xbmc/windowing/egl/EGLWrapper.cpp 2016-05-04 17:49:32.076600226 +0200 +@@ -37,6 +37,7 @@ + #include "EGLNativeTypeIMX.h" + #endif + #include "EGLNativeTypeAmlogic.h" ++#include "EGLNativeTypeSunxi.h" + #include "EGLWrapper.h" + + #define CheckError() m_result = eglGetError(); if(m_result != EGL_SUCCESS) CLog::Log(LOGERROR, "EGL error in %s: %x",__FUNCTION__, m_result); +@@ -105,7 +106,8 @@ + #if defined(HAS_IMXVPU) + (nativeGuess = CreateEGLNativeType(implementation)) || + #endif +- (nativeGuess = CreateEGLNativeType(implementation)) ++ (nativeGuess = CreateEGLNativeType(implementation)) || ++ (nativeGuess = CreateEGLNativeType(implementation)) + ) + { + m_nativeTypes = nativeGuess; +diff -Nur a/xbmc/windowing/egl/Makefile.in win/xbmc/windowing/egl/Makefile.in +--- a/xbmc/windowing/egl/Makefile.in 2016-04-15 18:52:10.000000000 +0200 ++++ win/xbmc/windowing/egl/Makefile.in 2016-05-04 17:49:32.076600226 +0200 +@@ -2,6 +2,7 @@ + + SRCS = WinSystemEGL.cpp + SRCS+= EGLNativeTypeAmlogic.cpp ++SRCS+= EGLNativeTypeSunxi.cpp + ifeq (@USE_ANDROID@,1) + SRCS+= EGLNativeTypeAndroid.cpp + SRCS+= EGLNativeTypeAmlAndroid.cpp diff --git a/projects/H3/patches/kodi/kodi-002-sound-fix.patch b/projects/H3/patches/kodi/kodi-002-sound-fix.patch new file mode 100644 index 00000000000..b36889350eb --- /dev/null +++ b/projects/H3/patches/kodi/kodi-002-sound-fix.patch @@ -0,0 +1,23 @@ +diff -Nur kodi-16.0-beta2-64de219.orig/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp kodi-16.0-beta2-64de219/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp +--- kodi-16.0-beta2-64de219.orig/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2015-11-25 23:02:39.000000000 +0100 ++++ kodi-16.0-beta2-64de219/xbmc/cores/AudioEngine/Sinks/AESinkALSA.cpp 2015-11-25 23:04:05.321722544 +0100 +@@ -695,7 +695,18 @@ + continue; + + if (m_passthrough && i != AE_FMT_S16BE && i != AE_FMT_S16LE) +- continue; ++ continue; ++ ++ if(i == AE_FMT_S24BE4 || ++ i == AE_FMT_S24LE4 || ++ i == AE_FMT_S24NE4 || ++ i == AE_FMT_S24NE4MSB || ++ i == AE_FMT_S24BE3 || ++ i == AE_FMT_S24LE3 || ++ i == AE_FMT_S24NE3) ++ { ++ continue; ++ } + + fmt = AEFormatToALSAFormat(i); + diff --git a/projects/H3/patches/kodi/kodi-003-perform_suspend_instead_of_powerdown.patch b/projects/H3/patches/kodi/kodi-003-perform_suspend_instead_of_powerdown.patch new file mode 100644 index 00000000000..07a504fe3dc --- /dev/null +++ b/projects/H3/patches/kodi/kodi-003-perform_suspend_instead_of_powerdown.patch @@ -0,0 +1,35 @@ +diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml +index 45682a2..b8ce91b 100644 +--- a/system/keymaps/keyboard.xml ++++ b/system/keymaps/keyboard.xml +@@ -96,7 +96,7 @@ + ToggleFullScreen + FirstPage + LastPage +- ActivateWindow(shutdownmenu) ++ XBMC.Powerdown() + ActivateWindow(shutdownmenu) + + XBMC.ActivateWindowAndFocus(MyPVR, 31,0, 10,0) +diff --git a/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp b/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp +index 5a97fe6..369e790 100644 +--- a/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp ++++ b/xbmc/powermanagement/linux/LogindUPowerSyscall.cpp +@@ -52,7 +52,7 @@ CLogindUPowerSyscall::CLogindUPowerSyscall() + m_canPowerdown = LogindCheckCapability("CanPowerOff"); + m_canReboot = LogindCheckCapability("CanReboot"); + m_canHibernate = LogindCheckCapability("CanHibernate"); +- m_canSuspend = LogindCheckCapability("CanSuspend"); ++ m_canSuspend = false; + + InhibitDelayLock(); + +@@ -97,7 +97,7 @@ CLogindUPowerSyscall::~CLogindUPowerSyscall() + + bool CLogindUPowerSyscall::Powerdown() + { +- return LogindSetPowerState("PowerOff"); ++ return Suspend(); + } + + bool CLogindUPowerSyscall::Reboot() diff --git a/projects/H3/patches/kodi/kodi-004-PR9430.patch b/projects/H3/patches/kodi/kodi-004-PR9430.patch new file mode 100644 index 00000000000..d992af7df96 --- /dev/null +++ b/projects/H3/patches/kodi/kodi-004-PR9430.patch @@ -0,0 +1,176 @@ +From b4423b184e08dbb35ce74b019128982436ed2400 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 22 Mar 2016 22:28:13 +0000 +Subject: [PATCH] [linux] Move hotplug checking into its own thread + +Currently checking for new linux input devices is called from the rendering thread. +We've been getting reports of skipped frames on raspberry pi. + +Specifically if eventlirc is active and you have an LIRC capable device connected +the hotplug check is slow and you get a frame skip every ten seconds. + +So move this code into its own thread +--- + xbmc/input/linux/LinuxInputDevices.cpp | 54 +++++++++++++++++++++------------- + xbmc/input/linux/LinuxInputDevices.h | 14 ++++++++- + xbmc/windowing/WinEventsLinux.cpp | 1 + + xbmc/windowing/WinEventsLinux.h | 2 ++ + 4 files changed, 49 insertions(+), 22 deletions(-) + +diff --git a/xbmc/input/linux/LinuxInputDevices.cpp b/xbmc/input/linux/LinuxInputDevices.cpp +index e691aa8..b97a40e 100644 +--- a/xbmc/input/linux/LinuxInputDevices.cpp ++++ b/xbmc/input/linux/LinuxInputDevices.cpp +@@ -1085,6 +1085,30 @@ bool CLinuxInputDevice::IsUnplugged() + return m_bUnplugged; + } + ++CLinuxInputDevicesCheckHotplugged::CLinuxInputDevicesCheckHotplugged(CLinuxInputDevices &parent) : ++ CThread("CLinuxInputDevicesCheckHotplugged"), m_parent(parent) ++{ ++ Create(); ++ SetPriority(THREAD_PRIORITY_BELOW_NORMAL); ++} ++ ++CLinuxInputDevicesCheckHotplugged::~CLinuxInputDevicesCheckHotplugged() ++{ ++ m_bStop = true; ++ m_quitEvent.Set(); ++ StopThread(true); ++} ++ ++void CLinuxInputDevicesCheckHotplugged::Process() ++{ ++ while (!m_bStop) ++ { ++ m_parent.CheckHotplugged(); ++ // every ten seconds ++ m_quitEvent.WaitMSec(10000); ++ } ++} ++ + /* + * this function is not powerful because it reinitializes a new udev search each + * time it would be nicer to call this only one time + one time at each hotplug +@@ -1225,10 +1249,6 @@ void CLinuxInputDevices::InitAvailable() + */ + void CLinuxInputDevices::CheckHotplugged() + { +- CSingleLock lock(m_devicesListLock); +- +- int deviceId = m_devices.size(); +- + /* No devices specified. Try to guess some. */ + for (int i = 0; i < MAX_LINUX_INPUT_DEVICES; i++) + { +@@ -1236,18 +1256,22 @@ void CLinuxInputDevices::CheckHotplugged() + bool ispresent = false; + + snprintf(buf, 32, "/dev/input/event%d", i); +- +- for (size_t j = 0; j < m_devices.size(); j++) + { +- if (m_devices[j]->GetFileName().compare(buf) == 0) ++ CSingleLock lock(m_devicesListLock); ++ for (size_t j = 0; j < m_devices.size(); j++) + { +- ispresent = true; +- break; ++ if (m_devices[j]->GetFileName().compare(buf) == 0) ++ { ++ ispresent = true; ++ break; ++ } + } + } + + if (!ispresent && CheckDevice(buf)) + { ++ CSingleLock lock(m_devicesListLock); ++ int deviceId = m_devices.size(); + CLog::Log(LOGINFO, "Found input device %s", buf); + m_devices.push_back(new CLinuxInputDevice(buf, deviceId)); + ++deviceId; +@@ -1438,18 +1462,6 @@ XBMC_Event CLinuxInputDevices::ReadEvent() + InitAvailable(); + m_bReInitialize = false; + } +- else +- { +- time_t now; +- time(&now); +- +- if ((now - m_lastHotplugCheck) >= 10) +- { +- CheckHotplugged(); +- m_lastHotplugCheck = now; +- } +- } +- + CSingleLock lock(m_devicesListLock); + + XBMC_Event event; +diff --git a/xbmc/input/linux/LinuxInputDevices.h b/xbmc/input/linux/LinuxInputDevices.h +index 4c84efa..44a05fe 100644 +--- a/xbmc/input/linux/LinuxInputDevices.h ++++ b/xbmc/input/linux/LinuxInputDevices.h +@@ -28,6 +28,7 @@ + #include "threads/SingleLock.h" + #include "input/touch/ITouchInputHandler.h" + #include "input/touch/generic/IGenericTouchGestureDetector.h" ++#include "threads/Thread.h" + + struct KeymapEntry + { +@@ -106,7 +107,18 @@ class CLinuxInputDevices + bool CheckDevice(const char *device); + std::vector m_devices; + bool m_bReInitialize; +- time_t m_lastHotplugCheck; ++}; ++ ++class CLinuxInputDevicesCheckHotplugged : protected CThread ++{ ++public: ++ CLinuxInputDevicesCheckHotplugged(CLinuxInputDevices &parent); ++ ~CLinuxInputDevicesCheckHotplugged(); ++private: ++ CLinuxInputDevices &m_parent; ++ CEvent m_quitEvent; ++protected: ++ virtual void Process(); + }; + + #endif /* LINUXINPUTDEVICES_H_ */ +diff --git a/xbmc/windowing/WinEventsLinux.cpp b/xbmc/windowing/WinEventsLinux.cpp +index aaba119..a958a23 100644 +--- a/xbmc/windowing/WinEventsLinux.cpp ++++ b/xbmc/windowing/WinEventsLinux.cpp +@@ -53,6 +53,7 @@ bool CWinEventsLinux::MessagePump() + if (!m_initialized) + { + m_devices.InitAvailable(); ++ m_checkHotplug = std::unique_ptr(new CLinuxInputDevicesCheckHotplugged(m_devices)); + m_initialized = true; + } + +diff --git a/xbmc/windowing/WinEventsLinux.h b/xbmc/windowing/WinEventsLinux.h +index a17e987..1b1d2f2 100644 +--- a/xbmc/windowing/WinEventsLinux.h ++++ b/xbmc/windowing/WinEventsLinux.h +@@ -22,6 +22,7 @@ + #define WINDOW_EVENTS_LINUX_H + + #pragma once ++#include + #include "windowing/WinEvents.h" + #include "input/linux/LinuxInputDevices.h" + +@@ -43,6 +44,7 @@ class CWinEventsLinux : public IWinEvents + private: + static bool m_initialized; + static CLinuxInputDevices m_devices; ++ std::unique_ptr m_checkHotplug; + }; + + #endif diff --git a/projects/H3/patches/kodi/kodi-005-H3-support.patch b/projects/H3/patches/kodi/kodi-005-H3-support.patch new file mode 100644 index 00000000000..12181e11249 --- /dev/null +++ b/projects/H3/patches/kodi/kodi-005-H3-support.patch @@ -0,0 +1,1967 @@ +diff -Nur a/addons/resource.language.en_gb/resources/strings.po codec/addons/resource.language.en_gb/resources/strings.po +--- a/addons/resource.language.en_gb/resources/strings.po 2016-04-17 14:05:15.000000000 +0200 ++++ codec/addons/resource.language.en_gb/resources/strings.po 2016-10-24 17:57:39.882181450 +0200 +@@ -8333,7 +8333,13 @@ + msgid "IMX - Fast motion (double)" + msgstr "" + +-#empty strings from id 16336 to 16399 ++#. Description of OSD video settings for deinterlace method with label #16336 ++#: xbmc/video/dialogs/GUIDialogVideoSettings.cpp ++msgctxt "#16336" ++msgid "Disp2 - BOB" ++msgstr "" ++ ++#empty strings from id 16337 to 16399 + + #: xbmc/video/dialogs/GUIDialogVideoSettings.cpp + msgctxt "#16400" +diff -Nur a/configure.ac codec/configure.ac +--- a/configure.ac 2016-08-03 19:58:43.996813544 +0200 ++++ codec/configure.ac 2016-10-24 17:57:39.882181450 +0200 +@@ -513,7 +513,7 @@ + + AC_ARG_ENABLE([codec], + [AS_HELP_STRING([--enable-codec], +- [enable additional codecs from a list of comma separated names, (default is none, choices are amcodec, libstagefright and imxvpu)])], ++ [enable additional codecs from a list of comma separated names, (default is none, choices are amcodec, libstagefright, imxvpu and cedarx)])], + [add_codecs=$enableval], + [add_codecs=no]) + +@@ -1876,6 +1876,10 @@ + *libstagefright*) + XB_ADD_CODEC([LIBSTAGEFRIGHT], [libstagefright], [$codecs]) + ;; ++ *cedarx*) ++ AC_CHECK_LIB([vdecoder], main, LIBS="$LIBS -lvdecoder -lMemAdapter", AC_MSG_ERROR($missing_library)) ++ XB_ADD_CODEC([CEDARX], [cedarx], [$codecs]) ++ ;; + *imxvpu*) + AC_CHECK_HEADER([imx-mm/vpu/vpu_wrapper.h],, AC_MSG_ERROR($missing_headers)) + AC_CHECK_LIB([vpu], main, LIBS="$LIBS -lfslvpuwrap -lvpu -lg2d", AC_MSG_ERROR($missing_library)) +diff -Nur a/system/settings/sunxi.xml codec/system/settings/sunxi.xml +--- a/system/settings/sunxi.xml 1970-01-01 01:00:00.000000000 +0100 ++++ codec/system/settings/sunxi.xml 2016-10-24 17:57:39.885514784 +0200 +@@ -0,0 +1,17 @@ ++ ++ ++
++ ++ ++ ++ false ++ ++ ++ ++ ++ 3 ++ ++ ++ ++
++
+diff -Nur a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp codec/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp +--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2016-04-17 14:05:15.000000000 +0200 ++++ codec/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp 2016-10-24 17:57:39.885514784 +0200 +@@ -40,6 +40,7 @@ + #if defined(HAS_IMXVPU) + #include "Video/DVDVideoCodecIMX.h" + #endif ++#include "Video/DVDVideoCodecCedarX.h" + #include "Video/MMALCodec.h" + #include "Video/DVDVideoCodecStageFright.h" + #if defined(HAS_LIBAMCODEC) +@@ -159,6 +160,11 @@ + #else + hwSupport += "AMCodec:no "; + #endif ++#if defined(HAS_CEDARX) ++ hwSupport += "CedarX:yes "; ++#else ++ hwSupport += "CedarX:no "; ++#endif + #if defined(TARGET_ANDROID) + hwSupport += "MediaCodec:yes "; + #else +@@ -233,6 +239,13 @@ + } + #endif + ++#if defined(HAS_CEDARX) ++ if (!hint.software) ++ { ++ if ( (pCodec = OpenCodec(new CDVDVideoCodecSunxi(), hint, options)) ) return pCodec; ++ } ++#endif ++ + #if defined(TARGET_DARWIN_OSX) + if (!hint.software && CSettings::GetInstance().GetBool(CSettings::SETTING_VIDEOPLAYER_USEVDA) && !g_advancedSettings.m_useFfmpegVda) + { +diff -Nur a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCedarX.cpp codec/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCedarX.cpp +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCedarX.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ codec/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCedarX.cpp 2016-10-25 18:45:50.176909349 +0200 +@@ -0,0 +1,922 @@ ++/* ++ * Copyright (C) 2005-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "DVDVideoCodecCedarX.h" ++#include "DVDClock.h" ++#include "utils/log.h" ++#include "threads/Atomics.h" ++#include "windowing/WindowingFactory.h" ++ ++#define _4CC(c1,c2,c3,c4) (((uint32_t)(c4)<<24)|((uint32_t)(c3)<<16)|((uint32_t)(c2)<<8)|(uint32_t)(c1)) ++ ++#define DI_MODULE_TIMEOUT 0x1055 ++#define DI_IOC_MAGIC 'D' ++#define DI_IOCSTART _IOWR(DI_IOC_MAGIC, 0, DiParaT *) ++ ++typedef enum ++{ ++ DI_FORMAT_NV12 =0x00, ++ DI_FORMAT_NV21 =0x01, ++ DI_FORMAT_MB32_12 =0x02, //UV mapping like NV12 ++ DI_FORMAT_MB32_21 =0x03, //UV mapping like NV21 ++} DiPixelformatE; ++ ++typedef struct ++{ ++ unsigned int nWidth; ++ unsigned int nHeight; ++} DiRectSizeT; ++ ++typedef struct ++{ ++ uintptr_t addr[2]; // the address of frame buffer ++ DiRectSizeT mRectSize; ++ DiPixelformatE eFormat; ++} DiFbT; ++ ++typedef struct ++{ ++ DiFbT mInputFb; //current frame fb ++ DiFbT mPreFb; //previous frame fb ++ DiRectSizeT mSourceRegion; //current frame and previous frame process region ++ DiFbT mOutputFb; //output frame fb ++ DiRectSizeT mOutRegion; //output frame region ++ unsigned int nField; //process field <0-top field ; 1-bottom field> ++ unsigned int bTopFieldFirst; //video infomation <0-is not top_field_first; 1-is top_field_first> ++} DiParaT; ++ ++// global instance ++CSunxiContext g_SunxiContext; ++ ++CDVDVideoCodecSunxi::CDVDVideoCodecSunxi() : ++ m_videoCodec(nullptr), ++ m_pFormatName("cedarx-xxx"), ++ m_dropState(false), ++ m_vp9orhevccodec(false), ++ m_bitstream(nullptr) ++{ ++ ++} ++ ++CDVDVideoCodecSunxi::~CDVDVideoCodecSunxi() ++{ ++ CLog::Log(LOGDEBUG, "CDVDVideoCodecSunxi destructor"); ++ Dispose(); ++} ++ ++bool CDVDVideoCodecSunxi::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options) ++{ ++ VConfig vConfig; ++ bool ignoreExtraData = false; ++ ++ m_hints = hints; ++ ++ memset(&m_streamInfo, 0, sizeof(m_streamInfo)); ++ memset(&vConfig, 0, sizeof(VConfig)); ++ vConfig.eOutputPixelFormat = PIXEL_FORMAT_NV21; ++ ++ CLog::Log(LOGDEBUG, "Codec profile %d level %d", m_hints.profile, m_hints.level); ++ ++ switch (hints.codec) ++ { ++ case AV_CODEC_ID_MPEG1VIDEO: ++ m_pFormatName = "cedarx-mpeg1"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MPEG1; ++ break; ++ case AV_CODEC_ID_MPEG2VIDEO: ++ case AV_CODEC_ID_MPEG2VIDEO_XVMC: ++ m_pFormatName = "cedarx-mpeg2"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MPEG2; ++ break; ++ case AV_CODEC_ID_H263: ++ m_pFormatName = "cedarx-h263"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_H263; ++ break; ++ case AV_CODEC_ID_MPEG4: ++ switch(m_hints.codec_tag) ++ { ++ case _4CC('d','i','v','x'): ++ case _4CC('D','I','V','X'): ++ m_pFormatName = "cedarx-divx"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_DIVX4; ++ break; ++ case _4CC('D','X','5','0'): ++ case _4CC('d','x','5','0'): ++ case _4CC('D','I','V','5'): ++ case _4CC('d','i','v','5'): ++ m_pFormatName = "cedarx-divx5"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_DIVX5; ++ break; ++ case _4CC('X','V','I','D'): ++ case _4CC('x','v','i','d'): ++ case _4CC('M','P','4','V'): ++ case _4CC('m','p','4','v'): ++ case _4CC('P','M','P','4'): ++ case _4CC('F','M','P','4'): ++ m_pFormatName = "cedarx-xvid"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_XVID; ++ break; ++ default: ++ CLog::Log(LOGWARNING, "CedarX : Using XVID for MPEG4 codec with tag %d.", m_hints.codec_tag); ++ m_pFormatName = "cedarx-xvid"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_XVID; ++ break; ++ } ++ break; ++ case AV_CODEC_ID_MSMPEG4V1: ++ m_pFormatName = "cedarx-mpeg4v1"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MSMPEG4V1; ++ break; ++ case AV_CODEC_ID_MSMPEG4V2: ++ m_pFormatName = "cedarx-mpeg4v2"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MSMPEG4V2; ++ break; ++ case AV_CODEC_ID_MSMPEG4V3: ++ m_pFormatName = "cedarx-divx3"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_DIVX3; ++ break; ++ case AV_CODEC_ID_FLV1: ++ m_pFormatName = "cedarx-flv1"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_SORENSSON_H263; ++ break; ++ case AV_CODEC_ID_RV10: ++ case AV_CODEC_ID_RV20: ++ m_pFormatName = "cedarx-rxg2"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_RXG2; ++ break; ++ case AV_CODEC_ID_RV30: ++ case AV_CODEC_ID_RV40: ++ m_pFormatName = "cedarx-rx"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_RX; ++ break; ++ case AV_CODEC_ID_H264: ++ // Test for VPU unsupported profiles to revert to sw decoding ++ if (m_hints.profile == 110) //hi10p ++ { ++ CLog::Log(LOGNOTICE, "CedarX is not able to decode AVC profile %d level %d", m_hints.profile, m_hints.level); ++ return false; ++ } ++ m_pFormatName = "cedarx-h264"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_H264; ++ // convert h264-avcC to h264-annex-b as h264-avcC ++ // under streamers can have issues when seeking. ++ if (hints.extradata) ++ { ++ m_bitstream = new CBitstreamConverter; ++ if (!m_bitstream->Open(hints.codec, (uint8_t*)hints.extradata, hints.extrasize, true)) ++ { ++ SAFE_DELETE(m_bitstream); ++ } ++ else ++ { ++ // make sure we do not leak the existing hints.extradata ++ free(hints.extradata); ++ hints.extrasize = m_bitstream->GetExtraSize(); ++ hints.extradata = malloc(hints.extrasize); ++ memcpy(hints.extradata, m_bitstream->GetExtraData(), hints.extrasize); ++ } ++ } ++ break; ++ case AV_CODEC_ID_MJPEG: ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_MJPEG; ++ m_pFormatName = "cedarx-mjpeg"; ++ break; ++ case AV_CODEC_ID_WMV1: ++ m_pFormatName = "cedarx-wmv1"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_WMV1; ++ break; ++ case AV_CODEC_ID_WMV2: ++ m_pFormatName = "cedarx-wmv2"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_WMV2; ++ break; ++ case AV_CODEC_ID_VC1: ++ ignoreExtraData = true; ++ case AV_CODEC_ID_WMV3: ++ m_pFormatName = "cedarx-wmv3"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_WMV3; ++ m_streamInfo.bIsFramePackage = 1; ++ break; ++ case AV_CODEC_ID_AVS: ++ case AV_CODEC_ID_CAVS: ++ m_pFormatName = "cedarx-avs"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_AVS; ++ break; ++ case AV_CODEC_ID_HEVC: ++ // Test for VPU unsupported profiles to revert to sw decoding ++ if ((m_hints.profile == 2) && (m_hints.level == 120)) //Main 10 - 10 bit ++ { ++ CLog::Log(LOGNOTICE, "CedarX is not able to decode HEVC profile %d level %d", m_hints.profile, m_hints.level); ++ return false; ++ } ++ m_pFormatName = "cedarx-h265"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_H265; ++ m_vp9orhevccodec = true; ++ break; ++ case AV_CODEC_ID_VP6: ++ m_pFormatName = "cedarx-vp6"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_VP6; ++ break; ++ case AV_CODEC_ID_VP8: ++ m_pFormatName = "cedarx-vp8"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_VP8; ++ break; ++ case AV_CODEC_ID_VP9: ++ m_pFormatName = "cedarx-vp9"; ++ m_streamInfo.eCodecFormat = VIDEO_CODEC_FORMAT_VP9; ++ m_vp9orhevccodec = true; ++ // for some reason, there is a problem with NV21 ++ vConfig.eOutputPixelFormat = PIXEL_FORMAT_YV12; ++ break; ++ default: ++ CLog::Log(LOGDEBUG, "CDVDVideoCodecSunxi::OpenDecoder - Codec format is not supported (%d)!", (int)hints.codec); ++ return false; ++ } ++ ++ m_streamInfo.nWidth = hints.width; ++ m_streamInfo.nHeight = hints.height; ++ ++ // handle video rate ++ if((hints.rfpsscale > 0) && (hints.rfpsrate > 0)) ++ { ++ // check ffmpeg r_frame_rate 1st ++ m_streamInfo.nFrameRate = hints.rfpsrate * 1000 / hints.rfpsscale; ++ } ++ else if(hints.fpsscale > 0) ++ { ++ // then ffmpeg avg_frame_rate next ++ m_streamInfo.nFrameRate = hints.fpsrate * 1000 / hints.fpsscale; ++ } ++ else ++ { ++ m_streamInfo.nFrameRate = hints.fpsrate * 1000; ++ } ++ ++ CLog::Log(LOGDEBUG, "CDVDVideoCodecSunxi::OpenDecoder - AVCodecID(%d) -> CedarXID(0x%x)", ++ (int)hints.codec, m_streamInfo.eCodecFormat); ++ ++ if ((hints.extrasize > 0) && !ignoreExtraData) ++ { ++ m_streamInfo.pCodecSpecificData = (char*)hints.extradata; ++ m_streamInfo.nCodecSpecificDataLen = hints.extrasize; ++ CLog::Log(LOGDEBUG, "CDVDVideoCodecSunxi::OpenDecoder - ExtraSize[%d]", m_streamInfo.nCodecSpecificDataLen); ++ } ++ ++ m_videoCodec = CreateVideoDecoder(); ++ if(m_videoCodec == nullptr) ++ { ++ CLog::Log(LOGERROR,"CDVDVideoCodecSunxi::OpenDecoder - CreateVideoDecoder failed!\n"); ++ return false; ++ } ++ ++ InitializeVideoDecoder(m_videoCodec, &m_streamInfo, &vConfig); ++ g_SunxiContext.Configure(); ++ g_SunxiContext.AddDecoder(m_videoCodec); ++ ++ CLog::Log(LOGINFO, "CDVDVideoCodecSunxi: Opened AllwinnerTech CedarX Codec"); ++ ++ return true; ++} ++ ++void CDVDVideoCodecSunxi::Dispose(void) ++{ ++ CLog::Log(LOGDEBUG,"CDVDVideoCodecSunxi::Dispose"); ++ ++ g_SunxiContext.Close(); ++ ++ if (m_videoCodec) ++ { ++ g_SunxiContext.RemoveDecoder(m_videoCodec); ++ DestroyVideoDecoder(m_videoCodec); ++ m_videoCodec = nullptr; ++ } ++ ++ if (m_bitstream) ++ { ++ m_bitstream->Close(); ++ SAFE_DELETE(m_bitstream); ++ } ++} ++ ++int CDVDVideoCodecSunxi::Decode(uint8_t *pData, int iSize, double dts, double pts) ++{ ++ VideoPicture *picture; ++ VideoStreamDataInfo dataInfo; ++ char* buf0; ++ char* buf1; ++ int64_t nPts = -1; ++ int buf0Size; ++ int buf1Size; ++ int ret; ++ int status; ++ ++ if (m_hints.ptsinvalid) ++ pts = DVD_NOPTS_VALUE; ++ if (pts != DVD_NOPTS_VALUE) ++ nPts = pts; ++ else if (dts!= DVD_NOPTS_VALUE) ++ nPts = dts; ++ ++ if((pData != nullptr) && (iSize > 0)) ++ { ++ if (m_bitstream) ++ { ++ if (!m_bitstream->Convert(pData, iSize)) ++ return VC_ERROR; ++ ++ pData = m_bitstream->GetConvertBuffer(); ++ iSize = m_bitstream->GetConvertSize(); ++ } ++ ++ ret = RequestVideoStreamBuffer(m_videoCodec, iSize, &buf0, ++ &buf0Size, &buf1, &buf1Size, 0); ++ if(ret < 0) ++ { ++ CLog::Log(LOGERROR,"CDVDVideoCodecSunxi::Decode - RequestVideoStreamBuffer failed"); ++ return VC_ERROR; ++ } ++ ++ if(iSize > buf0Size) ++ { ++ memcpy(buf0, pData, buf0Size); ++ memcpy(buf1, pData + buf0Size, buf1Size); ++ } ++ else ++ { ++ memcpy(buf0, pData, iSize); ++ } ++ ++ memset(&dataInfo, 0, sizeof(dataInfo)); ++ dataInfo.pData = buf0; ++ dataInfo.nLength = iSize; ++ dataInfo.bIsFirstPart = 1; ++ dataInfo.bIsLastPart = 1; ++ dataInfo.nPts = nPts; ++ ++ ret = SubmitVideoStreamData(m_videoCodec, &dataInfo, 0); ++ if (ret != 0) ++ { ++ CLog::Log(LOGERROR, "SubmitVideoStreamData() error!"); ++ return VC_ERROR; ++ } ++ } ++ ++ ret = DecodeVideoStream(m_videoCodec, 0, 0, 0, 0); ++ switch(ret) ++ { ++ case VDECODE_RESULT_FRAME_DECODED: ++ case VDECODE_RESULT_KEYFRAME_DECODED: ++ case VDECODE_RESULT_OK: ++ case VDECODE_RESULT_NO_FRAME_BUFFER: //FIXME: what to do for this one? ++ case VDECODE_RESULT_NO_BITSTREAM: ++ case VDECODE_RESULT_CONTINUE: ++ status = VC_BUFFER; ++ break; ++ case VDECODE_RESULT_RESOLUTION_CHANGE: ++ status = VC_REOPEN; ++ break; ++ case VDECODE_RESULT_UNSUPPORTED: ++ default: ++ status = VC_ERROR; ++ break; ++ } ++ ++ //CLog::Log(LOGDEBUG, "CDVDVideoCodecSunxi::Decode - returned value: %d", ret); ++ ++ picture = RequestPicture(m_videoCodec, 0); ++ if(picture != nullptr) ++ { ++ m_buffer = new CCedarXBuffer; ++ ++ if(m_vp9orhevccodec) ++ { ++ m_buffer->leftOffset = picture->nLeftOffset; ++ m_buffer->topOffset = picture->nTopOffset; ++ } ++ else ++ { ++ m_buffer->leftOffset = 0; ++ m_buffer->topOffset = 0; ++ } ++ ++ m_buffer->pPicture = picture; ++ m_buffer->pVideoCodec = m_videoCodec; ++ m_buffer->Lock(); ++ ++ status |= VC_PICTURE; ++ } ++ ++ return status; ++} ++ ++void CDVDVideoCodecSunxi::Reset(void) ++{ ++ if(m_videoCodec != nullptr) ++ { ++ ResetVideoDecoder(m_videoCodec); ++ } ++} ++ ++bool CDVDVideoCodecSunxi::ClearPicture(DVDVideoPicture* pDvdVideoPicture) ++{ ++ if(pDvdVideoPicture != nullptr) ++ { ++ SAFE_RELEASE(pDvdVideoPicture->Disp2Buffer); ++ } ++ ++ return true; ++} ++ ++bool CDVDVideoCodecSunxi::GetPicture(DVDVideoPicture* pDvdVideoPicture) ++{ ++ if (pDvdVideoPicture != nullptr) ++ { ++ int realWidth = m_buffer->pPicture->nRightOffset - m_buffer->leftOffset; ++ int realHeight = m_buffer->pPicture->nBottomOffset - m_buffer->topOffset; ++ ++ // if the offset is not right, we should not use them to compute width and height ++ //FIXME: Why is there a problem with some videos? Is this limited to interlaced MPEG2s? ++ if ((realWidth <= 0) || (realHeight <= 0) || ++ (m_streamInfo.eCodecFormat == VIDEO_CODEC_FORMAT_MPEG2)) ++ { ++ realWidth = m_buffer->pPicture->nWidth; ++ realHeight = m_buffer->pPicture->nHeight; ++ } ++ ++ pDvdVideoPicture->pts = (m_buffer->pPicture->nPts > 0) ? ++ (double)m_buffer->pPicture->nPts : DVD_NOPTS_VALUE; ++ pDvdVideoPicture->dts = DVD_NOPTS_VALUE; ++ ++ pDvdVideoPicture->format = RENDER_FMT_DISP2; ++ pDvdVideoPicture->iWidth = realWidth; ++ pDvdVideoPicture->iHeight = realHeight; ++ pDvdVideoPicture->iDisplayWidth = realWidth; ++ pDvdVideoPicture->iDisplayHeight = realHeight; ++ pDvdVideoPicture->Disp2Buffer = m_buffer; ++ ++ pDvdVideoPicture->color_range = 0; ++ pDvdVideoPicture->color_matrix = 4; ++ ++ pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED; ++ if (!m_buffer->pPicture->bIsProgressive) ++ pDvdVideoPicture->iFlags |= DVP_FLAG_INTERLACED; ++ if (m_buffer->pPicture->bTopFieldFirst) ++ pDvdVideoPicture->iFlags |= DVP_FLAG_TOP_FIELD_FIRST; ++ if (m_buffer->pPicture->bRepeatTopField) ++ pDvdVideoPicture->iFlags |= DVP_FLAG_REPEAT_TOP_FIELD; ++ if (m_dropState) ++ pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED; ++ ++ return true; ++ } ++ ++ return false; ++} ++ ++void CDVDVideoCodecSunxi::SetSpeed(int iSpeed) ++{ ++ g_SunxiContext.Pause(iSpeed == DVD_PLAYSPEED_PAUSE); ++} ++ ++void CCedarXBuffer::Lock() ++{ ++ AtomicIncrement(&m_iRefs); ++} ++ ++long CCedarXBuffer::Release() ++{ ++ if (AtomicDecrement(&m_iRefs) == 0) ++ { ++ delete this; ++ } ++ ++ return m_iRefs; ++} ++ ++CCedarXBuffer::~CCedarXBuffer() ++{ ++ VideoPicture *pic = pPicture; ++ pPicture = nullptr; ++ g_SunxiContext.FreePicture(pVideoCodec, pic); ++} ++ ++CSunxiContext::CSunxiContext() : ++ m_deinterlace(false), ++ m_last(nullptr), ++ m_paused(false), ++ m_instances(0), ++ m_vsync(false), ++ m_fbHandle(-1), ++ m_screenid(0) ++{ ++ unsigned long args[4]; ++ disp_output para; ++ ++ m_difd = open("/dev/deinterlace", O_RDWR); ++ if (m_difd == -1) ++ { ++ CLog::Log(LOGERROR, "Can't open HW deinterlacer!"); ++ } ++ ++ m_disp = open("/dev/disp", O_RDWR); ++ if (m_disp == -1) ++ { ++ CLog::Log(LOGERROR, "%s - Can't open display. Nothing will work!\n", __FUNCTION__); ++ return; ++ } ++ ++ args[0] = 0; ++ args[1] = (unsigned long)(¶); ++ ioctl(m_disp, DISP_GET_OUTPUT, args); ++ ++ m_screenid = (para.type == 0) ? 1 : 0; ++} ++ ++CSunxiContext::~CSunxiContext() ++{ ++ if (m_difd != -1) ++ { ++ close(m_difd); ++ } ++ ++ if (m_disp != -1) ++ { ++ close(m_disp); ++ } ++} ++ ++void CSunxiContext::Configure() ++{ ++ CSingleLock lk(m_renderLock); ++ ++ if(m_instances == 0) ++ { ++ unsigned long args[4] = { m_screenid, (unsigned long)(&video_config), 1, 0 }; ++ ++ // framebuffer is always at layer(1,0) ++ video_config.channel = 1; ++ video_config.layer_id = 0; ++ ++ ioctl(m_disp, DISP_LAYER_GET_CONFIG, args); ++ ++ m_savedMode = video_config.info.alpha_mode; ++ m_savedZOrder = video_config.info.zorder; ++ ++ video_config.info.alpha_mode = 0; ++ video_config.info.zorder = 1; // highest number is on top ++ ++ ioctl(m_disp, DISP_LAYER_SET_CONFIG, args); ++ ++ video_config.info.mode = LAYER_MODE_BUFFER; ++ video_config.info.alpha_mode = 1; ++ video_config.info.alpha_value = 255; ++ ++ video_config.enable = 0; ++ video_config.channel = 0; ++ video_config.layer_id = 0; ++ video_config.info.zorder = 0; ++ ++ ioctl(m_disp, DISP_LAYER_SET_CONFIG, args); ++ ++ m_fbHandle = open("/dev/fb0", O_RDWR); ++ if (m_fbHandle == -1) ++ { ++ CLog::Log(LOGERROR, "Can't open framebuffer!"); ++ } ++ } ++ ++ m_instances++; ++} ++ ++void CSunxiContext::Close() ++{ ++ CSingleLock lk(m_renderLock); ++ ++ if (m_instances == 0) ++ return; ++ ++ if (m_instances == 1) ++ { ++ unsigned long args[4] = { m_screenid, (unsigned long)(&video_config), 1, 0 }; ++ ++ SAFE_RELEASE(m_last); ++ ++ video_config.enable = 0; ++ ++ ioctl(m_disp, DISP_LAYER_SET_CONFIG, args); ++ ++ // framebuffer is always at layer(1,0) ++ video_config.channel = 1; ++ video_config.layer_id = 0; ++ ++ ioctl(m_disp, DISP_LAYER_GET_CONFIG, args); ++ ++ video_config.info.alpha_mode = m_savedMode; ++ video_config.info.zorder = m_savedZOrder; ++ ++ ioctl(m_disp, DISP_LAYER_SET_CONFIG, args); ++ ++ if (m_fbHandle != -1) ++ { ++ close(m_fbHandle); ++ } ++ } ++ ++ m_instances--; ++} ++ ++void CSunxiContext::SetDeinterlacing(bool enabled) ++{ ++ m_deinterlace = enabled; ++} ++ ++void CSunxiContext::Pause(bool enabled) ++{ ++ m_paused = enabled; ++} ++ ++void CSunxiContext::SetVSync(bool enabled) ++{ ++ unsigned long args[4] = { 0, (unsigned long)(&video_config), 1, 0 }; ++ ++ args[0] = m_screenid; ++ args[1] = enabled ? 1 : 0; ++ args[2] = 0; ++ args[3] = 0; ++ ioctl(m_disp, DISP_VSYNC_EVENT_EN, args); ++ ++ m_vsync = enabled && (m_fbHandle != -1); ++} ++ ++void CSunxiContext::Render(CCedarXBuffer *buffer, CRect &srcRect, CRect &dstRect) ++{ ++ CSingleLock lk(m_renderLock); ++ unsigned long args[4] = { m_screenid, (unsigned long)(&video_config), 1, 0 }; ++ int numOfPasses = 1; ++ ++ if (!buffer || !buffer->pPicture || !IsDecoderValid(buffer->pVideoCodec)) ++ return; ++ ++ if (m_instances == 0) ++ return; ++ ++ if ((m_last != nullptr) && !IsDecoderValid(m_last->pVideoCodec)) ++ SAFE_RELEASE(m_last); ++ ++ if ((m_deinterlace) && (m_last != nullptr) && ++ (m_difd != -1) && (buffer->pPicture->ePixelFormat == PIXEL_FORMAT_NV21)) ++ { ++ numOfPasses = 2; ++ } ++ ++ for(int index = 0; index < numOfPasses; index++) ++ { ++ CCedarXBuffer *renderbuf; ++ VideoPicture *pPicture; ++ unsigned long memAddr0 = 0; ++ unsigned long memAddr1 = 0; ++ unsigned long memAddr2 = 0; ++ ++ if(numOfPasses > 1) ++ { ++ if(!m_paused) ++ renderbuf = Deinterlace(buffer, index); ++ else ++ renderbuf = m_last; ++ } ++ else ++ renderbuf = buffer; ++ ++ // sanity check ++ if(renderbuf == nullptr) ++ continue; ++ ++ pPicture = renderbuf->pPicture; ++ ++ // Y, U and V buffer format and addresses ++ if (pPicture->ePixelFormat == PIXEL_FORMAT_YV12) ++ { ++ video_config.info.fb.format = DISP_FORMAT_YUV420_P; ++ memAddr0 = (unsigned long)MemAdapterGetPhysicAddressCpu(pPicture->pData0); ++ memAddr1 = (unsigned long)MemAdapterGetPhysicAddressCpu(pPicture->pData2); ++ memAddr2 = (unsigned long)MemAdapterGetPhysicAddressCpu(pPicture->pData1); ++ ++ // sanity check ++ if (!memAddr0 || !memAddr1 || !memAddr2) ++ return; ++ } ++ else // NV21 is default ++ { ++ video_config.info.fb.format = DISP_FORMAT_YUV420_SP_VUVU; ++ memAddr0 = (unsigned long)MemAdapterGetPhysicAddressCpu(pPicture->pData0); ++ memAddr1 = (unsigned long)MemAdapterGetPhysicAddressCpu(pPicture->pData1); ++ ++ // sanity check ++ if (!memAddr0 || !memAddr1) ++ return; ++ } ++ ++ video_config.info.fb.addr[0] = memAddr0; ++ video_config.info.fb.addr[1] = memAddr1; ++ video_config.info.fb.addr[2] = memAddr2; ++ ++ // Y, U and V buffer sizes ++ //int bufWidth = (pPicture->nWidth + 15) & ~15; ++ //int bufHeight = (pPicture->nHeight + 15) & ~15; ++ int bufWidth = pPicture->nWidth; ++ int bufHeight = pPicture->nHeight; ++ ++ video_config.info.fb.size[0].width = bufWidth; ++ video_config.info.fb.size[0].height = bufHeight; ++ video_config.info.fb.size[1].width = bufWidth / 2; ++ video_config.info.fb.size[1].height = bufHeight / 2; ++ video_config.info.fb.size[2].width = bufWidth / 2; ++ video_config.info.fb.size[2].height = bufHeight / 2; ++ video_config.info.fb.align[0] = 0; ++ video_config.info.fb.align[1] = 0; ++ video_config.info.fb.align[2] = 0; ++ ++ // display rectangle ++ video_config.info.screen_win.x = lrint(dstRect.x1); ++ video_config.info.screen_win.y = lrint(dstRect.y1); ++ video_config.info.screen_win.width = lrint(dstRect.x2 - dstRect.x1); ++ video_config.info.screen_win.height = lrint(dstRect.y2 - dstRect.y1); ++ ++ // check zoom ++ unsigned int width = g_Windowing.GetWidth(); ++ unsigned int height = g_Windowing.GetHeight(); ++ double xzoom = (dstRect.x2 - dstRect.x1) / (srcRect.x2 - srcRect.x1); ++ double yzoom = (dstRect.y2 - dstRect.y1) / (srcRect.y2 - srcRect.x1); ++ double cropX = renderbuf->leftOffset + srcRect.x1; ++ double cropY = renderbuf->topOffset + srcRect.y1; ++ double cropWidth = srcRect.x2 - srcRect.x1; ++ double cropHeight = srcRect.y2 - srcRect.y1; ++ ++ if (video_config.info.screen_win.x < 0) ++ { ++ cropX -= video_config.info.screen_win.x / xzoom; ++ video_config.info.screen_win.x = 0; ++ } ++ if (video_config.info.screen_win.width > width) ++ { ++ cropWidth -= (video_config.info.screen_win.width - width) / xzoom; ++ video_config.info.screen_win.width = width; ++ } ++ ++ if (video_config.info.screen_win.y < 0) ++ { ++ cropY -= video_config.info.screen_win.y / yzoom; ++ video_config.info.screen_win.y = 0; ++ } ++ if (video_config.info.screen_win.height > height) ++ { ++ cropHeight -= (video_config.info.screen_win.height - height) / yzoom; ++ video_config.info.screen_win.height = height; ++ } ++ ++ // image cropping ++ video_config.info.fb.crop.x = (unsigned long long)(lrint(cropX)) << 32; ++ video_config.info.fb.crop.y = (unsigned long long)(lrint(cropY)) << 32; ++ video_config.info.fb.crop.width = (unsigned long long)(lrint(cropWidth)) << 32; ++ video_config.info.fb.crop.height = (unsigned long long)(lrint(cropHeight)) << 32; ++ ++ // misc ++ video_config.enable = 1; ++ //NOTE: Height calculation is strictly speaking incorrect, but will do. ++ video_config.info.fb.color_space = ((srcRect.y2 - srcRect.y1) < 720) ? DISP_BT601 : DISP_BT709; ++ ++ ioctl(m_disp, DISP_LAYER_SET_CONFIG, args); ++ ++ renderbuf->Lock(); ++ SAFE_RELEASE(m_last); ++ m_last = renderbuf; ++ ++ // Wait for sync ++// if (m_vsync) ++// { ++// if (ioctl(m_fbHandle, FBIO_WAITFORVSYNC, 0) < 0) ++// CLog::Log(LOGWARNING, "Vsync failed: %s\n", strerror(errno)); ++// } ++ ++ if(m_paused) ++ break; ++ } ++} ++ ++CCedarXBuffer *CSunxiContext::Deinterlace(CCedarXBuffer *current, int nField) ++{ ++ DiParaT mDiParaT; ++ DiRectSizeT mSrcSize; ++ DiRectSizeT mDstSize; ++ uintptr_t preMemAddr0; ++ uintptr_t preMemAddr1; ++ uintptr_t curMemAddr0; ++ uintptr_t curMemAddr1; ++ ++ // sanity check ++ if ((m_last == nullptr) || (current == nullptr)) ++ return nullptr; ++ ++ VideoPicture *pPrePicture = m_last->pPicture; ++ VideoPicture *pCurPicture = current->pPicture; ++ ++ // sanity check #2 ++ if ((pPrePicture == nullptr) || (pCurPicture == nullptr)) ++ return nullptr; ++ ++ preMemAddr0 = (uintptr_t)MemAdapterGetPhysicAddressCpu((void*)pPrePicture->pData0); ++ preMemAddr1 = (uintptr_t)MemAdapterGetPhysicAddressCpu((void*)pPrePicture->pData1); ++ curMemAddr0 = (uintptr_t)MemAdapterGetPhysicAddressCpu((void*)pCurPicture->pData0); ++ curMemAddr1 = (uintptr_t)MemAdapterGetPhysicAddressCpu((void*)pCurPicture->pData1); ++ ++ // sanity check #3 ++ if (!preMemAddr0 || !preMemAddr1 || !curMemAddr0 || !curMemAddr0) ++ { ++ CLog::Log(LOGERROR, "CedarX deinterlacing: Could not resolve phy memory address!"); ++ return nullptr; ++ } ++ ++ mSrcSize.nWidth = pCurPicture->nWidth; ++ mSrcSize.nHeight = pCurPicture->nHeight; ++ mDstSize.nWidth = pPrePicture->nLineStride; ++ mDstSize.nHeight = pPrePicture->nHeight; ++ mDiParaT.mInputFb.mRectSize = mSrcSize; ++ mDiParaT.mInputFb.eFormat = DI_FORMAT_NV21; ++ mDiParaT.mPreFb.mRectSize = mSrcSize; ++ mDiParaT.mPreFb.eFormat = DI_FORMAT_NV21; ++ mDiParaT.mOutputFb.mRectSize = mDstSize; ++ mDiParaT.mOutputFb.eFormat = DI_FORMAT_NV21; ++ mDiParaT.mSourceRegion = mSrcSize; ++ mDiParaT.mOutRegion = mSrcSize; ++ mDiParaT.nField = nField; ++ mDiParaT.bTopFieldFirst = pCurPicture->bTopFieldFirst; ++ ++ mDiParaT.mInputFb.addr[0] = curMemAddr0; ++ mDiParaT.mInputFb.addr[1] = curMemAddr1; ++ mDiParaT.mPreFb.addr[0] = preMemAddr0; ++ mDiParaT.mPreFb.addr[1] = preMemAddr1; ++ mDiParaT.mOutputFb.addr[0] = mDiParaT.mPreFb.addr[0]; ++ mDiParaT.mOutputFb.addr[1] = mDiParaT.mPreFb.addr[1]; ++ ++ if (ioctl(m_difd, DI_IOCSTART, &mDiParaT) != 0) ++ { ++ CLog::Log(LOGERROR, "HW deinterlacing failed!"); ++ return nullptr; ++ } ++ ++ return m_last; ++} ++ ++void CSunxiContext::AddDecoder(VideoDecoder *decoder) ++{ ++ CSingleLock lk(m_renderLock); ++ ++ if(decoder != nullptr) ++ { ++ m_decoders.insert(decoder); ++ } ++} ++ ++void CSunxiContext::RemoveDecoder(VideoDecoder *decoder) ++{ ++ CSingleLock lk(m_renderLock); ++ ++ m_decoders.erase(decoder); ++} ++ ++void CSunxiContext::FreePicture(VideoDecoder *decoder, VideoPicture *picture) ++{ ++ CSingleLock lk(m_renderLock); ++ ++ if((picture != nullptr) && IsDecoderValid(decoder)) ++ { ++ ReturnPicture(decoder, picture); ++ } ++} ++ ++bool CSunxiContext::IsDecoderValid(VideoDecoder *decoder) ++{ ++ return m_decoders.find(decoder) != m_decoders.end(); ++} +diff -Nur a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCedarX.h codec/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCedarX.h +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCedarX.h 1970-01-01 01:00:00.000000000 +0100 ++++ codec/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecCedarX.h 2016-10-24 18:10:42.145554063 +0200 +@@ -0,0 +1,128 @@ ++#pragma once ++/* ++ * Copyright (C) 2005-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include ++#include "sunxi_display2.h" ++#include ++#include ++ ++#include "DVDVideoCodec.h" ++#include "DVDStreamInfo.h" ++#include "utils/BitstreamConverter.h" ++#include "guilib/Geometry.h" ++#include "threads/SingleLock.h" ++ ++class CCedarXBuffer ++{ ++public: ++ CCedarXBuffer() : pPicture(nullptr), ++ pVideoCodec(nullptr), leftOffset(0), ++ topOffset(0), m_iRefs(0) {} ++ ++ // Shared pointer interface ++ virtual void Lock(); ++ virtual long Release(); ++ ++public: ++ VideoPicture *pPicture; ++ VideoDecoder *pVideoCodec; ++ int leftOffset; ++ int topOffset; ++ ++protected: ++ long m_iRefs; ++ ++private: ++ // private because we are reference counted ++ virtual ~CCedarXBuffer(); ++}; ++ ++class CDVDVideoCodecSunxi : public CDVDVideoCodec ++{ ++public: ++ CDVDVideoCodecSunxi(); ++ virtual ~CDVDVideoCodecSunxi(); ++ ++ // Required overrides ++ virtual bool Open(CDVDStreamInfo &hints, CDVDCodecOptions &options); ++ virtual void Dispose(void); ++ virtual int Decode(uint8_t *pData, int iSize, double dts, double pts); ++ virtual void Reset(void); ++ virtual bool ClearPicture(DVDVideoPicture* pDvdVideoPicture); ++ virtual bool GetPicture(DVDVideoPicture *pDvdVideoPicture); ++ virtual void SetDropState(bool bDrop) { m_dropState = bDrop; } ++ virtual const char* GetName(void) { return (const char*)m_pFormatName; } ++ virtual void SetSpeed(int iSpeed); ++ ++protected: ++ CCedarXBuffer *m_buffer; ++ CDVDStreamInfo m_hints; ++ VideoDecoder *m_videoCodec; ++ VideoStreamInfo m_streamInfo; ++ const char *m_pFormatName; ++ bool m_dropState; ++ bool m_vp9orhevccodec; ++ ++ CBitstreamConverter *m_bitstream; ++}; ++ ++class CSunxiContext ++{ ++public: ++ CSunxiContext(); ++ ~CSunxiContext(); ++ void Configure(); ++ void Close(); ++ ++ void SetDeinterlacing(bool enabled); ++ void DeinterlaceMode(bool bottomFirst); ++ void Pause(bool enabled); ++ void Render(CCedarXBuffer *buffer, CRect &srcRect, CRect &dstRect); ++ CCedarXBuffer *Deinterlace(CCedarXBuffer *current, int nField); ++ void SetVSync(bool enabled); ++ ++// ugly hack ++ void AddDecoder(VideoDecoder *decoder); ++ void RemoveDecoder(VideoDecoder *decoder); ++ void FreePicture(VideoDecoder *decoder, VideoPicture *picture); ++ ++private: ++ inline bool IsDecoderValid(VideoDecoder *decoder); ++ ++private: ++ disp_layer_config video_config; ++ CCriticalSection m_renderLock; ++ bool m_deinterlace; ++ int m_difd; ++ CCedarXBuffer *m_last; ++ bool m_paused; ++ unsigned int m_instances; ++ bool m_vsync; ++ int m_fbHandle; ++ unsigned long m_screenid; ++ int m_disp; ++ unsigned char m_savedMode; ++ unsigned char m_savedZOrder; ++ // ugly hack ++ std::set m_decoders; ++}; ++ ++extern CSunxiContext g_SunxiContext; +diff -Nur a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h codec/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2016-04-17 14:05:15.000000000 +0200 ++++ codec/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodec.h 2016-10-24 17:57:39.885514784 +0200 +@@ -52,6 +52,7 @@ + class CDVDMediaCodecInfo; + class CDVDVideoCodecIMXBuffer; + class CMMALVideoBuffer; ++class CCedarXBuffer; + typedef void* EGLImageKHR; + + +@@ -102,6 +103,10 @@ + struct { + CMMALVideoBuffer *MMALBuffer; + }; ++ ++ struct { ++ CCedarXBuffer *Disp2Buffer; ++ }; + + }; + +diff -Nur a/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in codec/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2016-04-17 14:05:15.000000000 +0200 ++++ codec/xbmc/cores/dvdplayer/DVDCodecs/Video/Makefile.in 2016-10-24 17:57:39.885514784 +0200 +@@ -23,6 +23,9 @@ + ifeq (@USE_IMXVPU@,1) + SRCS += DVDVideoCodecIMX.cpp + endif ++ifeq (@USE_CEDARX@,1) ++SRCS += DVDVideoCodecCedarX.cpp ++endif + ifeq (@USE_LIBAMCODEC@,1) + SRCS += AMLCodec.cpp + SRCS += DVDVideoCodecAmlogic.cpp +diff -Nur a/xbmc/cores/dvdplayer/DVDCodecs/Video/sunxi_display2.h codec/xbmc/cores/dvdplayer/DVDCodecs/Video/sunxi_display2.h +--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/sunxi_display2.h 1970-01-01 01:00:00.000000000 +0100 ++++ codec/xbmc/cores/dvdplayer/DVDCodecs/Video/sunxi_display2.h 2016-10-24 17:57:39.885514784 +0200 +@@ -0,0 +1,388 @@ ++#ifndef __SUNXI_DISPLAY_H__ ++#define __SUNXI_DISPLAY_H__ ++ ++typedef struct {unsigned char alpha;unsigned char red;unsigned char green; unsigned char blue; }disp_color; ++typedef struct {int x; int y; unsigned int width; unsigned int height;}disp_rect; ++typedef struct {unsigned int width;unsigned int height; }disp_rectsz; ++typedef struct {int x; int y; }disp_position; ++ ++typedef enum ++{ ++ DISP_FORMAT_ARGB_8888 = 0x00,//MSB A-R-G-B LSB ++ DISP_FORMAT_ABGR_8888 = 0x01, ++ DISP_FORMAT_RGBA_8888 = 0x02, ++ DISP_FORMAT_BGRA_8888 = 0x03, ++ DISP_FORMAT_XRGB_8888 = 0x04, ++ DISP_FORMAT_XBGR_8888 = 0x05, ++ DISP_FORMAT_RGBX_8888 = 0x06, ++ DISP_FORMAT_BGRX_8888 = 0x07, ++ DISP_FORMAT_RGB_888 = 0x08, ++ DISP_FORMAT_BGR_888 = 0x09, ++ DISP_FORMAT_RGB_565 = 0x0a, ++ DISP_FORMAT_BGR_565 = 0x0b, ++ DISP_FORMAT_ARGB_4444 = 0x0c, ++ DISP_FORMAT_ABGR_4444 = 0x0d, ++ DISP_FORMAT_RGBA_4444 = 0x0e, ++ DISP_FORMAT_BGRA_4444 = 0x0f, ++ DISP_FORMAT_ARGB_1555 = 0x10, ++ DISP_FORMAT_ABGR_1555 = 0x11, ++ DISP_FORMAT_RGBA_5551 = 0x12, ++ DISP_FORMAT_BGRA_5551 = 0x13, ++ ++ /* SP: semi-planar, P:planar, I:interleaved ++ * UVUV: U in the LSBs; VUVU: V in the LSBs */ ++ DISP_FORMAT_YUV444_I_AYUV = 0x40,//MSB A-Y-U-V LSB, reserved ++ DISP_FORMAT_YUV444_I_VUYA = 0x41,//MSB V-U-Y-A LSB ++ DISP_FORMAT_YUV422_I_YVYU = 0x42,//MSB Y-V-Y-U LSB ++ DISP_FORMAT_YUV422_I_YUYV = 0x43,//MSB Y-U-Y-V LSB ++ DISP_FORMAT_YUV422_I_UYVY = 0x44,//MSB U-Y-V-Y LSB ++ DISP_FORMAT_YUV422_I_VYUY = 0x45,//MSB V-Y-U-Y LSB ++ DISP_FORMAT_YUV444_P = 0x46,//MSB P3-2-1-0 LSB, YYYY UUUU VVVV, reserved ++ DISP_FORMAT_YUV422_P = 0x47,//MSB P3-2-1-0 LSB YYYY UU VV ++ DISP_FORMAT_YUV420_P = 0x48,//MSB P3-2-1-0 LSB YYYY U V ++ DISP_FORMAT_YUV411_P = 0x49,//MSB P3-2-1-0 LSB YYYY U V ++ DISP_FORMAT_YUV422_SP_UVUV = 0x4a,//MSB V-U-V-U LSB ++ DISP_FORMAT_YUV422_SP_VUVU = 0x4b,//MSB U-V-U-V LSB ++ DISP_FORMAT_YUV420_SP_UVUV = 0x4c, ++ DISP_FORMAT_YUV420_SP_VUVU = 0x4d, ++ DISP_FORMAT_YUV411_SP_UVUV = 0x4e, ++ DISP_FORMAT_YUV411_SP_VUVU = 0x4f, ++}disp_pixel_format; ++ ++typedef enum ++{ ++ DISP_3D_OUT_MODE_CI_1 = 0x5,//column interlaved 1 ++ DISP_3D_OUT_MODE_CI_2 = 0x6,//column interlaved 2 ++ DISP_3D_OUT_MODE_CI_3 = 0x7,//column interlaved 3 ++ DISP_3D_OUT_MODE_CI_4 = 0x8,//column interlaved 4 ++ DISP_3D_OUT_MODE_LIRGB = 0x9,//line interleaved rgb ++ ++ DISP_3D_OUT_MODE_TB = 0x0,//top bottom ++ DISP_3D_OUT_MODE_FP = 0x1,//frame packing ++ DISP_3D_OUT_MODE_SSF = 0x2,//side by side full ++ DISP_3D_OUT_MODE_SSH = 0x3,//side by side half ++ DISP_3D_OUT_MODE_LI = 0x4,//line interleaved ++ DISP_3D_OUT_MODE_FA = 0xa,//field alternative ++}disp_3d_out_mode; ++ ++typedef enum ++{ ++ DISP_BT601 = 0, ++ DISP_BT709 = 1, ++ DISP_YCC = 2, ++}disp_color_space; ++ ++typedef enum ++{ ++ DISP_CSC_TYPE_RGB = 0, ++ DISP_CSC_TYPE_YUV1 = 1,//HDMI ++ DISP_CSC_TYPE_YUV2 = 2,//TV ++}disp_csc_type; ++ ++typedef enum ++{ ++ DISP_COLOR_RANGE_16_255 = 0, ++ DISP_COLOR_RANGE_0_255 = 1, ++ DISP_COLOR_RANGE_16_235 = 2, ++}disp_color_range; ++ ++typedef enum ++{ ++ DISP_OUTPUT_TYPE_NONE = 0, ++ DISP_OUTPUT_TYPE_LCD = 1, ++ DISP_OUTPUT_TYPE_TV = 2, ++ DISP_OUTPUT_TYPE_HDMI = 4, ++ DISP_OUTPUT_TYPE_VGA = 8, ++}disp_output_type; ++ ++typedef enum ++{ ++ DISP_TV_MOD_480I = 0, ++ DISP_TV_MOD_576I = 1, ++ DISP_TV_MOD_480P = 2, ++ DISP_TV_MOD_576P = 3, ++ DISP_TV_MOD_720P_50HZ = 4, ++ DISP_TV_MOD_720P_60HZ = 5, ++ DISP_TV_MOD_1080I_50HZ = 6, ++ DISP_TV_MOD_1080I_60HZ = 7, ++ DISP_TV_MOD_1080P_24HZ = 8, ++ DISP_TV_MOD_1080P_50HZ = 9, ++ DISP_TV_MOD_1080P_60HZ = 0xa, ++ DISP_TV_MOD_1080P_24HZ_3D_FP = 0x17, ++ DISP_TV_MOD_720P_50HZ_3D_FP = 0x18, ++ DISP_TV_MOD_720P_60HZ_3D_FP = 0x19, ++ DISP_TV_MOD_1080P_25HZ = 0x1a, ++ DISP_TV_MOD_1080P_30HZ = 0x1b, ++ DISP_TV_MOD_PAL = 0xb, ++ DISP_TV_MOD_PAL_SVIDEO = 0xc, ++ DISP_TV_MOD_NTSC = 0xe, ++ DISP_TV_MOD_NTSC_SVIDEO = 0xf, ++ DISP_TV_MOD_PAL_M = 0x11, ++ DISP_TV_MOD_PAL_M_SVIDEO = 0x12, ++ DISP_TV_MOD_PAL_NC = 0x14, ++ DISP_TV_MOD_PAL_NC_SVIDEO = 0x15, ++ DISP_TV_MOD_3840_2160P_30HZ = 0x1c, ++ DISP_TV_MOD_3840_2160P_25HZ = 0x1d, ++ DISP_TV_MOD_3840_2160P_24HZ = 0x1e, ++ DISP_TV_MODE_NUM = 0x1f, ++}disp_tv_mode; ++ ++ ++//FIXME:still need? ++typedef enum ++{ ++ DISP_EXIT_MODE_CLEAN_ALL = 0, ++ DISP_EXIT_MODE_CLEAN_PARTLY = 1,//only clean interrupt temply ++}disp_exit_mode; ++ ++typedef enum ++{ ++ DISP_BF_NORMAL = 0,//non-stereo ++ DISP_BF_STEREO_TB = 1 << 0,//stereo top-bottom ++ DISP_BF_STEREO_FP = 1 << 1,//stereo frame packing ++ DISP_BF_STEREO_SSH = 1 << 2,//stereo side by side half ++ DISP_BF_STEREO_SSF = 1 << 3,//stereo side by side full ++ DISP_BF_STEREO_LI = 1 << 4,//stereo line interlace ++}disp_buffer_flags; ++ ++typedef enum ++{ ++ LAYER_MODE_BUFFER = 0, ++ LAYER_MODE_COLOR = 1, ++}disp_layer_mode; ++ ++typedef enum ++{ ++ DISP_SCAN_PROGRESSIVE = 0,//non interlace ++ DISP_SCAN_INTERLACED_ODD_FLD_FIRST = 1 << 0,//interlace ,odd field first ++ DISP_SCAN_INTERLACED_EVEN_FLD_FIRST = 1 << 1,//interlace,even field first ++}disp_scan_flags; ++ ++typedef struct ++{ ++ unsigned int type; ++ unsigned int mode; ++}disp_output; ++ ++typedef struct ++{ ++ long long x; ++ long long y; ++ long long width; ++ long long height; ++}disp_rect64; ++ ++typedef struct ++{ ++ unsigned long long addr[3]; /* address of frame buffer, ++ single addr for interleaved fomart, ++ double addr for semi-planar fomart ++ triple addr for planar format */ ++ disp_rectsz size[3]; //size for 3 component,unit: pixels ++ unsigned int align[3]; //align for 3 comonent,unit: bytes(align=2^n,i.e. 1/2/4/8/16/32..) ++ disp_pixel_format format; ++ disp_color_space color_space; //color space ++ unsigned int trd_right_addr[3];/* right address of 3d fb, ++ used when in frame packing 3d mode */ ++ bool pre_multiply; //true: pre-multiply fb ++ disp_rect64 crop; //crop rectangle boundaries ++ disp_buffer_flags flags; //indicate stereo or non-stereo buffer ++ disp_scan_flags scan; //scan type & scan order ++}disp_fb_info; ++ ++typedef struct ++{ ++ disp_layer_mode mode; ++ unsigned char zorder; /*specifies the front-to-back ordering of the layers on the screen, ++ the top layer having the highest Z value ++ can't set zorder, but can get */ ++ unsigned char alpha_mode; //0: pixel alpha; 1: global alpha; 2: global pixel alpha ++ unsigned char alpha_value; //global alpha value ++ disp_rect screen_win; //display window on the screen ++ bool b_trd_out; //3d display ++ disp_3d_out_mode out_trd_mode;//3d display mode ++ union { ++ unsigned int color; //valid when LAYER_MODE_COLOR ++ disp_fb_info fb; //framebuffer, valid when LAYER_MODE_BUFFER ++ }; ++ ++ unsigned int id; /* frame id, can get the id of frame display currently ++ by DISP_LAYER_GET_FRAME_ID */ ++}disp_layer_info; ++ ++typedef struct ++{ ++ disp_layer_info info; ++ bool enable; ++ unsigned int channel; ++ unsigned int layer_id; ++}disp_layer_config; ++ ++typedef struct ++{ ++ disp_color ck_max; ++ disp_color ck_min; ++ unsigned int red_match_rule;//0/1:always match; 2:match if min<=color<=max; 3:match if color>max or colormax or colormax or colorLock(); ++} ++#endif ++ + bool CLinuxRendererGLES::IsGuiLayer() + { +- if (m_format == RENDER_FMT_BYPASS || m_format == RENDER_FMT_IMXMAP || m_format == RENDER_FMT_MEDIACODECSURFACE) ++ if (m_format == RENDER_FMT_BYPASS || m_format == RENDER_FMT_IMXMAP || m_format == RENDER_FMT_MEDIACODECSURFACE || m_format == RENDER_FMT_DISP2) + return false; + else + return true; +diff -Nur a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h codec/xbmc/cores/VideoRenderers/LinuxRendererGLES.h +--- a/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2016-04-17 14:05:15.000000000 +0200 ++++ codec/xbmc/cores/VideoRenderers/LinuxRendererGLES.h 2016-10-24 17:57:39.888848117 +0200 +@@ -45,6 +45,7 @@ + #ifdef HAS_IMXVPU + class CDVDVideoCodecIMXBuffer; + #endif ++class CCedarXBuffer; + typedef std::vector Features; + + +@@ -94,7 +95,8 @@ + RENDER_EGLIMG = 0x200, + RENDER_MEDIACODEC = 0x400, + RENDER_MEDIACODECSURFACE = 0x800, +- RENDER_IMXMAP = 0x1000 ++ RENDER_IMXMAP = 0x1000, ++ RENDER_DISP2 = 0x2000 + }; + + enum RenderQuality +@@ -177,6 +179,9 @@ + #ifdef HAS_IMXVPU + virtual void AddProcessor(CDVDVideoCodecIMXBuffer *codecinfo, int index); + #endif ++#ifdef HAS_CEDARX ++ virtual void AddProcessor(CCedarXBuffer *codecinfo, int index); ++#endif + + protected: + virtual void Render(DWORD flags, int index); +@@ -225,6 +230,10 @@ + void UploadIMXMAPTexture(int index); + void DeleteIMXMAPTexture(int index); + bool CreateIMXMAPTexture(int index); ++ ++ void UploadDisp2Texture(int index); ++ void DeleteDisp2Texture(int index); ++ bool CreateDisp2Texture(int index); + + void CalculateTextureSourceRects(int source, int num_planes); + +@@ -237,6 +246,7 @@ + void RenderCoreVideoRef(int index, int field); // CoreVideo reference + void RenderSurfaceTexture(int index, int field);// MediaCodec rendering using SurfaceTexture + void RenderIMXMAPTexture(int index, int field); // IMXMAP rendering ++ void RenderDisp2Texture(int index, int field); // Disp2 rendering + + CFrameBufferObject m_fbo; + +@@ -306,6 +316,9 @@ + #ifdef HAS_IMXVPU + CDVDVideoCodecIMXBuffer *IMXBuffer; + #endif ++#ifdef HAS_CEDARX ++ CCedarXBuffer *Disp2Buffer; ++#endif + }; + + typedef YUVBUFFER YUVBUFFERS[NUM_BUFFERS]; +diff -Nur a/xbmc/cores/VideoRenderers/RenderFormats.h codec/xbmc/cores/VideoRenderers/RenderFormats.h +--- a/xbmc/cores/VideoRenderers/RenderFormats.h 2016-04-17 14:05:15.000000000 +0200 ++++ codec/xbmc/cores/VideoRenderers/RenderFormats.h 2016-10-24 17:57:39.888848117 +0200 +@@ -43,6 +43,7 @@ + RENDER_FMT_MEDIACODECSURFACE, + RENDER_FMT_IMXMAP, + RENDER_FMT_MMAL, ++ RENDER_FMT_DISP2, + }; + + struct CRenderInfo +diff -Nur a/xbmc/cores/VideoRenderers/RenderManager.cpp codec/xbmc/cores/VideoRenderers/RenderManager.cpp +--- a/xbmc/cores/VideoRenderers/RenderManager.cpp 2016-04-17 14:05:15.000000000 +0200 ++++ codec/xbmc/cores/VideoRenderers/RenderManager.cpp 2016-10-24 17:57:39.888848117 +0200 +@@ -1029,6 +1029,10 @@ + else if(pic.format == RENDER_FMT_MMAL) + m_pRenderer->AddProcessor(pic.MMALBuffer, index); + #endif ++#ifdef HAS_CEDARX ++ else if(pic.format == RENDER_FMT_DISP2) ++ m_pRenderer->AddProcessor(pic.Disp2Buffer, index); ++#endif + + m_pRenderer->ReleaseImage(index, false); + +diff -Nur a/xbmc/settings/Settings.cpp codec/xbmc/settings/Settings.cpp +--- a/xbmc/settings/Settings.cpp 2016-08-03 19:58:43.960146875 +0200 ++++ codec/xbmc/settings/Settings.cpp 2016-10-24 17:57:39.892181451 +0200 +@@ -812,6 +812,9 @@ + #elif defined(HAS_IMXVPU) + if (CFile::Exists(SETTINGS_XML_FOLDER "imx6.xml") && !Initialize(SETTINGS_XML_FOLDER "imx6.xml")) + CLog::Log(LOGFATAL, "Unable to load imx6-specific settings definitions"); ++#elif defined(HAS_CEDARX) ++ if (CFile::Exists(SETTINGS_XML_FOLDER "sunxi.xml") && !Initialize(SETTINGS_XML_FOLDER "sunxi.xml")) ++ CLog::Log(LOGFATAL, "Unable to load sunxi-specific settings definitions"); + #elif defined(TARGET_LINUX) + if (CFile::Exists(SETTINGS_XML_FOLDER "linux.xml") && !Initialize(SETTINGS_XML_FOLDER "linux.xml")) + CLog::Log(LOGFATAL, "Unable to load linux-specific settings definitions"); +diff -Nur a/xbmc/settings/VideoSettings.h codec/xbmc/settings/VideoSettings.h +--- a/xbmc/settings/VideoSettings.h 2016-04-17 14:05:15.000000000 +0200 ++++ codec/xbmc/settings/VideoSettings.h 2016-10-24 17:57:39.892181451 +0200 +@@ -74,6 +74,8 @@ + + VS_INTERLACEMETHOD_IMX_FASTMOTION = 29, + VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE = 30, ++ ++ VS_INTERLACEMETHOD_DISP2_BOB = 31, + + VS_INTERLACEMETHOD_MAX // do not use and keep as last enum value. + }; +diff -Nur a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp codec/xbmc/video/dialogs/GUIDialogVideoSettings.cpp +--- a/xbmc/video/dialogs/GUIDialogVideoSettings.cpp 2016-04-17 14:05:15.000000000 +0200 ++++ codec/xbmc/video/dialogs/GUIDialogVideoSettings.cpp 2016-10-24 17:57:39.892181451 +0200 +@@ -274,6 +274,7 @@ + entries.push_back(std::make_pair(16333, VS_INTERLACEMETHOD_MMAL_BOB_HALF)); + entries.push_back(std::make_pair(16334, VS_INTERLACEMETHOD_IMX_FASTMOTION)); + entries.push_back(std::make_pair(16335, VS_INTERLACEMETHOD_IMX_FASTMOTION_DOUBLE)); ++ entries.push_back(std::make_pair(16336, VS_INTERLACEMETHOD_DISP2_BOB)); + + /* remove unsupported methods */ + for (StaticIntegerSettingOptions::iterator it = entries.begin(); it != entries.end(); ) diff --git a/projects/H3/patches/kodi/kodi-006-disable-autoscrolling-on-screensaver.patch b/projects/H3/patches/kodi/kodi-006-disable-autoscrolling-on-screensaver.patch new file mode 100644 index 00000000000..d1c2c1c3751 --- /dev/null +++ b/projects/H3/patches/kodi/kodi-006-disable-autoscrolling-on-screensaver.patch @@ -0,0 +1,135 @@ +From 88a462e45db8f7c36e8a85203adc87ca5200aff0 Mon Sep 17 00:00:00 2001 +From: anaconda +Date: Thu, 11 Sep 2014 21:30:43 +0200 +Subject: [PATCH] Disable autoscrolling while on screensaver and while opening + streams. + +--- + xbmc/Application.cpp | 10 ++++++++++ + xbmc/Application.h | 2 ++ + xbmc/guilib/GUIFadeLabelControl.cpp | 4 +++- + xbmc/guilib/GUIFont.cpp | 4 ++++ + xbmc/guilib/GUILabel.cpp | 4 +++- + xbmc/guilib/GUITextBox.cpp | 3 ++- + 6 files changed, 24 insertions(+), 3 deletions(-) + +diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp +index 0e3d6da..b9460d5 100644 +--- a/xbmc/Application.cpp ++++ b/xbmc/Application.cpp +@@ -5296,3 +5296,13 @@ bool CApplication::NotifyActionListeners(const CAction &action) const + + return false; + } ++ ++bool CApplication::ScreenSaverDisablesAutoScrolling() ++{ ++ bool onBlackDimScreenSaver = IsInScreenSaver() && m_screenSaver && ++ (m_screenSaver->ID() == "screensaver.xbmc.builtin.black" || ++ m_screenSaver->ID() == "screensaver.xbmc.builtin.dim"); ++ bool openingStreams = m_pPlayer->IsPlaying() && g_windowManager.IsWindowActive(WINDOW_DIALOG_BUSY); ++ ++ return onBlackDimScreenSaver || openingStreams; ++} +diff --git a/xbmc/Application.h b/xbmc/Application.h +index d7e5eee..a34ed98 100644 +--- a/xbmc/Application.h ++++ b/xbmc/Application.h +@@ -390,6 +390,8 @@ public: + */ + void UnregisterActionListener(IActionListener *listener); + ++ bool ScreenSaverDisablesAutoScrolling(); ++ + protected: + virtual bool OnSettingsSaving() const override; + +diff --git a/xbmc/guilib/GUIFadeLabelControl.cpp b/xbmc/guilib/GUIFadeLabelControl.cpp +index ebd435e..97efc8a 100644 +--- a/xbmc/guilib/GUIFadeLabelControl.cpp ++++ b/xbmc/guilib/GUIFadeLabelControl.cpp +@@ -20,6 +20,8 @@ + + #include "GUIFadeLabelControl.h" + ++#include "Application.h" ++ + CGUIFadeLabelControl::CGUIFadeLabelControl(int parentID, int controlID, float posX, float posY, float width, float height, const CLabelInfo& labelInfo, bool scrollOut, unsigned int timeToDelayAtEnd, bool resetOnLabelChange, bool randomized) + : CGUIControl(parentID, controlID, posX, posY, width, height), m_label(labelInfo), m_scrollInfo(50, labelInfo.offsetX, labelInfo.scrollSpeed) + , m_textLayout(labelInfo.font, false) +@@ -105,7 +107,7 @@ void CGUIFadeLabelControl::Process(unsigned int currentTime, CDirtyRegionList &d + m_lastLabel = m_currentLabel; + } + +- if (m_infoLabels.size() > 1 || !m_shortText) ++ if ((m_infoLabels.size() > 1 || !m_shortText) && !g_application.ScreenSaverDisablesAutoScrolling()) + { // have scrolling text + bool moveToNextLabel = false; + if (!m_scrollOut) +diff --git a/xbmc/guilib/GUIFont.cpp b/xbmc/guilib/GUIFont.cpp +index 7f11089..1192b74 100644 +--- a/xbmc/guilib/GUIFont.cpp ++++ b/xbmc/guilib/GUIFont.cpp +@@ -22,6 +22,7 @@ + #include "GUIFontTTF.h" + #include "GraphicContext.h" + ++#include "Application.h" + #include "threads/SingleLock.h" + #include "utils/TimeUtils.h" + #include "utils/MathUtils.h" +@@ -128,6 +129,9 @@ bool CGUIFont::UpdateScrollInfo(const vecText &text, CScrollInfo &scrollInfo) + // If the string is smaller than the viewport, then it may be plotted even + // more times than that. + // ++ if (g_application.ScreenSaverDisablesAutoScrolling()) ++ return false; ++ + if (scrollInfo.waitTime) + { + scrollInfo.waitTime--; +diff --git a/xbmc/guilib/GUILabel.cpp b/xbmc/guilib/GUILabel.cpp +index 759ac09..bed6ad2 100644 +--- a/xbmc/guilib/GUILabel.cpp ++++ b/xbmc/guilib/GUILabel.cpp +@@ -21,6 +21,8 @@ + #include "GUILabel.h" + #include + ++#include "Application.h" ++ + CGUILabel::CGUILabel(float posX, float posY, float width, float height, const CLabelInfo& labelInfo, CGUILabel::OVER_FLOW overflow) + : m_label(labelInfo) + , m_textLayout(labelInfo.font, overflow == OVER_FLOW_WRAP, height) +@@ -104,7 +106,7 @@ void CGUILabel::Render() + color_t color = GetColor(); + bool renderSolid = (m_color == COLOR_DISABLED); + bool overFlows = (m_renderRect.Width() + 0.5f < m_textLayout.GetTextWidth()); // 0.5f to deal with floating point rounding issues +- if (overFlows && m_scrolling && !renderSolid) ++ if (overFlows && m_scrolling && !renderSolid && !g_application.ScreenSaverDisablesAutoScrolling()) + m_textLayout.RenderScrolling(m_renderRect.x1, m_renderRect.y1, m_label.angle, color, m_label.shadowColor, 0, m_renderRect.Width(), m_scrollInfo); + else + { +diff --git a/xbmc/guilib/GUITextBox.cpp b/xbmc/guilib/GUITextBox.cpp +index d7bc1c5..ac76629 100644 +--- a/xbmc/guilib/GUITextBox.cpp ++++ b/xbmc/guilib/GUITextBox.cpp +@@ -24,6 +24,7 @@ + #include "utils/MathUtils.h" + #include "utils/StringUtils.h" + #include "guiinfo/GUIInfoLabels.h" ++#include "Application.h" + + #include + +@@ -133,7 +134,7 @@ void CGUITextBox::Process(unsigned int currentTime, CDirtyRegionList &dirtyregio + // update our auto-scrolling as necessary + if (m_autoScrollTime && m_lines.size() > m_itemsPerPage) + { +- if (!m_autoScrollCondition || m_autoScrollCondition->Get()) ++ if ((!m_autoScrollCondition || m_autoScrollCondition->Get()) && !g_application.ScreenSaverDisablesAutoScrolling()) + { + if (m_lastRenderTime) + m_autoScrollDelayTime += currentTime - m_lastRenderTime; +-- +2.1.0 diff --git a/projects/H3/patches/linux/linux-001-block-cgroups-kconfig-build-bits-for-BFQ-v7r8-3.4.patch b/projects/H3/patches/linux/linux-001-block-cgroups-kconfig-build-bits-for-BFQ-v7r8-3.4.patch new file mode 100644 index 00000000000..65ddb41afee --- /dev/null +++ b/projects/H3/patches/linux/linux-001-block-cgroups-kconfig-build-bits-for-BFQ-v7r8-3.4.patch @@ -0,0 +1,104 @@ +From f02619fbce05cb82da19a48216b9ec67139112db Mon Sep 17 00:00:00 2001 +From: Arianna Avanzini +Date: Mon, 27 Jan 2014 23:50:08 +0100 +Subject: [PATCH 1/3] block: cgroups, kconfig, build bits for BFQ-v7r8-3.4 + +Update Kconfig.iosched and do the related Makefile changes to include +kernel configuration options for BFQ. Also add the bfqio controller +to the cgroups subsystem. + +Signed-off-by: Paolo Valente +Signed-off-by: Arianna Avanzini +--- + block/Kconfig.iosched | 33 +++++++++++++++++++++++++++++++++ + block/Makefile | 1 + + include/linux/cgroup_subsys.h | 6 ++++++ + 3 files changed, 40 insertions(+) + +diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched +index 3199b76..2b6d805 100644 +--- a/block/Kconfig.iosched ++++ b/block/Kconfig.iosched +@@ -43,6 +43,28 @@ config CFQ_GROUP_IOSCHED + ---help--- + Enable group IO scheduling in CFQ. + ++config IOSCHED_BFQ ++ tristate "BFQ I/O scheduler" ++ depends on EXPERIMENTAL ++ default n ++ ---help--- ++ The BFQ I/O scheduler tries to distribute bandwidth among ++ all processes according to their weights. ++ It aims at distributing the bandwidth as desired, independently of ++ the disk parameters and with any workload. It also tries to ++ guarantee low latency to interactive and soft real-time ++ applications. If compiled built-in (saying Y here), BFQ can ++ be configured to support hierarchical scheduling. ++ ++config CGROUP_BFQIO ++ bool "BFQ hierarchical scheduling support" ++ depends on CGROUPS && IOSCHED_BFQ=y ++ default n ++ ---help--- ++ Enable hierarchical scheduling in BFQ, using the cgroups ++ filesystem interface. The name of the subsystem will be ++ bfqio. ++ + choice + prompt "Default I/O scheduler" + default DEFAULT_CFQ +@@ -56,6 +78,16 @@ choice + config DEFAULT_CFQ + bool "CFQ" if IOSCHED_CFQ=y + ++ config DEFAULT_BFQ ++ bool "BFQ" if IOSCHED_BFQ=y ++ help ++ Selects BFQ as the default I/O scheduler which will be ++ used by default for all block devices. ++ The BFQ I/O scheduler aims at distributing the bandwidth ++ as desired, independently of the disk parameters and with ++ any workload. It also tries to guarantee low latency to ++ interactive and soft real-time applications. ++ + config DEFAULT_NOOP + bool "No-op" + +@@ -65,6 +97,7 @@ config DEFAULT_IOSCHED + string + default "deadline" if DEFAULT_DEADLINE + default "cfq" if DEFAULT_CFQ ++ default "bfq" if DEFAULT_BFQ + default "noop" if DEFAULT_NOOP + + endmenu +diff --git a/block/Makefile b/block/Makefile +index 39b76ba..c0d20fa 100644 +--- a/block/Makefile ++++ b/block/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o + obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o + obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o + obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o ++obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o + + obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o + obj-$(CONFIG_BLK_DEV_INTEGRITY) += blk-integrity.o +diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h +index 0bd390c..cbf22b1 100644 +--- a/include/linux/cgroup_subsys.h ++++ b/include/linux/cgroup_subsys.h +@@ -72,3 +72,9 @@ SUBSYS(net_prio) + #endif + + /* */ ++ ++#ifdef CONFIG_CGROUP_BFQIO ++SUBSYS(bfqio) ++#endif ++ ++/* */ +-- +2.1.4 + diff --git a/projects/H3/patches/linux/linux-002-block-introduce-the-BFQ-v7r8-I-O-sched-for-3.4.patch b/projects/H3/patches/linux/linux-002-block-introduce-the-BFQ-v7r8-I-O-sched-for-3.4.patch new file mode 100644 index 00000000000..a01e8b4fe1f --- /dev/null +++ b/projects/H3/patches/linux/linux-002-block-introduce-the-BFQ-v7r8-I-O-sched-for-3.4.patch @@ -0,0 +1,6912 @@ +From 5f51265c87917d7c1e46f7be0942f855792a596f Mon Sep 17 00:00:00 2001 +From: Paolo Valente +Date: Thu, 9 May 2013 19:10:02 +0200 +Subject: [PATCH 2/3] block: introduce the BFQ-v7r8 I/O sched for 3.4 + +Add the BFQ-v7r8 I/O scheduler to 3.4. +The general structure is borrowed from CFQ, as much of the code for +handling I/O contexts. Over time, several useful features have been +ported from CFQ as well (details in the changelog in README.BFQ). A +(bfq_)queue is associated to each task doing I/O on a device, and each +time a scheduling decision has to be made a queue is selected and served +until it expires. + + - Slices are given in the service domain: tasks are assigned + budgets, measured in number of sectors. Once got the disk, a task + must however consume its assigned budget within a configurable + maximum time (by default, the maximum possible value of the + budgets is automatically computed to comply with this timeout). + This allows the desired latency vs "throughput boosting" tradeoff + to be set. + + - Budgets are scheduled according to a variant of WF2Q+, implemented + using an augmented rb-tree to take eligibility into account while + preserving an O(log N) overall complexity. + + - A low-latency tunable is provided; if enabled, both interactive + and soft real-time applications are guaranteed a very low latency. + + - Latency guarantees are preserved also in the presence of NCQ. + + - Also with flash-based devices, a high throughput is achieved + while still preserving latency guarantees. + + - BFQ features Early Queue Merge (EQM), a sort of fusion of the + cooperating-queue-merging and the preemption mechanisms present + in CFQ. EQM is in fact a unified mechanism that tries to get a + sequential read pattern, and hence a high throughput, with any + set of processes performing interleaved I/O over a contiguous + sequence of sectors. + + - BFQ supports full hierarchical scheduling, exporting a cgroups + interface. Since each node has a full scheduler, each group can + be assigned its own weight. + + - If the cgroups interface is not used, only I/O priorities can be + assigned to processes, with ioprio values mapped to weights + with the relation weight = IOPRIO_BE_NR - ioprio. + + - ioprio classes are served in strict priority order, i.e., lower + priority queues are not served as long as there are higher + priority queues. Among queues in the same class the bandwidth is + distributed in proportion to the weight of each queue. A very + thin extra bandwidth is however guaranteed to the Idle class, to + prevent it from starving. + +Signed-off-by: Paolo Valente +Signed-off-by: Arianna Avanzini +--- + block/bfq-cgroup.c | 908 ++++++++++++ + block/bfq-ioc.c | 36 + + block/bfq-iosched.c | 3887 +++++++++++++++++++++++++++++++++++++++++++++++++++ + block/bfq-sched.c | 1208 ++++++++++++++++ + block/bfq.h | 770 ++++++++++ + 5 files changed, 6809 insertions(+) + create mode 100644 block/bfq-cgroup.c + create mode 100644 block/bfq-ioc.c + create mode 100644 block/bfq-iosched.c + create mode 100644 block/bfq-sched.c + create mode 100644 block/bfq.h + +diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c +new file mode 100644 +index 0000000..8399c92 +--- /dev/null ++++ b/block/bfq-cgroup.c +@@ -0,0 +1,908 @@ ++/* ++ * BFQ: CGROUPS support. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ */ ++ ++#ifdef CONFIG_CGROUP_BFQIO ++static struct bfqio_cgroup bfqio_root_cgroup = { ++ .weight = BFQ_DEFAULT_GRP_WEIGHT, ++ .ioprio = BFQ_DEFAULT_GRP_IOPRIO, ++ .ioprio_class = BFQ_DEFAULT_GRP_CLASS, ++}; ++ ++static inline void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ entity->ioprio = entity->new_ioprio; ++ entity->ioprio_class = entity->new_ioprio_class; ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static struct bfqio_cgroup *cgroup_to_bfqio(struct cgroup *cgroup) ++{ ++ return container_of(cgroup_subsys_state(cgroup, bfqio_subsys_id), ++ struct bfqio_cgroup, css); ++} ++ ++/* ++ * Search the bfq_group for bfqd into the hash table (by now only a list) ++ * of bgrp. Must be called under rcu_read_lock(). ++ */ ++static struct bfq_group *bfqio_lookup_group(struct bfqio_cgroup *bgrp, ++ struct bfq_data *bfqd) ++{ ++ struct bfq_group *bfqg; ++ struct hlist_node *n; ++ void *key; ++ ++ hlist_for_each_entry_rcu(bfqg, n, &bgrp->group_data, group_node) { ++ key = rcu_dereference(bfqg->bfqd); ++ if (key == bfqd) ++ return bfqg; ++ } ++ ++ return NULL; ++} ++ ++static inline void bfq_group_init_entity(struct bfqio_cgroup *bgrp, ++ struct bfq_group *bfqg) ++{ ++ struct bfq_entity *entity = &bfqg->entity; ++ ++ /* ++ * If the weight of the entity has never been set via the sysfs ++ * interface, then bgrp->weight == 0. In this case we initialize ++ * the weight from the current ioprio value. Otherwise, the group ++ * weight, if set, has priority over the ioprio value. ++ */ ++ if (bgrp->weight == 0) { ++ entity->new_weight = bfq_ioprio_to_weight(bgrp->ioprio); ++ entity->new_ioprio = bgrp->ioprio; ++ } else { ++ if (bgrp->weight < BFQ_MIN_WEIGHT || ++ bgrp->weight > BFQ_MAX_WEIGHT) { ++ printk(KERN_CRIT "bfq_group_init_entity: " ++ "bgrp->weight %d\n", bgrp->weight); ++ BUG(); ++ } ++ entity->new_weight = bgrp->weight; ++ entity->new_ioprio = bfq_weight_to_ioprio(bgrp->weight); ++ } ++ entity->orig_weight = entity->weight = entity->new_weight; ++ entity->ioprio = entity->new_ioprio; ++ entity->ioprio_class = entity->new_ioprio_class = bgrp->ioprio_class; ++ entity->my_sched_data = &bfqg->sched_data; ++ bfqg->active_entities = 0; ++} ++ ++static inline void bfq_group_set_parent(struct bfq_group *bfqg, ++ struct bfq_group *parent) ++{ ++ struct bfq_entity *entity; ++ ++ BUG_ON(parent == NULL); ++ BUG_ON(bfqg == NULL); ++ ++ entity = &bfqg->entity; ++ entity->parent = parent->my_entity; ++ entity->sched_data = &parent->sched_data; ++} ++ ++/** ++ * bfq_group_chain_alloc - allocate a chain of groups. ++ * @bfqd: queue descriptor. ++ * @cgroup: the leaf cgroup this chain starts from. ++ * ++ * Allocate a chain of groups starting from the one belonging to ++ * @cgroup up to the root cgroup. Stop if a cgroup on the chain ++ * to the root has already an allocated group on @bfqd. ++ */ ++static struct bfq_group *bfq_group_chain_alloc(struct bfq_data *bfqd, ++ struct cgroup *cgroup) ++{ ++ struct bfqio_cgroup *bgrp; ++ struct bfq_group *bfqg, *prev = NULL, *leaf = NULL; ++ ++ for (; cgroup != NULL; cgroup = cgroup->parent) { ++ bgrp = cgroup_to_bfqio(cgroup); ++ ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ if (bfqg != NULL) { ++ /* ++ * All the cgroups in the path from there to the ++ * root must have a bfq_group for bfqd, so we don't ++ * need any more allocations. ++ */ ++ break; ++ } ++ ++ bfqg = kzalloc(sizeof(*bfqg), GFP_ATOMIC); ++ if (bfqg == NULL) ++ goto cleanup; ++ ++ bfq_group_init_entity(bgrp, bfqg); ++ bfqg->my_entity = &bfqg->entity; ++ ++ if (leaf == NULL) { ++ leaf = bfqg; ++ prev = leaf; ++ } else { ++ bfq_group_set_parent(prev, bfqg); ++ /* ++ * Build a list of allocated nodes using the bfqd ++ * filed, that is still unused and will be ++ * initialized only after the node will be ++ * connected. ++ */ ++ prev->bfqd = bfqg; ++ prev = bfqg; ++ } ++ } ++ ++ return leaf; ++ ++cleanup: ++ while (leaf != NULL) { ++ prev = leaf; ++ leaf = leaf->bfqd; ++ kfree(prev); ++ } ++ ++ return NULL; ++} ++ ++/** ++ * bfq_group_chain_link - link an allocated group chain to a cgroup ++ * hierarchy. ++ * @bfqd: the queue descriptor. ++ * @cgroup: the leaf cgroup to start from. ++ * @leaf: the leaf group (to be associated to @cgroup). ++ * ++ * Try to link a chain of groups to a cgroup hierarchy, connecting the ++ * nodes bottom-up, so we can be sure that when we find a cgroup in the ++ * hierarchy that already as a group associated to @bfqd all the nodes ++ * in the path to the root cgroup have one too. ++ * ++ * On locking: the queue lock protects the hierarchy (there is a hierarchy ++ * per device) while the bfqio_cgroup lock protects the list of groups ++ * belonging to the same cgroup. ++ */ ++static void bfq_group_chain_link(struct bfq_data *bfqd, struct cgroup *cgroup, ++ struct bfq_group *leaf) ++{ ++ struct bfqio_cgroup *bgrp; ++ struct bfq_group *bfqg, *next, *prev = NULL; ++ unsigned long flags; ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ ++ for (; cgroup != NULL && leaf != NULL; cgroup = cgroup->parent) { ++ bgrp = cgroup_to_bfqio(cgroup); ++ next = leaf->bfqd; ++ ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ BUG_ON(bfqg != NULL); ++ ++ spin_lock_irqsave(&bgrp->lock, flags); ++ ++ rcu_assign_pointer(leaf->bfqd, bfqd); ++ hlist_add_head_rcu(&leaf->group_node, &bgrp->group_data); ++ hlist_add_head(&leaf->bfqd_node, &bfqd->group_list); ++ ++ spin_unlock_irqrestore(&bgrp->lock, flags); ++ ++ prev = leaf; ++ leaf = next; ++ } ++ ++ BUG_ON(cgroup == NULL && leaf != NULL); ++ if (cgroup != NULL && prev != NULL) { ++ bgrp = cgroup_to_bfqio(cgroup); ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ bfq_group_set_parent(prev, bfqg); ++ } ++} ++ ++/** ++ * bfq_find_alloc_group - return the group associated to @bfqd in @cgroup. ++ * @bfqd: queue descriptor. ++ * @cgroup: cgroup being searched for. ++ * ++ * Return a group associated to @bfqd in @cgroup, allocating one if ++ * necessary. When a group is returned all the cgroups in the path ++ * to the root have a group associated to @bfqd. ++ * ++ * If the allocation fails, return the root group: this breaks guarantees ++ * but is a safe fallback. If this loss becomes a problem it can be ++ * mitigated using the equivalent weight (given by the product of the ++ * weights of the groups in the path from @group to the root) in the ++ * root scheduler. ++ * ++ * We allocate all the missing nodes in the path from the leaf cgroup ++ * to the root and we connect the nodes only after all the allocations ++ * have been successful. ++ */ ++static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, ++ struct cgroup *cgroup) ++{ ++ struct bfqio_cgroup *bgrp = cgroup_to_bfqio(cgroup); ++ struct bfq_group *bfqg; ++ ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ if (bfqg != NULL) ++ return bfqg; ++ ++ bfqg = bfq_group_chain_alloc(bfqd, cgroup); ++ if (bfqg != NULL) ++ bfq_group_chain_link(bfqd, cgroup, bfqg); ++ else ++ bfqg = bfqd->root_group; ++ ++ return bfqg; ++} ++ ++/** ++ * bfq_bfqq_move - migrate @bfqq to @bfqg. ++ * @bfqd: queue descriptor. ++ * @bfqq: the queue to move. ++ * @entity: @bfqq's entity. ++ * @bfqg: the group to move to. ++ * ++ * Move @bfqq to @bfqg, deactivating it from its old group and reactivating ++ * it on the new one. Avoid putting the entity on the old group idle tree. ++ * ++ * Must be called under the queue lock; the cgroup owning @bfqg must ++ * not disappear (by now this just means that we are called under ++ * rcu_read_lock()). ++ */ ++static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct bfq_entity *entity, struct bfq_group *bfqg) ++{ ++ int busy, resume; ++ ++ busy = bfq_bfqq_busy(bfqq); ++ resume = !RB_EMPTY_ROOT(&bfqq->sort_list); ++ ++ BUG_ON(resume && !entity->on_st); ++ BUG_ON(busy && !resume && entity->on_st && ++ bfqq != bfqd->in_service_queue); ++ ++ if (busy) { ++ BUG_ON(atomic_read(&bfqq->ref) < 2); ++ ++ if (!resume) ++ bfq_del_bfqq_busy(bfqd, bfqq, 0); ++ else ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ } else if (entity->on_st) ++ bfq_put_idle_entity(bfq_entity_service_tree(entity), entity); ++ ++ /* ++ * Here we use a reference to bfqg. We don't need a refcounter ++ * as the cgroup reference will not be dropped, so that its ++ * destroy() callback will not be invoked. ++ */ ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++ ++ if (busy && resume) ++ bfq_activate_bfqq(bfqd, bfqq); ++ ++ if (bfqd->in_service_queue == NULL && !bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++} ++ ++/** ++ * __bfq_bic_change_cgroup - move @bic to @cgroup. ++ * @bfqd: the queue descriptor. ++ * @bic: the bic to move. ++ * @cgroup: the cgroup to move to. ++ * ++ * Move bic to cgroup, assuming that bfqd->queue is locked; the caller ++ * has to make sure that the reference to cgroup is valid across the call. ++ * ++ * NOTE: an alternative approach might have been to store the current ++ * cgroup in bfqq and getting a reference to it, reducing the lookup ++ * time here, at the price of slightly more complex code. ++ */ ++static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic, ++ struct cgroup *cgroup) ++{ ++ struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); ++ struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); ++ struct bfq_entity *entity; ++ struct bfq_group *bfqg; ++ struct bfqio_cgroup *bgrp; ++ ++ bgrp = cgroup_to_bfqio(cgroup); ++ ++ bfqg = bfq_find_alloc_group(bfqd, cgroup); ++ if (async_bfqq != NULL) { ++ entity = &async_bfqq->entity; ++ ++ if (entity->sched_data != &bfqg->sched_data) { ++ bic_set_bfqq(bic, NULL, 0); ++ bfq_log_bfqq(bfqd, async_bfqq, ++ "bic_change_group: %p %d", ++ async_bfqq, atomic_read(&async_bfqq->ref)); ++ bfq_put_queue(async_bfqq); ++ } ++ } ++ ++ if (sync_bfqq != NULL) { ++ entity = &sync_bfqq->entity; ++ if (entity->sched_data != &bfqg->sched_data) ++ bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg); ++ } ++ ++ return bfqg; ++} ++ ++/** ++ * bfq_bic_change_cgroup - move @bic to @cgroup. ++ * @bic: the bic being migrated. ++ * @cgroup: the destination cgroup. ++ * ++ * When the task owning @bic is moved to @cgroup, @bic is immediately ++ * moved into its new parent group. ++ */ ++static void bfq_bic_change_cgroup(struct bfq_io_cq *bic, ++ struct cgroup *cgroup) ++{ ++ struct bfq_data *bfqd; ++ unsigned long uninitialized_var(flags); ++ ++ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), ++ &flags); ++ if (bfqd != NULL) { ++ __bfq_bic_change_cgroup(bfqd, bic, cgroup); ++ bfq_put_bfqd_unlock(bfqd, &flags); ++ } ++} ++ ++/** ++ * bfq_bic_update_cgroup - update the cgroup of @bic. ++ * @bic: the @bic to update. ++ * ++ * Make sure that @bic is enqueued in the cgroup of the current task. ++ * We need this in addition to moving bics during the cgroup attach ++ * phase because the task owning @bic could be at its first disk ++ * access or we may end up in the root cgroup as the result of a ++ * memory allocation failure and here we try to move to the right ++ * group. ++ * ++ * Must be called under the queue lock. It is safe to use the returned ++ * value even after the rcu_read_unlock() as the migration/destruction ++ * paths act under the queue lock too. IOW it is impossible to race with ++ * group migration/destruction and end up with an invalid group as: ++ * a) here cgroup has not yet been destroyed, nor its destroy callback ++ * has started execution, as current holds a reference to it, ++ * b) if it is destroyed after rcu_read_unlock() [after current is ++ * migrated to a different cgroup] its attach() callback will have ++ * taken care of remove all the references to the old cgroup data. ++ */ ++static struct bfq_group *bfq_bic_update_cgroup(struct bfq_io_cq *bic) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ struct bfq_group *bfqg; ++ struct cgroup *cgroup; ++ ++ BUG_ON(bfqd == NULL); ++ ++ rcu_read_lock(); ++ cgroup = task_cgroup(current, bfqio_subsys_id); ++ bfqg = __bfq_bic_change_cgroup(bfqd, bic, cgroup); ++ rcu_read_unlock(); ++ ++ return bfqg; ++} ++ ++/** ++ * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st. ++ * @st: the service tree being flushed. ++ */ ++static inline void bfq_flush_idle_tree(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entity = st->first_idle; ++ ++ for (; entity != NULL; entity = st->first_idle) ++ __bfq_deactivate_entity(entity, 0); ++} ++ ++/** ++ * bfq_reparent_leaf_entity - move leaf entity to the root_group. ++ * @bfqd: the device data structure with the root group. ++ * @entity: the entity to move. ++ */ ++static inline void bfq_reparent_leaf_entity(struct bfq_data *bfqd, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ BUG_ON(bfqq == NULL); ++ bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group); ++ return; ++} ++ ++/** ++ * bfq_reparent_active_entities - move to the root group all active ++ * entities. ++ * @bfqd: the device data structure with the root group. ++ * @bfqg: the group to move from. ++ * @st: the service tree with the entities. ++ * ++ * Needs queue_lock to be taken and reference to be valid over the call. ++ */ ++static inline void bfq_reparent_active_entities(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ struct bfq_service_tree *st) ++{ ++ struct rb_root *active = &st->active; ++ struct bfq_entity *entity = NULL; ++ ++ if (!RB_EMPTY_ROOT(&st->active)) ++ entity = bfq_entity_of(rb_first(active)); ++ ++ for (; entity != NULL; entity = bfq_entity_of(rb_first(active))) ++ bfq_reparent_leaf_entity(bfqd, entity); ++ ++ if (bfqg->sched_data.in_service_entity != NULL) ++ bfq_reparent_leaf_entity(bfqd, ++ bfqg->sched_data.in_service_entity); ++ ++ return; ++} ++ ++/** ++ * bfq_destroy_group - destroy @bfqg. ++ * @bgrp: the bfqio_cgroup containing @bfqg. ++ * @bfqg: the group being destroyed. ++ * ++ * Destroy @bfqg, making sure that it is not referenced from its parent. ++ */ ++static void bfq_destroy_group(struct bfqio_cgroup *bgrp, struct bfq_group *bfqg) ++{ ++ struct bfq_data *bfqd; ++ struct bfq_service_tree *st; ++ struct bfq_entity *entity = bfqg->my_entity; ++ unsigned long uninitialized_var(flags); ++ int i; ++ ++ hlist_del(&bfqg->group_node); ++ ++ /* ++ * Empty all service_trees belonging to this group before ++ * deactivating the group itself. ++ */ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) { ++ st = bfqg->sched_data.service_tree + i; ++ ++ /* ++ * The idle tree may still contain bfq_queues belonging ++ * to exited task because they never migrated to a different ++ * cgroup from the one being destroyed now. No one else ++ * can access them so it's safe to act without any lock. ++ */ ++ bfq_flush_idle_tree(st); ++ ++ /* ++ * It may happen that some queues are still active ++ * (busy) upon group destruction (if the corresponding ++ * processes have been forced to terminate). We move ++ * all the leaf entities corresponding to these queues ++ * to the root_group. ++ * Also, it may happen that the group has an entity ++ * in service, which is disconnected from the active ++ * tree: it must be moved, too. ++ * There is no need to put the sync queues, as the ++ * scheduler has taken no reference. ++ */ ++ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); ++ if (bfqd != NULL) { ++ bfq_reparent_active_entities(bfqd, bfqg, st); ++ bfq_put_bfqd_unlock(bfqd, &flags); ++ } ++ BUG_ON(!RB_EMPTY_ROOT(&st->active)); ++ BUG_ON(!RB_EMPTY_ROOT(&st->idle)); ++ } ++ BUG_ON(bfqg->sched_data.next_in_service != NULL); ++ BUG_ON(bfqg->sched_data.in_service_entity != NULL); ++ ++ /* ++ * We may race with device destruction, take extra care when ++ * dereferencing bfqg->bfqd. ++ */ ++ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); ++ if (bfqd != NULL) { ++ hlist_del(&bfqg->bfqd_node); ++ __bfq_deactivate_entity(entity, 0); ++ bfq_put_async_queues(bfqd, bfqg); ++ bfq_put_bfqd_unlock(bfqd, &flags); ++ } ++ BUG_ON(entity->tree != NULL); ++ ++ /* ++ * No need to defer the kfree() to the end of the RCU grace ++ * period: we are called from the destroy() callback of our ++ * cgroup, so we can be sure that no one is a) still using ++ * this cgroup or b) doing lookups in it. ++ */ ++ kfree(bfqg); ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ struct hlist_node *pos, *n; ++ struct bfq_group *bfqg; ++ ++ hlist_for_each_entry_safe(bfqg, pos, n, &bfqd->group_list, bfqd_node) ++ bfq_end_wr_async_queues(bfqd, bfqg); ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++/** ++ * bfq_disconnect_groups - disconnect @bfqd from all its groups. ++ * @bfqd: the device descriptor being exited. ++ * ++ * When the device exits we just make sure that no lookup can return ++ * the now unused group structures. They will be deallocated on cgroup ++ * destruction. ++ */ ++static void bfq_disconnect_groups(struct bfq_data *bfqd) ++{ ++ struct hlist_node *pos, *n; ++ struct bfq_group *bfqg; ++ ++ bfq_log(bfqd, "disconnect_groups beginning"); ++ hlist_for_each_entry_safe(bfqg, pos, n, &bfqd->group_list, bfqd_node) { ++ hlist_del(&bfqg->bfqd_node); ++ ++ __bfq_deactivate_entity(bfqg->my_entity, 0); ++ ++ /* ++ * Don't remove from the group hash, just set an ++ * invalid key. No lookups can race with the ++ * assignment as bfqd is being destroyed; this ++ * implies also that new elements cannot be added ++ * to the list. ++ */ ++ rcu_assign_pointer(bfqg->bfqd, NULL); ++ ++ bfq_log(bfqd, "disconnect_groups: put async for group %p", ++ bfqg); ++ bfq_put_async_queues(bfqd, bfqg); ++ } ++} ++ ++static inline void bfq_free_root_group(struct bfq_data *bfqd) ++{ ++ struct bfqio_cgroup *bgrp = &bfqio_root_cgroup; ++ struct bfq_group *bfqg = bfqd->root_group; ++ ++ bfq_put_async_queues(bfqd, bfqg); ++ ++ spin_lock_irq(&bgrp->lock); ++ hlist_del_rcu(&bfqg->group_node); ++ spin_unlock_irq(&bgrp->lock); ++ ++ /* ++ * No need to synchronize_rcu() here: since the device is gone ++ * there cannot be any read-side access to its root_group. ++ */ ++ kfree(bfqg); ++} ++ ++static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) ++{ ++ struct bfq_group *bfqg; ++ struct bfqio_cgroup *bgrp; ++ int i; ++ ++ bfqg = kzalloc_node(sizeof(*bfqg), GFP_KERNEL, node); ++ if (bfqg == NULL) ++ return NULL; ++ ++ bfqg->entity.parent = NULL; ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++ ++ bgrp = &bfqio_root_cgroup; ++ spin_lock_irq(&bgrp->lock); ++ rcu_assign_pointer(bfqg->bfqd, bfqd); ++ hlist_add_head_rcu(&bfqg->group_node, &bgrp->group_data); ++ spin_unlock_irq(&bgrp->lock); ++ ++ return bfqg; ++} ++ ++#define SHOW_FUNCTION(__VAR) \ ++static u64 bfqio_cgroup_##__VAR##_read(struct cgroup *cgroup, \ ++ struct cftype *cftype) \ ++{ \ ++ struct bfqio_cgroup *bgrp; \ ++ u64 ret; \ ++ \ ++ if (!cgroup_lock_live_group(cgroup)) \ ++ return -ENODEV; \ ++ \ ++ bgrp = cgroup_to_bfqio(cgroup); \ ++ spin_lock_irq(&bgrp->lock); \ ++ ret = bgrp->__VAR; \ ++ spin_unlock_irq(&bgrp->lock); \ ++ \ ++ cgroup_unlock(); \ ++ \ ++ return ret; \ ++} ++ ++SHOW_FUNCTION(weight); ++SHOW_FUNCTION(ioprio); ++SHOW_FUNCTION(ioprio_class); ++#undef SHOW_FUNCTION ++ ++#define STORE_FUNCTION(__VAR, __MIN, __MAX) \ ++static int bfqio_cgroup_##__VAR##_write(struct cgroup *cgroup, \ ++ struct cftype *cftype, \ ++ u64 val) \ ++{ \ ++ struct bfqio_cgroup *bgrp; \ ++ struct bfq_group *bfqg; \ ++ struct hlist_node *n; \ ++ \ ++ if (val < (__MIN) || val > (__MAX)) \ ++ return -EINVAL; \ ++ \ ++ if (!cgroup_lock_live_group(cgroup)) \ ++ return -ENODEV; \ ++ \ ++ bgrp = cgroup_to_bfqio(cgroup); \ ++ \ ++ spin_lock_irq(&bgrp->lock); \ ++ bgrp->__VAR = (unsigned short)val; \ ++ hlist_for_each_entry(bfqg, n, &bgrp->group_data, group_node) { \ ++ /* \ ++ * Setting the ioprio_changed flag of the entity \ ++ * to 1 with new_##__VAR == ##__VAR would re-set \ ++ * the value of the weight to its ioprio mapping. \ ++ * Set the flag only if necessary. \ ++ */ \ ++ if ((unsigned short)val != bfqg->entity.new_##__VAR) { \ ++ bfqg->entity.new_##__VAR = (unsigned short)val; \ ++ /* \ ++ * Make sure that the above new value has been \ ++ * stored in bfqg->entity.new_##__VAR before \ ++ * setting the ioprio_changed flag. In fact, \ ++ * this flag may be read asynchronously (in \ ++ * critical sections protected by a different \ ++ * lock than that held here), and finding this \ ++ * flag set may cause the execution of the code \ ++ * for updating parameters whose value may \ ++ * depend also on bfqg->entity.new_##__VAR (in \ ++ * __bfq_entity_update_weight_prio). \ ++ * This barrier makes sure that the new value \ ++ * of bfqg->entity.new_##__VAR is correctly \ ++ * seen in that code. \ ++ */ \ ++ smp_wmb(); \ ++ bfqg->entity.ioprio_changed = 1; \ ++ } \ ++ } \ ++ spin_unlock_irq(&bgrp->lock); \ ++ \ ++ cgroup_unlock(); \ ++ \ ++ return 0; \ ++} ++ ++STORE_FUNCTION(weight, BFQ_MIN_WEIGHT, BFQ_MAX_WEIGHT); ++STORE_FUNCTION(ioprio, 0, IOPRIO_BE_NR - 1); ++STORE_FUNCTION(ioprio_class, IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE); ++#undef STORE_FUNCTION ++ ++static struct cftype bfqio_files[] = { ++ { ++ .name = "weight", ++ .read_u64 = bfqio_cgroup_weight_read, ++ .write_u64 = bfqio_cgroup_weight_write, ++ }, ++ { ++ .name = "ioprio", ++ .read_u64 = bfqio_cgroup_ioprio_read, ++ .write_u64 = bfqio_cgroup_ioprio_write, ++ }, ++ { ++ .name = "ioprio_class", ++ .read_u64 = bfqio_cgroup_ioprio_class_read, ++ .write_u64 = bfqio_cgroup_ioprio_class_write, ++ }, ++}; ++ ++static int bfqio_populate(struct cgroup_subsys *subsys, struct cgroup *cgroup) ++{ ++ return cgroup_add_files(cgroup, subsys, bfqio_files, ++ ARRAY_SIZE(bfqio_files)); ++} ++ ++static struct cgroup_subsys_state *bfqio_create(struct cgroup *cgroup) ++{ ++ struct bfqio_cgroup *bgrp; ++ ++ if (cgroup->parent != NULL) { ++ bgrp = kzalloc(sizeof(*bgrp), GFP_KERNEL); ++ if (bgrp == NULL) ++ return ERR_PTR(-ENOMEM); ++ } else ++ bgrp = &bfqio_root_cgroup; ++ ++ spin_lock_init(&bgrp->lock); ++ INIT_HLIST_HEAD(&bgrp->group_data); ++ bgrp->ioprio = BFQ_DEFAULT_GRP_IOPRIO; ++ bgrp->ioprio_class = BFQ_DEFAULT_GRP_CLASS; ++ ++ return &bgrp->css; ++} ++ ++/* ++ * We cannot support shared io contexts, as we have no means to support ++ * two tasks with the same ioc in two different groups without major rework ++ * of the main bic/bfqq data structures. By now we allow a task to change ++ * its cgroup only if it's the only owner of its ioc; the drawback of this ++ * behavior is that a group containing a task that forked using CLONE_IO ++ * will not be destroyed until the tasks sharing the ioc die. ++ */ ++static int bfqio_can_attach(struct cgroup *cgroup, struct cgroup_taskset *tset) ++{ ++ struct task_struct *task; ++ struct io_context *ioc; ++ int ret = 0; ++ ++ cgroup_taskset_for_each(task, cgroup, tset) { ++ /* task_lock() is needed to avoid races with exit_io_context() */ ++ task_lock(task); ++ ioc = task->io_context; ++ if (ioc != NULL && atomic_read(&ioc->nr_tasks) > 1) ++ /* ++ * ioc == NULL means that the task is either too ++ * young or exiting: if it has still no ioc the ++ * ioc can't be shared, if the task is exiting the ++ * attach will fail anyway, no matter what we ++ * return here. ++ */ ++ ret = -EINVAL; ++ task_unlock(task); ++ if (ret) ++ break; ++ } ++ ++ return ret; ++} ++ ++static void bfqio_attach(struct cgroup *cgroup, struct cgroup_taskset *tset) ++{ ++ struct task_struct *task; ++ struct io_context *ioc; ++ struct io_cq *icq; ++ struct hlist_node *n; ++ ++ /* ++ * IMPORTANT NOTE: The move of more than one process at a time to a ++ * new group has not yet been tested. ++ */ ++ cgroup_taskset_for_each(task, cgroup, tset) { ++ ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE); ++ if (ioc) { ++ /* ++ * Handle cgroup change here. ++ */ ++ rcu_read_lock(); ++ hlist_for_each_entry_rcu(icq, n, &ioc->icq_list, ioc_node) ++ if (!strncmp( ++ icq->q->elevator->type->elevator_name, ++ "bfq", ELV_NAME_MAX)) ++ bfq_bic_change_cgroup(icq_to_bic(icq), ++ cgroup); ++ rcu_read_unlock(); ++ put_io_context(ioc); ++ } ++ } ++} ++ ++static void bfqio_destroy(struct cgroup *cgroup) ++{ ++ struct bfqio_cgroup *bgrp = cgroup_to_bfqio(cgroup); ++ struct hlist_node *n, *tmp; ++ struct bfq_group *bfqg; ++ ++ /* ++ * Since we are destroying the cgroup, there are no more tasks ++ * referencing it, and all the RCU grace periods that may have ++ * referenced it are ended (as the destruction of the parent ++ * cgroup is RCU-safe); bgrp->group_data will not be accessed by ++ * anything else and we don't need any synchronization. ++ */ ++ hlist_for_each_entry_safe(bfqg, n, tmp, &bgrp->group_data, group_node) ++ bfq_destroy_group(bgrp, bfqg); ++ ++ BUG_ON(!hlist_empty(&bgrp->group_data)); ++ ++ kfree(bgrp); ++} ++ ++struct cgroup_subsys bfqio_subsys = { ++ .name = "bfqio", ++ .create = bfqio_create, ++ .can_attach = bfqio_can_attach, ++ .attach = bfqio_attach, ++ .destroy = bfqio_destroy, ++ .populate = bfqio_populate, ++ .subsys_id = bfqio_subsys_id, ++}; ++#else ++static inline void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ entity->ioprio = entity->new_ioprio; ++ entity->ioprio_class = entity->new_ioprio_class; ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static inline struct bfq_group * ++bfq_bic_update_cgroup(struct bfq_io_cq *bic) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ return bfqd->root_group; ++} ++ ++static inline void bfq_bfqq_move(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++static inline void bfq_disconnect_groups(struct bfq_data *bfqd) ++{ ++ bfq_put_async_queues(bfqd, bfqd->root_group); ++} ++ ++static inline void bfq_free_root_group(struct bfq_data *bfqd) ++{ ++ kfree(bfqd->root_group); ++} ++ ++static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) ++{ ++ struct bfq_group *bfqg; ++ int i; ++ ++ bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node); ++ if (bfqg == NULL) ++ return NULL; ++ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++ ++ return bfqg; ++} ++#endif +diff --git a/block/bfq-ioc.c b/block/bfq-ioc.c +new file mode 100644 +index 0000000..7f6b000 +--- /dev/null ++++ b/block/bfq-ioc.c +@@ -0,0 +1,36 @@ ++/* ++ * BFQ: I/O context handling. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++/** ++ * icq_to_bic - convert iocontext queue structure to bfq_io_cq. ++ * @icq: the iocontext queue. ++ */ ++static inline struct bfq_io_cq *icq_to_bic(struct io_cq *icq) ++{ ++ /* bic->icq is the first member, %NULL will convert to %NULL */ ++ return container_of(icq, struct bfq_io_cq, icq); ++} ++ ++/** ++ * bfq_bic_lookup - search into @ioc a bic associated to @bfqd. ++ * @bfqd: the lookup key. ++ * @ioc: the io_context of the process doing I/O. ++ * ++ * Queue lock must be held. ++ */ ++static inline struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd, ++ struct io_context *ioc) ++{ ++ if (ioc) ++ return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue)); ++ return NULL; ++} +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +new file mode 100644 +index 0000000..f8a3dfd +--- /dev/null ++++ b/block/bfq-iosched.c +@@ -0,0 +1,3887 @@ ++/* ++ * Budget Fair Queueing (BFQ) disk scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ * ++ * BFQ is a proportional-share storage-I/O scheduling algorithm based on ++ * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets, ++ * measured in number of sectors, to processes instead of time slices. The ++ * device is not granted to the in-service process for a given time slice, ++ * but until it has exhausted its assigned budget. This change from the time ++ * to the service domain allows BFQ to distribute the device throughput ++ * among processes as desired, without any distortion due to ZBR, workload ++ * fluctuations or other factors. BFQ uses an ad hoc internal scheduler, ++ * called B-WF2Q+, to schedule processes according to their budgets. More ++ * precisely, BFQ schedules queues associated to processes. Thanks to the ++ * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to ++ * I/O-bound processes issuing sequential requests (to boost the ++ * throughput), and yet guarantee a low latency to interactive and soft ++ * real-time applications. ++ * ++ * BFQ is described in [1], where also a reference to the initial, more ++ * theoretical paper on BFQ can be found. The interested reader can find ++ * in the latter paper full details on the main algorithm, as well as ++ * formulas of the guarantees and formal proofs of all the properties. ++ * With respect to the version of BFQ presented in these papers, this ++ * implementation adds a few more heuristics, such as the one that ++ * guarantees a low latency to soft real-time applications, and a ++ * hierarchical extension based on H-WF2Q+. ++ * ++ * B-WF2Q+ is based on WF2Q+, that is described in [2], together with ++ * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N) ++ * complexity derives from the one introduced with EEVDF in [3]. ++ * ++ * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness ++ * with the BFQ Disk I/O Scheduler'', ++ * Proceedings of the 5th Annual International Systems and Storage ++ * Conference (SYSTOR '12), June 2012. ++ * ++ * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf ++ * ++ * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing ++ * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689, ++ * Oct 1997. ++ * ++ * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz ++ * ++ * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline ++ * First: A Flexible and Accurate Mechanism for Proportional Share ++ * Resource Allocation,'' technical report. ++ * ++ * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bfq.h" ++#include "blk.h" ++ ++/* Expiration time of sync (0) and async (1) requests, in jiffies. */ ++static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 }; ++ ++/* Maximum backwards seek, in KiB. */ ++static const int bfq_back_max = 16 * 1024; ++ ++/* Penalty of a backwards seek, in number of sectors. */ ++static const int bfq_back_penalty = 2; ++ ++/* Idling period duration, in jiffies. */ ++static int bfq_slice_idle = HZ / 125; ++ ++/* Default maximum budget values, in sectors and number of requests. */ ++static const int bfq_default_max_budget = 16 * 1024; ++static const int bfq_max_budget_async_rq = 4; ++ ++/* ++ * Async to sync throughput distribution is controlled as follows: ++ * when an async request is served, the entity is charged the number ++ * of sectors of the request, multiplied by the factor below ++ */ ++static const int bfq_async_charge_factor = 10; ++ ++/* Default timeout values, in jiffies, approximating CFQ defaults. */ ++static const int bfq_timeout_sync = HZ / 8; ++static int bfq_timeout_async = HZ / 25; ++ ++struct kmem_cache *bfq_pool; ++ ++/* Below this threshold (in ms), we consider thinktime immediate. */ ++#define BFQ_MIN_TT 2 ++ ++/* hw_tag detection: parallel requests threshold and min samples needed. */ ++#define BFQ_HW_QUEUE_THRESHOLD 4 ++#define BFQ_HW_QUEUE_SAMPLES 32 ++ ++#define BFQQ_SEEK_THR (sector_t)(8 * 1024) ++#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR) ++ ++/* Min samples used for peak rate estimation (for autotuning). */ ++#define BFQ_PEAK_RATE_SAMPLES 32 ++ ++/* Shift used for peak rate fixed precision calculations. */ ++#define BFQ_RATE_SHIFT 16 ++ ++/* ++ * By default, BFQ computes the duration of the weight raising for ++ * interactive applications automatically, using the following formula: ++ * duration = (R / r) * T, where r is the peak rate of the device, and ++ * R and T are two reference parameters. ++ * In particular, R is the peak rate of the reference device (see below), ++ * and T is a reference time: given the systems that are likely to be ++ * installed on the reference device according to its speed class, T is ++ * about the maximum time needed, under BFQ and while reading two files in ++ * parallel, to load typical large applications on these systems. ++ * In practice, the slower/faster the device at hand is, the more/less it ++ * takes to load applications with respect to the reference device. ++ * Accordingly, the longer/shorter BFQ grants weight raising to interactive ++ * applications. ++ * ++ * BFQ uses four different reference pairs (R, T), depending on: ++ * . whether the device is rotational or non-rotational; ++ * . whether the device is slow, such as old or portable HDDs, as well as ++ * SD cards, or fast, such as newer HDDs and SSDs. ++ * ++ * The device's speed class is dynamically (re)detected in ++ * bfq_update_peak_rate() every time the estimated peak rate is updated. ++ * ++ * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0] ++ * are the reference values for a slow/fast rotational device, whereas ++ * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for ++ * a slow/fast non-rotational device. Finally, device_speed_thresh are the ++ * thresholds used to switch between speed classes. ++ * Both the reference peak rates and the thresholds are measured in ++ * sectors/usec, left-shifted by BFQ_RATE_SHIFT. ++ */ ++static int R_slow[2] = {1536, 10752}; ++static int R_fast[2] = {17415, 34791}; ++/* ++ * To improve readability, a conversion function is used to initialize the ++ * following arrays, which entails that they can be initialized only in a ++ * function. ++ */ ++static int T_slow[2]; ++static int T_fast[2]; ++static int device_speed_thresh[2]; ++ ++#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \ ++ { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 }) ++ ++#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0]) ++#define RQ_BFQQ(rq) ((rq)->elv.priv[1]) ++ ++static inline void bfq_schedule_dispatch(struct bfq_data *bfqd); ++ ++#include "bfq-ioc.c" ++#include "bfq-sched.c" ++#include "bfq-cgroup.c" ++ ++#define bfq_class_idle(bfqq) ((bfqq)->entity.ioprio_class ==\ ++ IOPRIO_CLASS_IDLE) ++#define bfq_class_rt(bfqq) ((bfqq)->entity.ioprio_class ==\ ++ IOPRIO_CLASS_RT) ++ ++#define bfq_sample_valid(samples) ((samples) > 80) ++ ++/* ++ * The following macro groups conditions that need to be evaluated when ++ * checking if existing queues and groups form a symmetric scenario ++ * and therefore idling can be reduced or disabled for some of the ++ * queues. See the comment to the function bfq_bfqq_must_not_expire() ++ * for further details. ++ */ ++#ifdef CONFIG_CGROUP_BFQIO ++#define symmetric_scenario (!bfqd->active_numerous_groups && \ ++ !bfq_differentiated_weights(bfqd)) ++#else ++#define symmetric_scenario (!bfq_differentiated_weights(bfqd)) ++#endif ++ ++/* ++ * We regard a request as SYNC, if either it's a read or has the SYNC bit ++ * set (in which case it could also be a direct WRITE). ++ */ ++static inline int bfq_bio_sync(struct bio *bio) ++{ ++ if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC)) ++ return 1; ++ ++ return 0; ++} ++ ++/* ++ * Scheduler run of queue, if there are requests pending and no one in the ++ * driver that will restart queueing. ++ */ ++static inline void bfq_schedule_dispatch(struct bfq_data *bfqd) ++{ ++ if (bfqd->queued != 0) { ++ bfq_log(bfqd, "schedule dispatch"); ++ kblockd_schedule_work(bfqd->queue, &bfqd->unplug_work); ++ } ++} ++ ++/* ++ * Lifted from AS - choose which of rq1 and rq2 that is best served now. ++ * We choose the request that is closesr to the head right now. Distance ++ * behind the head is penalized and only allowed to a certain extent. ++ */ ++static struct request *bfq_choose_req(struct bfq_data *bfqd, ++ struct request *rq1, ++ struct request *rq2, ++ sector_t last) ++{ ++ sector_t s1, s2, d1 = 0, d2 = 0; ++ unsigned long back_max; ++#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */ ++#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */ ++ unsigned wrap = 0; /* bit mask: requests behind the disk head? */ ++ ++ if (rq1 == NULL || rq1 == rq2) ++ return rq2; ++ if (rq2 == NULL) ++ return rq1; ++ ++ if (rq_is_sync(rq1) && !rq_is_sync(rq2)) ++ return rq1; ++ else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) ++ return rq2; ++ if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META)) ++ return rq1; ++ else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META)) ++ return rq2; ++ ++ s1 = blk_rq_pos(rq1); ++ s2 = blk_rq_pos(rq2); ++ ++ /* ++ * By definition, 1KiB is 2 sectors. ++ */ ++ back_max = bfqd->bfq_back_max * 2; ++ ++ /* ++ * Strict one way elevator _except_ in the case where we allow ++ * short backward seeks which are biased as twice the cost of a ++ * similar forward seek. ++ */ ++ if (s1 >= last) ++ d1 = s1 - last; ++ else if (s1 + back_max >= last) ++ d1 = (last - s1) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ1_WRAP; ++ ++ if (s2 >= last) ++ d2 = s2 - last; ++ else if (s2 + back_max >= last) ++ d2 = (last - s2) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ2_WRAP; ++ ++ /* Found required data */ ++ ++ /* ++ * By doing switch() on the bit mask "wrap" we avoid having to ++ * check two variables for all permutations: --> faster! ++ */ ++ switch (wrap) { ++ case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ ++ if (d1 < d2) ++ return rq1; ++ else if (d2 < d1) ++ return rq2; ++ else { ++ if (s1 >= s2) ++ return rq1; ++ else ++ return rq2; ++ } ++ ++ case BFQ_RQ2_WRAP: ++ return rq1; ++ case BFQ_RQ1_WRAP: ++ return rq2; ++ case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */ ++ default: ++ /* ++ * Since both rqs are wrapped, ++ * start with the one that's further behind head ++ * (--> only *one* back seek required), ++ * since back seek takes more time than forward. ++ */ ++ if (s1 <= s2) ++ return rq1; ++ else ++ return rq2; ++ } ++} ++ ++static struct bfq_queue * ++bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root, ++ sector_t sector, struct rb_node **ret_parent, ++ struct rb_node ***rb_link) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *bfqq = NULL; ++ ++ parent = NULL; ++ p = &root->rb_node; ++ while (*p) { ++ struct rb_node **n; ++ ++ parent = *p; ++ bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ ++ /* ++ * Sort strictly based on sector. Smallest to the left, ++ * largest to the right. ++ */ ++ if (sector > blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_right; ++ else if (sector < blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_left; ++ else ++ break; ++ p = n; ++ bfqq = NULL; ++ } ++ ++ *ret_parent = parent; ++ if (rb_link) ++ *rb_link = p; ++ ++ bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d", ++ (long long unsigned)sector, ++ bfqq != NULL ? bfqq->pid : 0); ++ ++ return bfqq; ++} ++ ++static void bfq_rq_pos_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *__bfqq; ++ ++ if (bfqq->pos_root != NULL) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ ++ if (bfq_class_idle(bfqq)) ++ return; ++ if (!bfqq->next_rq) ++ return; ++ ++ bfqq->pos_root = &bfqd->rq_pos_tree; ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root, ++ blk_rq_pos(bfqq->next_rq), &parent, &p); ++ if (__bfqq == NULL) { ++ rb_link_node(&bfqq->pos_node, parent, p); ++ rb_insert_color(&bfqq->pos_node, bfqq->pos_root); ++ } else ++ bfqq->pos_root = NULL; ++} ++ ++/* ++ * Tell whether there are active queues or groups with differentiated weights. ++ */ ++static inline bool bfq_differentiated_weights(struct bfq_data *bfqd) ++{ ++ /* ++ * For weights to differ, at least one of the trees must contain ++ * at least two nodes. ++ */ ++ return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) && ++ (bfqd->queue_weights_tree.rb_node->rb_left || ++ bfqd->queue_weights_tree.rb_node->rb_right) ++#ifdef CONFIG_CGROUP_BFQIO ++ ) || ++ (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) && ++ (bfqd->group_weights_tree.rb_node->rb_left || ++ bfqd->group_weights_tree.rb_node->rb_right) ++#endif ++ ); ++} ++ ++/* ++ * If the weight-counter tree passed as input contains no counter for ++ * the weight of the input entity, then add that counter; otherwise just ++ * increment the existing counter. ++ * ++ * Note that weight-counter trees contain few nodes in mostly symmetric ++ * scenarios. For example, if all queues have the same weight, then the ++ * weight-counter tree for the queues may contain at most one node. ++ * This holds even if low_latency is on, because weight-raised queues ++ * are not inserted in the tree. ++ * In most scenarios, the rate at which nodes are created/destroyed ++ * should be low too. ++ */ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ struct rb_node **new = &(root->rb_node), *parent = NULL; ++ ++ /* ++ * Do not insert if the entity is already associated with a ++ * counter, which happens if: ++ * 1) the entity is associated with a queue, ++ * 2) a request arrival has caused the queue to become both ++ * non-weight-raised, and hence change its weight, and ++ * backlogged; in this respect, each of the two events ++ * causes an invocation of this function, ++ * 3) this is the invocation of this function caused by the ++ * second event. This second invocation is actually useless, ++ * and we handle this fact by exiting immediately. More ++ * efficient or clearer solutions might possibly be adopted. ++ */ ++ if (entity->weight_counter) ++ return; ++ ++ while (*new) { ++ struct bfq_weight_counter *__counter = container_of(*new, ++ struct bfq_weight_counter, ++ weights_node); ++ parent = *new; ++ ++ if (entity->weight == __counter->weight) { ++ entity->weight_counter = __counter; ++ goto inc_counter; ++ } ++ if (entity->weight < __counter->weight) ++ new = &((*new)->rb_left); ++ else ++ new = &((*new)->rb_right); ++ } ++ ++ entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter), ++ GFP_ATOMIC); ++ entity->weight_counter->weight = entity->weight; ++ rb_link_node(&entity->weight_counter->weights_node, parent, new); ++ rb_insert_color(&entity->weight_counter->weights_node, root); ++ ++inc_counter: ++ entity->weight_counter->num_active++; ++} ++ ++/* ++ * Decrement the weight counter associated with the entity, and, if the ++ * counter reaches 0, remove the counter from the tree. ++ * See the comments to the function bfq_weights_tree_add() for considerations ++ * about overhead. ++ */ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ if (!entity->weight_counter) ++ return; ++ ++ BUG_ON(RB_EMPTY_ROOT(root)); ++ BUG_ON(entity->weight_counter->weight != entity->weight); ++ ++ BUG_ON(!entity->weight_counter->num_active); ++ entity->weight_counter->num_active--; ++ if (entity->weight_counter->num_active > 0) ++ goto reset_entity_pointer; ++ ++ rb_erase(&entity->weight_counter->weights_node, root); ++ kfree(entity->weight_counter); ++ ++reset_entity_pointer: ++ entity->weight_counter = NULL; ++} ++ ++static struct request *bfq_find_next_rq(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct request *last) ++{ ++ struct rb_node *rbnext = rb_next(&last->rb_node); ++ struct rb_node *rbprev = rb_prev(&last->rb_node); ++ struct request *next = NULL, *prev = NULL; ++ ++ BUG_ON(RB_EMPTY_NODE(&last->rb_node)); ++ ++ if (rbprev != NULL) ++ prev = rb_entry_rq(rbprev); ++ ++ if (rbnext != NULL) ++ next = rb_entry_rq(rbnext); ++ else { ++ rbnext = rb_first(&bfqq->sort_list); ++ if (rbnext && rbnext != &last->rb_node) ++ next = rb_entry_rq(rbnext); ++ } ++ ++ return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last)); ++} ++ ++/* see the definition of bfq_async_charge_factor for details */ ++static inline unsigned long bfq_serv_to_charge(struct request *rq, ++ struct bfq_queue *bfqq) ++{ ++ return blk_rq_sectors(rq) * ++ (1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) * ++ bfq_async_charge_factor)); ++} ++ ++/** ++ * bfq_updated_next_req - update the queue after a new next_rq selection. ++ * @bfqd: the device data the queue belongs to. ++ * @bfqq: the queue to update. ++ * ++ * If the first request of a queue changes we make sure that the queue ++ * has enough budget to serve at least its first request (if the ++ * request has grown). We do this because if the queue has not enough ++ * budget for its first request, it has to go through two dispatch ++ * rounds to actually get it dispatched. ++ */ ++static void bfq_updated_next_req(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ struct request *next_rq = bfqq->next_rq; ++ unsigned long new_budget; ++ ++ if (next_rq == NULL) ++ return; ++ ++ if (bfqq == bfqd->in_service_queue) ++ /* ++ * In order not to break guarantees, budgets cannot be ++ * changed after an entity has been selected. ++ */ ++ return; ++ ++ BUG_ON(entity->tree != &st->active); ++ BUG_ON(entity == entity->sched_data->in_service_entity); ++ ++ new_budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ if (entity->budget != new_budget) { ++ entity->budget = new_budget; ++ bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu", ++ new_budget); ++ bfq_activate_bfqq(bfqd, bfqq); ++ } ++} ++ ++static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd) ++{ ++ u64 dur; ++ ++ if (bfqd->bfq_wr_max_time > 0) ++ return bfqd->bfq_wr_max_time; ++ ++ dur = bfqd->RT_prod; ++ do_div(dur, bfqd->peak_rate); ++ ++ return dur; ++} ++ ++/* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ ++static inline void bfq_reset_burst_list(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *item; ++ struct hlist_node *pos, *n; ++ ++ hlist_for_each_entry_safe(item, pos, n, ++ &bfqd->burst_list, burst_list_node) ++ hlist_del_init(&item->burst_list_node); ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++ bfqd->burst_size = 1; ++} ++ ++/* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */ ++static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ /* Increment burst size to take into account also bfqq */ ++ bfqd->burst_size++; ++ ++ if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { ++ struct bfq_queue *pos, *bfqq_item; ++ struct hlist_node *p, *n; ++ ++ /* ++ * Enough queues have been activated shortly after each ++ * other to consider this burst as large. ++ */ ++ bfqd->large_burst = true; ++ ++ /* ++ * We can now mark all queues in the burst list as ++ * belonging to a large burst. ++ */ ++ hlist_for_each_entry(bfqq_item, n, &bfqd->burst_list, ++ burst_list_node) ++ bfq_mark_bfqq_in_large_burst(bfqq_item); ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ ++ /* ++ * From now on, and until the current burst finishes, any ++ * new queue being activated shortly after the last queue ++ * was inserted in the burst can be immediately marked as ++ * belonging to a large burst. So the burst list is not ++ * needed any more. Remove it. ++ */ ++ hlist_for_each_entry_safe(pos, p, n, &bfqd->burst_list, ++ burst_list_node) ++ hlist_del_init(&pos->burst_list_node); ++ } else /* burst not yet large: add bfqq to the burst list */ ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++} ++ ++/* ++ * If many queues happen to become active shortly after each other, then, ++ * to help the processes associated to these queues get their job done as ++ * soon as possible, it is usually better to not grant either weight-raising ++ * or device idling to these queues. In this comment we describe, firstly, ++ * the reasons why this fact holds, and, secondly, the next function, which ++ * implements the main steps needed to properly mark these queues so that ++ * they can then be treated in a different way. ++ * ++ * As for the terminology, we say that a queue becomes active, i.e., ++ * switches from idle to backlogged, either when it is created (as a ++ * consequence of the arrival of an I/O request), or, if already existing, ++ * when a new request for the queue arrives while the queue is idle. ++ * Bursts of activations, i.e., activations of different queues occurring ++ * shortly after each other, are typically caused by services or applications ++ * that spawn or reactivate many parallel threads/processes. Examples are ++ * systemd during boot or git grep. ++ * ++ * These services or applications benefit mostly from a high throughput: ++ * the quicker the requests of the activated queues are cumulatively served, ++ * the sooner the target job of these queues gets completed. As a consequence, ++ * weight-raising any of these queues, which also implies idling the device ++ * for it, is almost always counterproductive: in most cases it just lowers ++ * throughput. ++ * ++ * On the other hand, a burst of activations may be also caused by the start ++ * of an application that does not consist in a lot of parallel I/O-bound ++ * threads. In fact, with a complex application, the burst may be just a ++ * consequence of the fact that several processes need to be executed to ++ * start-up the application. To start an application as quickly as possible, ++ * the best thing to do is to privilege the I/O related to the application ++ * with respect to all other I/O. Therefore, the best strategy to start as ++ * quickly as possible an application that causes a burst of activations is ++ * to weight-raise all the queues activated during the burst. This is the ++ * exact opposite of the best strategy for the other type of bursts. ++ * ++ * In the end, to take the best action for each of the two cases, the two ++ * types of bursts need to be distinguished. Fortunately, this seems ++ * relatively easy to do, by looking at the sizes of the bursts. In ++ * particular, we found a threshold such that bursts with a larger size ++ * than that threshold are apparently caused only by services or commands ++ * such as systemd or git grep. For brevity, hereafter we call just 'large' ++ * these bursts. BFQ *does not* weight-raise queues whose activations occur ++ * in a large burst. In addition, for each of these queues BFQ performs or ++ * does not perform idling depending on which choice boosts the throughput ++ * most. The exact choice depends on the device and request pattern at ++ * hand. ++ * ++ * Turning back to the next function, it implements all the steps needed ++ * to detect the occurrence of a large burst and to properly mark all the ++ * queues belonging to it (so that they can then be treated in a different ++ * way). This goal is achieved by maintaining a special "burst list" that ++ * holds, temporarily, the queues that belong to the burst in progress. The ++ * list is then used to mark these queues as belonging to a large burst if ++ * the burst does become large. The main steps are the following. ++ * ++ * . when the very first queue is activated, the queue is inserted into the ++ * list (as it could be the first queue in a possible burst) ++ * ++ * . if the current burst has not yet become large, and a queue Q that does ++ * not yet belong to the burst is activated shortly after the last time ++ * at which a new queue entered the burst list, then the function appends ++ * Q to the burst list ++ * ++ * . if, as a consequence of the previous step, the burst size reaches ++ * the large-burst threshold, then ++ * ++ * . all the queues in the burst list are marked as belonging to a ++ * large burst ++ * ++ * . the burst list is deleted; in fact, the burst list already served ++ * its purpose (keeping temporarily track of the queues in a burst, ++ * so as to be able to mark them as belonging to a large burst in the ++ * previous sub-step), and now is not needed any more ++ * ++ * . the device enters a large-burst mode ++ * ++ * . if a queue Q that does not belong to the burst is activated while ++ * the device is in large-burst mode and shortly after the last time ++ * at which a queue either entered the burst list or was marked as ++ * belonging to the current large burst, then Q is immediately marked ++ * as belonging to a large burst. ++ * ++ * . if a queue Q that does not belong to the burst is activated a while ++ * later, i.e., not shortly after, than the last time at which a queue ++ * either entered the burst list or was marked as belonging to the ++ * current large burst, then the current burst is deemed as finished and: ++ * ++ * . the large-burst mode is reset if set ++ * ++ * . the burst list is emptied ++ * ++ * . Q is inserted in the burst list, as Q may be the first queue ++ * in a possible new burst (then the burst list contains just Q ++ * after this step). ++ */ ++static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ bool idle_for_long_time) ++{ ++ /* ++ * If bfqq happened to be activated in a burst, but has been idle ++ * for at least as long as an interactive queue, then we assume ++ * that, in the overall I/O initiated in the burst, the I/O ++ * associated to bfqq is finished. So bfqq does not need to be ++ * treated as a queue belonging to a burst anymore. Accordingly, ++ * we reset bfqq's in_large_burst flag if set, and remove bfqq ++ * from the burst list if it's there. We do not decrement instead ++ * burst_size, because the fact that bfqq does not need to belong ++ * to the burst list any more does not invalidate the fact that ++ * bfqq may have been activated during the current burst. ++ */ ++ if (idle_for_long_time) { ++ hlist_del_init(&bfqq->burst_list_node); ++ bfq_clear_bfqq_in_large_burst(bfqq); ++ } ++ ++ /* ++ * If bfqq is already in the burst list or is part of a large ++ * burst, then there is nothing else to do. ++ */ ++ if (!hlist_unhashed(&bfqq->burst_list_node) || ++ bfq_bfqq_in_large_burst(bfqq)) ++ return; ++ ++ /* ++ * If bfqq's activation happens late enough, then the current ++ * burst is finished, and related data structures must be reset. ++ * ++ * In this respect, consider the special case where bfqq is the very ++ * first queue being activated. In this case, last_ins_in_burst is ++ * not yet significant when we get here. But it is easy to verify ++ * that, whether or not the following condition is true, bfqq will ++ * end up being inserted into the burst list. In particular the ++ * list will happen to contain only bfqq. And this is exactly what ++ * has to happen, as bfqq may be the first queue in a possible ++ * burst. ++ */ ++ if (time_is_before_jiffies(bfqd->last_ins_in_burst + ++ bfqd->bfq_burst_interval)) { ++ bfqd->large_burst = false; ++ bfq_reset_burst_list(bfqd, bfqq); ++ return; ++ } ++ ++ /* ++ * If we get here, then bfqq is being activated shortly after the ++ * last queue. So, if the current burst is also large, we can mark ++ * bfqq as belonging to this large burst immediately. ++ */ ++ if (bfqd->large_burst) { ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ return; ++ } ++ ++ /* ++ * If we get here, then a large-burst state has not yet been ++ * reached, but bfqq is being activated shortly after the last ++ * queue. Then we add bfqq to the burst. ++ */ ++ bfq_add_to_burst(bfqd, bfqq); ++} ++ ++static void bfq_add_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *next_rq, *prev; ++ unsigned long old_wr_coeff = bfqq->wr_coeff; ++ bool interactive = false; ++ ++ bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq)); ++ bfqq->queued[rq_is_sync(rq)]++; ++ bfqd->queued++; ++ ++ elv_rb_add(&bfqq->sort_list, rq); ++ ++ /* ++ * Check if this request is a better next-serve candidate. ++ */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position); ++ BUG_ON(next_rq == NULL); ++ bfqq->next_rq = next_rq; ++ ++ /* ++ * Adjust priority tree position, if next_rq changes. ++ */ ++ if (prev != bfqq->next_rq) ++ bfq_rq_pos_tree_add(bfqd, bfqq); ++ ++ if (!bfq_bfqq_busy(bfqq)) { ++ bool soft_rt, ++ idle_for_long_time = time_is_before_jiffies( ++ bfqq->budget_timeout + ++ bfqd->bfq_wr_min_idle_time); ++ ++ if (bfq_bfqq_sync(bfqq)) { ++ bool already_in_burst = ++ !hlist_unhashed(&bfqq->burst_list_node) || ++ bfq_bfqq_in_large_burst(bfqq); ++ bfq_handle_burst(bfqd, bfqq, idle_for_long_time); ++ /* ++ * If bfqq was not already in the current burst, ++ * then, at this point, bfqq either has been ++ * added to the current burst or has caused the ++ * current burst to terminate. In particular, in ++ * the second case, bfqq has become the first ++ * queue in a possible new burst. ++ * In both cases last_ins_in_burst needs to be ++ * moved forward. ++ */ ++ if (!already_in_burst) ++ bfqd->last_ins_in_burst = jiffies; ++ } ++ ++ soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && ++ !bfq_bfqq_in_large_burst(bfqq) && ++ time_is_before_jiffies(bfqq->soft_rt_next_start); ++ interactive = !bfq_bfqq_in_large_burst(bfqq) && ++ idle_for_long_time; ++ entity->budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ ++ if (!bfq_bfqq_IO_bound(bfqq)) { ++ if (time_before(jiffies, ++ RQ_BIC(rq)->ttime.last_end_request + ++ bfqd->bfq_slice_idle)) { ++ bfqq->requests_within_timer++; ++ if (bfqq->requests_within_timer >= ++ bfqd->bfq_requests_within_timer) ++ bfq_mark_bfqq_IO_bound(bfqq); ++ } else ++ bfqq->requests_within_timer = 0; ++ } ++ ++ if (!bfqd->low_latency) ++ goto add_bfqq_busy; ++ ++ /* ++ * If the queue is not being boosted and has been idle ++ * for enough time, start a weight-raising period ++ */ ++ if (old_wr_coeff == 1 && (interactive || soft_rt)) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ if (interactive) ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ else ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais starting at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } else if (old_wr_coeff > 1) { ++ if (interactive) ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ else if (bfq_bfqq_in_large_burst(bfqq) || ++ (bfqq->wr_cur_max_time == ++ bfqd->bfq_wr_rt_max_time && ++ !soft_rt)) { ++ bfqq->wr_coeff = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais ending at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq-> ++ wr_cur_max_time)); ++ } else if (time_before( ++ bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time, ++ jiffies + ++ bfqd->bfq_wr_rt_max_time) && ++ soft_rt) { ++ /* ++ * ++ * The remaining weight-raising time is lower ++ * than bfqd->bfq_wr_rt_max_time, which ++ * means that the application is enjoying ++ * weight raising either because deemed soft- ++ * rt in the near past, or because deemed ++ * interactive a long ago. In both cases, ++ * resetting now the current remaining weight- ++ * raising time for the application to the ++ * weight-raising duration for soft rt ++ * applications would not cause any latency ++ * increase for the application (as the new ++ * duration would be higher than the remaining ++ * time). ++ * ++ * In addition, the application is now meeting ++ * the requirements for being deemed soft rt. ++ * In the end we can correctly and safely ++ * (re)charge the weight-raising duration for ++ * the application with the weight-raising ++ * duration for soft rt applications. ++ * ++ * In particular, doing this recharge now, i.e., ++ * before the weight-raising period for the ++ * application finishes, reduces the probability ++ * of the following negative scenario: ++ * 1) the weight of a soft rt application is ++ * raised at startup (as for any newly ++ * created application), ++ * 2) since the application is not interactive, ++ * at a certain time weight-raising is ++ * stopped for the application, ++ * 3) at that time the application happens to ++ * still have pending requests, and hence ++ * is destined to not have a chance to be ++ * deemed soft rt before these requests are ++ * completed (see the comments to the ++ * function bfq_bfqq_softrt_next_start() ++ * for details on soft rt detection), ++ * 4) these pending requests experience a high ++ * latency because the application is not ++ * weight-raised while they are pending. ++ */ ++ bfqq->last_wr_start_finish = jiffies; ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ } ++ } ++ if (old_wr_coeff != bfqq->wr_coeff) ++ entity->ioprio_changed = 1; ++add_bfqq_busy: ++ bfqq->last_idle_bklogged = jiffies; ++ bfqq->service_from_backlogged = 0; ++ bfq_clear_bfqq_softrt_update(bfqq); ++ bfq_add_bfqq_busy(bfqd, bfqq); ++ } else { ++ if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) && ++ time_is_before_jiffies( ++ bfqq->last_wr_start_finish + ++ bfqd->bfq_wr_min_inter_arr_async)) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ ++ bfqd->wr_busy_queues++; ++ entity->ioprio_changed = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "non-idle wrais starting at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ if (prev != bfqq->next_rq) ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ if (bfqd->low_latency && ++ (old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive)) ++ bfqq->last_wr_start_finish = jiffies; ++} ++ ++static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd, ++ struct bio *bio) ++{ ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (bic == NULL) ++ return NULL; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ if (bfqq != NULL) { ++ sector_t sector = bio->bi_sector + bio_sectors(bio); ++ ++ return elv_rb_find(&bfqq->sort_list, sector); ++ } ++ ++ return NULL; ++} ++ ++static void bfq_activate_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ ++ bfqd->rq_in_driver++; ++ bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ bfq_log(bfqd, "activate_request: new bfqd->last_position %llu", ++ (long long unsigned)bfqd->last_position); ++} ++ ++static inline void bfq_deactivate_request(struct request_queue *q, ++ struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ ++ BUG_ON(bfqd->rq_in_driver == 0); ++ bfqd->rq_in_driver--; ++} ++ ++static void bfq_remove_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ const int sync = rq_is_sync(rq); ++ ++ if (bfqq->next_rq == rq) { ++ bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq); ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ if (rq->queuelist.prev != &rq->queuelist) ++ list_del_init(&rq->queuelist); ++ BUG_ON(bfqq->queued[sync] == 0); ++ bfqq->queued[sync]--; ++ bfqd->queued--; ++ elv_rb_del(&bfqq->sort_list, rq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ /* ++ * Remove queue from request-position tree as it is empty. ++ */ ++ if (bfqq->pos_root != NULL) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ } ++ ++ if (rq->cmd_flags & REQ_META) { ++ BUG_ON(bfqq->meta_pending == 0); ++ bfqq->meta_pending--; ++ } ++} ++ ++static int bfq_merge(struct request_queue *q, struct request **req, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct request *__rq; ++ ++ __rq = bfq_find_rq_fmerge(bfqd, bio); ++ if (__rq != NULL && elv_rq_merge_ok(__rq, bio)) { ++ *req = __rq; ++ return ELEVATOR_FRONT_MERGE; ++ } ++ ++ return ELEVATOR_NO_MERGE; ++} ++ ++static void bfq_merged_request(struct request_queue *q, struct request *req, ++ int type) ++{ ++ if (type == ELEVATOR_FRONT_MERGE && ++ rb_prev(&req->rb_node) && ++ blk_rq_pos(req) < ++ blk_rq_pos(container_of(rb_prev(&req->rb_node), ++ struct request, rb_node))) { ++ struct bfq_queue *bfqq = RQ_BFQQ(req); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *prev, *next_rq; ++ ++ /* Reposition request in its sort_list */ ++ elv_rb_del(&bfqq->sort_list, req); ++ elv_rb_add(&bfqq->sort_list, req); ++ /* Choose next request to be served for bfqq */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req, ++ bfqd->last_position); ++ BUG_ON(next_rq == NULL); ++ bfqq->next_rq = next_rq; ++ /* ++ * If next_rq changes, update both the queue's budget to ++ * fit the new request and the queue's position in its ++ * rq_pos_tree. ++ */ ++ if (prev != bfqq->next_rq) { ++ bfq_updated_next_req(bfqd, bfqq); ++ bfq_rq_pos_tree_add(bfqd, bfqq); ++ } ++ } ++} ++ ++static void bfq_merged_requests(struct request_queue *q, struct request *rq, ++ struct request *next) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq), *next_bfqq = RQ_BFQQ(next); ++ ++ /* ++ * If next and rq belong to the same bfq_queue and next is older ++ * than rq, then reposition rq in the fifo (by substituting next ++ * with rq). Otherwise, if next and rq belong to different ++ * bfq_queues, never reposition rq: in fact, we would have to ++ * reposition it with respect to next's position in its own fifo, ++ * which would most certainly be too expensive with respect to ++ * the benefits. ++ */ ++ if (bfqq == next_bfqq && ++ !list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && ++ time_before(rq_fifo_time(next), rq_fifo_time(rq))) { ++ list_del_init(&rq->queuelist); ++ list_replace_init(&next->queuelist, &rq->queuelist); ++ rq_set_fifo_time(rq, rq_fifo_time(next)); ++ } ++ ++ if (bfqq->next_rq == next) ++ bfqq->next_rq = rq; ++ ++ bfq_remove_request(next); ++} ++ ++/* Must be called with bfqq != NULL */ ++static inline void bfq_bfqq_end_wr(struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfqq == NULL); ++ if (bfq_bfqq_busy(bfqq)) ++ bfqq->bfqd->wr_busy_queues--; ++ bfqq->wr_coeff = 1; ++ bfqq->wr_cur_max_time = 0; ++ /* Trigger a weight change on the next activation of the queue */ ++ bfqq->entity.ioprio_changed = 1; ++} ++ ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ if (bfqg->async_bfqq[i][j] != NULL) ++ bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]); ++ if (bfqg->async_idle_bfqq != NULL) ++ bfq_bfqq_end_wr(bfqg->async_idle_bfqq); ++} ++ ++static void bfq_end_wr(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq; ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ bfq_end_wr_async(bfqd); ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++} ++ ++static int bfq_allow_merge(struct request_queue *q, struct request *rq, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ /* ++ * Disallow merge of a sync bio into an async request. ++ */ ++ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) ++ return 0; ++ ++ /* ++ * Lookup the bfqq that this bio will be queued with. Allow ++ * merge only if rq is queued there. ++ * Queue lock is held here. ++ */ ++ bic = bfq_bic_lookup(bfqd, current->io_context); ++ if (bic == NULL) ++ return 0; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ return bfqq == RQ_BFQQ(rq); ++} ++ ++static void __bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq != NULL) { ++ bfq_mark_bfqq_must_alloc(bfqq); ++ bfq_mark_bfqq_budget_new(bfqq); ++ bfq_clear_bfqq_fifo_expire(bfqq); ++ ++ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_in_service_queue, cur-budget = %lu", ++ bfqq->entity.budget); ++ } ++ ++ bfqd->in_service_queue = bfqq; ++} ++ ++/* ++ * Get and set a new queue for service. ++ */ ++static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (!bfqq) ++ bfqq = bfq_get_next_queue(bfqd); ++ else ++ bfq_get_next_queue_forced(bfqd, bfqq); ++ ++ __bfq_set_in_service_queue(bfqd, bfqq); ++ return bfqq; ++} ++ ++static inline sector_t bfq_dist_from_last(struct bfq_data *bfqd, ++ struct request *rq) ++{ ++ if (blk_rq_pos(rq) >= bfqd->last_position) ++ return blk_rq_pos(rq) - bfqd->last_position; ++ else ++ return bfqd->last_position - blk_rq_pos(rq); ++} ++ ++/* ++ * Return true if bfqq has no request pending and rq is close enough to ++ * bfqd->last_position, or if rq is closer to bfqd->last_position than ++ * bfqq->next_rq ++ */ ++static inline int bfq_rq_close(struct bfq_data *bfqd, struct request *rq) ++{ ++ return bfq_dist_from_last(bfqd, rq) <= BFQQ_SEEK_THR; ++} ++ ++static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) ++{ ++ struct rb_root *root = &bfqd->rq_pos_tree; ++ struct rb_node *parent, *node; ++ struct bfq_queue *__bfqq; ++ sector_t sector = bfqd->last_position; ++ ++ if (RB_EMPTY_ROOT(root)) ++ return NULL; ++ ++ /* ++ * First, if we find a request starting at the end of the last ++ * request, choose it. ++ */ ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL); ++ if (__bfqq != NULL) ++ return __bfqq; ++ ++ /* ++ * If the exact sector wasn't found, the parent of the NULL leaf ++ * will contain the closest sector (rq_pos_tree sorted by ++ * next_request position). ++ */ ++ __bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ return __bfqq; ++ ++ if (blk_rq_pos(__bfqq->next_rq) < sector) ++ node = rb_next(&__bfqq->pos_node); ++ else ++ node = rb_prev(&__bfqq->pos_node); ++ if (node == NULL) ++ return NULL; ++ ++ __bfqq = rb_entry(node, struct bfq_queue, pos_node); ++ if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ return __bfqq; ++ ++ return NULL; ++} ++ ++/* ++ * bfqd - obvious ++ * cur_bfqq - passed in so that we don't decide that the current queue ++ * is closely cooperating with itself. ++ * ++ * We are assuming that cur_bfqq has dispatched at least one request, ++ * and that bfqd->last_position reflects a position on the disk associated ++ * with the I/O issued by cur_bfqq. ++ */ ++static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, ++ struct bfq_queue *cur_bfqq) ++{ ++ struct bfq_queue *bfqq; ++ ++ if (bfq_class_idle(cur_bfqq)) ++ return NULL; ++ if (!bfq_bfqq_sync(cur_bfqq)) ++ return NULL; ++ if (BFQQ_SEEKY(cur_bfqq)) ++ return NULL; ++ ++ /* If device has only one backlogged bfq_queue, don't search. */ ++ if (bfqd->busy_queues == 1) ++ return NULL; ++ ++ /* ++ * We should notice if some of the queues are cooperating, e.g. ++ * working closely on the same area of the disk. In that case, ++ * we can group them together and don't waste time idling. ++ */ ++ bfqq = bfqq_close(bfqd); ++ if (bfqq == NULL || bfqq == cur_bfqq) ++ return NULL; ++ ++ /* ++ * Do not merge queues from different bfq_groups. ++ */ ++ if (bfqq->entity.parent != cur_bfqq->entity.parent) ++ return NULL; ++ ++ /* ++ * It only makes sense to merge sync queues. ++ */ ++ if (!bfq_bfqq_sync(bfqq)) ++ return NULL; ++ if (BFQQ_SEEKY(bfqq)) ++ return NULL; ++ ++ /* ++ * Do not merge queues of different priority classes. ++ */ ++ if (bfq_class_rt(bfqq) != bfq_class_rt(cur_bfqq)) ++ return NULL; ++ ++ return bfqq; ++} ++ ++/* ++ * If enough samples have been computed, return the current max budget ++ * stored in bfqd, which is dynamically updated according to the ++ * estimated disk peak rate; otherwise return the default max budget ++ */ ++static inline unsigned long bfq_max_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < 194) ++ return bfq_default_max_budget; ++ else ++ return bfqd->bfq_max_budget; ++} ++ ++/* ++ * Return min budget, which is a fraction of the current or default ++ * max budget (trying with 1/32) ++ */ ++static inline unsigned long bfq_min_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < 194) ++ return bfq_default_max_budget / 32; ++ else ++ return bfqd->bfq_max_budget / 32; ++} ++ ++static void bfq_arm_slice_timer(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfqd->in_service_queue; ++ struct bfq_io_cq *bic; ++ unsigned long sl; ++ ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Processes have exited, don't wait. */ ++ bic = bfqd->in_service_bic; ++ if (bic == NULL || atomic_read(&bic->icq.ioc->nr_tasks) == 0) ++ return; ++ ++ bfq_mark_bfqq_wait_request(bfqq); ++ ++ /* ++ * We don't want to idle for seeks, but we do want to allow ++ * fair distribution of slice time for a process doing back-to-back ++ * seeks. So allow a little bit of time for him to submit a new rq. ++ * ++ * To prevent processes with (partly) seeky workloads from ++ * being too ill-treated, grant them a small fraction of the ++ * assigned budget before reducing the waiting time to ++ * BFQ_MIN_TT. This happened to help reduce latency. ++ */ ++ sl = bfqd->bfq_slice_idle; ++ /* ++ * Unless the queue is being weight-raised or the scenario is ++ * asymmetric, grant only minimum idle time if the queue either ++ * has been seeky for long enough or has already proved to be ++ * constantly seeky. ++ */ ++ if (bfq_sample_valid(bfqq->seek_samples) && ++ ((BFQQ_SEEKY(bfqq) && bfqq->entity.service > ++ bfq_max_budget(bfqq->bfqd) / 8) || ++ bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1 && ++ symmetric_scenario) ++ sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT)); ++ else if (bfqq->wr_coeff > 1) ++ sl = sl * 3; ++ bfqd->last_idling_start = ktime_get(); ++ mod_timer(&bfqd->idle_slice_timer, jiffies + sl); ++ bfq_log(bfqd, "arm idle: %u/%u ms", ++ jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle)); ++} ++ ++/* ++ * Set the maximum time for the in-service queue to consume its ++ * budget. This prevents seeky processes from lowering the disk ++ * throughput (always guaranteed with a time slice scheme as in CFQ). ++ */ ++static void bfq_set_budget_timeout(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfqd->in_service_queue; ++ unsigned int timeout_coeff; ++ if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) ++ timeout_coeff = 1; ++ else ++ timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight; ++ ++ bfqd->last_budget_start = ktime_get(); ++ ++ bfq_clear_bfqq_budget_new(bfqq); ++ bfqq->budget_timeout = jiffies + ++ bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff; ++ ++ bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u", ++ jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * ++ timeout_coeff)); ++} ++ ++/* ++ * Move request from internal lists to the request queue dispatch list. ++ */ ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ /* ++ * For consistency, the next instruction should have been executed ++ * after removing the request from the queue and dispatching it. ++ * We execute instead this instruction before bfq_remove_request() ++ * (and hence introduce a temporary inconsistency), for efficiency. ++ * In fact, in a forced_dispatch, this prevents two counters related ++ * to bfqq->dispatched to risk to be uselessly decremented if bfqq ++ * is not in service, and then to be incremented again after ++ * incrementing bfqq->dispatched. ++ */ ++ bfqq->dispatched++; ++ bfq_remove_request(rq); ++ elv_dispatch_sort(q, rq); ++ ++ if (bfq_bfqq_sync(bfqq)) ++ bfqd->sync_flight++; ++} ++ ++/* ++ * Return expired entry, or NULL to just start from scratch in rbtree. ++ */ ++static struct request *bfq_check_fifo(struct bfq_queue *bfqq) ++{ ++ struct request *rq = NULL; ++ ++ if (bfq_bfqq_fifo_expire(bfqq)) ++ return NULL; ++ ++ bfq_mark_bfqq_fifo_expire(bfqq); ++ ++ if (list_empty(&bfqq->fifo)) ++ return NULL; ++ ++ rq = rq_entry_fifo(bfqq->fifo.next); ++ ++ if (time_before(jiffies, rq_fifo_time(rq))) ++ return NULL; ++ ++ return rq; ++} ++ ++/* Must be called with the queue_lock held. */ ++static int bfqq_process_refs(struct bfq_queue *bfqq) ++{ ++ int process_refs, io_refs; ++ ++ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; ++ process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; ++ BUG_ON(process_refs < 0); ++ return process_refs; ++} ++ ++static void bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ int process_refs, new_process_refs; ++ struct bfq_queue *__bfqq; ++ ++ /* ++ * If there are no process references on the new_bfqq, then it is ++ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain ++ * may have dropped their last reference (not just their last process ++ * reference). ++ */ ++ if (!bfqq_process_refs(new_bfqq)) ++ return; ++ ++ /* Avoid a circular list and skip interim queue merges. */ ++ while ((__bfqq = new_bfqq->new_bfqq)) { ++ if (__bfqq == bfqq) ++ return; ++ new_bfqq = __bfqq; ++ } ++ ++ process_refs = bfqq_process_refs(bfqq); ++ new_process_refs = bfqq_process_refs(new_bfqq); ++ /* ++ * If the process for the bfqq has gone away, there is no ++ * sense in merging the queues. ++ */ ++ if (process_refs == 0 || new_process_refs == 0) ++ return; ++ ++ /* ++ * Merge in the direction of the lesser amount of work. ++ */ ++ if (new_process_refs >= process_refs) { ++ bfqq->new_bfqq = new_bfqq; ++ atomic_add(process_refs, &new_bfqq->ref); ++ } else { ++ new_bfqq->new_bfqq = bfqq; ++ atomic_add(new_process_refs, &bfqq->ref); ++ } ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", ++ new_bfqq->pid); ++} ++ ++static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ return entity->budget - entity->service; ++} ++ ++static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ __bfq_bfqd_reset_in_service(bfqd); ++ ++ /* ++ * If this bfqq is shared between multiple processes, check ++ * to make sure that those processes are still issuing I/Os ++ * within the mean seek distance. If not, it may be time to ++ * break the queues apart again. ++ */ ++ if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq)) ++ bfq_mark_bfqq_split_coop(bfqq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ /* ++ * Overloading budget_timeout field to store the time ++ * at which the queue remains with no backlog; used by ++ * the weight-raising mechanism. ++ */ ++ bfqq->budget_timeout = jiffies; ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ } else { ++ bfq_activate_bfqq(bfqd, bfqq); ++ /* ++ * Resort priority tree of potential close cooperators. ++ */ ++ bfq_rq_pos_tree_add(bfqd, bfqq); ++ } ++} ++ ++/** ++ * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior. ++ * @bfqd: device data. ++ * @bfqq: queue to update. ++ * @reason: reason for expiration. ++ * ++ * Handle the feedback on @bfqq budget. See the body for detailed ++ * comments. ++ */ ++static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ enum bfqq_expiration reason) ++{ ++ struct request *next_rq; ++ unsigned long budget, min_budget; ++ ++ budget = bfqq->max_budget; ++ min_budget = bfq_min_budget(bfqd); ++ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %lu, budg left %lu", ++ bfqq->entity.budget, bfq_bfqq_budget_left(bfqq)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %lu, min budg %lu", ++ budget, bfq_min_budget(bfqd)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d", ++ bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue)); ++ ++ if (bfq_bfqq_sync(bfqq)) { ++ switch (reason) { ++ /* ++ * Caveat: in all the following cases we trade latency ++ * for throughput. ++ */ ++ case BFQ_BFQQ_TOO_IDLE: ++ /* ++ * This is the only case where we may reduce ++ * the budget: if there is no request of the ++ * process still waiting for completion, then ++ * we assume (tentatively) that the timer has ++ * expired because the batch of requests of ++ * the process could have been served with a ++ * smaller budget. Hence, betting that ++ * process will behave in the same way when it ++ * becomes backlogged again, we reduce its ++ * next budget. As long as we guess right, ++ * this budget cut reduces the latency ++ * experienced by the process. ++ * ++ * However, if there are still outstanding ++ * requests, then the process may have not yet ++ * issued its next request just because it is ++ * still waiting for the completion of some of ++ * the still outstanding ones. So in this ++ * subcase we do not reduce its budget, on the ++ * contrary we increase it to possibly boost ++ * the throughput, as discussed in the ++ * comments to the BUDGET_TIMEOUT case. ++ */ ++ if (bfqq->dispatched > 0) /* still outstanding reqs */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ else { ++ if (budget > 5 * min_budget) ++ budget -= 4 * min_budget; ++ else ++ budget = min_budget; ++ } ++ break; ++ case BFQ_BFQQ_BUDGET_TIMEOUT: ++ /* ++ * We double the budget here because: 1) it ++ * gives the chance to boost the throughput if ++ * this is not a seeky process (which may have ++ * bumped into this timeout because of, e.g., ++ * ZBR), 2) together with charge_full_budget ++ * it helps give seeky processes higher ++ * timestamps, and hence be served less ++ * frequently. ++ */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_BUDGET_EXHAUSTED: ++ /* ++ * The process still has backlog, and did not ++ * let either the budget timeout or the disk ++ * idling timeout expire. Hence it is not ++ * seeky, has a short thinktime and may be ++ * happy with a higher budget too. So ++ * definitely increase the budget of this good ++ * candidate to boost the disk throughput. ++ */ ++ budget = min(budget * 4, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_NO_MORE_REQUESTS: ++ /* ++ * Leave the budget unchanged. ++ */ ++ default: ++ return; ++ } ++ } else /* async queue */ ++ /* async queues get always the maximum possible budget ++ * (their ability to dispatch is limited by ++ * @bfqd->bfq_max_budget_async_rq). ++ */ ++ budget = bfqd->bfq_max_budget; ++ ++ bfqq->max_budget = budget; ++ ++ if (bfqd->budgets_assigned >= 194 && bfqd->bfq_user_max_budget == 0 && ++ bfqq->max_budget > bfqd->bfq_max_budget) ++ bfqq->max_budget = bfqd->bfq_max_budget; ++ ++ /* ++ * Make sure that we have enough budget for the next request. ++ * Since the finish time of the bfqq must be kept in sync with ++ * the budget, be sure to call __bfq_bfqq_expire() after the ++ * update. ++ */ ++ next_rq = bfqq->next_rq; ++ if (next_rq != NULL) ++ bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ else ++ bfqq->entity.budget = bfqq->max_budget; ++ ++ bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %lu", ++ next_rq != NULL ? blk_rq_sectors(next_rq) : 0, ++ bfqq->entity.budget); ++} ++ ++static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout) ++{ ++ unsigned long max_budget; ++ ++ /* ++ * The max_budget calculated when autotuning is equal to the ++ * amount of sectors transfered in timeout_sync at the ++ * estimated peak rate. ++ */ ++ max_budget = (unsigned long)(peak_rate * 1000 * ++ timeout >> BFQ_RATE_SHIFT); ++ ++ return max_budget; ++} ++ ++/* ++ * In addition to updating the peak rate, checks whether the process ++ * is "slow", and returns 1 if so. This slow flag is used, in addition ++ * to the budget timeout, to reduce the amount of service provided to ++ * seeky processes, and hence reduce their chances to lower the ++ * throughput. See the code for more details. ++ */ ++static int bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int compensate, enum bfqq_expiration reason) ++{ ++ u64 bw, usecs, expected, timeout; ++ ktime_t delta; ++ int update = 0; ++ ++ if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq)) ++ return 0; ++ ++ if (compensate) ++ delta = bfqd->last_idling_start; ++ else ++ delta = ktime_get(); ++ delta = ktime_sub(delta, bfqd->last_budget_start); ++ usecs = ktime_to_us(delta); ++ ++ /* Don't trust short/unrealistic values. */ ++ if (usecs < 100 || usecs >= LONG_MAX) ++ return 0; ++ ++ /* ++ * Calculate the bandwidth for the last slice. We use a 64 bit ++ * value to store the peak rate, in sectors per usec in fixed ++ * point math. We do so to have enough precision in the estimate ++ * and to avoid overflows. ++ */ ++ bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT; ++ do_div(bw, (unsigned long)usecs); ++ ++ timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); ++ ++ /* ++ * Use only long (> 20ms) intervals to filter out spikes for ++ * the peak rate estimation. ++ */ ++ if (usecs > 20000) { ++ if (bw > bfqd->peak_rate || ++ (!BFQQ_SEEKY(bfqq) && ++ reason == BFQ_BFQQ_BUDGET_TIMEOUT)) { ++ bfq_log(bfqd, "measured bw =%llu", bw); ++ /* ++ * To smooth oscillations use a low-pass filter with ++ * alpha=7/8, i.e., ++ * new_rate = (7/8) * old_rate + (1/8) * bw ++ */ ++ do_div(bw, 8); ++ if (bw == 0) ++ return 0; ++ bfqd->peak_rate *= 7; ++ do_div(bfqd->peak_rate, 8); ++ bfqd->peak_rate += bw; ++ update = 1; ++ bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate); ++ } ++ ++ update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1; ++ ++ if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES) ++ bfqd->peak_rate_samples++; ++ ++ if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES && ++ update) { ++ int dev_type = blk_queue_nonrot(bfqd->queue); ++ if (bfqd->bfq_user_max_budget == 0) { ++ bfqd->bfq_max_budget = ++ bfq_calc_max_budget(bfqd->peak_rate, ++ timeout); ++ bfq_log(bfqd, "new max_budget=%lu", ++ bfqd->bfq_max_budget); ++ } ++ if (bfqd->device_speed == BFQ_BFQD_FAST && ++ bfqd->peak_rate < device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_SLOW; ++ bfqd->RT_prod = R_slow[dev_type] * ++ T_slow[dev_type]; ++ } else if (bfqd->device_speed == BFQ_BFQD_SLOW && ++ bfqd->peak_rate > device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ bfqd->RT_prod = R_fast[dev_type] * ++ T_fast[dev_type]; ++ } ++ } ++ } ++ ++ /* ++ * If the process has been served for a too short time ++ * interval to let its possible sequential accesses prevail on ++ * the initial seek time needed to move the disk head on the ++ * first sector it requested, then give the process a chance ++ * and for the moment return false. ++ */ ++ if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8) ++ return 0; ++ ++ /* ++ * A process is considered ``slow'' (i.e., seeky, so that we ++ * cannot treat it fairly in the service domain, as it would ++ * slow down too much the other processes) if, when a slice ++ * ends for whatever reason, it has received service at a ++ * rate that would not be high enough to complete the budget ++ * before the budget timeout expiration. ++ */ ++ expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT; ++ ++ /* ++ * Caveat: processes doing IO in the slower disk zones will ++ * tend to be slow(er) even if not seeky. And the estimated ++ * peak rate will actually be an average over the disk ++ * surface. Hence, to not be too harsh with unlucky processes, ++ * we keep a budget/3 margin of safety before declaring a ++ * process slow. ++ */ ++ return expected > (4 * bfqq->entity.budget) / 3; ++} ++ ++/* ++ * To be deemed as soft real-time, an application must meet two ++ * requirements. First, the application must not require an average ++ * bandwidth higher than the approximate bandwidth required to playback or ++ * record a compressed high-definition video. ++ * The next function is invoked on the completion of the last request of a ++ * batch, to compute the next-start time instant, soft_rt_next_start, such ++ * that, if the next request of the application does not arrive before ++ * soft_rt_next_start, then the above requirement on the bandwidth is met. ++ * ++ * The second requirement is that the request pattern of the application is ++ * isochronous, i.e., that, after issuing a request or a batch of requests, ++ * the application stops issuing new requests until all its pending requests ++ * have been completed. After that, the application may issue a new batch, ++ * and so on. ++ * For this reason the next function is invoked to compute ++ * soft_rt_next_start only for applications that meet this requirement, ++ * whereas soft_rt_next_start is set to infinity for applications that do ++ * not. ++ * ++ * Unfortunately, even a greedy application may happen to behave in an ++ * isochronous way if the CPU load is high. In fact, the application may ++ * stop issuing requests while the CPUs are busy serving other processes, ++ * then restart, then stop again for a while, and so on. In addition, if ++ * the disk achieves a low enough throughput with the request pattern ++ * issued by the application (e.g., because the request pattern is random ++ * and/or the device is slow), then the application may meet the above ++ * bandwidth requirement too. To prevent such a greedy application to be ++ * deemed as soft real-time, a further rule is used in the computation of ++ * soft_rt_next_start: soft_rt_next_start must be higher than the current ++ * time plus the maximum time for which the arrival of a request is waited ++ * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle. ++ * This filters out greedy applications, as the latter issue instead their ++ * next request as soon as possible after the last one has been completed ++ * (in contrast, when a batch of requests is completed, a soft real-time ++ * application spends some time processing data). ++ * ++ * Unfortunately, the last filter may easily generate false positives if ++ * only bfqd->bfq_slice_idle is used as a reference time interval and one ++ * or both the following cases occur: ++ * 1) HZ is so low that the duration of a jiffy is comparable to or higher ++ * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with ++ * HZ=100. ++ * 2) jiffies, instead of increasing at a constant rate, may stop increasing ++ * for a while, then suddenly 'jump' by several units to recover the lost ++ * increments. This seems to happen, e.g., inside virtual machines. ++ * To address this issue, we do not use as a reference time interval just ++ * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In ++ * particular we add the minimum number of jiffies for which the filter ++ * seems to be quite precise also in embedded systems and KVM/QEMU virtual ++ * machines. ++ */ ++static inline unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ return max(bfqq->last_idle_bklogged + ++ HZ * bfqq->service_from_backlogged / ++ bfqd->bfq_wr_max_softrt_rate, ++ jiffies + bfqq->bfqd->bfq_slice_idle + 4); ++} ++ ++/* ++ * Return the largest-possible time instant such that, for as long as possible, ++ * the current time will be lower than this time instant according to the macro ++ * time_is_before_jiffies(). ++ */ ++static inline unsigned long bfq_infinity_from_now(unsigned long now) ++{ ++ return now + ULONG_MAX / 2; ++} ++ ++/** ++ * bfq_bfqq_expire - expire a queue. ++ * @bfqd: device owning the queue. ++ * @bfqq: the queue to expire. ++ * @compensate: if true, compensate for the time spent idling. ++ * @reason: the reason causing the expiration. ++ * ++ * ++ * If the process associated to the queue is slow (i.e., seeky), or in ++ * case of budget timeout, or, finally, if it is async, we ++ * artificially charge it an entire budget (independently of the ++ * actual service it received). As a consequence, the queue will get ++ * higher timestamps than the correct ones upon reactivation, and ++ * hence it will be rescheduled as if it had received more service ++ * than what it actually received. In the end, this class of processes ++ * will receive less service in proportion to how slowly they consume ++ * their budgets (and hence how seriously they tend to lower the ++ * throughput). ++ * ++ * In contrast, when a queue expires because it has been idling for ++ * too much or because it exhausted its budget, we do not touch the ++ * amount of service it has received. Hence when the queue will be ++ * reactivated and its timestamps updated, the latter will be in sync ++ * with the actual service received by the queue until expiration. ++ * ++ * Charging a full budget to the first type of queues and the exact ++ * service to the others has the effect of using the WF2Q+ policy to ++ * schedule the former on a timeslice basis, without violating the ++ * service domain guarantees of the latter. ++ */ ++static void bfq_bfqq_expire(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ int compensate, ++ enum bfqq_expiration reason) ++{ ++ int slow; ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ /* Update disk peak rate for autotuning and check whether the ++ * process is slow (see bfq_update_peak_rate). ++ */ ++ slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason); ++ ++ /* ++ * As above explained, 'punish' slow (i.e., seeky), timed-out ++ * and async queues, to favor sequential sync workloads. ++ * ++ * Processes doing I/O in the slower disk zones will tend to be ++ * slow(er) even if not seeky. Hence, since the estimated peak ++ * rate is actually an average over the disk surface, these ++ * processes may timeout just for bad luck. To avoid punishing ++ * them we do not charge a full budget to a process that ++ * succeeded in consuming at least 2/3 of its budget. ++ */ ++ if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT && ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3)) ++ bfq_bfqq_charge_full_budget(bfqq); ++ ++ bfqq->service_from_backlogged += bfqq->entity.service; ++ ++ if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT && ++ !bfq_bfqq_constantly_seeky(bfqq)) { ++ bfq_mark_bfqq_constantly_seeky(bfqq); ++ if (!blk_queue_nonrot(bfqd->queue)) ++ bfqd->const_seeky_busy_in_flight_queues++; ++ } ++ ++ if (reason == BFQ_BFQQ_TOO_IDLE && ++ bfqq->entity.service <= 2 * bfqq->entity.budget / 10 ) ++ bfq_clear_bfqq_IO_bound(bfqq); ++ ++ if (bfqd->low_latency && bfqq->wr_coeff == 1) ++ bfqq->last_wr_start_finish = jiffies; ++ ++ if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ /* ++ * If we get here, and there are no outstanding requests, ++ * then the request pattern is isochronous (see the comments ++ * to the function bfq_bfqq_softrt_next_start()). Hence we ++ * can compute soft_rt_next_start. If, instead, the queue ++ * still has outstanding requests, then we have to wait ++ * for the completion of all the outstanding requests to ++ * discover whether the request pattern is actually ++ * isochronous. ++ */ ++ if (bfqq->dispatched == 0) ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ else { ++ /* ++ * The application is still waiting for the ++ * completion of one or more requests: ++ * prevent it from possibly being incorrectly ++ * deemed as soft real-time by setting its ++ * soft_rt_next_start to infinity. In fact, ++ * without this assignment, the application ++ * would be incorrectly deemed as soft ++ * real-time if: ++ * 1) it issued a new request before the ++ * completion of all its in-flight ++ * requests, and ++ * 2) at that time, its soft_rt_next_start ++ * happened to be in the past. ++ */ ++ bfqq->soft_rt_next_start = ++ bfq_infinity_from_now(jiffies); ++ /* ++ * Schedule an update of soft_rt_next_start to when ++ * the task may be discovered to be isochronous. ++ */ ++ bfq_mark_bfqq_softrt_update(bfqq); ++ } ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "expire (%d, slow %d, num_disp %d, idle_win %d)", reason, ++ slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq)); ++ ++ /* ++ * Increase, decrease or leave budget unchanged according to ++ * reason. ++ */ ++ __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); ++ __bfq_bfqq_expire(bfqd, bfqq); ++} ++ ++/* ++ * Budget timeout is not implemented through a dedicated timer, but ++ * just checked on request arrivals and completions, as well as on ++ * idle timer expirations. ++ */ ++static int bfq_bfqq_budget_timeout(struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_budget_new(bfqq) || ++ time_before(jiffies, bfqq->budget_timeout)) ++ return 0; ++ return 1; ++} ++ ++/* ++ * If we expire a queue that is waiting for the arrival of a new ++ * request, we may prevent the fictitious timestamp back-shifting that ++ * allows the guarantees of the queue to be preserved (see [1] for ++ * this tricky aspect). Hence we return true only if this condition ++ * does not hold, or if the queue is slow enough to deserve only to be ++ * kicked off for preserving a high throughput. ++*/ ++static inline int bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "may_budget_timeout: wait_request %d left %d timeout %d", ++ bfq_bfqq_wait_request(bfqq), ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3, ++ bfq_bfqq_budget_timeout(bfqq)); ++ ++ return (!bfq_bfqq_wait_request(bfqq) || ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3) ++ && ++ bfq_bfqq_budget_timeout(bfqq); ++} ++ ++/* ++ * Device idling is allowed only for the queues for which this function ++ * returns true. For this reason, the return value of this function plays a ++ * critical role for both throughput boosting and service guarantees. The ++ * return value is computed through a logical expression. In this rather ++ * long comment, we try to briefly describe all the details and motivations ++ * behind the components of this logical expression. ++ * ++ * First, the expression is false if bfqq is not sync, or if: bfqq happened ++ * to become active during a large burst of queue activations, and the ++ * pattern of requests bfqq contains boosts the throughput if bfqq is ++ * expired. In fact, queues that became active during a large burst benefit ++ * only from throughput, as discussed in the comments to bfq_handle_burst. ++ * In this respect, expiring bfqq certainly boosts the throughput on NCQ- ++ * capable flash-based devices, whereas, on rotational devices, it boosts ++ * the throughput only if bfqq contains random requests. ++ * ++ * On the opposite end, if (a) bfqq is sync, (b) the above burst-related ++ * condition does not hold, and (c) bfqq is being weight-raised, then the ++ * expression always evaluates to true, as device idling is instrumental ++ * for preserving low-latency guarantees (see [1]). If, instead, conditions ++ * (a) and (b) do hold, but (c) does not, then the expression evaluates to ++ * true only if: (1) bfqq is I/O-bound and has a non-null idle window, and ++ * (2) at least one of the following two conditions holds. ++ * The first condition is that the device is not performing NCQ, because ++ * idling the device most certainly boosts the throughput if this condition ++ * holds and bfqq is I/O-bound and has been granted a non-null idle window. ++ * The second compound condition is made of the logical AND of two components. ++ * ++ * The first component is true only if there is no weight-raised busy ++ * queue. This guarantees that the device is not idled for a sync non- ++ * weight-raised queue when there are busy weight-raised queues. The former ++ * is then expired immediately if empty. Combined with the timestamping ++ * rules of BFQ (see [1] for details), this causes sync non-weight-raised ++ * queues to get a lower number of requests served, and hence to ask for a ++ * lower number of requests from the request pool, before the busy weight- ++ * raised queues get served again. ++ * ++ * This is beneficial for the processes associated with weight-raised ++ * queues, when the request pool is saturated (e.g., in the presence of ++ * write hogs). In fact, if the processes associated with the other queues ++ * ask for requests at a lower rate, then weight-raised processes have a ++ * higher probability to get a request from the pool immediately (or at ++ * least soon) when they need one. Hence they have a higher probability to ++ * actually get a fraction of the disk throughput proportional to their ++ * high weight. This is especially true with NCQ-capable drives, which ++ * enqueue several requests in advance and further reorder internally- ++ * queued requests. ++ * ++ * In the end, mistreating non-weight-raised queues when there are busy ++ * weight-raised queues seems to mitigate starvation problems in the ++ * presence of heavy write workloads and NCQ, and hence to guarantee a ++ * higher application and system responsiveness in these hostile scenarios. ++ * ++ * If the first component of the compound condition is instead true, i.e., ++ * there is no weight-raised busy queue, then the second component of the ++ * compound condition takes into account service-guarantee and throughput ++ * issues related to NCQ (recall that the compound condition is evaluated ++ * only if the device is detected as supporting NCQ). ++ * ++ * As for service guarantees, allowing the drive to enqueue more than one ++ * request at a time, and hence delegating de facto final scheduling ++ * decisions to the drive's internal scheduler, causes loss of control on ++ * the actual request service order. In this respect, when the drive is ++ * allowed to enqueue more than one request at a time, the service ++ * distribution enforced by the drive's internal scheduler is likely to ++ * coincide with the desired device-throughput distribution only in the ++ * following, perfectly symmetric, scenario: ++ * 1) all active queues have the same weight, ++ * 2) all active groups at the same level in the groups tree have the same ++ * weight, ++ * 3) all active groups at the same level in the groups tree have the same ++ * number of children. ++ * ++ * Even in such a scenario, sequential I/O may still receive a preferential ++ * treatment, but this is not likely to be a big issue with flash-based ++ * devices, because of their non-dramatic loss of throughput with random ++ * I/O. Things do differ with HDDs, for which additional care is taken, as ++ * explained after completing the discussion for flash-based devices. ++ * ++ * Unfortunately, keeping the necessary state for evaluating exactly the ++ * above symmetry conditions would be quite complex and time-consuming. ++ * Therefore BFQ evaluates instead the following stronger sub-conditions, ++ * for which it is much easier to maintain the needed state: ++ * 1) all active queues have the same weight, ++ * 2) all active groups have the same weight, ++ * 3) all active groups have at most one active child each. ++ * In particular, the last two conditions are always true if hierarchical ++ * support and the cgroups interface are not enabled, hence no state needs ++ * to be maintained in this case. ++ * ++ * According to the above considerations, the second component of the ++ * compound condition evaluates to true if any of the above symmetry ++ * sub-condition does not hold, or the device is not flash-based. Therefore, ++ * if also the first component is true, then idling is allowed for a sync ++ * queue. These are the only sub-conditions considered if the device is ++ * flash-based, as, for such a device, it is sensible to force idling only ++ * for service-guarantee issues. In fact, as for throughput, idling ++ * NCQ-capable flash-based devices would not boost the throughput even ++ * with sequential I/O; rather it would lower the throughput in proportion ++ * to how fast the device is. In the end, (only) if all the three ++ * sub-conditions hold and the device is flash-based, the compound ++ * condition evaluates to false and therefore no idling is performed. ++ * ++ * As already said, things change with a rotational device, where idling ++ * boosts the throughput with sequential I/O (even with NCQ). Hence, for ++ * such a device the second component of the compound condition evaluates ++ * to true also if the following additional sub-condition does not hold: ++ * the queue is constantly seeky. Unfortunately, this different behavior ++ * with respect to flash-based devices causes an additional asymmetry: if ++ * some sync queues enjoy idling and some other sync queues do not, then ++ * the latter get a low share of the device throughput, simply because the ++ * former get many requests served after being set as in service, whereas ++ * the latter do not. As a consequence, to guarantee the desired throughput ++ * distribution, on HDDs the compound expression evaluates to true (and ++ * hence device idling is performed) also if the following last symmetry ++ * condition does not hold: no other queue is benefiting from idling. Also ++ * this last condition is actually replaced with a simpler-to-maintain and ++ * stronger condition: there is no busy queue which is not constantly seeky ++ * (and hence may also benefit from idling). ++ * ++ * To sum up, when all the required symmetry and throughput-boosting ++ * sub-conditions hold, the second component of the compound condition ++ * evaluates to false, and hence no idling is performed. This helps to ++ * keep the drives' internal queues full on NCQ-capable devices, and hence ++ * to boost the throughput, without causing 'almost' any loss of service ++ * guarantees. The 'almost' follows from the fact that, if the internal ++ * queue of one such device is filled while all the sub-conditions hold, ++ * but at some point in time some sub-condition stops to hold, then it may ++ * become impossible to let requests be served in the new desired order ++ * until all the requests already queued in the device have been served. ++ */ ++static inline bool bfq_bfqq_must_not_expire(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++#define cond_for_seeky_on_ncq_hdd (bfq_bfqq_constantly_seeky(bfqq) && \ ++ bfqd->busy_in_flight_queues == \ ++ bfqd->const_seeky_busy_in_flight_queues) ++ ++#define cond_for_expiring_in_burst (bfq_bfqq_in_large_burst(bfqq) && \ ++ bfqd->hw_tag && \ ++ (blk_queue_nonrot(bfqd->queue) || \ ++ bfq_bfqq_constantly_seeky(bfqq))) ++ ++/* ++ * Condition for expiring a non-weight-raised queue (and hence not idling ++ * the device). ++ */ ++#define cond_for_expiring_non_wr (bfqd->hw_tag && \ ++ (bfqd->wr_busy_queues > 0 || \ ++ (blk_queue_nonrot(bfqd->queue) || \ ++ cond_for_seeky_on_ncq_hdd))) ++ ++ return bfq_bfqq_sync(bfqq) && ++ !cond_for_expiring_in_burst && ++ (bfqq->wr_coeff > 1 || !symmetric_scenario || ++ (bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_idle_window(bfqq) && ++ !cond_for_expiring_non_wr) ++ ); ++} ++ ++/* ++ * If the in-service queue is empty but sync, and the function ++ * bfq_bfqq_must_not_expire returns true, then: ++ * 1) the queue must remain in service and cannot be expired, and ++ * 2) the disk must be idled to wait for the possible arrival of a new ++ * request for the queue. ++ * See the comments to the function bfq_bfqq_must_not_expire for the reasons ++ * why performing device idling is the best choice to boost the throughput ++ * and preserve service guarantees when bfq_bfqq_must_not_expire itself ++ * returns true. ++ */ ++static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 && ++ bfq_bfqq_must_not_expire(bfqq); ++} ++ ++/* ++ * Select a queue for service. If we have a current queue in service, ++ * check whether to continue servicing it, or retrieve and set a new one. ++ */ ++static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq, *new_bfqq = NULL; ++ struct request *next_rq; ++ enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ ++ bfqq = bfqd->in_service_queue; ++ if (bfqq == NULL) ++ goto new_queue; ++ ++ bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); ++ ++ /* ++ * If another queue has a request waiting within our mean seek ++ * distance, let it run. The expire code will check for close ++ * cooperators and put the close queue at the front of the ++ * service tree. If possible, merge the expiring queue with the ++ * new bfqq. ++ */ ++ new_bfqq = bfq_close_cooperator(bfqd, bfqq); ++ if (new_bfqq != NULL && bfqq->new_bfqq == NULL) ++ bfq_setup_merge(bfqq, new_bfqq); ++ ++ if (bfq_may_expire_for_budg_timeout(bfqq) && ++ !timer_pending(&bfqd->idle_slice_timer) && ++ !bfq_bfqq_must_idle(bfqq)) ++ goto expire; ++ ++ next_rq = bfqq->next_rq; ++ /* ++ * If bfqq has requests queued and it has enough budget left to ++ * serve them, keep the queue, otherwise expire it. ++ */ ++ if (next_rq != NULL) { ++ if (bfq_serv_to_charge(next_rq, bfqq) > ++ bfq_bfqq_budget_left(bfqq)) { ++ reason = BFQ_BFQQ_BUDGET_EXHAUSTED; ++ goto expire; ++ } else { ++ /* ++ * The idle timer may be pending because we may ++ * not disable disk idling even when a new request ++ * arrives. ++ */ ++ if (timer_pending(&bfqd->idle_slice_timer)) { ++ /* ++ * If we get here: 1) at least a new request ++ * has arrived but we have not disabled the ++ * timer because the request was too small, ++ * 2) then the block layer has unplugged ++ * the device, causing the dispatch to be ++ * invoked. ++ * ++ * Since the device is unplugged, now the ++ * requests are probably large enough to ++ * provide a reasonable throughput. ++ * So we disable idling. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ del_timer(&bfqd->idle_slice_timer); ++ } ++ if (new_bfqq == NULL) ++ goto keep_queue; ++ else ++ goto expire; ++ } ++ } ++ ++ /* ++ * No requests pending. However, if the in-service queue is idling ++ * for a new request, or has requests waiting for a completion and ++ * may idle after their completion, then keep it anyway. ++ */ ++ if (new_bfqq == NULL && (timer_pending(&bfqd->idle_slice_timer) || ++ (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq)))) { ++ bfqq = NULL; ++ goto keep_queue; ++ } else if (new_bfqq != NULL && timer_pending(&bfqd->idle_slice_timer)) { ++ /* ++ * Expiring the queue because there is a close cooperator, ++ * cancel timer. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ del_timer(&bfqd->idle_slice_timer); ++ } ++ ++ reason = BFQ_BFQQ_NO_MORE_REQUESTS; ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, 0, reason); ++new_queue: ++ bfqq = bfq_set_in_service_queue(bfqd, new_bfqq); ++ bfq_log(bfqd, "select_queue: new queue %d returned", ++ bfqq != NULL ? bfqq->pid : 0); ++keep_queue: ++ return bfqq; ++} ++ ++static void bfq_update_wr_data(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq->wr_coeff > 1) { /* queue is being boosted */ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "raising period dur %u/%u msec, old coeff %u, w %d(%d)", ++ jiffies_to_msecs(jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time), ++ bfqq->wr_coeff, ++ bfqq->entity.weight, bfqq->entity.orig_weight); ++ ++ BUG_ON(bfqq != bfqd->in_service_queue && entity->weight != ++ entity->orig_weight * bfqq->wr_coeff); ++ if (entity->ioprio_changed) ++ bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); ++ /* ++ * If the queue was activated in a burst, or ++ * too much time has elapsed from the beginning ++ * of this weight-raising, then end weight raising. ++ */ ++ if (bfq_bfqq_in_large_burst(bfqq) || ++ time_is_before_jiffies(bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time)) { ++ bfqq->last_wr_start_finish = jiffies; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais ending at %lu, rais_max_time %u", ++ bfqq->last_wr_start_finish, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ bfq_bfqq_end_wr(bfqq); ++ __bfq_entity_update_weight_prio( ++ bfq_entity_service_tree(entity), ++ entity); ++ } ++ } ++} ++ ++/* ++ * Dispatch one request from bfqq, moving it to the request queue ++ * dispatch list. ++ */ ++static int bfq_dispatch_request(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ struct request *rq; ++ unsigned long service_to_charge; ++ ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Follow expired path, else get first next available. */ ++ rq = bfq_check_fifo(bfqq); ++ if (rq == NULL) ++ rq = bfqq->next_rq; ++ service_to_charge = bfq_serv_to_charge(rq, bfqq); ++ ++ if (service_to_charge > bfq_bfqq_budget_left(bfqq)) { ++ /* ++ * This may happen if the next rq is chosen in fifo order ++ * instead of sector order. The budget is properly ++ * dimensioned to be always sufficient to serve the next ++ * request only if it is chosen in sector order. The reason ++ * is that it would be quite inefficient and little useful ++ * to always make sure that the budget is large enough to ++ * serve even the possible next rq in fifo order. ++ * In fact, requests are seldom served in fifo order. ++ * ++ * Expire the queue for budget exhaustion, and make sure ++ * that the next act_budget is enough to serve the next ++ * request, even if it comes from the fifo expired path. ++ */ ++ bfqq->next_rq = rq; ++ /* ++ * Since this dispatch is failed, make sure that ++ * a new one will be performed ++ */ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ goto expire; ++ } ++ ++ /* Finally, insert request into driver dispatch list. */ ++ bfq_bfqq_served(bfqq, service_to_charge); ++ bfq_dispatch_insert(bfqd->queue, rq); ++ ++ bfq_update_wr_data(bfqd, bfqq); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "dispatched %u sec req (%llu), budg left %lu", ++ blk_rq_sectors(rq), ++ (long long unsigned)blk_rq_pos(rq), ++ bfq_bfqq_budget_left(bfqq)); ++ ++ dispatched++; ++ ++ if (bfqd->in_service_bic == NULL) { ++ atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount); ++ bfqd->in_service_bic = RQ_BIC(rq); ++ } ++ ++ if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) && ++ dispatched >= bfqd->bfq_max_budget_async_rq) || ++ bfq_class_idle(bfqq))) ++ goto expire; ++ ++ return dispatched; ++ ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_EXHAUSTED); ++ return dispatched; ++} ++ ++static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ ++ while (bfqq->next_rq != NULL) { ++ bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq); ++ dispatched++; ++ } ++ ++ BUG_ON(!list_empty(&bfqq->fifo)); ++ return dispatched; ++} ++ ++/* ++ * Drain our current requests. ++ * Used for barriers and when switching io schedulers on-the-fly. ++ */ ++static int bfq_forced_dispatch(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq, *n; ++ struct bfq_service_tree *st; ++ int dispatched = 0; ++ ++ bfqq = bfqd->in_service_queue; ++ if (bfqq != NULL) ++ __bfq_bfqq_expire(bfqd, bfqq); ++ ++ /* ++ * Loop through classes, and be careful to leave the scheduler ++ * in a consistent state, as feedback mechanisms and vtime ++ * updates cannot be disabled during the process. ++ */ ++ list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) { ++ st = bfq_entity_service_tree(&bfqq->entity); ++ ++ dispatched += __bfq_forced_dispatch_bfqq(bfqq); ++ bfqq->max_budget = bfq_max_budget(bfqd); ++ ++ bfq_forget_idle(st); ++ } ++ ++ BUG_ON(bfqd->busy_queues != 0); ++ ++ return dispatched; ++} ++ ++static int bfq_dispatch_requests(struct request_queue *q, int force) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq; ++ int max_dispatch; ++ ++ bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues); ++ if (bfqd->busy_queues == 0) ++ return 0; ++ ++ if (unlikely(force)) ++ return bfq_forced_dispatch(bfqd); ++ ++ bfqq = bfq_select_queue(bfqd); ++ if (bfqq == NULL) ++ return 0; ++ ++ if (bfq_class_idle(bfqq)) ++ max_dispatch = 1; ++ ++ if (!bfq_bfqq_sync(bfqq)) ++ max_dispatch = bfqd->bfq_max_budget_async_rq; ++ ++ if (!bfq_bfqq_sync(bfqq) && bfqq->dispatched >= max_dispatch) { ++ if (bfqd->busy_queues > 1) ++ return 0; ++ if (bfqq->dispatched >= 4 * max_dispatch) ++ return 0; ++ } ++ ++ if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq)) ++ return 0; ++ ++ bfq_clear_bfqq_wait_request(bfqq); ++ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); ++ ++ if (!bfq_dispatch_request(bfqd, bfqq)) ++ return 0; ++ ++ bfq_log_bfqq(bfqd, bfqq, "dispatched %s request", ++ bfq_bfqq_sync(bfqq) ? "sync" : "async"); ++ ++ return 1; ++} ++ ++/* ++ * Task holds one reference to the queue, dropped when task exits. Each rq ++ * in-flight on this queue also holds a reference, dropped when rq is freed. ++ * ++ * Queue lock must be held here. ++ */ ++static void bfq_put_queue(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ BUG_ON(atomic_read(&bfqq->ref) <= 0); ++ ++ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ if (!atomic_dec_and_test(&bfqq->ref)) ++ return; ++ ++ BUG_ON(rb_first(&bfqq->sort_list) != NULL); ++ BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0); ++ BUG_ON(bfqq->entity.tree != NULL); ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqd->in_service_queue == bfqq); ++ ++ if (bfq_bfqq_sync(bfqq)) ++ /* ++ * The fact that this queue is being destroyed does not ++ * invalidate the fact that this queue may have been ++ * activated during the current burst. As a consequence, ++ * although the queue does not exist anymore, and hence ++ * needs to be removed from the burst list if there, ++ * the burst size has not to be decremented. ++ */ ++ hlist_del_init(&bfqq->burst_list_node); ++ ++ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq); ++ ++ kmem_cache_free(bfq_pool, bfqq); ++} ++ ++static void bfq_put_cooperator(struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *__bfqq, *next; ++ ++ /* ++ * If this queue was scheduled to merge with another queue, be ++ * sure to drop the reference taken on that queue (and others in ++ * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs. ++ */ ++ __bfqq = bfqq->new_bfqq; ++ while (__bfqq) { ++ if (__bfqq == bfqq) ++ break; ++ next = __bfqq->new_bfqq; ++ bfq_put_queue(__bfqq); ++ __bfqq = next; ++ } ++} ++ ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ if (bfqq == bfqd->in_service_queue) { ++ __bfq_bfqq_expire(bfqd, bfqq); ++ bfq_schedule_dispatch(bfqd); ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++} ++ ++static inline void bfq_init_icq(struct io_cq *icq) ++{ ++ struct bfq_io_cq *bic = icq_to_bic(icq); ++ ++ bic->ttime.last_end_request = jiffies; ++} ++ ++static void bfq_exit_icq(struct io_cq *icq) ++{ ++ struct bfq_io_cq *bic = icq_to_bic(icq); ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ ++ if (bic->bfqq[BLK_RW_ASYNC]) { ++ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]); ++ bic->bfqq[BLK_RW_ASYNC] = NULL; ++ } ++ ++ if (bic->bfqq[BLK_RW_SYNC]) { ++ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); ++ bic->bfqq[BLK_RW_SYNC] = NULL; ++ } ++} ++ ++/* ++ * Update the entity prio values; note that the new values will not ++ * be used until the next (re)activation. ++ */ ++static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) ++{ ++ struct task_struct *tsk = current; ++ struct io_context *ioc = bic->icq.ioc; ++ int ioprio_class; ++ ++ ioprio_class = IOPRIO_PRIO_CLASS(ioc->ioprio); ++ switch (ioprio_class) { ++ default: ++ dev_err(bfqq->bfqd->queue->backing_dev_info.dev, ++ "bfq: bad prio class %d\n", ioprio_class); ++ case IOPRIO_CLASS_NONE: ++ /* ++ * No prio set, inherit CPU scheduling settings. ++ */ ++ bfqq->entity.new_ioprio = task_nice_ioprio(tsk); ++ bfqq->entity.new_ioprio_class = task_nice_ioclass(tsk); ++ break; ++ case IOPRIO_CLASS_RT: ++ bfqq->entity.new_ioprio = task_ioprio(ioc); ++ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_RT; ++ break; ++ case IOPRIO_CLASS_BE: ++ bfqq->entity.new_ioprio = task_ioprio(ioc); ++ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_BE; ++ break; ++ case IOPRIO_CLASS_IDLE: ++ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_IDLE; ++ bfqq->entity.new_ioprio = 7; ++ bfq_clear_bfqq_idle_window(bfqq); ++ break; ++ } ++ ++ if (bfqq->entity.new_ioprio < 0 || ++ bfqq->entity.new_ioprio >= IOPRIO_BE_NR) { ++ printk(KERN_CRIT "bfq_set_next_ioprio_data: new_ioprio %d\n", ++ bfqq->entity.new_ioprio); ++ BUG(); ++ } ++ ++ bfqq->entity.new_weight = bfq_ioprio_to_weight(bfqq->entity.new_ioprio); ++ bfqq->entity.ioprio_changed = 1; ++} ++ ++static void bfq_check_ioprio_change(struct io_context *ioc, ++ struct bfq_io_cq *bic) ++{ ++ struct bfq_data *bfqd; ++ struct bfq_queue *bfqq, *new_bfqq; ++ struct bfq_group *bfqg; ++ unsigned long uninitialized_var(flags); ++ int ioprio = bic->icq.ioc->ioprio; ++ ++ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), ++ &flags); ++ if (unlikely(bfqd == NULL)) ++ return; ++ ++ bic->ioprio = ioprio; ++ ++ bfqq = bic->bfqq[BLK_RW_ASYNC]; ++ if (bfqq != NULL) { ++ bfqg = container_of(bfqq->entity.sched_data, struct bfq_group, ++ sched_data); ++ new_bfqq = bfq_get_queue(bfqd, bfqg, BLK_RW_ASYNC, bic->icq.ioc, ++ GFP_ATOMIC); ++ if (new_bfqq != NULL) { ++ bic->bfqq[BLK_RW_ASYNC] = new_bfqq; ++ bfq_log_bfqq(bfqd, bfqq, ++ "check_ioprio_change: bfqq %p %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ } ++ } ++ ++ bfqq = bic->bfqq[BLK_RW_SYNC]; ++ if (bfqq != NULL) ++ bfq_set_next_ioprio_data(bfqq, bic); ++ ++ bfq_put_bfqd_unlock(bfqd, &flags); ++} ++ ++static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic, pid_t pid, int is_sync) ++{ ++ RB_CLEAR_NODE(&bfqq->entity.rb_node); ++ INIT_LIST_HEAD(&bfqq->fifo); ++ INIT_HLIST_NODE(&bfqq->burst_list_node); ++ ++ atomic_set(&bfqq->ref, 0); ++ bfqq->bfqd = bfqd; ++ ++ if (bic) ++ bfq_set_next_ioprio_data(bfqq, bic); ++ ++ if (is_sync) { ++ if (!bfq_class_idle(bfqq)) ++ bfq_mark_bfqq_idle_window(bfqq); ++ bfq_mark_bfqq_sync(bfqq); ++ } ++ bfq_mark_bfqq_IO_bound(bfqq); ++ ++ /* Tentative initial value to trade off between thr and lat */ ++ bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3; ++ bfqq->pid = pid; ++ ++ bfqq->wr_coeff = 1; ++ bfqq->last_wr_start_finish = 0; ++ /* ++ * Set to the value for which bfqq will not be deemed as ++ * soft rt when it becomes backlogged. ++ */ ++ bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies); ++} ++ ++static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ int is_sync, ++ struct io_context *ioc, ++ gfp_t gfp_mask) ++{ ++ struct bfq_queue *bfqq, *new_bfqq = NULL; ++ struct bfq_io_cq *bic; ++ ++retry: ++ bic = bfq_bic_lookup(bfqd, ioc); ++ /* bic always exists here */ ++ bfqq = bic_to_bfqq(bic, is_sync); ++ ++ /* ++ * Always try a new alloc if we fall back to the OOM bfqq ++ * originally, since it should just be a temporary situation. ++ */ ++ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { ++ bfqq = NULL; ++ if (new_bfqq != NULL) { ++ bfqq = new_bfqq; ++ new_bfqq = NULL; ++ } else if (gfp_mask & __GFP_WAIT) { ++ spin_unlock_irq(bfqd->queue->queue_lock); ++ new_bfqq = kmem_cache_alloc_node(bfq_pool, ++ gfp_mask | __GFP_ZERO, ++ bfqd->queue->node); ++ spin_lock_irq(bfqd->queue->queue_lock); ++ if (new_bfqq != NULL) ++ goto retry; ++ } else { ++ bfqq = kmem_cache_alloc_node(bfq_pool, ++ gfp_mask | __GFP_ZERO, ++ bfqd->queue->node); ++ } ++ ++ if (bfqq != NULL) { ++ bfq_init_bfqq(bfqd, bfqq, bic, current->pid, ++ is_sync); ++ bfq_init_entity(&bfqq->entity, bfqg); ++ bfq_log_bfqq(bfqd, bfqq, "allocated"); ++ } else { ++ bfqq = &bfqd->oom_bfqq; ++ bfq_log_bfqq(bfqd, bfqq, "using oom bfqq"); ++ } ++ } ++ ++ if (new_bfqq != NULL) ++ kmem_cache_free(bfq_pool, new_bfqq); ++ ++ return bfqq; ++} ++ ++static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ int ioprio_class, int ioprio) ++{ ++ switch (ioprio_class) { ++ case IOPRIO_CLASS_RT: ++ return &bfqg->async_bfqq[0][ioprio]; ++ case IOPRIO_CLASS_BE: ++ return &bfqg->async_bfqq[1][ioprio]; ++ case IOPRIO_CLASS_IDLE: ++ return &bfqg->async_idle_bfqq; ++ default: ++ BUG(); ++ } ++} ++ ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, int is_sync, ++ struct io_context *ioc, gfp_t gfp_mask) ++{ ++ const int ioprio = task_ioprio(ioc); ++ const int ioprio_class = task_ioprio_class(ioc); ++ struct bfq_queue **async_bfqq = NULL; ++ struct bfq_queue *bfqq = NULL; ++ ++ if (!is_sync) { ++ async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class, ++ ioprio); ++ bfqq = *async_bfqq; ++ } ++ ++ if (bfqq == NULL) ++ bfqq = bfq_find_alloc_queue(bfqd, bfqg, is_sync, ioc, gfp_mask); ++ ++ /* ++ * Pin the queue now that it's allocated, scheduler exit will ++ * prune it. ++ */ ++ if (!is_sync && *async_bfqq == NULL) { ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ *async_bfqq = bfqq; ++ } ++ ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ return bfqq; ++} ++ ++static void bfq_update_io_thinktime(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic) ++{ ++ unsigned long elapsed = jiffies - bic->ttime.last_end_request; ++ unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle); ++ ++ bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8; ++ bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8; ++ bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) / ++ bic->ttime.ttime_samples; ++} ++ ++static void bfq_update_io_seektime(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ sector_t sdist; ++ u64 total; ++ ++ if (bfqq->last_request_pos < blk_rq_pos(rq)) ++ sdist = blk_rq_pos(rq) - bfqq->last_request_pos; ++ else ++ sdist = bfqq->last_request_pos - blk_rq_pos(rq); ++ ++ /* ++ * Don't allow the seek distance to get too large from the ++ * odd fragment, pagein, etc. ++ */ ++ if (bfqq->seek_samples == 0) /* first request, not really a seek */ ++ sdist = 0; ++ else if (bfqq->seek_samples <= 60) /* second & third seek */ ++ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024); ++ else ++ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64); ++ ++ bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8; ++ bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8; ++ total = bfqq->seek_total + (bfqq->seek_samples/2); ++ do_div(total, bfqq->seek_samples); ++ bfqq->seek_mean = (sector_t)total; ++ ++ bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist, ++ (u64)bfqq->seek_mean); ++} ++ ++/* ++ * Disable idle window if the process thinks too long or seeks so much that ++ * it doesn't matter. ++ */ ++static void bfq_update_idle_window(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic) ++{ ++ int enable_idle; ++ ++ /* Don't idle for async or idle io prio class. */ ++ if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) ++ return; ++ ++ enable_idle = bfq_bfqq_idle_window(bfqq); ++ ++ if (atomic_read(&bic->icq.ioc->nr_tasks) == 0 || ++ bfqd->bfq_slice_idle == 0 || ++ (bfqd->hw_tag && BFQQ_SEEKY(bfqq) && ++ bfqq->wr_coeff == 1)) ++ enable_idle = 0; ++ else if (bfq_sample_valid(bic->ttime.ttime_samples)) { ++ if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle && ++ bfqq->wr_coeff == 1) ++ enable_idle = 0; ++ else ++ enable_idle = 1; ++ } ++ bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d", ++ enable_idle); ++ ++ if (enable_idle) ++ bfq_mark_bfqq_idle_window(bfqq); ++ else ++ bfq_clear_bfqq_idle_window(bfqq); ++} ++ ++/* ++ * Called when a new fs request (rq) is added to bfqq. Check if there's ++ * something we should do about it. ++ */ ++static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ struct bfq_io_cq *bic = RQ_BIC(rq); ++ ++ if (rq->cmd_flags & REQ_META) ++ bfqq->meta_pending++; ++ ++ bfq_update_io_thinktime(bfqd, bic); ++ bfq_update_io_seektime(bfqd, bfqq, rq); ++ if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) { ++ bfq_clear_bfqq_constantly_seeky(bfqq); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ BUG_ON(!bfqd->const_seeky_busy_in_flight_queues); ++ bfqd->const_seeky_busy_in_flight_queues--; ++ } ++ } ++ if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || ++ !BFQQ_SEEKY(bfqq)) ++ bfq_update_idle_window(bfqd, bfqq, bic); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", ++ bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq), ++ (long long unsigned)bfqq->seek_mean); ++ ++ bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ ++ if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) { ++ int small_req = bfqq->queued[rq_is_sync(rq)] == 1 && ++ blk_rq_sectors(rq) < 32; ++ int budget_timeout = bfq_bfqq_budget_timeout(bfqq); ++ ++ /* ++ * There is just this request queued: if the request ++ * is small and the queue is not to be expired, then ++ * just exit. ++ * ++ * In this way, if the disk is being idled to wait for ++ * a new request from the in-service queue, we avoid ++ * unplugging the device and committing the disk to serve ++ * just a small request. On the contrary, we wait for ++ * the block layer to decide when to unplug the device: ++ * hopefully, new requests will be merged to this one ++ * quickly, then the device will be unplugged and ++ * larger requests will be dispatched. ++ */ ++ if (small_req && !budget_timeout) ++ return; ++ ++ /* ++ * A large enough request arrived, or the queue is to ++ * be expired: in both cases disk idling is to be ++ * stopped, so clear wait_request flag and reset ++ * timer. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ del_timer(&bfqd->idle_slice_timer); ++ ++ /* ++ * The queue is not empty, because a new request just ++ * arrived. Hence we can safely expire the queue, in ++ * case of budget timeout, without risking that the ++ * timestamps of the queue are not updated correctly. ++ * See [1] for more details. ++ */ ++ if (budget_timeout) ++ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); ++ ++ /* ++ * Let the request rip immediately, or let a new queue be ++ * selected if bfqq has just been expired. ++ */ ++ __blk_run_queue(bfqd->queue); ++ } ++} ++ ++static void bfq_insert_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ ++ bfq_add_request(rq); ++ ++ rq_set_fifo_time(rq, jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]); ++ list_add_tail(&rq->queuelist, &bfqq->fifo); ++ ++ bfq_rq_enqueued(bfqd, bfqq, rq); ++} ++ ++static void bfq_update_hw_tag(struct bfq_data *bfqd) ++{ ++ bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver, ++ bfqd->rq_in_driver); ++ ++ if (bfqd->hw_tag == 1) ++ return; ++ ++ /* ++ * This sample is valid if the number of outstanding requests ++ * is large enough to allow a queueing behavior. Note that the ++ * sum is not exact, as it's not taking into account deactivated ++ * requests. ++ */ ++ if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD) ++ return; ++ ++ if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES) ++ return; ++ ++ bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD; ++ bfqd->max_rq_in_driver = 0; ++ bfqd->hw_tag_samples = 0; ++} ++ ++static void bfq_completed_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ bool sync = bfq_bfqq_sync(bfqq); ++ ++ bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)", ++ blk_rq_sectors(rq), sync); ++ ++ bfq_update_hw_tag(bfqd); ++ ++ BUG_ON(!bfqd->rq_in_driver); ++ BUG_ON(!bfqq->dispatched); ++ bfqd->rq_in_driver--; ++ bfqq->dispatched--; ++ ++ if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) { ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ BUG_ON(!bfqd->busy_in_flight_queues); ++ bfqd->busy_in_flight_queues--; ++ if (bfq_bfqq_constantly_seeky(bfqq)) { ++ BUG_ON(!bfqd-> ++ const_seeky_busy_in_flight_queues); ++ bfqd->const_seeky_busy_in_flight_queues--; ++ } ++ } ++ } ++ ++ if (sync) { ++ bfqd->sync_flight--; ++ RQ_BIC(rq)->ttime.last_end_request = jiffies; ++ } ++ ++ /* ++ * If we are waiting to discover whether the request pattern of the ++ * task associated with the queue is actually isochronous, and ++ * both requisites for this condition to hold are satisfied, then ++ * compute soft_rt_next_start (see the comments to the function ++ * bfq_bfqq_softrt_next_start()). ++ */ ++ if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ ++ /* ++ * If this is the in-service queue, check if it needs to be expired, ++ * or if we want to idle in case it has no pending requests. ++ */ ++ if (bfqd->in_service_queue == bfqq) { ++ if (bfq_bfqq_budget_new(bfqq)) ++ bfq_set_budget_timeout(bfqd); ++ ++ if (bfq_bfqq_must_idle(bfqq)) { ++ bfq_arm_slice_timer(bfqd); ++ goto out; ++ } else if (bfq_may_expire_for_budg_timeout(bfqq)) ++ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); ++ else if (RB_EMPTY_ROOT(&bfqq->sort_list) && ++ (bfqq->dispatched == 0 || ++ !bfq_bfqq_must_not_expire(bfqq))) ++ bfq_bfqq_expire(bfqd, bfqq, 0, ++ BFQ_BFQQ_NO_MORE_REQUESTS); ++ } ++ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ ++out: ++ return; ++} ++ ++static inline int __bfq_may_queue(struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) { ++ bfq_clear_bfqq_must_alloc(bfqq); ++ return ELV_MQUEUE_MUST; ++ } ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++static int bfq_may_queue(struct request_queue *q, int rw) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ /* ++ * Don't force setup of a queue from here, as a call to may_queue ++ * does not necessarily imply that a request actually will be ++ * queued. So just lookup a possibly existing queue, or return ++ * 'may queue' if that fails. ++ */ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (bic == NULL) ++ return ELV_MQUEUE_MAY; ++ ++ bfqq = bic_to_bfqq(bic, rw_is_sync(rw)); ++ if (bfqq != NULL) ++ return __bfq_may_queue(bfqq); ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++/* ++ * Queue lock held here. ++ */ ++static void bfq_put_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ if (bfqq != NULL) { ++ const int rw = rq_data_dir(rq); ++ ++ BUG_ON(!bfqq->allocated[rw]); ++ bfqq->allocated[rw]--; ++ ++ rq->elv.priv[0] = NULL; ++ rq->elv.priv[1] = NULL; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++static struct bfq_queue * ++bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", ++ (long unsigned)bfqq->new_bfqq->pid); ++ bic_set_bfqq(bic, bfqq->new_bfqq, 1); ++ bfq_mark_bfqq_coop(bfqq->new_bfqq); ++ bfq_put_queue(bfqq); ++ return bic_to_bfqq(bic, 1); ++} ++ ++/* ++ * Returns NULL if a new bfqq should be allocated, or the old bfqq if this ++ * was the last process referring to said bfqq. ++ */ ++static struct bfq_queue * ++bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); ++ if (bfqq_process_refs(bfqq) == 1) { ++ bfqq->pid = current->pid; ++ bfq_clear_bfqq_coop(bfqq); ++ bfq_clear_bfqq_split_coop(bfqq); ++ return bfqq; ++ } ++ ++ bic_set_bfqq(bic, NULL, 1); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++ return NULL; ++} ++ ++/* ++ * Allocate bfq data structures associated with this request. ++ */ ++static int bfq_set_request(struct request_queue *q, struct request *rq, ++ gfp_t gfp_mask) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq); ++ const int rw = rq_data_dir(rq); ++ const int is_sync = rq_is_sync(rq); ++ struct bfq_queue *bfqq; ++ struct bfq_group *bfqg; ++ unsigned long flags; ++ ++ /* handle changed prio notifications; cgroup change is handled separately */ ++ if (unlikely(icq_get_changed(&bic->icq) & ICQ_IOPRIO_CHANGED)) ++ bfq_check_ioprio_change(bic->icq.ioc, bic); ++ ++ might_sleep_if(gfp_mask & __GFP_WAIT); ++ ++ spin_lock_irqsave(q->queue_lock, flags); ++ ++ if (bic == NULL) ++ goto queue_fail; ++ ++ bfqg = bfq_bic_update_cgroup(bic); ++ ++new_queue: ++ bfqq = bic_to_bfqq(bic, is_sync); ++ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { ++ bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic->icq.ioc, gfp_mask); ++ bic_set_bfqq(bic, bfqq, is_sync); ++ } else { ++ /* ++ * If the queue was seeky for too long, break it apart. ++ */ ++ if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { ++ bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); ++ bfqq = bfq_split_bfqq(bic, bfqq); ++ if (!bfqq) ++ goto new_queue; ++ } ++ ++ /* ++ * Check to see if this queue is scheduled to merge with ++ * another closely cooperating queue. The merging of queues ++ * happens here as it must be done in process context. ++ * The reference on new_bfqq was taken in merge_bfqqs. ++ */ ++ if (bfqq->new_bfqq != NULL) ++ bfqq = bfq_merge_bfqqs(bfqd, bic, bfqq); ++ } ++ ++ bfqq->allocated[rw]++; ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ ++ rq->elv.priv[0] = bic; ++ rq->elv.priv[1] = bfqq; ++ ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 0; ++ ++queue_fail: ++ bfq_schedule_dispatch(bfqd); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 1; ++} ++ ++static void bfq_kick_queue(struct work_struct *work) ++{ ++ struct bfq_data *bfqd = ++ container_of(work, struct bfq_data, unplug_work); ++ struct request_queue *q = bfqd->queue; ++ ++ spin_lock_irq(q->queue_lock); ++ __blk_run_queue(q); ++ spin_unlock_irq(q->queue_lock); ++} ++ ++/* ++ * Handler of the expiration of the timer running if the in-service queue ++ * is idling inside its time slice. ++ */ ++static void bfq_idle_slice_timer(unsigned long data) ++{ ++ struct bfq_data *bfqd = (struct bfq_data *)data; ++ struct bfq_queue *bfqq; ++ unsigned long flags; ++ enum bfqq_expiration reason; ++ ++ spin_lock_irqsave(bfqd->queue->queue_lock, flags); ++ ++ bfqq = bfqd->in_service_queue; ++ /* ++ * Theoretical race here: the in-service queue can be NULL or ++ * different from the queue that was idling if the timer handler ++ * spins on the queue_lock and a new request arrives for the ++ * current queue and there is a full dispatch cycle that changes ++ * the in-service queue. This can hardly happen, but in the worst ++ * case we just expire a queue too early. ++ */ ++ if (bfqq != NULL) { ++ bfq_log_bfqq(bfqd, bfqq, "slice_timer expired"); ++ if (bfq_bfqq_budget_timeout(bfqq)) ++ /* ++ * Also here the queue can be safely expired ++ * for budget timeout without wasting ++ * guarantees ++ */ ++ reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0) ++ /* ++ * The queue may not be empty upon timer expiration, ++ * because we may not disable the timer when the ++ * first request of the in-service queue arrives ++ * during disk idling. ++ */ ++ reason = BFQ_BFQQ_TOO_IDLE; ++ else ++ goto schedule_dispatch; ++ ++ bfq_bfqq_expire(bfqd, bfqq, 1, reason); ++ } ++ ++schedule_dispatch: ++ bfq_schedule_dispatch(bfqd); ++ ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, flags); ++} ++ ++static void bfq_shutdown_timer_wq(struct bfq_data *bfqd) ++{ ++ del_timer_sync(&bfqd->idle_slice_timer); ++ cancel_work_sync(&bfqd->unplug_work); ++} ++ ++static inline void __bfq_put_async_bfqq(struct bfq_data *bfqd, ++ struct bfq_queue **bfqq_ptr) ++{ ++ struct bfq_group *root_group = bfqd->root_group; ++ struct bfq_queue *bfqq = *bfqq_ptr; ++ ++ bfq_log(bfqd, "put_async_bfqq: %p", bfqq); ++ if (bfqq != NULL) { ++ bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group); ++ bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ *bfqq_ptr = NULL; ++ } ++} ++ ++/* ++ * Release all the bfqg references to its async queues. If we are ++ * deallocating the group these queues may still contain requests, so ++ * we reparent them to the root cgroup (i.e., the only one that will ++ * exist for sure until all the requests on a device are gone). ++ */ ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]); ++ ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq); ++} ++ ++static void bfq_exit_queue(struct elevator_queue *e) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ struct request_queue *q = bfqd->queue; ++ struct bfq_queue *bfqq, *n; ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ spin_lock_irq(q->queue_lock); ++ ++ BUG_ON(bfqd->in_service_queue != NULL); ++ list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ ++ bfq_disconnect_groups(bfqd); ++ spin_unlock_irq(q->queue_lock); ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ synchronize_rcu(); ++ ++ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); ++ ++ bfq_free_root_group(bfqd); ++ kfree(bfqd); ++} ++ ++static void *bfq_init_queue(struct request_queue *q) ++{ ++ struct bfq_group *bfqg; ++ struct bfq_data *bfqd; ++ ++ bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node); ++ if (bfqd == NULL) ++ return NULL; ++ ++ /* ++ * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues. ++ * Grab a permanent reference to it, so that the normal code flow ++ * will not attempt to free it. ++ */ ++ bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, NULL, 1, 0); ++ atomic_inc(&bfqd->oom_bfqq.ref); ++ bfqd->oom_bfqq.entity.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO; ++ bfqd->oom_bfqq.entity.new_ioprio_class = IOPRIO_CLASS_BE; ++ bfqd->oom_bfqq.entity.new_weight = ++ bfq_ioprio_to_weight(bfqd->oom_bfqq.entity.new_ioprio); ++ /* ++ * Trigger weight initialization, according to ioprio, at the ++ * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio ++ * class won't be changed any more. ++ */ ++ bfqd->oom_bfqq.entity.ioprio_changed = 1; ++ ++ bfqd->queue = q; ++ ++ bfqg = bfq_alloc_root_group(bfqd, q->node); ++ if (bfqg == NULL) { ++ kfree(bfqd); ++ return NULL; ++ } ++ ++ bfqd->root_group = bfqg; ++ bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); ++#ifdef CONFIG_CGROUP_BFQIO ++ bfqd->active_numerous_groups = 0; ++#endif ++ ++ init_timer(&bfqd->idle_slice_timer); ++ bfqd->idle_slice_timer.function = bfq_idle_slice_timer; ++ bfqd->idle_slice_timer.data = (unsigned long)bfqd; ++ ++ bfqd->rq_pos_tree = RB_ROOT; ++ bfqd->queue_weights_tree = RB_ROOT; ++ bfqd->group_weights_tree = RB_ROOT; ++ ++ INIT_WORK(&bfqd->unplug_work, bfq_kick_queue); ++ ++ INIT_LIST_HEAD(&bfqd->active_list); ++ INIT_LIST_HEAD(&bfqd->idle_list); ++ INIT_HLIST_HEAD(&bfqd->burst_list); ++ ++ bfqd->hw_tag = -1; ++ ++ bfqd->bfq_max_budget = bfq_default_max_budget; ++ ++ bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0]; ++ bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1]; ++ bfqd->bfq_back_max = bfq_back_max; ++ bfqd->bfq_back_penalty = bfq_back_penalty; ++ bfqd->bfq_slice_idle = bfq_slice_idle; ++ bfqd->bfq_class_idle_last_service = 0; ++ bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq; ++ bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async; ++ bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync; ++ ++ bfqd->bfq_coop_thresh = 2; ++ bfqd->bfq_failed_cooperations = 7000; ++ bfqd->bfq_requests_within_timer = 120; ++ ++ bfqd->bfq_large_burst_thresh = 11; ++ bfqd->bfq_burst_interval = msecs_to_jiffies(500); ++ ++ bfqd->low_latency = true; ++ ++ bfqd->bfq_wr_coeff = 20; ++ bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300); ++ bfqd->bfq_wr_max_time = 0; ++ bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000); ++ bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500); ++ bfqd->bfq_wr_max_softrt_rate = 7000; /* ++ * Approximate rate required ++ * to playback or record a ++ * high-definition compressed ++ * video. ++ */ ++ bfqd->wr_busy_queues = 0; ++ bfqd->busy_in_flight_queues = 0; ++ bfqd->const_seeky_busy_in_flight_queues = 0; ++ ++ /* ++ * Begin by assuming, optimistically, that the device peak rate is ++ * equal to the highest reference rate. ++ */ ++ bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] * ++ T_fast[blk_queue_nonrot(bfqd->queue)]; ++ bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)]; ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ ++ return bfqd; ++} ++ ++static void bfq_slab_kill(void) ++{ ++ if (bfq_pool != NULL) ++ kmem_cache_destroy(bfq_pool); ++} ++ ++static int __init bfq_slab_setup(void) ++{ ++ bfq_pool = KMEM_CACHE(bfq_queue, 0); ++ if (bfq_pool == NULL) ++ return -ENOMEM; ++ return 0; ++} ++ ++static ssize_t bfq_var_show(unsigned int var, char *page) ++{ ++ return sprintf(page, "%d\n", var); ++} ++ ++static ssize_t bfq_var_store(unsigned long *var, const char *page, ++ size_t count) ++{ ++ unsigned long new_val; ++ int ret = kstrtoul(page, 10, &new_val); ++ ++ if (ret == 0) ++ *var = new_val; ++ ++ return count; ++} ++ ++static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ? ++ jiffies_to_msecs(bfqd->bfq_wr_max_time) : ++ jiffies_to_msecs(bfq_wr_duration(bfqd))); ++} ++ ++static ssize_t bfq_weights_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_queue *bfqq; ++ struct bfq_data *bfqd = e->elevator_data; ++ ssize_t num_char = 0; ++ ++ num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n", ++ bfqd->queued); ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ num_char += sprintf(page + num_char, "Active:\n"); ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, nr_queued %d %d, dur %d/%u\n", ++ bfqq->pid, ++ bfqq->entity.weight, ++ bfqq->queued[0], ++ bfqq->queued[1], ++ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ num_char += sprintf(page + num_char, "Idle:\n"); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, dur %d/%u\n", ++ bfqq->pid, ++ bfqq->entity.weight, ++ jiffies_to_msecs(jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++ ++ return num_char; ++} ++ ++#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ ++static ssize_t __FUNC(struct elevator_queue *e, char *page) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned int __data = __VAR; \ ++ if (__CONV) \ ++ __data = jiffies_to_msecs(__data); \ ++ return bfq_var_show(__data, (page)); \ ++} ++SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1); ++SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1); ++SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0); ++SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0); ++SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1); ++SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0); ++SHOW_FUNCTION(bfq_max_budget_async_rq_show, ++ bfqd->bfq_max_budget_async_rq, 0); ++SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1); ++SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1); ++SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0); ++SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0); ++SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1); ++SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1); ++SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async, ++ 1); ++SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0); ++#undef SHOW_FUNCTION ++ ++#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ ++static ssize_t \ ++__FUNC(struct elevator_queue *e, const char *page, size_t count) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned long uninitialized_var(__data); \ ++ int ret = bfq_var_store(&__data, (page), count); \ ++ if (__data < (MIN)) \ ++ __data = (MIN); \ ++ else if (__data > (MAX)) \ ++ __data = (MAX); \ ++ if (__CONV) \ ++ *(__PTR) = msecs_to_jiffies(__data); \ ++ else \ ++ *(__PTR) = __data; \ ++ return ret; \ ++} ++STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0); ++STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1, ++ INT_MAX, 0); ++STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq, ++ 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX, ++ 1); ++STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_min_inter_arr_async_store, ++ &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0, ++ INT_MAX, 0); ++#undef STORE_FUNCTION ++ ++/* do nothing for the moment */ ++static ssize_t bfq_weights_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ return count; ++} ++ ++static inline unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd) ++{ ++ u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); ++ ++ if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES) ++ return bfq_calc_max_budget(bfqd->peak_rate, timeout); ++ else ++ return bfq_default_max_budget; ++} ++ ++static ssize_t bfq_max_budget_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data == 0) ++ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); ++ else { ++ if (__data > INT_MAX) ++ __data = INT_MAX; ++ bfqd->bfq_max_budget = __data; ++ } ++ ++ bfqd->bfq_user_max_budget = __data; ++ ++ return ret; ++} ++ ++static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data < 1) ++ __data = 1; ++ else if (__data > INT_MAX) ++ __data = INT_MAX; ++ ++ bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data); ++ if (bfqd->bfq_user_max_budget == 0) ++ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); ++ ++ return ret; ++} ++ ++static ssize_t bfq_low_latency_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data > 1) ++ __data = 1; ++ if (__data == 0 && bfqd->low_latency != 0) ++ bfq_end_wr(bfqd); ++ bfqd->low_latency = __data; ++ ++ return ret; ++} ++ ++#define BFQ_ATTR(name) \ ++ __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store) ++ ++static struct elv_fs_entry bfq_attrs[] = { ++ BFQ_ATTR(fifo_expire_sync), ++ BFQ_ATTR(fifo_expire_async), ++ BFQ_ATTR(back_seek_max), ++ BFQ_ATTR(back_seek_penalty), ++ BFQ_ATTR(slice_idle), ++ BFQ_ATTR(max_budget), ++ BFQ_ATTR(max_budget_async_rq), ++ BFQ_ATTR(timeout_sync), ++ BFQ_ATTR(timeout_async), ++ BFQ_ATTR(low_latency), ++ BFQ_ATTR(wr_coeff), ++ BFQ_ATTR(wr_max_time), ++ BFQ_ATTR(wr_rt_max_time), ++ BFQ_ATTR(wr_min_idle_time), ++ BFQ_ATTR(wr_min_inter_arr_async), ++ BFQ_ATTR(wr_max_softrt_rate), ++ BFQ_ATTR(weights), ++ __ATTR_NULL ++}; ++ ++static struct elevator_type iosched_bfq = { ++ .ops = { ++ .elevator_merge_fn = bfq_merge, ++ .elevator_merged_fn = bfq_merged_request, ++ .elevator_merge_req_fn = bfq_merged_requests, ++ .elevator_allow_merge_fn = bfq_allow_merge, ++ .elevator_dispatch_fn = bfq_dispatch_requests, ++ .elevator_add_req_fn = bfq_insert_request, ++ .elevator_activate_req_fn = bfq_activate_request, ++ .elevator_deactivate_req_fn = bfq_deactivate_request, ++ .elevator_completed_req_fn = bfq_completed_request, ++ .elevator_former_req_fn = elv_rb_former_request, ++ .elevator_latter_req_fn = elv_rb_latter_request, ++ .elevator_init_icq_fn = bfq_init_icq, ++ .elevator_exit_icq_fn = bfq_exit_icq, ++ .elevator_set_req_fn = bfq_set_request, ++ .elevator_put_req_fn = bfq_put_request, ++ .elevator_may_queue_fn = bfq_may_queue, ++ .elevator_init_fn = bfq_init_queue, ++ .elevator_exit_fn = bfq_exit_queue, ++ }, ++ .icq_size = sizeof(struct bfq_io_cq), ++ .icq_align = __alignof__(struct bfq_io_cq), ++ .elevator_attrs = bfq_attrs, ++ .elevator_name = "bfq", ++ .elevator_owner = THIS_MODULE, ++}; ++ ++static int __init bfq_init(void) ++{ ++ /* ++ * Can be 0 on HZ < 1000 setups. ++ */ ++ if (bfq_slice_idle == 0) ++ bfq_slice_idle = 1; ++ ++ if (bfq_timeout_async == 0) ++ bfq_timeout_async = 1; ++ ++ if (bfq_slab_setup()) ++ return -ENOMEM; ++ ++ /* ++ * Times to load large popular applications for the typical systems ++ * installed on the reference devices (see the comments before the ++ * definitions of the two arrays). ++ */ ++ T_slow[0] = msecs_to_jiffies(2600); ++ T_slow[1] = msecs_to_jiffies(1000); ++ T_fast[0] = msecs_to_jiffies(5500); ++ T_fast[1] = msecs_to_jiffies(2000); ++ ++ /* ++ * Thresholds that determine the switch between speed classes (see ++ * the comments before the definition of the array). ++ */ ++ device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2; ++ device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2; ++ ++ elv_register(&iosched_bfq); ++ pr_info("BFQ I/O-scheduler: v7r8"); ++ ++ return 0; ++} ++ ++static void __exit bfq_exit(void) ++{ ++ elv_unregister(&iosched_bfq); ++ bfq_slab_kill(); ++} ++ ++module_init(bfq_init); ++module_exit(bfq_exit); ++ ++MODULE_AUTHOR("Fabio Checconi, Paolo Valente"); ++MODULE_LICENSE("GPL"); +diff --git a/block/bfq-sched.c b/block/bfq-sched.c +new file mode 100644 +index 0000000..c343099 +--- /dev/null ++++ b/block/bfq-sched.c +@@ -0,0 +1,1208 @@ ++/* ++ * BFQ: Hierarchical B-WF2Q+ scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++#ifdef CONFIG_CGROUP_BFQIO ++#define for_each_entity(entity) \ ++ for (; entity != NULL; entity = entity->parent) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (; entity && ({ parent = entity->parent; 1; }); entity = parent) ++ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd); ++ ++static inline void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++ struct bfq_entity *bfqg_entity; ++ struct bfq_group *bfqg; ++ struct bfq_sched_data *group_sd; ++ ++ BUG_ON(next_in_service == NULL); ++ ++ group_sd = next_in_service->sched_data; ++ ++ bfqg = container_of(group_sd, struct bfq_group, sched_data); ++ /* ++ * bfq_group's my_entity field is not NULL only if the group ++ * is not the root group. We must not touch the root entity ++ * as it must never become an in-service entity. ++ */ ++ bfqg_entity = bfqg->my_entity; ++ if (bfqg_entity != NULL) ++ bfqg_entity->budget = next_in_service->budget; ++} ++ ++static int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ struct bfq_entity *next_in_service; ++ ++ if (sd->in_service_entity != NULL) ++ /* will update/requeue at the end of service */ ++ return 0; ++ ++ /* ++ * NOTE: this can be improved in many ways, such as returning ++ * 1 (and thus propagating upwards the update) only when the ++ * budget changes, or caching the bfqq that will be scheduled ++ * next from this subtree. By now we worry more about ++ * correctness than about performance... ++ */ ++ next_in_service = bfq_lookup_next_entity(sd, 0, NULL); ++ sd->next_in_service = next_in_service; ++ ++ if (next_in_service != NULL) ++ bfq_update_budget(next_in_service); ++ ++ return 1; ++} ++ ++static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++ BUG_ON(sd->next_in_service != entity); ++} ++#else ++#define for_each_entity(entity) \ ++ for (; entity != NULL; entity = NULL) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (parent = NULL; entity != NULL; entity = parent) ++ ++static inline int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ return 0; ++} ++ ++static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++} ++ ++static inline void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++} ++#endif ++ ++/* ++ * Shift for timestamp calculations. This actually limits the maximum ++ * service allowed in one timestamp delta (small shift values increase it), ++ * the maximum total weight that can be used for the queues in the system ++ * (big shift values increase it), and the period of virtual time ++ * wraparounds. ++ */ ++#define WFQ_SERVICE_SHIFT 22 ++ ++/** ++ * bfq_gt - compare two timestamps. ++ * @a: first ts. ++ * @b: second ts. ++ * ++ * Return @a > @b, dealing with wrapping correctly. ++ */ ++static inline int bfq_gt(u64 a, u64 b) ++{ ++ return (s64)(a - b) > 0; ++} ++ ++static inline struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = NULL; ++ ++ BUG_ON(entity == NULL); ++ ++ if (entity->my_sched_data == NULL) ++ bfqq = container_of(entity, struct bfq_queue, entity); ++ ++ return bfqq; ++} ++ ++ ++/** ++ * bfq_delta - map service into the virtual time domain. ++ * @service: amount of service. ++ * @weight: scale factor (weight of an entity or weight sum). ++ */ ++static inline u64 bfq_delta(unsigned long service, ++ unsigned long weight) ++{ ++ u64 d = (u64)service << WFQ_SERVICE_SHIFT; ++ ++ do_div(d, weight); ++ return d; ++} ++ ++/** ++ * bfq_calc_finish - assign the finish time to an entity. ++ * @entity: the entity to act upon. ++ * @service: the service to be charged to the entity. ++ */ ++static inline void bfq_calc_finish(struct bfq_entity *entity, ++ unsigned long service) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ BUG_ON(entity->weight == 0); ++ ++ entity->finish = entity->start + ++ bfq_delta(service, entity->weight); ++ ++ if (bfqq != NULL) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: serv %lu, w %d", ++ service, entity->weight); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: start %llu, finish %llu, delta %llu", ++ entity->start, entity->finish, ++ bfq_delta(service, entity->weight)); ++ } ++} ++ ++/** ++ * bfq_entity_of - get an entity from a node. ++ * @node: the node field of the entity. ++ * ++ * Convert a node pointer to the relative entity. This is used only ++ * to simplify the logic of some functions and not as the generic ++ * conversion mechanism because, e.g., in the tree walking functions, ++ * the check for a %NULL value would be redundant. ++ */ ++static inline struct bfq_entity *bfq_entity_of(struct rb_node *node) ++{ ++ struct bfq_entity *entity = NULL; ++ ++ if (node != NULL) ++ entity = rb_entry(node, struct bfq_entity, rb_node); ++ ++ return entity; ++} ++ ++/** ++ * bfq_extract - remove an entity from a tree. ++ * @root: the tree root. ++ * @entity: the entity to remove. ++ */ ++static inline void bfq_extract(struct rb_root *root, ++ struct bfq_entity *entity) ++{ ++ BUG_ON(entity->tree != root); ++ ++ entity->tree = NULL; ++ rb_erase(&entity->rb_node, root); ++} ++ ++/** ++ * bfq_idle_extract - extract an entity from the idle tree. ++ * @st: the service tree of the owning @entity. ++ * @entity: the entity being removed. ++ */ ++static void bfq_idle_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *next; ++ ++ BUG_ON(entity->tree != &st->idle); ++ ++ if (entity == st->first_idle) { ++ next = rb_next(&entity->rb_node); ++ st->first_idle = bfq_entity_of(next); ++ } ++ ++ if (entity == st->last_idle) { ++ next = rb_prev(&entity->rb_node); ++ st->last_idle = bfq_entity_of(next); ++ } ++ ++ bfq_extract(&st->idle, entity); ++ ++ if (bfqq != NULL) ++ list_del(&bfqq->bfqq_list); ++} ++ ++/** ++ * bfq_insert - generic tree insertion. ++ * @root: tree root. ++ * @entity: entity to insert. ++ * ++ * This is used for the idle and the active tree, since they are both ++ * ordered by finish time. ++ */ ++static void bfq_insert(struct rb_root *root, struct bfq_entity *entity) ++{ ++ struct bfq_entity *entry; ++ struct rb_node **node = &root->rb_node; ++ struct rb_node *parent = NULL; ++ ++ BUG_ON(entity->tree != NULL); ++ ++ while (*node != NULL) { ++ parent = *node; ++ entry = rb_entry(parent, struct bfq_entity, rb_node); ++ ++ if (bfq_gt(entry->finish, entity->finish)) ++ node = &parent->rb_left; ++ else ++ node = &parent->rb_right; ++ } ++ ++ rb_link_node(&entity->rb_node, parent, node); ++ rb_insert_color(&entity->rb_node, root); ++ ++ entity->tree = root; ++} ++ ++/** ++ * bfq_update_min - update the min_start field of a entity. ++ * @entity: the entity to update. ++ * @node: one of its children. ++ * ++ * This function is called when @entity may store an invalid value for ++ * min_start due to updates to the active tree. The function assumes ++ * that the subtree rooted at @node (which may be its left or its right ++ * child) has a valid min_start value. ++ */ ++static inline void bfq_update_min(struct bfq_entity *entity, ++ struct rb_node *node) ++{ ++ struct bfq_entity *child; ++ ++ if (node != NULL) { ++ child = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entity->min_start, child->min_start)) ++ entity->min_start = child->min_start; ++ } ++} ++ ++/** ++ * bfq_update_active_node - recalculate min_start. ++ * @node: the node to update. ++ * ++ * @node may have changed position or one of its children may have moved, ++ * this function updates its min_start value. The left and right subtrees ++ * are assumed to hold a correct min_start value. ++ */ ++static inline void bfq_update_active_node(struct rb_node *node) ++{ ++ struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node); ++ ++ entity->min_start = entity->start; ++ bfq_update_min(entity, node->rb_right); ++ bfq_update_min(entity, node->rb_left); ++} ++ ++/** ++ * bfq_update_active_tree - update min_start for the whole active tree. ++ * @node: the starting node. ++ * ++ * @node must be the deepest modified node after an update. This function ++ * updates its min_start using the values held by its children, assuming ++ * that they did not change, and then updates all the nodes that may have ++ * changed in the path to the root. The only nodes that may have changed ++ * are the ones in the path or their siblings. ++ */ ++static void bfq_update_active_tree(struct rb_node *node) ++{ ++ struct rb_node *parent; ++ ++up: ++ bfq_update_active_node(node); ++ ++ parent = rb_parent(node); ++ if (parent == NULL) ++ return; ++ ++ if (node == parent->rb_left && parent->rb_right != NULL) ++ bfq_update_active_node(parent->rb_right); ++ else if (parent->rb_left != NULL) ++ bfq_update_active_node(parent->rb_left); ++ ++ node = parent; ++ goto up; ++} ++ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++ ++/** ++ * bfq_active_insert - insert an entity in the active tree of its ++ * group/device. ++ * @st: the service tree of the entity. ++ * @entity: the entity being inserted. ++ * ++ * The active tree is ordered by finish time, but an extra key is kept ++ * per each node, containing the minimum value for the start times of ++ * its children (and the node itself), so it's possible to search for ++ * the eligible node with the lowest finish time in logarithmic time. ++ */ ++static void bfq_active_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node = &entity->rb_node; ++#ifdef CONFIG_CGROUP_BFQIO ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ bfq_insert(&st->active, entity); ++ ++ if (node->rb_left != NULL) ++ node = node->rb_left; ++ else if (node->rb_right != NULL) ++ node = node->rb_right; ++ ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq != NULL) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list); ++#ifdef CONFIG_CGROUP_BFQIO ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ bfqg->active_entities++; ++ if (bfqg->active_entities == 2) ++ bfqd->active_numerous_groups++; ++ } ++#endif ++} ++ ++/** ++ * bfq_ioprio_to_weight - calc a weight from an ioprio. ++ * @ioprio: the ioprio value to convert. ++ */ ++static inline unsigned short bfq_ioprio_to_weight(int ioprio) ++{ ++ BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR); ++ return IOPRIO_BE_NR - ioprio; ++} ++ ++/** ++ * bfq_weight_to_ioprio - calc an ioprio from a weight. ++ * @weight: the weight value to convert. ++ * ++ * To preserve as mush as possible the old only-ioprio user interface, ++ * 0 is used as an escape ioprio value for weights (numerically) equal or ++ * larger than IOPRIO_BE_NR ++ */ ++static inline unsigned short bfq_weight_to_ioprio(int weight) ++{ ++ BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT); ++ return IOPRIO_BE_NR - weight < 0 ? 0 : IOPRIO_BE_NR - weight; ++} ++ ++static inline void bfq_get_entity(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ if (bfqq != NULL) { ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ } ++} ++ ++/** ++ * bfq_find_deepest - find the deepest node that an extraction can modify. ++ * @node: the node being removed. ++ * ++ * Do the first step of an extraction in an rb tree, looking for the ++ * node that will replace @node, and returning the deepest node that ++ * the following modifications to the tree can touch. If @node is the ++ * last node in the tree return %NULL. ++ */ ++static struct rb_node *bfq_find_deepest(struct rb_node *node) ++{ ++ struct rb_node *deepest; ++ ++ if (node->rb_right == NULL && node->rb_left == NULL) ++ deepest = rb_parent(node); ++ else if (node->rb_right == NULL) ++ deepest = node->rb_left; ++ else if (node->rb_left == NULL) ++ deepest = node->rb_right; ++ else { ++ deepest = rb_next(node); ++ if (deepest->rb_right != NULL) ++ deepest = deepest->rb_right; ++ else if (rb_parent(deepest) != node) ++ deepest = rb_parent(deepest); ++ } ++ ++ return deepest; ++} ++ ++/** ++ * bfq_active_extract - remove an entity from the active tree. ++ * @st: the service_tree containing the tree. ++ * @entity: the entity being removed. ++ */ ++static void bfq_active_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node; ++#ifdef CONFIG_CGROUP_BFQIO ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ node = bfq_find_deepest(&entity->rb_node); ++ bfq_extract(&st->active, entity); ++ ++ if (node != NULL) ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq != NULL) ++ list_del(&bfqq->bfqq_list); ++#ifdef CONFIG_CGROUP_BFQIO ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_remove(bfqd, entity, ++ &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ BUG_ON(!bfqg->active_entities); ++ bfqg->active_entities--; ++ if (bfqg->active_entities == 1) { ++ BUG_ON(!bfqd->active_numerous_groups); ++ bfqd->active_numerous_groups--; ++ } ++ } ++#endif ++} ++ ++/** ++ * bfq_idle_insert - insert an entity into the idle tree. ++ * @st: the service tree containing the tree. ++ * @entity: the entity to insert. ++ */ ++static void bfq_idle_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (first_idle == NULL || bfq_gt(first_idle->finish, entity->finish)) ++ st->first_idle = entity; ++ if (last_idle == NULL || bfq_gt(entity->finish, last_idle->finish)) ++ st->last_idle = entity; ++ ++ bfq_insert(&st->idle, entity); ++ ++ if (bfqq != NULL) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list); ++} ++ ++/** ++ * bfq_forget_entity - remove an entity from the wfq trees. ++ * @st: the service tree. ++ * @entity: the entity being removed. ++ * ++ * Update the device status and forget everything about @entity, putting ++ * the device reference to it, if it is a queue. Entities belonging to ++ * groups are not refcounted. ++ */ ++static void bfq_forget_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_sched_data *sd; ++ ++ BUG_ON(!entity->on_st); ++ ++ entity->on_st = 0; ++ st->wsum -= entity->weight; ++ if (bfqq != NULL) { ++ sd = entity->sched_data; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++/** ++ * bfq_put_idle_entity - release the idle tree ref of an entity. ++ * @st: service tree for the entity. ++ * @entity: the entity being released. ++ */ ++static void bfq_put_idle_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ bfq_idle_extract(st, entity); ++ bfq_forget_entity(st, entity); ++} ++ ++/** ++ * bfq_forget_idle - update the idle tree if necessary. ++ * @st: the service tree to act upon. ++ * ++ * To preserve the global O(log N) complexity we only remove one entry here; ++ * as the idle tree will not grow indefinitely this can be done safely. ++ */ ++static void bfq_forget_idle(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (RB_EMPTY_ROOT(&st->active) && last_idle != NULL && ++ !bfq_gt(last_idle->finish, st->vtime)) { ++ /* ++ * Forget the whole idle tree, increasing the vtime past ++ * the last finish time of idle entities. ++ */ ++ st->vtime = last_idle->finish; ++ } ++ ++ if (first_idle != NULL && !bfq_gt(first_idle->finish, st->vtime)) ++ bfq_put_idle_entity(st, first_idle); ++} ++ ++static struct bfq_service_tree * ++__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_service_tree *new_st = old_st; ++ ++ if (entity->ioprio_changed) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ unsigned short prev_weight, new_weight; ++ struct bfq_data *bfqd = NULL; ++ struct rb_root *root; ++#ifdef CONFIG_CGROUP_BFQIO ++ struct bfq_sched_data *sd; ++ struct bfq_group *bfqg; ++#endif ++ ++ if (bfqq != NULL) ++ bfqd = bfqq->bfqd; ++#ifdef CONFIG_CGROUP_BFQIO ++ else { ++ sd = entity->my_sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++ BUG_ON(!bfqd); ++ } ++#endif ++ ++ BUG_ON(old_st->wsum < entity->weight); ++ old_st->wsum -= entity->weight; ++ ++ if (entity->new_weight != entity->orig_weight) { ++ if (entity->new_weight < BFQ_MIN_WEIGHT || ++ entity->new_weight > BFQ_MAX_WEIGHT) { ++ printk(KERN_CRIT "update_weight_prio: " ++ "new_weight %d\n", ++ entity->new_weight); ++ BUG(); ++ } ++ entity->orig_weight = entity->new_weight; ++ entity->ioprio = ++ bfq_weight_to_ioprio(entity->orig_weight); ++ } ++ ++ entity->ioprio_class = entity->new_ioprio_class; ++ entity->ioprio_changed = 0; ++ ++ /* ++ * NOTE: here we may be changing the weight too early, ++ * this will cause unfairness. The correct approach ++ * would have required additional complexity to defer ++ * weight changes to the proper time instants (i.e., ++ * when entity->finish <= old_st->vtime). ++ */ ++ new_st = bfq_entity_service_tree(entity); ++ ++ prev_weight = entity->weight; ++ new_weight = entity->orig_weight * ++ (bfqq != NULL ? bfqq->wr_coeff : 1); ++ /* ++ * If the weight of the entity changes, remove the entity ++ * from its old weight counter (if there is a counter ++ * associated with the entity), and add it to the counter ++ * associated with its new weight. ++ */ ++ if (prev_weight != new_weight) { ++ root = bfqq ? &bfqd->queue_weights_tree : ++ &bfqd->group_weights_tree; ++ bfq_weights_tree_remove(bfqd, entity, root); ++ } ++ entity->weight = new_weight; ++ /* ++ * Add the entity to its weights tree only if it is ++ * not associated with a weight-raised queue. ++ */ ++ if (prev_weight != new_weight && ++ (bfqq ? bfqq->wr_coeff == 1 : 1)) ++ /* If we get here, root has been initialized. */ ++ bfq_weights_tree_add(bfqd, entity, root); ++ ++ new_st->wsum += entity->weight; ++ ++ if (new_st != old_st) ++ entity->start = new_st->vtime; ++ } ++ ++ return new_st; ++} ++ ++/** ++ * bfq_bfqq_served - update the scheduler status after selection for ++ * service. ++ * @bfqq: the queue being served. ++ * @served: bytes to transfer. ++ * ++ * NOTE: this can be optimized, as the timestamps of upper level entities ++ * are synchronized every time a new bfqq is selected for service. By now, ++ * we keep it to better check consistency. ++ */ ++static void bfq_bfqq_served(struct bfq_queue *bfqq, unsigned long served) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st; ++ ++ for_each_entity(entity) { ++ st = bfq_entity_service_tree(entity); ++ ++ entity->service += served; ++ BUG_ON(entity->service > entity->budget); ++ BUG_ON(st->wsum == 0); ++ ++ st->vtime += bfq_delta(served, st->wsum); ++ bfq_forget_idle(st); ++ } ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %lu secs", served); ++} ++ ++/** ++ * bfq_bfqq_charge_full_budget - set the service to the entity budget. ++ * @bfqq: the queue that needs a service update. ++ * ++ * When it's not possible to be fair in the service domain, because ++ * a queue is not consuming its budget fast enough (the meaning of ++ * fast depends on the timeout parameter), we charge it a full ++ * budget. In this way we should obtain a sort of time-domain ++ * fairness among all the seeky/slow queues. ++ */ ++static inline void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget"); ++ ++ bfq_bfqq_served(bfqq, entity->budget - entity->service); ++} ++ ++/** ++ * __bfq_activate_entity - activate an entity. ++ * @entity: the entity being activated. ++ * ++ * Called whenever an entity is activated, i.e., it is not active and one ++ * of its children receives a new request, or has to be reactivated due to ++ * budget exhaustion. It uses the current budget of the entity (and the ++ * service received if @entity is active) of the queue to calculate its ++ * timestamps. ++ */ ++static void __bfq_activate_entity(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ ++ if (entity == sd->in_service_entity) { ++ BUG_ON(entity->tree != NULL); ++ /* ++ * If we are requeueing the current entity we have ++ * to take care of not charging to it service it has ++ * not received. ++ */ ++ bfq_calc_finish(entity, entity->service); ++ entity->start = entity->finish; ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) { ++ /* ++ * Requeueing an entity due to a change of some ++ * next_in_service entity below it. We reuse the ++ * old start time. ++ */ ++ bfq_active_extract(st, entity); ++ } else if (entity->tree == &st->idle) { ++ /* ++ * Must be on the idle tree, bfq_idle_extract() will ++ * check for that. ++ */ ++ bfq_idle_extract(st, entity); ++ entity->start = bfq_gt(st->vtime, entity->finish) ? ++ st->vtime : entity->finish; ++ } else { ++ /* ++ * The finish time of the entity may be invalid, and ++ * it is in the past for sure, otherwise the queue ++ * would have been on the idle tree. ++ */ ++ entity->start = st->vtime; ++ st->wsum += entity->weight; ++ bfq_get_entity(entity); ++ ++ BUG_ON(entity->on_st); ++ entity->on_st = 1; ++ } ++ ++ st = __bfq_entity_update_weight_prio(st, entity); ++ bfq_calc_finish(entity, entity->budget); ++ bfq_active_insert(st, entity); ++} ++ ++/** ++ * bfq_activate_entity - activate an entity and its ancestors if necessary. ++ * @entity: the entity to activate. ++ * ++ * Activate @entity and all the entities on the path from it to the root. ++ */ ++static void bfq_activate_entity(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sd; ++ ++ for_each_entity(entity) { ++ __bfq_activate_entity(entity); ++ ++ sd = entity->sched_data; ++ if (!bfq_update_next_in_service(sd)) ++ /* ++ * No need to propagate the activation to the ++ * upper entities, as they will be updated when ++ * the in-service entity is rescheduled. ++ */ ++ break; ++ } ++} ++ ++/** ++ * __bfq_deactivate_entity - deactivate an entity from its service tree. ++ * @entity: the entity to deactivate. ++ * @requeue: if false, the entity will not be put into the idle tree. ++ * ++ * Deactivate an entity, independently from its previous state. If the ++ * entity was not on a service tree just return, otherwise if it is on ++ * any scheduler tree, extract it from that tree, and if necessary ++ * and if the caller did not specify @requeue, put it on the idle tree. ++ * ++ * Return %1 if the caller should update the entity hierarchy, i.e., ++ * if the entity was in service or if it was the next_in_service for ++ * its sched_data; return %0 otherwise. ++ */ ++static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ int was_in_service = entity == sd->in_service_entity; ++ int ret = 0; ++ ++ if (!entity->on_st) ++ return 0; ++ ++ BUG_ON(was_in_service && entity->tree != NULL); ++ ++ if (was_in_service) { ++ bfq_calc_finish(entity, entity->service); ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) ++ bfq_active_extract(st, entity); ++ else if (entity->tree == &st->idle) ++ bfq_idle_extract(st, entity); ++ else if (entity->tree != NULL) ++ BUG(); ++ ++ if (was_in_service || sd->next_in_service == entity) ++ ret = bfq_update_next_in_service(sd); ++ ++ if (!requeue || !bfq_gt(entity->finish, st->vtime)) ++ bfq_forget_entity(st, entity); ++ else ++ bfq_idle_insert(st, entity); ++ ++ BUG_ON(sd->in_service_entity == entity); ++ BUG_ON(sd->next_in_service == entity); ++ ++ return ret; ++} ++ ++/** ++ * bfq_deactivate_entity - deactivate an entity. ++ * @entity: the entity to deactivate. ++ * @requeue: true if the entity can be put on the idle tree ++ */ ++static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd; ++ struct bfq_entity *parent; ++ ++ for_each_entity_safe(entity, parent) { ++ sd = entity->sched_data; ++ ++ if (!__bfq_deactivate_entity(entity, requeue)) ++ /* ++ * The parent entity is still backlogged, and ++ * we don't need to update it as it is still ++ * in service. ++ */ ++ break; ++ ++ if (sd->next_in_service != NULL) ++ /* ++ * The parent entity is still backlogged and ++ * the budgets on the path towards the root ++ * need to be updated. ++ */ ++ goto update; ++ ++ /* ++ * If we reach there the parent is no more backlogged and ++ * we want to propagate the dequeue upwards. ++ */ ++ requeue = 1; ++ } ++ ++ return; ++ ++update: ++ entity = parent; ++ for_each_entity(entity) { ++ __bfq_activate_entity(entity); ++ ++ sd = entity->sched_data; ++ if (!bfq_update_next_in_service(sd)) ++ break; ++ } ++} ++ ++/** ++ * bfq_update_vtime - update vtime if necessary. ++ * @st: the service tree to act upon. ++ * ++ * If necessary update the service tree vtime to have at least one ++ * eligible entity, skipping to its start time. Assumes that the ++ * active tree of the device is not empty. ++ * ++ * NOTE: this hierarchical implementation updates vtimes quite often, ++ * we may end up with reactivated processes getting timestamps after a ++ * vtime skip done because we needed a ->first_active entity on some ++ * intermediate node. ++ */ ++static void bfq_update_vtime(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry; ++ struct rb_node *node = st->active.rb_node; ++ ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entry->min_start, st->vtime)) { ++ st->vtime = entry->min_start; ++ bfq_forget_idle(st); ++ } ++} ++ ++/** ++ * bfq_first_active_entity - find the eligible entity with ++ * the smallest finish time ++ * @st: the service tree to select from. ++ * ++ * This function searches the first schedulable entity, starting from the ++ * root of the tree and going on the left every time on this side there is ++ * a subtree with at least one eligible (start >= vtime) entity. The path on ++ * the right is followed only if a) the left subtree contains no eligible ++ * entities and b) no eligible entity has been found yet. ++ */ ++static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry, *first = NULL; ++ struct rb_node *node = st->active.rb_node; ++ ++ while (node != NULL) { ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++left: ++ if (!bfq_gt(entry->start, st->vtime)) ++ first = entry; ++ ++ BUG_ON(bfq_gt(entry->min_start, st->vtime)); ++ ++ if (node->rb_left != NULL) { ++ entry = rb_entry(node->rb_left, ++ struct bfq_entity, rb_node); ++ if (!bfq_gt(entry->min_start, st->vtime)) { ++ node = node->rb_left; ++ goto left; ++ } ++ } ++ if (first != NULL) ++ break; ++ node = node->rb_right; ++ } ++ ++ BUG_ON(first == NULL && !RB_EMPTY_ROOT(&st->active)); ++ return first; ++} ++ ++/** ++ * __bfq_lookup_next_entity - return the first eligible entity in @st. ++ * @st: the service tree. ++ * ++ * Update the virtual time in @st and return the first eligible entity ++ * it contains. ++ */ ++static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st, ++ bool force) ++{ ++ struct bfq_entity *entity, *new_next_in_service = NULL; ++ ++ if (RB_EMPTY_ROOT(&st->active)) ++ return NULL; ++ ++ bfq_update_vtime(st); ++ entity = bfq_first_active_entity(st); ++ BUG_ON(bfq_gt(entity->start, st->vtime)); ++ ++ /* ++ * If the chosen entity does not match with the sched_data's ++ * next_in_service and we are forcedly serving the IDLE priority ++ * class tree, bubble up budget update. ++ */ ++ if (unlikely(force && entity != entity->sched_data->next_in_service)) { ++ new_next_in_service = entity; ++ for_each_entity(new_next_in_service) ++ bfq_update_budget(new_next_in_service); ++ } ++ ++ return entity; ++} ++ ++/** ++ * bfq_lookup_next_entity - return the first eligible entity in @sd. ++ * @sd: the sched_data. ++ * @extract: if true the returned entity will be also extracted from @sd. ++ * ++ * NOTE: since we cache the next_in_service entity at each level of the ++ * hierarchy, the complexity of the lookup can be decreased with ++ * absolutely no effort just returning the cached next_in_service value; ++ * we prefer to do full lookups to test the consistency of * the data ++ * structures. ++ */ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd) ++{ ++ struct bfq_service_tree *st = sd->service_tree; ++ struct bfq_entity *entity; ++ int i = 0; ++ ++ BUG_ON(sd->in_service_entity != NULL); ++ ++ if (bfqd != NULL && ++ jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) { ++ entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1, ++ true); ++ if (entity != NULL) { ++ i = BFQ_IOPRIO_CLASSES - 1; ++ bfqd->bfq_class_idle_last_service = jiffies; ++ sd->next_in_service = entity; ++ } ++ } ++ for (; i < BFQ_IOPRIO_CLASSES; i++) { ++ entity = __bfq_lookup_next_entity(st + i, false); ++ if (entity != NULL) { ++ if (extract) { ++ bfq_check_next_in_service(sd, entity); ++ bfq_active_extract(st + i, entity); ++ sd->in_service_entity = entity; ++ sd->next_in_service = NULL; ++ } ++ break; ++ } ++ } ++ ++ return entity; ++} ++ ++/* ++ * Get next queue for service. ++ */ ++static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_entity *entity = NULL; ++ struct bfq_sched_data *sd; ++ struct bfq_queue *bfqq; ++ ++ BUG_ON(bfqd->in_service_queue != NULL); ++ ++ if (bfqd->busy_queues == 0) ++ return NULL; ++ ++ sd = &bfqd->root_group->sched_data; ++ for (; sd != NULL; sd = entity->my_sched_data) { ++ entity = bfq_lookup_next_entity(sd, 1, bfqd); ++ BUG_ON(entity == NULL); ++ entity->service = 0; ++ } ++ ++ bfqq = bfq_entity_to_bfqq(entity); ++ BUG_ON(bfqq == NULL); ++ ++ return bfqq; ++} ++ ++/* ++ * Forced extraction of the given queue. ++ */ ++static void bfq_get_next_queue_forced(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity; ++ struct bfq_sched_data *sd; ++ ++ BUG_ON(bfqd->in_service_queue != NULL); ++ ++ entity = &bfqq->entity; ++ /* ++ * Bubble up extraction/update from the leaf to the root. ++ */ ++ for_each_entity(entity) { ++ sd = entity->sched_data; ++ bfq_update_budget(entity); ++ bfq_update_vtime(bfq_entity_service_tree(entity)); ++ bfq_active_extract(bfq_entity_service_tree(entity), entity); ++ sd->in_service_entity = entity; ++ sd->next_in_service = NULL; ++ entity->service = 0; ++ } ++ ++ return; ++} ++ ++static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) ++{ ++ if (bfqd->in_service_bic != NULL) { ++ put_io_context(bfqd->in_service_bic->icq.ioc); ++ bfqd->in_service_bic = NULL; ++ } ++ ++ bfqd->in_service_queue = NULL; ++ del_timer(&bfqd->idle_slice_timer); ++} ++ ++static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ if (bfqq == bfqd->in_service_queue) ++ __bfq_bfqd_reset_in_service(bfqd); ++ ++ bfq_deactivate_entity(entity, requeue); ++} ++ ++static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_activate_entity(entity); ++} ++ ++/* ++ * Called when the bfqq no longer has requests pending, remove it from ++ * the service tree. ++ */ ++static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ BUG_ON(!bfq_bfqq_busy(bfqq)); ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ bfq_log_bfqq(bfqd, bfqq, "del from busy"); ++ ++ bfq_clear_bfqq_busy(bfqq); ++ ++ BUG_ON(bfqd->busy_queues == 0); ++ bfqd->busy_queues--; ++ ++ if (!bfqq->dispatched) { ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ BUG_ON(!bfqd->busy_in_flight_queues); ++ bfqd->busy_in_flight_queues--; ++ if (bfq_bfqq_constantly_seeky(bfqq)) { ++ BUG_ON(!bfqd-> ++ const_seeky_busy_in_flight_queues); ++ bfqd->const_seeky_busy_in_flight_queues--; ++ } ++ } ++ } ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues--; ++ ++ bfq_deactivate_bfqq(bfqd, bfqq, requeue); ++} ++ ++/* ++ * Called when an inactive queue receives a new request. ++ */ ++static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "add to busy"); ++ ++ bfq_activate_bfqq(bfqd, bfqq); ++ ++ bfq_mark_bfqq_busy(bfqq); ++ bfqd->busy_queues++; ++ ++ if (!bfqq->dispatched) { ++ if (bfqq->wr_coeff == 1) ++ bfq_weights_tree_add(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ bfqd->busy_in_flight_queues++; ++ if (bfq_bfqq_constantly_seeky(bfqq)) ++ bfqd->const_seeky_busy_in_flight_queues++; ++ } ++ } ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues++; ++} +diff --git a/block/bfq.h b/block/bfq.h +new file mode 100644 +index 0000000..89078fc +--- /dev/null ++++ b/block/bfq.h +@@ -0,0 +1,770 @@ ++/* ++ * BFQ-v7r8 for 3.4.0: data structures and common functions prototypes. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++#ifndef _BFQ_H ++#define _BFQ_H ++ ++#include ++#include ++#include ++#include ++ ++#define BFQ_IOPRIO_CLASSES 3 ++#define BFQ_CL_IDLE_TIMEOUT (HZ/5) ++ ++#define BFQ_MIN_WEIGHT 1 ++#define BFQ_MAX_WEIGHT 1000 ++ ++#define BFQ_DEFAULT_QUEUE_IOPRIO 4 ++ ++#define BFQ_DEFAULT_GRP_WEIGHT 10 ++#define BFQ_DEFAULT_GRP_IOPRIO 0 ++#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE ++ ++struct bfq_entity; ++ ++/** ++ * struct bfq_service_tree - per ioprio_class service tree. ++ * @active: tree for active entities (i.e., those backlogged). ++ * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i). ++ * @first_idle: idle entity with minimum F_i. ++ * @last_idle: idle entity with maximum F_i. ++ * @vtime: scheduler virtual time. ++ * @wsum: scheduler weight sum; active and idle entities contribute to it. ++ * ++ * Each service tree represents a B-WF2Q+ scheduler on its own. Each ++ * ioprio_class has its own independent scheduler, and so its own ++ * bfq_service_tree. All the fields are protected by the queue lock ++ * of the containing bfqd. ++ */ ++struct bfq_service_tree { ++ struct rb_root active; ++ struct rb_root idle; ++ ++ struct bfq_entity *first_idle; ++ struct bfq_entity *last_idle; ++ ++ u64 vtime; ++ unsigned long wsum; ++}; ++ ++/** ++ * struct bfq_sched_data - multi-class scheduler. ++ * @in_service_entity: entity in service. ++ * @next_in_service: head-of-the-line entity in the scheduler. ++ * @service_tree: array of service trees, one per ioprio_class. ++ * ++ * bfq_sched_data is the basic scheduler queue. It supports three ++ * ioprio_classes, and can be used either as a toplevel queue or as ++ * an intermediate queue on a hierarchical setup. ++ * @next_in_service points to the active entity of the sched_data ++ * service trees that will be scheduled next. ++ * ++ * The supported ioprio_classes are the same as in CFQ, in descending ++ * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE. ++ * Requests from higher priority queues are served before all the ++ * requests from lower priority queues; among requests of the same ++ * queue requests are served according to B-WF2Q+. ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_sched_data { ++ struct bfq_entity *in_service_entity; ++ struct bfq_entity *next_in_service; ++ struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES]; ++}; ++ ++/** ++ * struct bfq_weight_counter - counter of the number of all active entities ++ * with a given weight. ++ * @weight: weight of the entities that this counter refers to. ++ * @num_active: number of active entities with this weight. ++ * @weights_node: weights tree member (see bfq_data's @queue_weights_tree ++ * and @group_weights_tree). ++ */ ++struct bfq_weight_counter { ++ short int weight; ++ unsigned int num_active; ++ struct rb_node weights_node; ++}; ++ ++/** ++ * struct bfq_entity - schedulable entity. ++ * @rb_node: service_tree member. ++ * @weight_counter: pointer to the weight counter associated with this entity. ++ * @on_st: flag, true if the entity is on a tree (either the active or ++ * the idle one of its service_tree). ++ * @finish: B-WF2Q+ finish timestamp (aka F_i). ++ * @start: B-WF2Q+ start timestamp (aka S_i). ++ * @tree: tree the entity is enqueued into; %NULL if not on a tree. ++ * @min_start: minimum start time of the (active) subtree rooted at ++ * this entity; used for O(log N) lookups into active trees. ++ * @service: service received during the last round of service. ++ * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight. ++ * @weight: weight of the queue ++ * @parent: parent entity, for hierarchical scheduling. ++ * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the ++ * associated scheduler queue, %NULL on leaf nodes. ++ * @sched_data: the scheduler queue this entity belongs to. ++ * @ioprio: the ioprio in use. ++ * @new_weight: when a weight change is requested, the new weight value. ++ * @orig_weight: original weight, used to implement weight boosting ++ * @new_ioprio: when an ioprio change is requested, the new ioprio value. ++ * @ioprio_class: the ioprio_class in use. ++ * @new_ioprio_class: when an ioprio_class change is requested, the new ++ * ioprio_class value. ++ * @ioprio_changed: flag, true when the user requested a weight, ioprio or ++ * ioprio_class change. ++ * ++ * A bfq_entity is used to represent either a bfq_queue (leaf node in the ++ * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each ++ * entity belongs to the sched_data of the parent group in the cgroup ++ * hierarchy. Non-leaf entities have also their own sched_data, stored ++ * in @my_sched_data. ++ * ++ * Each entity stores independently its priority values; this would ++ * allow different weights on different devices, but this ++ * functionality is not exported to userspace by now. Priorities and ++ * weights are updated lazily, first storing the new values into the ++ * new_* fields, then setting the @ioprio_changed flag. As soon as ++ * there is a transition in the entity state that allows the priority ++ * update to take place the effective and the requested priority ++ * values are synchronized. ++ * ++ * Unless cgroups are used, the weight value is calculated from the ++ * ioprio to export the same interface as CFQ. When dealing with ++ * ``well-behaved'' queues (i.e., queues that do not spend too much ++ * time to consume their budget and have true sequential behavior, and ++ * when there are no external factors breaking anticipation) the ++ * relative weights at each level of the cgroups hierarchy should be ++ * guaranteed. All the fields are protected by the queue lock of the ++ * containing bfqd. ++ */ ++struct bfq_entity { ++ struct rb_node rb_node; ++ struct bfq_weight_counter *weight_counter; ++ ++ int on_st; ++ ++ u64 finish; ++ u64 start; ++ ++ struct rb_root *tree; ++ ++ u64 min_start; ++ ++ unsigned long service, budget; ++ unsigned short weight, new_weight; ++ unsigned short orig_weight; ++ ++ struct bfq_entity *parent; ++ ++ struct bfq_sched_data *my_sched_data; ++ struct bfq_sched_data *sched_data; ++ ++ unsigned short ioprio, new_ioprio; ++ unsigned short ioprio_class, new_ioprio_class; ++ ++ int ioprio_changed; ++}; ++ ++struct bfq_group; ++ ++/** ++ * struct bfq_queue - leaf schedulable entity. ++ * @ref: reference counter. ++ * @bfqd: parent bfq_data. ++ * @new_bfqq: shared bfq_queue if queue is cooperating with ++ * one or more other queues. ++ * @pos_node: request-position tree member (see bfq_data's @rq_pos_tree). ++ * @pos_root: request-position tree root (see bfq_data's @rq_pos_tree). ++ * @sort_list: sorted list of pending requests. ++ * @next_rq: if fifo isn't expired, next request to serve. ++ * @queued: nr of requests queued in @sort_list. ++ * @allocated: currently allocated requests. ++ * @meta_pending: pending metadata requests. ++ * @fifo: fifo list of requests in sort_list. ++ * @entity: entity representing this queue in the scheduler. ++ * @max_budget: maximum budget allowed from the feedback mechanism. ++ * @budget_timeout: budget expiration (in jiffies). ++ * @dispatched: number of requests on the dispatch list or inside driver. ++ * @flags: status flags. ++ * @bfqq_list: node for active/idle bfqq list inside our bfqd. ++ * @burst_list_node: node for the device's burst list. ++ * @seek_samples: number of seeks sampled ++ * @seek_total: sum of the distances of the seeks sampled ++ * @seek_mean: mean seek distance ++ * @last_request_pos: position of the last request enqueued ++ * @requests_within_timer: number of consecutive pairs of request completion ++ * and arrival, such that the queue becomes idle ++ * after the completion, but the next request arrives ++ * within an idle time slice; used only if the queue's ++ * IO_bound has been cleared. ++ * @pid: pid of the process owning the queue, used for logging purposes. ++ * @last_wr_start_finish: start time of the current weight-raising period if ++ * the @bfq-queue is being weight-raised, otherwise ++ * finish time of the last weight-raising period ++ * @wr_cur_max_time: current max raising time for this queue ++ * @soft_rt_next_start: minimum time instant such that, only if a new ++ * request is enqueued after this time instant in an ++ * idle @bfq_queue with no outstanding requests, then ++ * the task associated with the queue it is deemed as ++ * soft real-time (see the comments to the function ++ * bfq_bfqq_softrt_next_start()). ++ * @last_idle_bklogged: time of the last transition of the @bfq_queue from ++ * idle to backlogged ++ * @service_from_backlogged: cumulative service received from the @bfq_queue ++ * since the last transition from idle to ++ * backlogged ++ * ++ * A bfq_queue is a leaf request queue; it can be associated with an io_context ++ * or more, if it is async or shared between cooperating processes. @cgroup ++ * holds a reference to the cgroup, to be sure that it does not disappear while ++ * a bfqq still references it (mostly to avoid races between request issuing and ++ * task migration followed by cgroup destruction). ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_queue { ++ atomic_t ref; ++ struct bfq_data *bfqd; ++ ++ /* fields for cooperating queues handling */ ++ struct bfq_queue *new_bfqq; ++ struct rb_node pos_node; ++ struct rb_root *pos_root; ++ ++ struct rb_root sort_list; ++ struct request *next_rq; ++ int queued[2]; ++ int allocated[2]; ++ int meta_pending; ++ struct list_head fifo; ++ ++ struct bfq_entity entity; ++ ++ unsigned long max_budget; ++ unsigned long budget_timeout; ++ ++ int dispatched; ++ ++ unsigned int flags; ++ ++ struct list_head bfqq_list; ++ ++ struct hlist_node burst_list_node; ++ ++ unsigned int seek_samples; ++ u64 seek_total; ++ sector_t seek_mean; ++ sector_t last_request_pos; ++ ++ unsigned int requests_within_timer; ++ ++ pid_t pid; ++ ++ /* weight-raising fields */ ++ unsigned long wr_cur_max_time; ++ unsigned long soft_rt_next_start; ++ unsigned long last_wr_start_finish; ++ unsigned int wr_coeff; ++ unsigned long last_idle_bklogged; ++ unsigned long service_from_backlogged; ++}; ++ ++/** ++ * struct bfq_ttime - per process thinktime stats. ++ * @ttime_total: total process thinktime ++ * @ttime_samples: number of thinktime samples ++ * @ttime_mean: average process thinktime ++ */ ++struct bfq_ttime { ++ unsigned long last_end_request; ++ ++ unsigned long ttime_total; ++ unsigned long ttime_samples; ++ unsigned long ttime_mean; ++}; ++ ++/** ++ * struct bfq_io_cq - per (request_queue, io_context) structure. ++ * @icq: associated io_cq structure ++ * @bfqq: array of two process queues, the sync and the async ++ * @ttime: associated @bfq_ttime struct ++ */ ++struct bfq_io_cq { ++ struct io_cq icq; /* must be the first member */ ++ struct bfq_queue *bfqq[2]; ++ struct bfq_ttime ttime; ++ int ioprio; ++}; ++ ++enum bfq_device_speed { ++ BFQ_BFQD_FAST, ++ BFQ_BFQD_SLOW, ++}; ++ ++/** ++ * struct bfq_data - per device data structure. ++ * @queue: request queue for the managed device. ++ * @root_group: root bfq_group for the device. ++ * @rq_pos_tree: rbtree sorted by next_request position, used when ++ * determining if two or more queues have interleaving ++ * requests (see bfq_close_cooperator()). ++ * @active_numerous_groups: number of bfq_groups containing more than one ++ * active @bfq_entity. ++ * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by ++ * weight. Used to keep track of whether all @bfq_queues ++ * have the same weight. The tree contains one counter ++ * for each distinct weight associated to some active ++ * and not weight-raised @bfq_queue (see the comments to ++ * the functions bfq_weights_tree_[add|remove] for ++ * further details). ++ * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted ++ * by weight. Used to keep track of whether all ++ * @bfq_groups have the same weight. The tree contains ++ * one counter for each distinct weight associated to ++ * some active @bfq_group (see the comments to the ++ * functions bfq_weights_tree_[add|remove] for further ++ * details). ++ * @busy_queues: number of bfq_queues containing requests (including the ++ * queue in service, even if it is idling). ++ * @busy_in_flight_queues: number of @bfq_queues containing pending or ++ * in-flight requests, plus the @bfq_queue in ++ * service, even if idle but waiting for the ++ * possible arrival of its next sync request. This ++ * field is updated only if the device is rotational, ++ * but used only if the device is also NCQ-capable. ++ * The reason why the field is updated also for non- ++ * NCQ-capable rotational devices is related to the ++ * fact that the value of @hw_tag may be set also ++ * later than when busy_in_flight_queues may need to ++ * be incremented for the first time(s). Taking also ++ * this possibility into account, to avoid unbalanced ++ * increments/decrements, would imply more overhead ++ * than just updating busy_in_flight_queues ++ * regardless of the value of @hw_tag. ++ * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues ++ * (that is, seeky queues that expired ++ * for budget timeout at least once) ++ * containing pending or in-flight ++ * requests, including the in-service ++ * @bfq_queue if constantly seeky. This ++ * field is updated only if the device ++ * is rotational, but used only if the ++ * device is also NCQ-capable (see the ++ * comments to @busy_in_flight_queues). ++ * @wr_busy_queues: number of weight-raised busy @bfq_queues. ++ * @queued: number of queued requests. ++ * @rq_in_driver: number of requests dispatched and waiting for completion. ++ * @sync_flight: number of sync requests in the driver. ++ * @max_rq_in_driver: max number of reqs in driver in the last ++ * @hw_tag_samples completed requests. ++ * @hw_tag_samples: nr of samples used to calculate hw_tag. ++ * @hw_tag: flag set to one if the driver is showing a queueing behavior. ++ * @budgets_assigned: number of budgets assigned. ++ * @idle_slice_timer: timer set when idling for the next sequential request ++ * from the queue in service. ++ * @unplug_work: delayed work to restart dispatching on the request queue. ++ * @in_service_queue: bfq_queue in service. ++ * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue. ++ * @last_position: on-disk position of the last served request. ++ * @last_budget_start: beginning of the last budget. ++ * @last_idling_start: beginning of the last idle slice. ++ * @peak_rate: peak transfer rate observed for a budget. ++ * @peak_rate_samples: number of samples used to calculate @peak_rate. ++ * @bfq_max_budget: maximum budget allotted to a bfq_queue before ++ * rescheduling. ++ * @group_list: list of all the bfq_groups active on the device. ++ * @active_list: list of all the bfq_queues active on the device. ++ * @idle_list: list of all the bfq_queues idle on the device. ++ * @bfq_fifo_expire: timeout for async/sync requests; when it expires ++ * requests are served in fifo order. ++ * @bfq_back_penalty: weight of backward seeks wrt forward ones. ++ * @bfq_back_max: maximum allowed backward seek. ++ * @bfq_slice_idle: maximum idling time. ++ * @bfq_user_max_budget: user-configured max budget value ++ * (0 for auto-tuning). ++ * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to ++ * async queues. ++ * @bfq_timeout: timeout for bfq_queues to consume their budget; used to ++ * to prevent seeky queues to impose long latencies to well ++ * behaved ones (this also implies that seeky queues cannot ++ * receive guarantees in the service domain; after a timeout ++ * they are charged for the whole allocated budget, to try ++ * to preserve a behavior reasonably fair among them, but ++ * without service-domain guarantees). ++ * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is ++ * no more granted any weight-raising. ++ * @bfq_failed_cooperations: number of consecutive failed cooperation ++ * chances after which weight-raising is restored ++ * to a queue subject to more than bfq_coop_thresh ++ * queue merges. ++ * @bfq_requests_within_timer: number of consecutive requests that must be ++ * issued within the idle time slice to set ++ * again idling to a queue which was marked as ++ * non-I/O-bound (see the definition of the ++ * IO_bound flag for further details). ++ * @last_ins_in_burst: last time at which a queue entered the current ++ * burst of queues being activated shortly after ++ * each other; for more details about this and the ++ * following parameters related to a burst of ++ * activations, see the comments to the function ++ * @bfq_handle_burst. ++ * @bfq_burst_interval: reference time interval used to decide whether a ++ * queue has been activated shortly after ++ * @last_ins_in_burst. ++ * @burst_size: number of queues in the current burst of queue activations. ++ * @bfq_large_burst_thresh: maximum burst size above which the current ++ * queue-activation burst is deemed as 'large'. ++ * @large_burst: true if a large queue-activation burst is in progress. ++ * @burst_list: head of the burst list (as for the above fields, more details ++ * in the comments to the function bfq_handle_burst). ++ * @low_latency: if set to true, low-latency heuristics are enabled. ++ * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised ++ * queue is multiplied. ++ * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies). ++ * @bfq_wr_rt_max_time: maximum duration for soft real-time processes. ++ * @bfq_wr_min_idle_time: minimum idle period after which weight-raising ++ * may be reactivated for a queue (in jiffies). ++ * @bfq_wr_min_inter_arr_async: minimum period between request arrivals ++ * after which weight-raising may be ++ * reactivated for an already busy queue ++ * (in jiffies). ++ * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue, ++ * sectors per seconds. ++ * @RT_prod: cached value of the product R*T used for computing the maximum ++ * duration of the weight raising automatically. ++ * @device_speed: device-speed class for the low-latency heuristic. ++ * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions. ++ * ++ * All the fields are protected by the @queue lock. ++ */ ++struct bfq_data { ++ struct request_queue *queue; ++ ++ struct bfq_group *root_group; ++ struct rb_root rq_pos_tree; ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ int active_numerous_groups; ++#endif ++ ++ struct rb_root queue_weights_tree; ++ struct rb_root group_weights_tree; ++ ++ int busy_queues; ++ int busy_in_flight_queues; ++ int const_seeky_busy_in_flight_queues; ++ int wr_busy_queues; ++ int queued; ++ int rq_in_driver; ++ int sync_flight; ++ ++ int max_rq_in_driver; ++ int hw_tag_samples; ++ int hw_tag; ++ ++ int budgets_assigned; ++ ++ struct timer_list idle_slice_timer; ++ struct work_struct unplug_work; ++ ++ struct bfq_queue *in_service_queue; ++ struct bfq_io_cq *in_service_bic; ++ ++ sector_t last_position; ++ ++ ktime_t last_budget_start; ++ ktime_t last_idling_start; ++ int peak_rate_samples; ++ u64 peak_rate; ++ unsigned long bfq_max_budget; ++ ++ struct hlist_head group_list; ++ struct list_head active_list; ++ struct list_head idle_list; ++ ++ unsigned int bfq_fifo_expire[2]; ++ unsigned int bfq_back_penalty; ++ unsigned int bfq_back_max; ++ unsigned int bfq_slice_idle; ++ u64 bfq_class_idle_last_service; ++ ++ unsigned int bfq_user_max_budget; ++ unsigned int bfq_max_budget_async_rq; ++ unsigned int bfq_timeout[2]; ++ ++ unsigned int bfq_coop_thresh; ++ unsigned int bfq_failed_cooperations; ++ unsigned int bfq_requests_within_timer; ++ ++ unsigned long last_ins_in_burst; ++ unsigned long bfq_burst_interval; ++ int burst_size; ++ unsigned long bfq_large_burst_thresh; ++ bool large_burst; ++ struct hlist_head burst_list; ++ ++ bool low_latency; ++ ++ /* parameters of the low_latency heuristics */ ++ unsigned int bfq_wr_coeff; ++ unsigned int bfq_wr_max_time; ++ unsigned int bfq_wr_rt_max_time; ++ unsigned int bfq_wr_min_idle_time; ++ unsigned long bfq_wr_min_inter_arr_async; ++ unsigned int bfq_wr_max_softrt_rate; ++ u64 RT_prod; ++ enum bfq_device_speed device_speed; ++ ++ struct bfq_queue oom_bfqq; ++}; ++ ++enum bfqq_state_flags { ++ BFQ_BFQQ_FLAG_busy = 0, /* has requests or is in service */ ++ BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */ ++ BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ ++ BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ ++ BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */ ++ BFQ_BFQQ_FLAG_sync, /* synchronous queue */ ++ BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */ ++ BFQ_BFQQ_FLAG_IO_bound, /* ++ * bfqq has timed-out at least once ++ * having consumed at most 2/10 of ++ * its budget ++ */ ++ BFQ_BFQQ_FLAG_in_large_burst, /* ++ * bfqq activated in a large burst, ++ * see comments to bfq_handle_burst. ++ */ ++ BFQ_BFQQ_FLAG_constantly_seeky, /* ++ * bfqq has proved to be slow and ++ * seeky until budget timeout ++ */ ++ BFQ_BFQQ_FLAG_softrt_update, /* ++ * may need softrt-next-start ++ * update ++ */ ++ BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ ++ BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be splitted */ ++}; ++ ++#define BFQ_BFQQ_FNS(name) \ ++static inline void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static inline void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static inline int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ ++{ \ ++ return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \ ++} ++ ++BFQ_BFQQ_FNS(busy); ++BFQ_BFQQ_FNS(wait_request); ++BFQ_BFQQ_FNS(must_alloc); ++BFQ_BFQQ_FNS(fifo_expire); ++BFQ_BFQQ_FNS(idle_window); ++BFQ_BFQQ_FNS(sync); ++BFQ_BFQQ_FNS(budget_new); ++BFQ_BFQQ_FNS(IO_bound); ++BFQ_BFQQ_FNS(in_large_burst); ++BFQ_BFQQ_FNS(constantly_seeky); ++BFQ_BFQQ_FNS(coop); ++BFQ_BFQQ_FNS(split_coop); ++BFQ_BFQQ_FNS(softrt_update); ++#undef BFQ_BFQQ_FNS ++ ++/* Logging facilities. */ ++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args) ++ ++#define bfq_log(bfqd, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) ++ ++/* Expiration reasons. */ ++enum bfqq_expiration { ++ BFQ_BFQQ_TOO_IDLE = 0, /* ++ * queue has been idling for ++ * too long ++ */ ++ BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */ ++ BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */ ++ BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */ ++}; ++ ++#ifdef CONFIG_CGROUP_BFQIO ++/** ++ * struct bfq_group - per (device, cgroup) data structure. ++ * @entity: schedulable entity to insert into the parent group sched_data. ++ * @sched_data: own sched_data, to contain child entities (they may be ++ * both bfq_queues and bfq_groups). ++ * @group_node: node to be inserted into the bfqio_cgroup->group_data ++ * list of the containing cgroup's bfqio_cgroup. ++ * @bfqd_node: node to be inserted into the @bfqd->group_list list ++ * of the groups active on the same device; used for cleanup. ++ * @bfqd: the bfq_data for the device this group acts upon. ++ * @async_bfqq: array of async queues for all the tasks belonging to ++ * the group, one queue per ioprio value per ioprio_class, ++ * except for the idle class that has only one queue. ++ * @async_idle_bfqq: async queue for the idle class (ioprio is ignored). ++ * @my_entity: pointer to @entity, %NULL for the toplevel group; used ++ * to avoid too many special cases during group creation/ ++ * migration. ++ * @active_entities: number of active entities belonging to the group; ++ * unused for the root group. Used to know whether there ++ * are groups with more than one active @bfq_entity ++ * (see the comments to the function ++ * bfq_bfqq_must_not_expire()). ++ * ++ * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup ++ * there is a set of bfq_groups, each one collecting the lower-level ++ * entities belonging to the group that are acting on the same device. ++ * ++ * Locking works as follows: ++ * o @group_node is protected by the bfqio_cgroup lock, and is accessed ++ * via RCU from its readers. ++ * o @bfqd is protected by the queue lock, RCU is used to access it ++ * from the readers. ++ * o All the other fields are protected by the @bfqd queue lock. ++ */ ++struct bfq_group { ++ struct bfq_entity entity; ++ struct bfq_sched_data sched_data; ++ ++ struct hlist_node group_node; ++ struct hlist_node bfqd_node; ++ ++ void *bfqd; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++ ++ struct bfq_entity *my_entity; ++ ++ int active_entities; ++}; ++ ++/** ++ * struct bfqio_cgroup - bfq cgroup data structure. ++ * @css: subsystem state for bfq in the containing cgroup. ++ * @weight: cgroup weight. ++ * @ioprio: cgroup ioprio. ++ * @ioprio_class: cgroup ioprio_class. ++ * @lock: spinlock that protects @ioprio, @ioprio_class and @group_data. ++ * @group_data: list containing the bfq_group belonging to this cgroup. ++ * ++ * @group_data is accessed using RCU, with @lock protecting the updates, ++ * @ioprio and @ioprio_class are protected by @lock. ++ */ ++struct bfqio_cgroup { ++ struct cgroup_subsys_state css; ++ ++ unsigned short weight, ioprio, ioprio_class; ++ ++ spinlock_t lock; ++ struct hlist_head group_data; ++}; ++#else ++struct bfq_group { ++ struct bfq_sched_data sched_data; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++}; ++#endif ++ ++static inline struct bfq_service_tree * ++bfq_entity_service_tree(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sched_data = entity->sched_data; ++ unsigned int idx = entity->ioprio_class - 1; ++ ++ BUG_ON(idx >= BFQ_IOPRIO_CLASSES); ++ BUG_ON(sched_data == NULL); ++ ++ return sched_data->service_tree + idx; ++} ++ ++static inline struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, ++ bool is_sync) ++{ ++ return bic->bfqq[is_sync]; ++} ++ ++static inline void bic_set_bfqq(struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq, bool is_sync) ++{ ++ bic->bfqq[is_sync] = bfqq; ++} ++ ++static inline struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) ++{ ++ return bic->icq.q->elevator->elevator_data; ++} ++ ++/** ++ * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer. ++ * @ptr: a pointer to a bfqd. ++ * @flags: storage for the flags to be saved. ++ * ++ * This function allows bfqg->bfqd to be protected by the ++ * queue lock of the bfqd they reference; the pointer is dereferenced ++ * under RCU, so the storage for bfqd is assured to be safe as long ++ * as the RCU read side critical section does not end. After the ++ * bfqd->queue->queue_lock is taken the pointer is rechecked, to be ++ * sure that no other writer accessed it. If we raced with a writer, ++ * the function returns NULL, with the queue unlocked, otherwise it ++ * returns the dereferenced pointer, with the queue locked. ++ */ ++static inline struct bfq_data *bfq_get_bfqd_locked(void **ptr, ++ unsigned long *flags) ++{ ++ struct bfq_data *bfqd; ++ ++ rcu_read_lock(); ++ bfqd = rcu_dereference(*(struct bfq_data **)ptr); ++ ++ if (bfqd != NULL) { ++ spin_lock_irqsave(bfqd->queue->queue_lock, *flags); ++ if (*ptr == bfqd) ++ goto out; ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); ++ } ++ ++ bfqd = NULL; ++out: ++ rcu_read_unlock(); ++ return bfqd; ++} ++ ++static inline void bfq_put_bfqd_unlock(struct bfq_data *bfqd, ++ unsigned long *flags) ++{ ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); ++} ++ ++static void bfq_check_ioprio_change(struct io_context *ioc, ++ struct bfq_io_cq *bic); ++static void bfq_put_queue(struct bfq_queue *bfqq); ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq); ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, int is_sync, ++ struct io_context *ioc, gfp_t gfp_mask); ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg); ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); ++ ++#endif /* _BFQ_H */ +-- +2.1.4 + diff --git a/projects/H3/patches/linux/linux-003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r8-for-3.4.0.patch b/projects/H3/patches/linux/linux-003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r8-for-3.4.0.patch new file mode 100644 index 00000000000..f56dbe716a4 --- /dev/null +++ b/projects/H3/patches/linux/linux-003-block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r8-for-3.4.0.patch @@ -0,0 +1,1220 @@ +From f4a80111e29aa8856a7005ee1fe1e445ab5ba5e9 Mon Sep 17 00:00:00 2001 +From: Mauro Andreolini +Date: Sun, 7 Jun 2015 02:34:22 +0200 +Subject: [PATCH 3/3] block, bfq: add Early Queue Merge (EQM) to BFQ-v7r8 for + 3.4.0 + +A set of processes may happen to perform interleaved reads, i.e.,requests +whose union would give rise to a sequential read pattern. There are two +typical cases: in the first case, processes read fixed-size chunks of +data at a fixed distance from each other, while in the second case processes +may read variable-size chunks at variable distances. The latter case occurs +for example with QEMU, which splits the I/O generated by the guest into +multiple chunks, and lets these chunks be served by a pool of cooperating +processes, iteratively assigning the next chunk of I/O to the first +available process. CFQ uses actual queue merging for the first type of +rocesses, whereas it uses preemption to get a sequential read pattern out +of the read requests performed by the second type of processes. In the end +it uses two different mechanisms to achieve the same goal: boosting the +throughput with interleaved I/O. + +This patch introduces Early Queue Merge (EQM), a unified mechanism to get a +sequential read pattern with both types of processes. The main idea is +checking newly arrived requests against the next request of the active queue +both in case of actual request insert and in case of request merge. By doing +so, both the types of processes can be handled by just merging their queues. +EQM is then simpler and more compact than the pair of mechanisms used in +CFQ. + +Finally, EQM also preserves the typical low-latency properties of BFQ, by +properly restoring the weight-raising state of a queue when it gets back to +a non-merged state. + +Signed-off-by: Mauro Andreolini +Signed-off-by: Arianna Avanzini +Signed-off-by: Paolo Valente +--- + block/bfq-iosched.c | 750 +++++++++++++++++++++++++++++++++++++--------------- + block/bfq-sched.c | 28 -- + block/bfq.h | 54 +++- + 3 files changed, 580 insertions(+), 252 deletions(-) + +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index f8a3dfd..637c906 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -573,6 +573,57 @@ static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd) + return dur; + } + ++static inline unsigned ++bfq_bfqq_cooperations(struct bfq_queue *bfqq) ++{ ++ return bfqq->bic ? bfqq->bic->cooperations : 0; ++} ++ ++static inline void ++bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) ++{ ++ if (bic->saved_idle_window) ++ bfq_mark_bfqq_idle_window(bfqq); ++ else ++ bfq_clear_bfqq_idle_window(bfqq); ++ if (bic->saved_IO_bound) ++ bfq_mark_bfqq_IO_bound(bfqq); ++ else ++ bfq_clear_bfqq_IO_bound(bfqq); ++ /* Assuming that the flag in_large_burst is already correctly set */ ++ if (bic->wr_time_left && bfqq->bfqd->low_latency && ++ !bfq_bfqq_in_large_burst(bfqq) && ++ bic->cooperations < bfqq->bfqd->bfq_coop_thresh) { ++ /* ++ * Start a weight raising period with the duration given by ++ * the raising_time_left snapshot. ++ */ ++ if (bfq_bfqq_busy(bfqq)) ++ bfqq->bfqd->wr_busy_queues++; ++ bfqq->wr_coeff = bfqq->bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bic->wr_time_left; ++ bfqq->last_wr_start_finish = jiffies; ++ bfqq->entity.ioprio_changed = 1; ++ } ++ /* ++ * Clear wr_time_left to prevent bfq_bfqq_save_state() from ++ * getting confused about the queue's need of a weight-raising ++ * period. ++ */ ++ bic->wr_time_left = 0; ++} ++ ++/* Must be called with the queue_lock held. */ ++static int bfqq_process_refs(struct bfq_queue *bfqq) ++{ ++ int process_refs, io_refs; ++ ++ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; ++ process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; ++ BUG_ON(process_refs < 0); ++ return process_refs; ++} ++ + /* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ + static inline void bfq_reset_burst_list(struct bfq_data *bfqd, + struct bfq_queue *bfqq) +@@ -818,7 +869,7 @@ static void bfq_add_request(struct request *rq) + bfq_rq_pos_tree_add(bfqd, bfqq); + + if (!bfq_bfqq_busy(bfqq)) { +- bool soft_rt, ++ bool soft_rt, coop_or_in_burst, + idle_for_long_time = time_is_before_jiffies( + bfqq->budget_timeout + + bfqd->bfq_wr_min_idle_time); +@@ -842,11 +893,12 @@ static void bfq_add_request(struct request *rq) + bfqd->last_ins_in_burst = jiffies; + } + ++ coop_or_in_burst = bfq_bfqq_in_large_burst(bfqq) || ++ bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh; + soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && +- !bfq_bfqq_in_large_burst(bfqq) && ++ !coop_or_in_burst && + time_is_before_jiffies(bfqq->soft_rt_next_start); +- interactive = !bfq_bfqq_in_large_burst(bfqq) && +- idle_for_long_time; ++ interactive = !coop_or_in_burst && idle_for_long_time; + entity->budget = max_t(unsigned long, bfqq->max_budget, + bfq_serv_to_charge(next_rq, bfqq)); + +@@ -865,11 +917,20 @@ static void bfq_add_request(struct request *rq) + if (!bfqd->low_latency) + goto add_bfqq_busy; + ++ if (bfq_bfqq_just_split(bfqq)) ++ goto set_ioprio_changed; ++ + /* +- * If the queue is not being boosted and has been idle +- * for enough time, start a weight-raising period ++ * If the queue: ++ * - is not being boosted, ++ * - has been idle for enough time, ++ * - is not a sync queue or is linked to a bfq_io_cq (it is ++ * shared "for its nature" or it is not shared and its ++ * requests have not been redirected to a shared queue) ++ * start a weight-raising period. + */ +- if (old_wr_coeff == 1 && (interactive || soft_rt)) { ++ if (old_wr_coeff == 1 && (interactive || soft_rt) && ++ (!bfq_bfqq_sync(bfqq) || bfqq->bic != NULL)) { + bfqq->wr_coeff = bfqd->bfq_wr_coeff; + if (interactive) + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); +@@ -883,7 +944,7 @@ static void bfq_add_request(struct request *rq) + } else if (old_wr_coeff > 1) { + if (interactive) + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); +- else if (bfq_bfqq_in_large_burst(bfqq) || ++ else if (coop_or_in_burst || + (bfqq->wr_cur_max_time == + bfqd->bfq_wr_rt_max_time && + !soft_rt)) { +@@ -902,18 +963,18 @@ static void bfq_add_request(struct request *rq) + /* + * + * The remaining weight-raising time is lower +- * than bfqd->bfq_wr_rt_max_time, which +- * means that the application is enjoying +- * weight raising either because deemed soft- +- * rt in the near past, or because deemed +- * interactive a long ago. In both cases, +- * resetting now the current remaining weight- +- * raising time for the application to the +- * weight-raising duration for soft rt +- * applications would not cause any latency +- * increase for the application (as the new +- * duration would be higher than the remaining +- * time). ++ * than bfqd->bfq_wr_rt_max_time, which means ++ * that the application is enjoying weight ++ * raising either because deemed soft-rt in ++ * the near past, or because deemed interactive ++ * a long ago. ++ * In both cases, resetting now the current ++ * remaining weight-raising time for the ++ * application to the weight-raising duration ++ * for soft rt applications would not cause any ++ * latency increase for the application (as the ++ * new duration would be higher than the ++ * remaining time). + * + * In addition, the application is now meeting + * the requirements for being deemed soft rt. +@@ -948,6 +1009,7 @@ static void bfq_add_request(struct request *rq) + bfqd->bfq_wr_rt_max_time; + } + } ++set_ioprio_changed: + if (old_wr_coeff != bfqq->wr_coeff) + entity->ioprio_changed = 1; + add_bfqq_busy: +@@ -1171,90 +1233,35 @@ static void bfq_end_wr(struct bfq_data *bfqd) + spin_unlock_irq(bfqd->queue->queue_lock); + } + +-static int bfq_allow_merge(struct request_queue *q, struct request *rq, +- struct bio *bio) ++static inline sector_t bfq_io_struct_pos(void *io_struct, bool request) + { +- struct bfq_data *bfqd = q->elevator->elevator_data; +- struct bfq_io_cq *bic; +- struct bfq_queue *bfqq; +- +- /* +- * Disallow merge of a sync bio into an async request. +- */ +- if (bfq_bio_sync(bio) && !rq_is_sync(rq)) +- return 0; +- +- /* +- * Lookup the bfqq that this bio will be queued with. Allow +- * merge only if rq is queued there. +- * Queue lock is held here. +- */ +- bic = bfq_bic_lookup(bfqd, current->io_context); +- if (bic == NULL) +- return 0; +- +- bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); +- return bfqq == RQ_BFQQ(rq); +-} +- +-static void __bfq_set_in_service_queue(struct bfq_data *bfqd, +- struct bfq_queue *bfqq) +-{ +- if (bfqq != NULL) { +- bfq_mark_bfqq_must_alloc(bfqq); +- bfq_mark_bfqq_budget_new(bfqq); +- bfq_clear_bfqq_fifo_expire(bfqq); +- +- bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; +- +- bfq_log_bfqq(bfqd, bfqq, +- "set_in_service_queue, cur-budget = %lu", +- bfqq->entity.budget); +- } +- +- bfqd->in_service_queue = bfqq; +-} +- +-/* +- * Get and set a new queue for service. +- */ +-static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd, +- struct bfq_queue *bfqq) +-{ +- if (!bfqq) +- bfqq = bfq_get_next_queue(bfqd); ++ if (request) ++ return blk_rq_pos(io_struct); + else +- bfq_get_next_queue_forced(bfqd, bfqq); +- +- __bfq_set_in_service_queue(bfqd, bfqq); +- return bfqq; ++ return ((struct bio *)io_struct)->bi_sector; + } + +-static inline sector_t bfq_dist_from_last(struct bfq_data *bfqd, +- struct request *rq) ++static inline sector_t bfq_dist_from(sector_t pos1, ++ sector_t pos2) + { +- if (blk_rq_pos(rq) >= bfqd->last_position) +- return blk_rq_pos(rq) - bfqd->last_position; ++ if (pos1 >= pos2) ++ return pos1 - pos2; + else +- return bfqd->last_position - blk_rq_pos(rq); ++ return pos2 - pos1; + } + +-/* +- * Return true if bfqq has no request pending and rq is close enough to +- * bfqd->last_position, or if rq is closer to bfqd->last_position than +- * bfqq->next_rq +- */ +-static inline int bfq_rq_close(struct bfq_data *bfqd, struct request *rq) ++static inline int bfq_rq_close_to_sector(void *io_struct, bool request, ++ sector_t sector) + { +- return bfq_dist_from_last(bfqd, rq) <= BFQQ_SEEK_THR; ++ return bfq_dist_from(bfq_io_struct_pos(io_struct, request), sector) <= ++ BFQQ_SEEK_THR; + } + +-static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) ++static struct bfq_queue *bfqq_close(struct bfq_data *bfqd, sector_t sector) + { + struct rb_root *root = &bfqd->rq_pos_tree; + struct rb_node *parent, *node; + struct bfq_queue *__bfqq; +- sector_t sector = bfqd->last_position; + + if (RB_EMPTY_ROOT(root)) + return NULL; +@@ -1273,7 +1280,7 @@ static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) + * next_request position). + */ + __bfqq = rb_entry(parent, struct bfq_queue, pos_node); +- if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) + return __bfqq; + + if (blk_rq_pos(__bfqq->next_rq) < sector) +@@ -1284,7 +1291,7 @@ static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) + return NULL; + + __bfqq = rb_entry(node, struct bfq_queue, pos_node); +- if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) + return __bfqq; + + return NULL; +@@ -1293,14 +1300,12 @@ static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) + /* + * bfqd - obvious + * cur_bfqq - passed in so that we don't decide that the current queue +- * is closely cooperating with itself. +- * +- * We are assuming that cur_bfqq has dispatched at least one request, +- * and that bfqd->last_position reflects a position on the disk associated +- * with the I/O issued by cur_bfqq. ++ * is closely cooperating with itself ++ * sector - used as a reference point to search for a close queue + */ + static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, +- struct bfq_queue *cur_bfqq) ++ struct bfq_queue *cur_bfqq, ++ sector_t sector) + { + struct bfq_queue *bfqq; + +@@ -1320,7 +1325,7 @@ static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, + * working closely on the same area of the disk. In that case, + * we can group them together and don't waste time idling. + */ +- bfqq = bfqq_close(bfqd); ++ bfqq = bfqq_close(bfqd, sector); + if (bfqq == NULL || bfqq == cur_bfqq) + return NULL; + +@@ -1347,6 +1352,315 @@ static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, + return bfqq; + } + ++static struct bfq_queue * ++bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ int process_refs, new_process_refs; ++ struct bfq_queue *__bfqq; ++ ++ /* ++ * If there are no process references on the new_bfqq, then it is ++ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain ++ * may have dropped their last reference (not just their last process ++ * reference). ++ */ ++ if (!bfqq_process_refs(new_bfqq)) ++ return NULL; ++ ++ /* Avoid a circular list and skip interim queue merges. */ ++ while ((__bfqq = new_bfqq->new_bfqq)) { ++ if (__bfqq == bfqq) ++ return NULL; ++ new_bfqq = __bfqq; ++ } ++ ++ process_refs = bfqq_process_refs(bfqq); ++ new_process_refs = bfqq_process_refs(new_bfqq); ++ /* ++ * If the process for the bfqq has gone away, there is no ++ * sense in merging the queues. ++ */ ++ if (process_refs == 0 || new_process_refs == 0) ++ return NULL; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", ++ new_bfqq->pid); ++ ++ /* ++ * Merging is just a redirection: the requests of the process ++ * owning one of the two queues are redirected to the other queue. ++ * The latter queue, in its turn, is set as shared if this is the ++ * first time that the requests of some process are redirected to ++ * it. ++ * ++ * We redirect bfqq to new_bfqq and not the opposite, because we ++ * are in the context of the process owning bfqq, hence we have ++ * the io_cq of this process. So we can immediately configure this ++ * io_cq to redirect the requests of the process to new_bfqq. ++ * ++ * NOTE, even if new_bfqq coincides with the in-service queue, the ++ * io_cq of new_bfqq is not available, because, if the in-service ++ * queue is shared, bfqd->in_service_bic may not point to the ++ * io_cq of the in-service queue. ++ * Redirecting the requests of the process owning bfqq to the ++ * currently in-service queue is in any case the best option, as ++ * we feed the in-service queue with new requests close to the ++ * last request served and, by doing so, hopefully increase the ++ * throughput. ++ */ ++ bfqq->new_bfqq = new_bfqq; ++ atomic_add(process_refs, &new_bfqq->ref); ++ return new_bfqq; ++} ++ ++/* ++ * Attempt to schedule a merge of bfqq with the currently in-service queue ++ * or with a close queue among the scheduled queues. ++ * Return NULL if no merge was scheduled, a pointer to the shared bfq_queue ++ * structure otherwise. ++ * ++ * The OOM queue is not allowed to participate to cooperation: in fact, since ++ * the requests temporarily redirected to the OOM queue could be redirected ++ * again to dedicated queues at any time, the state needed to correctly ++ * handle merging with the OOM queue would be quite complex and expensive ++ * to maintain. Besides, in such a critical condition as an out of memory, ++ * the benefits of queue merging may be little relevant, or even negligible. ++ */ ++static struct bfq_queue * ++bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ void *io_struct, bool request) ++{ ++ struct bfq_queue *in_service_bfqq, *new_bfqq; ++ ++ if (bfqq->new_bfqq) ++ return bfqq->new_bfqq; ++ ++ if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq)) ++ return NULL; ++ ++ in_service_bfqq = bfqd->in_service_queue; ++ ++ if (in_service_bfqq == NULL || in_service_bfqq == bfqq || ++ !bfqd->in_service_bic || ++ unlikely(in_service_bfqq == &bfqd->oom_bfqq)) ++ goto check_scheduled; ++ ++ if (bfq_class_idle(in_service_bfqq) || bfq_class_idle(bfqq)) ++ goto check_scheduled; ++ ++ if (bfq_class_rt(in_service_bfqq) != bfq_class_rt(bfqq)) ++ goto check_scheduled; ++ ++ if (in_service_bfqq->entity.parent != bfqq->entity.parent) ++ goto check_scheduled; ++ ++ if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) && ++ bfq_bfqq_sync(in_service_bfqq) && bfq_bfqq_sync(bfqq)) { ++ new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq); ++ if (new_bfqq != NULL) ++ return new_bfqq; /* Merge with in-service queue */ ++ } ++ ++ /* ++ * Check whether there is a cooperator among currently scheduled ++ * queues. The only thing we need is that the bio/request is not ++ * NULL, as we need it to establish whether a cooperator exists. ++ */ ++check_scheduled: ++ new_bfqq = bfq_close_cooperator(bfqd, bfqq, ++ bfq_io_struct_pos(io_struct, request)); ++ if (new_bfqq && likely(new_bfqq != &bfqd->oom_bfqq)) ++ return bfq_setup_merge(bfqq, new_bfqq); ++ ++ return NULL; ++} ++ ++static inline void ++bfq_bfqq_save_state(struct bfq_queue *bfqq) ++{ ++ /* ++ * If bfqq->bic == NULL, the queue is already shared or its requests ++ * have already been redirected to a shared queue; both idle window ++ * and weight raising state have already been saved. Do nothing. ++ */ ++ if (bfqq->bic == NULL) ++ return; ++ if (bfqq->bic->wr_time_left) ++ /* ++ * This is the queue of a just-started process, and would ++ * deserve weight raising: we set wr_time_left to the full ++ * weight-raising duration to trigger weight-raising when ++ * and if the queue is split and the first request of the ++ * queue is enqueued. ++ */ ++ bfqq->bic->wr_time_left = bfq_wr_duration(bfqq->bfqd); ++ else if (bfqq->wr_coeff > 1) { ++ unsigned long wr_duration = ++ jiffies - bfqq->last_wr_start_finish; ++ /* ++ * It may happen that a queue's weight raising period lasts ++ * longer than its wr_cur_max_time, as weight raising is ++ * handled only when a request is enqueued or dispatched (it ++ * does not use any timer). If the weight raising period is ++ * about to end, don't save it. ++ */ ++ if (bfqq->wr_cur_max_time <= wr_duration) ++ bfqq->bic->wr_time_left = 0; ++ else ++ bfqq->bic->wr_time_left = ++ bfqq->wr_cur_max_time - wr_duration; ++ /* ++ * The bfq_queue is becoming shared or the requests of the ++ * process owning the queue are being redirected to a shared ++ * queue. Stop the weight raising period of the queue, as in ++ * both cases it should not be owned by an interactive or ++ * soft real-time application. ++ */ ++ bfq_bfqq_end_wr(bfqq); ++ } else ++ bfqq->bic->wr_time_left = 0; ++ bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq); ++ bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq); ++ bfqq->bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq); ++ bfqq->bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node); ++ bfqq->bic->cooperations++; ++ bfqq->bic->failed_cooperations = 0; ++} ++ ++static inline void ++bfq_get_bic_reference(struct bfq_queue *bfqq) ++{ ++ /* ++ * If bfqq->bic has a non-NULL value, the bic to which it belongs ++ * is about to begin using a shared bfq_queue. ++ */ ++ if (bfqq->bic) ++ atomic_long_inc(&bfqq->bic->icq.ioc->refcount); ++} ++ ++static void ++bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", ++ (long unsigned)new_bfqq->pid); ++ /* Save weight raising and idle window of the merged queues */ ++ bfq_bfqq_save_state(bfqq); ++ bfq_bfqq_save_state(new_bfqq); ++ if (bfq_bfqq_IO_bound(bfqq)) ++ bfq_mark_bfqq_IO_bound(new_bfqq); ++ bfq_clear_bfqq_IO_bound(bfqq); ++ /* ++ * Grab a reference to the bic, to prevent it from being destroyed ++ * before being possibly touched by a bfq_split_bfqq(). ++ */ ++ bfq_get_bic_reference(bfqq); ++ bfq_get_bic_reference(new_bfqq); ++ /* ++ * Merge queues (that is, let bic redirect its requests to new_bfqq) ++ */ ++ bic_set_bfqq(bic, new_bfqq, 1); ++ bfq_mark_bfqq_coop(new_bfqq); ++ /* ++ * new_bfqq now belongs to at least two bics (it is a shared queue): ++ * set new_bfqq->bic to NULL. bfqq either: ++ * - does not belong to any bic any more, and hence bfqq->bic must ++ * be set to NULL, or ++ * - is a queue whose owning bics have already been redirected to a ++ * different queue, hence the queue is destined to not belong to ++ * any bic soon and bfqq->bic is already NULL (therefore the next ++ * assignment causes no harm). ++ */ ++ new_bfqq->bic = NULL; ++ bfqq->bic = NULL; ++ bfq_put_queue(bfqq); ++} ++ ++static inline void bfq_bfqq_increase_failed_cooperations(struct bfq_queue *bfqq) ++{ ++ struct bfq_io_cq *bic = bfqq->bic; ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ if (bic && bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh) { ++ bic->failed_cooperations++; ++ if (bic->failed_cooperations >= bfqd->bfq_failed_cooperations) ++ bic->cooperations = 0; ++ } ++} ++ ++static int bfq_allow_merge(struct request_queue *q, struct request *rq, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq, *new_bfqq; ++ ++ /* ++ * Disallow merge of a sync bio into an async request. ++ */ ++ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) ++ return 0; ++ ++ /* ++ * Lookup the bfqq that this bio will be queued with. Allow ++ * merge only if rq is queued there. ++ * Queue lock is held here. ++ */ ++ bic = bfq_bic_lookup(bfqd, current->io_context); ++ if (bic == NULL) ++ return 0; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ /* ++ * We take advantage of this function to perform an early merge ++ * of the queues of possible cooperating processes. ++ */ ++ if (bfqq != NULL) { ++ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false); ++ if (new_bfqq != NULL) { ++ bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq); ++ /* ++ * If we get here, the bio will be queued in the ++ * shared queue, i.e., new_bfqq, so use new_bfqq ++ * to decide whether bio and rq can be merged. ++ */ ++ bfqq = new_bfqq; ++ } else ++ bfq_bfqq_increase_failed_cooperations(bfqq); ++ } ++ ++ return bfqq == RQ_BFQQ(rq); ++} ++ ++static void __bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq != NULL) { ++ bfq_mark_bfqq_must_alloc(bfqq); ++ bfq_mark_bfqq_budget_new(bfqq); ++ bfq_clear_bfqq_fifo_expire(bfqq); ++ ++ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_in_service_queue, cur-budget = %lu", ++ bfqq->entity.budget); ++ } ++ ++ bfqd->in_service_queue = bfqq; ++} ++ ++/* ++ * Get and set a new queue for service. ++ */ ++static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfq_get_next_queue(bfqd); ++ ++ __bfq_set_in_service_queue(bfqd, bfqq); ++ return bfqq; ++} ++ + /* + * If enough samples have been computed, return the current max budget + * stored in bfqd, which is dynamically updated according to the +@@ -1492,61 +1806,6 @@ static struct request *bfq_check_fifo(struct bfq_queue *bfqq) + return rq; + } + +-/* Must be called with the queue_lock held. */ +-static int bfqq_process_refs(struct bfq_queue *bfqq) +-{ +- int process_refs, io_refs; +- +- io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; +- process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; +- BUG_ON(process_refs < 0); +- return process_refs; +-} +- +-static void bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) +-{ +- int process_refs, new_process_refs; +- struct bfq_queue *__bfqq; +- +- /* +- * If there are no process references on the new_bfqq, then it is +- * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain +- * may have dropped their last reference (not just their last process +- * reference). +- */ +- if (!bfqq_process_refs(new_bfqq)) +- return; +- +- /* Avoid a circular list and skip interim queue merges. */ +- while ((__bfqq = new_bfqq->new_bfqq)) { +- if (__bfqq == bfqq) +- return; +- new_bfqq = __bfqq; +- } +- +- process_refs = bfqq_process_refs(bfqq); +- new_process_refs = bfqq_process_refs(new_bfqq); +- /* +- * If the process for the bfqq has gone away, there is no +- * sense in merging the queues. +- */ +- if (process_refs == 0 || new_process_refs == 0) +- return; +- +- /* +- * Merge in the direction of the lesser amount of work. +- */ +- if (new_process_refs >= process_refs) { +- bfqq->new_bfqq = new_bfqq; +- atomic_add(process_refs, &new_bfqq->ref); +- } else { +- new_bfqq->new_bfqq = bfqq; +- atomic_add(new_process_refs, &bfqq->ref); +- } +- bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", +- new_bfqq->pid); +-} +- + static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq) + { + struct bfq_entity *entity = &bfqq->entity; +@@ -2273,7 +2532,7 @@ static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) + */ + static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + { +- struct bfq_queue *bfqq, *new_bfqq = NULL; ++ struct bfq_queue *bfqq; + struct request *next_rq; + enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; + +@@ -2283,17 +2542,6 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + + bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); + +- /* +- * If another queue has a request waiting within our mean seek +- * distance, let it run. The expire code will check for close +- * cooperators and put the close queue at the front of the +- * service tree. If possible, merge the expiring queue with the +- * new bfqq. +- */ +- new_bfqq = bfq_close_cooperator(bfqd, bfqq); +- if (new_bfqq != NULL && bfqq->new_bfqq == NULL) +- bfq_setup_merge(bfqq, new_bfqq); +- + if (bfq_may_expire_for_budg_timeout(bfqq) && + !timer_pending(&bfqd->idle_slice_timer) && + !bfq_bfqq_must_idle(bfqq)) +@@ -2332,10 +2580,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + bfq_clear_bfqq_wait_request(bfqq); + del_timer(&bfqd->idle_slice_timer); + } +- if (new_bfqq == NULL) +- goto keep_queue; +- else +- goto expire; ++ goto keep_queue; + } + } + +@@ -2344,40 +2589,30 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + * for a new request, or has requests waiting for a completion and + * may idle after their completion, then keep it anyway. + */ +- if (new_bfqq == NULL && (timer_pending(&bfqd->idle_slice_timer) || +- (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq)))) { ++ if (timer_pending(&bfqd->idle_slice_timer) || ++ (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq))) { + bfqq = NULL; + goto keep_queue; +- } else if (new_bfqq != NULL && timer_pending(&bfqd->idle_slice_timer)) { +- /* +- * Expiring the queue because there is a close cooperator, +- * cancel timer. +- */ +- bfq_clear_bfqq_wait_request(bfqq); +- del_timer(&bfqd->idle_slice_timer); + } + + reason = BFQ_BFQQ_NO_MORE_REQUESTS; + expire: + bfq_bfqq_expire(bfqd, bfqq, 0, reason); + new_queue: +- bfqq = bfq_set_in_service_queue(bfqd, new_bfqq); ++ bfqq = bfq_set_in_service_queue(bfqd); + bfq_log(bfqd, "select_queue: new queue %d returned", + bfqq != NULL ? bfqq->pid : 0); + keep_queue: + return bfqq; + } + +-static void bfq_update_wr_data(struct bfq_data *bfqd, +- struct bfq_queue *bfqq) ++static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) + { +- if (bfqq->wr_coeff > 1) { /* queue is being boosted */ +- struct bfq_entity *entity = &bfqq->entity; +- ++ struct bfq_entity *entity = &bfqq->entity; ++ if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */ + bfq_log_bfqq(bfqd, bfqq, + "raising period dur %u/%u msec, old coeff %u, w %d(%d)", +- jiffies_to_msecs(jiffies - +- bfqq->last_wr_start_finish), ++ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), + jiffies_to_msecs(bfqq->wr_cur_max_time), + bfqq->wr_coeff, + bfqq->entity.weight, bfqq->entity.orig_weight); +@@ -2386,12 +2621,16 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, + entity->orig_weight * bfqq->wr_coeff); + if (entity->ioprio_changed) + bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); ++ + /* + * If the queue was activated in a burst, or + * too much time has elapsed from the beginning +- * of this weight-raising, then end weight raising. ++ * of this weight-raising period, or the queue has ++ * exceeded the acceptable number of cooperations, ++ * then end weight raising. + */ + if (bfq_bfqq_in_large_burst(bfqq) || ++ bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh || + time_is_before_jiffies(bfqq->last_wr_start_finish + + bfqq->wr_cur_max_time)) { + bfqq->last_wr_start_finish = jiffies; +@@ -2400,11 +2639,13 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, + bfqq->last_wr_start_finish, + jiffies_to_msecs(bfqq->wr_cur_max_time)); + bfq_bfqq_end_wr(bfqq); +- __bfq_entity_update_weight_prio( +- bfq_entity_service_tree(entity), +- entity); + } + } ++ /* Update weight both if it must be raised and if it must be lowered */ ++ if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1)) ++ __bfq_entity_update_weight_prio( ++ bfq_entity_service_tree(entity), ++ entity); + } + + /* +@@ -2651,6 +2892,25 @@ static inline void bfq_init_icq(struct io_cq *icq) + struct bfq_io_cq *bic = icq_to_bic(icq); + + bic->ttime.last_end_request = jiffies; ++ /* ++ * A newly created bic indicates that the process has just ++ * started doing I/O, and is probably mapping into memory its ++ * executable and libraries: it definitely needs weight raising. ++ * There is however the possibility that the process performs, ++ * for a while, I/O close to some other process. EQM intercepts ++ * this behavior and may merge the queue corresponding to the ++ * process with some other queue, BEFORE the weight of the queue ++ * is raised. Merged queues are not weight-raised (they are assumed ++ * to belong to processes that benefit only from high throughput). ++ * If the merge is basically the consequence of an accident, then ++ * the queue will be split soon and will get back its old weight. ++ * It is then important to write down somewhere that this queue ++ * does need weight raising, even if it did not make it to get its ++ * weight raised before being merged. To this purpose, we overload ++ * the field raising_time_left and assign 1 to it, to mark the queue ++ * as needing weight raising. ++ */ ++ bic->wr_time_left = 1; + } + + static void bfq_exit_icq(struct io_cq *icq) +@@ -2664,6 +2924,13 @@ static void bfq_exit_icq(struct io_cq *icq) + } + + if (bic->bfqq[BLK_RW_SYNC]) { ++ /* ++ * If the bic is using a shared queue, put the reference ++ * taken on the io_context when the bic started using a ++ * shared bfq_queue. ++ */ ++ if (bfq_bfqq_coop(bic->bfqq[BLK_RW_SYNC])) ++ put_io_context(icq->ioc); + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); + bic->bfqq[BLK_RW_SYNC] = NULL; + } +@@ -2952,6 +3219,10 @@ static void bfq_update_idle_window(struct bfq_data *bfqd, + if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) + return; + ++ /* Idle window just restored, statistics are meaningless. */ ++ if (bfq_bfqq_just_split(bfqq)) ++ return; ++ + enable_idle = bfq_bfqq_idle_window(bfqq); + + if (atomic_read(&bic->icq.ioc->nr_tasks) == 0 || +@@ -2999,6 +3270,7 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, + if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || + !BFQQ_SEEKY(bfqq)) + bfq_update_idle_window(bfqd, bfqq, bic); ++ bfq_clear_bfqq_just_split(bfqq); + + bfq_log_bfqq(bfqd, bfqq, + "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", +@@ -3059,12 +3331,47 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, + static void bfq_insert_request(struct request_queue *q, struct request *rq) + { + struct bfq_data *bfqd = q->elevator->elevator_data; +- struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq; + + assert_spin_locked(bfqd->queue->queue_lock); + ++ /* ++ * An unplug may trigger a requeue of a request from the device ++ * driver: make sure we are in process context while trying to ++ * merge two bfq_queues. ++ */ ++ if (!in_interrupt()) { ++ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true); ++ if (new_bfqq != NULL) { ++ if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq) ++ new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1); ++ /* ++ * Release the request's reference to the old bfqq ++ * and make sure one is taken to the shared queue. ++ */ ++ new_bfqq->allocated[rq_data_dir(rq)]++; ++ bfqq->allocated[rq_data_dir(rq)]--; ++ atomic_inc(&new_bfqq->ref); ++ bfq_put_queue(bfqq); ++ if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq) ++ bfq_merge_bfqqs(bfqd, RQ_BIC(rq), ++ bfqq, new_bfqq); ++ rq->elv.priv[1] = new_bfqq; ++ bfqq = new_bfqq; ++ } else ++ bfq_bfqq_increase_failed_cooperations(bfqq); ++ } ++ + bfq_add_request(rq); + ++ /* ++ * Here a newly-created bfq_queue has already started a weight-raising ++ * period: clear raising_time_left to prevent bfq_bfqq_save_state() ++ * from assigning it a full weight-raising period. See the detailed ++ * comments about this field in bfq_init_icq(). ++ */ ++ if (bfqq->bic != NULL) ++ bfqq->bic->wr_time_left = 0; + rq_set_fifo_time(rq, jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]); + list_add_tail(&rq->queuelist, &bfqq->fifo); + +@@ -3226,18 +3533,6 @@ static void bfq_put_request(struct request *rq) + } + } + +-static struct bfq_queue * +-bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, +- struct bfq_queue *bfqq) +-{ +- bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", +- (long unsigned)bfqq->new_bfqq->pid); +- bic_set_bfqq(bic, bfqq->new_bfqq, 1); +- bfq_mark_bfqq_coop(bfqq->new_bfqq); +- bfq_put_queue(bfqq); +- return bic_to_bfqq(bic, 1); +-} +- + /* + * Returns NULL if a new bfqq should be allocated, or the old bfqq if this + * was the last process referring to said bfqq. +@@ -3246,6 +3541,9 @@ static struct bfq_queue * + bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) + { + bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); ++ ++ put_io_context(bic->icq.ioc); ++ + if (bfqq_process_refs(bfqq) == 1) { + bfqq->pid = current->pid; + bfq_clear_bfqq_coop(bfqq); +@@ -3274,6 +3572,7 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, + struct bfq_queue *bfqq; + struct bfq_group *bfqg; + unsigned long flags; ++ bool split = false; + + /* handle changed prio notifications; cgroup change is handled separately */ + if (unlikely(icq_get_changed(&bic->icq) & ICQ_IOPRIO_CHANGED)) +@@ -3293,25 +3592,26 @@ new_queue: + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { + bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic->icq.ioc, gfp_mask); + bic_set_bfqq(bic, bfqq, is_sync); ++ if (split && is_sync) { ++ if ((bic->was_in_burst_list && bfqd->large_burst) || ++ bic->saved_in_large_burst) ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ else { ++ bfq_clear_bfqq_in_large_burst(bfqq); ++ if (bic->was_in_burst_list) ++ hlist_add_head(&bfqq->burst_list_node, ++ &bfqd->burst_list); ++ } ++ } + } else { +- /* +- * If the queue was seeky for too long, break it apart. +- */ ++ /* If the queue was seeky for too long, break it apart. */ + if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { + bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); + bfqq = bfq_split_bfqq(bic, bfqq); ++ split = true; + if (!bfqq) + goto new_queue; + } +- +- /* +- * Check to see if this queue is scheduled to merge with +- * another closely cooperating queue. The merging of queues +- * happens here as it must be done in process context. +- * The reference on new_bfqq was taken in merge_bfqqs. +- */ +- if (bfqq->new_bfqq != NULL) +- bfqq = bfq_merge_bfqqs(bfqd, bic, bfqq); + } + + bfqq->allocated[rw]++; +@@ -3322,6 +3622,26 @@ new_queue: + rq->elv.priv[0] = bic; + rq->elv.priv[1] = bfqq; + ++ /* ++ * If a bfq_queue has only one process reference, it is owned ++ * by only one bfq_io_cq: we can set the bic field of the ++ * bfq_queue to the address of that structure. Also, if the ++ * queue has just been split, mark a flag so that the ++ * information is available to the other scheduler hooks. ++ */ ++ if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { ++ bfqq->bic = bic; ++ if (split) { ++ bfq_mark_bfqq_just_split(bfqq); ++ /* ++ * If the queue has just been split from a shared ++ * queue, restore the idle window and the possible ++ * weight raising period. ++ */ ++ bfq_bfqq_resume_state(bfqq, bic); ++ } ++ } ++ + spin_unlock_irqrestore(q->queue_lock, flags); + + return 0; +diff --git a/block/bfq-sched.c b/block/bfq-sched.c +index c343099..d0890c6 100644 +--- a/block/bfq-sched.c ++++ b/block/bfq-sched.c +@@ -1085,34 +1085,6 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) + return bfqq; + } + +-/* +- * Forced extraction of the given queue. +- */ +-static void bfq_get_next_queue_forced(struct bfq_data *bfqd, +- struct bfq_queue *bfqq) +-{ +- struct bfq_entity *entity; +- struct bfq_sched_data *sd; +- +- BUG_ON(bfqd->in_service_queue != NULL); +- +- entity = &bfqq->entity; +- /* +- * Bubble up extraction/update from the leaf to the root. +- */ +- for_each_entity(entity) { +- sd = entity->sched_data; +- bfq_update_budget(entity); +- bfq_update_vtime(bfq_entity_service_tree(entity)); +- bfq_active_extract(bfq_entity_service_tree(entity), entity); +- sd->in_service_entity = entity; +- sd->next_in_service = NULL; +- entity->service = 0; +- } +- +- return; +-} +- + static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) + { + if (bfqd->in_service_bic != NULL) { +diff --git a/block/bfq.h b/block/bfq.h +index 89078fc..e6f1a88 100644 +--- a/block/bfq.h ++++ b/block/bfq.h +@@ -218,18 +218,21 @@ struct bfq_group; + * idle @bfq_queue with no outstanding requests, then + * the task associated with the queue it is deemed as + * soft real-time (see the comments to the function +- * bfq_bfqq_softrt_next_start()). ++ * bfq_bfqq_softrt_next_start()) + * @last_idle_bklogged: time of the last transition of the @bfq_queue from + * idle to backlogged + * @service_from_backlogged: cumulative service received from the @bfq_queue + * since the last transition from idle to + * backlogged ++ * @bic: pointer to the bfq_io_cq owning the bfq_queue, set to %NULL if the ++ * queue is shared + * +- * A bfq_queue is a leaf request queue; it can be associated with an io_context +- * or more, if it is async or shared between cooperating processes. @cgroup +- * holds a reference to the cgroup, to be sure that it does not disappear while +- * a bfqq still references it (mostly to avoid races between request issuing and +- * task migration followed by cgroup destruction). ++ * A bfq_queue is a leaf request queue; it can be associated with an ++ * io_context or more, if it is async or shared between cooperating ++ * processes. @cgroup holds a reference to the cgroup, to be sure that it ++ * does not disappear while a bfqq still references it (mostly to avoid ++ * races between request issuing and task migration followed by cgroup ++ * destruction). + * All the fields are protected by the queue lock of the containing bfqd. + */ + struct bfq_queue { +@@ -269,6 +272,7 @@ struct bfq_queue { + unsigned int requests_within_timer; + + pid_t pid; ++ struct bfq_io_cq *bic; + + /* weight-raising fields */ + unsigned long wr_cur_max_time; +@@ -298,12 +302,42 @@ struct bfq_ttime { + * @icq: associated io_cq structure + * @bfqq: array of two process queues, the sync and the async + * @ttime: associated @bfq_ttime struct ++ * @wr_time_left: snapshot of the time left before weight raising ends ++ * for the sync queue associated to this process; this ++ * snapshot is taken to remember this value while the weight ++ * raising is suspended because the queue is merged with a ++ * shared queue, and is used to set @raising_cur_max_time ++ * when the queue is split from the shared queue and its ++ * weight is raised again ++ * @saved_idle_window: same purpose as the previous field for the idle ++ * window ++ * @saved_IO_bound: same purpose as the previous two fields for the I/O ++ * bound classification of a queue ++ * @saved_in_large_burst: same purpose as the previous fields for the ++ * value of the field keeping the queue's belonging ++ * to a large burst ++ * @was_in_burst_list: true if the queue belonged to a burst list ++ * before its merge with another cooperating queue ++ * @cooperations: counter of consecutive successful queue merges underwent ++ * by any of the process' @bfq_queues ++ * @failed_cooperations: counter of consecutive failed queue merges of any ++ * of the process' @bfq_queues + */ + struct bfq_io_cq { + struct io_cq icq; /* must be the first member */ + struct bfq_queue *bfqq[2]; + struct bfq_ttime ttime; + int ioprio; ++ ++ unsigned int wr_time_left; ++ bool saved_idle_window; ++ bool saved_IO_bound; ++ ++ bool saved_in_large_burst; ++ bool was_in_burst_list; ++ ++ unsigned int cooperations; ++ unsigned int failed_cooperations; + }; + + enum bfq_device_speed { +@@ -536,7 +570,7 @@ enum bfqq_state_flags { + BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */ + BFQ_BFQQ_FLAG_sync, /* synchronous queue */ + BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */ +- BFQ_BFQQ_FLAG_IO_bound, /* ++ BFQ_BFQQ_FLAG_IO_bound, /* + * bfqq has timed-out at least once + * having consumed at most 2/10 of + * its budget +@@ -549,12 +583,13 @@ enum bfqq_state_flags { + * bfqq has proved to be slow and + * seeky until budget timeout + */ +- BFQ_BFQQ_FLAG_softrt_update, /* ++ BFQ_BFQQ_FLAG_softrt_update, /* + * may need softrt-next-start + * update + */ + BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ +- BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be splitted */ ++ BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be split */ ++ BFQ_BFQQ_FLAG_just_split, /* queue has just been split */ + }; + + #define BFQ_BFQQ_FNS(name) \ +@@ -583,6 +618,7 @@ BFQ_BFQQ_FNS(in_large_burst); + BFQ_BFQQ_FNS(constantly_seeky); + BFQ_BFQQ_FNS(coop); + BFQ_BFQQ_FNS(split_coop); ++BFQ_BFQQ_FNS(just_split); + BFQ_BFQQ_FNS(softrt_update); + #undef BFQ_BFQQ_FNS + +-- +2.1.4 + diff --git a/projects/H3/patches/linux/linux-004-Backport-firmware-loader.patch b/projects/H3/patches/linux/linux-004-Backport-firmware-loader.patch new file mode 100644 index 00000000000..9fc00384a28 --- /dev/null +++ b/projects/H3/patches/linux/linux-004-Backport-firmware-loader.patch @@ -0,0 +1,2562 @@ +From c1715f7de4f2b7c42f432d4a7eb02f3f954d34ca Mon Sep 17 00:00:00 2001 +From: Kevin Mihelich +Date: Sat, 6 Dec 2014 10:44:46 -0700 +Subject: [PATCH] Backport firmware loader + +commit 390ac45ceb37d70308194820e25b1cb885b67260 +Author: Ming Lei +Date: Fri Aug 17 22:06:59 2012 +0800 + + PM / Sleep: introduce dpm_for_each_dev + + dpm_list and its pm lock provide a good way to iterate all + devices in system. Except this way, there is no other easy + way to iterate devices in system. + + firmware loader need to cache firmware images for devices + before system sleep, so introduce the function to meet its + demand. + + Reported-by: Fengguang Wu + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit 1dc17a9704a49c008a8d4cd8bdf03eccc54bcf84 +Author: Kevin Mihelich +Date: Wed Nov 26 13:03:08 2014 -0700 + + Revert "firmware loader: sync firmware cache by async_synchronize_full_domain" + + This reverts commit d28d3882bd1fdb88ae4e02f11b091a92b0e5068b. + +commit 6cf1b1b3016fb279d6a866151e75c94986be032b +Author: Ming Lei +Date: Sat Aug 4 12:01:26 2012 +0800 + + driver core: devres: introduce devres_for_each_res + + This patch introduces one devres API of devres_for_each_res + so that the device's driver can iterate each resource it has + interest in. + + The firmware loader will use the API to get each firmware name + from the device instance. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit 6183261d20682701b6ddd189060da4f8325e775c +Author: Mark Brown +Date: Thu May 3 18:15:12 2012 +0100 + + devres: Clarify documentation for devres_destroy() + + It's not massively obvious (at least to me) that removing and freeing a + resource does not involve calling the release function for the resource + but rather only removes the management of it. Make the documentation more + explicit. + + Signed-off-by: Mark Brown + Signed-off-by: Greg Kroah-Hartman + +commit bf4725b4926af17c246faf3b6dda250890b3e1ae +Author: Takashi Iwai +Date: Thu Jan 31 11:13:57 2013 +0100 + + firmware: Ignore abort check when no user-helper is used + + FW_STATUS_ABORT can be set only during the user-helper invocation, + thus we can ignore the check when CONFIG_HW_LOADER_USER_HELPER is + disabled. + + Acked-by: Ming Lei + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +commit 5d5c8b23919037f575fb6370d87b875c86793834 +Author: Takashi Iwai +Date: Thu Jan 31 11:13:56 2013 +0100 + + firmware: Reduce ifdef CONFIG_FW_LOADER_USER_HELPER + + By shuffling the code, reduce a few ifdefs in firmware_class.c. + Also, firmware_buf fmt field is changed to is_pages_buf boolean for + simplification. + + Acked-by: Ming Lei + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +commit 861d2fc3539af167b5c4c9e81b5bf67300465cef +Author: Takashi Iwai +Date: Thu Jan 31 11:13:55 2013 +0100 + + firmware: Make user-mode helper optional + + This patch adds a new kconfig, CONFIG_FW_LOADER_USER_HELPER, and + guards the user-helper codes in firmware_class.c with ifdefs. + + Yeah, yeah, there are lots of ifdefs in this patch. The further + clean-up with code shuffling follows in the next. + + Acked-by: Ming Lei + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +commit eb2e7c184b7e7bf2ae1968bd32c4354d28c75e69 +Author: Takashi Iwai +Date: Thu Jan 31 11:13:54 2013 +0100 + + firmware: Refactoring for splitting user-mode helper code + + Since 3.7 kernel, the firmware loader can read the firmware files + directly, and the traditional user-mode helper is invoked only as a + fallback. This seems working pretty well, and the next step would be + to reduce the redundant user-mode helper stuff in future. + + This patch is a preparation for that: refactor the code for splitting + user-mode helper stuff more easily. No functional change. + + Acked-by: Ming Lei + Signed-off-by: Takashi Iwai + Signed-off-by: Greg Kroah-Hartman + +commit 542061e36122107363fcf7c9aeffa957dee8bffc +Author: Luciano Coelho +Date: Tue Jan 15 10:43:43 2013 +0200 + + firmware: make sure the fw file size is not 0 + + If the requested firmware file size is 0 bytes in the filesytem, we + will try to vmalloc(0), which causes a warning: + + vmalloc: allocation failure: 0 bytes + kworker/1:1: page allocation failure: order:0, mode:0xd2 + __vmalloc_node_range+0x164/0x208 + __vmalloc_node+0x4c/0x58 + vmalloc+0x38/0x44 + _request_firmware_load+0x220/0x6b0 + request_firmware+0x64/0xc8 + wl18xx_setup+0xb4/0x570 [wl18xx] + wlcore_nvs_cb+0x64/0x9f8 [wlcore] + request_firmware_work_func+0x94/0x100 + process_one_work+0x1d0/0x750 + worker_thread+0x184/0x4ac + kthread+0xb4/0xc0 + + To fix this, check whether the file size is less than or equal to zero + in fw_read_file_contents(). + + Cc: stable [3.7] + Signed-off-by: Luciano Coelho + Acked-by: Ming Lei + Signed-off-by: Linus Torvalds + +commit 906aa734d888dfeb855d50ebdaa1abafb4e16880 +Author: Ming Lei +Date: Sat Nov 3 17:48:16 2012 +0800 + + firmware loader: document firmware cache mechanism + + This patch documents the firmware cache mechanism so that + users of request_firmware() know that it can be called + safely inside device's suspend and resume callback, and + the device's firmware needn't be cached any more by individual + driver itself to deal with firmware loss during system resume. + + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit 2a2f0be2bb74403c0079a823271e6ff7c2434735 +Author: Ming Lei +Date: Sat Nov 3 17:47:58 2012 +0800 + + firmware loader: introduce module parameter to customize(v4) fw search path + + This patch introduces one module parameter of 'path' in firmware_class + to support customizing firmware image search path, so that people can + use its own firmware path if the default built-in paths can't meet their + demand[1], and the typical usage is passing the below from kernel command + parameter when 'firmware_class' is built in kernel: + + firmware_class.path=$CUSTOMIZED_PATH + + [1], https://lkml.org/lkml/2012/10/11/337 + + Cc: Linus Torvalds + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + + Conflicts: + Documentation/firmware_class/README + +commit d6c6925a1c5091163df48d68ba38d2ec2003302e +Author: Cesar Eduardo Barros +Date: Sat Oct 27 20:37:10 2012 -0200 + + firmware: use noinline_for_stack + + The comment above fw_file_size() suggests it is noinline for stack size + reasons. Use noinline_for_stack to make this more clear. + + Signed-off-by: Cesar Eduardo Barros + Acked-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit f0d798c22f43f008b0b86ff58f2c68b522f1be90 +Author: Chuansheng Liu +Date: Sat Nov 10 01:27:22 2012 +0800 + + firmware loader: Fix the concurrent request_firmware() race for kref_get/put + + There is one race that both request_firmware() with the same + firmware name. + + The race scenerio is as below: + CPU1 CPU2 + request_firmware() --> + _request_firmware_load() return err another request_firmware() is coming --> + _request_firmware_cleanup is called --> _request_firmware_prepare --> + release_firmware ---> fw_lookup_and_allocate_buf --> + spin_lock(&fwc->lock) + ... __fw_lookup_buf() return true + fw_free_buf() will be called --> ... + kref_put --> + decrease the refcount to 0 + kref_get(&tmp->ref) ==> it will trigger warning + due to refcount == 0 + __fw_free_buf() --> + ... spin_unlock(&fwc->lock) + spin_lock(&fwc->lock) + list_del(&buf->list) + spin_unlock(&fwc->lock) + kfree(buf) + After that, the freed buf will be used. + + The key race is decreasing refcount to 0 and list_del is not protected together by + fwc->lock, and it is possible another thread try to get it between refcount==0 + and list_del. + + Fix it here to protect it together. + + Acked-by: Ming Lei + Signed-off-by: liu chuansheng + Cc: stable + Signed-off-by: Greg Kroah-Hartman + +commit 58af61921c9d1f6a8ffa097043bf78a2ff0bc44e +Author: Chuansheng Liu +Date: Thu Nov 8 19:14:40 2012 +0800 + + firmware loader: Fix the race FW_STATUS_DONE is followed by class_timeout + + There is a race as below when calling request_firmware(): + CPU1 CPU2 + write 0 > loading + mutex_lock(&fw_lock) + ... + set_bit FW_STATUS_DONE class_timeout is coming + set_bit FW_STATUS_ABORT + complete_all &completion + ... + mutex_unlock(&fw_lock) + + In this time, the bit FW_STATUS_DONE and FW_STATUS_ABORT are set, + and request_firmware() will return failure due to condition in + _request_firmware_load(): + if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status)) + retval = -ENOENT; + + But from the above scenerio, it should be a successful requesting. + So we need judge if the bit FW_STATUS_DONE is already set before + calling fw_load_abort() in timeout function. + + As Ming's proposal, we need change the timer into sched_work to + benefit from using &fw_lock mutex also. + + Signed-off-by: liu chuansheng + Acked-by: Ming Lei + Cc: stable + Signed-off-by: Greg Kroah-Hartman + +commit c6a3b74d6c42ca8aead23788768cdd358f672ed3 +Author: Ming Lei +Date: Tue Oct 9 12:01:04 2012 +0800 + + firmware loader: sync firmware cache by async_synchronize_full_domain + + async.c has provided synchronization mechanism on async_schedule_*, + so use async_synchronize_full_domain to sync caching firmware instead + of reinventing the wheel. + + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit 9a27bd527d58a887a65bad24fd864122f860ef79 +Author: Ming Lei +Date: Tue Oct 9 12:01:03 2012 +0800 + + firmware loader: let direct loading back on 'firmware_buf' + + Firstly 'firmware_buf' is introduced to make all loading requests + to share one firmware kernel buffer, so firmware_buf should + be used in direct loading for saving memory and speedup firmware + loading. + + Secondly, the commit below + + abb139e75c2cdbb955e840d6331cb5863e409d0e(firmware:teach + the kernel to load firmware files directly from the filesystem) + + introduces direct loading for fixing udev regression, but it + bypasses the firmware cache meachnism, so this patch enables + caching firmware for direct loading case since it is still needed + to solve drivers' dependency during system resume. + + Cc: Linus Torvalds + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit 451768e107b4bd2beb054f3ec44b666910a8f6ce +Author: Ming Lei +Date: Tue Oct 9 12:01:02 2012 +0800 + + firmware loader: fix one reqeust_firmware race + + Several loading requests may be pending on one same + firmware buf, and this patch moves fw_map_pages_buf() + before complete_all(&fw_buf->completion) and let all + requests see the mapped 'buf->data' once the loading + is completed. + + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit 31159a04875c46fe2f8634479f5c2c07b3ebd6aa +Author: Ming Lei +Date: Tue Oct 9 12:01:01 2012 +0800 + + firmware loader: cancel uncache work before caching firmware + + Under 'Opportunistic sleep' situation, system sleep might be + triggered very frequently, so the uncahce work may not be completed + before caching firmware during next suspend. + + This patch cancels the uncache work before caching firmware to + fix the problem above. + + Also this patch optimizes the cacheing firmware mechanism a bit by + only storing one firmware cache entry for one firmware image. + + So if the firmware is still cached during suspend, it doesn't need + to be loaded from user space any more. + + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit 4c7559d930c34c76a33b51f413c13f27367e95ff +Author: Linus Torvalds +Date: Thu Oct 4 09:19:02 2012 -0700 + + firmware: use 'kernel_read()' to read firmware into kernel buffer + + Fengguang correctly points out that the firmware reading should not use + vfs_read(), since the buffer is in kernel space. + + The vfs_read() just happened to work for kernel threads, but sparse + warns about the incorrect address spaces, and it's definitely incorrect + and could fail for other users of the firmware loading. + + Reported-by: Fengguang Wu + Signed-off-by: Linus Torvalds + +commit 2047dd6d95ac6066e518c26cb5133f4787aefb52 +Author: Linus Torvalds +Date: Wed Oct 3 15:58:32 2012 -0700 + + firmware: teach the kernel to load firmware files directly from the filesystem + + This is a first step in allowing people to by-pass udev for loading + device firmware. Current versions of udev will deadlock (causing us to + block for the 30 second timeout) under some circumstances if the + firmware is loaded as part of the module initialization path, and this + is causing problems for media drivers in particular. + + The current patch hardcodes the firmware path that udev uses by default, + and will fall back to the legacy udev mode if the firmware cannot be + found there. We'd like to add support for both configuring the paths + and the fallback behaviour, but in the meantime this hopefully fixes the + immediate problem, while also giving us a way forward. + + [ v2: Some VFS layer interface cleanups suggested by Al Viro ] + [ v3: use the default udev paths suggested by Kay Sievers ] + + Suggested-by: Ivan Kalvachev + Acked-by: Greg KH + Acked-by: Al Viro + Cc: Mauro Carvalho Chehab + Cc: Kay Sievers + Cc: Ming Lei + Signed-off-by: Linus Torvalds + +commit 7dc9f6ac529be96085a096c440823fe49f95f1cd +Author: Ming Lei +Date: Sat Sep 8 17:32:30 2012 +0800 + + firmware loader: fix compile warning when CONFIG_PM=n + + This patch replaces the previous macro of CONFIG_PM with + CONFIG_PM_SLEEP becasue firmware cache is only used in + system sleep situations. + + Also this patch fixes the below compile warning when + CONFIG_PM=n: + + drivers/base/firmware_class.c:1147: warning: 'device_cache_fw_images' + defined but not used + drivers/base/firmware_class.c:1212: warning: + 'device_uncache_fw_images_delay' defined but not used + + Reported-by: Andrew Morton + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit d4da2957c44390959fea1003188f449b3f38aba3 +Author: Ming Lei +Date: Mon Aug 20 19:04:16 2012 +0800 + + firmware loader: let caching firmware piggyback on loading firmware + + After starting caching firmware, there is still some time left + before devices are suspended, during the period, request_firmware + or its nowait version may still be triggered by the below situations + to load firmware images which can't be cached during suspend/resume + cycle. + + - new devices added + - driver bind + - or device open kind of things + + This patch utilizes the piggyback trick to cache firmware for + this kind of situation: just increase the firmware buf's reference + count and add the fw name entry into cache entry list after starting + caching firmware and before syscore_suspend() is called. + + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit 580eb13b0fb703c49e729d42c313dc901145c278 +Author: Ming Lei +Date: Mon Aug 20 19:04:15 2012 +0800 + + firmware loader: fix firmware -ENOENT situations + + If the requested firmware image doesn't exist, firmware->priv + should be set for the later concurrent requests, otherwise + warning and oops will be triggered inside firmware_free_data(). + + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit 529f2b00940c82abdf17bdc902e2b02d1904a789 +Author: Ming Lei +Date: Fri Aug 17 22:07:00 2012 +0800 + + firmware loader: fix build failure if FW_LOADER is m + + device_cache_fw_images need to iterate devices in system, + so this patch applies the introduced dpm_for_each_dev to + avoid link failure if CONFIG_FW_LOADER is m. + + Reported-by: Fengguang Wu + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit e51f2ca3d0d22b9cd08b6262d6e8423888a339e6 +Author: Ming Lei +Date: Fri Aug 17 22:06:58 2012 +0800 + + firmware loader: fix compile failure if !PM + + 'return 0' should be added to fw_pm_notify if !PM because + return value of the funcion is defined as 'int'. + + Reported-by: Fengguang Wu + Signed-off-by: Ming Lei + Signed-off-by: Greg Kroah-Hartman + +commit 402bbcd0a468c1388fe9fd98a6bd0d4d57f1f5e4 +Author: Ming Lei +Date: Sat Aug 4 12:01:29 2012 +0800 + + firmware loader: cache devices firmware during suspend/resume cycle + + This patch implements caching devices' firmware automatically + during system syspend/resume cycle, so any device drivers can + call request_firmware or request_firmware_nowait inside resume + path to get the cached firmware if they have loaded firmwares + successfully at least once before entering suspend. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit 6b5ef252737d7e46cee1471de1f8f778816ed432 +Author: Ming Lei +Date: Sat Aug 4 12:01:28 2012 +0800 + + firmware loader: use small timeout for cache device firmware + + Because device_cache_fw_images only cache the firmware which has been + loaded sucessfully at leat once, using a small loading timeout should + be reasonable. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit 3a78247eb488608da2dbf2c0b5f312abc7fb36bf +Author: Ming Lei +Date: Sat Aug 4 12:01:27 2012 +0800 + + firmware: introduce device_cache/uncache_fw_images + + This patch introduces the three helpers below: + + void device_cache_fw_images(void) + void device_uncache_fw_images(void) + void device_uncache_fw_images_delay(unsigned long) + + so we can use device_cache_fw_images() to cache firmware for + all devices which need firmware to work, and the device driver + can get the firmware easily from kernel memory when system isn't + ready for completing requests of loading firmware. + + After system is ready for completing firmware loading, driver core + will call device_uncache_fw_images() or its delay version to free + the cached firmware. + + The above helpers will be used to cache device firmware during + system suspend/resume cycle in the following patches. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit fec2fa2ad35e9b5ac3b556b57f2ce0d93d88dad3 +Author: Ming Lei +Date: Sat Aug 4 12:01:25 2012 +0800 + + firmware loader: store firmware name into devres list + + This patch will store firmware name into devres list of the device + which is requesting firmware loading, so that we can implement + auto cache and uncache firmware for devices in need. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit 82502e82fdb519661d280f9a2ff7888a7e11719d +Author: Ming Lei +Date: Sat Aug 4 12:01:24 2012 +0800 + + firmware loader: fix comments on request_firmware_nowait + + request_firmware_nowait is allowed to be called in atomic + context now if @gfp is GFP_ATOMIC, so fix the obsolete + comments and states which situations are suitable for using + it. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit 885f2a4d3e79590a5ac56c600ef21c7f33edf1ff +Author: Ming Lei +Date: Sat Aug 4 12:01:23 2012 +0800 + + firmware loader: fix device lifetime + + Callers of request_firmware* must hold the reference count of + @device, otherwise it is easy to trigger oops since the firmware + loader device is the child of @device. + + This patch adds comments about the usage. In fact, most of drivers + call request_firmware* in its probe() or open(), so the constraint + should be reasonable and can be satisfied. + + Also this patch holds the reference count of @device before + schedule_work() in request_firmware_nowait() to avoid that + the @device is released after request_firmware_nowait returns + and before the worker function is scheduled. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit f8c40c19896e07c5e24596d1c73e0004b83bf564 +Author: Ming Lei +Date: Sat Aug 4 12:01:22 2012 +0800 + + firmware loader: introduce cache_firmware and uncache_firmware + + This patches introduce two kernel APIs of cache_firmware and + uncache_firmware, both of which take the firmware file name + as the only parameter. + + So any drivers can call cache_firmware to cache the specified + firmware file into kernel memory, and can use the cached firmware + in situations which can't request firmware from user space. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit 33f7f4606f2add663f0f055d9e22224b2ed927e6 +Author: Ming Lei +Date: Sat Aug 4 12:01:21 2012 +0800 + + firmware loader: always let firmware_buf own the pages buffer + + This patch always let firmware_buf own the pages buffer allocated + inside firmware_data_write, and add all instances of firmware_buf + into the firmware cache global list. Also introduce one private field + in 'struct firmware', so release_firmware will see the instance of + firmware_buf associated with the current firmware instance, then just + 'free' the instance of firmware_buf. + + The firmware_buf instance represents one pages buffer for one + firmware image, so lots of firmware loading requests can share + the same firmware_buf instance if they request the same firmware + image file. + + This patch will make implementation of the following cache_firmware/ + uncache_firmware very easy and simple. + + In fact, the patch improves request_formware/release_firmware: + + - only request userspace to write firmware image once if + several devices share one same firmware image and its drivers + call request_firmware concurrently. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit 23f444643c50ab3dc66e2cd699ef03d90dbdccc8 +Author: Ming Lei +Date: Sat Aug 4 12:01:20 2012 +0800 + + firmware loader: introduce firmware_buf + + This patch introduces struct firmware_buf to describe the buffer + which holds the firmware data, which will make the following + cache_firmware/uncache_firmware implemented easily. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit c341f46309619686830be4b608c9db06b68bafc1 +Author: Ming Lei +Date: Sat Aug 4 12:01:19 2012 +0800 + + firmware loader: fix creation failure of fw loader device + + If one device driver calls request_firmware_nowait() to request + several different firmwares' loading, device_add() will return + failure since all firmware loader device use same name of the + device who is requesting firmware. + + This patch always use the name of firmware image as the firmware + loader device name to fix the problem since the following patches + for caching firmware will make sure only one loading for same + firmware is alllowd at the same time. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit fca2060e5dac12511c0860878e89e0e5ad8e7a3e +Author: Ming Lei +Date: Sat Aug 4 12:01:18 2012 +0800 + + firmware loader: remove unnecessary wmb() + + The wmb() inside fw_load_abort is not necessary, since + complete() and wait_on_completion() has implied one pair + of memory barrier. + + Also wmb() isn't a correct usage, so just remove it. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit 4eaaa8782ff182e0de3ac050aeb0305879dc89eb +Author: Ming Lei +Date: Sat Aug 4 12:01:17 2012 +0800 + + firmware loader: fix races during loading firmware + + This patch fixes two races in loading firmware: + + 1, FW_STATUS_DONE should be set before waking up the task waitting + on _request_firmware_load, otherwise FW_STATUS_ABORT may be + thought as DONE mistakenly. + + 2, Inside _request_firmware_load(), there is a small window between + wait_for_completion() and mutex_lock(&fw_lock), and 'echo 1 > loading' + still may happen during the period, so this patch checks FW_STATUS_DONE + to prevent pages' buffer completed from being freed in firmware_loading_store. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit dc3ca115481cc50a7d4aa866f607b470280b1e5e +Author: Ming Lei +Date: Sat Aug 4 12:01:16 2012 +0800 + + firmware loader: simplify pages ownership transfer + + This patch doesn't transfer ownership of pages' buffer to the + instance of firmware until the firmware loading is completed, + which will simplify firmware_loading_store a lot, so help + to introduce the following cache_firmware and uncache_firmware + mechanism during system suspend-resume cycle. + + In fact, this patch fixes one bug: if writing data into + firmware loader device is bypassed between writting 1 and 0 to + 'loading', OOPS will be triggered without the patch. + + Also handle the vmap failure case, and add some comments to make + code more readable. + + Signed-off-by: Ming Lei + Cc: Linus Torvalds + Signed-off-by: Greg Kroah-Hartman + +commit e728c819e3666bb37e08a49255b24e6933bb72e5 +Author: Lars-Peter Clausen +Date: Tue Jul 3 18:49:36 2012 +0200 + + driver-core: Use kobj_to_dev instead of re-implementing it + + Signed-off-by: Lars-Peter Clausen + Signed-off-by: Greg Kroah-Hartman +--- + Documentation/firmware_class/README | 7 + + drivers/base/Kconfig | 11 + + drivers/base/core.c | 17 +- + drivers/base/devres.c | 77 +++ + drivers/base/firmware_class.c | 1216 +++++++++++++++++++++++++++++------ + drivers/base/power/main.c | 22 + + include/linux/device.h | 6 + + include/linux/firmware.h | 15 + + include/linux/pm.h | 5 + + 9 files changed, 1177 insertions(+), 199 deletions(-) + +diff --git a/Documentation/firmware_class/README b/Documentation/firmware_class/README +index 7eceaff..5fde1ef 100644 +--- a/Documentation/firmware_class/README ++++ b/Documentation/firmware_class/README +@@ -106,3 +106,10 @@ + on the setup, so I think that the choice on what firmware to make + persistent should be left to userspace. + ++ about firmware cache: ++ -------------------- ++ After firmware cache mechanism is introduced during system sleep, ++ request_firmware can be called safely inside device's suspend and ++ resume callback, and callers need't cache the firmware by ++ themselves any more for dealing with firmware loss during system ++ resume. +diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig +index 7c96a3a..b7af956 100644 +--- a/drivers/base/Kconfig ++++ b/drivers/base/Kconfig +@@ -145,6 +145,17 @@ config EXTRA_FIRMWARE_DIR + this option you can point it elsewhere, such as /lib/firmware/ or + some other directory containing the firmware files. + ++config FW_LOADER_USER_HELPER ++ bool "Fallback user-helper invocation for firmware loading" ++ depends on FW_LOADER ++ default y ++ help ++ This option enables / disables the invocation of user-helper ++ (e.g. udev) for loading firmware files as a fallback after the ++ direct file loading in kernel fails. The user-mode helper is ++ no longer required unless you have a special firmware file that ++ resides in a non-standard path. ++ + config DEBUG_DRIVER + bool "Driver Core verbose debug messages" + depends on DEBUG_KERNEL +diff --git a/drivers/base/core.c b/drivers/base/core.c +index f428321..c360a22 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -84,14 +84,13 @@ const char *dev_driver_string(const struct device *dev) + } + EXPORT_SYMBOL(dev_driver_string); + +-#define to_dev(obj) container_of(obj, struct device, kobj) + #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) + + static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) + { + struct device_attribute *dev_attr = to_dev_attr(attr); +- struct device *dev = to_dev(kobj); ++ struct device *dev = kobj_to_dev(kobj); + ssize_t ret = -EIO; + + if (dev_attr->show) +@@ -107,7 +106,7 @@ static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) + { + struct device_attribute *dev_attr = to_dev_attr(attr); +- struct device *dev = to_dev(kobj); ++ struct device *dev = kobj_to_dev(kobj); + ssize_t ret = -EIO; + + if (dev_attr->store) +@@ -181,7 +180,7 @@ EXPORT_SYMBOL_GPL(device_show_int); + */ + static void device_release(struct kobject *kobj) + { +- struct device *dev = to_dev(kobj); ++ struct device *dev = kobj_to_dev(kobj); + struct device_private *p = dev->p; + + if (dev->release) +@@ -199,7 +198,7 @@ static void device_release(struct kobject *kobj) + + static const void *device_namespace(struct kobject *kobj) + { +- struct device *dev = to_dev(kobj); ++ struct device *dev = kobj_to_dev(kobj); + const void *ns = NULL; + + if (dev->class && dev->class->ns_type) +@@ -220,7 +219,7 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) + struct kobj_type *ktype = get_ktype(kobj); + + if (ktype == &device_ktype) { +- struct device *dev = to_dev(kobj); ++ struct device *dev = kobj_to_dev(kobj); + if (dev->bus) + return 1; + if (dev->class) +@@ -231,7 +230,7 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) + + static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) + { +- struct device *dev = to_dev(kobj); ++ struct device *dev = kobj_to_dev(kobj); + + if (dev->bus) + return dev->bus->name; +@@ -243,7 +242,7 @@ static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) + static int dev_uevent(struct kset *kset, struct kobject *kobj, + struct kobj_uevent_env *env) + { +- struct device *dev = to_dev(kobj); ++ struct device *dev = kobj_to_dev(kobj); + int retval = 0; + + /* add device node properties if present */ +@@ -1131,7 +1130,7 @@ int device_register(struct device *dev) + */ + struct device *get_device(struct device *dev) + { +- return dev ? to_dev(kobject_get(&dev->kobj)) : NULL; ++ return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; + } + + /** +diff --git a/drivers/base/devres.c b/drivers/base/devres.c +index 524bf96..8731979 100644 +--- a/drivers/base/devres.c ++++ b/drivers/base/devres.c +@@ -144,6 +144,48 @@ EXPORT_SYMBOL_GPL(devres_alloc); + #endif + + /** ++ * devres_for_each_res - Resource iterator ++ * @dev: Device to iterate resource from ++ * @release: Look for resources associated with this release function ++ * @match: Match function (optional) ++ * @match_data: Data for the match function ++ * @fn: Function to be called for each matched resource. ++ * @data: Data for @fn, the 3rd parameter of @fn ++ * ++ * Call @fn for each devres of @dev which is associated with @release ++ * and for which @match returns 1. ++ * ++ * RETURNS: ++ * void ++ */ ++void devres_for_each_res(struct device *dev, dr_release_t release, ++ dr_match_t match, void *match_data, ++ void (*fn)(struct device *, void *, void *), ++ void *data) ++{ ++ struct devres_node *node; ++ struct devres_node *tmp; ++ unsigned long flags; ++ ++ if (!fn) ++ return; ++ ++ spin_lock_irqsave(&dev->devres_lock, flags); ++ list_for_each_entry_safe_reverse(node, tmp, ++ &dev->devres_head, entry) { ++ struct devres *dr = container_of(node, struct devres, node); ++ ++ if (node->release != release) ++ continue; ++ if (match && !match(dev, dr->data, match_data)) ++ continue; ++ fn(dev, dr->data, data); ++ } ++ spin_unlock_irqrestore(&dev->devres_lock, flags); ++} ++EXPORT_SYMBOL_GPL(devres_for_each_res); ++ ++/** + * devres_free - Free device resource data + * @res: Pointer to devres data to free + * +@@ -309,6 +351,10 @@ EXPORT_SYMBOL_GPL(devres_remove); + * which @match returns 1. If @match is NULL, it's considered to + * match all. If found, the resource is removed atomically and freed. + * ++ * Note that the release function for the resource will not be called, ++ * only the devres-allocated data will be freed. The caller becomes ++ * responsible for freeing any other data. ++ * + * RETURNS: + * 0 if devres is found and freed, -ENOENT if not found. + */ +diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c +index 5401814..15b36b7 100644 +--- a/drivers/base/firmware_class.c ++++ b/drivers/base/firmware_class.c +@@ -21,8 +21,16 @@ + #include + #include + #include ++#include ++#include ++#include ++#include ++#include ++#include + +-#define to_dev(obj) container_of(obj, struct device, kobj) ++#include ++ ++#include "base.h" + + MODULE_AUTHOR("Manuel Estrada Sainz"); + MODULE_DESCRIPTION("Multi purpose firmware loading support"); +@@ -87,23 +95,354 @@ static inline long firmware_loading_timeout(void) + return loading_timeout > 0 ? loading_timeout * HZ : MAX_SCHEDULE_TIMEOUT; + } + +-/* fw_lock could be moved to 'struct firmware_priv' but since it is just +- * guarding for corner cases a global lock should be OK */ +-static DEFINE_MUTEX(fw_lock); ++struct firmware_cache { ++ /* firmware_buf instance will be added into the below list */ ++ spinlock_t lock; ++ struct list_head head; ++ int state; ++ ++#ifdef CONFIG_PM_SLEEP ++ /* ++ * Names of firmware images which have been cached successfully ++ * will be added into the below list so that device uncache ++ * helper can trace which firmware images have been cached ++ * before. ++ */ ++ spinlock_t name_lock; ++ struct list_head fw_names; ++ ++ wait_queue_head_t wait_queue; ++ int cnt; ++ struct delayed_work work; ++ ++ struct notifier_block pm_notify; ++#endif ++}; + +-struct firmware_priv { ++struct firmware_buf { ++ struct kref ref; ++ struct list_head list; + struct completion completion; +- struct firmware *fw; ++ struct firmware_cache *fwc; + unsigned long status; ++ void *data; ++ size_t size; ++#ifdef CONFIG_FW_LOADER_USER_HELPER ++ bool is_paged_buf; + struct page **pages; + int nr_pages; + int page_array_size; +- struct timer_list timeout; +- struct device dev; +- bool nowait; ++#endif + char fw_id[]; + }; + ++struct fw_cache_entry { ++ struct list_head list; ++ char name[]; ++}; ++ ++struct fw_name_devm { ++ unsigned long magic; ++ char name[]; ++}; ++ ++#define to_fwbuf(d) container_of(d, struct firmware_buf, ref) ++ ++#define FW_LOADER_NO_CACHE 0 ++#define FW_LOADER_START_CACHE 1 ++ ++static int fw_cache_piggyback_on_request(const char *name); ++ ++/* fw_lock could be moved to 'struct firmware_priv' but since it is just ++ * guarding for corner cases a global lock should be OK */ ++static DEFINE_MUTEX(fw_lock); ++ ++static struct firmware_cache fw_cache; ++ ++static struct firmware_buf *__allocate_fw_buf(const char *fw_name, ++ struct firmware_cache *fwc) ++{ ++ struct firmware_buf *buf; ++ ++ buf = kzalloc(sizeof(*buf) + strlen(fw_name) + 1 , GFP_ATOMIC); ++ ++ if (!buf) ++ return buf; ++ ++ kref_init(&buf->ref); ++ strcpy(buf->fw_id, fw_name); ++ buf->fwc = fwc; ++ init_completion(&buf->completion); ++ ++ pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); ++ ++ return buf; ++} ++ ++static struct firmware_buf *__fw_lookup_buf(const char *fw_name) ++{ ++ struct firmware_buf *tmp; ++ struct firmware_cache *fwc = &fw_cache; ++ ++ list_for_each_entry(tmp, &fwc->head, list) ++ if (!strcmp(tmp->fw_id, fw_name)) ++ return tmp; ++ return NULL; ++} ++ ++static int fw_lookup_and_allocate_buf(const char *fw_name, ++ struct firmware_cache *fwc, ++ struct firmware_buf **buf) ++{ ++ struct firmware_buf *tmp; ++ ++ spin_lock(&fwc->lock); ++ tmp = __fw_lookup_buf(fw_name); ++ if (tmp) { ++ kref_get(&tmp->ref); ++ spin_unlock(&fwc->lock); ++ *buf = tmp; ++ return 1; ++ } ++ tmp = __allocate_fw_buf(fw_name, fwc); ++ if (tmp) ++ list_add(&tmp->list, &fwc->head); ++ spin_unlock(&fwc->lock); ++ ++ *buf = tmp; ++ ++ return tmp ? 0 : -ENOMEM; ++} ++ ++static struct firmware_buf *fw_lookup_buf(const char *fw_name) ++{ ++ struct firmware_buf *tmp; ++ struct firmware_cache *fwc = &fw_cache; ++ ++ spin_lock(&fwc->lock); ++ tmp = __fw_lookup_buf(fw_name); ++ spin_unlock(&fwc->lock); ++ ++ return tmp; ++} ++ ++static void __fw_free_buf(struct kref *ref) ++{ ++ struct firmware_buf *buf = to_fwbuf(ref); ++ struct firmware_cache *fwc = buf->fwc; ++ ++ pr_debug("%s: fw-%s buf=%p data=%p size=%u\n", ++ __func__, buf->fw_id, buf, buf->data, ++ (unsigned int)buf->size); ++ ++ list_del(&buf->list); ++ spin_unlock(&fwc->lock); ++ ++#ifdef CONFIG_FW_LOADER_USER_HELPER ++ if (buf->is_paged_buf) { ++ int i; ++ vunmap(buf->data); ++ for (i = 0; i < buf->nr_pages; i++) ++ __free_page(buf->pages[i]); ++ kfree(buf->pages); ++ } else ++#endif ++ vfree(buf->data); ++ kfree(buf); ++} ++ ++static void fw_free_buf(struct firmware_buf *buf) ++{ ++ struct firmware_cache *fwc = buf->fwc; ++ spin_lock(&fwc->lock); ++ if (!kref_put(&buf->ref, __fw_free_buf)) ++ spin_unlock(&fwc->lock); ++} ++ ++/* direct firmware loading support */ ++static char fw_path_para[256]; ++static const char * const fw_path[] = { ++ fw_path_para, ++ "/lib/firmware/updates/" UTS_RELEASE, ++ "/lib/firmware/updates", ++ "/lib/firmware/" UTS_RELEASE, ++ "/lib/firmware" ++}; ++ ++/* ++ * Typical usage is that passing 'firmware_class.path=$CUSTOMIZED_PATH' ++ * from kernel command line because firmware_class is generally built in ++ * kernel instead of module. ++ */ ++module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); ++MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); ++ ++/* Don't inline this: 'struct kstat' is biggish */ ++static noinline_for_stack long fw_file_size(struct file *file) ++{ ++ struct kstat st; ++ if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st)) ++ return -1; ++ if (!S_ISREG(st.mode)) ++ return -1; ++ if (st.size != (long)st.size) ++ return -1; ++ return st.size; ++} ++ ++static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) ++{ ++ long size; ++ char *buf; ++ ++ size = fw_file_size(file); ++ if (size <= 0) ++ return false; ++ buf = vmalloc(size); ++ if (!buf) ++ return false; ++ if (kernel_read(file, 0, buf, size) != size) { ++ vfree(buf); ++ return false; ++ } ++ fw_buf->data = buf; ++ fw_buf->size = size; ++ return true; ++} ++ ++static bool fw_get_filesystem_firmware(struct device *device, ++ struct firmware_buf *buf) ++{ ++ int i; ++ bool success = false; ++ char *path = __getname(); ++ ++ for (i = 0; i < ARRAY_SIZE(fw_path); i++) { ++ struct file *file; ++ ++ /* skip the unset customized path */ ++ if (!fw_path[i][0]) ++ continue; ++ ++ snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id); ++ ++ file = filp_open(path, O_RDONLY, 0); ++ if (IS_ERR(file)) ++ continue; ++ success = fw_read_file_contents(file, buf); ++ fput(file); ++ if (success) ++ break; ++ } ++ __putname(path); ++ ++ if (success) { ++ dev_dbg(device, "firmware: direct-loading firmware %s\n", ++ buf->fw_id); ++ mutex_lock(&fw_lock); ++ set_bit(FW_STATUS_DONE, &buf->status); ++ complete_all(&buf->completion); ++ mutex_unlock(&fw_lock); ++ } ++ ++ return success; ++} ++ ++/* firmware holds the ownership of pages */ ++static void firmware_free_data(const struct firmware *fw) ++{ ++ /* Loaded directly? */ ++ if (!fw->priv) { ++ vfree(fw->data); ++ return; ++ } ++ fw_free_buf(fw->priv); ++} ++ ++/* store the pages buffer info firmware from buf */ ++static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) ++{ ++ fw->priv = buf; ++#ifdef CONFIG_FW_LOADER_USER_HELPER ++ fw->pages = buf->pages; ++#endif ++ fw->size = buf->size; ++ fw->data = buf->data; ++ ++ pr_debug("%s: fw-%s buf=%p data=%p size=%u\n", ++ __func__, buf->fw_id, buf, buf->data, ++ (unsigned int)buf->size); ++} ++ ++#ifdef CONFIG_PM_SLEEP ++static void fw_name_devm_release(struct device *dev, void *res) ++{ ++ struct fw_name_devm *fwn = res; ++ ++ if (fwn->magic == (unsigned long)&fw_cache) ++ pr_debug("%s: fw_name-%s devm-%p released\n", ++ __func__, fwn->name, res); ++} ++ ++static int fw_devm_match(struct device *dev, void *res, ++ void *match_data) ++{ ++ struct fw_name_devm *fwn = res; ++ ++ return (fwn->magic == (unsigned long)&fw_cache) && ++ !strcmp(fwn->name, match_data); ++} ++ ++static struct fw_name_devm *fw_find_devm_name(struct device *dev, ++ const char *name) ++{ ++ struct fw_name_devm *fwn; ++ ++ fwn = devres_find(dev, fw_name_devm_release, ++ fw_devm_match, (void *)name); ++ return fwn; ++} ++ ++/* add firmware name into devres list */ ++static int fw_add_devm_name(struct device *dev, const char *name) ++{ ++ struct fw_name_devm *fwn; ++ ++ fwn = fw_find_devm_name(dev, name); ++ if (fwn) ++ return 1; ++ ++ fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm) + ++ strlen(name) + 1, GFP_KERNEL); ++ if (!fwn) ++ return -ENOMEM; ++ ++ fwn->magic = (unsigned long)&fw_cache; ++ strcpy(fwn->name, name); ++ devres_add(dev, fwn); ++ ++ return 0; ++} ++#else ++static int fw_add_devm_name(struct device *dev, const char *name) ++{ ++ return 0; ++} ++#endif ++ ++ ++/* ++ * user-mode helper code ++ */ ++#ifdef CONFIG_FW_LOADER_USER_HELPER ++struct firmware_priv { ++ struct delayed_work timeout_work; ++ bool nowait; ++ struct device dev; ++ struct firmware_buf *buf; ++ struct firmware *fw; ++}; ++ + static struct firmware_priv *to_firmware_priv(struct device *dev) + { + return container_of(dev, struct firmware_priv, dev); +@@ -111,11 +450,15 @@ static struct firmware_priv *to_firmware_priv(struct device *dev) + + static void fw_load_abort(struct firmware_priv *fw_priv) + { +- set_bit(FW_STATUS_ABORT, &fw_priv->status); +- wmb(); +- complete(&fw_priv->completion); ++ struct firmware_buf *buf = fw_priv->buf; ++ ++ set_bit(FW_STATUS_ABORT, &buf->status); ++ complete_all(&buf->completion); + } + ++#define is_fw_load_aborted(buf) \ ++ test_bit(FW_STATUS_ABORT, &(buf)->status) ++ + static ssize_t firmware_timeout_show(struct class *class, + struct class_attribute *attr, + char *buf) +@@ -156,11 +499,7 @@ static struct class_attribute firmware_class_attrs[] = { + static void fw_dev_release(struct device *dev) + { + struct firmware_priv *fw_priv = to_firmware_priv(dev); +- int i; + +- for (i = 0; i < fw_priv->nr_pages; i++) +- __free_page(fw_priv->pages[i]); +- kfree(fw_priv->pages); + kfree(fw_priv); + + module_put(THIS_MODULE); +@@ -170,7 +509,7 @@ static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) + { + struct firmware_priv *fw_priv = to_firmware_priv(dev); + +- if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id)) ++ if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->buf->fw_id)) + return -ENOMEM; + if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout)) + return -ENOMEM; +@@ -191,26 +530,30 @@ static ssize_t firmware_loading_show(struct device *dev, + struct device_attribute *attr, char *buf) + { + struct firmware_priv *fw_priv = to_firmware_priv(dev); +- int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); ++ int loading = test_bit(FW_STATUS_LOADING, &fw_priv->buf->status); + + return sprintf(buf, "%d\n", loading); + } + +-static void firmware_free_data(const struct firmware *fw) +-{ +- int i; +- vunmap(fw->data); +- if (fw->pages) { +- for (i = 0; i < PFN_UP(fw->size); i++) +- __free_page(fw->pages[i]); +- kfree(fw->pages); +- } +-} +- + /* Some architectures don't have PAGE_KERNEL_RO */ + #ifndef PAGE_KERNEL_RO + #define PAGE_KERNEL_RO PAGE_KERNEL + #endif ++ ++/* one pages buffer should be mapped/unmapped only once */ ++static int fw_map_pages_buf(struct firmware_buf *buf) ++{ ++ if (!buf->is_paged_buf) ++ return 0; ++ ++ if (buf->data) ++ vunmap(buf->data); ++ buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO); ++ if (!buf->data) ++ return -ENOMEM; ++ return 0; ++} ++ + /** + * firmware_loading_store - set value in the 'loading' control file + * @dev: device pointer +@@ -229,45 +572,41 @@ static ssize_t firmware_loading_store(struct device *dev, + const char *buf, size_t count) + { + struct firmware_priv *fw_priv = to_firmware_priv(dev); ++ struct firmware_buf *fw_buf = fw_priv->buf; + int loading = simple_strtol(buf, NULL, 10); + int i; + + mutex_lock(&fw_lock); + +- if (!fw_priv->fw) ++ if (!fw_buf) + goto out; + + switch (loading) { + case 1: +- firmware_free_data(fw_priv->fw); +- memset(fw_priv->fw, 0, sizeof(struct firmware)); +- /* If the pages are not owned by 'struct firmware' */ +- for (i = 0; i < fw_priv->nr_pages; i++) +- __free_page(fw_priv->pages[i]); +- kfree(fw_priv->pages); +- fw_priv->pages = NULL; +- fw_priv->page_array_size = 0; +- fw_priv->nr_pages = 0; +- set_bit(FW_STATUS_LOADING, &fw_priv->status); ++ /* discarding any previous partial load */ ++ if (!test_bit(FW_STATUS_DONE, &fw_buf->status)) { ++ for (i = 0; i < fw_buf->nr_pages; i++) ++ __free_page(fw_buf->pages[i]); ++ kfree(fw_buf->pages); ++ fw_buf->pages = NULL; ++ fw_buf->page_array_size = 0; ++ fw_buf->nr_pages = 0; ++ set_bit(FW_STATUS_LOADING, &fw_buf->status); ++ } + break; + case 0: +- if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) { +- vunmap(fw_priv->fw->data); +- fw_priv->fw->data = vmap(fw_priv->pages, +- fw_priv->nr_pages, +- 0, PAGE_KERNEL_RO); +- if (!fw_priv->fw->data) { +- dev_err(dev, "%s: vmap() failed\n", __func__); +- goto err; +- } +- /* Pages are now owned by 'struct firmware' */ +- fw_priv->fw->pages = fw_priv->pages; +- fw_priv->pages = NULL; +- +- fw_priv->page_array_size = 0; +- fw_priv->nr_pages = 0; +- complete(&fw_priv->completion); +- clear_bit(FW_STATUS_LOADING, &fw_priv->status); ++ if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { ++ set_bit(FW_STATUS_DONE, &fw_buf->status); ++ clear_bit(FW_STATUS_LOADING, &fw_buf->status); ++ ++ /* ++ * Several loading requests may be pending on ++ * one same firmware buf, so let all requests ++ * see the mapped 'buf->data' once the loading ++ * is completed. ++ * */ ++ fw_map_pages_buf(fw_buf); ++ complete_all(&fw_buf->completion); + break; + } + /* fallthrough */ +@@ -275,7 +614,6 @@ static ssize_t firmware_loading_store(struct device *dev, + dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading); + /* fallthrough */ + case -1: +- err: + fw_load_abort(fw_priv); + break; + } +@@ -290,23 +628,23 @@ static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t offset, size_t count) + { +- struct device *dev = to_dev(kobj); ++ struct device *dev = kobj_to_dev(kobj); + struct firmware_priv *fw_priv = to_firmware_priv(dev); +- struct firmware *fw; ++ struct firmware_buf *buf; + ssize_t ret_count; + + mutex_lock(&fw_lock); +- fw = fw_priv->fw; +- if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { ++ buf = fw_priv->buf; ++ if (!buf || test_bit(FW_STATUS_DONE, &buf->status)) { + ret_count = -ENODEV; + goto out; + } +- if (offset > fw->size) { ++ if (offset > buf->size) { + ret_count = 0; + goto out; + } +- if (count > fw->size - offset) +- count = fw->size - offset; ++ if (count > buf->size - offset) ++ count = buf->size - offset; + + ret_count = count; + +@@ -316,11 +654,11 @@ static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, + int page_ofs = offset & (PAGE_SIZE-1); + int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count); + +- page_data = kmap(fw_priv->pages[page_nr]); ++ page_data = kmap(buf->pages[page_nr]); + + memcpy(buffer, page_data + page_ofs, page_cnt); + +- kunmap(fw_priv->pages[page_nr]); ++ kunmap(buf->pages[page_nr]); + buffer += page_cnt; + offset += page_cnt; + count -= page_cnt; +@@ -332,12 +670,13 @@ out: + + static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) + { ++ struct firmware_buf *buf = fw_priv->buf; + int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT; + + /* If the array of pages is too small, grow it... */ +- if (fw_priv->page_array_size < pages_needed) { ++ if (buf->page_array_size < pages_needed) { + int new_array_size = max(pages_needed, +- fw_priv->page_array_size * 2); ++ buf->page_array_size * 2); + struct page **new_pages; + + new_pages = kmalloc(new_array_size * sizeof(void *), +@@ -346,24 +685,24 @@ static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) + fw_load_abort(fw_priv); + return -ENOMEM; + } +- memcpy(new_pages, fw_priv->pages, +- fw_priv->page_array_size * sizeof(void *)); +- memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * +- (new_array_size - fw_priv->page_array_size)); +- kfree(fw_priv->pages); +- fw_priv->pages = new_pages; +- fw_priv->page_array_size = new_array_size; ++ memcpy(new_pages, buf->pages, ++ buf->page_array_size * sizeof(void *)); ++ memset(&new_pages[buf->page_array_size], 0, sizeof(void *) * ++ (new_array_size - buf->page_array_size)); ++ kfree(buf->pages); ++ buf->pages = new_pages; ++ buf->page_array_size = new_array_size; + } + +- while (fw_priv->nr_pages < pages_needed) { +- fw_priv->pages[fw_priv->nr_pages] = ++ while (buf->nr_pages < pages_needed) { ++ buf->pages[buf->nr_pages] = + alloc_page(GFP_KERNEL | __GFP_HIGHMEM); + +- if (!fw_priv->pages[fw_priv->nr_pages]) { ++ if (!buf->pages[buf->nr_pages]) { + fw_load_abort(fw_priv); + return -ENOMEM; + } +- fw_priv->nr_pages++; ++ buf->nr_pages++; + } + return 0; + } +@@ -384,20 +723,21 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t offset, size_t count) + { +- struct device *dev = to_dev(kobj); ++ struct device *dev = kobj_to_dev(kobj); + struct firmware_priv *fw_priv = to_firmware_priv(dev); +- struct firmware *fw; ++ struct firmware_buf *buf; + ssize_t retval; + + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + + mutex_lock(&fw_lock); +- fw = fw_priv->fw; +- if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { ++ buf = fw_priv->buf; ++ if (!buf || test_bit(FW_STATUS_DONE, &buf->status)) { + retval = -ENODEV; + goto out; + } ++ + retval = fw_realloc_buffer(fw_priv, offset + count); + if (retval) + goto out; +@@ -410,17 +750,17 @@ static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, + int page_ofs = offset & (PAGE_SIZE - 1); + int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count); + +- page_data = kmap(fw_priv->pages[page_nr]); ++ page_data = kmap(buf->pages[page_nr]); + + memcpy(page_data + page_ofs, buffer, page_cnt); + +- kunmap(fw_priv->pages[page_nr]); ++ kunmap(buf->pages[page_nr]); + buffer += page_cnt; + offset += page_cnt; + count -= page_cnt; + } + +- fw->size = max_t(size_t, offset, fw->size); ++ buf->size = max_t(size_t, offset, buf->size); + out: + mutex_unlock(&fw_lock); + return retval; +@@ -433,11 +773,18 @@ static struct bin_attribute firmware_attr_data = { + .write = firmware_data_write, + }; + +-static void firmware_class_timeout(u_long data) ++static void firmware_class_timeout_work(struct work_struct *work) + { +- struct firmware_priv *fw_priv = (struct firmware_priv *) data; ++ struct firmware_priv *fw_priv = container_of(work, ++ struct firmware_priv, timeout_work.work); + ++ mutex_lock(&fw_lock); ++ if (test_bit(FW_STATUS_DONE, &(fw_priv->buf->status))) { ++ mutex_unlock(&fw_lock); ++ return; ++ } + fw_load_abort(fw_priv); ++ mutex_unlock(&fw_lock); + } + + static struct firmware_priv * +@@ -447,70 +794,38 @@ fw_create_instance(struct firmware *firmware, const char *fw_name, + struct firmware_priv *fw_priv; + struct device *f_dev; + +- fw_priv = kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL); ++ fw_priv = kzalloc(sizeof(*fw_priv), GFP_KERNEL); + if (!fw_priv) { + dev_err(device, "%s: kmalloc failed\n", __func__); +- return ERR_PTR(-ENOMEM); ++ fw_priv = ERR_PTR(-ENOMEM); ++ goto exit; + } + +- fw_priv->fw = firmware; + fw_priv->nowait = nowait; +- strcpy(fw_priv->fw_id, fw_name); +- init_completion(&fw_priv->completion); +- setup_timer(&fw_priv->timeout, +- firmware_class_timeout, (u_long) fw_priv); ++ fw_priv->fw = firmware; ++ INIT_DELAYED_WORK(&fw_priv->timeout_work, ++ firmware_class_timeout_work); + + f_dev = &fw_priv->dev; + + device_initialize(f_dev); +- dev_set_name(f_dev, "%s", dev_name(device)); ++ dev_set_name(f_dev, "%s", fw_name); + f_dev->parent = device; + f_dev->class = &firmware_class; +- ++exit: + return fw_priv; + } + +-static struct firmware_priv * +-_request_firmware_prepare(const struct firmware **firmware_p, const char *name, +- struct device *device, bool uevent, bool nowait) +-{ +- struct firmware *firmware; +- struct firmware_priv *fw_priv; +- +- if (!firmware_p) +- return ERR_PTR(-EINVAL); +- +- *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); +- if (!firmware) { +- dev_err(device, "%s: kmalloc(struct firmware) failed\n", +- __func__); +- return ERR_PTR(-ENOMEM); +- } +- +- if (fw_get_builtin_firmware(firmware, name)) { +- dev_dbg(device, "firmware: using built-in firmware %s\n", name); +- return NULL; +- } +- +- fw_priv = fw_create_instance(firmware, name, device, uevent, nowait); +- if (IS_ERR(fw_priv)) { +- release_firmware(firmware); +- *firmware_p = NULL; +- } +- return fw_priv; +-} +- +-static void _request_firmware_cleanup(const struct firmware **firmware_p) +-{ +- release_firmware(*firmware_p); +- *firmware_p = NULL; +-} +- ++/* load a firmware via user helper */ + static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, + long timeout) + { + int retval = 0; + struct device *f_dev = &fw_priv->dev; ++ struct firmware_buf *buf = fw_priv->buf; ++ ++ /* fall back on userspace loading */ ++ buf->is_paged_buf = true; + + dev_set_uevent_suppress(f_dev, true); + +@@ -537,24 +852,18 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, + + if (uevent) { + dev_set_uevent_suppress(f_dev, false); +- dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_id); ++ dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); + if (timeout != MAX_SCHEDULE_TIMEOUT) +- mod_timer(&fw_priv->timeout, +- round_jiffies_up(jiffies + timeout)); ++ schedule_delayed_work(&fw_priv->timeout_work, timeout); + + kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); + } + +- wait_for_completion(&fw_priv->completion); ++ wait_for_completion(&buf->completion); + +- set_bit(FW_STATUS_DONE, &fw_priv->status); +- del_timer_sync(&fw_priv->timeout); ++ cancel_delayed_work_sync(&fw_priv->timeout_work); + +- mutex_lock(&fw_lock); +- if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) +- retval = -ENOENT; +- fw_priv->fw = NULL; +- mutex_unlock(&fw_lock); ++ fw_priv->buf = NULL; + + device_remove_file(f_dev, &dev_attr_loading); + err_del_bin_attr: +@@ -566,6 +875,186 @@ err_put_dev: + return retval; + } + ++static int fw_load_from_user_helper(struct firmware *firmware, ++ const char *name, struct device *device, ++ bool uevent, bool nowait, long timeout) ++{ ++ struct firmware_priv *fw_priv; ++ ++ fw_priv = fw_create_instance(firmware, name, device, uevent, nowait); ++ if (IS_ERR(fw_priv)) ++ return PTR_ERR(fw_priv); ++ ++ fw_priv->buf = firmware->priv; ++ return _request_firmware_load(fw_priv, uevent, timeout); ++} ++#else /* CONFIG_FW_LOADER_USER_HELPER */ ++static inline int ++fw_load_from_user_helper(struct firmware *firmware, const char *name, ++ struct device *device, bool uevent, bool nowait, ++ long timeout) ++{ ++ return -ENOENT; ++} ++ ++/* No abort during direct loading */ ++#define is_fw_load_aborted(buf) false ++ ++#endif /* CONFIG_FW_LOADER_USER_HELPER */ ++ ++ ++/* wait until the shared firmware_buf becomes ready (or error) */ ++static int sync_cached_firmware_buf(struct firmware_buf *buf) ++{ ++ int ret = 0; ++ ++ mutex_lock(&fw_lock); ++ while (!test_bit(FW_STATUS_DONE, &buf->status)) { ++ if (is_fw_load_aborted(buf)) { ++ ret = -ENOENT; ++ break; ++ } ++ mutex_unlock(&fw_lock); ++ wait_for_completion(&buf->completion); ++ mutex_lock(&fw_lock); ++ } ++ mutex_unlock(&fw_lock); ++ return ret; ++} ++ ++/* prepare firmware and firmware_buf structs; ++ * return 0 if a firmware is already assigned, 1 if need to load one, ++ * or a negative error code ++ */ ++static int ++_request_firmware_prepare(struct firmware **firmware_p, const char *name, ++ struct device *device) ++{ ++ struct firmware *firmware; ++ struct firmware_buf *buf; ++ int ret; ++ ++ *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); ++ if (!firmware) { ++ dev_err(device, "%s: kmalloc(struct firmware) failed\n", ++ __func__); ++ return -ENOMEM; ++ } ++ ++ if (fw_get_builtin_firmware(firmware, name)) { ++ dev_dbg(device, "firmware: using built-in firmware %s\n", name); ++ return 0; /* assigned */ ++ } ++ ++ ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf); ++ ++ /* ++ * bind with 'buf' now to avoid warning in failure path ++ * of requesting firmware. ++ */ ++ firmware->priv = buf; ++ ++ if (ret > 0) { ++ ret = sync_cached_firmware_buf(buf); ++ if (!ret) { ++ fw_set_page_data(buf, firmware); ++ return 0; /* assigned */ ++ } ++ } ++ ++ if (ret < 0) ++ return ret; ++ return 1; /* need to load */ ++} ++ ++static int assign_firmware_buf(struct firmware *fw, struct device *device) ++{ ++ struct firmware_buf *buf = fw->priv; ++ ++ mutex_lock(&fw_lock); ++ if (!buf->size || is_fw_load_aborted(buf)) { ++ mutex_unlock(&fw_lock); ++ return -ENOENT; ++ } ++ ++ /* ++ * add firmware name into devres list so that we can auto cache ++ * and uncache firmware for device. ++ * ++ * device may has been deleted already, but the problem ++ * should be fixed in devres or driver core. ++ */ ++ if (device) ++ fw_add_devm_name(device, buf->fw_id); ++ ++ /* ++ * After caching firmware image is started, let it piggyback ++ * on request firmware. ++ */ ++ if (buf->fwc->state == FW_LOADER_START_CACHE) { ++ if (fw_cache_piggyback_on_request(buf->fw_id)) ++ kref_get(&buf->ref); ++ } ++ ++ /* pass the pages buffer to driver at the last minute */ ++ fw_set_page_data(buf, fw); ++ mutex_unlock(&fw_lock); ++ return 0; ++} ++ ++/* called from request_firmware() and request_firmware_work_func() */ ++static int ++_request_firmware(const struct firmware **firmware_p, const char *name, ++ struct device *device, bool uevent, bool nowait) ++{ ++ struct firmware *fw; ++ long timeout; ++ int ret; ++ ++ if (!firmware_p) ++ return -EINVAL; ++ ++ ret = _request_firmware_prepare(&fw, name, device); ++ if (ret <= 0) /* error or already assigned */ ++ goto out; ++ ++ ret = 0; ++ timeout = firmware_loading_timeout(); ++ if (nowait) { ++ timeout = usermodehelper_read_lock_wait(timeout); ++ if (!timeout) { ++ dev_dbg(device, "firmware: %s loading timed out\n", ++ name); ++ ret = -EBUSY; ++ goto out; ++ } ++ } else { ++ ret = usermodehelper_read_trylock(); ++ if (WARN_ON(ret)) { ++ dev_err(device, "firmware: %s will not be loaded\n", ++ name); ++ goto out; ++ } ++ } ++ ++ if (!fw_get_filesystem_firmware(device, fw->priv)) ++ ret = fw_load_from_user_helper(fw, name, device, ++ uevent, nowait, timeout); ++ if (!ret) ++ ret = assign_firmware_buf(fw, device); ++ ++ usermodehelper_read_unlock(); ++ ++ out: ++ if (ret < 0) { ++ release_firmware(fw); ++ fw = NULL; ++ } ++ ++ *firmware_p = fw; ++ return ret; ++} ++ + /** + * request_firmware: - send firmware request and wait for it + * @firmware_p: pointer to firmware image +@@ -580,34 +1069,17 @@ err_put_dev: + * @name will be used as $FIRMWARE in the uevent environment and + * should be distinctive enough not to be confused with any other + * firmware image for this or any other device. ++ * ++ * Caller must hold the reference count of @device. ++ * ++ * The function can be called safely inside device's suspend and ++ * resume callback. + **/ + int + request_firmware(const struct firmware **firmware_p, const char *name, + struct device *device) + { +- struct firmware_priv *fw_priv; +- int ret; +- +- if (!name || name[0] == '\0') +- return -EINVAL; +- +- fw_priv = _request_firmware_prepare(firmware_p, name, device, true, +- false); +- if (IS_ERR_OR_NULL(fw_priv)) +- return PTR_RET(fw_priv); +- +- ret = usermodehelper_read_trylock(); +- if (WARN_ON(ret)) { +- dev_err(device, "firmware: %s will not be loaded\n", name); +- } else { +- ret = _request_firmware_load(fw_priv, true, +- firmware_loading_timeout()); +- usermodehelper_read_unlock(); +- } +- if (ret) +- _request_firmware_cleanup(firmware_p); +- +- return ret; ++ return _request_firmware(firmware_p, name, device, true, false); + } + + /** +@@ -635,32 +1110,13 @@ static void request_firmware_work_func(struct work_struct *work) + { + struct firmware_work *fw_work; + const struct firmware *fw; +- struct firmware_priv *fw_priv; +- long timeout; +- int ret; + + fw_work = container_of(work, struct firmware_work, work); +- fw_priv = _request_firmware_prepare(&fw, fw_work->name, fw_work->device, +- fw_work->uevent, true); +- if (IS_ERR_OR_NULL(fw_priv)) { +- ret = PTR_RET(fw_priv); +- goto out; +- } +- +- timeout = usermodehelper_read_lock_wait(firmware_loading_timeout()); +- if (timeout) { +- ret = _request_firmware_load(fw_priv, fw_work->uevent, timeout); +- usermodehelper_read_unlock(); +- } else { +- dev_dbg(fw_work->device, "firmware: %s loading timed out\n", +- fw_work->name); +- ret = -EAGAIN; +- } +- if (ret) +- _request_firmware_cleanup(&fw); + +- out: ++ _request_firmware(&fw, fw_work->name, fw_work->device, ++ fw_work->uevent, true); + fw_work->cont(fw, fw_work->context); ++ put_device(fw_work->device); /* taken in request_firmware_nowait() */ + + module_put(fw_work->module); + kfree(fw_work); +@@ -679,9 +1135,15 @@ static void request_firmware_work_func(struct work_struct *work) + * @cont: function will be called asynchronously when the firmware + * request is over. + * +- * Asynchronous variant of request_firmware() for user contexts where +- * it is not possible to sleep for long time. It can't be called +- * in atomic contexts. ++ * Caller must hold the reference count of @device. ++ * ++ * Asynchronous variant of request_firmware() for user contexts: ++ * - sleep for as small periods as possible since it may ++ * increase kernel boot time of built-in device drivers ++ * requesting firmware in their ->probe() methods, if ++ * @gfp is GFP_KERNEL. ++ * ++ * - can't sleep at all if @gfp is GFP_ATOMIC. + **/ + int + request_firmware_nowait( +@@ -707,19 +1169,391 @@ request_firmware_nowait( + return -EFAULT; + } + ++ get_device(fw_work->device); + INIT_WORK(&fw_work->work, request_firmware_work_func); + schedule_work(&fw_work->work); + return 0; + } + ++/** ++ * cache_firmware - cache one firmware image in kernel memory space ++ * @fw_name: the firmware image name ++ * ++ * Cache firmware in kernel memory so that drivers can use it when ++ * system isn't ready for them to request firmware image from userspace. ++ * Once it returns successfully, driver can use request_firmware or its ++ * nowait version to get the cached firmware without any interacting ++ * with userspace ++ * ++ * Return 0 if the firmware image has been cached successfully ++ * Return !0 otherwise ++ * ++ */ ++int cache_firmware(const char *fw_name) ++{ ++ int ret; ++ const struct firmware *fw; ++ ++ pr_debug("%s: %s\n", __func__, fw_name); ++ ++ ret = request_firmware(&fw, fw_name, NULL); ++ if (!ret) ++ kfree(fw); ++ ++ pr_debug("%s: %s ret=%d\n", __func__, fw_name, ret); ++ ++ return ret; ++} ++ ++/** ++ * uncache_firmware - remove one cached firmware image ++ * @fw_name: the firmware image name ++ * ++ * Uncache one firmware image which has been cached successfully ++ * before. ++ * ++ * Return 0 if the firmware cache has been removed successfully ++ * Return !0 otherwise ++ * ++ */ ++int uncache_firmware(const char *fw_name) ++{ ++ struct firmware_buf *buf; ++ struct firmware fw; ++ ++ pr_debug("%s: %s\n", __func__, fw_name); ++ ++ if (fw_get_builtin_firmware(&fw, fw_name)) ++ return 0; ++ ++ buf = fw_lookup_buf(fw_name); ++ if (buf) { ++ fw_free_buf(buf); ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ ++#ifdef CONFIG_PM_SLEEP ++static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) ++{ ++ struct fw_cache_entry *fce; ++ ++ fce = kzalloc(sizeof(*fce) + strlen(name) + 1, GFP_ATOMIC); ++ if (!fce) ++ goto exit; ++ ++ strcpy(fce->name, name); ++exit: ++ return fce; ++} ++ ++static int __fw_entry_found(const char *name) ++{ ++ struct firmware_cache *fwc = &fw_cache; ++ struct fw_cache_entry *fce; ++ ++ list_for_each_entry(fce, &fwc->fw_names, list) { ++ if (!strcmp(fce->name, name)) ++ return 1; ++ } ++ return 0; ++} ++ ++static int fw_cache_piggyback_on_request(const char *name) ++{ ++ struct firmware_cache *fwc = &fw_cache; ++ struct fw_cache_entry *fce; ++ int ret = 0; ++ ++ spin_lock(&fwc->name_lock); ++ if (__fw_entry_found(name)) ++ goto found; ++ ++ fce = alloc_fw_cache_entry(name); ++ if (fce) { ++ ret = 1; ++ list_add(&fce->list, &fwc->fw_names); ++ pr_debug("%s: fw: %s\n", __func__, name); ++ } ++found: ++ spin_unlock(&fwc->name_lock); ++ return ret; ++} ++ ++static void free_fw_cache_entry(struct fw_cache_entry *fce) ++{ ++ kfree(fce); ++} ++ ++static void __async_dev_cache_fw_image(void *fw_entry, ++ async_cookie_t cookie) ++{ ++ struct fw_cache_entry *fce = fw_entry; ++ struct firmware_cache *fwc = &fw_cache; ++ int ret; ++ ++ ret = cache_firmware(fce->name); ++ if (ret) { ++ spin_lock(&fwc->name_lock); ++ list_del(&fce->list); ++ spin_unlock(&fwc->name_lock); ++ ++ free_fw_cache_entry(fce); ++ } ++ ++ spin_lock(&fwc->name_lock); ++ fwc->cnt--; ++ spin_unlock(&fwc->name_lock); ++ ++ wake_up(&fwc->wait_queue); ++} ++ ++/* called with dev->devres_lock held */ ++static void dev_create_fw_entry(struct device *dev, void *res, ++ void *data) ++{ ++ struct fw_name_devm *fwn = res; ++ const char *fw_name = fwn->name; ++ struct list_head *head = data; ++ struct fw_cache_entry *fce; ++ ++ fce = alloc_fw_cache_entry(fw_name); ++ if (fce) ++ list_add(&fce->list, head); ++} ++ ++static int devm_name_match(struct device *dev, void *res, ++ void *match_data) ++{ ++ struct fw_name_devm *fwn = res; ++ return (fwn->magic == (unsigned long)match_data); ++} ++ ++static void dev_cache_fw_image(struct device *dev, void *data) ++{ ++ LIST_HEAD(todo); ++ struct fw_cache_entry *fce; ++ struct fw_cache_entry *fce_next; ++ struct firmware_cache *fwc = &fw_cache; ++ ++ devres_for_each_res(dev, fw_name_devm_release, ++ devm_name_match, &fw_cache, ++ dev_create_fw_entry, &todo); ++ ++ list_for_each_entry_safe(fce, fce_next, &todo, list) { ++ list_del(&fce->list); ++ ++ spin_lock(&fwc->name_lock); ++ /* only one cache entry for one firmware */ ++ if (!__fw_entry_found(fce->name)) { ++ fwc->cnt++; ++ list_add(&fce->list, &fwc->fw_names); ++ } else { ++ free_fw_cache_entry(fce); ++ fce = NULL; ++ } ++ spin_unlock(&fwc->name_lock); ++ ++ if (fce) ++ async_schedule(__async_dev_cache_fw_image, ++ (void *)fce); ++ } ++} ++ ++static void __device_uncache_fw_images(void) ++{ ++ struct firmware_cache *fwc = &fw_cache; ++ struct fw_cache_entry *fce; ++ ++ spin_lock(&fwc->name_lock); ++ while (!list_empty(&fwc->fw_names)) { ++ fce = list_entry(fwc->fw_names.next, ++ struct fw_cache_entry, list); ++ list_del(&fce->list); ++ spin_unlock(&fwc->name_lock); ++ ++ uncache_firmware(fce->name); ++ free_fw_cache_entry(fce); ++ ++ spin_lock(&fwc->name_lock); ++ } ++ spin_unlock(&fwc->name_lock); ++} ++ ++/** ++ * device_cache_fw_images - cache devices' firmware ++ * ++ * If one device called request_firmware or its nowait version ++ * successfully before, the firmware names are recored into the ++ * device's devres link list, so device_cache_fw_images can call ++ * cache_firmware() to cache these firmwares for the device, ++ * then the device driver can load its firmwares easily at ++ * time when system is not ready to complete loading firmware. ++ */ ++static void device_cache_fw_images(void) ++{ ++ struct firmware_cache *fwc = &fw_cache; ++ int old_timeout; ++ DEFINE_WAIT(wait); ++ ++ pr_debug("%s\n", __func__); ++ ++ /* cancel uncache work */ ++ cancel_delayed_work_sync(&fwc->work); ++ ++ /* ++ * use small loading timeout for caching devices' firmware ++ * because all these firmware images have been loaded ++ * successfully at lease once, also system is ready for ++ * completing firmware loading now. The maximum size of ++ * firmware in current distributions is about 2M bytes, ++ * so 10 secs should be enough. ++ */ ++ old_timeout = loading_timeout; ++ loading_timeout = 10; ++ ++ mutex_lock(&fw_lock); ++ fwc->state = FW_LOADER_START_CACHE; ++ dpm_for_each_dev(NULL, dev_cache_fw_image); ++ mutex_unlock(&fw_lock); ++ ++ /* wait for completion of caching firmware for all devices */ ++ spin_lock(&fwc->name_lock); ++ for (;;) { ++ prepare_to_wait(&fwc->wait_queue, &wait, ++ TASK_UNINTERRUPTIBLE); ++ if (!fwc->cnt) ++ break; ++ ++ spin_unlock(&fwc->name_lock); ++ ++ schedule(); ++ ++ spin_lock(&fwc->name_lock); ++ } ++ spin_unlock(&fwc->name_lock); ++ finish_wait(&fwc->wait_queue, &wait); ++ ++ loading_timeout = old_timeout; ++} ++ ++/** ++ * device_uncache_fw_images - uncache devices' firmware ++ * ++ * uncache all firmwares which have been cached successfully ++ * by device_uncache_fw_images earlier ++ */ ++static void device_uncache_fw_images(void) ++{ ++ pr_debug("%s\n", __func__); ++ __device_uncache_fw_images(); ++} ++ ++static void device_uncache_fw_images_work(struct work_struct *work) ++{ ++ device_uncache_fw_images(); ++} ++ ++/** ++ * device_uncache_fw_images_delay - uncache devices firmwares ++ * @delay: number of milliseconds to delay uncache device firmwares ++ * ++ * uncache all devices's firmwares which has been cached successfully ++ * by device_cache_fw_images after @delay milliseconds. ++ */ ++static void device_uncache_fw_images_delay(unsigned long delay) ++{ ++ schedule_delayed_work(&fw_cache.work, ++ msecs_to_jiffies(delay)); ++} ++ ++static int fw_pm_notify(struct notifier_block *notify_block, ++ unsigned long mode, void *unused) ++{ ++ switch (mode) { ++ case PM_HIBERNATION_PREPARE: ++ case PM_SUSPEND_PREPARE: ++ device_cache_fw_images(); ++ break; ++ ++ case PM_POST_SUSPEND: ++ case PM_POST_HIBERNATION: ++ case PM_POST_RESTORE: ++ /* ++ * In case that system sleep failed and syscore_suspend is ++ * not called. ++ */ ++ mutex_lock(&fw_lock); ++ fw_cache.state = FW_LOADER_NO_CACHE; ++ mutex_unlock(&fw_lock); ++ ++ device_uncache_fw_images_delay(10 * MSEC_PER_SEC); ++ break; ++ } ++ ++ return 0; ++} ++ ++/* stop caching firmware once syscore_suspend is reached */ ++static int fw_suspend(void) ++{ ++ fw_cache.state = FW_LOADER_NO_CACHE; ++ return 0; ++} ++ ++static struct syscore_ops fw_syscore_ops = { ++ .suspend = fw_suspend, ++}; ++#else ++static int fw_cache_piggyback_on_request(const char *name) ++{ ++ return 0; ++} ++#endif ++ ++static void __init fw_cache_init(void) ++{ ++ spin_lock_init(&fw_cache.lock); ++ INIT_LIST_HEAD(&fw_cache.head); ++ fw_cache.state = FW_LOADER_NO_CACHE; ++ ++#ifdef CONFIG_PM_SLEEP ++ spin_lock_init(&fw_cache.name_lock); ++ INIT_LIST_HEAD(&fw_cache.fw_names); ++ fw_cache.cnt = 0; ++ ++ init_waitqueue_head(&fw_cache.wait_queue); ++ INIT_DELAYED_WORK(&fw_cache.work, ++ device_uncache_fw_images_work); ++ ++ fw_cache.pm_notify.notifier_call = fw_pm_notify; ++ register_pm_notifier(&fw_cache.pm_notify); ++ ++ register_syscore_ops(&fw_syscore_ops); ++#endif ++} ++ + static int __init firmware_class_init(void) + { ++ fw_cache_init(); ++#ifdef CONFIG_FW_LOADER_USER_HELPER + return class_register(&firmware_class); ++#else ++ return 0; ++#endif + } + + static void __exit firmware_class_exit(void) + { ++#ifdef CONFIG_PM_SLEEP ++ unregister_syscore_ops(&fw_syscore_ops); ++ unregister_pm_notifier(&fw_cache.pm_notify); ++#endif ++#ifdef CONFIG_FW_LOADER_USER_HELPER + class_unregister(&firmware_class); ++#endif + } + + fs_initcall(firmware_class_init); +@@ -728,3 +1562,5 @@ module_exit(firmware_class_exit); + EXPORT_SYMBOL(release_firmware); + EXPORT_SYMBOL(request_firmware); + EXPORT_SYMBOL(request_firmware_nowait); ++EXPORT_SYMBOL_GPL(cache_firmware); ++EXPORT_SYMBOL_GPL(uncache_firmware); +diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c +index 77e3b97..8bde48f 100644 +--- a/drivers/base/power/main.c ++++ b/drivers/base/power/main.c +@@ -1387,3 +1387,25 @@ int device_pm_wait_for_dev(struct device *subordinate, struct device *dev) + return async_error; + } + EXPORT_SYMBOL_GPL(device_pm_wait_for_dev); ++ ++/** ++ * dpm_for_each_dev - device iterator. ++ * @data: data for the callback. ++ * @fn: function to be called for each device. ++ * ++ * Iterate over devices in dpm_list, and call @fn for each device, ++ * passing it @data. ++ */ ++void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *)) ++{ ++ struct device *dev; ++ ++ if (!fn) ++ return; ++ ++ device_pm_lock(); ++ list_for_each_entry(dev, &dpm_list, power.entry) ++ fn(dev, data); ++ device_pm_unlock(); ++} ++EXPORT_SYMBOL_GPL(dpm_for_each_dev); +diff --git a/include/linux/device.h b/include/linux/device.h +index 5ad17cc..ad8904d 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -531,6 +531,10 @@ extern void *__devres_alloc(dr_release_t release, size_t size, gfp_t gfp, + #else + extern void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp); + #endif ++extern void devres_for_each_res(struct device *dev, dr_release_t release, ++ dr_match_t match, void *match_data, ++ void (*fn)(struct device *, void *, void *), ++ void *data); + extern void devres_free(void *res); + extern void devres_add(struct device *dev, void *res); + extern void *devres_find(struct device *dev, dr_release_t release, +diff --git a/include/linux/firmware.h b/include/linux/firmware.h +index 1e7c011..e4279fe 100644 +--- a/include/linux/firmware.h ++++ b/include/linux/firmware.h +@@ -12,6 +12,9 @@ struct firmware { + size_t size; + const u8 *data; + struct page **pages; ++ ++ /* firmware loader private fields */ ++ void *priv; + }; + + struct module; +@@ -44,6 +47,8 @@ int request_firmware_nowait( + void (*cont)(const struct firmware *fw, void *context)); + + void release_firmware(const struct firmware *fw); ++int cache_firmware(const char *name); ++int uncache_firmware(const char *name); + #else + static inline int request_firmware(const struct firmware **fw, + const char *name, +@@ -62,6 +67,16 @@ static inline int request_firmware_nowait( + static inline void release_firmware(const struct firmware *fw) + { + } ++ ++static inline int cache_firmware(const char *name) ++{ ++ return -ENOENT; ++} ++ ++static inline int uncache_firmware(const char *name) ++{ ++ return -EINVAL; ++} + #endif + + #endif +diff --git a/include/linux/pm.h b/include/linux/pm.h +index f067e60..88f034a 100644 +--- a/include/linux/pm.h ++++ b/include/linux/pm.h +@@ -638,6 +638,7 @@ extern void __suspend_report_result(const char *function, void *fn, int ret); + } while (0) + + extern int device_pm_wait_for_dev(struct device *sub, struct device *dev); ++extern void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *)); + + extern int pm_generic_prepare(struct device *dev); + extern int pm_generic_suspend_late(struct device *dev); +@@ -677,6 +678,10 @@ static inline int device_pm_wait_for_dev(struct device *a, struct device *b) + return 0; + } + ++static inline void dpm_for_each_dev(void *data, void (*fn)(struct device *, void *)) ++{ ++} ++ + #define pm_generic_prepare NULL + #define pm_generic_suspend NULL + #define pm_generic_resume NULL +-- +2.1.3 + diff --git a/projects/H3/patches/linux/linux-005-backport-lirc-sunxi-driver.patch b/projects/H3/patches/linux/linux-005-backport-lirc-sunxi-driver.patch new file mode 100644 index 00000000000..0597d72d922 --- /dev/null +++ b/projects/H3/patches/linux/linux-005-backport-lirc-sunxi-driver.patch @@ -0,0 +1,437 @@ +diff -Nur a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig +--- a/drivers/media/rc/Kconfig 2016-04-12 12:21:19.000000000 +0200 ++++ b/drivers/media/rc/Kconfig 2016-05-07 20:11:02.219989548 +0200 +@@ -274,5 +274,15 @@ + + To compile this driver as a module, choose M here: the module will + be called gpio-ir-recv. ++ ++config IR_SUNXI ++ tristate "SUNXI IR remote control" ++ depends on RC_CORE && !IR_RX_SUNXI ++ depends on ARCH_SUNXI ++ ---help--- ++ Say Y if you want to use sunXi internal IR Controller ++ ++ To compile this driver as a module, choose M here: the module will ++ be called sunxi-cir. + + endif #RC_CORE +diff -Nur a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile +--- a/drivers/media/rc/Makefile 2016-04-12 12:21:19.000000000 +0200 ++++ b/drivers/media/rc/Makefile 2016-05-07 20:11:02.219989548 +0200 +@@ -27,3 +27,4 @@ + obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o + obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o + obj-$(CONFIG_IR_GPIO_CIR) += gpio-ir-recv.o ++obj-$(CONFIG_IR_SUNXI) += sunxi-cir.o +diff -Nur a/drivers/media/rc/sunxi-cir.c b/drivers/media/rc/sunxi-cir.c +--- a/drivers/media/rc/sunxi-cir.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/media/rc/sunxi-cir.c 2016-05-09 18:45:50.207831727 +0200 +@@ -0,0 +1,406 @@ ++/* ++ * Driver for Allwinner sunXi IR controller ++ * ++ * Copyright (C) 2014 Alexsey Shestacov ++ * Copyright (C) 2014 Alexander Bersenev ++ * ++ * Based on sun5i-ir.c: ++ * Copyright (C) 2007-2012 Daniel Wang ++ * Allwinner Technology Co., Ltd. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of ++ * the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#define IR0_BASE (void __iomem *)(0xf1f02000) ++ ++#define SUNXI_IR_DEV "sunxi-ir" ++ ++#ifndef GENMASK ++#define GENMASK(h, l) \ ++ (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h)))) ++#endif ++ ++/* Registers */ ++/* IR Control */ ++#define SUNXI_IR_CTL_REG 0x00 ++/* Global Enable */ ++#define REG_CTL_GEN BIT(0) ++/* RX block enable */ ++#define REG_CTL_RXEN BIT(1) ++/* CIR mode */ ++#define REG_CTL_MD (BIT(4) | BIT(5)) ++ ++/* Rx Config */ ++#define SUNXI_IR_RXCTL_REG 0x10 ++/* Pulse Polarity Invert flag */ ++#define REG_RXCTL_RPPI BIT(2) ++ ++/* Rx Data */ ++#define SUNXI_IR_RXFIFO_REG 0x20 ++ ++/* Rx Interrupt Enable */ ++#define SUNXI_IR_RXINT_REG 0x2C ++/* Rx FIFO Overflow */ ++#define REG_RXINT_ROI_EN BIT(0) ++/* Rx Packet End */ ++#define REG_RXINT_RPEI_EN BIT(1) ++/* Rx FIFO Data Available */ ++#define REG_RXINT_RAI_EN BIT(4) ++ ++/* Rx FIFO available byte level */ ++#define REG_RXINT_RAL(val) ((val) << 8) ++ ++/* Rx Interrupt Status */ ++#define SUNXI_IR_RXSTA_REG 0x30 ++/* RX FIFO Get Available Counter */ ++#define REG_RXSTA_GET_AC(val) (((val) >> 8) & (ir->fifo_size * 2 - 1)) ++/* Clear all interrupt status value */ ++#define REG_RXSTA_CLEARALL 0xff ++ ++/* IR Sample Config */ ++#define SUNXI_IR_CIR_REG 0x34 ++/* CIR_REG register noise threshold */ ++#define REG_CIR_NTHR(val) (((val) << 2) & (GENMASK(7, 2))) ++/* CIR_REG register idle threshold */ ++#define REG_CIR_ITHR(val) (((val) << 8) & (GENMASK(15, 8))) ++ ++/* Required frequency for IR0 or IR1 clock in CIR mode */ ++#define SUNXI_IR_BASE_CLK 8000000 ++/* Frequency after IR internal divider */ ++#define SUNXI_IR_CLK (SUNXI_IR_BASE_CLK / 64) ++/* Sample period in ns */ ++#define SUNXI_IR_SAMPLE (1000000000ul / SUNXI_IR_CLK) ++/* Noise threshold in samples */ ++#define SUNXI_IR_RXNOISE 1 ++/* Idle Threshold in samples */ ++#define SUNXI_IR_RXIDLE 20 ++/* Time after which device stops sending data in ms */ ++#define SUNXI_IR_TIMEOUT 120 ++ ++ ++struct sunxi_ir { ++ spinlock_t ir_lock; ++ struct rc_dev *rc; ++ void __iomem *base; ++ int fifo_size; ++ struct clk *clk; ++ struct clk *apb_clk; ++ struct pinctrl *pinctrl; ++}; ++ ++static char ir_dev_name[] = "s_cir0"; ++ ++static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id) ++{ ++ unsigned long status; ++ unsigned char dt; ++ unsigned int cnt, rc; ++ struct sunxi_ir *ir = dev_id; ++ DEFINE_IR_RAW_EVENT(rawir); ++ ++ spin_lock(&ir->ir_lock); ++ ++ status = sunxi_smc_readl(ir->base + SUNXI_IR_RXSTA_REG); ++ ++ /* clean all pending statuses */ ++ sunxi_smc_writel(status | REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); ++ ++ if (status & (REG_RXINT_RAI_EN | REG_RXINT_RPEI_EN)) { ++ /* How many messages in fifo */ ++ rc = REG_RXSTA_GET_AC(status); ++ /* Sanity check */ ++ rc = rc > ir->fifo_size ? ir->fifo_size : rc; ++ /* If we have data */ ++ for (cnt = 0; cnt < rc; cnt++) { ++ /* for each bit in fifo */ ++ dt = (unsigned char)(sunxi_smc_readl(ir->base + SUNXI_IR_RXFIFO_REG)); ++ rawir.pulse = (dt & 0x80) != 0; ++ rawir.duration = ((dt & 0x7f) + 1) * SUNXI_IR_SAMPLE; ++ ir_raw_event_store_with_filter(ir->rc, &rawir); ++ } ++ } ++ ++ if (status & REG_RXINT_ROI_EN) { ++ ir_raw_event_reset(ir->rc); ++ } else if (status & REG_RXINT_RPEI_EN) { ++ ir_raw_event_set_idle(ir->rc, true); ++ ir_raw_event_handle(ir->rc); ++ } ++ ++ spin_unlock(&ir->ir_lock); ++ ++ return IRQ_HANDLED; ++} ++ ++static void sunxi_ir_regcfg(struct sunxi_ir *ir) ++{ ++ unsigned long tmp = 0; ++ ++ /* Enable CIR Mode */ ++ sunxi_smc_writel(REG_CTL_MD, ir->base+SUNXI_IR_CTL_REG); ++ ++ /* Set noise threshold and idle threshold */ ++ sunxi_smc_writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE)|REG_CIR_ITHR(SUNXI_IR_RXIDLE), ++ ir->base + SUNXI_IR_CIR_REG); ++ ++ /* Invert Input Signal */ ++ sunxi_smc_writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG); ++ ++ /* Clear All Rx Interrupt Status */ ++ sunxi_smc_writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); ++ ++ /* ++ * Enable IRQ on overflow, packet end, FIFO available with trigger ++ * level ++ */ ++ sunxi_smc_writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN | ++ REG_RXINT_RAI_EN | REG_RXINT_RAL(ir->fifo_size / 2 - 1), ++ ir->base + SUNXI_IR_RXINT_REG); ++ ++ /* Enable IR Module */ ++ tmp = sunxi_smc_readl(ir->base + SUNXI_IR_CTL_REG); ++ sunxi_smc_writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG); ++} ++ ++#ifdef CONFIG_PM ++static int sunxi_ir_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct sunxi_ir *ir = platform_get_drvdata(pdev); ++ ++ //TODO: Should be disable_irq_nosync()? ++ disable_irq(SUNXI_IRQ_R_CIR_RX); ++ ++ clk_disable_unprepare(ir->clk); ++ clk_disable_unprepare(ir->apb_clk); ++ ++ return 0; ++} ++ ++static int sunxi_ir_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct sunxi_ir *ir = platform_get_drvdata(pdev); ++ ++ clk_prepare_enable(ir->apb_clk); ++ clk_prepare_enable(ir->clk); ++ ++ sunxi_ir_regcfg(ir); ++ ++ enable_irq(SUNXI_IRQ_R_CIR_RX); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops sunxi_ir_pm_ops = { ++ .suspend = sunxi_ir_suspend, ++ .resume = sunxi_ir_resume, ++}; ++#endif ++ ++static int sunxi_ir_probe(struct platform_device *pdev) ++{ ++ int ret; ++ ++ struct device *dev = &pdev->dev; ++ struct sunxi_ir *ir; ++ ++ ir = devm_kzalloc(dev, sizeof(struct sunxi_ir), GFP_KERNEL); ++ if (!ir) ++ return -ENOMEM; ++ ++ spin_lock_init(&ir->ir_lock); ++ ++ ir->fifo_size = 64; ++ ++ /* Clock */ ++ ir->apb_clk = clk_get(NULL, HOSC_CLK); ++ if (IS_ERR(ir->apb_clk)) { ++ dev_err(dev, "failed to get a apb clock.\n"); ++ return PTR_ERR(ir->apb_clk); ++ } ++ ir->clk = clk_get(NULL, "cpurcir"); ++ if (IS_ERR(ir->clk)) { ++ dev_err(dev, "failed to get a ir clock.\n"); ++ return PTR_ERR(ir->clk); ++ } ++ ++ if(clk_set_parent(ir->clk, ir->apb_clk)) ++ dev_err(dev, "set ir_clk parent to ir_clk_source failed!\n"); ++ ++ ret = clk_set_rate(ir->clk, SUNXI_IR_BASE_CLK); ++ if (ret) { ++ dev_err(dev, "set ir base clock failed!\n"); ++ goto exit_reset_assert; ++ } ++ ++ if (clk_prepare_enable(ir->apb_clk)) { ++ dev_err(dev, "try to enable apb_ir_clk failed\n"); ++ ret = -EINVAL; ++ goto exit_reset_assert; ++ } ++ ++ if (clk_prepare_enable(ir->clk)) { ++ dev_err(dev, "try to enable ir_clk failed\n"); ++ ret = -EINVAL; ++ goto exit_clkdisable_apb_clk; ++ } ++ ++ /* IO */ ++ ir->base = IR0_BASE; ++ if (IS_ERR(ir->base)) { ++ dev_err(dev, "failed to map registers\n"); ++ ret = PTR_ERR(ir->base); ++ goto exit_clkdisable_clk; ++ } ++ ++ ir->rc = rc_allocate_device(); ++ if (!ir->rc) { ++ dev_err(dev, "failed to allocate device\n"); ++ ret = -ENOMEM; ++ goto exit_clkdisable_clk; ++ } ++ ++ ir->rc->priv = ir; ++ ir->rc->input_name = SUNXI_IR_DEV; ++ ir->rc->input_phys = "sunxi-ir/input1"; ++ ir->rc->input_id.bustype = BUS_HOST; ++ ir->rc->input_id.vendor = 0x0001; ++ ir->rc->input_id.product = 0x0001; ++ ir->rc->input_id.version = 0x0100; ++ ir->rc->map_name = RC_MAP_EMPTY; ++ ir->rc->dev.parent = dev; ++ ir->rc->driver_type = RC_DRIVER_IR_RAW; ++ ir->rc->allowed_protos = RC_TYPE_ALL; ++ ir->rc->rx_resolution = SUNXI_IR_SAMPLE; ++ ir->rc->timeout = MS_TO_NS(SUNXI_IR_TIMEOUT); ++ ir->rc->driver_name = SUNXI_IR_DEV; ++ ++ ret = rc_register_device(ir->rc); ++ if (ret) { ++ dev_err(dev, "failed to register rc device\n"); ++ goto exit_free_dev; ++ } ++ ++ platform_set_drvdata(pdev, ir); ++ ++ /* pin config */ ++ dev->init_name = &ir_dev_name[0]; ++ ir->pinctrl = devm_pinctrl_get_select_default(dev); ++ if (IS_ERR_OR_NULL(ir->pinctrl)) { ++ dev_err(dev, "%s: config ir rx pin err.\n", __func__); ++ goto exit_free_dev; ++ } ++ ++ ret = devm_request_irq(dev, SUNXI_IRQ_R_CIR_RX, sunxi_ir_irq, 0, SUNXI_IR_DEV, ir); ++ if (ret) { ++ dev_err(dev, "failed request irq\n"); ++ goto exit_free_pinctrl; ++ } ++ ++ sunxi_ir_regcfg(ir); ++ ++ dev_info(dev, "initialized sunXi IR driver\n"); ++ return 0; ++ ++exit_free_pinctrl: ++ devm_pinctrl_put(ir->pinctrl); ++exit_free_dev: ++ rc_free_device(ir->rc); ++exit_clkdisable_clk: ++ clk_disable_unprepare(ir->clk); ++exit_clkdisable_apb_clk: ++ clk_disable_unprepare(ir->apb_clk); ++exit_reset_assert: ++ ++ return ret; ++} ++ ++static int sunxi_ir_remove(struct platform_device *pdev) ++{ ++ unsigned long flags; ++ struct sunxi_ir *ir = platform_get_drvdata(pdev); ++ ++ clk_disable_unprepare(ir->clk); ++ clk_disable_unprepare(ir->apb_clk); ++ ++ spin_lock_irqsave(&ir->ir_lock, flags); ++ /* disable IR IRQ */ ++ sunxi_smc_writel(0, ir->base + SUNXI_IR_RXINT_REG); ++ /* clear All Rx Interrupt Status */ ++ sunxi_smc_writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); ++ /* disable IR */ ++ sunxi_smc_writel(0, ir->base + SUNXI_IR_CTL_REG); ++ spin_unlock_irqrestore(&ir->ir_lock, flags); ++ ++ free_irq(SUNXI_IRQ_R_CIR_RX, ir); ++ ++ devm_pinctrl_put(ir->pinctrl); ++ ++ rc_unregister_device(ir->rc); ++ return 0; ++} ++ ++static struct platform_driver sunxi_ir_driver = { ++ .probe = sunxi_ir_probe, ++ .remove = sunxi_ir_remove, ++ .driver = { ++ .name = SUNXI_IR_DEV, ++ .owner = THIS_MODULE, ++#ifdef CONFIG_PM ++ .pm = &sunxi_ir_pm_ops, ++#endif ++ }, ++}; ++ ++static struct platform_device sunxi_ir_device = { ++ .name = SUNXI_IR_DEV ++}; ++ ++static int __init sunxi_ir_init(void) ++{ ++ int ret; ++ ++ ret = platform_device_register(&sunxi_ir_device); ++ if (ret) ++ return ret; ++ ++ ret = platform_driver_register(&sunxi_ir_driver); ++ if (ret) { ++ platform_device_unregister(&sunxi_ir_device); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void __exit sunxi_ir_exit(void) ++{ ++ platform_device_unregister(&sunxi_ir_device); ++ platform_driver_unregister(&sunxi_ir_driver); ++} ++ ++module_init(sunxi_ir_init); ++module_exit(sunxi_ir_exit); ++ ++MODULE_DESCRIPTION("Allwinner sunXi IR controller driver"); ++MODULE_AUTHOR("Alexsey Shestacov "); ++MODULE_LICENSE("GPL"); diff --git a/projects/H3/patches/linux/linux-006-fix-build-with-gcc-5.patch b/projects/H3/patches/linux/linux-006-fix-build-with-gcc-5.patch new file mode 100644 index 00000000000..9441994f64a --- /dev/null +++ b/projects/H3/patches/linux/linux-006-fix-build-with-gcc-5.patch @@ -0,0 +1,16 @@ +# see https://github.com/wongsyrone/openwrt-1/commit/93c0a5173414cfa7684547de3c3a1f3dc4240383 +# and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65932 + +diff -Naur linux-cuboxi-3.14-ea83bda.orig/arch/arm/Makefile linux-cuboxi-3.14-ea83bda/arch/arm/Makefile +--- linux-cuboxi-3.14-ea83bda.orig/arch/arm/Makefile 2015-05-06 10:05:43.000000000 -0700 ++++ linux-cuboxi-3.14-ea83bda/arch/arm/Makefile 2015-10-05 13:51:43.641612713 -0700 +@@ -120,7 +120,8 @@ + endif + + # Need -Uarm for gcc < 3.x +-KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm ++# Maybe we need -fno-ipa-sra for gcc > 4.9.x ++KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm -fno-ipa-sra + KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float + + CHECKFLAGS += -D__arm__ diff --git a/projects/H3/patches/linux/linux-007-some-build-fixes.patch b/projects/H3/patches/linux/linux-007-some-build-fixes.patch new file mode 100644 index 00000000000..5ede3f909ba --- /dev/null +++ b/projects/H3/patches/linux/linux-007-some-build-fixes.patch @@ -0,0 +1,472 @@ +Patch for generation of OrangePI 2 kernel with gcc-5.2.1 + +--- linux-3.4/arch/arm/kernel/arch_timer.c.orig 2015-01-27 03:29:26.000000000 +0100 ++++ linux-3.4/arch/arm/kernel/arch_timer.c 2015-06-26 18:54:05.176567992 +0200 +@@ -139,7 +139,7 @@ + #define smp_timer_broadcast NULL + #endif + +-static int __cpuinit arch_timer_setup(struct clock_event_device *clk) ++static int arch_timer_setup(struct clock_event_device *clk) + { + /* Be safe... */ + arch_timer_disable(); +@@ -255,7 +255,7 @@ + .flags = CLOCK_SOURCE_IS_CONTINUOUS, + }; + +-static void __cpuinit arch_timer_stop(struct clock_event_device *clk) ++static void arch_timer_stop(struct clock_event_device *clk) + { + pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", + clk->irq, smp_processor_id()); +--- linux-3.4/arch/arm/kernel/perf_event.c.orig 2015-01-27 03:29:26.000000000 +0100 ++++ linux-3.4/arch/arm/kernel/perf_event.c 2015-06-26 19:35:39.447062200 +0200 +@@ -702,8 +702,8 @@ + + return ret; + } +-static void __init cpu_pmu_init(struct arm_pmu *armpmu); +-static int __devinit armpmu_device_probe(struct platform_device *pdev) ++static void cpu_pmu_init(struct arm_pmu *armpmu); ++static int armpmu_device_probe(struct platform_device *pdev) + { + struct arm_pmu *pmu; + int cpu; +@@ -750,7 +750,7 @@ + * UNKNOWN at reset, the PMU must be explicitly reset to avoid reading + * junk values out of them. + */ +-static int __cpuinit pmu_cpu_notify(struct notifier_block *b, ++static int pmu_cpu_notify(struct notifier_block *b, + unsigned long action, void *hcpu) + { + struct arm_pmu *pmu = per_cpu(cpu_pmu, (long)hcpu); +@@ -816,7 +816,7 @@ + return &__get_cpu_var(cpu_hw_events); + } + +-static void __init cpu_pmu_init(struct arm_pmu *armpmu) ++static void cpu_pmu_init(struct arm_pmu *armpmu) + { + int cpu; + for_each_cpu_mask(cpu, armpmu->valid_cpus) { +--- linux-3.4/arch/arm/kernel/perf_event_v7.c.orig 2015-01-27 03:29:26.000000000 +0100 ++++ linux-3.4/arch/arm/kernel/perf_event_v7.c 2015-06-26 19:54:46.937289560 +0200 +@@ -1274,7 +1274,7 @@ + cpu_pmu->max_period = (1LLU << 32) - 1; + }; + +-static u32 __init armv7_read_num_pmnc_events(void) ++static u32 armv7_read_num_pmnc_events(void) + { + u32 nb_cnt; + +@@ -1285,7 +1285,7 @@ + return nb_cnt + 1; + } + +-static int __devinit armv7_a8_pmu_init(struct arm_pmu *cpu_pmu) ++static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu) + { + armv7pmu_init(cpu_pmu); + cpu_pmu->id = ARM_PERF_PMU_ID_CA8; +@@ -1295,7 +1295,7 @@ + return 0; + } + +-static int __devinit armv7_a9_pmu_init(struct arm_pmu *cpu_pmu) ++static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu) + { + armv7pmu_init(cpu_pmu); + cpu_pmu->id = ARM_PERF_PMU_ID_CA9; +@@ -1305,7 +1305,7 @@ + return 0; + } + +-static int __devinit armv7_a5_pmu_init(struct arm_pmu *cpu_pmu) ++static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu) + { + armv7pmu_init(cpu_pmu); + cpu_pmu->id = ARM_PERF_PMU_ID_CA5; +@@ -1315,7 +1315,7 @@ + return 0; + } + +-static int __devinit armv7_a15_pmu_init(struct arm_pmu *cpu_pmu) ++static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu) + { + armv7pmu_init(cpu_pmu); + cpu_pmu->id = ARM_PERF_PMU_ID_CA15; +@@ -1326,7 +1326,7 @@ + return 0; + } + +-static int __devinit armv7_a7_pmu_init(struct arm_pmu *cpu_pmu) ++static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu) + { + armv7pmu_init(cpu_pmu); + cpu_pmu->id = ARM_PERF_PMU_ID_CA7; +--- linux-3.4/arch/arm/mach-sunxi/include/mach/sunxi-chip.h.orig 2015-01-27 03:29:26.000000000 +0100 ++++ linux-3.4/arch/arm/mach-sunxi/include/mach/sunxi-chip.h 2015-06-27 09:09:18.220622500 +0200 +@@ -64,6 +64,6 @@ + + /* sunxi platform init functions */ + void __init sunxi_soc_ver_init(void); +-void __init sunxi_chip_id_init(void); ++void sunxi_chip_id_init(void); + + #endif /* __SUNXI_MACH_SUNXI_CHIP_H */ +--- linux-3.4/arch/arm/mach-sunxi/sunxi-chip.c.orig 2015-01-27 03:29:26.000000000 +0100 ++++ linux-3.4/arch/arm/mach-sunxi/sunxi-chip.c 2015-06-27 09:02:11.710537992 +0200 +@@ -251,7 +251,7 @@ + pr_debug("Init chip version:%x\n", sunxi_soc_ver); + } + +-void __init sunxi_chip_id_init(void) ++void sunxi_chip_id_init(void) + { + /* PMU chip id init */ + #if (defined CONFIG_SUNXI_ARISC) && (defined CONFIG_AW_AXP) +--- linux-3.4/arch/arm/mach-sunxi/sunxi-platsmp.c.orig 2015-01-27 03:29:26.000000000 +0100 ++++ linux-3.4/arch/arm/mach-sunxi/sunxi-platsmp.c 2015-07-07 19:21:41.532586216 +0200 +@@ -65,7 +65,7 @@ + } + #endif + +-void sunxi_set_cpus_boot_entry(int cpu, void *entry) ++void __cpuinit sunxi_set_cpus_boot_entry(int cpu, void *entry) + { + if(cpu < NR_CPUS) { + cpus_boot_entry[cpu] = (void *)(virt_to_phys(entry)); +@@ -78,7 +78,7 @@ + /* + * Setup the set of possible CPUs (via set_cpu_possible) + */ +-void sunxi_smp_init_cpus(void) ++void __init sunxi_smp_init_cpus(void) + { + unsigned int i, ncores; + +@@ -124,7 +124,7 @@ + #endif + } + +-static void sunxi_smp_prepare_cpus(unsigned int max_cpus) ++static __cpuinit void sunxi_smp_prepare_cpus(unsigned int max_cpus) + { + pr_info("[%s] enter\n", __func__); + sunxi_set_secondary_entry((void *)(virt_to_phys(sunxi_secondary_startup))); +@@ -133,7 +133,7 @@ + /* + * Perform platform specific initialisation of the specified CPU. + */ +-void sunxi_smp_secondary_init(unsigned int cpu) ++void __cpuinit sunxi_smp_secondary_init(unsigned int cpu) + { + /* + * if any interrupts are already enabled for the primary +@@ -153,7 +153,7 @@ + * Boot a secondary CPU, and assign it the specified idle task. + * This also gives us the initial stack to use for this CPU. + */ +-int sunxi_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) ++int __cpuinit sunxi_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) + { + pr_debug("[%s] enter\n", __func__); + spin_lock(&boot_lock); +--- linux-3.4/drivers/arisc/arisc.c.orig 2015-01-27 03:29:27.000000000 +0100 ++++ linux-3.4/drivers/arisc/arisc.c 2015-07-27 09:40:51.705349089 +0200 +@@ -21,6 +21,7 @@ + */ + + #include "arisc_i.h" ++#include + #include + #include + #include +--- linux-3.4/drivers/bluetooth/rtl_bluesleep.c.orig 2015-01-27 03:29:27.000000000 +0100 ++++ linux-3.4/drivers/bluetooth/rtl_bluesleep.c 2015-06-27 15:30:08.375149968 +0200 +@@ -33,6 +33,7 @@ + #include /* kernel module definitions */ + #include + #include ++#include + #include + #include + +--- linux-3.4/drivers/crypto/sunxi/sunxi_ss.c.orig 2015-01-27 03:29:27.000000000 +0100 ++++ linux-3.4/drivers/crypto/sunxi/sunxi_ss.c 2015-06-28 09:10:37.172824872 +0200 +@@ -720,7 +720,7 @@ + }; + + /* Requeset the resource: IRQ, mem */ +-static int __devinit sunxi_ss_res_request(struct platform_device *pdev) ++static int sunxi_ss_res_request(struct platform_device *pdev) + { + int irq = 0; + int ret = 0; +@@ -784,7 +784,7 @@ + } + + /* Release the resource: IRQ, mem */ +-static int __devexit sunxi_ss_res_release(sunxi_ss_t *sss) ++static int sunxi_ss_res_release(sunxi_ss_t *sss) + { + #ifdef SS_IDMA_ENABLE + int i; +@@ -977,7 +977,7 @@ + device_remove_file(&_pdev->dev, &sunxi_ss_status_attr); + } + +-static int __devinit sunxi_ss_probe(struct platform_device *pdev) ++static int sunxi_ss_probe(struct platform_device *pdev) + { + int ret = 0; + sunxi_ss_t *sss = NULL; +@@ -1038,7 +1038,7 @@ + return ret; + } + +-static int __devexit sunxi_ss_remove(struct platform_device *pdev) ++static int sunxi_ss_remove(struct platform_device *pdev) + { + sunxi_ss_t *sss = platform_get_drvdata(pdev); + +--- linux-3.4/drivers/crypto/sunxi/v3/sunxi_ss_proc.c.orig 2015-01-27 03:29:27.000000000 +0100 ++++ linux-3.4/drivers/crypto/sunxi/v3/sunxi_ss_proc.c 2015-06-27 15:34:03.295196514 +0200 +@@ -12,7 +12,7 @@ + + #include + #include +-#include ++#include + #include + #include + #include +--- linux-3.4/drivers/hwmon/hwmon.c.orig 2015-01-27 03:29:27.000000000 +0100 ++++ linux-3.4/drivers/hwmon/hwmon.c 2015-07-07 11:39:39.081561215 +0200 +@@ -104,7 +104,7 @@ + } + EXPORT_SYMBOL_GPL(hwmon_device_unregister); + +-static void __init hwmon_pci_quirks(void) ++static void hwmon_pci_quirks(void) + { + #if defined CONFIG_X86 && defined CONFIG_PCI + struct pci_dev *sb; +--- linux-3.4/drivers/media/video/sunxi-tsc/tscdrv.c.orig 2015-01-27 03:29:28.000000000 +0100 ++++ linux-3.4/drivers/media/video/sunxi-tsc/tscdrv.c 2015-06-29 10:36:50.085484413 +0200 +@@ -595,7 +595,7 @@ + return ret; + } + +-static void __exit tscdev_exit(void) ++static void tscdev_exit(void) + { + dev_t dev; + +@@ -642,13 +642,13 @@ + + #endif + +-static int __devexit sunxi_tsc_remove(struct platform_device *pdev) ++static int sunxi_tsc_remove(struct platform_device *pdev) + { + tscdev_exit(); + return 0; + } + +-static int __devinit sunxi_tsc_probe(struct platform_device *pdev) ++static int sunxi_tsc_probe(struct platform_device *pdev) + { + tscdev_init(); + return 0; +--- linux-3.4/drivers/rtc/rtc-sunxi.c.orig 2015-01-27 03:29:28.000000000 +0100 ++++ linux-3.4/drivers/rtc/rtc-sunxi.c 2015-06-26 19:41:20.777129830 +0200 +@@ -474,7 +474,7 @@ + return 0; + } + +-static int __init sunxi_rtc_probe(struct platform_device *pdev) ++static int sunxi_rtc_probe(struct platform_device *pdev) + { + struct rtc_device *rtc; + int ret; +--- linux-3.4/drivers/video/sunxi/disp2/hdmi/dev_hdmi.c.orig 2015-01-27 03:29:32.000000000 +0100 ++++ linux-3.4/drivers/video/sunxi/disp2/hdmi/dev_hdmi.c 2015-06-26 19:06:59.276721370 +0200 +@@ -148,7 +148,7 @@ + + static DEVICE_ATTR(edid, S_IRUGO|S_IWUSR|S_IWGRP,hdmi_edid_show, hdmi_edid_store); + +-static int __init hdmi_probe(struct platform_device *pdev) ++static int hdmi_probe(struct platform_device *pdev) + { + __inf("hdmi_probe call\n"); + memset(&ghdmi, 0, sizeof(hdmi_info_t)); +--- linux-3.4/drivers/video/sunxi/disp2/tv/dev_tv.c.orig 2015-01-27 03:29:32.000000000 +0100 ++++ linux-3.4/drivers/video/sunxi/disp2/tv/dev_tv.c 2015-06-28 08:47:02.362544545 +0200 +@@ -30,7 +30,7 @@ + + + +-static int __init tv_probe(struct platform_device *pdev) ++static int tv_probe(struct platform_device *pdev) + { + int ret; + memset(&g_tv_info, 0, sizeof(struct tv_info_t)); +--- linux-3.4/sound/soc/sunxi/audiocodec/sun8iw7_sndcodec.c.orig 2015-01-27 03:29:38.000000000 +0100 ++++ linux-3.4/sound/soc/sunxi/audiocodec/sun8iw7_sndcodec.c 2015-06-28 08:48:43.242564533 +0200 +@@ -1702,7 +1702,7 @@ + .attrs = audio_debug_attrs, + }; + +-static int __init sndpcm_codec_probe(struct platform_device *pdev) ++static int sndpcm_codec_probe(struct platform_device *pdev) + { + int err = -1; + int req_status; +@@ -1776,7 +1776,7 @@ + return 0; + } + +-static int __exit sndpcm_codec_remove(struct platform_device *pdev) ++static int sndpcm_codec_remove(struct platform_device *pdev) + { + if ((NULL == codec_moduleclk)||(IS_ERR(codec_moduleclk))) { + pr_err("codec_moduleclk handle is invaled, just return\n"); +--- linux-3.4/sound/soc/sunxi/audiocodec/sunxi_codecdma.c.orig 2015-01-27 03:29:38.000000000 +0100 ++++ linux-3.4/sound/soc/sunxi/audiocodec/sunxi_codecdma.c 2015-06-28 08:50:52.902590224 +0200 +@@ -314,12 +314,12 @@ + .pcm_free = sunxi_pcm_free_dma_buffers, + }; + +-static int __init sunxi_codec_pcm_probe(struct platform_device *pdev) ++static int sunxi_codec_pcm_probe(struct platform_device *pdev) + { + return snd_soc_register_platform(&pdev->dev, &sunxi_soc_platform); + } + +-static int __exit sunxi_codec_pcm_remove(struct platform_device *pdev) ++static int sunxi_codec_pcm_remove(struct platform_device *pdev) + { + snd_soc_unregister_platform(&pdev->dev); + return 0; +--- linux-3.4/sound/soc/sunxi/audiocodec/sunxi_codec.c.orig 2015-01-27 03:29:38.000000000 +0100 ++++ linux-3.4/sound/soc/sunxi/audiocodec/sunxi_codec.c 2015-06-28 09:11:30.582835454 +0200 +@@ -491,7 +491,7 @@ + #endif + }; + +-static int __init sunxi_pcm_dev_probe(struct platform_device *pdev) ++static int sunxi_pcm_dev_probe(struct platform_device *pdev) + { + int err = -1; + +@@ -509,7 +509,7 @@ + return 0; + } + +-static int __exit sunxi_pcm_dev_remove(struct platform_device *pdev) ++static int sunxi_pcm_dev_remove(struct platform_device *pdev) + { + snd_soc_unregister_dai(&pdev->dev); + platform_set_drvdata(pdev, NULL); +--- linux-3.4/sound/soc/sunxi/audiocodec/sunxi_sndcodec.c.orig 2015-01-27 03:29:38.000000000 +0100 ++++ linux-3.4/sound/soc/sunxi/audiocodec/sunxi_sndcodec.c 2015-06-28 08:49:33.382574468 +0200 +@@ -94,7 +94,7 @@ + .num_links = 1, + }; + +-static int __devinit sunxi_sndpcm_dev_probe(struct platform_device *pdev) ++static int sunxi_sndpcm_dev_probe(struct platform_device *pdev) + { + int ret = 0; + struct snd_soc_card *card = &snd_soc_sunxi_sndpcm; +@@ -108,7 +108,7 @@ + return ret; + } + +-static int __exit sunxi_sndpcm_dev_remove(struct platform_device *pdev) ++static int sunxi_sndpcm_dev_remove(struct platform_device *pdev) + { + struct snd_soc_card *card = platform_get_drvdata(pdev); + +--- linux-3.4/sound/soc/sunxi/audiohub/sun8iw7-hubaudio.c.orig 2015-01-27 03:29:38.000000000 +0100 ++++ linux-3.4/sound/soc/sunxi/audiohub/sun8iw7-hubaudio.c 2015-07-07 20:09:51.702920942 +0200 +@@ -359,7 +359,7 @@ + } + }; + +-static int __init sunxi_audiohub_dev_probe(struct platform_device *pdev) ++static int sunxi_audiohub_dev_probe(struct platform_device *pdev) + { + int ret = 0; + +--- linux-3.4/sound/soc/sunxi/hdmiaudio/sndhdmi.c.orig 2015-01-27 03:29:38.000000000 +0100 ++++ linux-3.4/sound/soc/sunxi/hdmiaudio/sndhdmi.c 2015-06-28 08:52:22.452607967 +0200 +@@ -332,7 +332,7 @@ + .resume = sunxi_sndhdmi_resume, + }; + +-static int __init sndhdmi_codec_probe(struct platform_device *pdev) ++static int sndhdmi_codec_probe(struct platform_device *pdev) + { + if (!pdev) { + pr_err("error:%s,line:%d\n", __func__, __LINE__); +@@ -344,7 +344,7 @@ + return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_sndhdmi, &sndhdmi_dai, 1); + } + +-static int __exit sndhdmi_codec_remove(struct platform_device *pdev) ++static int sndhdmi_codec_remove(struct platform_device *pdev) + { + if (!pdev) { + pr_err("error:%s,line:%d\n", __func__, __LINE__); +--- linux-3.4/sound/soc/sunxi/hdmiaudio/sunxi-hdmipcm.c.orig 2015-01-27 03:29:38.000000000 +0100 ++++ linux-3.4/sound/soc/sunxi/hdmiaudio/sunxi-hdmipcm.c 2015-06-28 08:54:08.212628922 +0200 +@@ -473,12 +473,12 @@ + .pcm_free = sunxi_pcm_free_dma_buffers, + }; + +-static int __init sunxi_hdmiaudio_pcm_probe(struct platform_device *pdev) ++static int sunxi_hdmiaudio_pcm_probe(struct platform_device *pdev) + { + return snd_soc_register_platform(&pdev->dev, &sunxi_soc_platform_hdmiaudio); + } + +-static int __exit sunxi_hdmiaudio_pcm_remove(struct platform_device *pdev) ++static int sunxi_hdmiaudio_pcm_remove(struct platform_device *pdev) + { + snd_soc_unregister_platform(&pdev->dev); + return 0; +--- linux-3.4/sound/soc/sunxi/hdmiaudio/sunxi-hdmitdm.c.orig 2015-01-27 03:29:38.000000000 +0100 ++++ linux-3.4/sound/soc/sunxi/hdmiaudio/sunxi-hdmitdm.c 2015-06-28 08:55:39.702647050 +0200 +@@ -711,7 +711,7 @@ + }; + + static struct pinctrl *daudio_pinctrl; +-static int __init sunxi_daudio_dev_probe(struct platform_device *pdev) ++static int sunxi_daudio_dev_probe(struct platform_device *pdev) + { + int ret = 0; + int reg_val = 0; +@@ -758,7 +758,7 @@ + return 0; + } + +-static int __exit sunxi_daudio_dev_remove(struct platform_device *pdev) ++static int sunxi_daudio_dev_remove(struct platform_device *pdev) + { + if (daudio_used) { + daudio_used = 0; +--- linux-3.4/sound/soc/sunxi/hdmiaudio/sunxi-sndhdmi.c.orig 2015-01-27 03:29:38.000000000 +0100 ++++ linux-3.4/sound/soc/sunxi/hdmiaudio/sunxi-sndhdmi.c 2015-06-27 16:18:09.035720734 +0200 +@@ -29,6 +29,7 @@ + #include "sunxi-hdmitdm.h" + #endif + int hdmi_format = 1; ++EXPORT_SYMBOL_GPL(hdmi_format); + #if defined (CONFIG_ARCH_SUN9I) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW6) + /*i2s1 as master, hdmi as slave*/ + static int i2s1_master = 4; diff --git a/projects/H3/patches/linux/linux-008-add-hw-hdmi-cec-support.patch b/projects/H3/patches/linux/linux-008-add-hw-hdmi-cec-support.patch new file mode 100644 index 00000000000..ed4498c7d27 --- /dev/null +++ b/projects/H3/patches/linux/linux-008-add-hw-hdmi-cec-support.patch @@ -0,0 +1,2223 @@ +From 9e2980af4c508f6a30b4d50b8cba9f10c254151f Mon Sep 17 00:00:00 2001 +From: Joachim Damm +Date: Mon, 13 Jun 2016 20:14:41 +0200 +Subject: [PATCH] add driver for H3 hdmi cec + +fix reconnect error H3 cec driver + +H3 cec driver wait for free cec line and fix wrong array size + +H3 cec driver fix for crash after resume +--- + drivers/video/sunxi/disp2/hdmi/Makefile | 2 +- + drivers/video/sunxi/disp2/hdmi/aw/dw_hdmi.h | 1089 ++++++++++++++++++++ + .../video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c | 6 +- + drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c | 840 +++++++++++++++ + drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.h | 39 + + drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c | 7 +- + drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.c | 5 + + drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.h | 44 +- + drivers/video/sunxi/disp2/hdmi/drv_hdmi.c | 19 + + drivers/video/sunxi/disp2/hdmi/drv_hdmi_i.h | 3 + + 10 files changed, 2029 insertions(+), 25 deletions(-) + create mode 100755 drivers/video/sunxi/disp2/hdmi/aw/dw_hdmi.h + create mode 100644 drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c + create mode 100644 drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.h + +diff --git a/drivers/video/sunxi/disp2/hdmi/Makefile b/drivers/video/sunxi/disp2/hdmi/Makefile +index 5759042..f281b65 100755 +--- a/drivers/video/sunxi/disp2/hdmi/Makefile ++++ b/drivers/video/sunxi/disp2/hdmi/Makefile +@@ -1,6 +1,6 @@ + obj-$(CONFIG_HDMI_DISP2_SUNXI) += hdmi.o ++obj-m += aw/hdmi_cec.o + + hdmi-y := dev_hdmi.o drv_hdmi.o aw/hdmi_core.o aw/hdmi_hal.o aw/hdmi_edid.o aw/hdmi_interface.o + hdmi-$(CONFIG_ARCH_SUN8IW6) += aw/hdmi_bsp_sun8iw6.o + hdmi-$(CONFIG_ARCH_SUN8IW7) += aw/hdmi_bsp_sun8iw7.o +- +diff --git a/drivers/video/sunxi/disp2/hdmi/aw/dw_hdmi.h b/drivers/video/sunxi/disp2/hdmi/aw/dw_hdmi.h +new file mode 100755 +index 0000000..5e99e71 +--- /dev/null ++++ b/drivers/video/sunxi/disp2/hdmi/aw/dw_hdmi.h +@@ -0,0 +1,1089 @@ ++/* ++ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. ++ */ ++ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#ifndef __DW_HDMI_H__ ++#define __DW_HDMI_H__ ++ ++/* ++ * Hdmi controller registers for Allwinner H3 ++ */ ++ ++/* Identification Registers */ ++#define HDMI_DESIGN_ID 0x0000 ++#define HDMI_REVISION_ID 0x0001 ++#define HDMI_PRODUCT_ID0 0x8000 ++#define HDMI_PRODUCT_ID1 0x8001 ++#define HDMI_CONFIG0_ID 0x0002 ++#define HDMI_CONFIG1_ID 0x0003 ++#define HDMI_CONFIG2_ID 0x8002 ++#define HDMI_CONFIG3_ID 0x8003 ++ ++/* Interrupt Registers */ ++#define HDMI_IH_FC_STAT0 0x0010 ++#define HDMI_IH_FC_STAT1 0x0011 ++#define HDMI_IH_FC_STAT2 0x8010 ++#define HDMI_IH_AS_STAT0 0x8011 ++#define HDMI_IH_PHY_STAT0 0x0012 ++#define HDMI_IH_I2CM_STAT0 0x0013 ++#define HDMI_IH_CEC_STAT0 0x8012 ++#define HDMI_IH_VP_STAT0 0x8013 ++#define HDMI_IH_I2CMPHY_STAT0 0x4010 ++#define HDMI_IH_AHBDMAAUD_STAT0 0x4011 ++ ++#define HDMI_IH_MUTE_FC_STAT0 0x1010 ++#define HDMI_IH_MUTE_FC_STAT1 0x1011 ++#define HDMI_IH_MUTE_FC_STAT2 0x9010 ++#define HDMI_IH_MUTE_AS_STAT0 0x9011 ++#define HDMI_IH_MUTE_PHY_STAT0 0x1012 ++#define HDMI_IH_MUTE_I2CM_STAT0 0x1013 ++#define HDMI_IH_MUTE_CEC_STAT0 0x9012 ++#define HDMI_IH_MUTE_VP_STAT0 0x9013 ++#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x5010 ++#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x5011 ++#define HDMI_IH_MUTE 0xf01f ++ ++/* Video Sample Registers */ ++#define HDMI_TX_INVID0 0x0800 ++#define HDMI_TX_INSTUFFING 0x0801 ++#define HDMI_TX_GYDATA0 0x8800 ++#define HDMI_TX_GYDATA1 0x8801 ++#define HDMI_TX_RCRDATA0 0x0802 ++#define HDMI_TX_RCRDATA1 0x0803 ++#define HDMI_TX_BCBDATA0 0x8802 ++#define HDMI_TX_BCBDATA1 0x8803 ++ ++/* Video Packetizer Registers */ ++#define HDMI_VP_STATUS 0x0400 ++#define HDMI_VP_PR_CD 0x0401 ++#define HDMI_VP_STUFF 0x8400 ++#define HDMI_VP_REMAP 0x8401 ++#define HDMI_VP_CONF 0x0402 ++#define HDMI_VP_STAT 0x0403 ++#define HDMI_VP_INT 0x8402 ++#define HDMI_VP_MASK 0x8403 ++#define HDMI_VP_POL 0x4400 ++ ++/* Frame Composer Registers */ ++#define HDMI_FC_INVIDCONF 0x0040 ++#define HDMI_FC_INHACTV0 0x0041 ++#define HDMI_FC_INHACTV1 0x8040 ++#define HDMI_FC_INHBLANK0 0x8041 ++#define HDMI_FC_INHBLANK1 0x0042 ++#define HDMI_FC_INVACTV0 0x0043 ++#define HDMI_FC_INVACTV1 0x8042 ++#define HDMI_FC_INVBLANK 0x8043 ++#define HDMI_FC_HSYNCINDELAY0 0x4040 ++#define HDMI_FC_HSYNCINDELAY1 0x4041 ++#define HDMI_FC_HSYNCINWIDTH0 0xC040 ++#define HDMI_FC_HSYNCINWIDTH1 0xC041 ++#define HDMI_FC_VSYNCINDELAY 0x4042 ++#define HDMI_FC_VSYNCINWIDTH 0x4043 ++#define HDMI_FC_INFREQ0 0xC042 ++#define HDMI_FC_INFREQ1 0xC043 ++#define HDMI_FC_INFREQ2 0x0044 ++#define HDMI_FC_CTRLDUR 0x0045 ++#define HDMI_FC_EXCTRLDUR 0x8044 ++#define HDMI_FC_EXCTRLSPAC 0x8045 ++#define HDMI_FC_CH0PREAM 0x0046 ++#define HDMI_FC_CH1PREAM 0x0047 ++#define HDMI_FC_CH2PREAM 0x8046 ++#define HDMI_FC_AVICONF3 0x8047 ++#define HDMI_FC_GCP 0x4044 ++#define HDMI_FC_AVICONF0 0x4045 ++#define HDMI_FC_AVICONF1 0xC044 ++#define HDMI_FC_AVICONF2 0xC045 ++#define HDMI_FC_AVIVID 0x4046 ++#define HDMI_FC_AVIETB0 0x4047 ++#define HDMI_FC_AVIETB1 0xC046 ++#define HDMI_FC_AVISBB0 0xC047 ++#define HDMI_FC_AVISBB1 0x2040 ++#define HDMI_FC_AVIELB0 0x2041 ++#define HDMI_FC_AVIELB1 0xA040 ++#define HDMI_FC_AVISRB0 0xA041 ++#define HDMI_FC_AVISRB1 0x2042 ++#define HDMI_FC_AUDICONF0 0x2043 ++#define HDMI_FC_AUDICONF1 0xA042 ++#define HDMI_FC_AUDICONF2 0xA043 ++#define HDMI_FC_AUDICONF3 0x6040 ++#define HDMI_FC_VSDIEEEID0 0x6041 ++#define HDMI_FC_VSDSIZE 0xE040 ++#define HDMI_FC_VSDIEEEID1 0x2044 ++#define HDMI_FC_VSDIEEEID2 0x2045 ++#define HDMI_FC_VSDPAYLOAD0 0xA044 ++#define HDMI_FC_VSDPAYLOAD1 0xA045 ++#define HDMI_FC_VSDPAYLOAD2 0x2046 ++#define HDMI_FC_VSDPAYLOAD3 0x2047 ++#define HDMI_FC_VSDPAYLOAD4 0xA046 ++#define HDMI_FC_VSDPAYLOAD5 0xA047 ++#define HDMI_FC_VSDPAYLOAD6 0x6044 ++#define HDMI_FC_VSDPAYLOAD7 0x6045 ++#define HDMI_FC_VSDPAYLOAD8 0xE044 ++#define HDMI_FC_VSDPAYLOAD9 0xE045 ++#define HDMI_FC_VSDPAYLOAD10 0x6046 ++#define HDMI_FC_VSDPAYLOAD11 0x6047 ++#define HDMI_FC_VSDPAYLOAD12 0xE046 ++#define HDMI_FC_VSDPAYLOAD13 0xE047 ++#define HDMI_FC_VSDPAYLOAD14 0x0048 ++#define HDMI_FC_VSDPAYLOAD15 0x0049 ++#define HDMI_FC_VSDPAYLOAD16 0x8048 ++#define HDMI_FC_VSDPAYLOAD17 0x8049 ++#define HDMI_FC_VSDPAYLOAD18 0x004A ++#define HDMI_FC_VSDPAYLOAD19 0x004B ++#define HDMI_FC_VSDPAYLOAD20 0x804A ++#define HDMI_FC_VSDPAYLOAD21 0x804B ++#define HDMI_FC_VSDPAYLOAD22 0x4048 ++#define HDMI_FC_VSDPAYLOAD23 0x4049 ++#define HDMI_FC_SPDVENDORNAME0 0xC048 ++#define HDMI_FC_SPDVENDORNAME1 0xC049 ++#define HDMI_FC_SPDVENDORNAME2 0x404A ++#define HDMI_FC_SPDVENDORNAME3 0x404B ++#define HDMI_FC_SPDVENDORNAME4 0xC04A ++#define HDMI_FC_SPDVENDORNAME5 0xC04B ++#define HDMI_FC_SPDVENDORNAME6 0x004C ++#define HDMI_FC_SPDVENDORNAME7 0x004D ++#define HDMI_FC_SDPPRODUCTNAME0 0x804C ++#define HDMI_FC_SDPPRODUCTNAME1 0x804D ++#define HDMI_FC_SDPPRODUCTNAME2 0x004E ++#define HDMI_FC_SDPPRODUCTNAME3 0x004F ++#define HDMI_FC_SDPPRODUCTNAME4 0x804E ++#define HDMI_FC_SDPPRODUCTNAME5 0x804F ++#define HDMI_FC_SDPPRODUCTNAME6 0x404C ++#define HDMI_FC_SDPPRODUCTNAME7 0x404D ++#define HDMI_FC_SDPPRODUCTNAME8 0xC04C ++#define HDMI_FC_SDPPRODUCTNAME9 0xC04D ++#define HDMI_FC_SDPPRODUCTNAME10 0x404E ++#define HDMI_FC_SDPPRODUCTNAME11 0x404F ++#define HDMI_FC_SDPPRODUCTNAME12 0xC04E ++#define HDMI_FC_SDPPRODUCTNAME13 0xC04F ++#define HDMI_FC_SDPPRODUCTNAME14 0x2048 ++#define HDMI_FC_SPDPRODUCTNAME15 0x2049 ++#define HDMI_FC_SPDDEVICEINF 0xA048 ++#define HDMI_FC_AUDSCONF 0xA049 ++#define HDMI_FC_AUDSSTAT 0x204A ++#define HDMI_FC_DATACH0FILL 0x204C ++#define HDMI_FC_DATACH1FILL 0x204D ++#define HDMI_FC_DATACH2FILL 0xA04C ++#define HDMI_FC_CTRLQHIGH 0xA04D ++#define HDMI_FC_CTRLQLOW 0x204E ++#define HDMI_FC_ACP0 0x204F ++#define HDMI_FC_ACP28 0xA04E ++#define HDMI_FC_ACP27 0xA04F ++#define HDMI_FC_ACP26 0x604C ++#define HDMI_FC_ACP25 0x604D ++#define HDMI_FC_ACP24 0xE04C ++#define HDMI_FC_ACP23 0xE04D ++#define HDMI_FC_ACP22 0x604E ++#define HDMI_FC_ACP21 0x604F ++#define HDMI_FC_ACP20 0xE04E ++#define HDMI_FC_ACP19 0xE04F ++#define HDMI_FC_ACP18 0x1040 ++#define HDMI_FC_ACP17 0x1041 ++#define HDMI_FC_ACP16 0x9040 ++#define HDMI_FC_ACP15 0x9041 ++#define HDMI_FC_ACP14 0x1042 ++#define HDMI_FC_ACP13 0x1043 ++#define HDMI_FC_ACP12 0x9042 ++#define HDMI_FC_ACP11 0x9043 ++#define HDMI_FC_ACP10 0x5040 ++#define HDMI_FC_ACP9 0x5041 ++#define HDMI_FC_ACP8 0xD040 ++#define HDMI_FC_ACP7 0xD041 ++#define HDMI_FC_ACP6 0x5042 ++#define HDMI_FC_ACP5 0x5043 ++#define HDMI_FC_ACP4 0xD042 ++#define HDMI_FC_ACP3 0xD043 ++#define HDMI_FC_ACP2 0x1044 ++#define HDMI_FC_ACP1 0x1045 ++#define HDMI_FC_ISCR1_0 0x9044 ++#define HDMI_FC_ISCR1_16 0x9045 ++#define HDMI_FC_ISCR1_15 0x1046 ++#define HDMI_FC_ISCR1_14 0x1047 ++#define HDMI_FC_ISCR1_13 0x9046 ++#define HDMI_FC_ISCR1_12 0x9047 ++#define HDMI_FC_ISCR1_11 0x5044 ++#define HDMI_FC_ISCR1_10 0x5045 ++#define HDMI_FC_ISCR1_9 0xD044 ++#define HDMI_FC_ISCR1_8 0xD045 ++#define HDMI_FC_ISCR1_7 0x5046 ++#define HDMI_FC_ISCR1_6 0x5047 ++#define HDMI_FC_ISCR1_5 0xD046 ++#define HDMI_FC_ISCR1_4 0xD047 ++#define HDMI_FC_ISCR1_3 0x3040 ++#define HDMI_FC_ISCR1_2 0x3041 ++#define HDMI_FC_ISCR1_1 0xB040 ++#define HDMI_FC_ISCR2_15 0xB041 ++#define HDMI_FC_ISCR2_14 0x3042 ++#define HDMI_FC_ISCR2_13 0x3043 ++#define HDMI_FC_ISCR2_12 0xB042 ++#define HDMI_FC_ISCR2_11 0xB043 ++#define HDMI_FC_ISCR2_10 0x7040 ++#define HDMI_FC_ISCR2_9 0x7041 ++#define HDMI_FC_ISCR2_8 0xF040 ++#define HDMI_FC_ISCR2_7 0xF041 ++#define HDMI_FC_ISCR2_6 0x7042 ++#define HDMI_FC_ISCR2_5 0x7043 ++#define HDMI_FC_ISCR2_4 0xF042 ++#define HDMI_FC_ISCR2_3 0xF043 ++#define HDMI_FC_ISCR2_2 0x3044 ++#define HDMI_FC_ISCR2_1 0x3045 ++#define HDMI_FC_ISCR2_0 0xB044 ++#define HDMI_FC_DATAUTO0 0xB045 ++#define HDMI_FC_DATAUTO1 0x3046 ++#define HDMI_FC_DATAUTO2 0x3047 ++#define HDMI_FC_DATMAN 0xB046 ++#define HDMI_FC_DATAUTO3 0xB047 ++#define HDMI_FC_RDRB0 0x7044 ++#define HDMI_FC_RDRB1 0x7045 ++#define HDMI_FC_RDRB2 0xF044 ++#define HDMI_FC_RDRB3 0xF045 ++#define HDMI_FC_RDRB4 0x7046 ++#define HDMI_FC_RDRB5 0x7047 ++#define HDMI_FC_RDRB6 0xF046 ++#define HDMI_FC_RDRB7 0xF047 ++#define HDMI_FC_STAT0 0x104C ++#define HDMI_FC_INT0 0x104D ++#define HDMI_FC_MASK0 0x904C ++#define HDMI_FC_POL0 0x904D ++#define HDMI_FC_STAT1 0x104E ++#define HDMI_FC_INT1 0x104F ++#define HDMI_FC_MASK1 0x904E ++#define HDMI_FC_POL1 0x904F ++#define HDMI_FC_STAT2 0x504C ++#define HDMI_FC_INT2 0x504D ++#define HDMI_FC_MASK2 0xD04C ++#define HDMI_FC_POL2 0xD04D ++#define HDMI_FC_PRCONF 0x3048 ++ ++#define HDMI_FC_GMD_STAT 0x0050 ++#define HDMI_FC_GMD_EN 0x0051 ++#define HDMI_FC_GMD_UP 0x8050 ++#define HDMI_FC_GMD_CONF 0x8051 ++#define HDMI_FC_GMD_HB 0x0052 ++#define HDMI_FC_GMD_PB0 0x0053 ++#define HDMI_FC_GMD_PB1 0x8052 ++#define HDMI_FC_GMD_PB2 0x8053 ++#define HDMI_FC_GMD_PB3 0x4050 ++#define HDMI_FC_GMD_PB4 0x4051 ++#define HDMI_FC_GMD_PB5 0xC050 ++#define HDMI_FC_GMD_PB6 0xC051 ++#define HDMI_FC_GMD_PB7 0x4052 ++#define HDMI_FC_GMD_PB8 0x4053 ++#define HDMI_FC_GMD_PB9 0xC052 ++#define HDMI_FC_GMD_PB10 0xC053 ++#define HDMI_FC_GMD_PB11 0x0054 ++#define HDMI_FC_GMD_PB12 0x0055 ++#define HDMI_FC_GMD_PB13 0x8054 ++#define HDMI_FC_GMD_PB14 0x8055 ++#define HDMI_FC_GMD_PB15 0x0056 ++#define HDMI_FC_GMD_PB16 0x0057 ++#define HDMI_FC_GMD_PB17 0x8056 ++#define HDMI_FC_GMD_PB18 0x8057 ++#define HDMI_FC_GMD_PB19 0x4054 ++#define HDMI_FC_GMD_PB20 0x4055 ++#define HDMI_FC_GMD_PB21 0xC054 ++#define HDMI_FC_GMD_PB22 0xC055 ++#define HDMI_FC_GMD_PB23 0x4056 ++#define HDMI_FC_GMD_PB24 0x4057 ++#define HDMI_FC_GMD_PB25 0xC056 ++#define HDMI_FC_GMD_PB26 0xC057 ++#define HDMI_FC_GMD_PB27 0x2050 ++ ++#define HDMI_FC_DBGFORCE 0x0840 ++#define HDMI_FC_DBGAUD0CH0 0x0841 ++#define HDMI_FC_DBGAUD1CH0 0x8840 ++#define HDMI_FC_DBGAUD2CH0 0x8841 ++#define HDMI_FC_DBGAUD0CH1 0x0842 ++#define HDMI_FC_DBGAUD1CH1 0x0843 ++#define HDMI_FC_DBGAUD2CH1 0x8842 ++#define HDMI_FC_DBGAUD0CH2 0x8843 ++#define HDMI_FC_DBGAUD1CH2 0x4840 ++#define HDMI_FC_DBGAUD2CH2 0x4841 ++#define HDMI_FC_DBGAUD0CH3 0xC840 ++#define HDMI_FC_DBGAUD1CH3 0xC841 ++#define HDMI_FC_DBGAUD2CH3 0x4842 ++#define HDMI_FC_DBGAUD0CH4 0x4843 ++#define HDMI_FC_DBGAUD1CH4 0xC842 ++#define HDMI_FC_DBGAUD2CH4 0xC843 ++#define HDMI_FC_DBGAUD0CH5 0x0844 ++#define HDMI_FC_DBGAUD1CH5 0x0845 ++#define HDMI_FC_DBGAUD2CH5 0x8844 ++#define HDMI_FC_DBGAUD0CH6 0x8845 ++#define HDMI_FC_DBGAUD1CH6 0x0846 ++#define HDMI_FC_DBGAUD2CH6 0x0847 ++#define HDMI_FC_DBGAUD0CH7 0x8846 ++#define HDMI_FC_DBGAUD1CH7 0x8847 ++#define HDMI_FC_DBGAUD2CH7 0x4844 ++#define HDMI_FC_DBGTMDS0 0x4845 ++#define HDMI_FC_DBGTMDS1 0xC844 ++#define HDMI_FC_DBGTMDS2 0xC845 ++ ++/* HDMI Source PHY Registers */ ++#define HDMI_PHY_CONF0 0x0240 ++#define HDMI_PHY_TST0 0x0241 ++#define HDMI_PHY_TST1 0x8240 ++#define HDMI_PHY_TST2 0x8241 ++#define HDMI_PHY_STAT0 0x0242 ++#define HDMI_PHY_INT0 0x0243 ++#define HDMI_PHY_MASK0 0x8242 ++#define HDMI_PHY_POL0 0x8243 ++ ++/* HDMI Master PHY Registers */ ++#define HDMI_PHY_I2CM_SLAVE_ADDR 0x2240 ++#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x2241 ++#define HDMI_PHY_I2CM_DATAO_1_ADDR 0xA240 ++#define HDMI_PHY_I2CM_DATAO_0_ADDR 0xA241 ++#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x2242 ++#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x2243 ++#define HDMI_PHY_I2CM_OPERATION_ADDR 0xA242 ++#define HDMI_PHY_I2CM_INT_ADDR 0xA243 ++#define HDMI_PHY_I2CM_CTLINT_ADDR 0x6240 ++#define HDMI_PHY_I2CM_DIV_ADDR 0x6241 ++#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0xE240 ++#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0xE241 ++#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x6242 ++#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x6243 ++#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0xE242 ++#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0xE243 ++#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x2244 ++#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x2245 ++#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0xA244 ++ ++/* Audio Sampler Registers */ ++#define HDMI_AUD_CONF0 0x0250 ++#define HDMI_AUD_CONF1 0x0251 ++#define HDMI_AUD_INT 0x8250 ++#define HDMI_AUD_CONF2 0x8251 ++#define HDMI_AUD_N1 0x0A40 ++#define HDMI_AUD_N2 0x0A41 ++#define HDMI_AUD_N3 0x8A40 ++#define HDMI_AUD_CTS1 0x8A41 ++#define HDMI_AUD_CTS2 0x0A42 ++#define HDMI_AUD_CTS3 0x0A43 ++#define HDMI_AUD_INPUTCLKFS 0x8A42 ++#define HDMI_AUD_SPDIFINT 0x8A50 ++#define HDMI_AUD_CONF0_HBR 0x0260 ++#define HDMI_AUD_HBR_STATUS 0x0261 ++#define HDMI_AUD_HBR_INT 0x8260 ++#define HDMI_AUD_HBR_POL 0x8261 ++#define HDMI_AUD_HBR_MASK 0x0262 ++ ++/* Generic Parallel Audio Interface Registers */ ++/* Not used as GPAUD interface is not enabled in hw */ ++#define HDMI_GP_CONF0 0x0270 ++#define HDMI_GP_CONF1 0x0271 ++#define HDMI_GP_CONF2 0x8270 ++#define HDMI_GP_STAT 0x8271 ++#define HDMI_GP_INT 0x0272 ++#define HDMI_GP_MASK 0x0273 ++#define HDMI_GP_POL 0x8272 ++ ++/* Audio DMA Registers */ ++#define HDMI_AHB_DMA_CONF0 0x0A60 ++#define HDMI_AHB_DMA_START 0x0A61 ++#define HDMI_AHB_DMA_STOP 0x8A60 ++#define HDMI_AHB_DMA_THRSLD 0x8A61 ++#define HDMI_AHB_DMA_STRADDR0 0x0A62 ++#define HDMI_AHB_DMA_STRADDR1 0x0A63 ++#define HDMI_AHB_DMA_STRADDR2 0x8A62 ++#define HDMI_AHB_DMA_STRADDR3 0x8A63 ++#define HDMI_AHB_DMA_STPADDR0 0x4A60 ++#define HDMI_AHB_DMA_STPADDR1 0x4A61 ++#define HDMI_AHB_DMA_STPADDR2 0xCA60 ++#define HDMI_AHB_DMA_STPADDR3 0xCA61 ++#define HDMI_AHB_DMA_BSTADDR0 0x4A62 ++#define HDMI_AHB_DMA_BSTADDR1 0x4A63 ++#define HDMI_AHB_DMA_BSTADDR2 0xCA62 ++#define HDMI_AHB_DMA_BSTADDR3 0xCA63 ++#define HDMI_AHB_DMA_MBLENGTH0 0x0A64 ++#define HDMI_AHB_DMA_MBLENGTH1 0x0A65 ++#define HDMI_AHB_DMA_STAT 0x8A64 ++#define HDMI_AHB_DMA_INT 0x8A65 ++#define HDMI_AHB_DMA_MASK 0x0A66 ++#define HDMI_AHB_DMA_POL 0x0A67 ++#define HDMI_AHB_DMA_CONF1 0x8A66 ++#define HDMI_AHB_DMA_BUFFSTAT 0x8A67 ++#define HDMI_AHB_DMA_BUFFINT 0x4A64 ++#define HDMI_AHB_DMA_BUFFMASK 0x4A65 ++#define HDMI_AHB_DMA_BUFFPOL 0xCA64 ++ ++/* Main Controller Registers */ ++#define HDMI_MC_SFRDIV 0x0080 ++#define HDMI_MC_CLKDIS 0x0081 ++#define HDMI_MC_SWRSTZ 0x8080 ++#define HDMI_MC_OPCTRL 0x8081 ++#define HDMI_MC_FLOWCTRL 0x0082 ++#define HDMI_MC_PHYRSTZ 0x0083 ++#define HDMI_MC_LOCKONCLOCK 0x8082 ++#define HDMI_MC_HEACPHY_RST 0x8083 ++ ++/* Color Space Converter Registers */ ++#define HDMI_CSC_CFG 0x0090 ++#define HDMI_CSC_SCALE 0x0091 ++#define HDMI_CSC_COEF_A1_MSB 0x8090 ++#define HDMI_CSC_COEF_A1_LSB 0x8091 ++#define HDMI_CSC_COEF_A2_MSB 0x0092 ++#define HDMI_CSC_COEF_A2_LSB 0x0093 ++#define HDMI_CSC_COEF_A3_MSB 0x8092 ++#define HDMI_CSC_COEF_A3_LSB 0x8093 ++#define HDMI_CSC_COEF_A4_MSB 0x4090 ++#define HDMI_CSC_COEF_A4_LSB 0x4091 ++#define HDMI_CSC_COEF_B1_MSB 0xC090 ++#define HDMI_CSC_COEF_B1_LSB 0xC091 ++#define HDMI_CSC_COEF_B2_MSB 0x4092 ++#define HDMI_CSC_COEF_B2_LSB 0x4093 ++#define HDMI_CSC_COEF_B3_MSB 0xC092 ++#define HDMI_CSC_COEF_B3_LSB 0xC093 ++#define HDMI_CSC_COEF_B4_MSB 0x0094 ++#define HDMI_CSC_COEF_B4_LSB 0x0095 ++#define HDMI_CSC_COEF_C1_MSB 0x8094 ++#define HDMI_CSC_COEF_C1_LSB 0x8095 ++#define HDMI_CSC_COEF_C2_MSB 0x0096 ++#define HDMI_CSC_COEF_C2_LSB 0x0097 ++#define HDMI_CSC_COEF_C3_MSB 0x8096 ++#define HDMI_CSC_COEF_C3_LSB 0x8097 ++#define HDMI_CSC_COEF_C4_MSB 0x4094 ++#define HDMI_CSC_COEF_C4_LSB 0x4095 ++ ++/* HDCP Encryption Engine Registers */ ++#define HDMI_A_HDCPCFG0 0x00C0 ++#define HDMI_A_HDCPCFG1 0x00C1 ++#define HDMI_A_HDCPOBS0 0x80C0 ++#define HDMI_A_HDCPOBS1 0x80C1 ++#define HDMI_A_HDCPOBS2 0x00C2 ++#define HDMI_A_HDCPOBS3 0x00C3 ++#define HDMI_A_APIINTCLR 0x80C2 ++#define HDMI_A_APIINTSTAT 0x80C3 ++#define HDMI_A_APIINTMSK 0x40C0 ++#define HDMI_A_VIDPOLCFG 0x40C1 ++#define HDMI_A_OESSWCFG 0xC0C0 ++#define HDMI_A_TIMER1SETUP0 0xC0C1 ++#define HDMI_A_TIMER1SETUP1 0x40C2 ++#define HDMI_A_TIMER2SETUP0 0x40C3 ++#define HDMI_A_TIMER2SETUP1 0xC0C2 ++#define HDMI_A_100MSCFG 0xC0C3 ++#define HDMI_A_2SCFG0 0x00C4 ++#define HDMI_A_2SCFG1 0x00C5 ++#define HDMI_A_5SCFG0 0x80C4 ++#define HDMI_A_5SCFG1 0x80C5 ++#define HDMI_A_SRMVERLSB 0x00C6 ++#define HDMI_A_SRMVERMSB 0x00C7 ++#define HDMI_A_SRMCTRL 0x80C6 ++#define HDMI_A_SFRSETUP 0x80C7 ++#define HDMI_A_I2CHSETUP 0x40C4 ++#define HDMI_A_INTSETUP 0x40C5 ++#define HDMI_A_PRESETUP 0xC0C4 ++#define HDMI_A_SRM_BASE 0x20C0 ++ ++/* CEC Engine Registers */ ++#define HDMI_CEC_CTRL 0x06F0 ++#define HDMI_CEC_STAT 0x06F1 ++#define HDMI_CEC_MASK 0x86F0 ++#define HDMI_CEC_POLARITY 0x86F1 ++#define HDMI_CEC_INT 0x06F2 ++#define HDMI_CEC_ADDR_L 0x06F3 ++#define HDMI_CEC_ADDR_H 0x86F2 ++#define HDMI_CEC_TX_CNT 0x86F3 ++#define HDMI_CEC_RX_CNT 0x46F0 ++#define HDMI_CEC_TX_DATA0 0x06F4 ++#define HDMI_CEC_TX_DATA1 0x06F5 ++#define HDMI_CEC_TX_DATA2 0x86F4 ++#define HDMI_CEC_TX_DATA3 0x86F5 ++#define HDMI_CEC_TX_DATA4 0x06F6 ++#define HDMI_CEC_TX_DATA5 0x06F7 ++#define HDMI_CEC_TX_DATA6 0x86F6 ++#define HDMI_CEC_TX_DATA7 0x86F7 ++#define HDMI_CEC_TX_DATA8 0x46F4 ++#define HDMI_CEC_TX_DATA9 0x46F5 ++#define HDMI_CEC_TX_DATA10 0xC6F4 ++#define HDMI_CEC_TX_DATA11 0xC6F5 ++#define HDMI_CEC_TX_DATA12 0x46F6 ++#define HDMI_CEC_TX_DATA13 0x46F7 ++#define HDMI_CEC_TX_DATA14 0xC6F6 ++#define HDMI_CEC_TX_DATA15 0xC6F7 ++#define HDMI_CEC_RX_DATA0 0x26F0 ++#define HDMI_CEC_RX_DATA1 0x26F1 ++#define HDMI_CEC_RX_DATA2 0xA6F0 ++#define HDMI_CEC_RX_DATA3 0xA6F1 ++#define HDMI_CEC_RX_DATA4 0x26F2 ++#define HDMI_CEC_RX_DATA5 0x26F3 ++#define HDMI_CEC_RX_DATA6 0xA6F2 ++#define HDMI_CEC_RX_DATA7 0xA6F3 ++#define HDMI_CEC_RX_DATA8 0x66F0 ++#define HDMI_CEC_RX_DATA9 0x66F1 ++#define HDMI_CEC_RX_DATA10 0xE6F0 ++#define HDMI_CEC_RX_DATA11 0xE6F1 ++#define HDMI_CEC_RX_DATA12 0x66F2 ++#define HDMI_CEC_RX_DATA13 0x66F3 ++#define HDMI_CEC_RX_DATA14 0xE6F2 ++#define HDMI_CEC_RX_DATA15 0xE6F3 ++#define HDMI_CEC_LOCK 0x26F4 ++#define HDMI_CEC_WKUPCTRL 0x26F5 ++ ++/* I2C Master Registers (E-DDC) */ ++#define HDMI_I2CM_SLAVE 0x0EE0 ++#define HDMI_I2CM_ADDRESS 0x0EE1 ++#define HDMI_I2CM_DATAO 0x8EE0 ++#define HDMI_I2CM_DATAI 0x8EE1 ++#define HDMI_I2CM_OPERATION 0x0EE2 ++#define HDMI_I2CM_INT 0x0EE3 ++#define HDMI_I2CM_CTLINT 0x8EE2 ++#define HDMI_I2CM_DIV 0x8EE3 ++#define HDMI_I2CM_SEGADDR 0x4EE0 ++#define HDMI_I2CM_SOFTRSTZ 0x4EE1 ++#define HDMI_I2CM_SEGPTR 0xCEE0 ++#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0xCEE1 ++#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x4EE2 ++#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x4EE3 ++#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0xCEE2 ++#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0xCEE3 ++#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x0EE4 ++#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x0EE5 ++#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x8EE4 ++ ++/* Random Number Generator Registers (RNG) */ ++#define HDMI_RNG_BASE 0x0100 ++ ++ ++/* ++ * Register field definitions ++ */ ++enum { ++/* IH_FC_INT2 field values */ ++ HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03, ++ HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, ++ HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, ++ ++/* IH_FC_STAT2 field values */ ++ HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03, ++ HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, ++ HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, ++ ++/* IH_PHY_STAT0 field values */ ++ HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20, ++ HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10, ++ HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8, ++ HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4, ++ HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2, ++ HDMI_IH_PHY_STAT0_HPD = 0x1, ++ ++/* IH_CEC_STAT0 field values */ ++ HDMI_IH_CEC_STAT0_WAKEUP = 0x40, ++ HDMI_IH_CEC_STAT0_ERROR_FOLL = 0x20, ++ HDMI_IH_CEC_STAT0_ERROR_INIT = 0x10, ++ HDMI_IH_CEC_STAT0_ARB_LOST = 0x8, ++ HDMI_IH_CEC_STAT0_NACK = 0x4, ++ HDMI_IH_CEC_STAT0_EOM = 0x2, ++ HDMI_IH_CEC_STAT0_DONE = 0x1, ++ ++ ++/* IH_MUTE_I2CMPHY_STAT0 field values */ ++ HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2, ++ HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1, ++ ++/* IH_PHY_STAT0 field values */ ++ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE3 = 0x20, ++ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE2 = 0x10, ++ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE1 = 0x8, ++ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE0 = 0x4, ++ HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2, ++ HDMI_IH_MUTE_PHY_STAT0_HPD = 0x1, ++ ++/* IH_AHBDMAAUD_STAT0 field values */ ++ HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20, ++ HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10, ++ HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08, ++ HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04, ++ HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02, ++ HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, ++ ++/* IH_MUTE_FC_STAT2 field values */ ++ HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03, ++ HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, ++ HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, ++ ++/* IH_MUTE_AHBDMAAUD_STAT0 field values */ ++ HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20, ++ HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10, ++ HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08, ++ HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04, ++ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02, ++ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, ++ ++/* IH_MUTE field values */ ++ HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2, ++ HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1, ++ ++/* TX_INVID0 field values */ ++ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80, ++ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80, ++ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00, ++ HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F, ++ HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0, ++ ++/* TX_INSTUFFING field values */ ++ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4, ++ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4, ++ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0, ++ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2, ++ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2, ++ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0, ++ HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1, ++ HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1, ++ HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0, ++ ++/* VP_PR_CD field values */ ++ HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0, ++ HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4, ++ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F, ++ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0, ++ ++/* VP_STUFF field values */ ++ HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20, ++ HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5, ++ HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10, ++ HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4, ++ HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8, ++ HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3, ++ HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4, ++ HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4, ++ HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0, ++ HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2, ++ HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2, ++ HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0, ++ HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1, ++ HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1, ++ HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0, ++ ++/* VP_CONF field values */ ++ HDMI_VP_CONF_BYPASS_EN_MASK = 0x40, ++ HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40, ++ HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00, ++ HDMI_VP_CONF_PP_EN_ENMASK = 0x20, ++ HDMI_VP_CONF_PP_EN_ENABLE = 0x20, ++ HDMI_VP_CONF_PP_EN_DISABLE = 0x00, ++ HDMI_VP_CONF_PR_EN_MASK = 0x10, ++ HDMI_VP_CONF_PR_EN_ENABLE = 0x10, ++ HDMI_VP_CONF_PR_EN_DISABLE = 0x00, ++ HDMI_VP_CONF_YCC422_EN_MASK = 0x8, ++ HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8, ++ HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0, ++ HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4, ++ HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4, ++ HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0, ++ HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3, ++ HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3, ++ HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1, ++ HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0, ++ ++/* VP_REMAP field values */ ++ HDMI_VP_REMAP_MASK = 0x3, ++ HDMI_VP_REMAP_YCC422_24bit = 0x2, ++ HDMI_VP_REMAP_YCC422_20bit = 0x1, ++ HDMI_VP_REMAP_YCC422_16bit = 0x0, ++ ++/* FC_INVIDCONF field values */ ++ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80, ++ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80, ++ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00, ++ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40, ++ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40, ++ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, ++ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20, ++ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20, ++ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, ++ HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10, ++ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10, ++ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00, ++ HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8, ++ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8, ++ HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0, ++ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2, ++ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2, ++ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0, ++ HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1, ++ HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1, ++ HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0, ++ ++/* FC_AUDICONF0 field values */ ++ HDMI_FC_AUDICONF0_CC_OFFSET = 4, ++ HDMI_FC_AUDICONF0_CC_MASK = 0x70, ++ HDMI_FC_AUDICONF0_CT_OFFSET = 0, ++ HDMI_FC_AUDICONF0_CT_MASK = 0xF, ++ ++/* FC_AUDICONF1 field values */ ++ HDMI_FC_AUDICONF1_SS_OFFSET = 3, ++ HDMI_FC_AUDICONF1_SS_MASK = 0x18, ++ HDMI_FC_AUDICONF1_SF_OFFSET = 0, ++ HDMI_FC_AUDICONF1_SF_MASK = 0x7, ++ ++/* FC_AUDICONF3 field values */ ++ HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5, ++ HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60, ++ HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4, ++ HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10, ++ HDMI_FC_AUDICONF3_LSV_OFFSET = 0, ++ HDMI_FC_AUDICONF3_LSV_MASK = 0xF, ++ ++/* FC_AUDSCHNLS0 field values */ ++ HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4, ++ HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30, ++ HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0, ++ HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01, ++ ++/* FC_AUDSCHNLS3-6 field values */ ++ HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0, ++ HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f, ++ HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4, ++ HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0, ++ HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0, ++ HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f, ++ HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4, ++ HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0, ++ ++ HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0, ++ HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f, ++ HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4, ++ HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0, ++ HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0, ++ HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f, ++ HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4, ++ HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0, ++ ++/* HDMI_FC_AUDSCHNLS7 field values */ ++ HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4, ++ HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30, ++ ++/* HDMI_FC_AUDSCHNLS8 field values */ ++ HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0, ++ HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4, ++ HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f, ++ HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0, ++ ++/* FC_AUDSCONF field values */ ++ HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0, ++ HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4, ++ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1, ++ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0, ++ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1, ++ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0, ++ ++/* FC_STAT2 field values */ ++ HDMI_FC_STAT2_OVERFLOW_MASK = 0x03, ++ HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, ++ HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, ++ ++/* FC_INT2 field values */ ++ HDMI_FC_INT2_OVERFLOW_MASK = 0x03, ++ HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, ++ HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, ++ ++/* FC_MASK2 field values */ ++ HDMI_FC_MASK2_OVERFLOW_MASK = 0x03, ++ HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02, ++ HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01, ++ ++/* FC_PRCONF field values */ ++ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0, ++ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4, ++ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F, ++ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0, ++ ++/* FC_AVICONF0-FC_AVICONF3 field values */ ++ HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03, ++ HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00, ++ HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01, ++ HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02, ++ HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40, ++ HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40, ++ HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00, ++ HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C, ++ HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00, ++ HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04, ++ HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08, ++ HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C, ++ HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30, ++ HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10, ++ HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20, ++ HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00, ++ ++ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F, ++ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08, ++ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09, ++ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A, ++ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B, ++ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30, ++ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00, ++ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10, ++ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20, ++ HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0, ++ HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00, ++ HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40, ++ HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80, ++ HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0, ++ ++ HDMI_FC_AVICONF2_SCALING_MASK = 0x03, ++ HDMI_FC_AVICONF2_SCALING_NONE = 0x00, ++ HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01, ++ HDMI_FC_AVICONF2_SCALING_VERT = 0x02, ++ HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03, ++ HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C, ++ HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00, ++ HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04, ++ HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08, ++ HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70, ++ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00, ++ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10, ++ HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20, ++ HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30, ++ HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40, ++ HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80, ++ HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00, ++ HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80, ++ ++ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03, ++ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00, ++ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01, ++ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02, ++ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03, ++ HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C, ++ HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00, ++ HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04, ++ ++/* FC_DBGFORCE field values */ ++ HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10, ++ HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1, ++ ++/* PHY_CONF0 field values */ ++ HDMI_PHY_CONF0_PDZ_MASK = 0x80, ++ HDMI_PHY_CONF0_PDZ_OFFSET = 7, ++ HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, ++ HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, ++ HDMI_PHY_CONF0_SPARECTRL = 0x20, ++ HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, ++ HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, ++ HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, ++ HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3, ++ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4, ++ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2, ++ HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2, ++ HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1, ++ HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1, ++ HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0, ++ ++/* PHY_TST0 field values */ ++ HDMI_PHY_TST0_TSTCLR_MASK = 0x20, ++ HDMI_PHY_TST0_TSTCLR_OFFSET = 5, ++ HDMI_PHY_TST0_TSTEN_MASK = 0x10, ++ HDMI_PHY_TST0_TSTEN_OFFSET = 4, ++ HDMI_PHY_TST0_TSTCLK_MASK = 0x1, ++ HDMI_PHY_TST0_TSTCLK_OFFSET = 0, ++ ++/* PHY_STAT0 field values */ ++ HDMI_PHY_RX_SENSE3 = 0x80, ++ HDMI_PHY_RX_SENSE2 = 0x40, ++ HDMI_PHY_RX_SENSE1 = 0x20, ++ HDMI_PHY_RX_SENSE0 = 0x10, ++ HDMI_PHY_HPD = 0x02, ++ HDMI_PHY_TX_PHY_LOCK = 0x01, ++ ++/* PHY_I2CM_SLAVE_ADDR field values */ ++ HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69, ++ HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49, ++ ++/* PHY_I2CM_OPERATION_ADDR field values */ ++ HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10, ++ HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1, ++ ++/* HDMI_PHY_I2CM_INT_ADDR */ ++ HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08, ++ HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04, ++ ++/* HDMI_PHY_I2CM_CTLINT_ADDR */ ++ HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80, ++ HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40, ++ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08, ++ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04, ++ ++/* AUD_CTS3 field values */ ++ HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5, ++ HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0, ++ HDMI_AUD_CTS3_N_SHIFT_1 = 0, ++ HDMI_AUD_CTS3_N_SHIFT_16 = 0x20, ++ HDMI_AUD_CTS3_N_SHIFT_32 = 0x40, ++ HDMI_AUD_CTS3_N_SHIFT_64 = 0x60, ++ HDMI_AUD_CTS3_N_SHIFT_128 = 0x80, ++ HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0, ++ /* note that the CTS3 MANUAL bit has been removed ++ from our part. Can't set it, will read as 0. */ ++ HDMI_AUD_CTS3_CTS_MANUAL = 0x10, ++ HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f, ++ ++/* AHB_DMA_CONF0 field values */ ++ HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7, ++ HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80, ++ HDMI_AHB_DMA_CONF0_HBR = 0x10, ++ HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3, ++ HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08, ++ HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1, ++ HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06, ++ HDMI_AHB_DMA_CONF0_INCR4 = 0x0, ++ HDMI_AHB_DMA_CONF0_INCR8 = 0x2, ++ HDMI_AHB_DMA_CONF0_INCR16 = 0x4, ++ HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1, ++ ++/* HDMI_AHB_DMA_START field values */ ++ HDMI_AHB_DMA_START_START_OFFSET = 0, ++ HDMI_AHB_DMA_START_START_MASK = 0x01, ++ ++/* HDMI_AHB_DMA_STOP field values */ ++ HDMI_AHB_DMA_STOP_STOP_OFFSET = 0, ++ HDMI_AHB_DMA_STOP_STOP_MASK = 0x01, ++ ++/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */ ++ HDMI_AHB_DMA_DONE = 0x80, ++ HDMI_AHB_DMA_RETRY_SPLIT = 0x40, ++ HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20, ++ HDMI_AHB_DMA_ERROR = 0x10, ++ HDMI_AHB_DMA_FIFO_THREMPTY = 0x04, ++ HDMI_AHB_DMA_FIFO_FULL = 0x02, ++ HDMI_AHB_DMA_FIFO_EMPTY = 0x01, ++ ++/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT, AHB_DMA_BUFFMASK, AHB_DMA_BUFFPOL field values */ ++ HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02, ++ HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01, ++ ++/* MC_CLKDIS field values */ ++ HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40, ++ HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20, ++ HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10, ++ HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8, ++ HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4, ++ HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2, ++ HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1, ++ ++/* MC_SWRSTZ field values */ ++ HDMI_MC_SWRSTZ_CECSWRST_REQ = 0x40, ++ HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02, ++ ++/* MC_FLOWCTRL field values */ ++ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1, ++ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1, ++ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0, ++ ++/* MC_PHYRSTZ field values */ ++ HDMI_MC_PHYRSTZ_ASSERT = 0x0, ++ HDMI_MC_PHYRSTZ_DEASSERT = 0x1, ++ ++/* MC_HEACPHY_RST field values */ ++ HDMI_MC_HEACPHY_RST_ASSERT = 0x1, ++ HDMI_MC_HEACPHY_RST_DEASSERT = 0x0, ++ ++/* CSC_CFG field values */ ++ HDMI_CSC_CFG_INTMODE_MASK = 0x30, ++ HDMI_CSC_CFG_INTMODE_OFFSET = 4, ++ HDMI_CSC_CFG_INTMODE_DISABLE = 0x00, ++ HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10, ++ HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20, ++ HDMI_CSC_CFG_DECMODE_MASK = 0x3, ++ HDMI_CSC_CFG_DECMODE_OFFSET = 0, ++ HDMI_CSC_CFG_DECMODE_DISABLE = 0x0, ++ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1, ++ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2, ++ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3, ++ ++/* CSC_SCALE field values */ ++ HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0, ++ HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00, ++ HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50, ++ HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60, ++ HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70, ++ HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03, ++ ++/* A_HDCPCFG0 field values */ ++ HDMI_A_HDCPCFG0_ELVENA_MASK = 0x80, ++ HDMI_A_HDCPCFG0_ELVENA_ENABLE = 0x80, ++ HDMI_A_HDCPCFG0_ELVENA_DISABLE = 0x00, ++ HDMI_A_HDCPCFG0_I2CFASTMODE_MASK = 0x40, ++ HDMI_A_HDCPCFG0_I2CFASTMODE_ENABLE = 0x40, ++ HDMI_A_HDCPCFG0_I2CFASTMODE_DISABLE = 0x00, ++ HDMI_A_HDCPCFG0_BYPENCRYPTION_MASK = 0x20, ++ HDMI_A_HDCPCFG0_BYPENCRYPTION_ENABLE = 0x20, ++ HDMI_A_HDCPCFG0_BYPENCRYPTION_DISABLE = 0x00, ++ HDMI_A_HDCPCFG0_SYNCRICHECK_MASK = 0x10, ++ HDMI_A_HDCPCFG0_SYNCRICHECK_ENABLE = 0x10, ++ HDMI_A_HDCPCFG0_SYNCRICHECK_DISABLE = 0x00, ++ HDMI_A_HDCPCFG0_AVMUTE_MASK = 0x8, ++ HDMI_A_HDCPCFG0_AVMUTE_ENABLE = 0x8, ++ HDMI_A_HDCPCFG0_AVMUTE_DISABLE = 0x0, ++ HDMI_A_HDCPCFG0_RXDETECT_MASK = 0x4, ++ HDMI_A_HDCPCFG0_RXDETECT_ENABLE = 0x4, ++ HDMI_A_HDCPCFG0_RXDETECT_DISABLE = 0x0, ++ HDMI_A_HDCPCFG0_EN11FEATURE_MASK = 0x2, ++ HDMI_A_HDCPCFG0_EN11FEATURE_ENABLE = 0x2, ++ HDMI_A_HDCPCFG0_EN11FEATURE_DISABLE = 0x0, ++ HDMI_A_HDCPCFG0_HDMIDVI_MASK = 0x1, ++ HDMI_A_HDCPCFG0_HDMIDVI_HDMI = 0x1, ++ HDMI_A_HDCPCFG0_HDMIDVI_DVI = 0x0, ++ ++/* A_HDCPCFG1 field values */ ++ HDMI_A_HDCPCFG1_DISSHA1CHECK_MASK = 0x8, ++ HDMI_A_HDCPCFG1_DISSHA1CHECK_DISABLE = 0x8, ++ HDMI_A_HDCPCFG1_DISSHA1CHECK_ENABLE = 0x0, ++ HDMI_A_HDCPCFG1_PH2UPSHFTENC_MASK = 0x4, ++ HDMI_A_HDCPCFG1_PH2UPSHFTENC_ENABLE = 0x4, ++ HDMI_A_HDCPCFG1_PH2UPSHFTENC_DISABLE = 0x0, ++ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK = 0x2, ++ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE = 0x2, ++ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_ENABLE = 0x0, ++ HDMI_A_HDCPCFG1_SWRESET_MASK = 0x1, ++ HDMI_A_HDCPCFG1_SWRESET_ASSERT = 0x0, ++ ++/* A_VIDPOLCFG field values */ ++ HDMI_A_VIDPOLCFG_UNENCRYPTCONF_MASK = 0x60, ++ HDMI_A_VIDPOLCFG_UNENCRYPTCONF_OFFSET = 5, ++ HDMI_A_VIDPOLCFG_DATAENPOL_MASK = 0x10, ++ HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH = 0x10, ++ HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW = 0x0, ++ HDMI_A_VIDPOLCFG_VSYNCPOL_MASK = 0x8, ++ HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_HIGH = 0x8, ++ HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_LOW = 0x0, ++ HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2, ++ HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2, ++ HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0, ++ ++ ++/* I2CM_OPERATION field values */ ++ HDMI_I2CM_OPERATION_WRITE = 0x10, ++ HDMI_I2CM_OPERATION_READ_EXT = 0x2, ++ HDMI_I2CM_OPERATION_READ = 0x1, ++ ++/* HDMI_I2CM_INT */ ++ HDMI_I2CM_INT_DONE_POL = 0x08, ++ HDMI_I2CM_INT_DONE_MASK = 0x04, ++ ++/* HDMI_I2CM_CTLINT */ ++ HDMI_I2CM_CTLINT_NAC_POL = 0x80, ++ HDMI_I2CM_CTLINT_NAC_MASK = 0x40, ++ HDMI_I2CM_CTLINT_ARBITRATION_POL = 0x08, ++ HDMI_I2CM_CTLINT_ARBITRATION_MASK = 0x04, ++ ++}; ++ ++#endif /* __DW_HDMI_H__ */ +diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c +index cd57651..777ca29 100755 +--- a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c ++++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_bsp_sun8iw7.c +@@ -1,6 +1,7 @@ + #include "hdmi_bsp_i.h" + #include "hdmi_bsp.h" + #include "hdmi_core.h" ++#include "dw_hdmi.h" + + static unsigned int hdmi_base_addr; + static struct video_para glb_video; +@@ -266,7 +267,6 @@ void bsp_hdmi_inner_init(void) + hdmi_write(0x10013,0x54); + hdmi_write(0x8080, 0x00); + hdmi_udelay(1); +- hdmi_write(0xF01F, 0x00); + hdmi_write(0x8403, 0xff); + hdmi_write(0x904C, 0xff); + hdmi_write(0x904E, 0xff); +@@ -275,9 +275,13 @@ void bsp_hdmi_inner_init(void) + hdmi_write(0x8A50, 0xff); + hdmi_write(0x8272, 0xff); + hdmi_write(0x40C0, 0xff); ++ hdmi_write(HDMI_PHY_MASK0, 0xff); ++ hdmi_write(HDMI_IH_MUTE_PHY_STAT0, 0xff); ++ hdmi_write(HDMI_IH_MUTE_I2CM_STAT0, 0xff); + hdmi_write(0x86F0, 0xff); + hdmi_write(0x0EE3, 0xff); + hdmi_write(0x8EE2, 0xff); ++ hdmi_write(HDMI_IH_MUTE, 0x00); + hdmi_write(0xA049, 0xf0); + hdmi_write(0xB045, 0x1e); + hdmi_write(0x00C1, 0x00); +diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c +new file mode 100644 +index 0000000..1ba8e6a +--- /dev/null ++++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.c +@@ -0,0 +1,840 @@ ++/* ++ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved. ++ * Copyright (C) 2016 Joachim Damm ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++ ++/*! ++ * @file hdmi_cec.c ++ * ++ * @brief HDMI CEC system initialization and file operation implementation ++ * ++ * @ingroup HDMI ++ */ ++ ++#include ++#include ++#include /* for struct file_operations */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dw_hdmi.h" ++#include "hdmi_cec.h" ++#include "hdmi_edid.h" ++#include "../drv_hdmi_i.h" ++ ++#define MAX_MESSAGE_LEN 17 ++ ++#define MESSAGE_TYPE_RECEIVE_SUCCESS 1 ++#define MESSAGE_TYPE_NOACK 2 ++#define MESSAGE_TYPE_DISCONNECTED 3 ++#define MESSAGE_TYPE_CONNECTED 4 ++#define MESSAGE_TYPE_SEND_SUCCESS 5 ++ ++#define CEC_TX_INPROGRESS -1 ++#define CEC_TX_AVAIL 0 ++ ++struct hdmi_cec_priv { ++ int receive_error; ++ int send_error; ++ u8 Logical_address; ++ bool cec_state; ++ bool msg_resend; ++ u8 last_msg[MAX_MESSAGE_LEN]; ++ u8 msg_len; ++ int tx_answer; ++ u16 latest_cec_stat; ++ u8 link_status; ++ u32 cec_irq; ++ spinlock_t irq_lock; ++ struct delayed_work hdmi_cec_work; ++ struct delayed_work hdmi_cec_resend; ++ struct mutex lock; ++}; ++ ++struct hdmi_cec_event { ++ int event_type; ++ int msg_len; ++ u8 msg[MAX_MESSAGE_LEN]; ++ struct list_head list; ++}; ++ ++static LIST_HEAD(head); ++ ++static int count_lo; ++static int count_hi; ++struct task_struct *rxack_task; ++static int hdmi_cec_major; ++static struct class *hdmi_cec_class; ++static struct hdmi_cec_priv hdmi_cec_data; ++static u8 open_count; ++static u8 cec_l_addr_l = 0, cec_l_addr_h = 0; ++static wait_queue_head_t hdmi_cec_queue; ++static wait_queue_head_t tx_cec_queue; ++ ++static int tx_reg[16] = {HDMI_CEC_TX_DATA0, HDMI_CEC_TX_DATA1, HDMI_CEC_TX_DATA2,\ ++ HDMI_CEC_TX_DATA3, HDMI_CEC_TX_DATA4, HDMI_CEC_TX_DATA5,\ ++ HDMI_CEC_TX_DATA6, HDMI_CEC_TX_DATA7, HDMI_CEC_TX_DATA8,\ ++ HDMI_CEC_TX_DATA9, HDMI_CEC_TX_DATA10, HDMI_CEC_TX_DATA11,\ ++ HDMI_CEC_TX_DATA12, HDMI_CEC_TX_DATA13, HDMI_CEC_TX_DATA14,\ ++ HDMI_CEC_TX_DATA15}; ++ ++static int rx_reg[16] = {HDMI_CEC_RX_DATA0, HDMI_CEC_RX_DATA1, HDMI_CEC_RX_DATA2,\ ++ HDMI_CEC_RX_DATA3, HDMI_CEC_RX_DATA4, HDMI_CEC_RX_DATA5,\ ++ HDMI_CEC_RX_DATA6, HDMI_CEC_RX_DATA7, HDMI_CEC_RX_DATA8,\ ++ HDMI_CEC_RX_DATA9, HDMI_CEC_RX_DATA10, HDMI_CEC_RX_DATA11,\ ++ HDMI_CEC_RX_DATA12, HDMI_CEC_RX_DATA13, HDMI_CEC_RX_DATA14,\ ++ HDMI_CEC_RX_DATA15}; ++ ++ ++/* FIXME : get base address from resource */ ++static unsigned long hdmi_base = 0xf1ee0000; ++ ++void hdmi_writel(u32 value, unsigned int reg) ++{ ++ __raw_writel(value, hdmi_base + reg); ++} ++ ++u32 hdmi_readl(unsigned int reg) ++{ ++ u32 value; ++ ++ value = __raw_readl(hdmi_base + reg); ++ return value; ++} ++ ++u8 hdmi_readb(unsigned int reg) ++{ ++ u8 value; ++ ++ /* unlock read access */ ++ hdmi_writel(0x54524545, 0x10010); ++ value = __raw_readb(hdmi_base + reg); ++ return value; ++} ++ ++void hdmi_writeb(u8 value, unsigned int reg) ++{ ++ __raw_writeb(value, hdmi_base + reg); ++} ++ ++static int sunxi_hdmi_notify(struct notifier_block *nb, ++ unsigned long code, void *unused) ++{ ++ u8 val = 0; ++ struct hdmi_cec_event *event = NULL; ++ ++ if (open_count) { ++ switch (code) { ++ case 0x00: // Unplug ++ pr_info("[CEC]HDMI link disconnected\n"); ++ event = vmalloc(sizeof(struct hdmi_cec_event)); ++ if (NULL == event) { ++ pr_err("%s: Not enough memory!\n", __func__); ++ break; ++ } ++ memset(event, 0, sizeof(struct hdmi_cec_event)); ++ event->event_type = MESSAGE_TYPE_DISCONNECTED; ++ mutex_lock(&hdmi_cec_data.lock); ++ list_add_tail(&event->list, &head); ++ mutex_unlock(&hdmi_cec_data.lock); ++ wake_up(&hdmi_cec_queue); ++ break; ++ case 0x04: // Plug ++ pr_info("[CEC]HDMI link connected\n"); ++ event = vmalloc(sizeof(struct hdmi_cec_event)); ++ if (NULL == event) { ++ pr_err("%s: Not enough memory\n", __func__); ++ break; ++ } ++ memset(event, 0, sizeof(struct hdmi_cec_event)); ++ event->event_type = MESSAGE_TYPE_CONNECTED; ++ mutex_lock(&hdmi_cec_data.lock); ++ list_add_tail(&event->list, &head); ++ mutex_unlock(&hdmi_cec_data.lock); ++ wake_up(&hdmi_cec_queue); ++ break; ++ case 0x05: // reinit done ++ pr_info("[CEC]HDMI reinitialized\n"); ++ val = hdmi_readb(HDMI_MC_CLKDIS); ++ val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE; ++ hdmi_writeb(val, HDMI_MC_CLKDIS); ++ hdmi_writeb(0x02, HDMI_CEC_CTRL); ++ /* enable CEC receive */ ++ hdmi_writel(0x84, 0x1003c); ++ /* Force read unlock */ ++ hdmi_writeb(0x0, HDMI_CEC_LOCK); ++ val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE; ++ hdmi_writeb(val, HDMI_CEC_POLARITY); ++ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST; ++ hdmi_writeb(val, HDMI_CEC_MASK); ++ hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0); ++ hdmi_writeb(cec_l_addr_l, HDMI_CEC_ADDR_L); ++ hdmi_writeb(cec_l_addr_h, HDMI_CEC_ADDR_H); ++ break; ++ } ++ } ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block sunxi_hdmi_nb = { ++ .notifier_call = sunxi_hdmi_notify, ++}; ++ ++static int hdmi_cec_read_reg_bit(void) /* 1bit */ ++{ ++ return (hdmi_readl(0x1003c) >> 1) & 0x1; ++} ++ ++int hdmi_cec_wait_for_signal(int signal, u32 timeout) ++{ ++ u32 count_timeout = 0; ++ ++ while (hdmi_cec_read_reg_bit() != signal) ++ { ++ count_timeout++; ++ usleep_range(50,50); ++ // no change in time, timeout ++ if (count_timeout > timeout) ++ { ++ return -1; ++ } ++ } ++ return 0; ++} ++ ++int hdmi_cec_wait_bit(void) ++{ ++ // wait for lo ++ if (hdmi_cec_wait_for_signal(SIG_LO, 40)) ++ { ++ return -1; ++ } ++ ++ // wait for end of bit ++ usleep_range(1900,1900); ++ ++ // wait for falling edge ++ if (hdmi_cec_wait_for_signal(SIG_LO, 16)) ++ { ++ return -1; ++ } ++ return 0; ++} ++ ++int hdmi_cec_wait_for_startbit(void) ++{ ++ // wait for hi of startbit. If we arrive here, signal can be lo for 1600 - 3400 us ++ if (hdmi_cec_wait_for_signal(SIG_HI, 46)) ++ { ++ return -1; ++ } ++ // Wait for falling edge ++ usleep_range(700, 700); ++ ++ if (hdmi_cec_wait_for_signal(SIG_LO, 9)) ++ { ++ return -1; ++ } ++ return 0; ++} ++ ++int hdmi_cec_ack_msg(void) ++{ ++ u32 i; ++ ++ if (hdmi_cec_wait_for_startbit()) ++ { ++ return -1; ++ } ++ ++ while(1) ++ { ++ /* Wait for 8 data bits and EOM bit */ ++ for (i = 0; i < 9; i++) { ++ if(hdmi_cec_wait_bit()) ++ { ++ return -1; ++ } ++ } ++ ++ // Enable Sending for ACK bit ++ hdmi_writel(0x00, 0x1003c); ++ ++ // wait for end of ACK bit ++ usleep_range(1700,1700); ++ ++ // Disable Sending ++ hdmi_writel(0x84, 0x1003c); ++ } ++} ++ ++int rxack_thread(void *data) ++{ ++ count_lo = 0; ++ count_hi = 0; ++ while(1) ++ { ++ // get cec input ++ if (hdmi_cec_read_reg_bit() == SIG_HI) ++ { ++ count_hi++; ++ count_lo = 0; ++ } ++ else ++ { ++ count_lo++; ++ count_hi = 0; ++ } ++ ++ // maybe a startbit, try to receive message ++ if ((count_lo >= 2)&&(hdmi_readl(0x1003c)> 128)) ++ { ++ hdmi_cec_ack_msg(); ++ ++ count_lo = 0; ++ count_hi = 0; ++ } ++ ++ if (kthread_should_stop()) ++ { ++ return 0; ++ } ++ usleep_range(1600, 1700); ++ } ++} ++ ++static irqreturn_t hdmi_cec_isr(int irq, void *data) ++{ ++ struct hdmi_cec_priv *hdmi_cec = data; ++ u8 cec_stat; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&hdmi_cec->irq_lock, flags); ++ ++ hdmi_writeb(0x7f, HDMI_IH_MUTE_CEC_STAT0); ++ ++ cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0); ++ hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0); ++ if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \ ++ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \ ++ HDMI_IH_CEC_STAT0_DONE)) == 0) { ++ spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags); ++ return IRQ_HANDLED; ++ } ++ ++ /* disable CEC sending */ ++ if (!(cec_stat & HDMI_IH_CEC_STAT0_EOM)) ++ hdmi_writel(0x84, 0x1003c); ++ ++ /* FIXME : there is a race with latest_cec_stat */ ++ hdmi_cec->latest_cec_stat = cec_stat ; ++ ++ schedule_delayed_work(&(hdmi_cec->hdmi_cec_work), msecs_to_jiffies(5)); ++ ++ spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags); ++ ++ return IRQ_HANDLED; ++} ++ ++void hdmi_cec_handle(u16 cec_stat) ++{ ++ u8 val = 0, i = 0; ++ struct hdmi_cec_event *event = NULL; ++ /*The current transmission is successful (for initiator only).*/ ++ if (!open_count) ++ return; ++ ++ if (cec_stat & HDMI_IH_CEC_STAT0_DONE) { ++ ++ hdmi_cec_data.tx_answer = cec_stat; ++ wake_up(&tx_cec_queue); ++ } ++ /*EOM is detected so that the received data is ready in the receiver data buffer*/ ++ if (cec_stat & HDMI_IH_CEC_STAT0_EOM) { ++ event = vmalloc(sizeof(struct hdmi_cec_event)); ++ if (NULL == event) { ++ pr_err("%s: Not enough memory!\n", __func__); ++ return; ++ } ++ memset(event, 0, sizeof(struct hdmi_cec_event)); ++ event->msg_len = hdmi_readb(HDMI_CEC_RX_CNT); ++ if (!event->msg_len) { ++ pr_err("%s: Invalid CEC message length!\n", __func__); ++ return; ++ } ++ event->event_type = MESSAGE_TYPE_RECEIVE_SUCCESS; ++ for (i = 0; i < event->msg_len; i++) ++ event->msg[i] = hdmi_readb(rx_reg[i]); ++ hdmi_writeb(0x0, HDMI_CEC_LOCK); ++ mutex_lock(&hdmi_cec_data.lock); ++ list_add_tail(&event->list, &head); ++ if (hdmi_cec_data.msg_resend) { ++ cancel_delayed_work(&hdmi_cec_data.hdmi_cec_resend); ++ schedule_delayed_work(&hdmi_cec_data.hdmi_cec_resend, msecs_to_jiffies(50)); ++ } ++ mutex_unlock(&hdmi_cec_data.lock); ++ wake_up(&hdmi_cec_queue); ++ } ++ /*An error is detected on cec line (for initiator only). */ ++ if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_INIT) { ++ mutex_lock(&hdmi_cec_data.lock); ++ hdmi_cec_data.send_error++; ++ if (hdmi_cec_data.send_error > 2) { ++ pr_err("%s:Re-transmission is attempted more than 2 times!\n", __func__); ++ hdmi_cec_data.send_error = 0; ++ mutex_unlock(&hdmi_cec_data.lock); ++ hdmi_cec_data.tx_answer = cec_stat; ++ wake_up(&tx_cec_queue); ++ return; ++ } ++ for (i = 0; i < hdmi_cec_data.msg_len; i++) ++ hdmi_writeb(hdmi_cec_data.last_msg[i], tx_reg[i]); ++ hdmi_writeb(hdmi_cec_data.msg_len, HDMI_CEC_TX_CNT); ++ val = hdmi_readb(HDMI_CEC_CTRL); ++ val |= 0x01; ++ hdmi_writeb(val, HDMI_CEC_CTRL); ++ mutex_unlock(&hdmi_cec_data.lock); ++ } ++ /*A frame is not acknowledged in a directly addressed message. Or a frame is negatively acknowledged in ++ a broadcast message (for initiator only).*/ ++ if (cec_stat & HDMI_IH_CEC_STAT0_NACK) { ++ mutex_lock(&hdmi_cec_data.lock); ++ hdmi_cec_data.send_error++; ++ if (hdmi_cec_data.send_error < 2) { ++ hdmi_cec_data.msg_resend = true; ++ schedule_delayed_work(&hdmi_cec_data.hdmi_cec_resend, msecs_to_jiffies(20)); ++ } else { ++ hdmi_cec_data.tx_answer = cec_stat; ++ wake_up(&tx_cec_queue); ++ } ++ mutex_unlock(&hdmi_cec_data.lock); ++ } ++ /*An error is notified by a follower. Abnormal logic data bit error (for follower).*/ ++ if (cec_stat & HDMI_IH_CEC_STAT0_ERROR_FOLL) { ++ hdmi_cec_data.receive_error++; ++ } ++ return; ++} ++ ++static void hdmi_cec_worker(struct work_struct *work) ++{ ++ u8 val; ++ hdmi_cec_handle(hdmi_cec_data.latest_cec_stat); ++ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST; ++ hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0); ++} ++ ++static int hdmi_wait_free_cecline(void) ++{ ++ u32 count_timeout = 0; ++ ++ while (count_hi < 5) ++ { ++ count_timeout++; ++ usleep_range(2000,2200); ++ // no change in time, timeout ++ if (count_timeout > 500) ++ { ++ return -1; ++ } ++ } ++ return 0; ++} ++ ++static void hdmi_cec_resender(struct work_struct *work) ++{ ++ u8 val; ++ mutex_lock(&hdmi_cec_data.lock); ++ hdmi_cec_data.msg_resend = false; ++ mutex_unlock(&hdmi_cec_data.lock); ++ ++ /* FIXME : check return value */ ++ hdmi_wait_free_cecline(); ++ /* Enable Sending */ ++ hdmi_writel(0x00, 0x1003c); ++ ++ val = hdmi_readb(HDMI_CEC_CTRL); ++ val |= 0x01; ++ hdmi_writeb(val, HDMI_CEC_CTRL); ++} ++ ++/*! ++ * @brief open function for cec file operation ++ * ++ * @return 0 on success or negative error code on error ++ */ ++static int hdmi_cec_open(struct inode *inode, struct file *filp) ++{ ++ mutex_lock(&hdmi_cec_data.lock); ++ if (open_count) { ++ mutex_unlock(&hdmi_cec_data.lock); ++ return -EBUSY; ++ } ++ open_count = 1; ++ filp->private_data = (void *)(&hdmi_cec_data); ++ hdmi_cec_data.Logical_address = 15; ++ hdmi_cec_data.cec_state = false; ++ mutex_unlock(&hdmi_cec_data.lock); ++ return 0; ++} ++ ++static ssize_t hdmi_cec_read(struct file *file, char __user *buf, size_t count, ++ loff_t *ppos) ++{ ++ struct hdmi_cec_event *event = NULL; ++ ++ if (!open_count) ++ return -ENODEV; ++ mutex_lock(&hdmi_cec_data.lock); ++ if (false == hdmi_cec_data.cec_state) { ++ mutex_unlock(&hdmi_cec_data.lock); ++ return -EACCES; ++ } ++ ++ if (list_empty(&head)) { ++ if (file->f_flags & O_NONBLOCK) { ++ mutex_unlock(&hdmi_cec_data.lock); ++ return -EAGAIN; ++ } else { ++ do { ++ mutex_unlock(&hdmi_cec_data.lock); ++ if (wait_event_interruptible(hdmi_cec_queue, (!list_empty(&head)))) ++ return -ERESTARTSYS; ++ mutex_lock(&hdmi_cec_data.lock); ++ } while (list_empty(&head)); ++ } ++ } ++ ++ event = list_first_entry(&head, struct hdmi_cec_event, list); ++ list_del(&event->list); ++ mutex_unlock(&hdmi_cec_data.lock); ++ if (copy_to_user(buf, event, ++ sizeof(struct hdmi_cec_event) - sizeof(struct list_head))) { ++ vfree(event); ++ return -EFAULT; ++ } ++ vfree(event); ++ return (sizeof(struct hdmi_cec_event) - sizeof(struct list_head)); ++} ++ ++static ssize_t hdmi_cec_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ int ret = 0 , i = 0; ++ u8 msg[MAX_MESSAGE_LEN]; ++ u8 msg_len = 0, val = 0; ++ ++ if (!open_count) ++ return -ENODEV; ++ /* wait for free CEC line */ ++ ret = hdmi_wait_free_cecline(); ++ if (ret < 0) { ++ pr_err("[CEC]No free cec line detected.\n"); ++ ret = -ERESTARTSYS; ++ goto tx_out; ++ } ++ mutex_lock(&hdmi_cec_data.lock); ++ if (false == hdmi_cec_data.cec_state) { ++ mutex_unlock(&hdmi_cec_data.lock); ++ return -EACCES; ++ } ++ /* Ensure that there is only one writer who is the only listener of tx_cec_queue */ ++ if (hdmi_cec_data.tx_answer != CEC_TX_AVAIL) { ++ mutex_unlock(&hdmi_cec_data.lock); ++ return -EBUSY; ++ } ++ mutex_unlock(&hdmi_cec_data.lock); ++ if (count > MAX_MESSAGE_LEN) ++ return -EINVAL; ++ memset(&msg, 0, MAX_MESSAGE_LEN); ++ ret = copy_from_user(&msg, buf, count); ++ if (ret) ++ return -EACCES; ++ mutex_lock(&hdmi_cec_data.lock); ++ hdmi_cec_data.send_error = 0; ++ hdmi_cec_data.tx_answer = CEC_TX_INPROGRESS; ++ msg_len = count; ++ hdmi_writeb(msg_len, HDMI_CEC_TX_CNT); ++ for (i = 0; i < msg_len; i++) ++ hdmi_writeb(msg[i], tx_reg[i]); ++ ++ /* Enable Sending */ ++ hdmi_writel(0x00, 0x1003c); ++ ++ val = hdmi_readb(HDMI_CEC_CTRL); ++ val |= 0x01; ++ hdmi_writeb(val, HDMI_CEC_CTRL); ++ memcpy(hdmi_cec_data.last_msg, msg, msg_len); ++ hdmi_cec_data.msg_len = msg_len; ++ mutex_unlock(&hdmi_cec_data.lock); ++ ++ ret = wait_event_interruptible_timeout(tx_cec_queue, hdmi_cec_data.tx_answer != CEC_TX_INPROGRESS, HZ); ++ ++ if (ret < 0) { ++ ret = -ERESTARTSYS; ++ goto tx_out; ++ } ++ ++ if (hdmi_cec_data.tx_answer & HDMI_IH_CEC_STAT0_DONE) { ++ /* msg correctly sent */ ++ ret = msg_len; ++ } ++ else ++ ret = -EIO; ++ ++ tx_out: ++ hdmi_cec_data.tx_answer = CEC_TX_AVAIL; ++ return ret; ++} ++ ++ ++static void hdmi_stop_device(void) ++{ ++ u8 val; ++ ++ hdmi_writeb(0x10, HDMI_CEC_CTRL); ++ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_ARB_LOST | \ ++ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE; ++ hdmi_writeb(val, HDMI_CEC_MASK); ++ hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0); ++ hdmi_writeb(0x0, HDMI_CEC_POLARITY); ++ val = hdmi_readb(HDMI_MC_CLKDIS); ++ val |= HDMI_MC_CLKDIS_CECCLK_DISABLE; ++ hdmi_writeb(val, HDMI_MC_CLKDIS); ++ mutex_lock(&hdmi_cec_data.lock); ++ hdmi_cec_data.cec_state = false; ++ mutex_unlock(&hdmi_cec_data.lock); ++ if (rxack_task != NULL){ ++ kthread_stop(rxack_task); ++ rxack_task = NULL; ++ } ++} ++ ++/*! ++ * @brief IO ctrl function for cec file operation ++ * @param cmd IO ctrl command ++ * @return 0 on success or negative error code on error ++ */ ++static long hdmi_cec_ioctl(struct file *filp, u_int cmd, ++ u_long arg) ++{ ++ int ret = 0, status = 0; ++ u8 val = 0; ++ if (!open_count) ++ return -ENODEV; ++ switch (cmd) { ++ case HDMICEC_IOC_SETLOGICALADDRESS: ++ mutex_lock(&hdmi_cec_data.lock); ++ if (false == hdmi_cec_data.cec_state) { ++ mutex_unlock(&hdmi_cec_data.lock); ++ pr_err("[CEC]Trying to set logical address while not started.\n"); ++ return -EACCES; ++ } ++ hdmi_cec_data.Logical_address = (u8)arg; ++ if (hdmi_cec_data.Logical_address <= 7) { ++ cec_l_addr_l = 1 << hdmi_cec_data.Logical_address; ++ cec_l_addr_h = 0; ++ } else if (hdmi_cec_data.Logical_address > 7 && hdmi_cec_data.Logical_address <= 15) { ++ cec_l_addr_l = 0; ++ cec_l_addr_h = 1 << (hdmi_cec_data.Logical_address - 8); ++ } else{ ++ mutex_unlock(&hdmi_cec_data.lock); ++ ret = -EINVAL; ++ } ++ hdmi_writeb(cec_l_addr_l, HDMI_CEC_ADDR_L); ++ hdmi_writeb(cec_l_addr_h, HDMI_CEC_ADDR_H); ++ mutex_unlock(&hdmi_cec_data.lock); ++ break; ++ case HDMICEC_IOC_STARTDEVICE: ++ val = hdmi_readb(HDMI_MC_CLKDIS); ++ val &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE; ++ hdmi_writeb(val, HDMI_MC_CLKDIS); ++ ++ hdmi_writeb(0x02, HDMI_CEC_CTRL); ++ /* enable CEC receive */ ++ hdmi_writel(0x84, 0x1003c); ++ /* Force read unlock */ ++ hdmi_writeb(0x0, HDMI_CEC_LOCK); ++ val = HDMI_IH_CEC_STAT0_ERROR_INIT | HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | HDMI_IH_CEC_STAT0_DONE; ++ hdmi_writeb(val, HDMI_CEC_POLARITY); ++ val = HDMI_IH_CEC_STAT0_WAKEUP | HDMI_IH_CEC_STAT0_ERROR_FOLL | HDMI_IH_CEC_STAT0_ARB_LOST; ++ hdmi_writeb(val, HDMI_CEC_MASK); ++ hdmi_writeb(val, HDMI_IH_MUTE_CEC_STAT0); ++ hdmi_cec_data.link_status = hdmi_readb(HDMI_PHY_STAT0) & 0x02; ++ mutex_lock(&hdmi_cec_data.lock); ++ hdmi_cec_data.cec_state = true; ++ mutex_unlock(&hdmi_cec_data.lock); ++ if (rxack_task == NULL) ++ rxack_task = kthread_run(rxack_thread,NULL,"cec_rxack"); ++ break; ++ case HDMICEC_IOC_STOPDEVICE: ++ hdmi_stop_device(); ++ break; ++ case HDMICEC_IOC_GETPHYADDRESS: ++ status = copy_to_user((void __user *)arg, ++ &cec_phy_addr, ++ sizeof(u32)); ++ if (status) ++ ret = -EFAULT; ++ break; ++ default: ++ ret = -EINVAL; ++ break; ++ } ++ return ret; ++} ++ ++/*! ++ * @brief Release function for cec file operation ++ * @return 0 on success or negative error code on error ++ */ ++static int hdmi_cec_release(struct inode *inode, struct file *filp) ++{ ++ mutex_lock(&hdmi_cec_data.lock); ++ if (open_count) { ++ open_count = 0; ++ hdmi_cec_data.cec_state = false; ++ hdmi_cec_data.Logical_address = 15; ++ } ++ mutex_unlock(&hdmi_cec_data.lock); ++ ++ return 0; ++} ++ ++static unsigned int hdmi_cec_poll(struct file *file, poll_table *wait) ++{ ++ unsigned int mask = 0; ++ ++ poll_wait(file, &hdmi_cec_queue, wait); ++ ++ /* Always writable */ ++ mask = (POLLOUT | POLLWRNORM); ++ mutex_lock(&hdmi_cec_data.lock); ++ if (!list_empty(&head)) ++ mask |= (POLLIN | POLLRDNORM); ++ mutex_unlock(&hdmi_cec_data.lock); ++ return mask; ++} ++ ++ ++const struct file_operations hdmi_cec_fops = { ++ .owner = THIS_MODULE, ++ .read = hdmi_cec_read, ++ .write = hdmi_cec_write, ++ .open = hdmi_cec_open, ++ .unlocked_ioctl = hdmi_cec_ioctl, ++ .release = hdmi_cec_release, ++ .poll = hdmi_cec_poll, ++}; ++ ++static int __init hdmi_cec_init(void) ++{ ++ int err = 0; ++ /* FIXME : get IRQ from resource */ ++ u32 irqhdmi = 120; ++ struct device *temp_class; ++ ++ hdmi_cec_major = register_chrdev(hdmi_cec_major, "sunxi_hdmi_cec", &hdmi_cec_fops); ++ if (hdmi_cec_major < 0) { ++ pr_err("hdmi_cec: unable to get a major for HDMI CEC\n"); ++ err = -EBUSY; ++ goto out; ++ } ++ ++ spin_lock_init(&hdmi_cec_data.irq_lock); ++ hdmi_cec_data.cec_irq = irqhdmi; ++ ++ err = request_irq(hdmi_cec_data.cec_irq, hdmi_cec_isr, IRQF_SHARED, ++ "sunxi_hdmi_cec", &hdmi_cec_data); ++ if (err < 0) { ++ pr_err("hdmi_cec:Unable to request irq: %d\n", err); ++ goto err_out_chrdev; ++ } ++ ++ hdmi_cec_class = class_create(THIS_MODULE, "sunxi_hdmi_cec"); ++ if (IS_ERR(hdmi_cec_class)) { ++ err = PTR_ERR(hdmi_cec_class); ++ goto err_out_chrdev; ++ } ++ ++ temp_class = device_create(hdmi_cec_class, NULL, MKDEV(hdmi_cec_major, 0), ++ NULL, "sunxi_hdmi_cec"); ++ if (IS_ERR(temp_class)) { ++ err = PTR_ERR(temp_class); ++ goto err_out_class; ++ } ++ ++ init_waitqueue_head(&hdmi_cec_queue); ++ init_waitqueue_head(&tx_cec_queue); ++ ++ INIT_LIST_HEAD(&head); ++ ++ mutex_init(&hdmi_cec_data.lock); ++ hdmi_cec_data.Logical_address = 15; ++ hdmi_cec_data.tx_answer = CEC_TX_AVAIL; ++ INIT_DELAYED_WORK(&hdmi_cec_data.hdmi_cec_work, hdmi_cec_worker); ++ INIT_DELAYED_WORK(&hdmi_cec_data.hdmi_cec_resend, hdmi_cec_resender); ++ register_sunxi_hdmi_notifier(&sunxi_hdmi_nb); ++ printk(KERN_INFO "HDMI CEC initialized\n"); ++ goto out; ++ ++err_out_class: ++ device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0)); ++ class_destroy(hdmi_cec_class); ++err_out_chrdev: ++ unregister_chrdev(hdmi_cec_major, "sunxi_hdmi_cec"); ++out: ++ return err; ++} ++ ++static void __exit hdmi_cec_exit(void) ++{ ++ unregister_sunxi_hdmi_notifier(&sunxi_hdmi_nb); ++ ++ if (hdmi_cec_data.cec_irq > 0) ++ free_irq(hdmi_cec_data.cec_irq, &hdmi_cec_data); ++ ++ if (hdmi_cec_major > 0) { ++ device_destroy(hdmi_cec_class, MKDEV(hdmi_cec_major, 0)); ++ class_destroy(hdmi_cec_class); ++ unregister_chrdev(hdmi_cec_major, "sunxi_hdmi_cec"); ++ hdmi_cec_major = 0; ++ } ++ ++ return; ++} ++ ++MODULE_AUTHOR("Joachim Damm"); ++MODULE_DESCRIPTION("Linux HDMI CEC driver for Allwiner H3"); ++MODULE_LICENSE("GPL"); ++ ++late_initcall(hdmi_cec_init); ++module_exit(hdmi_cec_exit); +diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.h b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.h +new file mode 100644 +index 0000000..0b10006 +--- /dev/null ++++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_cec.h +@@ -0,0 +1,39 @@ ++/* ++ * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved. ++ */ ++ ++/* ++ * The code contained herein is licensed under the GNU General Public ++ * License. You may obtain a copy of the GNU General Public License ++ * Version 2 or later at the following locations: ++ * ++ * http://www.opensource.org/licenses/gpl-license.html ++ * http://www.gnu.org/copyleft/gpl.html ++ */ ++#ifndef _HDMI_CEC_H_ ++#define _HDMI_CEC_H_ ++#include /* needed for the _IOW etc stuff used later */ ++ ++/* ++ * Ioctl definitions ++ */ ++ ++/* Use 'k' as magic number */ ++#define HDMICEC_IOC_MAGIC 'H' ++/* ++ * S means "Set" through a ptr, ++ * T means "Tell" directly with the argument value ++ * G means "Get": reply by setting through a pointer ++ * Q means "Query": response is on the return value ++ * X means "eXchange": G and S atomically ++ * H means "sHift": T and Q atomically ++ */ ++#define HDMICEC_IOC_SETLOGICALADDRESS _IOW(HDMICEC_IOC_MAGIC, 1, unsigned char) ++#define HDMICEC_IOC_STARTDEVICE _IO(HDMICEC_IOC_MAGIC, 2) ++#define HDMICEC_IOC_STOPDEVICE _IO(HDMICEC_IOC_MAGIC, 3) ++#define HDMICEC_IOC_GETPHYADDRESS _IOR(HDMICEC_IOC_MAGIC, 4, unsigned char[4]) ++ ++#define SIG_LO 0X0 ++#define SIG_HI 0X1 ++ ++#endif /* !_HDMI_CEC_H_ */ +diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c +index 2f3820c..afa446d 100755 +--- a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c ++++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_core.c +@@ -1,4 +1,5 @@ + #include "hdmi_core.h" ++#include "../drv_hdmi_i.h" + + static __s32 hdmi_state = HDMI_State_Idle; + static __u32 video_on = 0; +@@ -142,6 +143,7 @@ __s32 hdmi_main_task_loop(void) + video_on = 0; + audio_on = 0; + Hdmi_hpd_event(); ++ sunxi_hdmi_notifier_call_chain(hdmi_state); + } + + if((times++) >= 10) { +@@ -164,6 +166,8 @@ __s32 hdmi_main_task_loop(void) + if(HPD) { + hdmi_state = HDMI_State_EDID_Parse; + __inf("plugin\n"); ++ sunxi_hdmi_notifier_call_chain(hdmi_state); ++ + } else { + return 0; + } +@@ -177,7 +181,7 @@ __s32 hdmi_main_task_loop(void) + Hdmi_hpd_event(); + if(video_enable) + set_video_enable(true); +- ++ sunxi_hdmi_notifier_call_chain(hdmi_state); + case HDMI_State_HPD_Done: + //__inf("HDMI_State_HPD_Done\n"); + if(video_on && hdcp_enable) +@@ -518,6 +522,5 @@ __s32 video_enter_lp(void) + __s32 video_exit_lp(void) + { + bsp_hdmi_init(); +- + return 0; + } +diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.c b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.c +index 71ae0d3..d41b986 100755 +--- a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.c ++++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.c +@@ -6,6 +6,8 @@ __s32 is_exp = 0; + __u32 rgb_only = 0; + __u8 EDID_Buf[HDMI_EDID_LEN]; + __u8 Device_Support_VIC[512]; ++__u32 cec_phy_addr; ++EXPORT_SYMBOL(cec_phy_addr); + + static __u8 exp0[16] = + { +@@ -247,6 +249,9 @@ static __s32 Parse_HDMI_VSDB(__u8 * pbuf,__u8 size) + return 0; + } + ++ /* set cec phy addr */ ++ cec_phy_addr = (((__u32)pbuf[3]) << 8) | pbuf[4]; ++ + if(size <=8) + return 0; + +diff --git a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.h b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.h +index 3d35eeb..01743c4 100755 +--- a/drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.h ++++ b/drivers/video/sunxi/disp2/hdmi/aw/hdmi_edid.h +@@ -1,23 +1,25 @@ +-#ifndef __HDMI_EDID_H_ +-#define __HDMI_EDID_H_ +- +-#define Abort_Current_Operation 0 +-#define Special_Offset_Address_Read 1 +-#define Explicit_Offset_Address_Write 2 +-#define Implicit_Offset_Address_Write 3 +-#define Explicit_Offset_Address_Read 4 +-#define Implicit_Offset_Address_Read 5 +-#define Explicit_Offset_Address_E_DDC_Read 6 +-#define Implicit_Offset_Address_E_DDC_Read 7 +- +-//extern __u8 EDID_Buf[1024]; +-extern __u8 Device_Support_VIC[512]; +-extern __s32 ParseEDID(void); +-//extern __s32 DDC_Read(char cmd,char pointer,char offset,int nbyte,char * pbuf); +-//extern void DDC_Init(void); +-//extern void send_ini_sequence(void); +-extern __u32 GetIsHdmi(void); +-extern __u32 GetIsYUV(void); ++#ifndef __HDMI_EDID_H_ ++#define __HDMI_EDID_H_ ++ ++#define Abort_Current_Operation 0 ++#define Special_Offset_Address_Read 1 ++#define Explicit_Offset_Address_Write 2 ++#define Implicit_Offset_Address_Write 3 ++#define Explicit_Offset_Address_Read 4 ++#define Implicit_Offset_Address_Read 5 ++#define Explicit_Offset_Address_E_DDC_Read 6 ++#define Implicit_Offset_Address_E_DDC_Read 7 ++ ++ ++extern __u32 cec_phy_addr; ++//extern __u8 EDID_Buf[1024]; ++extern __u8 Device_Support_VIC[512]; ++extern __s32 ParseEDID(void); ++//extern __s32 DDC_Read(char cmd,char pointer,char offset,int nbyte,char * pbuf); ++//extern void DDC_Init(void); ++//extern void send_ini_sequence(void); ++extern __u32 GetIsHdmi(void); ++extern __u32 GetIsYUV(void); + extern __s32 GetEdidInfo(void); +- ++ + #endif //__HDMI_EDID_H_ +\ No newline at end of file +diff --git a/drivers/video/sunxi/disp2/hdmi/drv_hdmi.c b/drivers/video/sunxi/disp2/hdmi/drv_hdmi.c +index bfd1a3a..bd0a49e 100755 +--- a/drivers/video/sunxi/disp2/hdmi/drv_hdmi.c ++++ b/drivers/video/sunxi/disp2/hdmi/drv_hdmi.c +@@ -32,6 +32,25 @@ static bool b_hdmi_suspend; + static bool b_hdmi_suspend_pre; + __s32 Hdmi_suspend(void); + __s32 Hdmi_resume(void); ++static BLOCKING_NOTIFIER_HEAD(sunxi_hdmi_notifier_list); ++ ++int register_sunxi_hdmi_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_register(&sunxi_hdmi_notifier_list, nb); ++} ++EXPORT_SYMBOL(register_sunxi_hdmi_notifier); ++ ++int unregister_sunxi_hdmi_notifier(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_unregister(&sunxi_hdmi_notifier_list, nb); ++} ++EXPORT_SYMBOL(unregister_sunxi_hdmi_notifier); ++ ++int sunxi_hdmi_notifier_call_chain(unsigned long val) ++{ ++ int ret = blocking_notifier_call_chain(&sunxi_hdmi_notifier_list, val, NULL); ++ return ret; ++} + + void hdmi_delay_ms(__u32 t) + { +diff --git a/drivers/video/sunxi/disp2/hdmi/drv_hdmi_i.h b/drivers/video/sunxi/disp2/hdmi/drv_hdmi_i.h +index 23b8b0d..163fead 100755 +--- a/drivers/video/sunxi/disp2/hdmi/drv_hdmi_i.h ++++ b/drivers/video/sunxi/disp2/hdmi/drv_hdmi_i.h +@@ -64,6 +64,9 @@ __s32 Hdmi_get_hdcp_enable(void); + __s32 Hdmi_get_video_timming_info(disp_video_timings **video_info); + int Hdmi_get_video_info_index(u32 mode_id); + __s32 Hdmi_get_input_csc(void); ++int register_sunxi_hdmi_notifier(struct notifier_block *nb); ++int unregister_sunxi_hdmi_notifier(struct notifier_block *nb); ++extern int sunxi_hdmi_notifier_call_chain(unsigned long val); + + extern __s32 hdmi_i2c_add_driver(void); + extern __s32 hdmi_i2c_del_driver(void); +-- +2.9.0 + diff --git a/projects/H3/patches/linux/linux-009-no_dev_console.patch b/projects/H3/patches/linux/linux-009-no_dev_console.patch new file mode 100644 index 00000000000..b2d72cf8621 --- /dev/null +++ b/projects/H3/patches/linux/linux-009-no_dev_console.patch @@ -0,0 +1,21 @@ +diff --git a/init/main.c b/init/main.c +index 9484f4b..db55edd 100644 +--- a/init/main.c ++++ b/init/main.c +@@ -880,8 +880,14 @@ static noinline void __init kernel_init_freeable(void) + do_basic_setup(); + + /* Open the /dev/console on the rootfs, this should never fail */ +- if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) +- printk(KERN_WARNING "Warning: unable to open an initial console.\n"); ++ char *console = "/dev_console"; ++ ++ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) { ++ sys_mknod(console, S_IFCHR|0600, (TTYAUX_MAJOR<<8)|1); ++ if (sys_open(console, O_RDWR, 0) < 0) ++ printk(KERN_WARNING "Warning: unable to open an initial console.\n"); ++ sys_unlink(console); ++ } + + (void) sys_dup(0); + (void) sys_dup(0); diff --git a/projects/H3/patches/linux/linux-010-disp2-enable-vsync.patch b/projects/H3/patches/linux/linux-010-disp2-enable-vsync.patch new file mode 100644 index 00000000000..15667f1b1d6 --- /dev/null +++ b/projects/H3/patches/linux/linux-010-disp2-enable-vsync.patch @@ -0,0 +1,23 @@ +--- a/drivers/video/sunxi/disp2/disp/dev_fb.c 2015-01-27 03:29:32.000000000 +0100 ++++ b/drivers/video/sunxi/disp2/disp/dev_fb.c 2015-12-28 10:45:14.276418445 +0100 +@@ -874,7 +874,7 @@ + + case FBIO_WAITFORVSYNC: + { +- //ret = fb_wait_for_vsync(info); ++ ret = fb_wait_for_vsync(info); + break; + } + +diff -Nur a/drivers/video/sunxi/disp2/disp/dev_disp.c b/drivers/video/sunxi/disp2/disp/dev_disp.c +--- a/drivers/video/sunxi/disp2/disp/dev_disp.c 2016-04-12 12:21:19.000000000 +0200 ++++ b/drivers/video/sunxi/disp2/disp/dev_disp.c 2016-05-23 22:06:41.937693271 +0200 +@@ -932,7 +932,7 @@ + } + + para->disp_int_process = disp_sync_finish_process; +- //para->vsync_event = drv_disp_vsync_event; ++ para->vsync_event = drv_disp_vsync_event; + para->start_process = start_process; + //para.capture_event = capture_event; + diff --git a/projects/H3/patches/linux/linux-011-usb-updates.patch b/projects/H3/patches/linux/linux-011-usb-updates.patch new file mode 100644 index 00000000000..44e740ae629 --- /dev/null +++ b/projects/H3/patches/linux/linux-011-usb-updates.patch @@ -0,0 +1,785 @@ +diff -Nur linux-igor/drivers/usb/gadget/uvc_v4l2.c tinaos/drivers/usb/gadget/uvc_v4l2.c +--- linux-igor/drivers/usb/gadget/uvc_v4l2.c 2016-10-11 16:01:24.043603681 +0200 ++++ tinaos/drivers/usb/gadget/uvc_v4l2.c 2016-10-11 12:23:23.970089995 +0200 +@@ -137,19 +137,26 @@ + handle->device = &uvc->video; + file->private_data = &handle->vfh; + ++#ifndef CONFIG_USB_SUNXI_G_WEBCAM + uvc_function_connect(uvc); ++#endif ++ + return 0; + } + + static int + uvc_v4l2_release(struct file *file) + { ++#ifndef CONFIG_USB_SUNXI_G_WEBCAM + struct video_device *vdev = video_devdata(file); + struct uvc_device *uvc = video_get_drvdata(vdev); ++#endif + struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data); + struct uvc_video *video = handle->device; + ++#ifndef CONFIG_USB_SUNXI_G_WEBCAM + uvc_function_disconnect(uvc); ++#endif + + uvc_video_enable(video, 0); + mutex_lock(&video->queue.mutex); +diff -Nur linux-igor/drivers/usb/host/ehci_sunxi.c tinaos/drivers/usb/host/ehci_sunxi.c +--- linux-igor/drivers/usb/host/ehci_sunxi.c 2016-10-11 16:01:24.046937014 +0200 ++++ tinaos/drivers/usb/host/ehci_sunxi.c 2016-10-11 12:23:23.973423329 +0200 +@@ -423,7 +423,7 @@ + { + + sunxi_ehci->set_usbc_regulator(sunxi_ehci, 1); +-#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN9IW1) ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN9IW1) + sunxi_ehci->hci_phy_ctrl(sunxi_ehci, 1); + #endif + open_ehci_clock(sunxi_ehci); +@@ -438,7 +438,7 @@ + sunxi_ehci_port_configure(sunxi_ehci, 0); + sunxi_ehci->usb_passby(sunxi_ehci, 0); + close_ehci_clock(sunxi_ehci); +-#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN9IW1) ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN9IW1) + sunxi_ehci->hci_phy_ctrl(sunxi_ehci, 0); + #endif + sunxi_ehci->set_usbc_regulator(sunxi_ehci, 0); +diff -Nur linux-igor/drivers/usb/host/ohci-hcd.c tinaos/drivers/usb/host/ohci-hcd.c +--- linux-igor/drivers/usb/host/ohci-hcd.c 2016-10-11 16:01:24.050270348 +0200 ++++ tinaos/drivers/usb/host/ohci-hcd.c 2016-10-11 12:23:23.980089996 +0200 +@@ -924,8 +924,8 @@ + if (quirk_nec(ohci)) + flush_work_sync(&ohci->nec_work); + +- ohci_usb_reset (ohci); + ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); ++ ohci_usb_reset (ohci); + free_irq(hcd->irq, hcd); + hcd->irq = 0; + +diff -Nur linux-igor/drivers/usb/host/sunxi_hci.c tinaos/drivers/usb/host/sunxi_hci.c +--- linux-igor/drivers/usb/host/sunxi_hci.c 2016-10-11 16:01:24.053603680 +0200 ++++ tinaos/drivers/usb/host/sunxi_hci.c 2016-10-11 12:23:23.983423329 +0200 +@@ -531,16 +531,22 @@ + static s32 request_usb_regulator_io(struct sunxi_hci_hcd *sunxi_hci) + { + if(sunxi_hci->regulator_io != NULL){ +- sunxi_hci->regulator_io_hdle= regulator_get(NULL, sunxi_hci->regulator_io); ++ sunxi_hci->regulator_io_hdle = regulator_get(NULL, sunxi_hci->regulator_io); + if(IS_ERR(sunxi_hci->regulator_io_hdle)) { + DMSG_PANIC("ERR: some error happen, %s,regulator_io_hdle fail to get regulator!", sunxi_hci->hci_name); ++ sunxi_hci->regulator_io_hdle = NULL; + return 0; + } ++ } + +- if(regulator_set_voltage(sunxi_hci->regulator_io_hdle , sunxi_hci->regulator_value, sunxi_hci->regulator_value) < 0 ){ +- DMSG_PANIC("ERR: regulator_set_voltage: %s fail\n",sunxi_hci->hci_name); +- regulator_put(sunxi_hci->regulator_io_hdle); +- return 0; ++ if(sunxi_hci->hsic_flag){ ++ if(sunxi_hci->hsic_regulator_io != NULL){ ++ sunxi_hci->hsic_regulator_io_hdle = regulator_get(NULL, sunxi_hci->hsic_regulator_io); ++ if(IS_ERR(sunxi_hci->hsic_regulator_io_hdle)) { ++ DMSG_PANIC("ERR: some error happen, %s, hsic_regulator_io_hdle fail to get regulator!", sunxi_hci->hci_name); ++ sunxi_hci->hsic_regulator_io_hdle = NULL; ++ return 0; ++ } + } + } + +@@ -552,6 +558,13 @@ + if(sunxi_hci->regulator_io != NULL){ + regulator_put(sunxi_hci->regulator_io_hdle); + } ++ ++ if(sunxi_hci->hsic_flag){ ++ if(sunxi_hci->hsic_regulator_io != NULL){ ++ regulator_put(sunxi_hci->hsic_regulator_io_hdle); ++ } ++ } ++ + return 0; + } + +@@ -614,6 +627,9 @@ + sunxi_hci->not_suspend = 0; + } + ++ sunxi_hci->hsic_flag = 0; ++ ++#if defined (CONFIG_ARCH_SUN8IW3) || defined (CONFIG_ARCH_SUN8IW5) || defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW9) + type = script_get_item(usbc_name[sunxi_hci->usbc_no], "usb_hsic_used", &item_temp); + if(type == SCIRPT_ITEM_VALUE_TYPE_INT){ + sunxi_hci->hsic_flag = item_temp.val; +@@ -623,7 +639,21 @@ + } + + if(sunxi_hci->hsic_flag){ +- /* usb hisc ctrl */ ++ /* get HSIC regulator io information */ ++ type = script_get_item(usbc_name[sunxi_hci->usbc_no], "usb_hsic_regulator_io", &item_temp); ++ if (type == SCIRPT_ITEM_VALUE_TYPE_STR) { ++ if (!strcmp(item_temp.str, "nocare")) { ++ DMSG_INFO("get usb_regulator is nocare\n"); ++ sunxi_hci->hsic_regulator_io = NULL; ++ }else{ ++ sunxi_hci->hsic_regulator_io = item_temp.str; ++ } ++ }else { ++ DMSG_INFO("get usb_hsic_regulator is failed\n"); ++ sunxi_hci->regulator_io = NULL; ++ } ++ ++ /* Marvell 4G HSIC ctrl*/ + type = script_get_item(usbc_name[sunxi_hci->usbc_no], "usb_hsic_ctrl", &item_temp); + if(type == SCIRPT_ITEM_VALUE_TYPE_INT){ + sunxi_hci->hsic_ctrl_flag = item_temp.val; +@@ -639,10 +669,43 @@ + }else{ + sunxi_hci->usb_host_hsic_rdy_valid = 0; + } ++ ++ /* SMSC usb3503 HSIC HUB ctrl */ ++ type = script_get_item(usbc_name[sunxi_hci->usbc_no], "usb_hsic_usb3503_flag", &item_temp); ++ if(type == SCIRPT_ITEM_VALUE_TYPE_INT){ ++ sunxi_hci->usb_hsic_usb3503_flag = item_temp.val; ++ }else{ ++ DMSG_INFO("get usb_restrict_flag failed\n"); ++ sunxi_hci->usb_hsic_usb3503_flag = 0; ++ } ++ ++ type = script_get_item(usbc_name[sunxi_hci->usbc_no], "usb_hsic_hub_connect_gpio", &sunxi_hci->usb_hsic_hub_connect); ++ if(type == SCIRPT_ITEM_VALUE_TYPE_PIO){ ++ sunxi_hci->usb_hsic_hub_connect_valid = 1; ++ }else{ ++ sunxi_hci->usb_hsic_hub_connect_valid = 0; ++ } ++ ++ type = script_get_item(usbc_name[sunxi_hci->usbc_no], "usb_hsic_int_n_gpio", &sunxi_hci->usb_hsic_int_n); ++ if(type == SCIRPT_ITEM_VALUE_TYPE_PIO){ ++ sunxi_hci->usb_hsic_int_n_valid = 1; ++ }else{ ++ sunxi_hci->usb_hsic_int_n_valid = 0; ++ } ++ ++ type = script_get_item(usbc_name[sunxi_hci->usbc_no], "usb_hsic_reset_n_gpio", &sunxi_hci->usb_hsic_reset_n); ++ if(type == SCIRPT_ITEM_VALUE_TYPE_PIO){ ++ sunxi_hci->usb_hsic_reset_n_valid = 1; ++ }else{ ++ sunxi_hci->usb_hsic_reset_n_valid = 0; ++ } ++ + }else{ + sunxi_hci->hsic_ctrl_flag = 0; + sunxi_hci->usb_host_hsic_rdy_valid = 0; ++ sunxi_hci->usb_hsic_usb3503_flag = 0; + } ++#endif + + /* get regulator io information */ + type = script_get_item(usbc_name[sunxi_hci->usbc_no], "usb_regulator_io", &item_temp); +@@ -652,14 +715,6 @@ + sunxi_hci->regulator_io = NULL; + }else{ + sunxi_hci->regulator_io = item_temp.str; +- +- type = script_get_item(usbc_name[sunxi_hci->usbc_no], "usb_regulator_vol", &item_temp); +- if(type == SCIRPT_ITEM_VALUE_TYPE_INT){ +- sunxi_hci->regulator_value = item_temp.val; +- }else{ +- DMSG_INFO("get usb_voltage is failed\n"); +- sunxi_hci->regulator_value = 0; +- } + } + }else { + DMSG_INFO("get usb_regulator is failed\n"); +@@ -1715,13 +1770,54 @@ + } + } + +- if(sunxi_hci->usb_host_hsic_rdy_valid){ +- ret = gpio_request(sunxi_hci->usb_host_hsic_rdy.gpio.gpio, NULL); +- if(ret != 0){ +- DMSG_PANIC("ERR: gpio_request failed\n"); +- sunxi_hci->usb_host_hsic_rdy_valid = 0; +- }else{ +- gpio_direction_output(sunxi_hci->usb_host_hsic_rdy.gpio.gpio, 0); ++ if(sunxi_hci->hsic_flag){ ++ /* Marvell 4G HSIC ctrl*/ ++ if(sunxi_hci->usb_host_hsic_rdy_valid){ ++ ret = gpio_request(sunxi_hci->usb_host_hsic_rdy.gpio.gpio, NULL); ++ if(ret != 0){ ++ DMSG_PANIC("ERR: gpio_request failed\n"); ++ sunxi_hci->usb_host_hsic_rdy_valid = 0; ++ }else{ ++ gpio_direction_output(sunxi_hci->usb_host_hsic_rdy.gpio.gpio, 0); ++ } ++ } ++ ++ /* SMSC usb3503 HSIC HUB ctrl */ ++ if(sunxi_hci->usb_hsic_usb3503_flag){ ++ if(sunxi_hci->usb_hsic_hub_connect_valid){ ++ ret = gpio_request(sunxi_hci->usb_hsic_hub_connect.gpio.gpio, NULL); ++ if(ret != 0){ ++ DMSG_PANIC("ERR: gpio_request failed\n"); ++ sunxi_hci->usb_hsic_hub_connect_valid = 0; ++ }else{ ++ gpio_direction_output(sunxi_hci->usb_hsic_hub_connect.gpio.gpio, 1); ++ } ++ } ++ ++ if(sunxi_hci->usb_hsic_int_n_valid){ ++ ret = gpio_request(sunxi_hci->usb_hsic_int_n.gpio.gpio, NULL); ++ if(ret != 0){ ++ DMSG_PANIC("ERR: gpio_request failed\n"); ++ sunxi_hci->usb_hsic_int_n_valid = 0; ++ }else{ ++ gpio_direction_output(sunxi_hci->usb_hsic_int_n.gpio.gpio, 1); ++ } ++ } ++ ++ msleep(10); ++ ++ if(sunxi_hci->usb_hsic_reset_n_valid){ ++ ret = gpio_request(sunxi_hci->usb_hsic_reset_n.gpio.gpio, NULL); ++ if(ret != 0){ ++ DMSG_PANIC("ERR: gpio_request failed\n"); ++ sunxi_hci->usb_hsic_reset_n_valid = 0; ++ }else{ ++ gpio_direction_output(sunxi_hci->usb_hsic_reset_n.gpio.gpio, 1); ++ } ++ } ++ ++ /* usb3503 device goto hub connect statua is need 100ms after reset */ ++ msleep(100); + } + } + return 0; +@@ -1743,25 +1839,44 @@ + gpio_free(sunxi_hci->usb_host_hsic_rdy.gpio.gpio); + sunxi_hci->drv_vbus_gpio_valid = 0; + } ++ ++ if(sunxi_hci->hsic_flag){ ++ /* Marvell 4G HSIC ctrl*/ ++ if(sunxi_hci->usb_host_hsic_rdy_valid){ ++ gpio_free(sunxi_hci->usb_host_hsic_rdy.gpio.gpio); ++ sunxi_hci->usb_host_hsic_rdy_valid = 0; ++ } ++ ++ /* SMSC usb3503 HSIC HUB ctrl */ ++ if(sunxi_hci->usb_hsic_usb3503_flag){ ++ if(sunxi_hci->usb_hsic_hub_connect_valid){ ++ gpio_free(sunxi_hci->usb_hsic_hub_connect.gpio.gpio); ++ sunxi_hci->usb_hsic_hub_connect_valid = 0; ++ } ++ ++ if(sunxi_hci->usb_hsic_int_n_valid){ ++ gpio_free(sunxi_hci->usb_hsic_int_n.gpio.gpio); ++ sunxi_hci->usb_hsic_int_n_valid = 0; ++ } ++ ++ if(sunxi_hci->usb_hsic_reset_n_valid){ ++ gpio_free(sunxi_hci->usb_hsic_reset_n.gpio.gpio); ++ sunxi_hci->usb_hsic_reset_n_valid = 0; ++ } ++ } ++ } ++ + return; + } + + static void __sunxi_set_vbus(struct sunxi_hci_hcd *sunxi_hci, int is_on) + { +- //u32 on_off = 0; + + DMSG_INFO("[%s]: Set USB Power %s\n", sunxi_hci->hci_name, (is_on ? "ON" : "OFF")); + + /* set power flag */ + sunxi_hci->power_flag = is_on; + +- /* set power */ +- //if(sunxi_hci->drv_vbus_gpio_set.gpio.data == 0){ +- // on_off = is_on ? 1 : 0; +- //}else{ +- // on_off = is_on ? 0 : 1; +- //} +- + //no care of usb0 vbus when otg connect pc setup system without battery and to return + #ifdef CONFIG_USB_SUNXI_USB_MANAGER + #if defined (CONFIG_ARCH_SUN8IW8) || defined (CONFIG_ARCH_SUN8IW7) +@@ -1815,6 +1930,19 @@ + } + } + ++ if(sunxi_hci->hsic_flag){ ++ if((sunxi_hci->hsic_regulator_io != NULL) && (sunxi_hci->hsic_regulator_io_hdle != NULL)){ ++ if(is_on){ ++ if(regulator_enable(sunxi_hci->hsic_regulator_io_hdle) < 0){ ++ DMSG_INFO("%s: hsic_regulator_enable fail\n", sunxi_hci->hci_name); ++ } ++ }else{ ++ if(regulator_disable(sunxi_hci->hsic_regulator_io_hdle) < 0){ ++ DMSG_INFO("%s: hsic_regulator_disable fail\n", sunxi_hci->hci_name); ++ } ++ } ++ } ++ } + return; + } + +@@ -2006,6 +2134,11 @@ + #endif + + #ifdef CONFIG_ARCH_SUN8IW8 ++int sunxi_usb_enable_ehci(__u32 usbc_no); ++int sunxi_usb_disable_ehci(__u32 usbc_no); ++int sunxi_usb_enable_ohci(__u32 usbc_no); ++int sunxi_usb_disable_ohci(__u32 usbc_no); ++ + static void sunxi_usbc_work(struct work_struct *data) + { + struct sunxi_hci_hcd *sunxi_hci = NULL; +@@ -2015,7 +2148,12 @@ + printk("sunxi_usbc_work, usbc:%d\n", sunxi_hci->usbc_no); + + __sunxi_set_vbus(sunxi_hci, 0); ++ sunxi_usb_disable_ehci(HCI0_USBC_NO); ++ sunxi_usb_disable_ohci(HCI0_USBC_NO); + msleep(100); ++ ++ sunxi_usb_enable_ehci(HCI0_USBC_NO); ++ sunxi_usb_enable_ohci(HCI0_USBC_NO); + __sunxi_set_vbus(sunxi_hci, 1); + + printk("end sunxi_usbc_work\n"); +diff -Nur linux-igor/drivers/usb/host/sunxi_hci.h tinaos/drivers/usb/host/sunxi_hci.h +--- linux-igor/drivers/usb/host/sunxi_hci.h 2016-10-11 16:01:24.053603680 +0200 ++++ tinaos/drivers/usb/host/sunxi_hci.h 2016-10-11 12:23:23.983423329 +0200 +@@ -197,13 +197,11 @@ + + script_item_u drv_vbus_gpio_set; + script_item_u restrict_gpio_set; +- script_item_u usb_host_hsic_rdy; + + char* regulator_io; +- int regulator_value; ++ + struct regulator* regulator_io_hdle; + u32 drv_vbus_gpio_valid; +- u32 usb_host_hsic_rdy_valid; + u32 usb_restrict_valid; + __u8 power_flag; /* flag. power on or not */ + +@@ -213,10 +211,30 @@ + __u8 usb_restrict_flag; + __u8 usbc_type; /* usb controller type */ + __u8 not_suspend; /* flag. not suspend */ ++ ++ /* HSIC device susport */ + __u8 hsic_flag; /* flag. hsic usbed */ ++ char* hsic_regulator_io; ++ struct regulator* hsic_regulator_io_hdle; ++ ++ /* Marvell 4G HSIC ctrl */ ++ script_item_u usb_host_hsic_rdy; ++ u32 usb_host_hsic_rdy_valid; + __u8 hsic_ctrl_flag; /* flag. hsic ctrl */ + __u8 hsic_enable_flag; /* flag. hsic enable */ + ++ /* SMSC usb3503 HSIC HUB ctrl */ ++ __u8 usb_hsic_usb3503_flag; ++ ++ script_item_u usb_hsic_hub_connect; ++ u32 usb_hsic_hub_connect_valid; ++ ++ script_item_u usb_hsic_int_n; ++ u32 usb_hsic_int_n_valid; ++ ++ script_item_u usb_hsic_reset_n; ++ u32 usb_hsic_reset_n_valid; ++ + int (* open_clock)(struct sunxi_hci_hcd *sunxi_hci, u32 ohci); + int (* close_clock)(struct sunxi_hci_hcd *sunxi_hci, u32 ohci); + void (* set_power)(struct sunxi_hci_hcd *sunxi_hci, int is_on); +diff -Nur linux-igor/drivers/usb/sunxi_usb/hcd/hcd0/sunxi_hcd0.c tinaos/drivers/usb/sunxi_usb/hcd/hcd0/sunxi_hcd0.c +--- linux-igor/drivers/usb/sunxi_usb/hcd/hcd0/sunxi_hcd0.c 2016-10-11 16:01:24.080270348 +0200 ++++ tinaos/drivers/usb/sunxi_usb/hcd/hcd0/sunxi_hcd0.c 2016-10-11 12:23:24.013423330 +0200 +@@ -47,7 +47,7 @@ + + static struct scene_lock otg_standby_lock; + +-#ifdef CONFIG_ARCH_SUN8IW6 ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW9) + extern struct completion hcd_complete_notify; + #endif + +@@ -241,29 +241,6 @@ + return 0; + } + +- if(regulator_set_voltage(sunxi_hcd_io->regulator_io_hdle , sunxi_hcd_io->regulator_io_vol, sunxi_hcd_io->regulator_io_vol) < 0 ){ +- DMSG_PANIC("ERR:usb0 regulator set io voltage:fail\n"); +- regulator_put(sunxi_hcd_io->regulator_io_hdle); +- return 0; +- } +- } +- +- if(sunxi_hcd_io->regulator_id_vbus != NULL){ +- sunxi_hcd_io->regulator_id_vbus_hdle= regulator_get(NULL, sunxi_hcd_io->regulator_id_vbus); +- if(IS_ERR(sunxi_hcd_io->regulator_id_vbus_hdle)) { +- DMSG_PANIC("ERR: some error happen, usb0 regulator_id_vbus_hdle fail to get regulator!"); +- return 0; +- } +- +- if(regulator_set_voltage(sunxi_hcd_io->regulator_id_vbus_hdle , sunxi_hcd_io->regulator_id_vbus_vol, sunxi_hcd_io->regulator_id_vbus_vol) < 0 ){ +- DMSG_PANIC("ERR:usb0 regulator set id vbus voltage:fail\n"); +- regulator_put(sunxi_hcd_io->regulator_id_vbus_hdle); +- return 0; +- } +- +- if(regulator_enable(sunxi_hcd_io->regulator_id_vbus_hdle) < 0){ +- DMSG_INFO_HCD0("ERR: usb0 id vbus regulator_enable fail\n"); +- } + } + + return 0; +@@ -275,10 +252,7 @@ + regulator_put(sunxi_hcd_io->regulator_io_hdle); + sunxi_hcd_io->regulator_io_hdle = NULL; + } +- if(sunxi_hcd_io->regulator_id_vbus != NULL){ +- regulator_put(sunxi_hcd_io->regulator_id_vbus_hdle); +- sunxi_hcd_io->regulator_id_vbus_hdle = NULL; +- } ++ + return 0; + } + +@@ -349,7 +323,7 @@ + sunxi_hcd_io->ahb_otg, sunxi_hcd_io->mod_usbotg, sunxi_hcd_io->mod_usbphy, sunxi_hcd_io->clk_is_open); + } + +-#ifdef CONFIG_ARCH_SUN8IW6 ++#if defined (CONFIG_ARCH_SUN8IW6) + USBC_PHY_Set_Ctl(sunxi_hcd_io->usb_vbase, USBC_PHY_CTL_VBUSVLDEXT); + USBC_PHY_Clear_Ctl(sunxi_hcd_io->usb_vbase, USBC_PHY_CTL_SIDDQ); + #else +@@ -389,8 +363,8 @@ + (u32)USBC_Readl(sunxi_hcd_io->clock_vbase + 0x2c0)); + */ + +-#ifdef CONFIG_ARCH_SUN8IW6 +- USBC_PHY_Set_Ctl(sunxi_hcd_io->usb_vbase, USBC_PHY_CTL_SIDDQ); ++#if defined (CONFIG_ARCH_SUN8IW6) ++ USBC_PHY_Set_Ctl(sunxi_hcd_io->usb_vbase, USBC_PHY_CTL_SIDDQ); + #endif + + return 0; +@@ -421,6 +395,7 @@ + sunxi_hcd_io->drv_vbus_valid = 0; + } + ++ + if (sunxi_hcd_io->drv_vbus_valid) { + ret = gpio_request(sunxi_hcd_io->drv_vbus_gpio_set.gpio.gpio, "otg_drv_vbus"); + if (ret != 0) { +@@ -443,42 +418,12 @@ + sunxi_hcd_io->regulator_io = NULL; + }else{ + sunxi_hcd_io->regulator_io = item_temp.str; +- +- type = script_get_item(SET_USB0, KEY_USB_REGULATOR_IO_VOL, &item_temp); +- if(type == SCIRPT_ITEM_VALUE_TYPE_INT){ +- sunxi_hcd_io->regulator_io_vol = item_temp.val; +- }else{ +- DMSG_INFO_HCD0("get usb io voltage is failed\n"); +- sunxi_hcd_io->regulator_io_vol = 0; +- } + } + }else { + DMSG_INFO_HCD0("usb_regulator io is not exist\n"); + sunxi_hcd_io->regulator_io = NULL; + } + +- /* get regulator information */ +- type = script_get_item(SET_USB0, KEY_USB_REGULATOR_ID_VBUS, &item_temp); +- if (type == SCIRPT_ITEM_VALUE_TYPE_STR) { +- if (!strcmp(item_temp.str, "nocare")) { +- DMSG_INFO_HCD0("get usb_regulator id vbus is nocare\n"); +- sunxi_hcd_io->regulator_id_vbus = NULL; +- }else{ +- sunxi_hcd_io->regulator_id_vbus = item_temp.str; +- +- type = script_get_item(SET_USB0, KEY_USB_REGULATOR_ID_VBUS_VOL, &item_temp); +- if(type == SCIRPT_ITEM_VALUE_TYPE_INT){ +- sunxi_hcd_io->regulator_id_vbus_vol = item_temp.val; +- }else{ +- DMSG_INFO_HCD0("get usb id voltage is failed\n"); +- sunxi_hcd_io->regulator_id_vbus_vol = 0; +- } +- } +- }else { +- DMSG_INFO_HCD0("usb_regulator id vbus io is not exist\n"); +- sunxi_hcd_io->regulator_id_vbus = NULL; +- } +- + type = script_get_item(SET_USB0, KEY_USB_USB_NOT_SUSPEND, &item_temp); + if (type == SCIRPT_ITEM_VALUE_TYPE_INT) { + sunxi_hcd_io->no_suspend = item_temp.val; +@@ -630,23 +575,13 @@ + } + static void sunxi_hcd_board_set_vbus(struct sunxi_hcd *sunxi_hcd, int is_on) + { +-#ifndef SUNXI_USB_FPGA +- u32 on_off = 0; +-#endif + + DMSG_INFO_HCD0("[%s]: Set USB Power %s\n", sunxi_hcd->driver_name, (is_on ? "ON" : "OFF")); + + #ifndef SUNXI_USB_FPGA +- /* set power */ +- if (sunxi_hcd->sunxi_hcd_io->drv_vbus_gpio_set.gpio.data == 0) { +- on_off = is_on ? 1 : 0; +- } else { +- on_off = is_on ? 0 : 1; +- } +- + /* set gpio data */ + if (sunxi_hcd->sunxi_hcd_io->drv_vbus_valid) { +- __gpio_set_value(sunxi_hcd->sunxi_hcd_io->drv_vbus_gpio_set.gpio.gpio, on_off); ++ __gpio_set_value(sunxi_hcd->sunxi_hcd_io->drv_vbus_gpio_set.gpio.gpio, is_on); + } + #endif + +@@ -1700,7 +1635,7 @@ + goto end; + } + +-#ifdef CONFIG_ARCH_SUN8IW6 ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW9) + { + struct sunxi_hcd_platform_data *pdata = pdev->dev.platform_data; + if(pdata->config->port_info->port_type == USB_PORT_TYPE_HOST){ +@@ -1743,7 +1678,8 @@ + * bridge to a platform device; this driver then suffices. + * + */ +-#ifndef CONFIG_ARCH_SUN8IW6 ++ ++#if !defined (CONFIG_ARCH_SUN8IW6) && !defined (CONFIG_ARCH_SUN8IW9) + static int sunxi_hcd_probe_host_only(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -1819,7 +1755,7 @@ + static int __init sunxi_hcd_probe(struct platform_device *pdev) + { + #ifdef CONFIG_USB_SUNXI_USB0_OTG +-#ifdef CONFIG_ARCH_SUN8IW6 ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW9) + return sunxi_hcd_probe_otg(pdev); + #else + +@@ -1846,7 +1782,7 @@ + static int __exit sunxi_hcd_remove(struct platform_device *pdev) + { + #ifdef CONFIG_USB_SUNXI_USB0_OTG +-#ifdef CONFIG_ARCH_SUN8IW6 ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW9) + return sunxi_hcd_remove_otg(pdev); + #else + struct sunxi_hcd_platform_data *pdata = pdev->dev.platform_data; +diff -Nur linux-igor/drivers/usb/sunxi_usb/include/sunxi_usb_board.h tinaos/drivers/usb/sunxi_usb/include/sunxi_usb_board.h +--- linux-igor/drivers/usb/sunxi_usb/include/sunxi_usb_board.h 2016-10-11 16:01:24.083603681 +0200 ++++ tinaos/drivers/usb/sunxi_usb/include/sunxi_usb_board.h 2016-10-11 12:23:24.013423330 +0200 +@@ -35,8 +35,6 @@ + #define KEY_USB_RESTRICT_GPIO "usb_restrict_gpio" + #define KEY_USB_REGULATOR_IO "usb_regulator_io" + #define KEY_USB_REGULATOR_IO_VOL "usb_regulator_vol" +-#define KEY_USB_REGULATOR_ID_VBUS "usb_regulator_id_vbus" +-#define KEY_USB_REGULATOR_ID_VBUS_VOL "usb_regulator_id_vbus_vol" + + #define KEY_USB_HOST_INIT_STATE "usb_host_init_state" + #define KEY_USB_USB_RESTRICT_FLAG "usb_restric_flag" +diff -Nur linux-igor/drivers/usb/sunxi_usb/manager/usbc0_platform.c tinaos/drivers/usb/sunxi_usb/manager/usbc0_platform.c +--- linux-igor/drivers/usb/sunxi_usb/manager/usbc0_platform.c 2016-10-11 16:01:24.083603681 +0200 ++++ tinaos/drivers/usb/sunxi_usb/manager/usbc0_platform.c 2016-10-11 12:23:24.013423330 +0200 +@@ -274,7 +274,7 @@ + { + /* device */ + #ifndef CONFIG_ARCH_SUN9IW1 +-#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) || defined (CONFIG_ARCH_SUN8IW9) + sunxi_udc_cfg.port_info = port_info; + sunxi_udc_cfg.usbc_base = (unsigned int __force)SUNXI_USB_OTG_VBASE; + +diff -Nur linux-igor/drivers/usb/sunxi_usb/manager/usb_manager.c tinaos/drivers/usb/sunxi_usb/manager/usb_manager.c +--- linux-igor/drivers/usb/sunxi_usb/manager/usb_manager.c 2016-10-11 16:01:24.083603681 +0200 ++++ tinaos/drivers/usb/sunxi_usb/manager/usb_manager.c 2016-10-11 12:23:24.013423330 +0200 +@@ -50,7 +50,7 @@ + __u32 thread_device_run_flag = 0; + __u32 thread_host_run_flag = 0; + +-#ifdef CONFIG_ARCH_SUN8IW6 ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW9) + struct completion hcd_complete_notify; + struct completion udc_complete_notify; + #endif +@@ -225,7 +225,7 @@ + while(thread_device_run_flag) { + + msleep(1000); /* 1s */ +-#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) || defined (CONFIG_ARCH_SUN8IW9) + wait_for_completion(&udc_complete_notify); + #endif + hw_rmmod_usb_host(); +@@ -251,7 +251,7 @@ + while(thread_host_run_flag) { + + msleep(1000); /* 1s */ +-#ifdef CONFIG_ARCH_SUN8IW6 ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW9) + wait_for_completion(&hcd_complete_notify); + #endif + hw_rmmod_usb_host(); +@@ -677,7 +677,7 @@ + + if (g_usb_cfg.port[0].port_type == USB_PORT_TYPE_DEVICE) { + +-#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) || defined (CONFIG_ARCH_SUN8IW9) + init_completion(&udc_complete_notify); + #endif + thread_device_run_flag = 1; +@@ -697,7 +697,7 @@ + } + #else + +-#ifdef CONFIG_ARCH_SUN8IW6 ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW9) + init_completion(&hcd_complete_notify); + #endif + thread_host_run_flag = 1; +diff -Nur linux-igor/drivers/usb/sunxi_usb/udc/sunxi_udc.c tinaos/drivers/usb/sunxi_usb/udc/sunxi_udc.c +--- linux-igor/drivers/usb/sunxi_usb/udc/sunxi_udc.c 2016-10-11 16:01:24.083603681 +0200 ++++ tinaos/drivers/usb/sunxi_usb/udc/sunxi_udc.c 2016-10-11 12:23:24.016756663 +0200 +@@ -63,7 +63,7 @@ + static struct platform_device *g_udc_pdev = NULL; + #endif + +-#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) || defined (CONFIG_ARCH_SUN8IW9) + extern struct completion udc_complete_notify; + #endif + +@@ -3015,7 +3015,7 @@ + device_create_file(&pdev->dev, &dev_attr_msc_read_debug); + device_create_file(&pdev->dev, &dev_attr_msc_write_debug); + +-#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) || defined (CONFIG_ARCH_SUN8IW9) + { + struct sunxi_udc_mach_info *udc_cfg = pdev->dev.platform_data; + if(udc_cfg->port_info->port_type == USB_PORT_TYPE_DEVICE){ +@@ -3042,7 +3042,7 @@ + + return 0; + } +-#if !defined (CONFIG_ARCH_SUN8IW6) && !defined (CONFIG_ARCH_SUN8IW7) && !defined (CONFIG_ARCH_SUN8IW8) ++#if !defined (CONFIG_ARCH_SUN8IW6) && !defined (CONFIG_ARCH_SUN8IW7) && !defined (CONFIG_ARCH_SUN8IW8) && !defined (CONFIG_ARCH_SUN8IW9) + static int sunxi_udc_probe_device_only(struct platform_device *pdev) + { + struct sunxi_udc *udc = &sunxi_udc; +@@ -3128,10 +3128,10 @@ + return 0; + } + #endif +-static int __init sunxi_udc_probe(struct platform_device *pdev) ++static int __devinit sunxi_udc_probe(struct platform_device *pdev) + { + #ifdef CONFIG_USB_SUNXI_USB0_OTG +-#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) || defined (CONFIG_ARCH_SUN8IW9) + return sunxi_udc_probe_otg(pdev); + #else + struct sunxi_udc_mach_info *udc_cfg = pdev->dev.platform_data; +@@ -3155,10 +3155,10 @@ + #endif + } + +-static int __exit sunxi_udc_remove(struct platform_device *pdev) ++static int __devexit sunxi_udc_remove(struct platform_device *pdev) + { + #ifdef CONFIG_USB_SUNXI_USB0_OTG +-#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) ++#if defined (CONFIG_ARCH_SUN8IW6) || defined (CONFIG_ARCH_SUN8IW7) || defined (CONFIG_ARCH_SUN8IW8) || defined (CONFIG_ARCH_SUN8IW9) + return sunxi_udc_remove_otg(pdev); + #else + +diff -Nur linux-igor/drivers/usb/sunxi_usb/usb3/ep0.c tinaos/drivers/usb/sunxi_usb/usb3/ep0.c +--- linux-igor/drivers/usb/sunxi_usb/usb3/ep0.c 2016-10-11 16:01:24.083603681 +0200 ++++ tinaos/drivers/usb/sunxi_usb/usb3/ep0.c 2016-10-11 12:23:24.016756663 +0200 +@@ -545,12 +545,18 @@ + + sunxi_ep0_stall_and_restart(otgc); + } else { +- /* +- * handle the case where we have to send a zero packet. This +- * seems to be case when req.length > maxpacket. Could it be? +- */ +- if (r) +- sunxi_gadget_giveback(ep0, r, 0); ++ ++ sunxi_gadget_giveback(ep0, r, 0); ++ ++ if (IS_ALIGNED(ur->length, ep0->endpoint.maxpacket) && ++ ur->length && ur->zero) { ++ int ret; ++ otgc->ep0_next_event = SUNXI_EP0_COMPLETE; ++ ret = sunxi_ep0_start_trans(otgc, epnum, ++ otgc->ctrl_req_addr, 0, ++ SUNXI_TRBCTL_CONTROL_DATA); ++ WARN_ON(ret < 0); ++ } + } + } + +@@ -645,6 +651,9 @@ + SUNXI_TRBCTL_CONTROL_DATA); + } else if ((req->request.length % dep->endpoint.maxpacket) + && (event->endpoint_number == 0)) { ++ u32 transfer_size; ++ u32 maxpacket; ++ + ret = usb_gadget_map_request(&otgc->gadget, &req->request, + event->endpoint_number); + if (ret) { +@@ -652,9 +661,11 @@ + return; + } + +- WARN_ON(req->request.length > dep->endpoint.maxpacket); ++ WARN_ON(req->request.length > 512); + + otgc->ep0_bounced = true; ++ maxpacket = dep->endpoint.maxpacket; ++ transfer_size = roundup(req->request.length, maxpacket); + + /* + * REVISIT in case request length is bigger than EP0 +@@ -662,7 +673,7 @@ + * the transfer. + */ + ret = sunxi_ep0_start_trans(otgc, event->endpoint_number, +- otgc->ep0_bounce_addr, dep->endpoint.maxpacket, ++ otgc->ep0_bounce_addr, transfer_size, + SUNXI_TRBCTL_CONTROL_DATA); + } else { + ret = usb_gadget_map_request(&otgc->gadget, &req->request, diff --git a/projects/H3/patches/linux/linux-012-fix-8818eu-driver.patch b/projects/H3/patches/linux/linux-012-fix-8818eu-driver.patch new file mode 100644 index 00000000000..8c62788c73f --- /dev/null +++ b/projects/H3/patches/linux/linux-012-fix-8818eu-driver.patch @@ -0,0 +1,21 @@ +diff --git a/drivers/net/wireless/rtl8188eu/platform/platform_ARM_SUNxI_usb.c b/drivers/net/wireless/rtl8188eu/platform/platform_ARM_SUNxI_usb.c +index 7639591..c7e676b 100755 +--- a/drivers/net/wireless/rtl8188eu/platform/platform_ARM_SUNxI_usb.c ++++ b/drivers/net/wireless/rtl8188eu/platform/platform_ARM_SUNxI_usb.c +@@ -51,7 +51,7 @@ static script_item_u item; + int platform_wifi_power_on(void) + { + int ret = 0; +- ++#if 0 + #ifdef CONFIG_PLATFORM_ARM_SUNxI + #ifndef CONFIG_RTL8723A + { +@@ -111,6 +111,7 @@ int platform_wifi_power_on(void) + #endif + } + #endif //CONFIG_PLATFORM_ARM_SUN8I ++#endif + + exit: + return ret; diff --git a/projects/H3/patches/linux/linux-013-bfq-sched-Forcefully-lookup-entities-when-the-cache-is-inconsistent.patch b/projects/H3/patches/linux/linux-013-bfq-sched-Forcefully-lookup-entities-when-the-cache-is-inconsistent.patch new file mode 100644 index 00000000000..ac1c1fc7319 --- /dev/null +++ b/projects/H3/patches/linux/linux-013-bfq-sched-Forcefully-lookup-entities-when-the-cache-is-inconsistent.patch @@ -0,0 +1,66 @@ +From 5638e9aebfcd50ccb02043f4b558160c0e12d40b Mon Sep 17 00:00:00 2001 +From: Diogo Ferreira +Date: Wed, 23 Nov 2016 14:46:50 +0000 +Subject: [PATCH] bfq-sched: Forcefully lookup entities when the cache is + inconsistent + +bfq maintains a 'next-in-service' cache to prevent expensive lookups in +the hot path. However, the cache sometimes becomes inconsistent and +triggers a BUG: + +[44042.622839] -(3)[154:mmcqd/0]BUG: failure at ../../../../../../kernel/cyanogen/mt6735/block/bfq-sched.c:72/bfq_check_next_in_service()! +[44042.622858] -(3)[154:mmcqd/0]Unable to handle kernel paging request at virtual address 0000dead +[44042.622866] -(3)[154:mmcqd/0]pgd = ffffffc001361000 +[44042.622872] [0000dead] *pgd=000000007d816003, *pud=000000007d816003, *pmd=000000007d817003, *pte=0000000000000000 +[44042.622890] -(3)[154:mmcqd/0]Internal error: Oops: 96000045 [#1] PREEMPT SMP +[44042.622907] -(3)[154:mmcqd/0]CPU: 3 PID: 154 Comm: mmcqd/0 Tainted: +[44042.622915] -(3)[154:mmcqd/0]Hardware name: MT6735 (DT) +[44042.622922] -(3)[154:mmcqd/0]task: ffffffc0378a6000 ti: ffffffc0378c4000 +[44042.622936] -(3)[154:mmcqd/0]PC is at bfq_dispatch_requests+0x6c4/0x9bc +[44042.622944] -(3)[154:mmcqd/0]LR is at bfq_dispatch_requests+0x6bc/0x9bc +[44042.622952] -(3)[154:mmcqd/0]pc : [] lr : [] pstate: 800001c5 +[44042.622958] -(3)[154:mmcqd/0]sp : ffffffc0378c7d30 +[44042.622962] x29: ffffffc0378c7d30 x28: 0000000000000000 +[44042.622972] x27: 0000000000000000 x26: ffffffc006c58810 +[44042.622981] x25: ffffffc037f89820 x24: ffffffc000f14000 +[44042.622990] x23: ffffffc036adb088 x22: ffffffc0369b2800 +[44042.623000] x21: ffffffc036adb098 x20: ffffffc01d6a3b60 +[44042.623009] x19: ffffffc036adb0c8 x18: 0000007f8cfa1500 +[44042.623018] x17: 0000007f8db44f40 x16: ffffffc00012d0c0 +[44042.623027] x15: 0000007f8dde04d8 x14: 676f6e6179632f6c +[44042.623037] x13: 656e72656b2f2e2e x12: 2f2e2e2f2e2e2f2e +[44042.623046] x11: 2e2f2e2e2f2e2e20 x10: 7461206572756c69 +[44042.623055] x9 : 6166203a4755425d x8 : 00000000001f0cc5 +[44042.623064] x7 : ffffffc000f3d5a0 x6 : 000000000000008b +[44042.623073] x5 : 0000000000000000 x4 : 0000000000000004 +[44042.623082] x3 : 0000000000000002 x2 : 0000000000000001 +[44042.623091] x1 : 0000000000000aee x0 : 000000000000dead + +This patch makes the lookup resilient to cache inconsistencies by doing +the expensive recomputation in cases where the bug would otherwise be +triggered. + +Ticket: PORRDIGE-527 + +Change-Id: I5dd701960057983a42d3d3bd57521e8d17c03d7f +--- + block/bfq-sched.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/block/bfq-sched.c b/block/bfq-sched.c +index d0890c6..c3828a4 100644 +--- a/block/bfq-sched.c ++++ b/block/bfq-sched.c +@@ -1046,6 +1046,9 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, + entity = __bfq_lookup_next_entity(st + i, false); + if (entity != NULL) { + if (extract) { ++ if (sd->next_in_service != entity) { ++ entity = __bfq_lookup_next_entity(st + i, true); ++ } + bfq_check_next_in_service(sd, entity); + bfq_active_extract(st + i, entity); + sd->in_service_entity = entity; +-- +2.7.4 + diff --git a/projects/H3/patches/linux/linux-500-rtl2832.patch b/projects/H3/patches/linux/linux-500-rtl2832.patch new file mode 100644 index 00000000000..84800ac21b7 --- /dev/null +++ b/projects/H3/patches/linux/linux-500-rtl2832.patch @@ -0,0 +1,107330 @@ +diff -rpuN a/drivers/media/dvb/dvb-usb/demod_rtl2832.c b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2832.c +--- a/drivers/media/dvb/dvb-usb/demod_rtl2832.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2832.c 2016-04-02 19:17:52.076066084 -0300 +@@ -0,0 +1,2872 @@ ++/** ++ ++@file ++ ++@brief RTL2832 demod module definition ++ ++One can manipulate RTL2832 demod through RTL2832 module. ++RTL2832 module is derived from DVB-T demod module. ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 demod module builder ++ ++Use BuildRtl2832Module() to build RTL2832 module, set all module function pointers with the corresponding ++functions, and initialize module private variables. ++ ++ ++@param [in] ppDemod Pointer to RTL2832 demod module pointer ++@param [in] pDvbtDemodModuleMemory Pointer to an allocated DVB-T demod module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr RTL2832 I2C device address ++@param [in] CrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] TsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] AppMode RTL2832 application mode for setting ++@param [in] UpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] IsFunc1Enabled RTL2832 Function 1 enabling status for setting ++ ++ ++@note ++ -# One should call BuildRtl2832Module() to build RTL2832 module before using it. ++ ++*/ ++void ++BuildRtl2832Module( ++ DVBT_DEMOD_MODULE **ppDemod, ++ DVBT_DEMOD_MODULE *pDvbtDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ int AppMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set demod module pointer, ++ *ppDemod = pDvbtDemodModuleMemory; ++ ++ // Get demod module. ++ pDemod = *ppDemod; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pDemod->pBaseInterface = pBaseInterfaceModuleMemory; ++ pDemod->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Set demod type. ++ pDemod->DemodType = DVBT_DEMOD_TYPE_RTL2832; ++ ++ // Set demod I2C device address. ++ pDemod->DeviceAddr = DeviceAddr; ++ ++ // Set demod crystal frequency in Hz. ++ pDemod->CrystalFreqHz = CrystalFreqHz; ++ ++ // Set demod TS interface mode. ++ pDemod->TsInterfaceMode = TsInterfaceMode; ++ ++ ++ // Initialize demod parameter setting status ++ pDemod->IsBandwidthModeSet = NO; ++ pDemod->IsIfFreqHzSet = NO; ++ pDemod->IsSpectrumModeSet = NO; ++ ++ ++ // Initialize demod register table. ++ rtl2832_InitRegTable(pDemod); ++ ++ ++ // Build I2C birdge module. ++ rtl2832_BuildI2cBridgeModule(pDemod); ++ ++ ++ // Set demod module I2C function pointers with default functions. ++ pDemod->SetRegPage = dvbt_demod_default_SetRegPage; ++ pDemod->SetRegBytes = dvbt_demod_default_SetRegBytes; ++ pDemod->GetRegBytes = dvbt_demod_default_GetRegBytes; ++ pDemod->SetRegMaskBits = dvbt_demod_default_SetRegMaskBits; ++ pDemod->GetRegMaskBits = dvbt_demod_default_GetRegMaskBits; ++ pDemod->SetRegBits = dvbt_demod_default_SetRegBits; ++ pDemod->GetRegBits = dvbt_demod_default_GetRegBits; ++ pDemod->SetRegBitsWithPage = dvbt_demod_default_SetRegBitsWithPage; ++ pDemod->GetRegBitsWithPage = dvbt_demod_default_GetRegBitsWithPage; ++ ++ ++ // Set demod module manipulating function pointers with default functions. ++ pDemod->GetDemodType = dvbt_demod_default_GetDemodType; ++ pDemod->GetDeviceAddr = dvbt_demod_default_GetDeviceAddr; ++ pDemod->GetCrystalFreqHz = dvbt_demod_default_GetCrystalFreqHz; ++ ++ pDemod->GetBandwidthMode = dvbt_demod_default_GetBandwidthMode; ++ pDemod->GetIfFreqHz = dvbt_demod_default_GetIfFreqHz; ++ pDemod->GetSpectrumMode = dvbt_demod_default_GetSpectrumMode; ++ ++ ++ // Set demod module manipulating function pointers with particular functions. ++ pDemod->IsConnectedToI2c = rtl2832_IsConnectedToI2c; ++ pDemod->SoftwareReset = rtl2832_SoftwareReset; ++ pDemod->Initialize = rtl2832_Initialize; ++ pDemod->SetBandwidthMode = rtl2832_SetBandwidthMode; ++ pDemod->SetIfFreqHz = rtl2832_SetIfFreqHz; ++ pDemod->SetSpectrumMode = rtl2832_SetSpectrumMode; ++ ++ pDemod->IsTpsLocked = rtl2832_IsTpsLocked; ++ pDemod->IsSignalLocked = rtl2832_IsSignalLocked; ++ ++ pDemod->GetSignalStrength = rtl2832_GetSignalStrength; ++ pDemod->GetSignalQuality = rtl2832_GetSignalQuality; ++ ++ pDemod->GetBer = rtl2832_GetBer; ++ pDemod->GetSnrDb = rtl2832_GetSnrDb; ++ ++ pDemod->GetRfAgc = rtl2832_GetRfAgc; ++ pDemod->GetIfAgc = rtl2832_GetIfAgc; ++ pDemod->GetDiAgc = rtl2832_GetDiAgc; ++ ++ pDemod->GetTrOffsetPpm = rtl2832_GetTrOffsetPpm; ++ pDemod->GetCrOffsetHz = rtl2832_GetCrOffsetHz; ++ ++ pDemod->GetConstellation = rtl2832_GetConstellation; ++ pDemod->GetHierarchy = rtl2832_GetHierarchy; ++ pDemod->GetCodeRateLp = rtl2832_GetCodeRateLp; ++ pDemod->GetCodeRateHp = rtl2832_GetCodeRateHp; ++ pDemod->GetGuardInterval = rtl2832_GetGuardInterval; ++ pDemod->GetFftMode = rtl2832_GetFftMode; ++ ++ pDemod->UpdateFunction = rtl2832_UpdateFunction; ++ pDemod->ResetFunction = rtl2832_ResetFunction; ++ ++ ++ // Initialize demod extra module variables. ++ pExtra->AppMode = AppMode; ++ ++ ++ // Initialize demod Function 1 variables. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_NORMAL; ++ ++ pExtra->IsFunc1Enabled = IsFunc1Enabled; ++ ++ pExtra->Func1WaitTimeMax = DivideWithCeiling(RTL2832_FUNC1_WAIT_TIME_MS, UpdateFuncRefPeriodMs); ++ pExtra->Func1GettingTimeMax = DivideWithCeiling(RTL2832_FUNC1_GETTING_TIME_MS, UpdateFuncRefPeriodMs); ++ pExtra->Func1GettingNumEachTime = DivideWithCeiling(RTL2832_FUNC1_GETTING_NUM_MIN, pExtra->Func1GettingTimeMax + 1); ++ ++ pExtra->Func1QamBak = 0xff; ++ pExtra->Func1HierBak = 0xff; ++ pExtra->Func1LpCrBak = 0xff; ++ pExtra->Func1HpCrBak = 0xff; ++ pExtra->Func1GiBak = 0xff; ++ pExtra->Func1FftBak = 0xff; ++ ++ ++ // Set demod extra module function pointers. ++ pExtra->GetAppMode = rtl2832_GetAppMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C ++ ++*/ ++void ++rtl2832_IsConnectedToI2c( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char Nothing; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send read command. ++ // Note: The number of reading bytes must be greater than 0. ++ if(pBaseInterface->I2cRead(pBaseInterface, pDemod->DeviceAddr, &Nothing, LEN_1_BYTE) == FUNCTION_ERROR) ++ goto error_status_i2c_read; ++ ++ ++ // Set I2cConnectionStatus with YES. ++ *pAnswer = YES; ++ ++ ++ return; ++ ++ ++error_status_i2c_read: ++ ++ // Set I2cConnectionStatus with NO. ++ *pAnswer = NO; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SOFTWARE_RESET ++ ++*/ ++int ++rtl2832_SoftwareReset( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Set SOFT_RST with 1. Then, set SOFT_RST with 0. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SOFT_RST, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SOFT_RST, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_Initialize( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Initializing table entry only used in Initialize() ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue; ++ } ++ INIT_TABLE_ENTRY; ++ ++ // TS interface initializing table entry only used in Initialize() ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue[TS_INTERFACE_MODE_NUM]; ++ } ++ TS_INTERFACE_INIT_TABLE_ENTRY; ++ ++ // Application initializing table entry only used in Initialize() ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue[RTL2832_APPLICATION_MODE_NUM]; ++ } ++ APP_INIT_TABLE_ENTRY; ++ ++ ++ ++ static const INIT_TABLE_ENTRY InitTable[RTL2832_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue ++ {DVBT_AD_EN_REG, 0x1 }, ++ {DVBT_AD_EN_REG1, 0x1 }, ++ {DVBT_RSD_BER_FAIL_VAL, 0x2800 }, ++ {DVBT_MGD_THD0, 0x10 }, ++ {DVBT_MGD_THD1, 0x20 }, ++ {DVBT_MGD_THD2, 0x20 }, ++ {DVBT_MGD_THD3, 0x40 }, ++ {DVBT_MGD_THD4, 0x22 }, ++ {DVBT_MGD_THD5, 0x32 }, ++ {DVBT_MGD_THD6, 0x37 }, ++ {DVBT_MGD_THD7, 0x39 }, ++ {DVBT_EN_BK_TRK, 0x0 }, ++ {DVBT_EN_CACQ_NOTCH, 0x0 }, ++ {DVBT_AD_AV_REF, 0x2a }, ++ {DVBT_REG_PI, 0x6 }, ++ {DVBT_PIP_ON, 0x0 }, ++ {DVBT_CDIV_PH0, 0x8 }, ++ {DVBT_CDIV_PH1, 0x8 }, ++ {DVBT_SCALE1_B92, 0x4 }, ++ {DVBT_SCALE1_B93, 0xb0 }, ++ {DVBT_SCALE1_BA7, 0x78 }, ++ {DVBT_SCALE1_BA9, 0x28 }, ++ {DVBT_SCALE1_BAA, 0x59 }, ++ {DVBT_SCALE1_BAB, 0x83 }, ++ {DVBT_SCALE1_BAC, 0xd4 }, ++ {DVBT_SCALE1_BB0, 0x65 }, ++ {DVBT_SCALE1_BB1, 0x43 }, ++ {DVBT_KB_P1, 0x1 }, ++ {DVBT_KB_P2, 0x4 }, ++ {DVBT_KB_P3, 0x7 }, ++ {DVBT_K1_CR_STEP12, 0xa }, ++ {DVBT_REG_GPE, 0x1 }, ++ }; ++ ++ static const TS_INTERFACE_INIT_TABLE_ENTRY TsInterfaceInitTable[RTL2832_TS_INTERFACE_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue for {Parallel, Serial} ++ {DVBT_SERIAL, {0x0, 0x1}}, ++ {DVBT_CDIV_PH0, {0x9, 0x1}}, ++ {DVBT_CDIV_PH1, {0x9, 0x2}}, ++ {DVBT_MPEG_IO_OPT_2_2, {0x0, 0x0}}, ++ {DVBT_MPEG_IO_OPT_1_0, {0x0, 0x1}}, ++ }; ++ ++ static const APP_INIT_TABLE_ENTRY AppInitTable[RTL2832_APP_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue for {Dongle, STB} ++ {DVBT_TRK_KS_P2, {0x4, 0x4}}, ++ {DVBT_TRK_KS_I2, {0x7, 0x7}}, ++ {DVBT_TR_THD_SET2, {0x6, 0x6}}, ++ {DVBT_TRK_KC_I2, {0x5, 0x6}}, ++ {DVBT_CR_THD_SET2, {0x1, 0x1}}, ++ }; ++ ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ int i; ++ ++ int TsInterfaceMode; ++ int AppMode; ++ ++ ++ ++ // Get base interface and demod extra module. ++ pBaseInterface = pDemod->pBaseInterface; ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ // Get TS interface mode. ++ TsInterfaceMode = pDemod->TsInterfaceMode; ++ ++ // Get application mode. ++ pExtra->GetAppMode(pDemod, &AppMode); ++ ++ ++ // Initialize demod registers according to the initializing table. ++ for(i = 0; i < RTL2832_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->SetRegBitsWithPage(pDemod, InitTable[i].RegBitName, InitTable[i].WritingValue) ++ != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ // Initialize demod registers according to the TS interface initializing table. ++ for(i = 0; i < RTL2832_TS_INTERFACE_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->SetRegBitsWithPage(pDemod, TsInterfaceInitTable[i].RegBitName, ++ TsInterfaceInitTable[i].WritingValue[TsInterfaceMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ // Initialize demod registers according to the application initializing table. ++ for(i = 0; i < RTL2832_APP_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->SetRegBitsWithPage(pDemod, AppInitTable[i].RegBitName, ++ AppInitTable[i].WritingValue[AppMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_BANDWIDTH_MODE ++ ++*/ ++int ++rtl2832_SetBandwidthMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int BandwidthMode ++ ) ++{ ++ static const unsigned char HlpfxTable[DVBT_BANDWIDTH_MODE_NUM][RTL2832_H_LPF_X_LEN] = ++ { ++ // H_LPF_X writing value for 6 MHz bandwidth ++ { ++ 0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f, ++ 0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2, ++ 0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67, ++ 0x19, 0xe0, ++ }, ++ ++ // H_LPF_X writing value for 7 MHz bandwidth ++ { ++ 0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf, ++ 0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30, ++ 0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22, ++ 0x19, 0x10, ++ }, ++ ++ // H_LPF_X writing value for 8 MHz bandwidth ++ { ++ 0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf, ++ 0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7, ++ 0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8, ++ 0x19, 0xe0, ++ }, ++ }; ++ ++ ++ unsigned long CrystalFreqHz; ++ ++ long ConstWithBandwidthMode; ++ ++ MPI MpiCrystalFreqHz; ++ MPI MpiConst, MpiVar0, MpiVar1, MpiNone; ++ ++ unsigned long RsampRatio; ++ ++ long CfreqOffRatioInt; ++ unsigned long CfreqOffRatioBinary; ++ ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Set H_LPF_X registers with HlpfxTable according to BandwidthMode. ++ if(pDemod->SetRegPage(pDemod, RTL2832_H_LPF_X_PAGE) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegBytes(pDemod, RTL2832_H_LPF_X_ADDR, HlpfxTable[BandwidthMode], RTL2832_H_LPF_X_LEN) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Determine constant value with bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: ConstWithBandwidthMode = 48000000; break; ++ case DVBT_BANDWIDTH_7MHZ: ConstWithBandwidthMode = 56000000; break; ++ case DVBT_BANDWIDTH_8MHZ: ConstWithBandwidthMode = 64000000; break; ++ } ++ ++ ++ // Calculate RSAMP_RATIO value. ++ // Note: RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22) / ConstWithBandwidthMode) ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ MpiSetValue(&MpiVar1, ConstWithBandwidthMode); ++ MpiSetValue(&MpiConst, 7); ++ ++ MpiMul(&MpiVar0, MpiCrystalFreqHz, MpiConst); ++ MpiLeftShift(&MpiVar0, MpiVar0, 22); ++ MpiDiv(&MpiVar0, &MpiNone, MpiVar0, MpiVar1); ++ ++ MpiGetValue(MpiVar0, (long *)&RsampRatio); ++ ++ ++ // Set RSAMP_RATIO with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_RSAMP_RATIO, RsampRatio) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Calculate CFREQ_OFF_RATIO value. ++ // Note: CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20) / (CrystalFreqHz * 7)) ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ MpiSetValue(&MpiVar0, ConstWithBandwidthMode); ++ MpiSetValue(&MpiConst, 7); ++ ++ MpiLeftShift(&MpiVar0, MpiVar0, 20); ++ MpiMul(&MpiVar1, MpiCrystalFreqHz, MpiConst); ++ MpiDiv(&MpiVar0, &MpiNone, MpiVar0, MpiVar1); ++ ++ MpiGetValue(MpiVar0, &CfreqOffRatioInt); ++ CfreqOffRatioInt = - CfreqOffRatioInt; ++ ++ CfreqOffRatioBinary = SignedIntToBin(CfreqOffRatioInt, RTL2832_CFREQ_OFF_RATIO_BIT_NUM); ++ ++ ++ // Set CFREQ_OFF_RATIO with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_CFREQ_OFF_RATIO, CfreqOffRatioBinary) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ ++ // Set demod bandwidth mode parameter. ++ pDemod->BandwidthMode = BandwidthMode; ++ pDemod->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_IF_FREQ_HZ ++ ++*/ ++int ++rtl2832_SetIfFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ) ++{ ++ unsigned long CrystalFreqHz; ++ ++ unsigned long EnBbin; ++ ++ MPI MpiCrystalFreqHz, MpiVar, MpiNone; ++ ++ long PsetIffreqInt; ++ unsigned long PsetIffreqBinary; ++ ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Determine and set EN_BBIN value. ++ EnBbin = (IfFreqHz == IF_FREQ_0HZ) ? 0x1 : 0x0; ++ ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_EN_BBIN, EnBbin) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Calculate PSET_IFFREQ value. ++ // Note: PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22) / CrystalFreqHz) ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ ++ MpiSetValue(&MpiVar, (IfFreqHz % CrystalFreqHz)); ++ MpiLeftShift(&MpiVar, MpiVar, RTL2832_PSET_IFFREQ_BIT_NUM); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiCrystalFreqHz); ++ ++ MpiGetValue(MpiVar, &PsetIffreqInt); ++ PsetIffreqInt = - PsetIffreqInt; ++ ++ PsetIffreqBinary = SignedIntToBin(PsetIffreqInt, RTL2832_PSET_IFFREQ_BIT_NUM); ++ ++ ++ // Set PSET_IFFREQ with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_PSET_IFFREQ, PsetIffreqBinary) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod IF frequnecy parameter. ++ pDemod->IfFreqHz = IfFreqHz; ++ pDemod->IsIfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_SPECTRUM_MODE ++ ++*/ ++int ++rtl2832_SetSpectrumMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ) ++{ ++ unsigned long SpecInv; ++ ++ ++ ++ // Determine SpecInv according to spectrum mode. ++ switch(SpectrumMode) ++ { ++ default: ++ case SPECTRUM_NORMAL: SpecInv = 0; break; ++ case SPECTRUM_INVERSE: SpecInv = 1; break; ++ } ++ ++ ++ // Set SPEC_INV with SpecInv. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_SPEC_INV, SpecInv) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod spectrum mode parameter. ++ pDemod->SpectrumMode = SpectrumMode; ++ pDemod->IsSpectrumModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_IS_TPS_LOCKED ++ ++*/ ++int ++rtl2832_IsTpsLocked( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long FsmStage; ++ ++ ++ ++ // Get FSM stage from FSM_STAGE. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Determine answer according to FSM stage. ++ if(FsmStage > 9) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++rtl2832_IsSignalLocked( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long FsmStage; ++ ++ ++ ++ // Get FSM stage from FSM_STAGE. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Determine answer according to FSM stage. ++ if(FsmStage == 11) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++rtl2832_GetSignalStrength( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ) ++{ ++ unsigned long FsmStage; ++ long IfAgc; ++ ++ ++ ++ // Get FSM stage and IF AGC value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetIfAgc(pDemod, &IfAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Determine signal strength according to FSM stage and IF AGC value. ++ if(FsmStage < 10) ++ *pSignalStrength = 0; ++ else ++ *pSignalStrength = 55 - IfAgc / 182; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++rtl2832_GetSignalQuality( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ) ++{ ++ unsigned long FsmStage, RsdBerEst; ++ ++ MPI MpiVar; ++ long Var; ++ ++ ++ ++ // Get FSM_STAGE and RSD_BER_EST. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // If demod is not signal-locked, set signal quality with zero. ++ if(FsmStage < 10) ++ { ++ *pSignalQuality = 0; ++ goto success_status_non_signal_lock; ++ } ++ ++ // Determine signal quality according to RSD_BER_EST. ++ // Note: Map RSD_BER_EST value 8192 ~ 128 to 10 ~ 100 ++ // Original formula: SignalQuality = 205 - 15 * log2(RSD_BER_EST) ++ // Adjusted formula: SignalQuality = ((205 << 5) - 15 * (log2(RSD_BER_EST) << 5)) >> 5 ++ // If RSD_BER_EST > 8192, signal quality is 10. ++ // If RSD_BER_EST < 128, signal quality is 100. ++ if(RsdBerEst > 8192) ++ { ++ *pSignalQuality = 10; ++ } ++ else if(RsdBerEst < 128) ++ { ++ *pSignalQuality = 100; ++ } ++ else ++ { ++ MpiSetValue(&MpiVar, RsdBerEst); ++ MpiLog2(&MpiVar, MpiVar, RTL2832_SQ_FRAC_BIT_NUM); ++ MpiGetValue(MpiVar, &Var); ++ ++ *pSignalQuality = ((205 << RTL2832_SQ_FRAC_BIT_NUM) - 15 * Var) >> RTL2832_SQ_FRAC_BIT_NUM; ++ } ++ ++ ++success_status_non_signal_lock: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_BER ++ ++*/ ++int ++rtl2832_GetBer( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ) ++{ ++ unsigned long RsdBerEst; ++ ++ ++ ++ // Get RSD_BER_EST. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set BER numerator according to RSD_BER_EST. ++ *pBerNum = RsdBerEst; ++ ++ // Set BER denominator. ++ *pBerDen = RTL2832_BER_DEN_VALUE; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_SNR_DB ++ ++*/ ++int ++rtl2832_GetSnrDb( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ unsigned long FsmStage; ++ unsigned long CeEstEvm; ++ int Constellation, Hierarchy; ++ ++ static const long SnrDbNumConst[DVBT_CONSTELLATION_NUM][DVBT_HIERARCHY_NUM] = ++ { ++ {122880, 122880, 122880, 122880, }, ++ {146657, 146657, 156897, 171013, }, ++ {167857, 167857, 173127, 181810, }, ++ }; ++ ++ long Var; ++ MPI MpiCeEstEvm, MpiVar; ++ ++ ++ ++ // Get FSM stage, CE_EST_EVM, constellation, and hierarchy. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_CE_EST_EVM, &CeEstEvm) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetConstellation(pDemod, &Constellation) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetHierarchy(pDemod, &Hierarchy) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ ++ // SNR dB formula ++ // Original formula: SNR_dB = 10 * log10(Norm * pow(2, 11) / CeEstEvm) ++ // Adjusted formula: SNR_dB = (SNR_DB_NUM_CONST - 10 * log2(CeEstEvm) * pow(2, SNR_FRAC_BIT_NUM)) / SNR_DB_DEN ++ // SNR_DB_NUM_CONST = 10 * log2(Norm * pow(2, 11)) * pow(2, SNR_FRAC_BIT_NUM) ++ // SNR_DB_DEN = log2(10) * pow(2, SNR_FRAC_BIT_NUM) ++ // Norm: ++ // None Alpha=1 Alpha=2 Alpha=4 ++ // 4-QAM 2 2 2 2 ++ // 16-QAM 10 10 20 52 ++ // 64-QAM 42 42 60 108 ++ ++ ++ // If FSM stage < 10, set CE_EST_EVM with max value. ++ if(FsmStage < 10) ++ CeEstEvm = RTL2832_CE_EST_EVM_MAX_VALUE; ++ ++ ++ // Calculate SNR dB numerator. ++ MpiSetValue(&MpiCeEstEvm, CeEstEvm); ++ ++ MpiLog2(&MpiVar, MpiCeEstEvm, RTL2832_SNR_FRAC_BIT_NUM); ++ ++ MpiGetValue(MpiVar, &Var); ++ ++ *pSnrDbNum = SnrDbNumConst[Constellation][Hierarchy] - 10 * Var; ++ ++ ++ // Set SNR dB denominator. ++ *pSnrDbDen = RTL2832_SNR_DB_DEN; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_RF_AGC ++ ++*/ ++int ++rtl2832_GetRfAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ) ++{ ++ unsigned long Value; ++ ++ ++ ++ // Get RF_AGC_VAL to Value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RF_AGC_VAL, &Value) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Convert Value to signed integer and store the signed integer to RfAgc. ++ *pRfAgc = (int)BinToSignedInt(Value, RTL2832_RF_AGC_REG_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_IF_AGC ++ ++*/ ++int ++rtl2832_GetIfAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ) ++{ ++ unsigned long Value; ++ ++ ++ ++ // Get IF_AGC_VAL to Value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_IF_AGC_VAL, &Value) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Convert Value to signed integer and store the signed integer to IfAgc. ++ *pIfAgc = (int)BinToSignedInt(Value, RTL2832_IF_AGC_REG_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_DI_AGC ++ ++*/ ++int ++rtl2832_GetDiAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDiAgc ++ ) ++{ ++ unsigned long Value; ++ ++ ++ ++ // Get DAGC_VAL to DiAgc. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_DAGC_VAL, &Value) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ *pDiAgc = (unsigned char)Value; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++rtl2832_GetTrOffsetPpm( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ) ++{ ++ unsigned long SfreqOffBinary; ++ long SfreqOffInt; ++ ++ MPI MpiSfreqOffInt; ++ MPI MpiConst, MpiVar; ++ ++ ++ // Get SfreqOff binary value from SFREQ_OFF register bits. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_SFREQ_OFF, &SfreqOffBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Convert SfreqOff binary value to signed integer. ++ SfreqOffInt = BinToSignedInt(SfreqOffBinary, RTL2832_SFREQ_OFF_BIT_NUM); ++ ++ ++ // Get TR offset in ppm. ++ // Note: Original formula: TrOffsetPpm = (SfreqOffInt * 1000000) / pow(2, 24) ++ // Adjusted formula: TrOffsetPpm = (SfreqOffInt * 1000000) >> 24 ++ MpiSetValue(&MpiSfreqOffInt, SfreqOffInt); ++ MpiSetValue(&MpiConst, 1000000); ++ ++ MpiMul(&MpiVar, MpiSfreqOffInt, MpiConst); ++ MpiRightShift(&MpiVar, MpiVar, 24); ++ ++ MpiGetValue(MpiVar, pTrOffsetPpm); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++rtl2832_GetCrOffsetHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ) ++{ ++ int BandwidthMode; ++ int FftMode; ++ ++ unsigned long CfreqOffBinary; ++ long CfreqOffInt; ++ ++ long ConstWithBandwidthMode, ConstWithFftMode; ++ ++ MPI MpiCfreqOffInt; ++ MPI MpiConstWithBandwidthMode, MpiConstWithFftMode; ++ MPI MpiConst, MpiVar0, MpiVar1, MpiNone; ++ ++ ++ ++ // Get demod bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_bandwidth_mode; ++ ++ ++ // Get demod FFT mode. ++ if(pDemod->GetFftMode(pDemod, &FftMode) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Get CfreqOff binary value from CFREQ_OFF register bits. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_CFREQ_OFF, &CfreqOffBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Convert CfreqOff binary value to signed integer. ++ CfreqOffInt = BinToSignedInt(CfreqOffBinary, RTL2832_CFREQ_OFF_BIT_NUM); ++ ++ ++ // Determine constant value with bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: ConstWithBandwidthMode = 48000000; break; ++ case DVBT_BANDWIDTH_7MHZ: ConstWithBandwidthMode = 56000000; break; ++ case DVBT_BANDWIDTH_8MHZ: ConstWithBandwidthMode = 64000000; break; ++ } ++ ++ ++ // Determine constant value with FFT mode. ++ switch(FftMode) ++ { ++ default: ++ case DVBT_FFT_MODE_2K: ConstWithFftMode = 2048; break; ++ case DVBT_FFT_MODE_8K: ConstWithFftMode = 8192; break; ++ } ++ ++ ++ // Get Cr offset in Hz. ++ // Note: Original formula: CrOffsetHz = (CfreqOffInt * ConstWithBandwidthMode) / (ConstWithFftMode * 7 * 128) ++ // Adjusted formula: CrOffsetHz = (CfreqOffInt * ConstWithBandwidthMode) / ((ConstWithFftMode * 7) << 7) ++ MpiSetValue(&MpiCfreqOffInt, CfreqOffInt); ++ MpiSetValue(&MpiConstWithBandwidthMode, ConstWithBandwidthMode); ++ MpiSetValue(&MpiConstWithFftMode, ConstWithFftMode); ++ MpiSetValue(&MpiConst, 7); ++ ++ MpiMul(&MpiVar0, MpiCfreqOffInt, MpiConstWithBandwidthMode); ++ MpiMul(&MpiVar1, MpiConstWithFftMode, MpiConst); ++ MpiLeftShift(&MpiVar1, MpiVar1, 7); ++ MpiDiv(&MpiVar0, &MpiNone, MpiVar0, MpiVar1); ++ ++ MpiGetValue(MpiVar0, pCrOffsetHz); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_get_demod_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CONSTELLATION ++ ++*/ ++int ++rtl2832_GetConstellation( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConstellation ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS constellation information from RX_CONSTEL. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_CONSTEL, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pConstellation = DVBT_CONSTELLATION_QPSK; break; ++ case 1: *pConstellation = DVBT_CONSTELLATION_16QAM; break; ++ case 2: *pConstellation = DVBT_CONSTELLATION_64QAM; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_HIERARCHY ++ ++*/ ++int ++rtl2832_GetHierarchy( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pHierarchy ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS hierarchy infromation from RX_HIER. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_HIER, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pHierarchy = DVBT_HIERARCHY_NONE; break; ++ case 1: *pHierarchy = DVBT_HIERARCHY_ALPHA_1; break; ++ case 2: *pHierarchy = DVBT_HIERARCHY_ALPHA_2; break; ++ case 3: *pHierarchy = DVBT_HIERARCHY_ALPHA_4; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CODE_RATE_LP ++ ++*/ ++int ++rtl2832_GetCodeRateLp( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateLp ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS low-priority code rate infromation from RX_C_RATE_LP. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_C_RATE_LP, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pCodeRateLp = DVBT_CODE_RATE_1_OVER_2; break; ++ case 1: *pCodeRateLp = DVBT_CODE_RATE_2_OVER_3; break; ++ case 2: *pCodeRateLp = DVBT_CODE_RATE_3_OVER_4; break; ++ case 3: *pCodeRateLp = DVBT_CODE_RATE_5_OVER_6; break; ++ case 4: *pCodeRateLp = DVBT_CODE_RATE_7_OVER_8; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CODE_RATE_HP ++ ++*/ ++int ++rtl2832_GetCodeRateHp( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateHp ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS high-priority code rate infromation from RX_C_RATE_HP. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RX_C_RATE_HP, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pCodeRateHp = DVBT_CODE_RATE_1_OVER_2; break; ++ case 1: *pCodeRateHp = DVBT_CODE_RATE_2_OVER_3; break; ++ case 2: *pCodeRateHp = DVBT_CODE_RATE_3_OVER_4; break; ++ case 3: *pCodeRateHp = DVBT_CODE_RATE_5_OVER_6; break; ++ case 4: *pCodeRateHp = DVBT_CODE_RATE_7_OVER_8; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_GUARD_INTERVAL ++ ++*/ ++int ++rtl2832_GetGuardInterval( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pGuardInterval ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS guard interval infromation from GI_IDX. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_GI_IDX, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_32; break; ++ case 1: *pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_16; break; ++ case 2: *pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_8; break; ++ case 3: *pGuardInterval = DVBT_GUARD_INTERVAL_1_OVER_4; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_FFT_MODE ++ ++*/ ++int ++rtl2832_GetFftMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pFftMode ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ // Get TPS FFT mode infromation from FFT_MODE_IDX. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FFT_MODE_IDX, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(ReadingValue) ++ { ++ default: ++ case 0: *pFftMode = DVBT_FFT_MODE_2K; break; ++ case 1: *pFftMode = DVBT_FFT_MODE_8K; break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2832_UpdateFunction( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Execute Function 1 according to Function 1 enabling status ++ if(pExtra->IsFunc1Enabled == YES) ++ { ++ if(rtl2832_func1_Update(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_RESET_FUNCTION ++ ++*/ ++int ++rtl2832_ResetFunction( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Reset Function 1 settings according to Function 1 enabling status. ++ if(pExtra->IsFunc1Enabled == YES) ++ { ++ if(rtl2832_func1_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD ++ ++*/ ++int ++rtl2832_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send I2C reading command. ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_reading_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_reading_command: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD ++ ++*/ ++int ++rtl2832_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send I2C writing command. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, pWritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_writing_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_writing_command: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Initialize RTL2832 register table. ++ ++Use rtl2832_InitRegTable() to initialize RTL2832 register table. ++ ++ ++@param [in] pDemod RTL2832 demod module pointer ++ ++ ++@note ++ -# The rtl2832_InitRegTable() function will be called by BuildRtl2832Module(). ++ ++*/ ++void ++rtl2832_InitRegTable( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ static const DVBT_PRIMARY_REG_ENTRY PrimaryRegTable[RTL2832_REG_TABLE_LEN] = ++ { ++ // Software reset register ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_SOFT_RST, 0x1, 0x1, 2, 2}, ++ ++ // Tuner I2C forwording register ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_IIC_REPEAT, 0x1, 0x1, 3, 3}, ++ ++ // Registers for initialization ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_TR_WAIT_MIN_8K, 0x1, 0x88, 11, 2}, ++ {DVBT_RSD_BER_FAIL_VAL, 0x1, 0x8f, 15, 0}, ++ {DVBT_EN_BK_TRK, 0x1, 0xa6, 7, 7}, ++ {DVBT_AD_EN_REG, 0x0, 0x8, 7, 7}, ++ {DVBT_AD_EN_REG1, 0x0, 0x8, 6, 6}, ++ {DVBT_EN_BBIN, 0x1, 0xb1, 0, 0}, ++ {DVBT_MGD_THD0, 0x1, 0x95, 7, 0}, ++ {DVBT_MGD_THD1, 0x1, 0x96, 7, 0}, ++ {DVBT_MGD_THD2, 0x1, 0x97, 7, 0}, ++ {DVBT_MGD_THD3, 0x1, 0x98, 7, 0}, ++ {DVBT_MGD_THD4, 0x1, 0x99, 7, 0}, ++ {DVBT_MGD_THD5, 0x1, 0x9a, 7, 0}, ++ {DVBT_MGD_THD6, 0x1, 0x9b, 7, 0}, ++ {DVBT_MGD_THD7, 0x1, 0x9c, 7, 0}, ++ {DVBT_EN_CACQ_NOTCH, 0x1, 0x61, 4, 4}, ++ {DVBT_AD_AV_REF, 0x0, 0x9, 6, 0}, ++ {DVBT_REG_PI, 0x0, 0xa, 2, 0}, ++ {DVBT_PIP_ON, 0x0, 0x21, 3, 3}, ++ {DVBT_SCALE1_B92, 0x2, 0x92, 7, 0}, ++ {DVBT_SCALE1_B93, 0x2, 0x93, 7, 0}, ++ {DVBT_SCALE1_BA7, 0x2, 0xa7, 7, 0}, ++ {DVBT_SCALE1_BA9, 0x2, 0xa9, 7, 0}, ++ {DVBT_SCALE1_BAA, 0x2, 0xaa, 7, 0}, ++ {DVBT_SCALE1_BAB, 0x2, 0xab, 7, 0}, ++ {DVBT_SCALE1_BAC, 0x2, 0xac, 7, 0}, ++ {DVBT_SCALE1_BB0, 0x2, 0xb0, 7, 0}, ++ {DVBT_SCALE1_BB1, 0x2, 0xb1, 7, 0}, ++ {DVBT_KB_P1, 0x1, 0x64, 3, 1}, ++ {DVBT_KB_P2, 0x1, 0x64, 6, 4}, ++ {DVBT_KB_P3, 0x1, 0x65, 2, 0}, ++ {DVBT_OPT_ADC_IQ, 0x0, 0x6, 5, 4}, ++ {DVBT_AD_AVI, 0x0, 0x9, 1, 0}, ++ {DVBT_AD_AVQ, 0x0, 0x9, 3, 2}, ++ {DVBT_K1_CR_STEP12, 0x2, 0xad, 9, 4}, ++ ++ // Registers for initialization according to mode ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_TRK_KS_P2, 0x1, 0x6f, 2, 0}, ++ {DVBT_TRK_KS_I2, 0x1, 0x70, 5, 3}, ++ {DVBT_TR_THD_SET2, 0x1, 0x72, 3, 0}, ++ {DVBT_TRK_KC_P2, 0x1, 0x73, 5, 3}, ++ {DVBT_TRK_KC_I2, 0x1, 0x75, 2, 0}, ++ {DVBT_CR_THD_SET2, 0x1, 0x76, 7, 6}, ++ ++ // Registers for IF setting ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_PSET_IFFREQ, 0x1, 0x19, 21, 0}, ++ {DVBT_SPEC_INV, 0x1, 0x15, 0, 0}, ++ ++ // Registers for bandwidth programming ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_RSAMP_RATIO, 0x1, 0x9f, 27, 2}, ++ {DVBT_CFREQ_OFF_RATIO, 0x1, 0x9d, 23, 4}, ++ ++ // FSM stage register ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_FSM_STAGE, 0x3, 0x51, 6, 3}, ++ ++ // TPS content registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_RX_CONSTEL, 0x3, 0x3c, 3, 2}, ++ {DVBT_RX_HIER, 0x3, 0x3c, 6, 4}, ++ {DVBT_RX_C_RATE_LP, 0x3, 0x3d, 2, 0}, ++ {DVBT_RX_C_RATE_HP, 0x3, 0x3d, 5, 3}, ++ {DVBT_GI_IDX, 0x3, 0x51, 1, 0}, ++ {DVBT_FFT_MODE_IDX, 0x3, 0x51, 2, 2}, ++ ++ // Performance measurement registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_RSD_BER_EST, 0x3, 0x4e, 15, 0}, ++ {DVBT_CE_EST_EVM, 0x4, 0xc, 15, 0}, ++ ++ // AGC registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_RF_AGC_VAL, 0x3, 0x5b, 13, 0}, ++ {DVBT_IF_AGC_VAL, 0x3, 0x59, 13, 0}, ++ {DVBT_DAGC_VAL, 0x3, 0x5, 7, 0}, ++ ++ // TR offset and CR offset registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_SFREQ_OFF, 0x3, 0x18, 13, 0}, ++ {DVBT_CFREQ_OFF, 0x3, 0x5f, 17, 0}, ++ ++ // AGC relative registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_POLAR_RF_AGC, 0x0, 0xe, 1, 1}, ++ {DVBT_POLAR_IF_AGC, 0x0, 0xe, 0, 0}, ++ {DVBT_AAGC_HOLD, 0x1, 0x4, 5, 5}, ++ {DVBT_EN_RF_AGC, 0x1, 0x4, 6, 6}, ++ {DVBT_EN_IF_AGC, 0x1, 0x4, 7, 7}, ++ {DVBT_IF_AGC_MIN, 0x1, 0x8, 7, 0}, ++ {DVBT_IF_AGC_MAX, 0x1, 0x9, 7, 0}, ++ {DVBT_RF_AGC_MIN, 0x1, 0xa, 7, 0}, ++ {DVBT_RF_AGC_MAX, 0x1, 0xb, 7, 0}, ++ {DVBT_IF_AGC_MAN, 0x1, 0xc, 6, 6}, ++ {DVBT_IF_AGC_MAN_VAL, 0x1, 0xc, 13, 0}, ++ {DVBT_RF_AGC_MAN, 0x1, 0xe, 6, 6}, ++ {DVBT_RF_AGC_MAN_VAL, 0x1, 0xe, 13, 0}, ++ {DVBT_DAGC_TRG_VAL, 0x1, 0x12, 7, 0}, ++ {DVBT_AGC_TARG_VAL_0, 0x1, 0x2, 0, 0}, ++ {DVBT_AGC_TARG_VAL_8_1, 0x1, 0x3, 7, 0}, ++ {DVBT_AAGC_LOOP_GAIN, 0x1, 0xc7, 5, 1}, ++ {DVBT_LOOP_GAIN2_3_0, 0x1, 0x4, 4, 1}, ++ {DVBT_LOOP_GAIN2_4, 0x1, 0x5, 7, 7}, ++ {DVBT_LOOP_GAIN3, 0x1, 0xc8, 4, 0}, ++ {DVBT_VTOP1, 0x1, 0x6, 5, 0}, ++ {DVBT_VTOP2, 0x1, 0xc9, 5, 0}, ++ {DVBT_VTOP3, 0x1, 0xca, 5, 0}, ++ {DVBT_KRF1, 0x1, 0xcb, 7, 0}, ++ {DVBT_KRF2, 0x1, 0x7, 7, 0}, ++ {DVBT_KRF3, 0x1, 0xcd, 7, 0}, ++ {DVBT_KRF4, 0x1, 0xce, 7, 0}, ++ {DVBT_EN_GI_PGA, 0x1, 0xe5, 0, 0}, ++ {DVBT_THD_LOCK_UP, 0x1, 0xd9, 8, 0}, ++ {DVBT_THD_LOCK_DW, 0x1, 0xdb, 8, 0}, ++ {DVBT_THD_UP1, 0x1, 0xdd, 7, 0}, ++ {DVBT_THD_DW1, 0x1, 0xde, 7, 0}, ++ {DVBT_INTER_CNT_LEN, 0x1, 0xd8, 3, 0}, ++ {DVBT_GI_PGA_STATE, 0x1, 0xe6, 3, 3}, ++ {DVBT_EN_AGC_PGA, 0x1, 0xd7, 0, 0}, ++ ++ // TS interface registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_CKOUTPAR, 0x1, 0x7b, 5, 5}, ++ {DVBT_CKOUT_PWR, 0x1, 0x7b, 6, 6}, ++ {DVBT_SYNC_DUR, 0x1, 0x7b, 7, 7}, ++ {DVBT_ERR_DUR, 0x1, 0x7c, 0, 0}, ++ {DVBT_SYNC_LVL, 0x1, 0x7c, 1, 1}, ++ {DVBT_ERR_LVL, 0x1, 0x7c, 2, 2}, ++ {DVBT_VAL_LVL, 0x1, 0x7c, 3, 3}, ++ {DVBT_SERIAL, 0x1, 0x7c, 4, 4}, ++ {DVBT_SER_LSB, 0x1, 0x7c, 5, 5}, ++ {DVBT_CDIV_PH0, 0x1, 0x7d, 3, 0}, ++ {DVBT_CDIV_PH1, 0x1, 0x7d, 7, 4}, ++ {DVBT_MPEG_IO_OPT_2_2, 0x0, 0x6, 7, 7}, ++ {DVBT_MPEG_IO_OPT_1_0, 0x0, 0x7, 7, 6}, ++ {DVBT_CKOUTPAR_PIP, 0x0, 0xb7, 4, 4}, ++ {DVBT_CKOUT_PWR_PIP, 0x0, 0xb7, 3, 3}, ++ {DVBT_SYNC_LVL_PIP, 0x0, 0xb7, 2, 2}, ++ {DVBT_ERR_LVL_PIP, 0x0, 0xb7, 1, 1}, ++ {DVBT_VAL_LVL_PIP, 0x0, 0xb7, 0, 0}, ++ {DVBT_CKOUTPAR_PID, 0x0, 0xb9, 4, 4}, ++ {DVBT_CKOUT_PWR_PID, 0x0, 0xb9, 3, 3}, ++ {DVBT_SYNC_LVL_PID, 0x0, 0xb9, 2, 2}, ++ {DVBT_ERR_LVL_PID, 0x0, 0xb9, 1, 1}, ++ {DVBT_VAL_LVL_PID, 0x0, 0xb9, 0, 0}, ++ ++ // FSM state-holding register ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_SM_PASS, 0x1, 0x93, 11, 0}, ++ ++ // AD7 registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_AD7_SETTING, 0x0, 0x11, 15, 0}, ++ {DVBT_RSSI_R, 0x3, 0x1, 6, 0}, ++ ++ // ACI detection registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_ACI_DET_IND, 0x3, 0x12, 0, 0}, ++ ++ // Clock output registers ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DVBT_REG_MON, 0x0, 0xd, 1, 0}, ++ {DVBT_REG_MONSEL, 0x0, 0xd, 2, 2}, ++ {DVBT_REG_GPE, 0x0, 0xd, 7, 7}, ++ {DVBT_REG_GPO, 0x0, 0x10, 0, 0}, ++ {DVBT_REG_4MSEL, 0x0, 0x13, 0, 0}, ++ }; ++ ++ ++ int i; ++ int RegBitName; ++ ++ ++ ++ // Initialize register table according to primary register table. ++ // Note: 1. Register table rows are sorted by register bit name key. ++ // 2. The default value of the IsAvailable variable is "NO". ++ for(i = 0; i < DVBT_REG_TABLE_LEN_MAX; i++) ++ pDemod->RegTable[i].IsAvailable = NO; ++ ++ for(i = 0; i < RTL2832_REG_TABLE_LEN; i++) ++ { ++ RegBitName = PrimaryRegTable[i].RegBitName; ++ ++ pDemod->RegTable[RegBitName].IsAvailable = YES; ++ pDemod->RegTable[RegBitName].PageNo = PrimaryRegTable[i].PageNo; ++ pDemod->RegTable[RegBitName].RegStartAddr = PrimaryRegTable[i].RegStartAddr; ++ pDemod->RegTable[RegBitName].Msb = PrimaryRegTable[i].Msb; ++ pDemod->RegTable[RegBitName].Lsb = PrimaryRegTable[i].Lsb; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set I2C bridge module demod arguments. ++ ++RTL2832 builder will use rtl2832_BuildI2cBridgeModule() to set I2C bridge module demod arguments. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2832Module() ++ ++*/ ++void ++rtl2832_BuildI2cBridgeModule( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ ++ // Get I2C bridge module. ++ pI2cBridge = pDemod->pI2cBridge; ++ ++ // Set I2C bridge module demod arguments. ++ pI2cBridge->pPrivateData = (void *)pDemod; ++ pI2cBridge->ForwardI2cReadingCmd = rtl2832_ForwardI2cReadingCmd; ++ pI2cBridge->ForwardI2cWritingCmd = rtl2832_ForwardI2cWritingCmd; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/* ++ ++@see RTL2832_FP_GET_APP_MODE ++ ++*/ ++void ++rtl2832_GetAppMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAppMode ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Get demod type from demod module. ++ *pAppMode = pExtra->AppMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Reset Function 1 variables and registers. ++ ++One can use rtl2832_func1_Reset() to reset Function 1 variables and registers. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset Function 1 variables and registers successfully. ++@retval FUNCTION_ERROR Reset Function 1 variables and registers unsuccessfully. ++ ++ ++@note ++ -# Need to execute Function 1 reset function when change tuner RF frequency or demod parameters. ++ -# Function 1 update flow also employs Function 1 reset function. ++ ++*/ ++int ++rtl2832_func1_Reset( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ // Reset demod Function 1 variables. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_NORMAL; ++ pExtra->Func1WaitTime = 0; ++ pExtra->Func1GettingTime = 0; ++ pExtra->Func1RsdBerEstSumNormal = 0; ++ pExtra->Func1RsdBerEstSumConfig1 = 0; ++ pExtra->Func1RsdBerEstSumConfig2 = 0; ++ pExtra->Func1RsdBerEstSumConfig3 = 0; ++ ++ ++ // Reset demod Function 1 registers. ++ if(rtl2832_func1_ResetReg(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update demod registers with Function 1. ++ ++One can use rtl2832_func1_Update() to update demod registers with Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod registers with Function 1 successfully. ++@retval FUNCTION_ERROR Update demod registers with Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_Update( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ int Answer; ++ int MinWeightedBerConfigMode; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Run FSM. ++ switch(pExtra->Func1State) ++ { ++ case RTL2832_FUNC1_STATE_NORMAL: ++ ++ // Ask if criterion is matched. ++ if(rtl2832_func1_IsCriterionMatched(pDemod, &Answer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(Answer == YES) ++ { ++ // Accumulate RSD_BER_EST for normal case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumNormal) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset getting time counter. ++ pExtra->Func1GettingTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_NORMAL_GET_BER state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_NORMAL_GET_BER; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_NORMAL_GET_BER: ++ ++ // Accumulate RSD_BER_EST for normal case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumNormal) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Use getting time counter to hold RTL2832_FUNC1_STATE_NORMAL_GET_BER state several times. ++ pExtra->Func1GettingTime += 1; ++ ++ if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax) ++ { ++ // Set common registers for configuration 1, 2, and 3 case. ++ if(rtl2832_func1_SetCommonReg(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set registers with FFT mode for configuration 1, 2, and 3 case. ++ if(rtl2832_func1_SetRegWithFftMode(pDemod, pExtra->Func1FftBak) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set registers for configuration 1 case. ++ if(rtl2832_func1_SetRegWithConfigMode(pDemod, RTL2832_FUNC1_CONFIG_1) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset wait time counter. ++ pExtra->Func1WaitTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_1_WAIT state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_1_WAIT; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_1_WAIT: ++ ++ // Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_1_WAIT state several times. ++ pExtra->Func1WaitTime += 1; ++ ++ if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax) ++ { ++ // Accumulate RSD_BER_EST for configuration 1 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig1) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset getting time counter. ++ pExtra->Func1GettingTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_1_GET_BER state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_1_GET_BER; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_1_GET_BER: ++ ++ // Accumulate RSD_BER_EST for configuration 1 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig1) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Use getting time counter to hold RTL2832_FUNC1_STATE_CONFIG_1_GET_BER state several times. ++ pExtra->Func1GettingTime += 1; ++ ++ if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax) ++ { ++ // Set registers for configuration 2 case. ++ if(rtl2832_func1_SetRegWithConfigMode(pDemod, RTL2832_FUNC1_CONFIG_2) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset wait time counter. ++ pExtra->Func1WaitTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_2_WAIT state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_2_WAIT; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_2_WAIT: ++ ++ // Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_2_WAIT state several times. ++ pExtra->Func1WaitTime += 1; ++ ++ if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax) ++ { ++ // Accumulate RSD_BER_EST for configuration 2 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig2) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset getting time counter. ++ pExtra->Func1GettingTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_2_GET_BER state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_2_GET_BER; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_2_GET_BER: ++ ++ // Accumulate RSD_BER_EST for configuration 2 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig2) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Use getting time counter to hold RTL2832_FUNC1_STATE_CONFIG_2_GET_BER state several times. ++ pExtra->Func1GettingTime += 1; ++ ++ if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax) ++ { ++ // Set registers for configuration 3 case. ++ if(rtl2832_func1_SetRegWithConfigMode(pDemod, RTL2832_FUNC1_CONFIG_3) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset wait time counter. ++ pExtra->Func1WaitTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_3_WAIT state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_3_WAIT; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_3_WAIT: ++ ++ // Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_3_WAIT state several times. ++ pExtra->Func1WaitTime += 1; ++ ++ if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax) ++ { ++ // Accumulate RSD_BER_EST for configuration 3 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig3) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset getting time counter. ++ pExtra->Func1GettingTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_CONFIG_3_GET_BER state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_CONFIG_3_GET_BER; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_CONFIG_3_GET_BER: ++ ++ // Accumulate RSD_BER_EST for configuration 3 case. ++ if(rtl2832_func1_AccumulateRsdBerEst(pDemod, &pExtra->Func1RsdBerEstSumConfig3) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Use getting time counter to hold RTL2832_FUNC1_STATE_CONFIG_3_GET_BER state several times. ++ pExtra->Func1GettingTime += 1; ++ ++ if(pExtra->Func1GettingTime >= pExtra->Func1GettingTimeMax) ++ { ++ // Determine minimum-weighted-BER configuration mode. ++ rtl2832_func1_GetMinWeightedBerConfigMode(pDemod, &MinWeightedBerConfigMode); ++ ++ // Set registers with minimum-weighted-BER configuration mode. ++ switch(MinWeightedBerConfigMode) ++ { ++ case RTL2832_FUNC1_CONFIG_NORMAL: ++ ++ // Reset registers for normal configuration. ++ if(rtl2832_func1_ResetReg(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_CONFIG_1: ++ case RTL2832_FUNC1_CONFIG_2: ++ case RTL2832_FUNC1_CONFIG_3: ++ ++ // Set registers for minimum-weighted-BER configuration. ++ if(rtl2832_func1_SetRegWithConfigMode(pDemod, MinWeightedBerConfigMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ default: ++ ++ // Get error configuration mode, reset registers. ++ if(rtl2832_func1_ResetReg(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset wait time counter. ++ pExtra->Func1WaitTime = 0; ++ ++ // Go to RTL2832_FUNC1_STATE_DETERMINED_WAIT state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_DETERMINED_WAIT; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_DETERMINED_WAIT: ++ ++ // Use wait time counter to hold RTL2832_FUNC1_STATE_CONFIG_3_WAIT state several times. ++ pExtra->Func1WaitTime += 1; ++ ++ if(pExtra->Func1WaitTime >= pExtra->Func1WaitTimeMax) ++ { ++ // Go to RTL2832_FUNC1_STATE_DETERMINED state. ++ pExtra->Func1State = RTL2832_FUNC1_STATE_DETERMINED; ++ } ++ ++ break; ++ ++ ++ case RTL2832_FUNC1_STATE_DETERMINED: ++ ++ // Ask if criterion is matched. ++ if(rtl2832_func1_IsCriterionMatched(pDemod, &Answer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(Answer == NO) ++ { ++ // Reset FSM. ++ // Note: rtl2832_func1_Reset() will set FSM state with RTL2832_FUNC1_STATE_NORMAL. ++ if(rtl2832_func1_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ break; ++ ++ ++ default: ++ ++ // Get error state, reset FSM. ++ // Note: rtl2832_func1_Reset() will set FSM state with RTL2832_FUNC1_STATE_NORMAL. ++ if(rtl2832_func1_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Ask if criterion is matched for Function 1. ++ ++One can use rtl2832_func1_IsCriterionMatched() to ask if criterion is matched for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Ask if criterion is matched for Function 1 successfully. ++@retval FUNCTION_ERROR Ask if criterion is matched for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_IsCriterionMatched( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ unsigned long FsmStage; ++ ++ int Qam; ++ int Hier; ++ int LpCr; ++ int HpCr; ++ int Gi; ++ int Fft; ++ ++ unsigned long Reg0, Reg1; ++ ++ int BandwidthMode; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Get FSM_STAGE. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Get QAM. ++ if(pDemod->GetConstellation(pDemod, &Qam) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get hierarchy. ++ if(pDemod->GetHierarchy(pDemod, &Hier) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get low-priority code rate. ++ if(pDemod->GetCodeRateLp(pDemod, &LpCr) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get high-priority code rate. ++ if(pDemod->GetCodeRateHp(pDemod, &HpCr) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get guard interval. ++ if(pDemod->GetGuardInterval(pDemod, &Gi) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get FFT mode. ++ if(pDemod->GetFftMode(pDemod, &Fft) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Get REG_0 and REG_1. ++ if(pDemod->SetRegPage(pDemod, 0x3) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->GetRegMaskBits(pDemod, 0x22, 0, 0, &Reg0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->GetRegMaskBits(pDemod, 0x1a, 15, 3, &Reg1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Get bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Determine criterion answer. ++ *pAnswer = ++ (FsmStage == 11) && ++ ++ (Qam == pExtra->Func1QamBak) && ++ (Hier == pExtra->Func1HierBak) && ++ (LpCr == pExtra->Func1LpCrBak) && ++ (HpCr == pExtra->Func1HpCrBak) && ++ (Gi == pExtra->Func1GiBak) && ++ (Fft == pExtra->Func1FftBak) && ++ ++ (Reg0 == 0x1) && ++ ++ ((BandwidthMode == DVBT_BANDWIDTH_8MHZ) && ++ ( ((Fft == DVBT_FFT_MODE_2K) && (Reg1 > 1424) && (Reg1 < 1440)) || ++ ((Fft == DVBT_FFT_MODE_8K) && (Reg1 > 5696) && (Reg1 < 5760)) ) ); ++ ++ ++ // Backup TPS information. ++ pExtra->Func1QamBak = Qam; ++ pExtra->Func1HierBak = Hier; ++ pExtra->Func1LpCrBak = LpCr; ++ pExtra->Func1HpCrBak = HpCr; ++ pExtra->Func1GiBak = Gi; ++ pExtra->Func1FftBak = Fft; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Accumulate RSD_BER_EST value for Function 1. ++ ++One can use rtl2832_func1_AccumulateRsdBerEst() to accumulate RSD_BER_EST for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] pAccumulativeValue Accumulative RSD_BER_EST value ++ ++ ++@retval FUNCTION_SUCCESS Accumulate RSD_BER_EST for Function 1 successfully. ++@retval FUNCTION_ERROR Accumulate RSD_BER_EST for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_AccumulateRsdBerEst( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pAccumulativeValue ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ int i; ++ unsigned long RsdBerEst; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Get RSD_BER_EST with assigned times. ++ for(i = 0; i < pExtra->Func1GettingNumEachTime; i++) ++ { ++ // Get RSD_BER_EST. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Accumulate RSD_BER_EST to accumulative value. ++ *pAccumulativeValue += RsdBerEst; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Reset registers for Function 1. ++ ++One can use rtl2832_func1_ResetReg() to reset registers for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset registers for Function 1 successfully. ++@retval FUNCTION_ERROR Reset registers for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_ResetReg( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Reset Function 1 registers. ++ if(pDemod->SetRegPage(pDemod, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x65, 2, 0, 0x7) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x68, 5, 4, 0x3) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5b, 2, 0, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5b, 5, 3, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5c, 2, 0, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5c, 5, 3, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd0, 3, 2, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd1, 14, 0, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd3, 14, 0, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd5, 14, 0, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x1, 0, 0, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xb4, 7, 6, 0x3) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd2, 1, 1, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xb5, 7, 7, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set common registers for Function 1. ++ ++One can use rtl2832_func1_SetCommonReg() to set common registers for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Set common registers for Function 1 successfully. ++@retval FUNCTION_ERROR Set common registers for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_SetCommonReg( ++ DVBT_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Set common registers for Function 1. ++ if(pDemod->SetRegPage(pDemod, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x65, 2, 0, 0x5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x68, 5, 4, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd2, 1, 1, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xb5, 7, 7, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set registers with FFT mode for Function 1. ++ ++One can use rtl2832_func1_SetRegWithConfigMode() to set registers with FFT mode for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] FftMode FFT mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set registers with FFT mode for Function 1 successfully. ++@retval FUNCTION_ERROR Set registers with FFT mode for Function 1 unsuccessfully. ++ ++*/ ++int ++rtl2832_func1_SetRegWithFftMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int FftMode ++ ) ++{ ++ typedef struct ++ { ++ unsigned long Reg0[DVBT_FFT_MODE_NUM]; ++ unsigned long Reg1[DVBT_FFT_MODE_NUM]; ++ } ++ FFT_REF_ENTRY; ++ ++ ++ ++ static const FFT_REF_ENTRY FftRefTable = ++ { ++ // 2K mode, 8K mode ++ {0x0, 0x1 }, ++ {0x3, 0x0 }, ++ }; ++ ++ ++ ++ // Set registers with FFT mode for Function 1. ++ if(pDemod->SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x1, 0, 0, FftRefTable.Reg0[FftMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xb4, 7, 6, FftRefTable.Reg1[FftMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set registers with configuration mode for Function 1. ++ ++One can use rtl2832_func1_SetRegWithConfigMode() to set registers with configuration mode for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] ConfigMode Configuration mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set registers with configuration mode for Function 1 successfully. ++@retval FUNCTION_ERROR Set registers with configuration mode for Function 1 unsuccessfully. ++ ++ ++@note ++ -# This function can not set RTL2832_FUNC1_CONFIG_NORMAL configuration mode. ++ ++*/ ++int ++rtl2832_func1_SetRegWithConfigMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int ConfigMode ++ ) ++{ ++ typedef struct ++ { ++ unsigned long Reg0[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg1[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg2[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg3[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg4[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ ++ unsigned long Reg5Ref[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg6Ref[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ unsigned long Reg7Ref[RTL2832_FUNC1_CONFIG_MODE_NUM]; ++ } ++ CONFIG_REF_ENTRY; ++ ++ ++ ++ static const CONFIG_REF_ENTRY ConfigRefTable = ++ { ++ // Config 1, Config 2, Config 3 ++ {0x5, 0x4, 0x5 }, ++ {0x5, 0x4, 0x7 }, ++ {0x5, 0x4, 0x7 }, ++ {0x7, 0x6, 0x5 }, ++ {0x3, 0x3, 0x2 }, ++ ++ {4437, 4437, 4325 }, ++ {6000, 5500, 6500 }, ++ {6552, 5800, 5850 }, ++ }; ++ ++ int BandwidthMode; ++ ++ static const unsigned long Const[DVBT_BANDWIDTH_MODE_NUM] = ++ { ++ // 6Mhz, 7Mhz, 8Mhz ++ 48, 56, 64, ++ }; ++ ++ unsigned long Reg5, Reg6, Reg7; ++ ++ ++ ++ // Get bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Calculate REG_5, REG_6, and REG_7 with bandwidth mode and configuration mode. ++ Reg5 = (ConfigRefTable.Reg5Ref[ConfigMode] * 7 * 2048 * 8) / (1000 * Const[BandwidthMode]); ++ Reg6 = (ConfigRefTable.Reg6Ref[ConfigMode] * 7 * 2048 * 8) / (1000 * Const[BandwidthMode]); ++ Reg7 = (ConfigRefTable.Reg7Ref[ConfigMode] * 7 * 2048 * 8) / (1000 * Const[BandwidthMode]); ++ ++ ++ // Set registers with bandwidth mode and configuration mode. ++ if(pDemod->SetRegPage(pDemod, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5b, 2, 0, ConfigRefTable.Reg0[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5b, 5, 3, ConfigRefTable.Reg1[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5c, 2, 0, ConfigRefTable.Reg2[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0x5c, 5, 3, ConfigRefTable.Reg3[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd0, 3, 2, ConfigRefTable.Reg4[ConfigMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd1, 14, 0, Reg5) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd3, 14, 0, Reg6) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->SetRegMaskBits(pDemod, 0xd5, 14, 0, Reg7) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get minimum-weighted-BER configuration mode for Function 1. ++ ++One can use rtl2832_func1_GetMinWeightedBerConfigMode() to get minimum-weighted-BER configuration mode for Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pConfigMode Pointer to an allocated memory for storing configuration mode answer ++ ++ ++@retval FUNCTION_SUCCESS Get minimum-weighted-BER configuration mode for Function 1 successfully. ++@retval FUNCTION_ERROR Get minimum-weighted-BER configuration mode for Function 1 unsuccessfully. ++ ++*/ ++void ++rtl2832_func1_GetMinWeightedBerConfigMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConfigMode ++ ) ++{ ++ RTL2832_EXTRA_MODULE *pExtra; ++ ++ unsigned long WeightedBerNormal; ++ unsigned long WeightedBerConfig1; ++ unsigned long WeightedBerConfig2; ++ unsigned long WeightedBerConfig3; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2832); ++ ++ ++ // Calculate weighted BER for all configuration mode ++ WeightedBerNormal = pExtra->Func1RsdBerEstSumNormal * 2; ++ WeightedBerConfig1 = pExtra->Func1RsdBerEstSumConfig1; ++ WeightedBerConfig2 = pExtra->Func1RsdBerEstSumConfig2; ++ WeightedBerConfig3 = pExtra->Func1RsdBerEstSumConfig3; ++ ++ ++ // Determine minimum-weighted-BER configuration mode. ++ if(WeightedBerNormal <= WeightedBerConfig1 && ++ WeightedBerNormal <= WeightedBerConfig2 && ++ WeightedBerNormal <= WeightedBerConfig3) ++ { ++ *pConfigMode = RTL2832_FUNC1_CONFIG_NORMAL; ++ } ++ else if(WeightedBerConfig1 <= WeightedBerNormal && ++ WeightedBerConfig1 <= WeightedBerConfig2 && ++ WeightedBerConfig1 <= WeightedBerConfig3) ++ { ++ *pConfigMode = RTL2832_FUNC1_CONFIG_1; ++ } ++ else if(WeightedBerConfig2 <= WeightedBerNormal && ++ WeightedBerConfig2 <= WeightedBerConfig1 && ++ WeightedBerConfig2 <= WeightedBerConfig3) ++ { ++ *pConfigMode = RTL2832_FUNC1_CONFIG_2; ++ } ++ else if(WeightedBerConfig3 <= WeightedBerNormal && ++ WeightedBerConfig3 <= WeightedBerConfig1 && ++ WeightedBerConfig3 <= WeightedBerConfig2) ++ { ++ *pConfigMode = RTL2832_FUNC1_CONFIG_3; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/demod_rtl2832.h b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2832.h +--- a/drivers/media/dvb/dvb-usb/demod_rtl2832.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2832.h 2016-04-02 19:17:52.080066070 -0300 +@@ -0,0 +1,466 @@ ++#ifndef __DEMOD_RTL2832_H ++#define __DEMOD_RTL2832_H ++ ++/** ++ ++@file ++ ++@brief RTL2832 demod module declaration ++ ++One can manipulate RTL2832 demod through RTL2832 module. ++RTL2832 module is derived from DVB-T demod module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the DVB-T demod example in dvbt_demod_base.h except the listed lines. ++ ++ ++ ++#include "demod_rtl2832.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ ++ ... ++ ++ ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pDemod, ++ &DvbtDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x20, // I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // Crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // Application mode is STB. ++ 200, // Update function reference period is 200 millisecond ++ YES // Function 1 enabling status is YES. ++ ); ++ ++ ++ ++ // See the example for other DVB-T demod functions in dvbt_demod_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "dvbt_demod_base.h" ++ ++ ++extern int dvb_usb_rtl2832u_snrdb; ++ ++ ++// Definitions ++ ++// Initializing ++#define RTL2832_INIT_TABLE_LEN 32 ++#define RTL2832_TS_INTERFACE_INIT_TABLE_LEN 5 ++#define RTL2832_APP_INIT_TABLE_LEN 5 ++ ++ ++// Bandwidth setting ++#define RTL2832_H_LPF_X_PAGE 1 ++#define RTL2832_H_LPF_X_ADDR 0x1c ++#define RTL2832_H_LPF_X_LEN 32 ++#define RTL2832_RATIO_PAGE 1 ++#define RTL2832_RATIO_ADDR 0x9d ++#define RTL2832_RATIO_LEN 6 ++ ++ ++// Bandwidth setting ++#define RTL2832_CFREQ_OFF_RATIO_BIT_NUM 20 ++ ++ ++// IF frequency setting ++#define RTL2832_PSET_IFFREQ_BIT_NUM 22 ++ ++ ++// Signal quality ++#define RTL2832_SQ_FRAC_BIT_NUM 5 ++ ++ ++// BER ++#define RTL2832_BER_DEN_VALUE 1000000 ++ ++ ++// SNR ++#define RTL2832_CE_EST_EVM_MAX_VALUE 65535 ++#define RTL2832_SNR_FRAC_BIT_NUM 10 ++#define RTL2832_SNR_DB_DEN 3402 ++ ++ ++// AGC ++#define RTL2832_RF_AGC_REG_BIT_NUM 14 ++#define RTL2832_IF_AGC_REG_BIT_NUM 14 ++ ++ ++// TR offset and CR offset ++#define RTL2832_SFREQ_OFF_BIT_NUM 14 ++#define RTL2832_CFREQ_OFF_BIT_NUM 18 ++ ++ ++// Register table length ++#define RTL2832_REG_TABLE_LEN 127 ++ ++ ++// Function 1 ++#define RTL2832_FUNC1_WAIT_TIME_MS 500 ++#define RTL2832_FUNC1_GETTING_TIME_MS 200 ++#define RTL2832_FUNC1_GETTING_NUM_MIN 20 ++ ++ ++ ++/// Demod application modes ++enum RTL2832_APPLICATION_MODE ++{ ++ RTL2832_APPLICATION_DONGLE, ++ RTL2832_APPLICATION_STB, ++}; ++#define RTL2832_APPLICATION_MODE_NUM 2 ++ ++ ++// Function 1 ++enum RTL2832_FUNC1_CONFIG_MODE ++{ ++ RTL2832_FUNC1_CONFIG_1, ++ RTL2832_FUNC1_CONFIG_2, ++ RTL2832_FUNC1_CONFIG_3, ++}; ++#define RTL2832_FUNC1_CONFIG_MODE_NUM 3 ++#define RTL2832_FUNC1_CONFIG_NORMAL -1 ++ ++ ++enum RTL2832_FUNC1_STATE ++{ ++ RTL2832_FUNC1_STATE_NORMAL, ++ RTL2832_FUNC1_STATE_NORMAL_GET_BER, ++ RTL2832_FUNC1_STATE_CONFIG_1_WAIT, ++ RTL2832_FUNC1_STATE_CONFIG_1_GET_BER, ++ RTL2832_FUNC1_STATE_CONFIG_2_WAIT, ++ RTL2832_FUNC1_STATE_CONFIG_2_GET_BER, ++ RTL2832_FUNC1_STATE_CONFIG_3_WAIT, ++ RTL2832_FUNC1_STATE_CONFIG_3_GET_BER, ++ RTL2832_FUNC1_STATE_DETERMINED_WAIT, ++ RTL2832_FUNC1_STATE_DETERMINED, ++}; ++ ++ ++ ++ ++ ++// Demod module builder ++void ++BuildRtl2832Module( ++ DVBT_DEMOD_MODULE **ppDemod, ++ DVBT_DEMOD_MODULE *pDvbtDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ int AppMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled ++ ); ++ ++ ++ ++ ++ ++// Manipulating functions ++void ++rtl2832_IsConnectedToI2c( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++); ++ ++int ++rtl2832_SoftwareReset( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_Initialize( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_SetBandwidthMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_SetIfFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++int ++rtl2832_SetSpectrumMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++int ++rtl2832_IsTpsLocked( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2832_IsSignalLocked( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2832_GetSignalStrength( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++rtl2832_GetSignalQuality( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++rtl2832_GetBer( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++int ++rtl2832_GetSnrDb( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++rtl2832_GetRfAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++int ++rtl2832_GetIfAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++int ++rtl2832_GetDiAgc( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDiAgc ++ ); ++ ++int ++rtl2832_GetTrOffsetPpm( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++int ++rtl2832_GetCrOffsetHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++int ++rtl2832_GetConstellation( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConstellation ++ ); ++ ++int ++rtl2832_GetHierarchy( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pHierarchy ++ ); ++ ++int ++rtl2832_GetCodeRateLp( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateLp ++ ); ++ ++int ++rtl2832_GetCodeRateHp( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateHp ++ ); ++ ++int ++rtl2832_GetGuardInterval( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pGuardInterval ++ ); ++ ++int ++rtl2832_GetFftMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pFftMode ++ ); ++ ++int ++rtl2832_UpdateFunction( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_ResetFunction( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// I2C command forwarding functions ++int ++rtl2832_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++rtl2832_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++// Register table initializing ++void ++rtl2832_InitRegTable( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// I2C birdge module builder ++void ++rtl2832_BuildI2cBridgeModule( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// RTL2832 extra functions ++void ++rtl2832_GetAppMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAppMode ++ ); ++ ++ ++ ++ ++ ++// RTL2832 dependence ++int ++rtl2832_func1_Reset( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_func1_Update( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_func1_IsCriterionMatched( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2832_func1_AccumulateRsdBerEst( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pAccumulativeValue ++ ); ++ ++int ++rtl2832_func1_ResetReg( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_func1_SetCommonReg( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2832_func1_SetRegWithFftMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int FftMode ++ ); ++ ++int ++rtl2832_func1_SetRegWithConfigMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int ConfigMode ++ ); ++ ++void ++rtl2832_func1_GetMinWeightedBerConfigMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConfigMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/demod_rtl2836.c b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2836.c +--- a/drivers/media/dvb/dvb-usb/demod_rtl2836.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2836.c 2016-04-02 19:17:52.084066057 -0300 +@@ -0,0 +1,2049 @@ ++/** ++ ++@file ++ ++@brief RTL2836 demod module definition ++ ++One can manipulate RTL2836 demod through RTL2836 module. ++RTL2836 module is derived from DTMB demod module. ++ ++*/ ++ ++ ++#include "demod_rtl2836.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2836 demod module builder ++ ++Use BuildRtl2836Module() to build RTL2836 module, set all module function pointers with the corresponding ++functions, and initialize module private variables. ++ ++ ++@param [in] ppDemod Pointer to RTL2836 demod module pointer ++@param [in] pDtmbDemodModuleMemory Pointer to an allocated DTMB demod module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr RTL2836 I2C device address ++@param [in] CrystalFreqHz RTL2836 crystal frequency in Hz ++@param [in] TsInterfaceMode RTL2836 TS interface mode for setting ++@param [in] UpdateFuncRefPeriodMs RTL2836 update function reference period in millisecond ++@param [in] IsFunc1Enabled RTL2836 Function 1 enabling status for setting ++@param [in] IsFunc2Enabled RTL2836 Function 2 enabling status for setting ++ ++ ++@note ++ -# One should call BuildRtl2836Module() to build RTL2836 module before using it. ++ ++*/ ++void ++BuildRtl2836Module( ++ DTMB_DEMOD_MODULE **ppDemod, ++ DTMB_DEMOD_MODULE *pDtmbDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled, ++ int IsFunc2Enabled ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set demod module pointer, ++ *ppDemod = pDtmbDemodModuleMemory; ++ ++ // Get demod module. ++ pDemod = *ppDemod; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pDemod->pBaseInterface = pBaseInterfaceModuleMemory; ++ pDemod->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Set demod type. ++ pDemod->DemodType = DTMB_DEMOD_TYPE_RTL2836; ++ ++ // Set demod I2C device address. ++ pDemod->DeviceAddr = DeviceAddr; ++ ++ // Set demod crystal frequency in Hz. ++ pDemod->CrystalFreqHz = CrystalFreqHz; ++ ++ // Set demod TS interface mode. ++ pDemod->TsInterfaceMode = TsInterfaceMode; ++ ++ ++ // Initialize demod parameter setting status ++ pDemod->IsIfFreqHzSet = NO; ++ pDemod->IsSpectrumModeSet = NO; ++ ++ ++ // Initialize demod register table. ++ rtl2836_InitRegTable(pDemod); ++ ++ ++ // Build I2C birdge module. ++ rtl2836_BuildI2cBridgeModule(pDemod); ++ ++ ++ // Set demod module I2C function pointers with 8-bit address default functions. ++ pDemod->RegAccess.Addr8Bit.SetRegPage = dtmb_demod_addr_8bit_default_SetRegPage; ++ pDemod->RegAccess.Addr8Bit.SetRegBytes = dtmb_demod_addr_8bit_default_SetRegBytes; ++ pDemod->RegAccess.Addr8Bit.GetRegBytes = dtmb_demod_addr_8bit_default_GetRegBytes; ++ pDemod->RegAccess.Addr8Bit.SetRegMaskBits = dtmb_demod_addr_8bit_default_SetRegMaskBits; ++ pDemod->RegAccess.Addr8Bit.GetRegMaskBits = dtmb_demod_addr_8bit_default_GetRegMaskBits; ++ pDemod->RegAccess.Addr8Bit.SetRegBits = dtmb_demod_addr_8bit_default_SetRegBits; ++ pDemod->RegAccess.Addr8Bit.GetRegBits = dtmb_demod_addr_8bit_default_GetRegBits; ++ pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage = dtmb_demod_addr_8bit_default_SetRegBitsWithPage; ++ pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage = dtmb_demod_addr_8bit_default_GetRegBitsWithPage; ++ ++ ++ // Set demod module manipulating function pointers with default functions. ++ pDemod->GetDemodType = dtmb_demod_default_GetDemodType; ++ pDemod->GetDeviceAddr = dtmb_demod_default_GetDeviceAddr; ++ pDemod->GetCrystalFreqHz = dtmb_demod_default_GetCrystalFreqHz; ++ ++ pDemod->GetIfFreqHz = dtmb_demod_default_GetIfFreqHz; ++ pDemod->GetSpectrumMode = dtmb_demod_default_GetSpectrumMode; ++ ++ ++ // Set demod module manipulating function pointers with particular functions. ++ pDemod->IsConnectedToI2c = rtl2836_IsConnectedToI2c; ++ pDemod->SoftwareReset = rtl2836_SoftwareReset; ++ pDemod->Initialize = rtl2836_Initialize; ++ pDemod->SetIfFreqHz = rtl2836_SetIfFreqHz; ++ pDemod->SetSpectrumMode = rtl2836_SetSpectrumMode; ++ ++ pDemod->IsSignalLocked = rtl2836_IsSignalLocked; ++ ++ pDemod->GetSignalStrength = rtl2836_GetSignalStrength; ++ pDemod->GetSignalQuality = rtl2836_GetSignalQuality; ++ ++ pDemod->GetBer = rtl2836_GetBer; ++ pDemod->GetPer = rtl2836_GetPer; ++ pDemod->GetSnrDb = rtl2836_GetSnrDb; ++ ++ pDemod->GetRfAgc = rtl2836_GetRfAgc; ++ pDemod->GetIfAgc = rtl2836_GetIfAgc; ++ pDemod->GetDiAgc = rtl2836_GetDiAgc; ++ ++ pDemod->GetTrOffsetPpm = rtl2836_GetTrOffsetPpm; ++ pDemod->GetCrOffsetHz = rtl2836_GetCrOffsetHz; ++ ++ pDemod->GetCarrierMode = rtl2836_GetCarrierMode; ++ pDemod->GetPnMode = rtl2836_GetPnMode; ++ pDemod->GetQamMode = rtl2836_GetQamMode; ++ pDemod->GetCodeRateMode = rtl2836_GetCodeRateMode; ++ pDemod->GetTimeInterleaverMode = rtl2836_GetTimeInterleaverMode; ++ ++ pDemod->UpdateFunction = rtl2836_UpdateFunction; ++ pDemod->ResetFunction = rtl2836_ResetFunction; ++ ++ ++ // Initialize demod Function 1 variables. ++ pExtra->IsFunc1Enabled = IsFunc1Enabled; ++ pExtra->Func1CntThd = DivideWithCeiling(RTL2836_FUNC1_CHECK_TIME_MS, UpdateFuncRefPeriodMs); ++ pExtra->Func1Cnt = 0; ++ ++ // Initialize demod Function 2 variables. ++ pExtra->IsFunc2Enabled = IsFunc2Enabled; ++ pExtra->Func2SignalModePrevious = RTL2836_FUNC2_SIGNAL_NORMAL; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C ++ ++*/ ++void ++rtl2836_IsConnectedToI2c( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long ChipId; ++ ++ ++ ++ // Get CHIP_ID. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_CHIP_ID, &ChipId) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Check chip ID value. ++ if(ChipId != RTL2836_CHIP_ID_VALUE) ++ goto error_status_check_value; ++ ++ ++ // Set I2cConnectionStatus with YES. ++ *pAnswer = YES; ++ ++ ++ return; ++ ++ ++error_status_check_value: ++error_status_get_registers: ++ ++ // Set I2cConnectionStatus with NO. ++ *pAnswer = NO; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SOFTWARE_RESET ++ ++*/ ++int ++rtl2836_SoftwareReset( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Set SOFT_RST with 0x0. Then, set SOFT_RST with 0x1. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_SOFT_RST_N, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_SOFT_RST_N, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_INITIALIZE ++ ++*/ ++int ++rtl2836_Initialize( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Initializing table entry only used in Initialize() ++ typedef struct ++ { ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ } ++ INIT_TABLE_ENTRY; ++ ++ // TS interface initializing table entry only used in Initialize() ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue[TS_INTERFACE_MODE_NUM]; ++ } ++ TS_INTERFACE_INIT_TABLE_ENTRY; ++ ++ ++ ++ static const INIT_TABLE_ENTRY InitRegTable[RTL2836_INIT_REG_TABLE_LEN] = ++ { ++ // PageNo, RegStartAddr, Msb, Lsb, WritingValue ++ {0x0, 0x1, 0, 0, 0x1 }, ++ {0x0, 0x2, 4, 4, 0x0 }, ++ {0x0, 0x3, 2, 0, 0x0 }, ++ {0x0, 0xe, 5, 5, 0x1 }, ++ {0x0, 0x11, 3, 3, 0x0 }, ++ {0x0, 0x12, 1, 0, 0x1 }, ++ {0x0, 0x16, 2, 0, 0x3 }, ++ {0x0, 0x19, 7, 0, 0x19 }, ++ {0x0, 0x1b, 7, 0, 0xcc }, ++ {0x0, 0x1f, 7, 0, 0x5 }, ++ {0x0, 0x20, 2, 2, 0x1 }, ++ {0x0, 0x20, 3, 3, 0x0 }, ++ {0x1, 0x3, 7, 0, 0x38 }, ++ {0x1, 0x31, 1, 1, 0x0 }, ++ {0x1, 0x67, 7, 0, 0x30 }, ++ {0x1, 0x68, 7, 0, 0x10 }, ++ {0x1, 0x7f, 3, 2, 0x1 }, ++ {0x1, 0xda, 7, 7, 0x1 }, ++ {0x1, 0xdb, 7, 0, 0x5 }, ++ {0x2, 0x9, 7, 0, 0xa }, ++ {0x2, 0x10, 7, 0, 0x31 }, ++ {0x2, 0x11, 7, 0, 0x31 }, ++ {0x2, 0x1b, 7, 0, 0x1e }, ++ {0x2, 0x1e, 7, 0, 0x3a }, ++ {0x2, 0x1f, 5, 3, 0x3 }, ++ {0x2, 0x21, 7, 0, 0x3f }, ++ {0x2, 0x24, 6, 5, 0x0 }, ++ {0x2, 0x27, 7, 0, 0x17 }, ++ {0x2, 0x31, 7, 0, 0x35 }, ++ {0x2, 0x32, 7, 0, 0x3f }, ++ {0x2, 0x4f, 3, 2, 0x2 }, ++ {0x2, 0x5a, 7, 0, 0x5 }, ++ {0x2, 0x5b, 7, 0, 0x8 }, ++ {0x2, 0x5c, 7, 0, 0x8 }, ++ {0x2, 0x5e, 7, 5, 0x5 }, ++ {0x2, 0x70, 0, 0, 0x0 }, ++ {0x2, 0x77, 0, 0, 0x1 }, ++ {0x2, 0x7a, 7, 0, 0x2f }, ++ {0x2, 0x81, 3, 2, 0x2 }, ++ {0x2, 0x8d, 7, 0, 0x77 }, ++ {0x2, 0x8e, 7, 4, 0x8 }, ++ {0x2, 0x93, 7, 0, 0xff }, ++ {0x2, 0x94, 7, 0, 0x3 }, ++ {0x2, 0x9d, 7, 0, 0xff }, ++ {0x2, 0x9e, 7, 0, 0x3 }, ++ {0x2, 0xa8, 7, 0, 0xff }, ++ {0x2, 0xa9, 7, 0, 0x3 }, ++ {0x2, 0xa3, 2, 2, 0x1 }, ++ {0x3, 0x1, 7, 0, 0x0 }, ++ {0x3, 0x4, 7, 0, 0x20 }, ++ {0x3, 0x9, 7, 0, 0x10 }, ++ {0x3, 0x14, 7, 0, 0xe4 }, ++ {0x3, 0x15, 7, 0, 0x62 }, ++ {0x3, 0x16, 7, 0, 0x8c }, ++ {0x3, 0x17, 7, 0, 0x11 }, ++ {0x3, 0x1b, 7, 0, 0x40 }, ++ {0x3, 0x1c, 7, 0, 0x14 }, ++ {0x3, 0x23, 7, 0, 0x40 }, ++ {0x3, 0x24, 7, 0, 0xd6 }, ++ {0x3, 0x2b, 7, 0, 0x60 }, ++ {0x3, 0x2c, 7, 0, 0x16 }, ++ {0x3, 0x33, 7, 0, 0x40 }, ++ {0x3, 0x3b, 7, 0, 0x44 }, ++ {0x3, 0x43, 7, 0, 0x41 }, ++ {0x3, 0x4b, 7, 0, 0x40 }, ++ {0x3, 0x53, 7, 0, 0x4a }, ++ {0x3, 0x58, 7, 0, 0x1c }, ++ {0x3, 0x5b, 7, 0, 0x5a }, ++ {0x3, 0x5f, 7, 0, 0xe0 }, ++ {0x4, 0x2, 7, 0, 0x7 }, ++ {0x4, 0x3, 5, 0, 0x9 }, ++ {0x4, 0x4, 5, 0, 0xb }, ++ {0x4, 0x5, 5, 0, 0xd }, ++ {0x4, 0x7, 2, 1, 0x3 }, ++ {0x4, 0x7, 4, 3, 0x3 }, ++ {0x4, 0xe, 4, 0, 0x18 }, ++ {0x4, 0x10, 4, 0, 0x1c }, ++ {0x4, 0x12, 4, 0, 0x1c }, ++ {0x4, 0x2f, 7, 0, 0x0 }, ++ {0x4, 0x30, 7, 0, 0x20 }, ++ {0x4, 0x31, 7, 0, 0x40 }, ++ {0x4, 0x3e, 0, 0, 0x0 }, ++ {0x4, 0x3e, 1, 1, 0x1 }, ++ {0x4, 0x3e, 5, 2, 0x0 }, ++ {0x4, 0x3f, 5, 0, 0x10 }, ++ {0x4, 0x4a, 0, 0, 0x1 }, ++ }; ++ ++ static const TS_INTERFACE_INIT_TABLE_ENTRY TsInterfaceInitTable[RTL2836_TS_INTERFACE_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue for {Parallel, Serial} ++ {DTMB_SERIAL, {0x0, 0x1}}, ++ {DTMB_CDIV_PH0, {0xf, 0x1}}, ++ {DTMB_CDIV_PH1, {0xf, 0x1}}, ++ }; ++ ++ int i; ++ ++ int TsInterfaceMode; ++ ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ ++ ++ ++ // Get TS interface mode. ++ TsInterfaceMode = pDemod->TsInterfaceMode; ++ ++ // Initialize demod registers according to the initializing table. ++ for(i = 0; i < RTL2836_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get all information from each register initializing entry. ++ PageNo = InitRegTable[i].PageNo; ++ RegStartAddr = InitRegTable[i].RegStartAddr; ++ Msb = InitRegTable[i].Msb; ++ Lsb = InitRegTable[i].Lsb; ++ WritingValue = InitRegTable[i].WritingValue; ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ // Initialize demod registers according to the TS interface initializing table. ++ for(i = 0; i < RTL2836_TS_INTERFACE_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, TsInterfaceInitTable[i].RegBitName, ++ TsInterfaceInitTable[i].WritingValue[TsInterfaceMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_IF_FREQ_HZ ++ ++*/ ++int ++rtl2836_SetIfFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ) ++{ ++ ++ unsigned long BbinEn, EnDcr; ++ ++ unsigned long IfFreqHzAdj; ++ ++ MPI MpiVar, MpiNone, MpiConst; ++ ++ long IffreqInt; ++ unsigned long IffreqBinary; ++ ++ ++ ++ // Determine and set BBIN_EN and EN_DCR value. ++ BbinEn = (IfFreqHz == IF_FREQ_0HZ) ? 0x1 : 0x0; ++ EnDcr = (IfFreqHz == IF_FREQ_0HZ) ? 0x1 : 0x0; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_BBIN_EN, BbinEn) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_EN_DCR, EnDcr) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Calculate IFFREQ value. ++ // Note: Case 1: IfFreqHz < 24000000, IfFreqHzAdj = IfFreqHz; ++ // Case 2: IfFreqHz >= 24000000, IfFreqHzAdj = 48000000 - IfFreqHz; ++ // IFFREQ = - round( IfFreqHzAdj * pow(2, 10) / 48000000 ) ++ // = - floor( (IfFreqHzAdj * pow(2, 10) + 24000000) / 48000000 ) ++ // RTL2836_ADC_FREQ_HZ = 48 MHz ++ // IFFREQ_BIT_NUM = 10 ++ IfFreqHzAdj = (IfFreqHz < (RTL2836_ADC_FREQ_HZ / 2)) ? IfFreqHz : (RTL2836_ADC_FREQ_HZ - IfFreqHz); ++ ++ MpiSetValue(&MpiVar, IfFreqHzAdj); ++ MpiLeftShift(&MpiVar, MpiVar, RTL2836_IFFREQ_BIT_NUM); ++ ++ MpiSetValue(&MpiConst, (RTL2836_ADC_FREQ_HZ / 2)); ++ MpiAdd(&MpiVar, MpiVar, MpiConst); ++ ++ MpiSetValue(&MpiConst, RTL2836_ADC_FREQ_HZ); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiConst); ++ ++ MpiGetValue(MpiVar, &IffreqInt); ++ IffreqInt = - IffreqInt; ++ ++ IffreqBinary = SignedIntToBin(IffreqInt, RTL2836_IFFREQ_BIT_NUM); ++ ++ ++ // Set IFFREQ with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_IFFREQ, IffreqBinary) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod IF frequnecy parameter. ++ pDemod->IfFreqHz = IfFreqHz; ++ pDemod->IsIfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_SPECTRUM_MODE ++ ++*/ ++int ++rtl2836_SetSpectrumMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ) ++{ ++ unsigned long EnSpInv; ++ ++ ++ ++ // Determine SpecInv according to spectrum mode. ++ switch(SpectrumMode) ++ { ++ case SPECTRUM_NORMAL: EnSpInv = 0; break; ++ case SPECTRUM_INVERSE: EnSpInv = 1; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ // Set SPEC_INV with SpecInv. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_EN_SP_INV, EnSpInv) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod spectrum mode parameter. ++ pDemod->SpectrumMode = SpectrumMode; ++ pDemod->IsSpectrumModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++rtl2836_IsSignalLocked( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ long SnrDbNum; ++ long SnrDbDen; ++ long SnrDbInt; ++ ++ unsigned long PerNum; ++ unsigned long PerDen; ++ ++ ++ ++ // Get SNR integer part. ++ if(pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ SnrDbInt = SnrDbNum / SnrDbDen; ++ ++ ++ // Get PER. ++ if(pDemod->GetPer(pDemod, &PerNum, &PerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Determine answer according to SNR and PER. ++ // Note: The criterion is "(0 < SNR_in_Db < 40) && (PER < 1)" ++ if((SnrDbInt > 0) && (SnrDbInt < 40) && (PerNum < PerDen)) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++rtl2836_GetSignalStrength( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ) ++{ ++ int SignalLockStatus; ++ long IfAgc; ++ ++ ++ ++ // Get signal lock status. ++ if(pDemod->IsSignalLocked(pDemod, &SignalLockStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Get IF AGC value. ++ if(pDemod->GetIfAgc(pDemod, &IfAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // If demod is not signal-locked, set signal strength with zero. ++ if(SignalLockStatus != YES) ++ { ++ *pSignalStrength = 0; ++ goto success_status_signal_is_not_locked; ++ } ++ ++ // Determine signal strength according to signal lock status and IF AGC value. ++ // Note: Map IfAgc value 8191 ~ -8192 to 10 ~ 99 ++ // Formula: SignalStrength = 54 - IfAgc / 183 ++ *pSignalStrength = 54 - IfAgc / 183; ++ ++ ++success_status_signal_is_not_locked: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++rtl2836_GetSignalQuality( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ) ++{ ++ int SignalLockStatus; ++ long SnrDbNum, SnrDbDen; ++ ++ ++ ++ // Get signal lock status. ++ if(pDemod->IsSignalLocked(pDemod, &SignalLockStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // If demod is not signal-locked, set signal quality with zero. ++ if(SignalLockStatus != YES) ++ { ++ *pSignalQuality = 0; ++ goto success_status_signal_is_not_locked; ++ } ++ ++ // Determine signal quality according to SnrDbNum. ++ // Note: Map SnrDbNum value 12 ~ 100 to 12 ~ 100 ++ // Formula: SignalQuality = SnrDbNum ++ // If SnrDbNum < 12, signal quality is 10. ++ // If SnrDbNum > 100, signal quality is 100. ++ if(SnrDbNum < 12) ++ { ++ *pSignalQuality = 10; ++ } ++ else if(SnrDbNum > 100) ++ { ++ *pSignalQuality = 100; ++ } ++ else ++ { ++ *pSignalQuality = SnrDbNum; ++ } ++ ++ ++success_status_signal_is_not_locked: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_BER ++ ++*/ ++int ++rtl2836_GetBer( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ) ++{ ++/* ++ unsigned long RsdBerEst; ++ ++ ++ ++ // Get RSD_BER_EST. ++ if(pDemod->GetRegBitsWithPage(pDemod, DTMB_RSD_BER_EST, &RsdBerEst) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set BER numerator according to RSD_BER_EST. ++ *pBerNum = RsdBerEst; ++ ++ // Set BER denominator. ++ *pBerDen = RTL2836_BER_DEN_VALUE; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++*/ ++ return FUNCTION_SUCCESS; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_PER ++ ++*/ ++int ++rtl2836_GetPer( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ) ++{ ++ unsigned long RoPktErrRate; ++ ++ ++ ++ // Get RO_PKT_ERR_RATE. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_RO_PKT_ERR_RATE, &RoPktErrRate) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set PER numerator according to RO_PKT_ERR_RATE. ++ *pPerNum = RoPktErrRate; ++ ++ // Set PER denominator. ++ *pPerDen = RTL2836_PER_DEN_VALUE; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_SNR_DB ++ ++*/ ++int ++rtl2836_GetSnrDb( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ unsigned long EstSnr; ++ ++ ++ ++ // Get EST_SNR. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_EST_SNR, &EstSnr) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set SNR dB numerator according to EST_SNR. ++ *pSnrDbNum = BinToSignedInt(EstSnr, RTL2836_EST_SNR_BIT_NUM); ++ ++ // Set SNR dB denominator. ++ *pSnrDbDen = RTL2836_SNR_DB_DEN_VALUE; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_RF_AGC ++ ++*/ ++int ++rtl2836_GetRfAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ) ++{ ++ unsigned long RfAgcVal; ++ ++ ++ ++ // Get RF AGC binary value from RF_AGC_VAL. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_RF_AGC_VAL, &RfAgcVal) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Convert RF AGC binary value to signed integer. ++ *pRfAgc = (long)BinToSignedInt(RfAgcVal, RTL2836_RF_AGC_REG_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_IF_AGC ++ ++*/ ++int ++rtl2836_GetIfAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ) ++{ ++ unsigned long IfAgcVal; ++ ++ ++ ++ // Get IF AGC binary value from IF_AGC_VAL. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_IF_AGC_VAL, &IfAgcVal) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Convert IF AGC binary value to signed integer. ++ *pIfAgc = (long)BinToSignedInt(IfAgcVal, RTL2836_IF_AGC_REG_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_DI_AGC ++ ++*/ ++int ++rtl2836_GetDiAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ) ++{ ++ unsigned long GainOutR; ++ ++ ++ ++ // Get GAIN_OUT_R to DiAgc. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_GAIN_OUT_R, &GainOutR) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ *pDiAgc = GainOutR; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++rtl2836_GetTrOffsetPpm( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ) ++{ ++ unsigned long TrOutRBinary; ++ long TrOutRInt; ++ unsigned long SfoaqOutRBinary; ++ long SfoaqOutRInt; ++ ++ MPI MpiVar, MpiNone, MpiConst; ++ ++ ++ // Get TR_OUT_R and SFOAQ_OUT_R binary value. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_TR_OUT_R, &TrOutRBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_SFOAQ_OUT_R, &SfoaqOutRBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert TR_OUT_R and SFOAQ_OUT_R binary value to signed integer. ++ TrOutRInt = BinToSignedInt(TrOutRBinary, RTL2836_TR_OUT_R_BIT_NUM); ++ SfoaqOutRInt = BinToSignedInt(SfoaqOutRBinary, RTL2836_SFOAQ_OUT_R_BIT_NUM); ++ ++ ++ // Get TR offset in ppm. ++ // Note: Original formula: TrOffsetPpm = ((TrOutRInt + SfoaqOutRInt * 8) * 15.12 * pow(10, 6)) / (48 * pow(2, 23)) ++ // Adjusted formula: TrOffsetPpm = ((TrOutRInt + SfoaqOutRInt * 8) * 15120000) / 402653184 ++ MpiSetValue(&MpiVar, (TrOutRInt + SfoaqOutRInt * 8)); ++ ++ MpiSetValue(&MpiConst, 15120000); ++ MpiMul(&MpiVar, MpiVar, MpiConst); ++ ++ MpiSetValue(&MpiConst, 402653184); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiConst); ++ ++ MpiGetValue(MpiVar, pTrOffsetPpm); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++rtl2836_GetCrOffsetHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ) ++{ ++ unsigned long CfoEstRBinary; ++ long CfoEstRInt; ++ ++ MPI MpiVar, MpiConst; ++ ++ ++ // Get CFO_EST_R binary value. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_CFO_EST_R, &CfoEstRBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Convert CFO_EST_R binary value to signed integer. ++ CfoEstRInt = BinToSignedInt(CfoEstRBinary, RTL2836_CFO_EST_R_BIT_NUM); ++ ++ ++ // Get CR offset in Hz. ++ // Note: Original formula: CrOffsetHz = (CfoEstRInt * 15.12 * pow(10, 6)) / pow(2, 26) ++ // Adjusted formula: CrOffsetHz = (CfoEstRInt * 15120000) >> 26 ++ MpiSetValue(&MpiVar, CfoEstRInt); ++ ++ MpiSetValue(&MpiConst, 15120000); ++ MpiMul(&MpiVar, MpiVar, MpiConst); ++ ++ MpiRightShift(&MpiVar, MpiVar, 26); ++ ++ MpiGetValue(MpiVar, pCrOffsetHz); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_CARRIER_MODE ++ ++*/ ++int ++rtl2836_GetCarrierMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCarrierMode ++ ) ++{ ++ unsigned long EstCarrier; ++ ++ ++ // Get carrier mode from EST_CARRIER. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_EST_CARRIER, &EstCarrier) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(EstCarrier) ++ { ++ case 0: *pCarrierMode = DTMB_CARRIER_SINGLE; break; ++ case 1: *pCarrierMode = DTMB_CARRIER_MULTI; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_PN_MODE ++ ++*/ ++int ++rtl2836_GetPnMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pPnMode ++ ) ++{ ++ unsigned long RxModeR; ++ ++ ++ // Get PN mode from RX_MODE_R. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_RX_MODE_R, &RxModeR) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(RxModeR) ++ { ++ case 0: *pPnMode = DTMB_PN_420; break; ++ case 1: *pPnMode = DTMB_PN_595; break; ++ case 2: *pPnMode = DTMB_PN_945; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_QAM_MODE ++ ++*/ ++int ++rtl2836_GetQamMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ) ++{ ++ unsigned long UseTps; ++ ++ ++ // Get QAM mode from USE_TPS. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_USE_TPS, &UseTps) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(UseTps) ++ { ++ case 0: *pQamMode = DTMB_QAM_UNKNOWN; break; ++ ++ case 2: ++ case 3: *pQamMode = DTMB_QAM_4QAM_NR; break; ++ ++ case 4: ++ case 5: ++ case 6: ++ case 7: ++ case 8: ++ case 9: *pQamMode = DTMB_QAM_4QAM; break; ++ ++ case 10: ++ case 11: ++ case 12: ++ case 13: ++ case 14: ++ case 15: *pQamMode = DTMB_QAM_16QAM; break; ++ ++ case 16: ++ case 17: *pQamMode = DTMB_QAM_32QAM; break; ++ ++ case 18: ++ case 19: ++ case 20: ++ case 21: ++ case 22: ++ case 23: *pQamMode = DTMB_QAM_64QAM; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_CODE_RATE_MODE ++ ++*/ ++int ++rtl2836_GetCodeRateMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCodeRateMode ++ ) ++{ ++ unsigned long UseTps; ++ ++ ++ // Get QAM mode from USE_TPS. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_USE_TPS, &UseTps) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(UseTps) ++ { ++ case 0: *pCodeRateMode = DTMB_CODE_RATE_UNKNOWN; break; ++ ++ case 4: ++ case 5: ++ case 10: ++ case 11: ++ case 18: ++ case 19: *pCodeRateMode = DTMB_CODE_RATE_0P4; break; ++ ++ case 6: ++ case 7: ++ case 12: ++ case 13: ++ case 20: ++ case 21: *pCodeRateMode = DTMB_CODE_RATE_0P6; break; ++ ++ case 2: ++ case 3: ++ case 8: ++ case 9: ++ case 14: ++ case 15: ++ case 16: ++ case 17: ++ case 22: ++ case 23: *pCodeRateMode = DTMB_CODE_RATE_0P8; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE ++ ++*/ ++int ++rtl2836_GetTimeInterleaverMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pTimeInterleaverMode ++ ) ++{ ++ unsigned long UseTps; ++ ++ ++ // Get QAM mode from USE_TPS. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_USE_TPS, &UseTps) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ switch(UseTps) ++ { ++ case 0: *pTimeInterleaverMode = DTMB_TIME_INTERLEAVER_UNKNOWN; break; ++ ++ case 2: ++ case 4: ++ case 6: ++ case 8: ++ case 10: ++ case 12: ++ case 14: ++ case 16: ++ case 18: ++ case 20: ++ case 22: *pTimeInterleaverMode = DTMB_TIME_INTERLEAVER_240; break; ++ ++ case 3: ++ case 5: ++ case 7: ++ case 9: ++ case 11: ++ case 13: ++ case 15: ++ case 17: ++ case 19: ++ case 21: ++ case 23: *pTimeInterleaverMode = DTMB_TIME_INTERLEAVER_720; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2836_UpdateFunction( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Execute Function 1 according to Function 1 enabling status ++ if(pExtra->IsFunc1Enabled == YES) ++ { ++ if(rtl2836_func1_Update(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ // Execute Function 2 according to Function 2 enabling status ++ if(pExtra->IsFunc2Enabled == YES) ++ { ++ if(rtl2836_func2_Update(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_RESET_FUNCTION ++ ++*/ ++int ++rtl2836_ResetFunction( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Reset Function 1 settings according to Function 1 enabling status. ++ if(pExtra->IsFunc1Enabled == YES) ++ { ++ if(rtl2836_func1_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ // Reset Function 2 settings according to Function 2 enabling status. ++ if(pExtra->IsFunc2Enabled == YES) ++ { ++ if(rtl2836_func2_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD ++ ++*/ ++int ++rtl2836_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module. ++ pDemod = (DTMB_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send I2C reading command. ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_reading_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_reading_command: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD ++ ++*/ ++int ++rtl2836_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module. ++ pDemod = (DTMB_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Send I2C writing command. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, pWritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_writing_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_writing_command: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Initialize RTL2836 register table. ++ ++Use rtl2836_InitRegTable() to initialize RTL2836 register table. ++ ++ ++@param [in] pDemod RTL2836 demod module pointer ++ ++ ++@note ++ -# The rtl2836_InitRegTable() function will be called by BuildRtl2836Module(). ++ ++*/ ++void ++rtl2836_InitRegTable( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ static const DTMB_PRIMARY_REG_ENTRY_ADDR_8BIT PrimaryRegTable[RTL2836_REG_TABLE_LEN] = ++ { ++ // Software reset ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_SOFT_RST_N, 0x0, 0x4, 0, 0 }, ++ ++ // Tuner I2C forwording ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_I2CT_EN_CTRL, 0x0, 0x6, 0, 0 }, ++ ++ // Chip ID ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_CHIP_ID, 0x5, 0x10, 15, 0 }, ++ ++ // IF setting ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_EN_SP_INV, 0x1, 0x31, 1, 1 }, ++ {DTMB_EN_DCR, 0x1, 0x31, 0, 0 }, ++ {DTMB_BBIN_EN, 0x1, 0x6a, 0, 0 }, ++ {DTMB_IFFREQ, 0x1, 0x32, 9, 0 }, ++ ++ // AGC setting ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_TARGET_VAL, 0x1, 0x3, 7, 0 }, ++ ++ // IF setting ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_SERIAL, 0x4, 0x50, 7, 7 }, ++ {DTMB_CDIV_PH0, 0x4, 0x51, 4, 0 }, ++ {DTMB_CDIV_PH1, 0x4, 0x52, 4, 0 }, ++ ++ // Signal lock status ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_TPS_LOCK, 0x8, 0x2a, 6, 6 }, ++ {DTMB_PN_PEAK_EXIST, 0x6, 0x53, 0, 0 }, ++ ++ // FSM ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_FSM_STATE_R, 0x6, 0xc0, 4, 0 }, ++ ++ // Performance measurement ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_RO_PKT_ERR_RATE, 0x9, 0x2d, 15, 0 }, ++ {DTMB_EST_SNR, 0x8, 0x3e, 8, 0 }, ++ ++ // AGC ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_GAIN_OUT_R, 0x6, 0xb4, 12, 1 }, ++ {DTMB_RF_AGC_VAL, 0x6, 0x16, 13, 0 }, ++ {DTMB_IF_AGC_VAL, 0x6, 0x14, 13, 0 }, ++ ++ // TR and CR ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_TR_OUT_R, 0x7, 0x7c, 16, 0 }, ++ {DTMB_SFOAQ_OUT_R, 0x7, 0x21, 13, 0 }, ++ {DTMB_CFO_EST_R, 0x6, 0x94, 22, 0 }, ++ ++ // Signal information ++ // RegBitName, PageNo, RegStartAddr, MSB, LSB ++ {DTMB_EST_CARRIER, 0x8, 0x2a, 0, 0 }, ++ {DTMB_RX_MODE_R, 0x7, 0x17, 1, 0 }, ++ {DTMB_USE_TPS, 0x8, 0x2a, 5, 1 }, ++ }; ++ ++ ++ int i; ++ int RegBitName; ++ ++ ++ ++ // Initialize register table according to primary register table. ++ // Note: 1. Register table rows are sorted by register bit name key. ++ // 2. The default value of the IsAvailable variable is "NO". ++ for(i = 0; i < DTMB_REG_TABLE_LEN_MAX; i++) ++ pDemod->RegTable.Addr8Bit[i].IsAvailable = NO; ++ ++ for(i = 0; i < RTL2836_REG_TABLE_LEN; i++) ++ { ++ RegBitName = PrimaryRegTable[i].RegBitName; ++ ++ pDemod->RegTable.Addr8Bit[RegBitName].IsAvailable = YES; ++ pDemod->RegTable.Addr8Bit[RegBitName].PageNo = PrimaryRegTable[i].PageNo; ++ pDemod->RegTable.Addr8Bit[RegBitName].RegStartAddr = PrimaryRegTable[i].RegStartAddr; ++ pDemod->RegTable.Addr8Bit[RegBitName].Msb = PrimaryRegTable[i].Msb; ++ pDemod->RegTable.Addr8Bit[RegBitName].Lsb = PrimaryRegTable[i].Lsb; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set I2C bridge module demod arguments. ++ ++RTL2836 builder will use rtl2836_BuildI2cBridgeModule() to set I2C bridge module demod arguments. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2836Module() ++ ++*/ ++void ++rtl2836_BuildI2cBridgeModule( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ ++ // Get I2C bridge module. ++ pI2cBridge = pDemod->pI2cBridge; ++ ++ // Set I2C bridge module demod arguments. ++ pI2cBridge->pPrivateData = (void *)pDemod; ++ pI2cBridge->ForwardI2cReadingCmd = rtl2836_ForwardI2cReadingCmd; ++ pI2cBridge->ForwardI2cWritingCmd = rtl2836_ForwardI2cWritingCmd; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Reset Function 1 variables and registers. ++ ++One can use rtl2836_func1_Reset() to reset Function 1 variables and registers. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset Function 1 variables and registers successfully. ++@retval FUNCTION_ERROR Reset Function 1 variables and registers unsuccessfully. ++ ++ ++@note ++ -# Need to execute Function 1 reset function when change tuner RF frequency or demod parameters. ++ -# Function 1 update flow also employs Function 1 reset function. ++ ++*/ ++int ++rtl2836_func1_Reset( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ // Reset demod Function 1 variables. ++ pExtra->Func1Cnt = 0; ++ ++ ++ return FUNCTION_SUCCESS; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update demod registers with Function 1. ++ ++One can use rtl2836_func1_Update() to update demod registers with Function 1. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod registers with Function 1 successfully. ++@retval FUNCTION_ERROR Update demod registers with Function 1 unsuccessfully. ++ ++ ++@note ++ -# Recommended update period is 50 ~ 200 ms for Function 1. ++ -# Need to execute Function 1 reset function when change tuner RF frequency or demod parameters. ++ -# Function 1 update flow also employs Function 1 reset function. ++ ++*/ ++int ++rtl2836_func1_Update( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ unsigned long Reg0; ++ unsigned long Reg1; ++ unsigned long PnPeakExist; ++ unsigned long FsmStateR; ++ unsigned long TpsLock; ++ ++ long SnrDbNum; ++ long SnrDbDen; ++ long SnrDbInt; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Update Function 1 counter. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x9) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegMaskBits(pDemod, 0x1e, 9, 0, &Reg0) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if((Reg0 & 0x3fb) == 0) ++ { ++ pExtra->Func1Cnt += 1; ++ } ++ else ++ { ++ pExtra->Func1Cnt = 0; ++ } ++ ++ ++ // Get PN_PEAK_EXIST and FSM_STATE_R value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x6) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, DTMB_PN_PEAK_EXIST, &PnPeakExist) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, DTMB_FSM_STATE_R, &FsmStateR) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Get Reg1 and TPS_LOCK value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x8) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegMaskBits(pDemod, 0x28, 3, 0, &Reg1) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, DTMB_TPS_LOCK, &TpsLock) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Get SNR integer part. ++ if(pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ SnrDbInt = SnrDbNum / SnrDbDen; ++ ++ ++ // Determine if reset demod by software reset. ++ // Note: Need to reset Function 2 when reset demod. ++ if((pExtra->Func1Cnt > pExtra->Func1CntThd) || ((PnPeakExist == 0) && (FsmStateR > 9)) || ++ ((Reg1 >= 6) && (TpsLock == 0)) || (SnrDbInt == -64)) ++ { ++ pExtra->Func1Cnt = 0; ++ ++ if(pExtra->IsFunc2Enabled == ON) ++ { ++ if(rtl2836_func2_Reset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ } ++ ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_get_registers: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Reset Function 2 variables and registers. ++ ++One can use rtl2836_func2_Reset() to reset Function 1 variables and registers. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset Function 2 variables and registers successfully. ++@retval FUNCTION_ERROR Reset Function 2 variables and registers unsuccessfully. ++ ++ ++@note ++ -# Need to execute Function 2 reset function when change tuner RF frequency or demod parameters. ++ -# Function 2 update flow also employs Function 2 reset function. ++ ++*/ ++int ++rtl2836_func2_Reset( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get demod extra module. ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ // Reset demod Function 2 variables and registers to signal normal mode. ++ pExtra->Func2SignalModePrevious = RTL2836_FUNC2_SIGNAL_NORMAL; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x15, 7, 0, 0xf) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1e, 6, 0, 0x3a) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1f, 5, 0, 0x19) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x23, 4, 0, 0x1e) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update demod registers with Function 2. ++ ++One can use rtl2836_func2_Update() to update demod registers with Function 2. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod registers with Function 2 successfully. ++@retval FUNCTION_ERROR Update demod registers with Function 2 unsuccessfully. ++ ++ ++@note ++ -# Recommended update period is 50 ~ 200 ms for Function 2. ++ -# Need to execute Function 2 reset function when change tuner RF frequency or demod parameters. ++ -# Function 2 update flow also employs Function 2 reset function. ++ ++*/ ++int ++rtl2836_func2_Update( ++ DTMB_DEMOD_MODULE *pDemod ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ RTL2836_EXTRA_MODULE *pExtra; ++ ++ int i; ++ ++ unsigned long TpsLock; ++ unsigned long PnPeakExist; ++ ++ int PnMode; ++ int QamMode; ++ int CodeRateMode; ++ ++ int SignalLockStatus; ++ ++ int SignalMode; ++ ++ ++ ++ // Get base interface and demod extra module. ++ pBaseInterface = pDemod->pBaseInterface; ++ pExtra = &(pDemod->Extra.Rtl2836); ++ ++ ++ // Get TPS_LOCK value. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_TPS_LOCK, &TpsLock) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Get PN_PEAK_EXIST value. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, DTMB_PN_PEAK_EXIST, &PnPeakExist) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Get PN mode. ++ if(pDemod->GetPnMode(pDemod, &PnMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get QAM mode. ++ if(pDemod->GetQamMode(pDemod, &QamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get code rate mode. ++ if(pDemod->GetCodeRateMode(pDemod, &CodeRateMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // If TPS is not locked or PN peak doesn't exist, do nothing. ++ if((TpsLock != 0x1) || (PnPeakExist != 0x1)) ++ goto success_status_tps_is_not_locked; ++ ++ // Determine signal mode. ++ if((PnMode == DTMB_PN_945) && (QamMode == DTMB_QAM_64QAM) && (CodeRateMode == DTMB_CODE_RATE_0P6)) ++ { ++ SignalMode = RTL2836_FUNC2_SIGNAL_PARTICULAR; ++ } ++ else ++ { ++ SignalMode = RTL2836_FUNC2_SIGNAL_NORMAL; ++ } ++ ++ // If signal mode is the same as previous one, do nothing. ++ if(SignalMode == pExtra->Func2SignalModePrevious) ++ goto success_status_signal_mode_is_the_same; ++ ++ ++ // Set demod registers according to signal mode ++ switch(SignalMode) ++ { ++ default: ++ case RTL2836_FUNC2_SIGNAL_NORMAL: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x15, 7, 0, 0xf) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1e, 6, 0, 0x3a) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1f, 5, 0, 0x19) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x23, 4, 0, 0x1e) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ ++ ++ case RTL2836_FUNC2_SIGNAL_PARTICULAR: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0x2) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x15, 7, 0, 0x4) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1e, 6, 0, 0xa) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x1f, 5, 0, 0x3f) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, 0x23, 4, 0, 0x1f) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ } ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Wait 1000 ms for signal lock check. ++ for(i = 0; i < 10; i++) ++ { ++ // Wait 100 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 100); ++ ++ // Check signal lock status on demod. ++ // Note: If signal is locked, stop signal lock check. ++ if(pDemod->IsSignalLocked(pDemod, &SignalLockStatus) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(SignalLockStatus == YES) ++ break; ++ } ++ ++ ++ // Update previous signal mode. ++ pExtra->Func2SignalModePrevious = SignalMode; ++ ++ ++success_status_signal_mode_is_the_same: ++success_status_tps_is_not_locked: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/demod_rtl2836.h b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2836.h +--- a/drivers/media/dvb/dvb-usb/demod_rtl2836.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2836.h 2016-04-02 19:17:52.084066057 -0300 +@@ -0,0 +1,376 @@ ++#ifndef __DEMOD_RTL2836_H ++#define __DEMOD_RTL2836_H ++ ++/** ++ ++@file ++ ++@brief RTL2836 demod module declaration ++ ++One can manipulate RTL2836 demod through RTL2836 module. ++RTL2836 module is derived from DTMB demod module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the DTMB demod example in dtmb_demod_base.h except the listed lines. ++ ++ ++ ++#include "demod_rtl2836.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ ++ ... ++ ++ ++ ++ // Build RTL2836 demod module. ++ BuildRtl2836Module( ++ &pDemod, ++ &DtmbDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x3e, // I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // Crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // TS interface mode is serial. ++ 50, // Update function reference period is 50 millisecond ++ YES, // Function 1 enabling status is on. ++ YES // Function 2 enabling status is on. ++ ); ++ ++ ++ ++ // See the example for other DTMB demod functions in dtmb_demod_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "dtmb_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// Initializing ++#define RTL2836_INIT_REG_TABLE_LEN 86 ++#define RTL2836_TS_INTERFACE_INIT_TABLE_LEN 3 ++ ++ ++// Chip ID ++#define RTL2836_CHIP_ID_VALUE 0x4 ++ ++ ++// IF frequency setting ++#define RTL2836_ADC_FREQ_HZ 48000000 ++#define RTL2836_IFFREQ_BIT_NUM 10 ++ ++ ++// BER ++#define RTL2836_BER_DEN_VALUE 1000000 ++ ++ ++// PER ++#define RTL2836_PER_DEN_VALUE 32768 ++ ++ ++// SNR ++#define RTL2836_EST_SNR_BIT_NUM 9 ++#define RTL2836_SNR_DB_DEN_VALUE 4 ++ ++ ++// AGC ++#define RTL2836_RF_AGC_REG_BIT_NUM 14 ++#define RTL2836_IF_AGC_REG_BIT_NUM 14 ++ ++ ++// TR offset and CR offset ++#define RTL2836_TR_OUT_R_BIT_NUM 17 ++#define RTL2836_SFOAQ_OUT_R_BIT_NUM 14 ++#define RTL2836_CFO_EST_R_BIT_NUM 23 ++ ++ ++// Register table length ++#define RTL2836_REG_TABLE_LEN 25 ++ ++ ++// Function 1 ++#define RTL2836_FUNC1_CHECK_TIME_MS 500 ++ ++ ++// Function 2 ++enum RTL2836_FUNC2_SIGNAL_MODE ++{ ++ RTL2836_FUNC2_SIGNAL_NORMAL, ++ RTL2836_FUNC2_SIGNAL_PARTICULAR, ++}; ++ ++ ++ ++ ++ ++// Demod module builder ++void ++BuildRtl2836Module( ++ DTMB_DEMOD_MODULE **ppDemod, ++ DTMB_DEMOD_MODULE *pDtmbDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled, ++ int IsFunc2Enabled ++ ); ++ ++ ++ ++ ++ ++// Manipulating functions ++void ++rtl2836_IsConnectedToI2c( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++); ++ ++int ++rtl2836_SoftwareReset( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_Initialize( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_SetIfFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++int ++rtl2836_SetSpectrumMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++int ++rtl2836_IsSignalLocked( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2836_GetSignalStrength( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++rtl2836_GetSignalQuality( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++rtl2836_GetBer( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++int ++rtl2836_GetPer( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++int ++rtl2836_GetSnrDb( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++rtl2836_GetRfAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++int ++rtl2836_GetIfAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++int ++rtl2836_GetDiAgc( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ); ++ ++int ++rtl2836_GetTrOffsetPpm( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++int ++rtl2836_GetCrOffsetHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++int ++rtl2836_GetCarrierMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCarrierMode ++ ); ++ ++int ++rtl2836_GetPnMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pPnMode ++ ); ++ ++int ++rtl2836_GetQamMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ); ++ ++int ++rtl2836_GetCodeRateMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCodeRateMode ++ ); ++ ++int ++rtl2836_GetTimeInterleaverMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pTimeInterleaverMode ++ ); ++ ++int ++rtl2836_UpdateFunction( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_ResetFunction( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// I2C command forwarding functions ++int ++rtl2836_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++rtl2836_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++// Register table initializing ++void ++rtl2836_InitRegTable( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// I2C birdge module builder ++void ++rtl2836_BuildI2cBridgeModule( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// RTL2836 dependence ++int ++rtl2836_func1_Reset( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_func1_Update( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_func2_Reset( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2836_func2_Update( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/demod_rtl2840.c b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2840.c +--- a/drivers/media/dvb/dvb-usb/demod_rtl2840.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2840.c 2016-04-02 19:17:52.088066039 -0300 +@@ -0,0 +1,2437 @@ ++/** ++ ++@file ++ ++@brief RTL2840 QAM demod module definition ++ ++One can manipulate RTL2840 QAM demod through RTL2840 module. ++RTL2840 module is derived from QAM demod module. ++ ++*/ ++ ++ ++#include "demod_rtl2840.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2840 demod module builder ++ ++Use BuildRtl2840Module() to build RTL2840 module, set all module function pointers with the corresponding functions, and ++initialize module private variables. ++ ++ ++@param [in] ppDemod Pointer to RTL2840 demod module pointer ++@param [in] pQamDemodModuleMemory Pointer to an allocated QAM demod module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr RTL2840 I2C device address ++@param [in] CrystalFreqHz RTL2840 crystal frequency in Hz ++@param [in] TsInterfaceMode RTL2840 TS interface mode for setting ++@param [in] EnhancementMode RTL2840 enhancement mode for setting ++ ++ ++@note ++ -# One should call BuildRtl2840Module() to build RTL2840 module before using it. ++ ++*/ ++void ++BuildRtl2840Module( ++ QAM_DEMOD_MODULE **ppDemod, ++ QAM_DEMOD_MODULE *pQamDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ int EnhancementMode ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ ++ // Set demod module pointer. ++ *ppDemod = pQamDemodModuleMemory; ++ ++ // Get demod module. ++ pDemod = *ppDemod; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pDemod->pBaseInterface = pBaseInterfaceModuleMemory; ++ pDemod->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ ++ // Set demod type. ++ pDemod->DemodType = QAM_DEMOD_TYPE_RTL2840; ++ ++ // Set demod I2C device address. ++ pDemod->DeviceAddr = DeviceAddr; ++ ++ // Set demod crystal frequency in Hz. ++ pDemod->CrystalFreqHz = CrystalFreqHz; ++ ++ // Set demod TS interface mode. ++ pDemod->TsInterfaceMode = TsInterfaceMode; ++ ++ ++ // Initialize demod parameter setting status ++ pDemod->IsQamModeSet = NO; ++ pDemod->IsSymbolRateHzSet = NO; ++ pDemod->IsAlphaModeSet = NO; ++ pDemod->IsIfFreqHzSet = NO; ++ pDemod->IsSpectrumModeSet = NO; ++ ++ ++ // Initialize register tables in demod extra module. ++ rtl2840_InitBaseRegTable(pDemod); ++ rtl2840_InitMonitorRegTable(pDemod); ++ ++ ++ // Build I2C birdge module. ++ rtl2840_BuildI2cBridgeModule(pDemod); ++ ++ ++ // Set demod module I2C function pointers with default functions. ++ pDemod->RegAccess.Addr8Bit.SetRegPage = qam_demod_addr_8bit_default_SetRegPage; ++ pDemod->RegAccess.Addr8Bit.SetRegBytes = qam_demod_addr_8bit_default_SetRegBytes; ++ pDemod->RegAccess.Addr8Bit.GetRegBytes = qam_demod_addr_8bit_default_GetRegBytes; ++ pDemod->RegAccess.Addr8Bit.SetRegMaskBits = qam_demod_addr_8bit_default_SetRegMaskBits; ++ pDemod->RegAccess.Addr8Bit.GetRegMaskBits = qam_demod_addr_8bit_default_GetRegMaskBits; ++ pDemod->RegAccess.Addr8Bit.SetRegBits = qam_demod_addr_8bit_default_SetRegBits; ++ pDemod->RegAccess.Addr8Bit.GetRegBits = qam_demod_addr_8bit_default_GetRegBits; ++ pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage = qam_demod_addr_8bit_default_SetRegBitsWithPage; ++ pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage = qam_demod_addr_8bit_default_GetRegBitsWithPage; ++ ++ ++ // Set demod module manipulating function pointers with default functions. ++ pDemod->GetDemodType = qam_demod_default_GetDemodType; ++ pDemod->GetDeviceAddr = qam_demod_default_GetDeviceAddr; ++ pDemod->GetCrystalFreqHz = qam_demod_default_GetCrystalFreqHz; ++ ++ pDemod->GetQamMode = qam_demod_default_GetQamMode; ++ pDemod->GetSymbolRateHz = qam_demod_default_GetSymbolRateHz; ++ pDemod->GetAlphaMode = qam_demod_default_GetAlphaMode; ++ pDemod->GetIfFreqHz = qam_demod_default_GetIfFreqHz; ++ pDemod->GetSpectrumMode = qam_demod_default_GetSpectrumMode; ++ ++ ++ // Set demod module manipulating function pointers with particular functions. ++ // Note: Need to assign manipulating function pointers according to enhancement mode. ++ pDemod->IsConnectedToI2c = rtl2840_IsConnectedToI2c; ++ pDemod->SoftwareReset = rtl2840_SoftwareReset; ++ ++ pDemod->Initialize = rtl2840_Initialize; ++ pDemod->SetSymbolRateHz = rtl2840_SetSymbolRateHz; ++ pDemod->SetAlphaMode = rtl2840_SetAlphaMode; ++ pDemod->SetIfFreqHz = rtl2840_SetIfFreqHz; ++ pDemod->SetSpectrumMode = rtl2840_SetSpectrumMode; ++ ++ pDemod->GetRfAgc = rtl2840_GetRfAgc; ++ pDemod->GetIfAgc = rtl2840_GetIfAgc; ++ pDemod->GetDiAgc = rtl2840_GetDiAgc; ++ pDemod->GetTrOffsetPpm = rtl2840_GetTrOffsetPpm; ++ pDemod->GetCrOffsetHz = rtl2840_GetCrOffsetHz; ++ ++ pDemod->IsAagcLocked = rtl2840_IsAagcLocked; ++ pDemod->IsEqLocked = rtl2840_IsEqLocked; ++ pDemod->IsFrameLocked = rtl2840_IsFrameLocked; ++ ++ pDemod->GetErrorRate = rtl2840_GetErrorRate; ++ pDemod->GetSnrDb = rtl2840_GetSnrDb; ++ ++ pDemod->GetSignalStrength = rtl2840_GetSignalStrength; ++ pDemod->GetSignalQuality = rtl2840_GetSignalQuality; ++ ++ pDemod->UpdateFunction = rtl2840_UpdateFunction; ++ pDemod->ResetFunction = rtl2840_ResetFunction; ++ ++ switch(EnhancementMode) ++ { ++ case QAM_DEMOD_EN_NONE: ++ pDemod->SetQamMode = rtl2840_SetQamMode; ++ break; ++ ++ case QAM_DEMOD_EN_AM_HUM: ++ pDemod->SetQamMode = rtl2840_am_hum_en_SetQamMode; ++ break; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_IS_CONNECTED_TO_I2C ++ ++*/ ++void ++rtl2840_IsConnectedToI2c( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long ReadingValue; ++ ++ ++ ++ // Set reading value to zero, and get SYS_VERSION value. ++ // Note: Use GetRegBitsWithPage() to get register bits with page setting. ++ ReadingValue = 0; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_SYS_VERSION, &ReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Compare SYS_VERSION value with RTL2840_SYS_VERSION_VALUE. ++ if(ReadingValue == RTL2840_SYS_VERSION_VALUE) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return; ++ ++ ++error_status_get_demod_registers: ++ ++ *pAnswer = NO; ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SOFTWARE_RESET ++ ++*/ ++int ++rtl2840_SoftwareReset( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ // Set register page number with system page number for software resetting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 0) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set and clear SOFT_RESET register bit. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SOFT_RESET, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SOFT_RESET, OFF) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_INITIALIZE ++ ++*/ ++int ++rtl2840_Initialize( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ typedef struct ++ { ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ } ++ INIT_REG_ENTRY; ++ ++ ++ typedef struct ++ { ++ unsigned char SpecReg0Sel; ++ unsigned char SpecReg0ValueTable[RTL2840_SPEC_REG_0_VALUE_TABLE_LEN]; ++ } ++ INIT_SPEC_REG_0_ENTRY; ++ ++ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long WritingValue[TS_INTERFACE_MODE_NUM]; ++ } ++ TS_INTERFACE_INIT_TABLE_ENTRY; ++ ++ ++ ++ static const INIT_REG_ENTRY InitRegTable[RTL2840_INIT_REG_TABLE_LEN] = ++ { ++ // PageNo, RegStartAddr, Msb, Lsb, WritingValue ++ {0, 0x04, 2, 0, 0x5 }, ++ {0, 0x04, 4, 3, 0x0 }, ++ {0, 0x04, 5, 5, 0x1 }, ++ {0, 0x06, 0, 0, 0x0 }, ++ {0, 0x07, 2, 2, 0x0 }, ++ {1, 0x04, 0, 0, 0x0 }, ++ {1, 0x04, 1, 1, 0x0 }, ++ {1, 0x04, 2, 2, 0x0 }, ++ {1, 0x04, 3, 3, 0x0 }, ++ {1, 0x0c, 2, 0, 0x7 }, ++ {1, 0x19, 5, 5, 0x0 }, ++ {1, 0x19, 6, 6, 0x1 }, ++ {1, 0x19, 7, 7, 0x1 }, ++ {1, 0x1a, 0, 0, 0x0 }, ++ {1, 0x1a, 1, 1, 0x1 }, ++ {1, 0x1a, 2, 2, 0x0 }, ++ {1, 0x1a, 3, 3, 0x1 }, ++ {1, 0x1a, 4, 4, 0x0 }, ++ {1, 0x1a, 5, 5, 0x1 }, ++ {1, 0x1a, 6, 6, 0x1 }, ++ {1, 0x1b, 3, 0, 0x7 }, ++ {1, 0x1b, 7, 4, 0xc }, ++ {1, 0x1c, 2, 0, 0x4 }, ++ {1, 0x1c, 5, 3, 0x3 }, ++ {1, 0x1d, 5, 0, 0x7 }, ++ {1, 0x27, 9, 0, 0x6d }, ++ {1, 0x2b, 7, 0, 0x26 }, ++ {1, 0x2c, 7, 0, 0x1e }, ++ {1, 0x2e, 7, 6, 0x3 }, ++ {1, 0x32, 2, 0, 0x7 }, ++ {1, 0x32, 5, 3, 0x0 }, ++ {1, 0x32, 6, 6, 0x1 }, ++ {1, 0x32, 7, 7, 0x0 }, ++ {1, 0x33, 6, 0, 0xf }, ++ {1, 0x33, 7, 7, 0x1 }, ++ {1, 0x39, 7, 0, 0x88 }, ++ {1, 0x3a, 7, 0, 0x36 }, ++ {1, 0x3e, 7, 0, 0x26 }, ++ {1, 0x3f, 7, 0, 0x15 }, ++ {1, 0x4b, 8, 0, 0x166 }, ++ {1, 0x4d, 8, 0, 0x166 }, ++ {2, 0x11, 0, 0, 0x0 }, ++ {2, 0x02, 7, 0, 0x7e }, ++ {2, 0x12, 3, 0, 0x7 }, ++ {2, 0x12, 7, 4, 0x7 }, ++ }; ++ ++ ++ static const INIT_SPEC_REG_0_ENTRY InitSpecReg0Table[RTL2840_INIT_SPEC_REG_0_TABLE_LEN] = ++ { ++ // SpecReg0Sel, {SpecReg0ValueTable } ++ {0, {0x00, 0xd0, 0x49, 0x8e, 0xf2, 0x01, 0x00, 0xc0, 0x62, 0x62, 0x00} }, ++ {1, {0x11, 0x21, 0x89, 0x8e, 0xf2, 0x01, 0x80, 0x8b, 0x62, 0xe2, 0x00} }, ++ {2, {0x22, 0x32, 0x89, 0x8e, 0x72, 0x00, 0xc0, 0x86, 0xe2, 0xe3, 0x00} }, ++ {3, {0x43, 0x44, 0x8b, 0x0e, 0xf2, 0xdd, 0xb5, 0x84, 0xe2, 0xcb, 0x00} }, ++ {4, {0x54, 0x55, 0xcb, 0x1e, 0xf3, 0x4d, 0xb5, 0x84, 0xe2, 0xcb, 0x00} }, ++ {5, {0x65, 0x66, 0xcb, 0x1e, 0xf5, 0x4b, 0xb4, 0x84, 0xe2, 0xcb, 0x00} }, ++ {6, {0x76, 0x77, 0xcb, 0x9e, 0xf7, 0xc7, 0x73, 0x80, 0xe2, 0xcb, 0x00} }, ++ {7, {0x87, 0x88, 0xcb, 0x2e, 0x48, 0x41, 0x72, 0x80, 0xe2, 0xcb, 0x00} }, ++ {8, {0x98, 0x99, 0xcc, 0x3e, 0x48, 0x21, 0x71, 0x80, 0xea, 0xcb, 0x00} }, ++ {11, {0xbb, 0xc8, 0xcb, 0x6e, 0x24, 0x18, 0x73, 0xa0, 0xfa, 0xcf, 0x01} }, ++ {13, {0x1d, 0x1e, 0x4f, 0x8e, 0xf2, 0x01, 0x00, 0x80, 0x62, 0x62, 0x00} }, ++ {14, {0x1e, 0x1f, 0x4f, 0x8e, 0xf2, 0x01, 0x00, 0x80, 0x62, 0x62, 0x00} }, ++ {15, {0x1f, 0x11, 0x4f, 0x8e, 0xf2, 0x01, 0x00, 0x80, 0x62, 0x62, 0x00} }, ++ }; ++ ++ ++ static const TS_INTERFACE_INIT_TABLE_ENTRY TsInterfaceInitTable[RTL2840_TS_INTERFACE_INIT_TABLE_LEN] = ++ { ++ // RegBitName, WritingValue for {Parallel, Serial} ++ {QAM_SERIAL, {0x0, 0x1}}, ++ {QAM_CDIV_PH0, {0x7, 0x0}}, ++ {QAM_CDIV_PH1, {0x7, 0x0}}, ++ }; ++ ++ ++ int i; ++ ++ int TsInterfaceMode; ++ ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ ++ unsigned char SpecReg0Sel; ++ const unsigned char *pSpecReg0ValueTable; ++ ++ unsigned long QamSpecInitA2Backup; ++ unsigned long RegValue, RegValueComparison; ++ int AreAllValueEqual; ++ ++ ++ ++ // Get TS interface mode. ++ TsInterfaceMode = pDemod->TsInterfaceMode; ++ ++ // Initialize demod with register initializing table. ++ for(i = 0; i < RTL2840_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get all information from each register initializing entry. ++ PageNo = InitRegTable[i].PageNo; ++ RegStartAddr = InitRegTable[i].RegStartAddr; ++ Msb = InitRegTable[i].Msb; ++ Lsb = InitRegTable[i].Lsb; ++ WritingValue = InitRegTable[i].WritingValue; ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set register page number with inner page number for specific register 0 initializing. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Initialize demod with specific register 0 initializing table. ++ for(i = 0; i < RTL2840_INIT_SPEC_REG_0_TABLE_LEN; i++) ++ { ++ // Get all information from each specific register 0 initializing entry. ++ SpecReg0Sel = InitSpecReg0Table[i].SpecReg0Sel; ++ pSpecReg0ValueTable = InitSpecReg0Table[i].SpecReg0ValueTable; ++ ++ // Set specific register 0 selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_SEL, SpecReg0Sel) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 values. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RTL2840_SPEC_REG_0_VAL_START_ADDR, pSpecReg0ValueTable, LEN_11_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Initialize demod registers according to the TS interface initializing table. ++ for(i = 0; i < RTL2840_TS_INTERFACE_INIT_TABLE_LEN; i++) ++ { ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, TsInterfaceInitTable[i].RegBitName, ++ TsInterfaceInitTable[i].WritingValue[TsInterfaceMode]) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Backup SPEC_INIT_A2 value. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_SPEC_INIT_A2, &QamSpecInitA2Backup)!= FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Set SPEC_INIT_A2 with 0. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_SPEC_INIT_A2, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Get SPEC_MONITER_INIT_0 several times. ++ // If all SPEC_MONITER_INIT_0 getting values are the same, set SPEC_INIT_A1 with 0. ++ // Note: 1. Need to set SPEC_INIT_A2 with 0 when get SPEC_MONITER_INIT_0. ++ // 2. The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_SPEC_MONITER_INIT_0, &RegValueComparison) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ for(i = 0, AreAllValueEqual = YES; i < RTL2840_SPEC_MONITOR_INIT_0_COMPARISON_TIMES; i++) ++ { ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_SPEC_MONITER_INIT_0, &RegValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ if(RegValue != RegValueComparison) ++ { ++ AreAllValueEqual = NO; ++ ++ break; ++ } ++ } ++ ++ if(AreAllValueEqual == YES) ++ { ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_SPEC_INIT_A1, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ // Restore SPEC_INIT_A2 value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_SPEC_INIT_A2, QamSpecInitA2Backup) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_QAM_MODE ++ ++*/ ++int ++rtl2840_SetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ) ++{ ++ typedef struct ++ { ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue[QAM_QAM_MODE_NUM]; ++ } ++ QAM_MODE_REG_ENTRY; ++ ++ ++ typedef struct ++ { ++ unsigned char SpecReg0Sel; ++ unsigned char SpecReg0ValueTable[QAM_QAM_MODE_NUM][RTL2840_SPEC_REG_0_VALUE_TABLE_LEN]; ++ } ++ QAM_MODE_SPEC_REG_0_ENTRY; ++ ++ ++ ++ static const QAM_MODE_REG_ENTRY QamModeRegTable[RTL2840_QAM_MODE_REG_TABLE_LEN] = ++ { ++ // Reg, WritingValue according to QAM mode ++ // PageNo, StartAddr, Msb, Lsb, {4-Q, 16-Q, 32-Q, 64-Q, 128-Q, 256-Q, 512-Q, 1024-Q} ++ {1, 0x02, 2, 0, {0x7, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }}, ++ {1, 0x05, 7, 0, {0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b }}, ++ {1, 0x2f, 15, 5, {0x37, 0x82, 0xb9, 0x10e, 0x177, 0x21c, 0x2ee, 0x451 }}, ++ {1, 0x31, 5, 0, {0x1, 0x3, 0x4, 0x5, 0x8, 0xa, 0xf, 0x14 }}, ++ {1, 0x2e, 5, 0, {0x2, 0x4, 0x6, 0x8, 0xc, 0x10, 0x18, 0x20 }}, ++ {1, 0x18, 7, 0, {0x0, 0xdb, 0x79, 0x0, 0x8a, 0x0, 0x8c, 0x0 }}, ++ {1, 0x19, 4, 0, {0x14, 0x14, 0xf, 0x14, 0xf, 0x14, 0xf, 0x14 }}, ++ {1, 0x3b, 2, 0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3b, 5, 3, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3c, 2, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3c, 4, 3, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3c, 6, 5, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 1, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 3, 2, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3d, 5, 4, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 7, 6, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x40, 2, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x40, 5, 3, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x3 }}, ++ {1, 0x41, 2, 0, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4 }}, ++ {1, 0x41, 4, 3, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }}, ++ {1, 0x41, 6, 5, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2 }}, ++ {1, 0x42, 1, 0, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3 }}, ++ {1, 0x42, 3, 2, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }}, ++ {1, 0x42, 5, 4, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2 }}, ++ {1, 0x42, 7, 6, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3 }}, ++ }; ++ ++ ++ static const QAM_MODE_SPEC_REG_0_ENTRY QamModeSpecReg0Table[RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN] = ++ { ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {9, { {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 4-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 16-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 32-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 64-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 128-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 256-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 512-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, } // 1024-QAM ++ }, ++ ++ ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {10, { {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 4-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 16-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 32-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 64-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 128-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 256-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 512-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, } // 1024-QAM ++ }, ++ ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {12, { {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 4-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 16-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 32-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 64-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 128-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 256-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 512-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, } // 1024-QAM ++ }, ++ }; ++ ++ ++ int i; ++ ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ ++ unsigned char SpecReg0Sel; ++ const unsigned char *pSpecReg0ValueTable; ++ ++ ++ ++ // Set demod QAM mode with QAM mode register setting table. ++ for(i = 0; i < RTL2840_QAM_MODE_REG_TABLE_LEN; i++) ++ { ++ // Get all information from each register setting entry according to QAM mode. ++ PageNo = QamModeRegTable[i].PageNo; ++ RegStartAddr = QamModeRegTable[i].RegStartAddr; ++ Msb = QamModeRegTable[i].Msb; ++ Lsb = QamModeRegTable[i].Lsb; ++ WritingValue = QamModeRegTable[i].WritingValue[QamMode]; ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set register page number with inner page number for QAM mode specific register 0 setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set demod QAM mode with QAM mode specific register 0 setting table. ++ for(i = 0; i < RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN; i++) ++ { ++ // Get all information from each specific register 0 setting entry according to QAM mode. ++ SpecReg0Sel = QamModeSpecReg0Table[i].SpecReg0Sel; ++ pSpecReg0ValueTable = QamModeSpecReg0Table[i].SpecReg0ValueTable[QamMode]; ++ ++ // Set specific register 0 selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_SEL, SpecReg0Sel) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 values. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RTL2840_SPEC_REG_0_VAL_START_ADDR, pSpecReg0ValueTable, LEN_11_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set demod QAM mode parameter. ++ pDemod->QamMode = QamMode; ++ pDemod->IsQamModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ ++ ++*/ ++int ++rtl2840_SetSymbolRateHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long SymbolRateHz ++ ) ++{ ++ typedef struct ++ { ++ unsigned long TrDeciRatioRangeMin; ++ unsigned char SymbolRateReg0; ++ unsigned long SymbolRateValue[RTL2840_SYMBOL_RATE_VALUE_TABLE_LEN]; ++ } ++ SYMBOL_RATE_ENTRY; ++ ++ ++ ++ static const SYMBOL_RATE_ENTRY SymbolRateTable[RTL2840_SYMBOL_RATE_TABLE_LEN] = ++ { ++ // TrDeciRatioRangeMin, SymbolRateReg0, {SymbolRateValue } ++ {0x1a0000, 0x4, {10, 14, 1, 988, 955, 977, 68, 257, 438} }, ++ {0x160000, 0x5, {2, 15, 19, 1017, 967, 950, 12, 208, 420} }, ++ {0x0, 0x6, {1019, 1017, 9, 29, 3, 957, 956, 105, 377} }, ++ }; ++ ++ ++ int i; ++ ++ unsigned long CrystalFreqHz; ++ const SYMBOL_RATE_ENTRY *pSymbolRateEntry; ++ ++ MPI MpiCrystalFreqHz, MpiSymbolRateHz, MpiConst, MpiVar, MpiNone; ++ ++ unsigned long TrDeciRatio; ++ unsigned char SymbolRateReg0; ++ unsigned long SymbolRateValue; ++ ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Calculate TR_DECI_RATIO value. ++ // Note: Original formula: TR_DECI_RATIO = round( (CrystalFreqHz * pow(2, 18)) / SymbolRateHz ) ++ // Adjusted formula: TR_DECI_RATIO = floor( ((CrystalFreqHz << 19) / SymbolRateHz + 1) >> 1 ) ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ MpiSetValue(&MpiSymbolRateHz, SymbolRateHz); ++ MpiSetValue(&MpiConst, 1); ++ ++ MpiLeftShift(&MpiVar, MpiCrystalFreqHz, 19); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiSymbolRateHz); ++ MpiAdd(&MpiVar, MpiVar, MpiConst); ++ MpiRightShift(&MpiVar, MpiVar, 1); ++ ++ MpiGetValue(MpiVar, (long *)&TrDeciRatio); ++ ++ ++ // Determine symbol rate entry according to TR_DECI_RATIO value and minimum of TR_DECI_RATIO range. ++ for(i = 0; i < RTL2840_SYMBOL_RATE_TABLE_LEN; i++) ++ { ++ if(TrDeciRatio >= SymbolRateTable[i].TrDeciRatioRangeMin) ++ { ++ pSymbolRateEntry = &SymbolRateTable[i]; ++ ++ break; ++ } ++ } ++ ++ ++ // Set register page number with inner page number for symbol rate setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set TR_DECI_RATIO with calculated value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_TR_DECI_RATIO, TrDeciRatio) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set SPEC_SYMBOL_RATE_REG_0 value with determined symbol rate entry. ++ SymbolRateReg0 = pSymbolRateEntry->SymbolRateReg0; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_SYMBOL_RATE_REG_0, SymbolRateReg0) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set symbol rate value with determined symbol rate entry. ++ for(i = 0; i < RTL2840_SYMBOL_RATE_VALUE_TABLE_LEN; i++) ++ { ++ // Get symbol rate value. ++ SymbolRateValue = pSymbolRateEntry->SymbolRateValue[i]; ++ ++ // Set symbol rate register selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_SYMBOL_RATE_SEL, i) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set symbol rate register value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_SYMBOL_RATE_VAL, SymbolRateValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set symbol rate register strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_SYMBOL_RATE_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set demod symbol rate parameter. ++ pDemod->SymbolRateHz = SymbolRateHz; ++ pDemod->IsSymbolRateHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_ALPHA_MODE ++ ++*/ ++int ++rtl2840_SetAlphaMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int AlphaMode ++ ) ++{ ++ static const unsigned long AlphaValueTable[QAM_ALPHA_MODE_NUM][RTL2840_ALPHA_VALUE_TABLE_LEN] = ++ { ++ {258, 94, 156, 517, 6, 1015, 1016, 17, 11, 994, 1011, 51, 15, 926, 1008, 313}, // alpha = 0.12 ++ {258, 31, 28, 3, 6, 1016, 1016, 16, 11, 996, 1010, 50, 16, 927, 1007, 312}, // alpha = 0.13 ++ {131, 257, 27, 2, 8, 1017, 1013, 16, 14, 996, 1008, 50, 18, 927, 1004, 310}, // alpha = 0.15 ++ {0, 195, 30, 30, 6, 1022, 1014, 10, 14, 1002, 1006, 45, 21, 931, 1001, 307}, // alpha = 0.18 ++ {415, 68, 31, 29, 4, 1, 1016, 6, 13, 1006, 1006, 41, 23, 934, 998, 304}, // alpha = 0.20 ++ }; ++ ++ ++ int i; ++ unsigned long AlphaValue; ++ ++ ++ ++ // Set register page number with inner page number for alpha value setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set demod alpha mode with alpha value table. ++ for(i = 0; i < RTL2840_ALPHA_VALUE_TABLE_LEN; i++) ++ { ++ // Get alpha value from alpha value entry according to alpha mode. ++ AlphaValue = AlphaValueTable[AlphaMode][i]; ++ ++ // Set alpha register selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_ALPHA_SEL, i) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set alpha register value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_ALPHA_VAL, AlphaValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set alpha register strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_ALPHA_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set demod alpha mode parameter. ++ pDemod->AlphaMode = AlphaMode; ++ pDemod->IsAlphaModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_IF_FREQ_HZ ++ ++*/ ++int ++rtl2840_SetIfFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ) ++{ ++ unsigned long CrystalFreqHz; ++ unsigned long DdcFreq; ++ ++ MPI MpiIfFreqHz, MpiCrystalFreqHz, MpiConst, MpiVar, MpiNone; ++ ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Calculate DDC_FREQ value. ++ // Note: Original formula: DDC_FREQ = round( (CrystalFreqHz - (IfFreqHz % CrystalFreqHz)) * pow(2, 15) / ++ // CrystalFreqHz ) ++ // Adjusted formula: DDC_FREQ = floor( ( ((CrystalFreqHz - (IfFreqHz % CrystalFreqHz)) << 16) / ++ // CrystalFreqHz + 1 ) >> 1) ++ MpiSetValue(&MpiIfFreqHz, IfFreqHz); ++ MpiSetValue(&MpiCrystalFreqHz, CrystalFreqHz); ++ MpiSetValue(&MpiConst, 1); ++ ++ MpiSetValue(&MpiVar, CrystalFreqHz - (IfFreqHz % CrystalFreqHz)); ++ MpiLeftShift(&MpiVar, MpiVar, 16); ++ MpiDiv(&MpiVar, &MpiNone, MpiVar, MpiCrystalFreqHz); ++ MpiAdd(&MpiVar, MpiVar, MpiConst); ++ MpiRightShift(&MpiVar, MpiVar, 1); ++ ++ MpiGetValue(MpiVar, (long *)&DdcFreq); ++ ++ ++ // Set DDC_FREQ with calculated value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_DDC_FREQ, DdcFreq) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set demod IF frequnecy parameter. ++ pDemod->IfFreqHz = IfFreqHz; ++ pDemod->IsIfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_SPECTRUM_MODE ++ ++*/ ++int ++rtl2840_SetSpectrumMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ) ++{ ++ static const char SpecInvValueTable[SPECTRUM_MODE_NUM] = ++ { ++ // SpecInv ++ 0, // Normal spectrum ++ 1, // Inverse spectrum ++ }; ++ ++ ++ unsigned long SpecInv; ++ ++ ++ ++ // Get SPEC_INV value from spectrum inverse value table according to spectrum mode. ++ SpecInv = SpecInvValueTable[SpectrumMode]; ++ ++ ++ // Set SPEC_INV with gotten value. ++ // Note: Use SetRegBitsWithPage() to set register bits with page setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_SPEC_INV, SpecInv) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set demod spectrum mode parameter. ++ pDemod->SpectrumMode = SpectrumMode; ++ pDemod->IsSpectrumModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_RF_AGC ++ ++*/ ++int ++rtl2840_GetRfAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ) ++{ ++ unsigned long RfAgcBinary; ++ ++ ++ // Get RF AGC binary value from RF_AGC_VALUE monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_RF_AGC_VALUE, &RfAgcBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert RF AGC binary value to signed integer. ++ *pRfAgc = BinToSignedInt(RfAgcBinary, RTL2840_RF_AGC_VALUE_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_IF_AGC ++ ++*/ ++int ++rtl2840_GetIfAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ) ++{ ++ unsigned long IfAgcBinary; ++ ++ ++ // Get IF AGC binary value from IF_AGC_VALUE monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_IF_AGC_VALUE, &IfAgcBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert IF AGC binary value to signed integer. ++ *pIfAgc = BinToSignedInt(IfAgcBinary, RTL2840_IF_AGC_VALUE_BIT_NUM); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_DI_AGC ++ ++*/ ++int ++rtl2840_GetDiAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ) ++{ ++ // Get digital AGC value from DAGC_VALUE monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_DAGC_VALUE, pDiAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++rtl2840_GetTrOffsetPpm( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ) ++{ ++ unsigned long SymbolRateHz; ++ unsigned long CrystalFreqHz; ++ ++ unsigned long TrOffsetBinary; ++ long TrOffsetInt; ++ ++ MPI MpiTrOffsetInt, MpiSymbolRateHz, MpiCrystalFreqHz, MpiVar0, MpiVar1; ++ ++ ++ ++ // Get demod symbol rate in Hz. ++ if(pDemod->GetSymbolRateHz(pDemod, &SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_symbol_rate; ++ ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Get TR offset binary value from TR_OFFSET monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_TR_OFFSET, &TrOffsetBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert TR offset binary value to signed integer. ++ TrOffsetInt = BinToSignedInt(TrOffsetBinary, RTL2840_TR_OFFSET_BIT_NUM); ++ ++ ++ // Get TR offset in ppm. ++ // Note: (TR offset in ppm) = ((TR offset integer) * (symbol rate in Hz) * 1000000) / ++ // ((pow(2, 35) * (crystal frequency in Hz)) ++ // TR offset integer is 31 bit value. ++ MpiSetValue(&MpiTrOffsetInt, TrOffsetInt); ++ MpiSetValue(&MpiSymbolRateHz, (long)SymbolRateHz); ++ MpiSetValue(&MpiCrystalFreqHz, (long)CrystalFreqHz); ++ MpiSetValue(&MpiVar0, 1000000); ++ ++ MpiMul(&MpiVar0, MpiVar0, MpiTrOffsetInt); ++ MpiMul(&MpiVar0, MpiVar0, MpiSymbolRateHz); ++ MpiLeftShift(&MpiVar1, MpiCrystalFreqHz, 35); ++ MpiDiv(&MpiVar0, &MpiVar1, MpiVar0, MpiVar1); ++ ++ MpiGetValue(MpiVar0, pTrOffsetPpm); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_get_demod_symbol_rate: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++rtl2840_GetCrOffsetHz( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ) ++{ ++ unsigned long SymbolRateHz; ++ ++ unsigned long CrOffsetBinary; ++ long CrOffsetInt; ++ ++ MPI MpiCrOffsetInt, MpiSymbolRateHz, MpiMiddleResult; ++ ++ ++ ++ // Get demod symbol rate in Hz. ++ if(pDemod->GetSymbolRateHz(pDemod, &SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_symbol_rate; ++ ++ ++ // Get CR offset binary value from CR_OFFSET monitor register bits. ++ // Note: The function rtl2840_GetMonitorRegBits() will set register page automatically. ++ if(rtl2840_GetMonitorRegBits(pDemod, QAM_CR_OFFSET, &CrOffsetBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Convert CR offset binary value to signed integer. ++ CrOffsetInt = BinToSignedInt(CrOffsetBinary, RTL2840_CR_OFFSET_BIT_NUM); ++ ++ ++ // Get CR offset in Hz. ++ // Note: (CR offset in Hz) = (CR offset integer) * (symbol rate in Hz) / pow(2, 34) ++ // CR offset integer is 32 bit value. ++ MpiSetValue(&MpiCrOffsetInt, CrOffsetInt); ++ MpiSetValue(&MpiSymbolRateHz, (long)SymbolRateHz); ++ ++ MpiMul(&MpiMiddleResult, MpiCrOffsetInt, MpiSymbolRateHz); ++ MpiRightShift(&MpiMiddleResult, MpiMiddleResult, 34); ++ ++ MpiGetValue(MpiMiddleResult, pCrOffsetHz); ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_get_demod_symbol_rate: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_IS_AAGC_LOCKED ++ ++*/ ++int ++rtl2840_IsAagcLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long LockStatus; ++ ++ ++ ++ // Get AAGC lock status from AAGC_LD inner strobe register bits. ++ // Note: The function rtl2840_GetInnerStrobeRegBits() will set register page automatically. ++ if(rtl2840_GetInnerStrobeRegBits(pDemod, QAM_AAGC_LD, &LockStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine answer according to AAGC lock status. ++ if(LockStatus == LOCKED) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_IS_EQ_LOCKED ++ ++*/ ++int ++rtl2840_IsEqLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long LockStatus; ++ ++ ++ ++ // Get EQ lock status from EQ_LD inner strobe register bits. ++ // Note: The function rtl2840_GetInnerStrobeRegBits() will set register page automatically. ++ if(rtl2840_GetInnerStrobeRegBits(pDemod, QAM_EQ_LD, &LockStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine answer according to EQ lock status. ++ if(LockStatus == LOCKED) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_IS_FRAME_LOCKED ++ ++*/ ++int ++rtl2840_IsFrameLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ) ++{ ++ unsigned long LossStatus; ++ ++ ++ ++ // Get frame loss status from SYNCLOST register bits. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_SYNCLOST, &LossStatus) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine answer according to frame loss status. ++ if(LossStatus == NOT_LOST) ++ *pAnswer = YES; ++ else ++ *pAnswer = NO; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_ERROR_RATE ++ ++*/ ++int ++rtl2840_GetErrorRate( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i; ++ unsigned long TestPacketNum; ++ unsigned int WaitCnt; ++ int FrameLock; ++ unsigned long BerReg2, BerReg2Msb, BerReg2Lsb; ++ unsigned long BerReg0, BerReg1; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Calculate test packet number and wait counter value. ++ TestPacketNum = 0x1 << (TestVolume * 2 + 4); ++ WaitCnt = WaitTimeMsMax / RTL2840_BER_WAIT_TIME_MS; ++ ++ ++ // Set TEST_VOLUME with test volume. ++ // Note: The function SetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_TEST_VOLUME, TestVolume) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Clear and enable error counter. ++ // Note: The function SetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_BERT_EN, OFF) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_BERT_EN, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Check if error test is finished. ++ for(i = 0; i < WaitCnt; i++) ++ { ++ // Check if demod is frame-locked. ++ if(pDemod->IsFrameLocked(pDemod, &FrameLock) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ if(FrameLock == NO) ++ goto error_status_frame_lock; ++ ++ ++ // Wait a minute. ++ // Note: The input unit of WaitMs() is ms. ++ pBaseInterface->WaitMs(pBaseInterface, RTL2840_BER_WAIT_TIME_MS); ++ ++ ++ // Set error counter strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ // The function SetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_BER_RD_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Check if error test is finished. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_BER_REG2_15_0, &BerReg2Lsb) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_BER_REG2_18_16, &BerReg2Msb) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ BerReg2 = (BerReg2Msb << RTL2840_BER_REG2_MSB_SHIFT) | BerReg2Lsb; ++ ++ if(BerReg2 == TestPacketNum) ++ break; ++ } ++ ++ ++ // Check time-out status. ++ if(i == WaitCnt) ++ goto error_status_time_out; ++ ++ ++ // Get BER register 0 from BER_REG0. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_BER_REG0, &BerReg0) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Get BER register 1 from BER_REG1. ++ // Note: The function GetRegBitsWithPage() will set register page automatically. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBitsWithPage(pDemod, QAM_BER_REG1, &BerReg1) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Set BER numerator and denominator. ++ *pBerNum = 27 * BerReg0 + BerReg1; ++ *pBerDen = 1632 * TestPacketNum; ++ ++ ++ // Set PER numerator and denominator. ++ *pPerNum = BerReg0; ++ *pPerDen = TestPacketNum; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++error_status_frame_lock: ++error_status_time_out: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SNR_DB ++ ++*/ ++int ++rtl2840_GetSnrDb( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ static const unsigned long SnrConstTable[QAM_QAM_MODE_NUM] = ++ { ++ 26880, // for 4-QAM mode ++ 29852, // for 16-QAM mode ++ 31132, // for 32-QAM mode ++ 32502, // for 64-QAM mode ++ 33738, // for 128-QAM mode ++ 35084, // for 256-QAM mode ++ 36298, // for 512-QAM mode ++ 37649, // for 1024-QAM mode ++ }; ++ ++ int QamMode; ++ ++ unsigned long Mse; ++ long MiddleResult; ++ MPI MpiMse, MpiResult; ++ ++ ++ ++ // Get demod QAM mode. ++ if(pDemod->GetQamMode(pDemod, &QamMode) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_qam_mode; ++ ++ ++ // Get mean-square error from MSE. ++ // Note: The function rtl2840_GetInnerStrobeRegBits() will set register page automatically. ++ if(rtl2840_GetInnerStrobeRegBits(pDemod, QAM_MSE, &Mse) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Calculate SNR dB numerator. ++ MpiSetValue(&MpiMse, Mse); ++ MpiLog2(&MpiResult, MpiMse, RTL2840_SNR_FRAC_BIT_NUM); ++ MpiGetValue(MpiResult, &MiddleResult); ++ ++ *pSnrDbNum = SnrConstTable[QamMode] - 10 * MiddleResult; ++ ++ ++ // Set SNR dB denominator. ++ *pSnrDbDen = RTL2840_SNR_DB_DEN; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_get_demod_qam_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++rtl2840_GetSignalStrength( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ) ++{ ++ int FrameLock; ++ long IfAgcValue; ++ ++ ++ ++ // Get demod frame lock status. ++ if(pDemod->IsFrameLocked(pDemod, &FrameLock) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // If demod is not frame-locked, set signal strength with zero. ++ if(FrameLock == NO) ++ { ++ *pSignalStrength = 0; ++ goto success_status_non_frame_lock; ++ } ++ ++ ++ // Get IF AGC value. ++ if(pDemod->GetIfAgc(pDemod, &IfAgcValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine signal strength according to IF AGC value. ++ // Note: Map IF AGC value (1023 ~ -1024) to signal strength (0 ~ 100). ++ *pSignalStrength = (102300 - IfAgcValue * 100) / 2047; ++ ++ ++success_status_non_frame_lock: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++rtl2840_GetSignalQuality( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ) ++{ ++ int FrameLock; ++ ++ unsigned long Mse; ++ long MiddleResult; ++ MPI MpiMse, MpiResult; ++ ++ ++ ++ // Get demod frame lock status. ++ if(pDemod->IsFrameLocked(pDemod, &FrameLock) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // If demod is not frame-locked, set signal quality with zero. ++ if(FrameLock == NO) ++ { ++ *pSignalQuality = 0; ++ goto success_status_non_frame_lock; ++ } ++ ++ ++ // Get mean-square error from MSE. ++ // Note: The function rtl2840_GetInnerStrobeRegBits() will set register page automatically. ++ if(rtl2840_GetInnerStrobeRegBits(pDemod, QAM_MSE, &Mse) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Determine signal quality according to MSE value. ++ // Note: Map MSE value (pow(2, 19) ~ pow(2, 17)) to signal quality (0 ~ 100). ++ // If MSE value < pow(2, 17), signal quality is 100. ++ // If MSE value > pow(2, 19), signal quality is 0. ++ if(Mse > 524288) ++ { ++ *pSignalQuality = 0; ++ } ++ else if(Mse < 131072) ++ { ++ *pSignalQuality = 100; ++ } ++ else ++ { ++ MpiSetValue(&MpiMse, Mse); ++ MpiLog2(&MpiResult, MpiMse, RTL2840_SIGNAL_QUALITY_FRAC_BIT_NUM); ++ MpiGetValue(MpiResult, &MiddleResult); ++ ++ *pSignalQuality = (243200 - MiddleResult * 100) / 256; ++ } ++ ++ ++success_status_non_frame_lock: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2840_UpdateFunction( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ // RTL2840 does not use UpdateFunction(), so we just return FUNCTION_SUCCESS. ++ return FUNCTION_SUCCESS; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_RESET_FUNCTION ++ ++*/ ++int ++rtl2840_ResetFunction( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ // RTL2840 does not use UpdateFunction(), so we just return FUNCTION_SUCCESS. ++ return FUNCTION_SUCCESS; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_QAM_MODE ++ ++*/ ++int ++rtl2840_am_hum_en_SetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ) ++{ ++ typedef struct ++ { ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue[QAM_QAM_MODE_NUM]; ++ } ++ QAM_MODE_REG_ENTRY; ++ ++ ++ typedef struct ++ { ++ unsigned char SpecReg0Sel; ++ unsigned char SpecReg0ValueTable[QAM_QAM_MODE_NUM][RTL2840_SPEC_REG_0_VALUE_TABLE_LEN]; ++ } ++ QAM_MODE_SPEC_REG_0_ENTRY; ++ ++ ++ ++ static const QAM_MODE_REG_ENTRY QamModeRegTable[RTL2840_QAM_MODE_REG_TABLE_LEN] = ++ { ++ // Reg, WritingValue according to QAM mode ++ // PageNo, StartAddr, Msb, Lsb, {4-Q, 16-Q, 32-Q, 64-Q, 128-Q, 256-Q, 512-Q, 1024-Q} ++ {1, 0x02, 2, 0, {0x7, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }}, ++ {1, 0x2f, 15, 5, {0x37, 0x82, 0xb9, 0x10e, 0x177, 0x21c, 0x2ee, 0x451 }}, ++ {1, 0x31, 5, 0, {0x1, 0x3, 0x4, 0x5, 0x8, 0xa, 0xf, 0x14 }}, ++ {1, 0x2e, 5, 0, {0x2, 0x4, 0x6, 0x8, 0xc, 0x10, 0x18, 0x20 }}, ++ {1, 0x18, 7, 0, {0x0, 0xdb, 0x79, 0x0, 0x8a, 0x0, 0x8c, 0x0 }}, ++ {1, 0x19, 4, 0, {0x14, 0x14, 0xf, 0x14, 0xf, 0x14, 0xf, 0x14 }}, ++ {1, 0x3b, 2, 0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3b, 5, 3, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3c, 2, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3c, 4, 3, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3c, 6, 5, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 1, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 3, 2, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1 }}, ++ {1, 0x3d, 5, 4, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x3d, 7, 6, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x41, 4, 3, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }}, ++ {1, 0x41, 6, 5, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2 }}, ++ {1, 0x42, 1, 0, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3 }}, ++ {1, 0x42, 3, 2, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }}, ++ {1, 0x42, 5, 4, {0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2 }}, ++ {1, 0x42, 7, 6, {0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3 }}, ++ ++ ++ // For AM-hum enhancement ++ // Reg, WritingValue according to QAM mode ++ // PageNo, StartAddr, Msb, Lsb, {4-Q, 16-Q, 32-Q, 64-Q, 128-Q, 256-Q, 512-Q, 1024-Q} ++ {1, 0x05, 7, 0, {0x64, 0x64, 0x64, 0x64, 0x6b, 0x6b, 0x6b, 0x6b }}, ++ {1, 0x40, 2, 0, {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2 }}, ++ {1, 0x40, 5, 3, {0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x3, 0x3 }}, ++ {1, 0x41, 2, 0, {0x0, 0x0, 0x0, 0x0, 0x3, 0x3, 0x4, 0x4 }}, ++ }; ++ ++ ++ static const QAM_MODE_SPEC_REG_0_ENTRY QamModeSpecReg0Table[RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN] = ++ { ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {9, { {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 4-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 16-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 32-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 64-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 128-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, // 256-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x10, 0x70, 0x80, 0xfa, 0xcb, 0x00}, // 512-QAM ++ {0x99, 0xa9, 0xc9, 0x4e, 0x48, 0x20, 0x71, 0x80, 0xfa, 0xcb, 0x00}, } // 1024-QAM ++ }, ++ ++ ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {10, { {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 4-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 16-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 32-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 64-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 128-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x20, 0x71, 0xa0, 0xfa, 0xcb, 0x00}, // 256-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, // 512-QAM ++ {0xaa, 0xbb, 0xee, 0x5e, 0x48, 0x10, 0x70, 0xa0, 0xfa, 0xcb, 0x00}, } // 1024-QAM ++ }, ++ ++ ++ ++ // For AM-hum enhancement ++ // SpecReg0Sel, {SpecReg0ValueTable } QAM mode ++ {12, { {0xc8, 0xcc, 0x40, 0x7e, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 4-QAM ++ {0xc8, 0xcc, 0x40, 0x7e, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 16-QAM ++ {0xc8, 0xcc, 0x40, 0x7e, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 32-QAM ++ {0xc8, 0xcc, 0x40, 0x7e, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 64-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 128-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 256-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, // 512-QAM ++ {0xc8, 0xcc, 0x00, 0x7f, 0x28, 0xda, 0x4b, 0xa0, 0xfe, 0xcd, 0x01}, } // 1024-QAM ++ }, ++ }; ++ ++ ++ int i; ++ ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ unsigned long WritingValue; ++ ++ unsigned char SpecReg0Sel; ++ const unsigned char *pSpecReg0ValueTable; ++ ++ ++ ++ // Set demod QAM mode with QAM mode register setting table. ++ for(i = 0; i < RTL2840_QAM_MODE_REG_TABLE_LEN; i++) ++ { ++ // Get all information from each register setting entry according to QAM mode. ++ PageNo = QamModeRegTable[i].PageNo; ++ RegStartAddr = QamModeRegTable[i].RegStartAddr; ++ Msb = QamModeRegTable[i].Msb; ++ Lsb = QamModeRegTable[i].Lsb; ++ WritingValue = QamModeRegTable[i].WritingValue[QamMode]; ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set register page number with inner page number for QAM mode specific register 0 setting. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set demod QAM mode with QAM mode specific register 0 setting table. ++ for(i = 0; i < RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN; i++) ++ { ++ // Get all information from each specific register 0 setting entry according to QAM mode. ++ SpecReg0Sel = QamModeSpecReg0Table[i].SpecReg0Sel; ++ pSpecReg0ValueTable = QamModeSpecReg0Table[i].SpecReg0ValueTable[QamMode]; ++ ++ // Set specific register 0 selection. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_SEL, SpecReg0Sel) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 values. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RTL2840_SPEC_REG_0_VAL_START_ADDR, pSpecReg0ValueTable, LEN_11_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // Set specific register 0 strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_SPEC_REG_0_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set demod QAM mode parameter. ++ pDemod->QamMode = QamMode; ++ pDemod->IsQamModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD ++ ++*/ ++int ++rtl2840_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module and tuner device address. ++ pDemod = (QAM_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Enable demod I2C relay. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_OPT_I2C_RELAY, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Send I2C reading command. ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_reading_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_reading_command: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD ++ ++*/ ++int ++rtl2840_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get demod module and tuner device address. ++ pDemod = (QAM_DEMOD_MODULE *)pI2cBridge->pPrivateData; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Enable demod I2C relay. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_OPT_I2C_RELAY, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Send I2C writing command. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, pWritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_send_i2c_writing_command; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_send_i2c_writing_command: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Initialize base register table ++ ++RTL2840 builder will use rtl2840_InitBaseRegTable() to initialize base register table. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2840Module() ++ ++*/ ++void ++rtl2840_InitBaseRegTable( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ static const QAM_PRIMARY_BASE_REG_ENTRY_ADDR_8BIT PrimaryBaseRegTable[RTL2840_BASE_REG_TABLE_LEN] = ++ { ++ // Generality ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_SYS_VERSION, 0, 0x01, 7, 0 }, ++ {QAM_OPT_I2C_RELAY, 0, 0x03, 5, 5 }, ++ {QAM_SOFT_RESET, 0, 0x09, 0, 0 }, ++ ++ // Miscellany ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_OPT_I2C_DRIVE_CURRENT, 0, 0x07, 7, 7 }, ++ {QAM_GPIO2_OEN, 0, 0x05, 6, 6 }, ++ {QAM_GPIO3_OEN, 0, 0x05, 7, 7 }, ++ {QAM_GPIO2_O, 0, 0x0a, 2, 2 }, ++ {QAM_GPIO3_O, 0, 0x0a, 3, 3 }, ++ {QAM_GPIO2_I, 0, 0x0a, 6, 6 }, ++ {QAM_GPIO3_I, 0, 0x0a, 7, 7 }, ++ {QAM_INNER_DATA_STROBE, 1, 0x69, 0, 0 }, ++ {QAM_INNER_DATA_SEL1, 1, 0x48, 7, 0 }, ++ {QAM_INNER_DATA_SEL2, 1, 0x49, 7, 0 }, ++ {QAM_INNER_DATA1, 1, 0x6a, 15, 0 }, ++ {QAM_INNER_DATA2, 1, 0x6c, 15, 0 }, ++ ++ // QAM mode ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_QAM_MODE, 1, 0x02, 2, 0 }, ++ ++ // AD ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_AD_AV, 0, 0x0b, 2, 0 }, ++ ++ // AAGC ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_OPT_RF_AAGC_DRIVE_CURRENT, 0, 0x07, 0, 0 }, ++ {QAM_OPT_IF_AAGC_DRIVE_CURRENT, 0, 0x07, 1, 1 }, ++ {QAM_OPT_RF_AAGC_DRIVE, 0, 0x04, 3, 3 }, ++ {QAM_OPT_IF_AAGC_DRIVE, 0, 0x04, 4, 4 }, ++ {QAM_OPT_RF_AAGC_OEN, 0, 0x04, 6, 6 }, ++ {QAM_OPT_IF_AAGC_OEN, 0, 0x04, 7, 7 }, ++ {QAM_PAR_RF_SD_IB, 0, 0x03, 0, 0 }, ++ {QAM_PAR_IF_SD_IB, 0, 0x03, 1, 1 }, ++ {QAM_AAGC_FZ_OPTION, 1, 0x04, 5, 4 }, ++ {QAM_AAGC_TARGET, 1, 0x05, 7, 0 }, ++ {QAM_RF_AAGC_MAX, 1, 0x06, 7, 0 }, ++ {QAM_RF_AAGC_MIN, 1, 0x07, 7, 0 }, ++ {QAM_IF_AAGC_MAX, 1, 0x08, 7, 0 }, ++ {QAM_IF_AAGC_MIN, 1, 0x09, 7, 0 }, ++ {QAM_VTOP, 1, 0x0b, 7, 0 }, ++ {QAM_KRF_MSB, 1, 0x0c, 6, 3 }, ++ {QAM_KRF_LSB, 1, 0x04, 7, 6 }, ++ {QAM_AAGC_MODE_SEL, 1, 0x0c, 7, 7 }, ++ {QAM_AAGC_LD, 1, 0x72, 0, 0 }, ++ {QAM_AAGC_INIT_LEVEL, 1, 0x0a, 7, 0 }, ++ ++ // DDC ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_DDC_FREQ, 1, 0x0d, 14, 0 }, ++ {QAM_SPEC_INV, 1, 0x0e, 7, 7 }, ++ ++ // Timing recovery ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_TR_DECI_RATIO, 1, 0x1f, 23, 0 }, ++ ++ // Carrier recovery ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_CR_LD, 1, 0x74, 5, 0 }, ++ ++ // Equalizer ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_EQ_LD, 1, 0x72, 1, 1 }, ++ {QAM_MSE, 1, 0x76, 21, 0 }, ++ ++ // Frame sync. indicator ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_SYNCLOST, 2, 0x02, 7, 7 }, ++ ++ // BER ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_BER_RD_STROBE, 2, 0x05, 7, 7 }, ++ {QAM_BERT_EN, 2, 0x06, 0, 0 }, ++ {QAM_BERT_HOLD, 2, 0x06, 1, 1 }, ++ {QAM_DIS_AUTO_MODE, 2, 0x06, 2, 2 }, ++ {QAM_TEST_VOLUME, 2, 0x06, 5, 3 }, ++ {QAM_BER_REG0, 2, 0x0e, 15, 0 }, ++ {QAM_BER_REG1, 2, 0x07, 20, 0 }, ++ {QAM_BER_REG2_15_0, 2, 0x0a, 15, 0 }, ++ {QAM_BER_REG2_18_16, 2, 0x09, 7, 5 }, ++ ++ // MPEG TS output interface ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_CKOUTPAR, 2, 0x11, 0, 0 }, ++ {QAM_CKOUT_PWR, 2, 0x11, 1, 1 }, ++ {QAM_CDIV_PH0, 2, 0x12, 3, 0 }, ++ {QAM_CDIV_PH1, 2, 0x12, 7, 4 }, ++ {QAM_MPEG_OUT_EN, 0, 0x04, 5, 5 }, ++ {QAM_OPT_MPEG_DRIVE_CURRENT, 0, 0x07, 2, 2 }, ++ {QAM_NO_REINVERT, 2, 0x10, 2, 2 }, ++ {QAM_FIX_TEI, 2, 0x10, 3, 3 }, ++ {QAM_SERIAL, 2, 0x11, 2, 2 }, ++ ++ // Monitor ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_ADC_CLIP_CNT_REC, 1, 0x6a, 15, 4 }, ++ {QAM_DAGC_LEVEL_26_11, 1, 0x6a, 15, 0 }, ++ {QAM_DAGC_LEVEL_10_0, 1, 0x6c, 15, 5 }, ++ {QAM_RF_AAGC_SD_IN, 1, 0x6a, 15, 5 }, ++ {QAM_IF_AAGC_SD_IN, 1, 0x6c, 15, 5 }, ++ {QAM_KI_TR_OUT_30_15, 1, 0x6a, 15, 0 }, ++ {QAM_KI_TR_OUT_14_0, 1, 0x6c, 15, 1 }, ++ {QAM_KI_CR_OUT_15_0, 1, 0x6a, 15, 0 }, ++ {QAM_KI_CR_OUT_31_16, 1, 0x6c, 15, 0 }, ++ ++ // Specific register ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_SPEC_SIGNAL_INDICATOR, 1, 0x73, 5, 3 }, ++ {QAM_SPEC_ALPHA_STROBE, 1, 0x57, 0, 0 }, ++ {QAM_SPEC_ALPHA_SEL, 1, 0x57, 4, 1 }, ++ {QAM_SPEC_ALPHA_VAL, 1, 0x57, 14, 5 }, ++ {QAM_SPEC_SYMBOL_RATE_REG_0, 1, 0x0f, 2, 0 }, ++ {QAM_SPEC_SYMBOL_RATE_STROBE, 1, 0x5b, 0, 0 }, ++ {QAM_SPEC_SYMBOL_RATE_SEL, 1, 0x5b, 4, 1 }, ++ {QAM_SPEC_SYMBOL_RATE_VAL, 1, 0x5b, 14, 5 }, ++ {QAM_SPEC_REG_0_STROBE, 1, 0x5d, 0, 0 }, ++ {QAM_SPEC_REG_0_SEL, 1, 0x5d, 4, 1 }, ++ ++ // Specific register for initialization ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_SPEC_INIT_A0, 1, 0x6a, 15, 6 }, ++ {QAM_SPEC_INIT_A1, 0, 0x0f, 0, 0 }, ++ {QAM_SPEC_INIT_A2, 1, 0x2b, 1, 1 }, ++ ++ // Pseudo register for test only ++ // RegBitName, PageNo, RegStartAddr, Msb, Lsb ++ {QAM_TEST_REG_0, 1, 0x17, 6, 2 }, ++ {QAM_TEST_REG_1, 1, 0x17, 14, 1 }, ++ {QAM_TEST_REG_2, 1, 0x17, 21, 3 }, ++ {QAM_TEST_REG_3, 1, 0x17, 30, 2 }, ++ }; ++ ++ ++ int i; ++ int RegBitName; ++ ++ ++ ++ // Initialize base register table according to primary base register table. ++ // Note: 1. Base register table rows are sorted by register bit name key. ++ // 2. The default value of the IsAvailable variable is "NO". ++ for(i = 0; i < QAM_BASE_REG_TABLE_LEN_MAX; i++) ++ pDemod->BaseRegTable.Addr8Bit[i].IsAvailable = NO; ++ ++ for(i = 0; i < RTL2840_BASE_REG_TABLE_LEN; i++) ++ { ++ RegBitName = PrimaryBaseRegTable[i].RegBitName; ++ ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].IsAvailable = YES; ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].PageNo = PrimaryBaseRegTable[i].PageNo; ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].RegStartAddr = PrimaryBaseRegTable[i].RegStartAddr; ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].Msb = PrimaryBaseRegTable[i].Msb; ++ pDemod->BaseRegTable.Addr8Bit[RegBitName].Lsb = PrimaryBaseRegTable[i].Lsb; ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Initialize monitor register table ++ ++RTL2840 builder will use rtl2840_InitMonitorRegTable() to initialize monitor register table. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2840Module() ++ ++*/ ++void ++rtl2840_InitMonitorRegTable( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ static const QAM_PRIMARY_MONITOR_REG_ENTRY_ADDR_8BIT PrimaryMonitorRegTable[RTL2840_MONITOR_REG_TABLE_LEN] = ++ { ++ // Generality ++ // MonitorRegBitName, InfoNum, {SelRegAddr, SelValue, RegBitName, Shift } ++ {QAM_ADC_CLIP_CNT, 1, { {0x48, 0x01, QAM_ADC_CLIP_CNT_REC, 0 }, ++ {NO_USE, NO_USE, NO_USE, NO_USE }, }}, ++ ++ {QAM_DAGC_VALUE, 2, { {0x48, 0x20, QAM_DAGC_LEVEL_26_11, 11 }, ++ {0x49, 0x20, QAM_DAGC_LEVEL_10_0, 0 }, }}, ++ ++ {QAM_RF_AGC_VALUE, 1, { {0x48, 0x80, QAM_RF_AAGC_SD_IN, 0 }, ++ {NO_USE, NO_USE, NO_USE, NO_USE }, }}, ++ ++ {QAM_IF_AGC_VALUE, 1, { {0x49, 0x80, QAM_IF_AAGC_SD_IN, 0 }, ++ {NO_USE, NO_USE, NO_USE, NO_USE }, }}, ++ ++ {QAM_TR_OFFSET, 2, { {0x48, 0xc2, QAM_KI_TR_OUT_30_15, 15 }, ++ {0x49, 0xc2, QAM_KI_TR_OUT_14_0, 0 }, }}, ++ ++ {QAM_CR_OFFSET, 2, { {0x48, 0xc3, QAM_KI_CR_OUT_15_0, 0 }, ++ {0x49, 0xc3, QAM_KI_CR_OUT_31_16, 16 }, }}, ++ ++ // Specific monitor register for initialization ++ // MonitorRegBitName, InfoNum, {SelRegAddr, SelValue, RegBitName, Shift } ++ {QAM_SPEC_MONITER_INIT_0, 1, { {0x48, 0x00, QAM_SPEC_INIT_A0, 0 }, ++ {NO_USE, NO_USE, NO_USE, NO_USE }, }}, ++ }; ++ ++ ++ int i, j; ++ int MonitorRegBitName; ++ ++ ++ ++ // Initialize monitor register table according to primary monitor register table. ++ // Note: 1. Monitor register table rows are sorted by monitor register name key. ++ // 2. The default value of the IsAvailable variable is "NO". ++ for(i = 0; i < QAM_MONITOR_REG_TABLE_LEN_MAX; i++) ++ pDemod->MonitorRegTable.Addr8Bit[i].IsAvailable = NO; ++ ++ for(i = 0; i < RTL2840_MONITOR_REG_TABLE_LEN; i++) ++ { ++ MonitorRegBitName = PrimaryMonitorRegTable[i].MonitorRegBitName; ++ ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].IsAvailable = YES; ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoNum = PrimaryMonitorRegTable[i].InfoNum; ++ ++ for(j = 0; j < QAM_MONITOR_REG_INFO_TABLE_LEN; j++) ++ { ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[j].SelRegAddr = ++ PrimaryMonitorRegTable[i].InfoTable[j].SelRegAddr; ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[j].SelValue = ++ PrimaryMonitorRegTable[i].InfoTable[j].SelValue; ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[j].RegBitName = ++ PrimaryMonitorRegTable[i].InfoTable[j].RegBitName; ++ pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[j].Shift = ++ PrimaryMonitorRegTable[i].InfoTable[j].Shift; ++ } ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get inner strobe register bits. ++ ++RTL2840 upper level functions will use rtl2840_GetInnerStrobeRegBits() to get register bits with inner strobe. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name and inner strobe. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Don't need to set register page before using rtl2840_GetInnerStrobeRegBits(). ++ ++*/ ++int ++rtl2840_GetInnerStrobeRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ // Set register page number with inner page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set inner data strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_INNER_DATA_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get the inner strobe register bits. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, RegBitName, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get monitor register bits. ++ ++RTL2840 upper level functions will use rtl2840_GetMonitorRegBits() to get monitor register bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] MonitorRegBitName Pre-defined demod monitor register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod monitor register bits successfully with monitor bit name. ++@retval FUNCTION_ERROR Get demod monitor register bits unsuccessfully. ++ ++ ++@note ++ -# Don't need to set register page before using rtl2840_GetMonitorRegBits(). ++ ++*/ ++int ++rtl2840_GetMonitorRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int MonitorRegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char InfoNum; ++ unsigned char SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ ++ unsigned long Buffer[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++ ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].IsAvailable == NO) ++ goto error_status_monitor_register_bit_name; ++ ++ ++ // Get information entry number from monitor register table by monitor register name key. ++ InfoNum = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoNum; ++ ++ ++ // Set register page number with inner page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, 1) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set selection register with selection value for each information entry. ++ for(i = 0; i < InfoNum; i++) ++ { ++ // Get selection register address and value from information entry by monitor register name key. ++ SelRegAddr = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[i].SelRegAddr; ++ SelValue = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[i].SelValue; ++ ++ // Set selection register with selection value. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, SelRegAddr, &SelValue, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ // Set inner data strobe. ++ // Note: RTL2840 hardware will clear strobe automatically. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, QAM_INNER_DATA_STROBE, ON) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get register bits to buffer according to register bit names for each information entry. ++ for(i = 0; i < InfoNum; i++) ++ { ++ // Get register bit name from information entry by monitor register name key. ++ RegBitName = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[i].RegBitName; ++ ++ // Get register bits and store it to buffer. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, RegBitName, &Buffer[i]) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ // Combine the buffer values into reading value. ++ *pReadingValue = 0; ++ ++ for(i = 0; i < InfoNum; i++) ++ { ++ // Get shift from information entry by monitor register name key. ++ Shift = pDemod->MonitorRegTable.Addr8Bit[MonitorRegBitName].InfoTable[i].Shift; ++ ++ // Combine the buffer values into reading value with shift. ++ *pReadingValue |= Buffer[i] << Shift; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++error_status_monitor_register_bit_name: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set I2C bridge module demod arguments. ++ ++RTL2840 builder will use rtl2840_BuildI2cBridgeModule() to set I2C bridge module demod arguments. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@see BuildRtl2840Module() ++ ++*/ ++void ++rtl2840_BuildI2cBridgeModule( ++ QAM_DEMOD_MODULE *pDemod ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ ++ // Get I2C bridge module. ++ pI2cBridge = pDemod->pI2cBridge; ++ ++ // Set I2C bridge module demod arguments. ++ pI2cBridge->pPrivateData = (void *)pDemod; ++ pI2cBridge->ForwardI2cReadingCmd = rtl2840_ForwardI2cReadingCmd; ++ pI2cBridge->ForwardI2cWritingCmd = rtl2840_ForwardI2cWritingCmd; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/demod_rtl2840.h b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2840.h +--- a/drivers/media/dvb/dvb-usb/demod_rtl2840.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/demod_rtl2840.h 2016-04-02 19:17:52.088066039 -0300 +@@ -0,0 +1,386 @@ ++#ifndef __DEMOD_RTL2840_H ++#define __DEMOD_RTL2840_H ++ ++/** ++ ++@file ++ ++@brief RTL2840 QAM demod module declaration ++ ++One can manipulate RTL2840 QAM demod through RTL2840 module. ++RTL2840 module is derived from QAM demod module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the QAM demod example in qam_demod_base.h except the listed lines. ++ ++ ++ ++#include "demod_rtl2840.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ ++ ... ++ ++ ++ ++ // Build RTL2840 demod module. ++ BuildRtl2840Module( ++ &pDemod, ++ &QamDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x44, // I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // Crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM // Enhancement mode is AM-hum. ++ ); ++ ++ ++ ++ // See the example for other QAM demod functions in qam_demod_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "qam_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2840_BASE_REG_TABLE_LEN 88 ++#define RTL2840_MONITOR_REG_TABLE_LEN 7 ++ ++#define RTL2840_PAGE_REG_ADDR 0x0 ++#define RTL2840_SYS_VERSION_VALUE 0xa3 ++ ++ ++ ++// Specific register ++#define RTL2840_SPEC_REG_0_VAL_START_ADDR 0x5e ++ ++ ++ ++// Initialization ++#define RTL2840_SPEC_MONITOR_INIT_0_COMPARISON_TIMES 30 ++ ++// RF_AGC_VALUE register ++#define RTL2840_RF_AGC_VALUE_BIT_NUM 11 ++ ++// IF_AGC_VALUE register ++#define RTL2840_IF_AGC_VALUE_BIT_NUM 11 ++ ++// CR_OFFSET register ++#define RTL2840_CR_OFFSET_BIT_NUM 32 ++ ++// TR_OFFSET register ++#define RTL2840_TR_OFFSET_BIT_NUM 31 ++ ++ ++ ++// BER and UPER ++#define RTL2840_BER_WAIT_TIME_MS 10 ++#define RTL2840_BER_REG2_MSB_SHIFT 16 ++ ++// SNR ++// Note: RTL2840_SNR_DB_DEN = round(log2(10) * pow(2, RTL2840_SNR_FRAC_BIT_NUM)) ++#define RTL2840_SNR_FRAC_BIT_NUM 7 ++#define RTL2840_SNR_DB_DEN 425 ++ ++ ++ ++// Singal strength and signal quality ++#define RTL2840_SIGNAL_QUALITY_FRAC_BIT_NUM 7 ++ ++ ++ ++ ++ ++// Table length ++#define RTL2840_SPEC_REG_0_VALUE_TABLE_LEN 11 ++#define RTL2840_SYMBOL_RATE_VALUE_TABLE_LEN 9 ++ ++#define RTL2840_INIT_REG_TABLE_LEN 45 ++#define RTL2840_INIT_SPEC_REG_0_TABLE_LEN 13 ++#define RTL2840_TS_INTERFACE_INIT_TABLE_LEN 3 ++ ++#define RTL2840_QAM_MODE_REG_TABLE_LEN 25 ++#define RTL2840_QAM_MODE_SPEC_REG_0_TABLE_LEN 3 ++ ++#define RTL2840_ALPHA_VALUE_TABLE_LEN 16 ++ ++#define RTL2840_SYMBOL_RATE_TABLE_LEN 3 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2840Module( ++ QAM_DEMOD_MODULE **ppDemod, ++ QAM_DEMOD_MODULE *pQamDemodModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int TsInterfaceMode, ++ int EnhancementMode ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++rtl2840_IsConnectedToI2c( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2840_SoftwareReset( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2840_Initialize( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2840_SetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ); ++ ++int ++rtl2840_SetSymbolRateHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long SymbolRateHz ++ ); ++ ++int ++rtl2840_SetAlphaMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int AlphaMode ++ ); ++ ++int ++rtl2840_SetIfFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++int ++rtl2840_SetSpectrumMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++int ++rtl2840_GetRfAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++int ++rtl2840_GetIfAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++int ++rtl2840_GetDiAgc( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ); ++ ++int ++rtl2840_GetTrOffsetPpm( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++int ++rtl2840_GetCrOffsetHz( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++int ++rtl2840_IsAagcLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2840_IsEqLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2840_IsFrameLocked( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++int ++rtl2840_GetErrorRate( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++int ++rtl2840_GetSnrDb( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++rtl2840_GetSignalStrength( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++rtl2840_GetSignalQuality( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++rtl2840_UpdateFunction( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++int ++rtl2840_ResetFunction( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// Demod AM-hum enhancement functions ++int ++rtl2840_am_hum_en_SetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ); ++ ++ ++ ++ ++ ++// I2C command forwarding functions ++int ++rtl2840_ForwardI2cReadingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++rtl2840_ForwardI2cWritingCmd( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++// Register table initialization ++void ++rtl2840_InitBaseRegTable( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++void ++rtl2840_InitMonitorRegTable( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++// Register getting methods ++int ++rtl2840_GetInnerStrobeRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++int ++rtl2840_GetMonitorRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int MonitorRegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// I2C birdge module builder ++void ++rtl2840_BuildI2cBridgeModule( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/dtmb_demod_base.c b/drivers/drivers/media/dvb/dvb-usb/dtmb_demod_base.c +--- a/drivers/media/dvb/dvb-usb/dtmb_demod_base.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/dtmb_demod_base.c 2016-04-02 19:17:52.088066039 -0300 +@@ -0,0 +1,1566 @@ ++/** ++ ++@file ++ ++@brief DTMB demod default function definition ++ ++DTMB demod default functions. ++ ++*/ ++#include "rtl2832u_io.h" ++#include "dtmb_demod_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBytes[LEN_2_BYTE]; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Set demod register page with page number. ++ // Note: The I2C format of demod register page setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + DTMB_DEMOD_PAGE_REG_ADDR + PageNo + stop_bit ++ WritingBytes[0] = DTMB_DEMOD_PAGE_REG_ADDR; ++ WritingBytes[1] = (unsigned char)PageNo; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBytes, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ // temp, because page register is write-only. ++ pDemod->CurrentPageNo = PageNo; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Set register bytes separately. ++int ++internal_dtmb_demod_addr_8bit_SetRegBytesSeparately( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes one by one. ++ for(i = 0; i < ByteNum; i++) ++ { ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = (unsigned char)(RegStartAddr + i); ++ WritingBuffer[1] = pWritingBytes[i]; ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ struct dvb_usb_device *d; ++ unsigned int i; ++ unsigned char DeviceAddr; ++ //unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ unsigned long PageNo = pDemod->CurrentPageNo; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get user defined data pointer of base interface structure for context. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes one by one. ++ for(i = 0; i < ByteNum; i++) ++ { ++ ++ // Set demod register bytes with writing buffer. ++ if(write_demod_register(d, DeviceAddr, PageNo, RegStartAddr+i, (unsigned char*)pWritingBytes+i, LEN_1_BYTE)) ++ goto error_status_set_demod_registers; ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Set register bytes continuously. ++int ++internal_dtmb_demod_addr_8bit_SetRegBytesContinuously( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = (unsigned char)(RegStartAddr + i); ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ unsigned long CurrentPageNo; // temp, because page register is write-only. ++ ++ ++ ++ // Get page register number. ++ CurrentPageNo = pDemod->CurrentPageNo; // temp, because page register is write-only. ++ ++ ++ // Set register bytes according to page register number. ++ switch(CurrentPageNo) ++ { ++ case 0: ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ ++ if(internal_dtmb_demod_addr_8bit_SetRegBytesSeparately(pDemod, RegStartAddr, pWritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ break; ++ ++ ++ default: ++ ++ goto error_status_set_demod_registers; ++ ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Get register bytes separately. ++int ++internal_dtmb_demod_addr_8bit_GetRegBytesSeparately( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ ++ unsigned char DeviceAddr; ++ unsigned char RegAddr; ++ unsigned char RegByte; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes one by one. ++ for(i = 0; i < ByteNum; i++) ++ { ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ RegAddr = (unsigned char)(RegStartAddr + i); ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, &RegAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &RegByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ // Copy register byte to reading bytes. ++ pReadingBytes[i] = RegByte; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ struct dvb_usb_device *d; ++ unsigned int i; ++ ++ unsigned char DeviceAddr; ++ ++ unsigned long PageNo = pDemod->CurrentPageNo; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get user defined data pointer of base interface structure for context. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes one by one. ++ for(i = 0; i < ByteNum; i++) ++ { ++ ++ // Get demod register bytes. ++ if(read_demod_register(d, DeviceAddr, PageNo, RegStartAddr+i, pReadingBytes+i, LEN_1_BYTE)) ++ goto error_status_get_demod_registers; ++ ++ ++ ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++//error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Get register bytes continuously. ++int ++internal_dtmb_demod_addr_8bit_GetRegBytesContinuously( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = (unsigned char)(RegStartAddr + i); ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ struct dvb_usb_device *d; ++ ++ unsigned char DeviceAddr; ++ ++ unsigned long PageNo = pDemod->CurrentPageNo; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get user defined data pointer of base interface structure for context. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ ++ // Get demod register bytes. ++ if(read_demod_register(d, DeviceAddr, PageNo, RegStartAddr, pReadingBytes, ByteNum)) ++ goto error_status_get_demod_registers; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_GetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ unsigned long CurrentPageNo; // temp, because page register is write-only. ++ ++ ++ ++ // Get page register number. ++ CurrentPageNo = pDemod->CurrentPageNo; // temp, because page register is write-only. ++ ++ ++ // Get register bytes according to page register number. ++ switch(CurrentPageNo) ++ { ++ case 0: ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ ++ if(internal_dtmb_demod_addr_8bit_GetRegBytesSeparately(pDemod, RegStartAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ break; ++ ++ ++ case 5: ++ case 6: ++ case 7: ++ case 8: ++ case 9: ++ ++ if(internal_dtmb_demod_addr_8bit_GetRegBytesContinuously(pDemod, RegStartAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ break; ++ ++ ++ default: ++ ++ goto error_status_get_demod_registers; ++ ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value LSB. ++ // Pick up upper address byte from value MSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * i)) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_GetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable.Addr8Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable.Addr8Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable.Addr8Bit[RegBitName].Msb; ++ Lsb = pDemod->RegTable.Addr8Bit[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_GetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable.Addr8Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable.Addr8Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable.Addr8Bit[RegBitName].Msb; ++ Lsb = pDemod->RegTable.Addr8Bit[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_SetRegBitsWithPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned long PageNo; ++ ++ ++ // Get register page number from register table with register bit name key. ++ PageNo = pDemod->RegTable.Addr8Bit[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set register mask bits with register bit name key. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, RegBitName, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++dtmb_demod_addr_8bit_default_GetRegBitsWithPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned long PageNo; ++ ++ ++ // Get register page number from register table with register bit name key. ++ PageNo = pDemod->RegTable.Addr8Bit[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get register mask bits with register bit name key. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, RegBitName, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_SetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned short RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_2_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = (unsigned short)(RegStartAddr + i); ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddrMsb + RegWritingAddrLsb + ++ // writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = (RegWritingAddr >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = RegWritingAddr & BYTE_MASK; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_2_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_2_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Get register bytes normally. ++int ++internal_dtmb_demod_addr_16bit_GetRegBytesNormally( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned short RegReadingAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = (unsigned short)(RegStartAddr + i); ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddrMsb + RegReadingAddrLsb + stop_bit ++ WritingBuffer[0] = (RegReadingAddr >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = RegReadingAddr & BYTE_MASK; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Internal function: ++// Get register bytes with freeze. ++ ++#define DTMB_I2C_REG_DEBUG_PAGE_ADDR 0xc708 ++#define DTMB_I2C_REG_DEBUG_ADDR_ADDR 0xc709 ++#define DTMB_I2C_REG_DEBUG_FREEZE_ADDR 0xc70a ++#define DTMB_I2C_REG_DEBUG_BYTE_ADDR 0xc70b ++ ++int ++internal_dtmb_demod_addr_16bit_GetRegBytesWithFreeze( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ ++ unsigned char WritingBuffer[LEN_4_BYTE]; ++ unsigned char ReadingBuffer[LEN_4_BYTE]; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddrMsb + RegWritingAddrLsb + writing_bytes (WritingByteNum bytes) + stop_bit ++ ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ ++ // Set I2C_REG_DEBUG_PAGE and I2C_REG_DEBUG_ADDR with register start address. ++ // Note: 1. Set I2C_REG_DEBUG_PAGE with register start address [11:8]. ++ // 2. Set I2C_REG_DEBUG_ADDR with register start address [7:0]. ++ WritingBuffer[0] = (DTMB_I2C_REG_DEBUG_PAGE_ADDR >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = DTMB_I2C_REG_DEBUG_PAGE_ADDR & BYTE_MASK; ++ WritingBuffer[2] = (RegStartAddr >> BYTE_SHIFT) & HEX_DIGIT_MASK; ++ WritingBuffer[3] = RegStartAddr & BYTE_MASK; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_4_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set I2C_REG_DEBUG_FREEZE with 0x1. ++ WritingBuffer[0] = (DTMB_I2C_REG_DEBUG_FREEZE_ADDR >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = DTMB_I2C_REG_DEBUG_FREEZE_ADDR & BYTE_MASK; ++ WritingBuffer[2] = 0x1; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_3_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get I2C_REG_DEBUG_BYTE 4 bytes. ++ if(internal_dtmb_demod_addr_16bit_GetRegBytesNormally(pDemod, DTMB_I2C_REG_DEBUG_BYTE_ADDR, ReadingBuffer, LEN_4_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Arrange reading bytes from big-endian to little-endian. ++ // Note: 1. The bytes format reading from I2C_REG_DEBUG_BYTE is big-endian. ++ // 2. The bytes format we needs is little-endian. ++ for(i = 0; i < ByteNum; i++) ++ { ++ // Set reading bytes. ++ pReadingBytes[i] = ReadingBuffer[LEN_3_BYTE - i]; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_GetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ unsigned char RegStartAddrMsb; ++ ++ ++ ++ // Get regiser start address MSB. ++ RegStartAddrMsb = (RegStartAddr >> BYTE_SHIFT) & BYTE_MASK; ++ ++ ++ // Get register bytes according to page register number. ++ switch(RegStartAddrMsb) ++ { ++ case 0xc0: ++ case 0xc1: ++ case 0xc2: ++ case 0xc3: ++ case 0xc4: ++ case 0xc5: ++ case 0xc6: ++ case 0xc7: ++ case 0xe0: ++ case 0xe1: ++ case 0xe2: ++ case 0xe3: ++ case 0xe4: ++ case 0xf0: ++ ++ if(internal_dtmb_demod_addr_16bit_GetRegBytesNormally(pDemod, RegStartAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ break; ++ ++ ++ case 0xc8: ++ case 0xc9: ++ case 0xca: ++ case 0xcb: ++ case 0xcc: ++ case 0xcd: ++ ++ if(internal_dtmb_demod_addr_16bit_GetRegBytesWithFreeze(pDemod, RegStartAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ break; ++ ++ ++ default: ++ ++ goto error_status_get_demod_registers; ++ ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_SetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr16Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value LSB. ++ // Pick up upper address byte from value MSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * i)) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->RegAccess.Addr16Bit.SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_GetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr16Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_SetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable.Addr16Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable.Addr16Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable.Addr16Bit[RegBitName].Msb; ++ Lsb = pDemod->RegTable.Addr16Bit[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr16Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++dtmb_demod_addr_16bit_default_GetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable.Addr16Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable.Addr16Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable.Addr16Bit[RegBitName].Msb; ++ Lsb = pDemod->RegTable.Addr16Bit[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->RegAccess.Addr16Bit.GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_DEMOD_TYPE ++ ++*/ ++void ++dtmb_demod_default_GetDemodType( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ) ++{ ++ // Get demod type from demod module. ++ *pDemodType = pDemod->DemodType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++dtmb_demod_default_GetDeviceAddr( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get demod I2C device address from demod module. ++ *pDeviceAddr = pDemod->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ ++ ++*/ ++void ++dtmb_demod_default_GetCrystalFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ) ++{ ++ // Get demod crystal frequency in Hz from demod module. ++ *pCrystalFreqHz = pDemod->CrystalFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_IF_FREQ_HZ ++ ++*/ ++int ++dtmb_demod_default_GetIfFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ) ++{ ++ // Get demod IF frequency in Hz from demod module. ++ if(pDemod->IsIfFreqHzSet != YES) ++ goto error_status_get_demod_if_frequency; ++ ++ *pIfFreqHz = pDemod->IfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_if_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_DEMOD_FP_GET_SPECTRUM_MODE ++ ++*/ ++int ++dtmb_demod_default_GetSpectrumMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ) ++{ ++ // Get demod spectrum mode from demod module. ++ if(pDemod->IsSpectrumModeSet != YES) ++ goto error_status_get_demod_spectrum_mode; ++ ++ *pSpectrumMode = pDemod->SpectrumMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_spectrum_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/dtmb_demod_base.h b/drivers/drivers/media/dvb/dvb-usb/dtmb_demod_base.h +--- a/drivers/media/dvb/dvb-usb/dtmb_demod_base.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/dtmb_demod_base.h 2016-04-02 19:17:52.088066039 -0300 +@@ -0,0 +1,2505 @@ ++#ifndef __DTMB_DEMOD_BASE_H ++#define __DTMB_DEMOD_BASE_H ++ ++/** ++ ++@file ++ ++@brief DTMB demod base module definition ++ ++DTMB demod base module definitions contains demod module structure, demod funciton pointers, and demod definitions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_xxx.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ ++ long RfAgc, IfAgc; ++ unsigned long DiAgc; ++ ++ int Answer; ++ long TrOffsetPpm, CrOffsetHz; ++ unsigned long BerNum, BerDen; ++ double Ber; ++ unsigned long PerNum, PerDen; ++ double Per; ++ long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ unsigned long SignalStrength, SignalQuality; ++ ++ int CarrierMode; ++ int PnMode; ++ int QamMode; ++ int CodeRateMode; ++ int TimeInterleaverMode; ++ ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pBaseInterface, ++ &BaseInterfaceModuleMemory, ++ 9, // Set maximum I2C reading byte number with 9. ++ 8, // Set maximum I2C writing byte number with 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs // Employ CustomWaitMs() as basic waiting function. ++ ); ++ ++ ++ // Build DTMB demod XXX module. ++ BuildXxxModule( ++ &pDemod, ++ &DtmbDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x3e, // Demod I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // Demod crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // Demod TS interface mode is serial. ++ DIVERSITY_PIP_OFF // Demod diversity and PIP both are disabled. ++ ... // Other arguments by each demod module ++ ); ++ ++ ++ ++ ++ ++ // ==== Initialize DTMB demod and set its parameters ===== ++ ++ // Initialize demod. ++ pDemod->Initialize(pDemod); ++ ++ ++ // Set demod parameters. (IF frequency and spectrum mode) ++ // Note: In the example: ++ // 1. IF frequency is 36.125 MHz. ++ // 2. Spectrum mode is SPECTRUM_INVERSE. ++ IfFreqHz = IF_FREQ_36125000HZ; ++ SpectrumMode = SPECTRUM_INVERSE; ++ ++ pDemod->SetIfFreqHz(pDemod, IfFreqHz); ++ pDemod->SetSpectrumMode(pDemod, SpectrumMode); ++ ++ ++ // Need to set tuner before demod software reset. ++ // The order to set demod and tuner is not important. ++ // Note: 1. For 8-bit register address demod, one can use ++ // "pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1);" ++ // for tuner I2C command forwarding. ++ // 2. For 16-bit register address demod, one can use ++ // "pDemod->RegAccess.Addr16Bit.SetRegBits(pDemod, DTMB_I2CT_EN_CTRL, 0x1);" ++ // for tuner I2C command forwarding. ++ ++ ++ // Reset demod by software reset. ++ pDemod->SoftwareReset(pDemod); ++ ++ ++ // Wait maximum 1000 ms for demod converge. ++ for(i = 0; i < 25; i++) ++ { ++ // Wait 40 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 40); ++ ++ // Check signal lock status. ++ // Note: If Answer is YES, signal is locked. ++ // If Answer is NO, signal is not locked. ++ pDemod->IsSignalLocked(pDemod, &Answer); ++ ++ if(Answer == YES) ++ { ++ // Signal is locked. ++ break; ++ } ++ } ++ ++ ++ ++ ++ ++ // ==== Get DTMB demod information ===== ++ ++ // Get demod type. ++ // Note: One can find demod type in MODULE_TYPE enumeration. ++ pDemod->GetDemodType(pDemod, &DemodType); ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Ask demod if it is connected to I2C bus. ++ // Note: If Answer is YES, demod is connected to I2C bus. ++ // If Answer is NO, demod is not connected to I2C bus. ++ pDemod->IsConnectedToI2c(pDemod, &Answer); ++ ++ ++ // Get demod parameters. (IF frequency and spectrum mode) ++ pDemod->GetIfFreqHz(pDemod, &IfFreqHz); ++ pDemod->GetSpectrumMode(pDemod, &SpectrumMode); ++ ++ ++ // Get demod AGC value. ++ // Note: The range of RF AGC and IF AGC value is -8192 ~ 8191. ++ // The range of digital AGC value is 0 ~ 255. ++ pDemod->GetRfAgc(pDemod, &RfAgc); ++ pDemod->GetIfAgc(pDemod, &IfAgc); ++ pDemod->GetDiAgc(pDemod, &DiAgc); ++ ++ ++ // Get demod lock status. ++ // Note: If Answer is YES, it is locked. ++ // If Answer is NO, it is not locked. ++ pDemod->IsSignalLocked(pDemod, &Answer); ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz); ++ ++ ++ // Get BER. ++ pDemod->GetBer(pDemod, &BerNum, &BerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ ++ // Get PER. ++ pDemod->GetPer(pDemod, &PerNum, &PerDen); ++ Per = (double)PerNum / (double)PerDen; ++ ++ // Get SNR in dB. ++ pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pDemod->GetSignalStrength(pDemod, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pDemod->GetSignalQuality(pDemod, &SignalQuality); ++ ++ ++ // Get signal information. ++ // Note: One can find signal information definitions in the enumerations as follows: ++ // 1. DTMB_CARRIER_MODE ++ // 2. DTMB_PN_MODE ++ // 3. DTMB_QAM_MODE ++ // 4. DTMB_CODE_RATE_MODE ++ // 5. DTMB_TIME_INTERLEAVER_MODE ++ pDemod->GetCarrierMode(pDemod, &CarrierMode); ++ pDemod->GetPnMode(pDemod, &PnMode); ++ pDemod->GetQamMode(pDemod, &QamMode); ++ pDemod->GetCodeRateMode(pDemod, &CodeRateMode); ++ pDemod->GetTimeInterleaverMode(pDemod, &TimeInterleaverMode); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// Page register address ++#define DTMB_DEMOD_PAGE_REG_ADDR 0x0 ++ ++ ++// Carrier mode ++enum DTMB_CARRIER_MODE ++{ ++ DTMB_CARRIER_SINGLE, ++ DTMB_CARRIER_MULTI, ++}; ++ ++ ++// PN mode ++enum DTMB_PN_MODE ++{ ++ DTMB_PN_420, ++ DTMB_PN_595, ++ DTMB_PN_945, ++}; ++ ++ ++// QAM mode ++enum DTMB_QAM_MODE ++{ ++ DTMB_QAM_4QAM_NR, ++ DTMB_QAM_4QAM, ++ DTMB_QAM_16QAM, ++ DTMB_QAM_32QAM, ++ DTMB_QAM_64QAM, ++}; ++#define DTMB_QAM_UNKNOWN -1 ++ ++ ++// Code rate mode ++enum DTMB_CODE_RATE_MODE ++{ ++ DTMB_CODE_RATE_0P4, ++ DTMB_CODE_RATE_0P6, ++ DTMB_CODE_RATE_0P8, ++}; ++#define DTMB_CODE_RATE_UNKNOWN -1 ++ ++ ++// Time interleaver mode ++enum DTMB_TIME_INTERLEAVER_MODE ++{ ++ DTMB_TIME_INTERLEAVER_240, ++ DTMB_TIME_INTERLEAVER_720, ++}; ++#define DTMB_TIME_INTERLEAVER_UNKNOWN -1 ++ ++ ++ ++ ++ ++// Register entry definitions ++ ++// Register entry for 8-bit address ++typedef struct ++{ ++ int IsAvailable; ++ unsigned long PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DTMB_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Primary register entry for 8-bit address ++typedef struct ++{ ++ int RegBitName; ++ unsigned long PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DTMB_PRIMARY_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Register entry for 16-bit address ++typedef struct ++{ ++ int IsAvailable; ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DTMB_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++// Primary register entry for 16-bit address ++typedef struct ++{ ++ int RegBitName; ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DTMB_PRIMARY_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++ ++ ++// Register table dependence ++ ++// Demod register bit names ++enum DTMB_REG_BIT_NAME ++{ ++ // Software reset ++ DTMB_SOFT_RST_N, ++ ++ // Tuner I2C forwording ++ DTMB_I2CT_EN_CTRL, ++ ++ // Chip ID ++ DTMB_CHIP_ID, ++ ++ ++ // IF setting ++ DTMB_EN_SP_INV, ++ DTMB_EN_DCR, ++ DTMB_BBIN_EN, ++ DTMB_IFFREQ, ++ ++ // AGC setting ++ DTMB_AGC_DRIVE_LV, // for RTL2836B DTMB only ++ DTMB_Z_AGC, // for RTL2836B DTMB only ++ DTMB_EN_PGA_MODE, // for RTL2836B DTMB only ++ DTMB_TARGET_VAL, ++ DTMB_AAGC_LOOPGAIN1, // for RTL2836B DTMB only ++ DTMB_POLAR_IFAGC, // for RTL2836B DTMB only ++ DTMB_POLAR_RFAGC, // for RTL2836B DTMB only ++ DTMB_INTEGRAL_CNT_LEN, // for RTL2836B DTMB only ++ DTMB_AAGC_LOCK_PGA_HIT_LEN, // for RTL2836B DTMB only ++ DTMB_THD_LOCK_UP, // for RTL2836B DTMB only ++ DTMB_THD_LOCK_DW, // for RTL2836B DTMB only ++ DTMB_THD_UP1, // for RTL2836B DTMB only ++ DTMB_THD_DW1, // for RTL2836B DTMB only ++ DTMB_THD_UP2, // for RTL2836B DTMB only ++ DTMB_THD_DW2, // for RTL2836B DTMB only ++ DTMB_GAIN_PULSE_SPACE_LEN, // for RTL2836B DTMB only ++ DTMB_GAIN_PULSE_HOLD_LEN, // for RTL2836B DTMB only ++ DTMB_GAIN_STEP_SUM_UP_THD, // for RTL2836B DTMB only ++ DTMB_GAIN_STEP_SUM_DW_THD, // for RTL2836B DTMB only ++ ++ ++ // TS interface ++ DTMB_SERIAL, ++ DTMB_CDIV_PH0, ++ DTMB_CDIV_PH1, ++ DTMB_SER_LSB, ++ DTMB_SYNC_DUR, ++ DTMB_ERR_DUR, ++ DTMB_FIX_TEI, ++ ++ // Signal lock status ++ DTMB_TPS_LOCK, ++ DTMB_PN_PEAK_EXIST, ++ ++ // FSM ++ DTMB_FSM_STATE_R, ++ ++ // Performance measurement ++ DTMB_RO_PKT_ERR_RATE, ++ DTMB_EST_SNR, ++ DTMB_RO_LDPC_BER, ++ ++ // AGC ++ DTMB_GAIN_OUT_R, ++ DTMB_RF_AGC_VAL, ++ DTMB_IF_AGC_VAL, ++ ++ // TR and CR ++ DTMB_TR_OUT_R, ++ DTMB_SFOAQ_OUT_R, ++ DTMB_CFO_EST_R, ++ ++ // Signal information ++ DTMB_EST_CARRIER, ++ DTMB_RX_MODE_R, ++ DTMB_USE_TPS, ++ ++ // GPIO ++ DTMB_DMBT_GPIOA_OE, // For RTL2836B only ++ DTMB_DMBT_GPIOB_OE, // For RTL2836B only ++ DTMB_DMBT_OPT_GPIOA_SEL, // For RTL2836B only ++ DTMB_DMBT_OPT_GPIOB_SEL, // For RTL2836B only ++ DTMB_GPIOA_SEL, // For RTL2836B only ++ DTMB_GPIOB_SEL, // For RTL2836B only ++ ++ // AD7 ++ DTMB_RSSI_R, // For RTL2836B only ++ DTMB_AV_SET7, // For RTL2836B only ++ DTMB_IBX, // For RTL2836B only ++ DTMB_POW_AD7, // For RTL2836B only ++ DTMB_VICM_SET, // For RTL2836B only ++ DTMB_VRC, // For RTL2836B only ++ DTMB_ATT_AD7, // For RTL2836B only ++ ++ // Diversity ++ DTMB_DIV_EN, // For RTL2836B DTMB only ++ DTMB_DIV_MODE, // For RTL2836B DTMB only ++ DTMB_DIV_RX_CLK_XOR, // For RTL2836B DTMB only ++ DTMB_DIV_THD_ERR_CMP0, // For RTL2836B DTMB only ++ DTMB_FSM_10L_MSB_3Byte, // For RTL2836B DTMB only ++ ++ // Item terminator ++ DTMB_REG_BIT_NAME_ITEM_TERMINATOR, ++}; ++ ++ ++ ++// Register table length definitions ++#define DTMB_REG_TABLE_LEN_MAX DTMB_REG_BIT_NAME_ITEM_TERMINATOR ++ ++ ++ ++ ++ ++// DTMB demod module pre-definition ++typedef struct DTMB_DEMOD_MODULE_TAG DTMB_DEMOD_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register page setting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_PAGE() to set demod register page. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] PageNo Page number ++ ++ ++@retval FUNCTION_SUCCESS Set register page successfully with page number. ++@retval FUNCTION_ERROR Set register page unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_PAGE() with the corresponding function. ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register page with page number 2. ++ pDemod->SetRegPage(pDemod, 2); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_PAGE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register byte setting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_BYTES() to set demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] pWritingBytes Pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bytes successfully with writing bytes. ++@retval FUNCTION_ERROR Set demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by DTMB_DEMOD_FP_SET_REG_PAGE() before using DTMB_DEMOD_FP_SET_REG_BYTES(). ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_GET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char WritingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bytes (page 1, address 0x17 ~ 0x1b) with 5 writing bytes. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBytes(pDemod, 0x17, WritingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BYTES)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_BYTES)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register byte getting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_GET_REG_BYTES() to get demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [out] pReadingBytes Pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bytes successfully with reading byte number. ++@retval FUNCTION_ERROR Get demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by DTMB_DEMOD_FP_SET_REG_PAGE() before using DTMB_DEMOD_FP_GET_REG_BYTES(). ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_SET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char ReadingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bytes (page 1, address 0x17 ~ 0x1b) with reading byte number 5. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBytes(pDemod, 0x17, ReadingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BYTES)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_BYTES)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register mask bits setting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_MASK_BITS() to set demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register mask bits successfully with writing value. ++@retval FUNCTION_ERROR Set demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by DTMB_DEMOD_FP_SET_REG_PAGE() before using DTMB_DEMOD_FP_SET_REG_MASK_BITS(). ++ -# The constraints of DTMB_DEMOD_FP_SET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_GET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits (page 1, address {0x18, 0x17} [12:5]) with writing value 0x1d. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegMaskBits(pDemod, 0x17, 12, 5, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x17 0x18 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_MASK_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_MASK_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register mask bits getting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_GET_REG_MASK_BITS() to get demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register mask bits successfully. ++@retval FUNCTION_ERROR Get demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by DTMB_DEMOD_FP_SET_REG_PAGE() before using DTMB_DEMOD_FP_GET_REG_MASK_BITS(). ++ -# The constraints of DTMB_DEMOD_FP_GET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_SET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits (page 1, address {0x18, 0x17} [12:5]). ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegMaskBits(pDemod, 0x17, 12, 5, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_MASK_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_MASK_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register bits setting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_BITS() to set demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using DTMB_DEMOD_FP_SET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_GET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBits(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register bits getting function pointer ++ ++Demod upper level functions will use DTMB_DEMOD_FP_GET_REG_BITS() to get demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using DTMB_DEMOD_FP_GET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_PAGE, DTMB_DEMOD_FP_SET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBits(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_BITS)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register bits setting function pointer (with page setting) ++ ++Demod upper level functions will use DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE() to set demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name, page setting, and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DTMB_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BITS_WITH_PAGE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod register bits getting function pointer (with page setting) ++ ++Demod upper level functions will use DTMB_DEMOD_FPT_GET_REG_BITS_WITH_PAGE() to get demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name and page setting. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using DTMB_DEMOD_FP_GET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DTMB_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->GetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BITS_WITH_PAGE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// Demod register access for 8-bit address ++typedef struct ++{ ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_PAGE SetRegPage; ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BYTES SetRegBytes; ++ DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BYTES GetRegBytes; ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_MASK_BITS SetRegMaskBits; ++ DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_MASK_BITS GetRegMaskBits; ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BITS SetRegBits; ++ DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BITS GetRegBits; ++ DTMB_DEMOD_FP_ADDR_8BIT_SET_REG_BITS_WITH_PAGE SetRegBitsWithPage; ++ DTMB_DEMOD_FP_ADDR_8BIT_GET_REG_BITS_WITH_PAGE GetRegBitsWithPage; ++} ++DTMB_DEMOD_REG_ACCESS_ADDR_8BIT; ++ ++ ++ ++ ++ ++// Demod register access for 16-bit address ++typedef struct ++{ ++ DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_BYTES SetRegBytes; ++ DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_BYTES GetRegBytes; ++ DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_MASK_BITS SetRegMaskBits; ++ DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_MASK_BITS GetRegMaskBits; ++ DTMB_DEMOD_FP_ADDR_16BIT_SET_REG_BITS SetRegBits; ++ DTMB_DEMOD_FP_ADDR_16BIT_GET_REG_BITS GetRegBits; ++} ++DTMB_DEMOD_REG_ACCESS_ADDR_16BIT; ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod type getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_DEMOD_TYPE() to get DTMB demod type. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDemodType Pointer to an allocated memory for storing demod type ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_DEMOD_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*DTMB_DEMOD_FP_GET_DEMOD_TYPE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod I2C device address getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_DEVICE_ADDR() to get DTMB demod I2C device address. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDeviceAddr Pointer to an allocated memory for storing demod I2C device address ++ ++ ++@retval FUNCTION_SUCCESS Get demod device address successfully. ++@retval FUNCTION_ERROR Get demod device address unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_DEVICE_ADDR() with the corresponding function. ++ ++*/ ++typedef void ++(*DTMB_DEMOD_FP_GET_DEVICE_ADDR)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod crystal frequency getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() to get DTMB demod crystal frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrystalFreqHz Pointer to an allocated memory for storing demod crystal frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod crystal frequency successfully. ++@retval FUNCTION_ERROR Get demod crystal frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef void ++(*DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod I2C bus connection asking function pointer ++ ++One can use DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C() to ask DTMB demod if it is connected to I2C bus. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C() with the corresponding function. ++ ++*/ ++typedef void ++(*DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod software resetting function pointer ++ ++One can use DTMB_DEMOD_FP_SOFTWARE_RESET() to reset DTMB demod by software reset. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod by software reset successfully. ++@retval FUNCTION_ERROR Reset demod by software reset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SOFTWARE_RESET() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_SOFTWARE_RESET)( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod initializing function pointer ++ ++One can use DTMB_DEMOD_FP_INITIALIZE() to initialie DTMB demod. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize demod successfully. ++@retval FUNCTION_ERROR Initialize demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_INITIALIZE)( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod IF frequency setting function pointer ++ ++One can use DTMB_DEMOD_FP_SET_IF_FREQ_HZ() to set DTMB demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] IfFreqHz IF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod IF frequency successfully. ++@retval FUNCTION_ERROR Set demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_SET_IF_FREQ_HZ)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod spectrum mode setting function pointer ++ ++One can use DTMB_DEMOD_FP_SET_SPECTRUM_MODE() to set DTMB demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] SpectrumMode Spectrum mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod spectrum mode successfully. ++@retval FUNCTION_ERROR Set demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_SET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_SET_SPECTRUM_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod IF frequency getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_IF_FREQ_HZ() to get DTMB demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfFreqHz Pointer to an allocated memory for storing demod IF frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF frequency successfully. ++@retval FUNCTION_ERROR Get demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_IF_FREQ_HZ)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod spectrum mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_SPECTRUM_MODE() to get DTMB demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSpectrumMode Pointer to an allocated memory for storing demod spectrum mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod spectrum mode successfully. ++@retval FUNCTION_ERROR Get demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_SPECTRUM_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod signal lock asking function pointer ++ ++One can use DTMB_DEMOD_FP_IS_SIGNAL_LOCKED() to ask DTMB demod if it is signal-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_IS_SIGNAL_LOCKED)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod signal strength getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal strength successfully. ++@retval FUNCTION_ERROR Get demod signal strength unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod signal quality getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal quality successfully. ++@retval FUNCTION_ERROR Get demod signal quality unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_SIGNAL_QUALITY)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod BER getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_BER() to get BER. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod error rate value successfully. ++@retval FUNCTION_ERROR Get demod error rate value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_BER() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_BER)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod PER getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_PER() to get PER. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pPerNum Pointer to an allocated memory for storing PER numerator ++@param [out] pPerDen Pointer to an allocated memory for storing PER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod error rate value successfully. ++@retval FUNCTION_ERROR Get demod error rate value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_PER() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_PER)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod SNR getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod SNR successfully. ++@retval FUNCTION_ERROR Get demod SNR unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_SNR_DB)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod RF AGC getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_RF_AGC() to get DTMB demod RF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pRfAgc Pointer to an allocated memory for storing RF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod RF AGC value successfully. ++@retval FUNCTION_ERROR Get demod RF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_RF_AGC() with the corresponding function. ++ -# The range of RF AGC value is 0 ~ (pow(2, 14) - 1). ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_RF_AGC)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod IF AGC getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_IF_AGC() to get DTMB demod IF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfAgc Pointer to an allocated memory for storing IF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF AGC value successfully. ++@retval FUNCTION_ERROR Get demod IF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_IF_AGC() with the corresponding function. ++ -# The range of IF AGC value is 0 ~ (pow(2, 14) - 1). ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_IF_AGC)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod digital AGC getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_DI_AGC() to get DTMB demod digital AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDiAgc Pointer to an allocated memory for storing digital AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod digital AGC value successfully. ++@retval FUNCTION_ERROR Get demod digital AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_DI_AGC() with the corresponding function. ++ -# The range of digital AGC value is 0 ~ (pow(2, 12) - 1). ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_DI_AGC)( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod TR offset getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get demod TR offset successfully. ++@retval FUNCTION_ERROR Get demod TR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_TR_OFFSET_PPM)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod CR offset getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod CR offset successfully. ++@retval FUNCTION_ERROR Get demod CR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_CR_OFFSET_HZ)( ++ DTMB_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod carrier mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_CARRIER_MODE() to get DTMB demod carrier mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCarrierMode Pointer to an allocated memory for storing demod carrier mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod carrier mode successfully. ++@retval FUNCTION_ERROR Get demod carrier mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_CARRIER_MODE() with the corresponding function. ++ ++ ++@see DTMB_CARRIER_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_CARRIER_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCarrierMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod PN mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_PN_MODE() to get DTMB demod PN mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pPnMode Pointer to an allocated memory for storing demod PN mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod PN mode successfully. ++@retval FUNCTION_ERROR Get demod PN mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_PN_MODE() with the corresponding function. ++ ++ ++@see DTMB_PN_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_PN_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pPnMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod QAM mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_QAM_MODE() to get DTMB demod QAM mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pQamMode Pointer to an allocated memory for storing demod QAM mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod QAM mode successfully. ++@retval FUNCTION_ERROR Get demod QAM mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_QAM_MODE() with the corresponding function. ++ ++ ++@see DTMB_QAM_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_QAM_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod code rate mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_CODE_RATE_MODE() to get DTMB demod code rate mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCodeRateMode Pointer to an allocated memory for storing demod code rate mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod code rate mode successfully. ++@retval FUNCTION_ERROR Get demod code rate mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_CODE_RATE_MODE() with the corresponding function. ++ ++ ++@see DTMB_CODE_RATE_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_CODE_RATE_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pCodeRateMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod time interleaver mode getting function pointer ++ ++One can use DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE() to get DTMB demod time interleaver mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pTimeInterleaverMode Pointer to an allocated memory for storing demod time interleaver mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod time interleaver mode successfully. ++@retval FUNCTION_ERROR Get demod time interleaver mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE() with the corresponding function. ++ ++ ++@see DTMB_TIME_INTERLEAVER_MODE ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE)( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pTimeInterleaverMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod updating function pointer ++ ++One can use DTMB_DEMOD_FP_UPDATE_FUNCTION() to update demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod setting successfully. ++@retval FUNCTION_ERROR Update demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_UPDATE_FUNCTION)( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod reseting function pointer ++ ++One can use DTMB_DEMOD_FP_RESET_FUNCTION() to reset demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod setting successfully. ++@retval FUNCTION_ERROR Reset demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DTMB_DEMOD_FP_RESET_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DtmbDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_DEMOD_FP_RESET_FUNCTION)( ++ DTMB_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/// RTL2836 extra module ++typedef struct RTL2836_EXTRA_MODULE_TAG RTL2836_EXTRA_MODULE; ++struct RTL2836_EXTRA_MODULE_TAG ++{ ++ // RTL2836 update procedure enabling status ++ int IsFunc1Enabled; ++ int IsFunc2Enabled; ++ ++ // RTL2836 update Function 1 variables ++ int Func1CntThd; ++ int Func1Cnt; ++ ++ // RTL2836 update Function 2 variables ++ int Func2SignalModePrevious; ++}; ++ ++ ++ ++ ++ ++/// DTMB demod module structure ++struct DTMB_DEMOD_MODULE_TAG ++{ ++ // Private variables ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ int TsInterfaceMode; ++ int DiversityPipMode; ++ ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int IsIfFreqHzSet; ++ int IsSpectrumModeSet; ++ ++ unsigned long CurrentPageNo; // temp, because page register is write-only. ++ ++ union ///< Demod extra module used by driving module ++ { ++ RTL2836_EXTRA_MODULE Rtl2836; ++ } ++ Extra; ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ // Demod register table ++ union ++ { ++ DTMB_REG_ENTRY_ADDR_8BIT Addr8Bit[DTMB_REG_TABLE_LEN_MAX]; ++ DTMB_REG_ENTRY_ADDR_16BIT Addr16Bit[DTMB_REG_TABLE_LEN_MAX]; ++ } ++ RegTable; ++ ++ ++ // Demod I2C function pointers ++ union ++ { ++ DTMB_DEMOD_REG_ACCESS_ADDR_8BIT Addr8Bit; ++ DTMB_DEMOD_REG_ACCESS_ADDR_16BIT Addr16Bit; ++ } ++ RegAccess; ++ ++ ++ // Demod manipulating function pointers ++ DTMB_DEMOD_FP_GET_DEMOD_TYPE GetDemodType; ++ DTMB_DEMOD_FP_GET_DEVICE_ADDR GetDeviceAddr; ++ DTMB_DEMOD_FP_GET_CRYSTAL_FREQ_HZ GetCrystalFreqHz; ++ ++ DTMB_DEMOD_FP_IS_CONNECTED_TO_I2C IsConnectedToI2c; ++ ++ DTMB_DEMOD_FP_SOFTWARE_RESET SoftwareReset; ++ ++ DTMB_DEMOD_FP_INITIALIZE Initialize; ++ DTMB_DEMOD_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ DTMB_DEMOD_FP_SET_SPECTRUM_MODE SetSpectrumMode; ++ DTMB_DEMOD_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++ DTMB_DEMOD_FP_GET_SPECTRUM_MODE GetSpectrumMode; ++ ++ DTMB_DEMOD_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ ++ DTMB_DEMOD_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ DTMB_DEMOD_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ ++ DTMB_DEMOD_FP_GET_BER GetBer; ++ DTMB_DEMOD_FP_GET_PER GetPer; ++ DTMB_DEMOD_FP_GET_SNR_DB GetSnrDb; ++ ++ DTMB_DEMOD_FP_GET_RF_AGC GetRfAgc; ++ DTMB_DEMOD_FP_GET_IF_AGC GetIfAgc; ++ DTMB_DEMOD_FP_GET_DI_AGC GetDiAgc; ++ ++ DTMB_DEMOD_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ DTMB_DEMOD_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ ++ DTMB_DEMOD_FP_GET_CARRIER_MODE GetCarrierMode; ++ DTMB_DEMOD_FP_GET_PN_MODE GetPnMode; ++ DTMB_DEMOD_FP_GET_QAM_MODE GetQamMode; ++ DTMB_DEMOD_FP_GET_CODE_RATE_MODE GetCodeRateMode; ++ DTMB_DEMOD_FP_GET_TIME_INTERLEAVER_MODE GetTimeInterleaverMode; ++ ++ DTMB_DEMOD_FP_UPDATE_FUNCTION UpdateFunction; ++ DTMB_DEMOD_FP_RESET_FUNCTION ResetFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// DTMB demod default I2C functions for 8-bit address ++int ++dtmb_demod_addr_8bit_default_SetRegPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_SetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_GetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_SetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_GetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_SetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_GetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_SetRegBitsWithPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_8bit_default_GetRegBitsWithPage( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// DTMB demod default I2C functions for 16-bit address ++int ++dtmb_demod_addr_16bit_default_SetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_GetRegBytes( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_SetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_GetRegMaskBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_SetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dtmb_demod_addr_16bit_default_GetRegBits( ++ DTMB_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// DTMB demod default manipulating functions ++void ++dtmb_demod_default_GetDemodType( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++void ++dtmb_demod_default_GetDeviceAddr( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++void ++dtmb_demod_default_GetCrystalFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++int ++dtmb_demod_default_GetBandwidthMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pBandwidthMode ++ ); ++ ++int ++dtmb_demod_default_GetIfFreqHz( ++ DTMB_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++int ++dtmb_demod_default_GetSpectrumMode( ++ DTMB_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/dtmb_nim_base.c b/drivers/drivers/media/dvb/dvb-usb/dtmb_nim_base.c +--- a/drivers/media/dvb/dvb-usb/dtmb_nim_base.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/dtmb_nim_base.c 2016-04-02 19:17:52.092066030 -0300 +@@ -0,0 +1,545 @@ ++/** ++ ++@file ++ ++@brief DTMB NIM base module definition ++ ++DTMB NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++*/ ++ ++ ++#include "dtmb_nim_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_NIM_TYPE ++ ++*/ ++void ++dtmb_nim_default_GetNimType( ++ DTMB_NIM_MODULE *pNim, ++ int *pNimType ++ ) ++{ ++ // Get NIM type from NIM module. ++ *pNimType = pNim->NimType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++dtmb_nim_default_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_PARAMETERS ++ ++*/ ++int ++dtmb_nim_default_GetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ ++ ++ // Get tuner module. ++ pTuner = pNim->pTuner; ++ ++ ++ // Get tuner RF frequency in Hz. ++ if(pTuner->GetRfFreqHz(pTuner, pRfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_IS_SIGNAL_PRESENT ++ ++*/ ++int ++dtmb_nim_default_IsSignalPresent( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ DTMB_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait for signal present check. ++ for(i = 0; i < DTMB_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX_DEFAULT; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check signal lock status on demod. ++ // Note: If signal is locked, stop signal lock check. ++ if(pDemod->IsSignalLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++dtmb_nim_default_IsSignalLocked( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ DTMB_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait for signal lock check. ++ for(i = 0; i < DTMB_NIM_SINGAL_LOCK_CHECK_TIMES_MAX_DEFAULT; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check signal lock status on demod. ++ // Note: If signal is locked, stop signal lock check. ++ if(pDemod->IsSignalLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++dtmb_nim_default_GetSignalStrength( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal strength from demod. ++ if(pDemod->GetSignalStrength(pDemod, pSignalStrength) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++dtmb_nim_default_GetSignalQuality( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal quality from demod. ++ if(pDemod->GetSignalQuality(pDemod, pSignalQuality) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_BER ++ ++*/ ++int ++dtmb_nim_default_GetBer( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get BER from demod. ++ if(pDemod->GetBer(pDemod, pBerNum, pBerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_PER ++ ++*/ ++int ++dtmb_nim_default_GetPer( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get PER from demod. ++ if(pDemod->GetPer(pDemod, pPerNum, pPerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_SNR_DB ++ ++*/ ++int ++dtmb_nim_default_GetSnrDb( ++ DTMB_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get SNR in dB from demod. ++ if(pDemod->GetSnrDb(pDemod, pSnrDbNum, pSnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++dtmb_nim_default_GetTrOffsetPpm( ++ DTMB_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get TR offset in ppm from demod. ++ if(pDemod->GetTrOffsetPpm(pDemod, pTrOffsetPpm) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++dtmb_nim_default_GetCrOffsetHz( ++ DTMB_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get CR offset in Hz from demod. ++ if(pDemod->GetCrOffsetHz(pDemod, pCrOffsetHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_GET_SIGNAL_INFO ++ ++*/ ++int ++dtmb_nim_default_GetSignalInfo( ++ DTMB_NIM_MODULE *pNim, ++ int *pCarrierMode, ++ int *pPnMode, ++ int *pQamMode, ++ int *pCodeRateMode, ++ int *pTimeInterleaverMode ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal information from demod. ++ if(pDemod->GetCarrierMode(pDemod, pCarrierMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->GetPnMode(pDemod, pPnMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->GetQamMode(pDemod, pQamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->GetCodeRateMode(pDemod, pCodeRateMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->GetTimeInterleaverMode(pDemod, pTimeInterleaverMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++dtmb_nim_default_UpdateFunction( ++ DTMB_NIM_MODULE *pNim ++ ) ++{ ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/dtmb_nim_base.h b/drivers/drivers/media/dvb/dvb-usb/dtmb_nim_base.h +--- a/drivers/media/dvb/dvb-usb/dtmb_nim_base.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/dtmb_nim_base.h 2016-04-02 19:17:52.092066030 -0300 +@@ -0,0 +1,967 @@ ++#ifndef __DTMB_NIM_BASE_H ++#define __DTMB_NIM_BASE_H ++ ++/** ++ ++@file ++ ++@brief DTMB NIM base module definition ++ ++DTMB NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ DTMB_NIM_MODULE *pNim; ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ unsigned long RfFreqHz; ++ ++ int Answer; ++ unsigned long SignalStrength, SignalQuality; ++ unsigned long BerNum, BerDen; ++ double Ber; ++ unsigned long PerNum, PerDen; ++ double Per; ++ unsigned long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ long TrOffsetPpm, CrOffsetHz; ++ ++ int CarrierMode; ++ int PnMode; ++ int QamMode; ++ int CodeRateMode; ++ int TimeInterleaverMode; ++ ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ &pNim, ++ &DtmbNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs // Employ CustomWaitMs() as basic waiting function. ++ ++ &DemodxExtraModuleMemory, // Employ Demod-X extra module. ++ 0x3e, // The Demod-X I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The Demod-X crystal frequency is 27.0 MHz. ++ ... // Other arguments for Demod-X ++ ++ &TunerxExtraModuleMemory, // Employ Tuner-Y extra module. ++ 0xc0, // The Tuner-Y I2C device address is 0xc0 in 8-bit format. ++ ... // Other arguments for Tuner-Y ++ ); ++ ++ ++ ++ // Get NIM type. ++ // Note: NIM types are defined in the MODULE_TYPE enumeration. ++ pNim->GetNimType(pNim, &NimType); ++ ++ ++ ++ ++ ++ ++ ++ // ==== Initialize NIM and set its parameters ===== ++ ++ // Initialize NIM. ++ pNim->Initialize(pNim); ++ ++ // Set NIM parameters. (RF frequency) ++ // Note: In the example: RF frequency is 666 MHz. ++ RfFreqHz = 666000000; ++ pNim->SetParameters(pNim, RfFreqHz); ++ ++ ++ ++ // Wait 1 second for demod convergence. ++ ++ ++ ++ ++ ++ // ==== Get NIM information ===== ++ ++ // Get NIM parameters. (RF frequency) ++ pNim->GetParameters(pNim, &RfFreqHz); ++ ++ ++ // Get signal present status. ++ // Note: 1. The argument Answer is YES when the NIM module has found DTMB signal in the RF channel. ++ // 2. The argument Answer is NO when the NIM module does not find DTMB signal in the RF channel. ++ // Recommendation: Use the IsSignalPresent() function for channel scan. ++ pNim->IsSignalPresent(pNim, &Answer); ++ ++ // Get signal lock status. ++ // Note: 1. The argument Answer is YES when the NIM module has locked DTMB signal in the RF channel. ++ // At the same time, the NIM module sends TS packets through TS interface hardware pins. ++ // 2. The argument Answer is NO when the NIM module does not lock DTMB signal in the RF channel. ++ // Recommendation: Use the IsSignalLocked() function for signal lock check. ++ pNim->IsSignalLocked(pNim, &Answer); ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pNim->GetSignalStrength(pNim, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pNim->GetSignalQuality(pNim, &SignalQuality); ++ ++ ++ // Get BER. ++ pNim->GetBer(pNim, &BerNum, &BerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ ++ // Get PER. ++ pNim->GetPer(pNim, &PerNum, &PerDen); ++ Per = (double)PerNum / (double)PerDen; ++ ++ // Get SNR in dB. ++ pNim->GetSnrDb(pNim, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pNim->GetTrOffsetPpm(pNim, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pNim->GetCrOffsetHz(pNim, &CrOffsetHz); ++ ++ ++ // Get signal information. ++ // Note: One can find signal information definitions in the enumerations as follows: ++ // 1. DTMB_CARRIER_MODE ++ // 2. DTMB_PN_MODE ++ // 3. DTMB_QAM_MODE ++ // 4. DTMB_CODE_RATE_MODE ++ // 5. DTMB_TIME_INTERLEAVER_MODE ++ pNim->GetSignalInfo(pNim, &CarrierMode, &PnMode, &QamMode, &CodeRateMode, &TimeInterleaverMode); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++#include "tuner_base.h" ++#include "dtmb_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define DTMB_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX_DEFAULT 1 ++#define DTMB_NIM_SINGAL_LOCK_CHECK_TIMES_MAX_DEFAULT 1 ++ ++ ++ ++ ++ ++/// DTMB NIM module pre-definition ++typedef struct DTMB_NIM_MODULE_TAG DTMB_NIM_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB demod type getting function pointer ++ ++One can use DTMB_NIM_FP_GET_NIM_TYPE() to get DTMB NIM type. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pNimType Pointer to an allocated memory for storing NIM type ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_NIM_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*DTMB_NIM_FP_GET_NIM_TYPE)( ++ DTMB_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM initializing function pointer ++ ++One can use DTMB_NIM_FP_INITIALIZE() to initialie DTMB NIM. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize NIM successfully. ++@retval FUNCTION_ERROR Initialize NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_INITIALIZE)( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM parameter setting function pointer ++ ++One can use DTMB_NIM_FP_SET_PARAMETERS() to set DTMB NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [in] RfFreqHz RF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set NIM parameters successfully. ++@retval FUNCTION_ERROR Set NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_SET_PARAMETERS() with the corresponding function. ++ ++ ++@see DTMB_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_SET_PARAMETERS)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM parameter getting function pointer ++ ++One can use DTMB_NIM_FP_GET_PARAMETERS() to get DTMB NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pRfFreqHz Pointer to an allocated memory for storing NIM RF frequency in Hz ++@param [out] pBandwidthMode Pointer to an allocated memory for storing NIM bandwidth mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM parameters successfully. ++@retval FUNCTION_ERROR Get NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_PARAMETERS() with the corresponding function. ++ ++ ++@see DTMB_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_PARAMETERS)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal present asking function pointer ++ ++One can use DTMB_NIM_FP_IS_SIGNAL_PRESENT() to ask DTMB NIM if signal is present. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal present asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal present asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_IS_SIGNAL_PRESENT() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_IS_SIGNAL_PRESENT)( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal lock asking function pointer ++ ++One can use DTMB_NIM_FP_IS_SIGNAL_LOCKED() to ask DTMB NIM if signal is locked. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_IS_SIGNAL_LOCKED)( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal strength getting function pointer ++ ++One can use DTMB_NIM_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal strength successfully. ++@retval FUNCTION_ERROR Get NIM signal strength unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_SIGNAL_STRENGTH)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal quality getting function pointer ++ ++One can use DTMB_NIM_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal quality successfully. ++@retval FUNCTION_ERROR Get NIM signal quality unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_SIGNAL_QUALITY)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM BER value getting function pointer ++ ++One can use DTMB_NIM_FP_GET_BER() to get BER. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM BER value successfully. ++@retval FUNCTION_ERROR Get NIM BER value unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_BER() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_BER)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM PER value getting function pointer ++ ++One can use DTMB_NIM_FP_GET_PER() to get PER. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pPerNum Pointer to an allocated memory for storing PER numerator ++@param [out] pPerDen Pointer to an allocated memory for storing PER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM PER value successfully. ++@retval FUNCTION_ERROR Get NIM PER value unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_PER() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_PER)( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM SNR getting function pointer ++ ++One can use DTMB_NIM_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM SNR successfully. ++@retval FUNCTION_ERROR Get NIM SNR unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_SNR_DB)( ++ DTMB_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM TR offset getting function pointer ++ ++One can use DTMB_NIM_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get NIM TR offset successfully. ++@retval FUNCTION_ERROR Get NIM TR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_TR_OFFSET_PPM)( ++ DTMB_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM CR offset getting function pointer ++ ++One can use DTMB_NIM_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get NIM CR offset successfully. ++@retval FUNCTION_ERROR Get NIM CR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_CR_OFFSET_HZ)( ++ DTMB_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM signal information getting function pointer ++ ++One can use DTMB_NIM_FP_GET_SIGNAL_INFO() to get signal information. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pCarrierMode Pointer to an allocated memory for storing demod carrier mode ++@param [out] pPnMode Pointer to an allocated memory for storing demod PN mode ++@param [out] pQamMode Pointer to an allocated memory for storing demod QAM mode ++@param [out] pCodeRateMode Pointer to an allocated memory for storing demod code rate mode ++@param [out] pTimeInterleaverMode Pointer to an allocated memory for storing demod time interleaver mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal information successfully. ++@retval FUNCTION_ERROR Get NIM signal information unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_GET_SIGNAL_INFO() with the corresponding function. ++ ++ ++@see DTMB_CARRIER_MODE, DTMB_PN_MODE, DTMB_QAM_MODE, DTMB_CODE_RATE_MODE, DTMB_TIME_INTERLEAVER_MODE ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_GET_SIGNAL_INFO)( ++ DTMB_NIM_MODULE *pNim, ++ int *pCarrierMode, ++ int *pPnMode, ++ int *pQamMode, ++ int *pCodeRateMode, ++ int *pTimeInterleaverMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DTMB NIM updating function pointer ++ ++One can use DTMB_NIM_FP_UPDATE_FUNCTION() to update NIM register setting. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update NIM setting successfully. ++@retval FUNCTION_ERROR Update NIM setting unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DTMB_NIM_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++int main(void) ++{ ++ DTMB_NIM_MODULE *pNim; ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ ... ++ ); ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pNim->UpdateFunction(pNim); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DTMB_NIM_FP_UPDATE_FUNCTION)( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++// RTL2836 E4000 extra module ++typedef struct RTL2836_E4000_EXTRA_MODULE_TAG RTL2836_E4000_EXTRA_MODULE; ++struct RTL2836_E4000_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long TunerModeUpdateWaitTimeMax; ++ unsigned long TunerModeUpdateWaitTime; ++ unsigned char TunerGainMode; ++}; ++ ++ ++ ++ ++ ++// RTL2836B DTMB E4000 extra module ++typedef struct RTL2836B_DTMB_E4000_EXTRA_MODULE_TAG RTL2836B_DTMB_E4000_EXTRA_MODULE; ++struct RTL2836B_DTMB_E4000_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long TunerModeUpdateWaitTimeMax; ++ unsigned long TunerModeUpdateWaitTime; ++ unsigned char TunerGainMode; ++}; ++ ++ ++ ++ ++ ++// RTL2836B DTMB E4005 extra module ++typedef struct RTL2836B_DTMB_E4005_EXTRA_MODULE_TAG RTL2836B_DTMB_E4005_EXTRA_MODULE; ++struct RTL2836B_DTMB_E4005_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long TunerModeUpdateWaitTimeMax; ++ unsigned long TunerModeUpdateWaitTime; ++ unsigned char TunerGainMode; ++}; ++ ++ ++ ++ ++ ++// RTL2836B DTMB FC0012 extra module ++typedef struct RTL2836B_DTMB_FC0012_EXTRA_MODULE_TAG RTL2836B_DTMB_FC0012_EXTRA_MODULE; ++struct RTL2836B_DTMB_FC0012_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long LnaUpdateWaitTimeMax; ++ unsigned long LnaUpdateWaitTime; ++ unsigned long RssiRCalOn; ++}; ++ ++ ++ ++ ++ ++// RTL2836B DTMB FC0013B extra module ++typedef struct RTL2836B_DTMB_FC0013B_EXTRA_MODULE_TAG RTL2836B_DTMB_FC0013B_EXTRA_MODULE; ++struct RTL2836B_DTMB_FC0013B_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long LnaUpdateWaitTimeMax; ++ unsigned long LnaUpdateWaitTime; ++ unsigned long RssiRCalOn; ++ unsigned char LowGainTestMode; ++}; ++ ++ ++ ++ ++ ++/// DTMB NIM module structure ++struct DTMB_NIM_MODULE_TAG ++{ ++ // Private variables ++ int NimType; ++ ++ union ///< NIM extra module used by driving module ++ { ++ RTL2836_E4000_EXTRA_MODULE Rtl2836E4000; ++ RTL2836B_DTMB_E4000_EXTRA_MODULE Rtl2836bDtmbE4000; ++ RTL2836B_DTMB_E4005_EXTRA_MODULE Rtl2836bDtmbE4005; ++ RTL2836B_DTMB_FC0012_EXTRA_MODULE Rtl2836bDtmbFc0012; ++ RTL2836B_DTMB_FC0013B_EXTRA_MODULE Rtl2836bDtmbFc0013b; ++ } ++ Extra; ++ ++ ++ // Modules ++ BASE_INTERFACE_MODULE *pBaseInterface; ///< Base interface module pointer ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ///< Base interface module memory ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ///< I2C bridge module pointer ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ///< I2C bridge module memory ++ ++ TUNER_MODULE *pTuner; ///< Tuner module pointer ++ TUNER_MODULE TunerModuleMemory; ///< Tuner module memory ++ ++ DTMB_DEMOD_MODULE *pDemod; ///< DTMB demod module pointer ++ DTMB_DEMOD_MODULE DtmbDemodModuleMemory; ///< DTMB demod module memory ++ ++ ++ // NIM manipulating functions ++ DTMB_NIM_FP_GET_NIM_TYPE GetNimType; ++ DTMB_NIM_FP_INITIALIZE Initialize; ++ DTMB_NIM_FP_SET_PARAMETERS SetParameters; ++ DTMB_NIM_FP_GET_PARAMETERS GetParameters; ++ DTMB_NIM_FP_IS_SIGNAL_PRESENT IsSignalPresent; ++ DTMB_NIM_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ DTMB_NIM_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ DTMB_NIM_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ DTMB_NIM_FP_GET_BER GetBer; ++ DTMB_NIM_FP_GET_PER GetPer; ++ DTMB_NIM_FP_GET_SNR_DB GetSnrDb; ++ DTMB_NIM_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ DTMB_NIM_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ DTMB_NIM_FP_GET_SIGNAL_INFO GetSignalInfo; ++ DTMB_NIM_FP_UPDATE_FUNCTION UpdateFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// DTMB NIM default manipulaing functions ++void ++dtmb_nim_default_GetNimType( ++ DTMB_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++int ++dtmb_nim_default_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ); ++ ++int ++dtmb_nim_default_GetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz ++ ); ++ ++int ++dtmb_nim_default_IsSignalPresent( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++dtmb_nim_default_IsSignalLocked( ++ DTMB_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++dtmb_nim_default_GetSignalStrength( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++dtmb_nim_default_GetSignalQuality( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++dtmb_nim_default_GetBer( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++int ++dtmb_nim_default_GetPer( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++int ++dtmb_nim_default_GetSnrDb( ++ DTMB_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++dtmb_nim_default_GetTrOffsetPpm( ++ DTMB_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++int ++dtmb_nim_default_GetCrOffsetHz( ++ DTMB_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++int ++dtmb_nim_default_GetSignalInfo( ++ DTMB_NIM_MODULE *pNim, ++ int *pCarrierMode, ++ int *pPnMode, ++ int *pQamMode, ++ int *pCodeRateMode, ++ int *pTimeInterleaverMode ++ ); ++ ++int ++dtmb_nim_default_UpdateFunction( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/dvbt_demod_base.c b/drivers/drivers/media/dvb/dvb-usb/dvbt_demod_base.c +--- a/drivers/media/dvb/dvb-usb/dvbt_demod_base.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/dvbt_demod_base.c 2016-04-02 19:17:52.092066030 -0300 +@@ -0,0 +1,816 @@ ++/** ++ ++@file ++ ++@brief DVB-T demod default function definition ++ ++DVB-T demod default functions. ++ ++*/ ++ ++#include "dvbt_demod_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE ++ ++*/ ++int ++dvbt_demod_default_SetRegPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBytes[LEN_2_BYTE]; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Set demod register page with page number. ++ // Note: The I2C format of demod register page setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + DVBT_DEMOD_PAGE_REG_ADDR + PageNo + stop_bit ++ WritingBytes[0] = DVBT_DEMOD_PAGE_REG_ADDR; ++ WritingBytes[1] = (unsigned char)PageNo; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBytes, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ if( mutex_lock_interruptible(&d->usb_mutex) ) goto error; ++ ++ pDemod->CurrentPageNo = PageNo; ++ ++ mutex_unlock(&d->usb_mutex); ++ ++ return FUNCTION_SUCCESS; ++ ++error: ++ return FUNCTION_ERROR; ++ ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++dvbt_demod_default_SetRegBytes( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned char WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[j] = pWritingBytes[i + j]; ++ ++ // Set demod register bytes with writing buffer. ++ if(write_demod_register( d, DeviceAddr, pDemod->CurrentPageNo, RegWritingAddr, WritingBuffer, WritingByteNum )) goto error; ++ ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++error: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++dvbt_demod_default_GetRegBytes( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i; ++ unsigned char DeviceAddr; ++ unsigned char ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Get demod register bytes. ++ if(read_demod_register(d, DeviceAddr, pDemod->CurrentPageNo, RegReadingAddr, &pReadingBytes[i], ReadingByteNum)) goto error; ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++error: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++dvbt_demod_default_SetRegMaskBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value MSB. ++ // Put upper address byte on value LSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * (ByteNum - i -1)); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value MSB. ++ // Pick up upper address byte from value LSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * (ByteNum - i -1))) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++dvbt_demod_default_GetRegMaskBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value MSB. ++ // Put upper address byte on value LSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * (ByteNum - i -1)); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++dvbt_demod_default_SetRegBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable[RegBitName].Msb; ++ Lsb = pDemod->RegTable[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++dvbt_demod_default_GetRegBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->RegTable[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from register table with register bit name key. ++ RegStartAddr = pDemod->RegTable[RegBitName].RegStartAddr; ++ Msb = pDemod->RegTable[RegBitName].Msb; ++ Lsb = pDemod->RegTable[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++dvbt_demod_default_SetRegBitsWithPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned long PageNo; ++ ++ ++ // Get register page number from register table with register bit name key. ++ PageNo = pDemod->RegTable[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set register mask bits with register bit name key. ++ if(pDemod->SetRegBits(pDemod, RegBitName, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++dvbt_demod_default_GetRegBitsWithPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned long PageNo; ++ ++ ++ // Get register page number from register table with register bit name key. ++ PageNo = pDemod->RegTable[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get register mask bits with register bit name key. ++ if(pDemod->GetRegBits(pDemod, RegBitName, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_DEMOD_TYPE ++ ++*/ ++void ++dvbt_demod_default_GetDemodType( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ) ++{ ++ // Get demod type from demod module. ++ *pDemodType = pDemod->DemodType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++dvbt_demod_default_GetDeviceAddr( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get demod I2C device address from demod module. ++ *pDeviceAddr = pDemod->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ ++ ++*/ ++void ++dvbt_demod_default_GetCrystalFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ) ++{ ++ // Get demod crystal frequency in Hz from demod module. ++ *pCrystalFreqHz = pDemod->CrystalFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_BANDWIDTH_MODE ++ ++*/ ++int ++dvbt_demod_default_GetBandwidthMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pBandwidthMode ++ ) ++{ ++ // Get demod bandwidth mode from demod module. ++ if(pDemod->IsBandwidthModeSet != YES) ++ goto error_status_get_demod_bandwidth_mode; ++ ++ *pBandwidthMode = pDemod->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_IF_FREQ_HZ ++ ++*/ ++int ++dvbt_demod_default_GetIfFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ) ++{ ++ // Get demod IF frequency in Hz from demod module. ++ if(pDemod->IsIfFreqHzSet != YES) ++ goto error_status_get_demod_if_frequency; ++ ++ *pIfFreqHz = pDemod->IfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_if_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_DEMOD_FP_GET_SPECTRUM_MODE ++ ++*/ ++int ++dvbt_demod_default_GetSpectrumMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ) ++{ ++ // Get demod spectrum mode from demod module. ++ if(pDemod->IsSpectrumModeSet != YES) ++ goto error_status_get_demod_spectrum_mode; ++ ++ *pSpectrumMode = pDemod->SpectrumMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_spectrum_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/dvbt_demod_base.h b/drivers/drivers/media/dvb/dvb-usb/dvbt_demod_base.h +--- a/drivers/media/dvb/dvb-usb/dvbt_demod_base.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/dvbt_demod_base.h 2016-04-02 19:17:52.092066030 -0300 +@@ -0,0 +1,2722 @@ ++#ifndef __DVBT_DEMOD_BASE_H ++#define __DVBT_DEMOD_BASE_H ++ ++/** ++ ++@file ++ ++@brief DVB-T demod base module definition ++ ++DVB-T demod base module definitions contains demod module structure, demod funciton pointers, and demod definitions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_xxx.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ int BandwidthMode; ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ ++ long RfAgc, IfAgc; ++ unsigned char DiAgc; ++ ++ int Answer; ++ long TrOffsetPpm, CrOffsetHz; ++ unsigned long BerNum, BerDen; ++ double Ber; ++ long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ unsigned long SignalStrength, SignalQuality; ++ ++ int Constellation; ++ int Hierarchy; ++ int CodeRateLp; ++ int CodeRateHp; ++ int GuardInterval; ++ int FftMode; ++ ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pBaseInterface, ++ &BaseInterfaceModuleMemory, ++ 9, // Set maximum I2C reading byte number with 9. ++ 8, // Set maximum I2C writing byte number with 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs // Employ CustomWaitMs() as basic waiting function. ++ ); ++ ++ ++ // Build DVB-T demod XXX module. ++ BuildXxxModule( ++ &pDemod, ++ &DvbtDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x20, // Demod I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // Demod crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // Demod TS interface mode is serial. ++ ... // Other arguments by each demod module ++ ); ++ ++ ++ ++ ++ ++ // ==== Initialize DVB-T demod and set its parameters ===== ++ ++ // Initialize demod. ++ pDemod->Initialize(pDemod); ++ ++ ++ // Set demod parameters. (bandwidth mode, IF frequency, spectrum mode) ++ // Note: In the example: ++ // 1. Bandwidth mode is 8 MHz. ++ // 2. IF frequency is 36.125 MHz. ++ // 3. Spectrum mode is SPECTRUM_INVERSE. ++ BandwidthMode = DVBT_BANDWIDTH_8MHZ; ++ IfFreqHz = IF_FREQ_36125000HZ; ++ SpectrumMode = SPECTRUM_INVERSE; ++ ++ pDemod->SetBandwidthMode(pDemod, BandwidthMode); ++ pDemod->SetIfFreqHz(pDemod, IfFreqHz); ++ pDemod->SetSpectrumMode(pDemod, SpectrumMode); ++ ++ ++ // Need to set tuner before demod software reset. ++ // The order to set demod and tuner is not important. ++ // Note: One can use "pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1);" ++ // for tuner I2C command forwarding. ++ ++ ++ // Reset demod by software reset. ++ pDemod->SoftwareReset(pDemod); ++ ++ ++ // Wait maximum 1000 ms for demod converge. ++ for(i = 0; i < 25; i++) ++ { ++ // Wait 40 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 40); ++ ++ // Check signal lock status. ++ // Note: If Answer is YES, signal is locked. ++ // If Answer is NO, signal is not locked. ++ pDemod->IsSignalLocked(pDemod, &Answer); ++ ++ if(Answer == YES) ++ { ++ // Signal is locked. ++ break; ++ } ++ } ++ ++ ++ ++ ++ ++ // ==== Get DVB-T demod information ===== ++ ++ // Get demod type. ++ // Note: One can find demod type in MODULE_TYPE enumeration. ++ pDemod->GetDemodType(pDemod, &DemodType); ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Ask demod if it is connected to I2C bus. ++ // Note: If Answer is YES, demod is connected to I2C bus. ++ // If Answer is NO, demod is not connected to I2C bus. ++ pDemod->IsConnectedToI2c(pDemod, &Answer); ++ ++ ++ // Get demod parameters. (bandwidth mode, IF frequency, spectrum mode) ++ pDemod->GetBandwidthMode(pDemod, &BandwidthMode); ++ pDemod->GetIfFreqHz(pDemod, &IfFreqHz); ++ pDemod->GetSpectrumMode(pDemod, &SpectrumMode); ++ ++ ++ // Get demod AGC value. ++ // Note: The range of RF AGC and IF AGC value is -8192 ~ 8191. ++ // The range of digital AGC value is 0 ~ 255. ++ pDemod->GetRfAgc(pDemod, &RfAgc); ++ pDemod->GetIfAgc(pDemod, &IfAgc); ++ pDemod->GetDiAgc(pDemod, &DiAgc); ++ ++ ++ // Get demod lock status. ++ // Note: If Answer is YES, it is locked. ++ // If Answer is NO, it is not locked. ++ pDemod->IsTpsLocked(pDemod, &Answer); ++ pDemod->IsSignalLocked(pDemod, &Answer); ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz); ++ ++ ++ // Get BER. ++ pDemod->GetBer(pDemod, &BerNum, &BerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ ++ // Get SNR in dB. ++ pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pDemod->GetSignalStrength(pDemod, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pDemod->GetSignalQuality(pDemod, &SignalQuality); ++ ++ ++ // Get TPS information. ++ // Note: One can find TPS information definitions in the enumerations as follows: ++ // 1. DVBT_CONSTELLATION_MODE ++ // 2. DVBT_HIERARCHY_MODE ++ // 3. DVBT_CODE_RATE_MODE (for low-priority and high-priority code rate) ++ // 4. DVBT_GUARD_INTERVAL_MODE ++ // 5. DVBT_FFT_MODE_MODE ++ pDemod->GetConstellation(pDemod, &Constellation); ++ pDemod->GetHierarchy(pDemod, &Hierarchy); ++ pDemod->GetCodeRateLp(pDemod, &CodeRateLp); ++ pDemod->GetCodeRateHp(pDemod, &CodeRateHp); ++ pDemod->GetGuardInterval(pDemod, &GuardInterval); ++ pDemod->GetFftMode(pDemod, &FftMode); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// Page register address ++#define DVBT_DEMOD_PAGE_REG_ADDR 0x00 ++ ++ ++// Bandwidth modes ++#define DVBT_BANDWIDTH_NONE -1 ++enum DVBT_BANDWIDTH_MODE ++{ ++ DVBT_BANDWIDTH_6MHZ, ++ DVBT_BANDWIDTH_7MHZ, ++ DVBT_BANDWIDTH_8MHZ, ++}; ++#define DVBT_BANDWIDTH_MODE_NUM 3 ++ ++ ++// Constellation ++enum DVBT_CONSTELLATION_MODE ++{ ++ DVBT_CONSTELLATION_QPSK, ++ DVBT_CONSTELLATION_16QAM, ++ DVBT_CONSTELLATION_64QAM, ++}; ++#define DVBT_CONSTELLATION_NUM 3 ++ ++ ++// Hierarchy ++enum DVBT_HIERARCHY_MODE ++{ ++ DVBT_HIERARCHY_NONE, ++ DVBT_HIERARCHY_ALPHA_1, ++ DVBT_HIERARCHY_ALPHA_2, ++ DVBT_HIERARCHY_ALPHA_4, ++}; ++#define DVBT_HIERARCHY_NUM 4 ++ ++ ++// Code rate ++enum DVBT_CODE_RATE_MODE ++{ ++ DVBT_CODE_RATE_1_OVER_2, ++ DVBT_CODE_RATE_2_OVER_3, ++ DVBT_CODE_RATE_3_OVER_4, ++ DVBT_CODE_RATE_5_OVER_6, ++ DVBT_CODE_RATE_7_OVER_8, ++}; ++#define DVBT_CODE_RATE_NUM 5 ++ ++ ++// Guard interval ++enum DVBT_GUARD_INTERVAL_MODE ++{ ++ DVBT_GUARD_INTERVAL_1_OVER_32, ++ DVBT_GUARD_INTERVAL_1_OVER_16, ++ DVBT_GUARD_INTERVAL_1_OVER_8, ++ DVBT_GUARD_INTERVAL_1_OVER_4, ++}; ++#define DVBT_GUARD_INTERVAL_NUM 4 ++ ++ ++// FFT mode ++enum DVBT_FFT_MODE_MODE ++{ ++ DVBT_FFT_MODE_2K, ++ DVBT_FFT_MODE_8K, ++}; ++#define DVBT_FFT_MODE_NUM 2 ++ ++ ++ ++ ++ ++// Register entry definitions ++ ++// Register entry ++typedef struct ++{ ++ int IsAvailable; ++ unsigned long PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DVBT_REG_ENTRY; ++ ++ ++ ++// Primary register entry ++typedef struct ++{ ++ int RegBitName; ++ unsigned long PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++DVBT_PRIMARY_REG_ENTRY; ++ ++ ++ ++ ++ ++// Register table dependence ++ ++// Demod register bit names ++enum DVBT_REG_BIT_NAME ++{ ++ // Software reset register ++ DVBT_SOFT_RST, ++ ++ // Tuner I2C forwording register ++ DVBT_IIC_REPEAT, ++ ++ ++ // Registers for initializing ++ DVBT_TR_WAIT_MIN_8K, ++ DVBT_RSD_BER_FAIL_VAL, ++ DVBT_EN_BK_TRK, ++ DVBT_REG_PI, ++ ++ DVBT_REG_PFREQ_1_0, // For RTL2830 only ++ DVBT_PD_DA8, // For RTL2830 only ++ DVBT_LOCK_TH, // For RTL2830 only ++ DVBT_BER_PASS_SCAL, // For RTL2830 only ++ DVBT_CE_FFSM_BYPASS, // For RTL2830 only ++ DVBT_ALPHAIIR_N, // For RTL2830 only ++ DVBT_ALPHAIIR_DIF, // For RTL2830 only ++ DVBT_EN_TRK_SPAN, // For RTL2830 only ++ DVBT_LOCK_TH_LEN, // For RTL2830 only ++ DVBT_CCI_THRE, // For RTL2830 only ++ DVBT_CCI_MON_SCAL, // For RTL2830 only ++ DVBT_CCI_M0, // For RTL2830 only ++ DVBT_CCI_M1, // For RTL2830 only ++ DVBT_CCI_M2, // For RTL2830 only ++ DVBT_CCI_M3, // For RTL2830 only ++ DVBT_SPEC_INIT_0, // For RTL2830 only ++ DVBT_SPEC_INIT_1, // For RTL2830 only ++ DVBT_SPEC_INIT_2, // For RTL2830 only ++ ++ DVBT_AD_EN_REG, // For RTL2832 only ++ DVBT_AD_EN_REG1, // For RTL2832 only ++ DVBT_EN_BBIN, // For RTL2832 only ++ DVBT_MGD_THD0, // For RTL2832 only ++ DVBT_MGD_THD1, // For RTL2832 only ++ DVBT_MGD_THD2, // For RTL2832 only ++ DVBT_MGD_THD3, // For RTL2832 only ++ DVBT_MGD_THD4, // For RTL2832 only ++ DVBT_MGD_THD5, // For RTL2832 only ++ DVBT_MGD_THD6, // For RTL2832 only ++ DVBT_MGD_THD7, // For RTL2832 only ++ DVBT_EN_CACQ_NOTCH, // For RTL2832 only ++ DVBT_AD_AV_REF, // For RTL2832 only ++ DVBT_PIP_ON, // For RTL2832 only ++ DVBT_SCALE1_B92, // For RTL2832 only ++ DVBT_SCALE1_B93, // For RTL2832 only ++ DVBT_SCALE1_BA7, // For RTL2832 only ++ DVBT_SCALE1_BA9, // For RTL2832 only ++ DVBT_SCALE1_BAA, // For RTL2832 only ++ DVBT_SCALE1_BAB, // For RTL2832 only ++ DVBT_SCALE1_BAC, // For RTL2832 only ++ DVBT_SCALE1_BB0, // For RTL2832 only ++ DVBT_SCALE1_BB1, // For RTL2832 only ++ DVBT_KB_P1, // For RTL2832 only ++ DVBT_KB_P2, // For RTL2832 only ++ DVBT_KB_P3, // For RTL2832 only ++ DVBT_OPT_ADC_IQ, // For RTL2832 only ++ DVBT_AD_AVI, // For RTL2832 only ++ DVBT_AD_AVQ, // For RTL2832 only ++ DVBT_K1_CR_STEP12, // For RTL2832 only ++ ++ // Registers for initializing according to mode ++ DVBT_TRK_KS_P2, ++ DVBT_TRK_KS_I2, ++ DVBT_TR_THD_SET2, ++ DVBT_TRK_KC_P2, ++ DVBT_TRK_KC_I2, ++ DVBT_CR_THD_SET2, ++ ++ // Registers for IF setting ++ DVBT_PSET_IFFREQ, ++ DVBT_SPEC_INV, ++ ++ ++ // Registers for bandwidth programming ++ DVBT_BW_INDEX, // For RTL2830 only ++ ++ DVBT_RSAMP_RATIO, // For RTL2832 only ++ DVBT_CFREQ_OFF_RATIO, // For RTL2832 only ++ ++ ++ // FSM stage register ++ DVBT_FSM_STAGE, ++ ++ // TPS content registers ++ DVBT_RX_CONSTEL, ++ DVBT_RX_HIER, ++ DVBT_RX_C_RATE_LP, ++ DVBT_RX_C_RATE_HP, ++ DVBT_GI_IDX, ++ DVBT_FFT_MODE_IDX, ++ ++ // Performance measurement registers ++ DVBT_RSD_BER_EST, ++ DVBT_CE_EST_EVM, ++ ++ // AGC registers ++ DVBT_RF_AGC_VAL, ++ DVBT_IF_AGC_VAL, ++ DVBT_DAGC_VAL, ++ ++ // TR offset and CR offset registers ++ DVBT_SFREQ_OFF, ++ DVBT_CFREQ_OFF, ++ ++ ++ // AGC relative registers ++ DVBT_POLAR_RF_AGC, ++ DVBT_POLAR_IF_AGC, ++ DVBT_AAGC_HOLD, ++ DVBT_EN_RF_AGC, ++ DVBT_EN_IF_AGC, ++ DVBT_IF_AGC_MIN, ++ DVBT_IF_AGC_MAX, ++ DVBT_RF_AGC_MIN, ++ DVBT_RF_AGC_MAX, ++ DVBT_IF_AGC_MAN, ++ DVBT_IF_AGC_MAN_VAL, ++ DVBT_RF_AGC_MAN, ++ DVBT_RF_AGC_MAN_VAL, ++ DVBT_DAGC_TRG_VAL, ++ ++ DVBT_AGC_TARG_VAL, // For RTL2830 only ++ DVBT_LOOP_GAIN_3_0, // For RTL2830 only ++ DVBT_LOOP_GAIN_4, // For RTL2830 only ++ DVBT_VTOP, // For RTL2830 only ++ DVBT_KRF, // For RTL2830 only ++ ++ DVBT_AGC_TARG_VAL_0, // For RTL2832 only ++ DVBT_AGC_TARG_VAL_8_1, // For RTL2832 only ++ DVBT_AAGC_LOOP_GAIN, // For RTL2832 only ++ DVBT_LOOP_GAIN2_3_0, // For RTL2832 only ++ DVBT_LOOP_GAIN2_4, // For RTL2832 only ++ DVBT_LOOP_GAIN3, // For RTL2832 only ++ DVBT_VTOP1, // For RTL2832 only ++ DVBT_VTOP2, // For RTL2832 only ++ DVBT_VTOP3, // For RTL2832 only ++ DVBT_KRF1, // For RTL2832 only ++ DVBT_KRF2, // For RTL2832 only ++ DVBT_KRF3, // For RTL2832 only ++ DVBT_KRF4, // For RTL2832 only ++ DVBT_EN_GI_PGA, // For RTL2832 only ++ DVBT_THD_LOCK_UP, // For RTL2832 only ++ DVBT_THD_LOCK_DW, // For RTL2832 only ++ DVBT_THD_UP1, // For RTL2832 only ++ DVBT_THD_DW1, // For RTL2832 only ++ DVBT_INTER_CNT_LEN, // For RTL2832 only ++ DVBT_GI_PGA_STATE, // For RTL2832 only ++ DVBT_EN_AGC_PGA, // For RTL2832 only ++ ++ ++ // TS interface registers ++ DVBT_CKOUTPAR, ++ DVBT_CKOUT_PWR, ++ DVBT_SYNC_DUR, ++ DVBT_ERR_DUR, ++ DVBT_SYNC_LVL, ++ DVBT_ERR_LVL, ++ DVBT_VAL_LVL, ++ DVBT_SERIAL, ++ DVBT_SER_LSB, ++ DVBT_CDIV_PH0, ++ DVBT_CDIV_PH1, ++ ++ DVBT_MPEG_IO_OPT_2_2, // For RTL2832 only ++ DVBT_MPEG_IO_OPT_1_0, // For RTL2832 only ++ DVBT_CKOUTPAR_PIP, // For RTL2832 only ++ DVBT_CKOUT_PWR_PIP, // For RTL2832 only ++ DVBT_SYNC_LVL_PIP, // For RTL2832 only ++ DVBT_ERR_LVL_PIP, // For RTL2832 only ++ DVBT_VAL_LVL_PIP, // For RTL2832 only ++ DVBT_CKOUTPAR_PID, // For RTL2832 only ++ DVBT_CKOUT_PWR_PID, // For RTL2832 only ++ DVBT_SYNC_LVL_PID, // For RTL2832 only ++ DVBT_ERR_LVL_PID, // For RTL2832 only ++ DVBT_VAL_LVL_PID, // For RTL2832 only ++ ++ ++ // FSM state-holding register ++ DVBT_SM_PASS, ++ ++ // Registers for function 2 (for RTL2830 only) ++ DVBT_UPDATE_REG_2, ++ ++ // Registers for function 3 (for RTL2830 only) ++ DVBT_BTHD_P3, ++ DVBT_BTHD_D3, ++ ++ // Registers for function 4 (for RTL2830 only) ++ DVBT_FUNC4_REG0, ++ DVBT_FUNC4_REG1, ++ DVBT_FUNC4_REG2, ++ DVBT_FUNC4_REG3, ++ DVBT_FUNC4_REG4, ++ DVBT_FUNC4_REG5, ++ DVBT_FUNC4_REG6, ++ DVBT_FUNC4_REG7, ++ DVBT_FUNC4_REG8, ++ DVBT_FUNC4_REG9, ++ DVBT_FUNC4_REG10, ++ ++ // Registers for functin 5 (for RTL2830 only) ++ DVBT_FUNC5_REG0, ++ DVBT_FUNC5_REG1, ++ DVBT_FUNC5_REG2, ++ DVBT_FUNC5_REG3, ++ DVBT_FUNC5_REG4, ++ DVBT_FUNC5_REG5, ++ DVBT_FUNC5_REG6, ++ DVBT_FUNC5_REG7, ++ DVBT_FUNC5_REG8, ++ DVBT_FUNC5_REG9, ++ DVBT_FUNC5_REG10, ++ DVBT_FUNC5_REG11, ++ DVBT_FUNC5_REG12, ++ DVBT_FUNC5_REG13, ++ DVBT_FUNC5_REG14, ++ DVBT_FUNC5_REG15, ++ DVBT_FUNC5_REG16, ++ DVBT_FUNC5_REG17, ++ DVBT_FUNC5_REG18, ++ ++ ++ // AD7 registers (for RTL2832 only) ++ DVBT_AD7_SETTING, ++ DVBT_RSSI_R, ++ ++ // ACI detection registers (for RTL2832 only) ++ DVBT_ACI_DET_IND, ++ ++ // Clock output registers (for RTL2832 only) ++ DVBT_REG_MON, ++ DVBT_REG_MONSEL, ++ DVBT_REG_GPE, ++ DVBT_REG_GPO, ++ DVBT_REG_4MSEL, ++ ++ ++ // Test registers for test only ++ DVBT_TEST_REG_1, ++ DVBT_TEST_REG_2, ++ DVBT_TEST_REG_3, ++ DVBT_TEST_REG_4, ++ ++ // Item terminator ++ DVBT_REG_BIT_NAME_ITEM_TERMINATOR, ++}; ++ ++ ++ ++// Register table length definitions ++#define DVBT_REG_TABLE_LEN_MAX DVBT_REG_BIT_NAME_ITEM_TERMINATOR ++ ++ ++ ++ ++ ++// DVB-T demod module pre-definition ++typedef struct DVBT_DEMOD_MODULE_TAG DVBT_DEMOD_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register page setting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_PAGE() to set demod register page. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] PageNo Page number ++ ++ ++@retval FUNCTION_SUCCESS Set register page successfully with page number. ++@retval FUNCTION_ERROR Set register page unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_PAGE() with the corresponding function. ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register page with page number 2. ++ pDemod->SetRegPage(pDemod, 2); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_PAGE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register byte setting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_BYTES() to set demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] pWritingBytes Pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bytes successfully with writing bytes. ++@retval FUNCTION_ERROR Set demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_SET_REG_BYTES(). ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_GET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char WritingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bytes (page 1, address 0x17 ~ 0x1b) with 5 writing bytes. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBytes(pDemod, 0x17, WritingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_BYTES)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register byte getting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_BYTES() to get demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [out] pReadingBytes Pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bytes successfully with reading byte number. ++@retval FUNCTION_ERROR Get demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_GET_REG_BYTES(). ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_SET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char ReadingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bytes (page 1, address 0x17 ~ 0x1b) with reading byte number 5. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBytes(pDemod, 0x17, ReadingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_REG_BYTES)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register mask bits setting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_MASK_BITS() to set demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register mask bits successfully with writing value. ++@retval FUNCTION_ERROR Set demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_SET_REG_MASK_BITS(). ++ -# The constraints of DVBT_DEMOD_FP_SET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_GET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits (page 1, address {0x18, 0x17} [12:5]) with writing value 0x1d. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegMaskBits(pDemod, 0x17, 12, 5, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x17 0x18 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_MASK_BITS)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register mask bits getting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_MASK_BITS() to get demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register mask bits successfully. ++@retval FUNCTION_ERROR Get demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by DVBT_DEMOD_FP_SET_REG_PAGE() before using DVBT_DEMOD_FP_GET_REG_MASK_BITS(). ++ -# The constraints of DVBT_DEMOD_FP_GET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_SET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits (page 1, address {0x18, 0x17} [12:5]). ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegMaskBits(pDemod, 0x17, 12, 5, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_REG_MASK_BITS)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register bits setting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_BITS() to set demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using DVBT_DEMOD_FP_SET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_GET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBits(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_BITS)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register bits getting function pointer ++ ++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_BITS() to get demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using DVBT_DEMOD_FP_GET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_PAGE, DVBT_DEMOD_FP_SET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBits(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_REG_BITS)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register bits setting function pointer (with page setting) ++ ++Demod upper level functions will use DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE() to set demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name, page setting, and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod register bits getting function pointer (with page setting) ++ ++Demod upper level functions will use DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE() to get demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name and page setting. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->GetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod type getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_DEMOD_TYPE() to get DVB-T demod type. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDemodType Pointer to an allocated memory for storing demod type ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_DEMOD_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*DVBT_DEMOD_FP_GET_DEMOD_TYPE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod I2C device address getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_DEVICE_ADDR() to get DVB-T demod I2C device address. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDeviceAddr Pointer to an allocated memory for storing demod I2C device address ++ ++ ++@retval FUNCTION_SUCCESS Get demod device address successfully. ++@retval FUNCTION_ERROR Get demod device address unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_DEVICE_ADDR() with the corresponding function. ++ ++*/ ++typedef void ++(*DVBT_DEMOD_FP_GET_DEVICE_ADDR)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod crystal frequency getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() to get DVB-T demod crystal frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrystalFreqHz Pointer to an allocated memory for storing demod crystal frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod crystal frequency successfully. ++@retval FUNCTION_ERROR Get demod crystal frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef void ++(*DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod I2C bus connection asking function pointer ++ ++One can use DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C() to ask DVB-T demod if it is connected to I2C bus. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C() with the corresponding function. ++ ++*/ ++typedef void ++(*DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod software resetting function pointer ++ ++One can use DVBT_DEMOD_FP_SOFTWARE_RESET() to reset DVB-T demod by software reset. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod by software reset successfully. ++@retval FUNCTION_ERROR Reset demod by software reset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SOFTWARE_RESET() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SOFTWARE_RESET)( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod initializing function pointer ++ ++One can use DVBT_DEMOD_FP_INITIALIZE() to initialie DVB-T demod. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize demod successfully. ++@retval FUNCTION_ERROR Initialize demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_INITIALIZE)( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod bandwidth mode setting function pointer ++ ++One can use DVBT_DEMOD_FP_SET_DVBT_MODE() to set DVB-T demod bandwidth mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] BandwidthMode Bandwidth mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod bandwidth mode successfully. ++@retval FUNCTION_ERROR Set demod bandwidth mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_DVBT_MODE() with the corresponding function. ++ ++ ++@see DVBT_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_BANDWIDTH_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod IF frequency setting function pointer ++ ++One can use DVBT_DEMOD_FP_SET_IF_FREQ_HZ() to set DVB-T demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] IfFreqHz IF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod IF frequency successfully. ++@retval FUNCTION_ERROR Set demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_IF_FREQ_HZ)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod spectrum mode setting function pointer ++ ++One can use DVBT_DEMOD_FP_SET_SPECTRUM_MODE() to set DVB-T demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] SpectrumMode Spectrum mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod spectrum mode successfully. ++@retval FUNCTION_ERROR Set demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_SET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_SET_SPECTRUM_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod bandwidth mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_DVBT_MODE() to get DVB-T demod bandwidth mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pBandwidthMode Pointer to an allocated memory for storing demod bandwidth mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod bandwidth mode successfully. ++@retval FUNCTION_ERROR Get demod bandwidth mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_DVBT_MODE() with the corresponding function. ++ ++ ++@see DVBT_DVBT_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_BANDWIDTH_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod IF frequency getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_IF_FREQ_HZ() to get DVB-T demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfFreqHz Pointer to an allocated memory for storing demod IF frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF frequency successfully. ++@retval FUNCTION_ERROR Get demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_IF_FREQ_HZ)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod spectrum mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_SPECTRUM_MODE() to get DVB-T demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSpectrumMode Pointer to an allocated memory for storing demod spectrum mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod spectrum mode successfully. ++@retval FUNCTION_ERROR Get demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_SPECTRUM_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod TPS lock asking function pointer ++ ++One can use DVBT_DEMOD_FP_IS_TPS_LOCKED() to ask DVB-T demod if it is TPS-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform TPS lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform TPS lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_IS_TPS_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_IS_TPS_LOCKED)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod signal lock asking function pointer ++ ++One can use DVBT_DEMOD_FP_IS_SIGNAL_LOCKED() to ask DVB-T demod if it is signal-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_IS_SIGNAL_LOCKED)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod signal strength getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal strength successfully. ++@retval FUNCTION_ERROR Get demod signal strength unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod signal quality getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal quality successfully. ++@retval FUNCTION_ERROR Get demod signal quality unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_SIGNAL_QUALITY)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod BER getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_BER() to get BER. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod error rate value successfully. ++@retval FUNCTION_ERROR Get demod error rate value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_BER() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_BER)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod SNR getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod SNR successfully. ++@retval FUNCTION_ERROR Get demod SNR unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_SNR_DB)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod RF AGC getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_RF_AGC() to get DVB-T demod RF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pRfAgc Pointer to an allocated memory for storing RF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod RF AGC value successfully. ++@retval FUNCTION_ERROR Get demod RF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_RF_AGC() with the corresponding function. ++ -# The range of RF AGC value is (-pow(2, 13)) ~ (pow(2, 13) - 1). ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_RF_AGC)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod IF AGC getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_IF_AGC() to get DVB-T demod IF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfAgc Pointer to an allocated memory for storing IF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF AGC value successfully. ++@retval FUNCTION_ERROR Get demod IF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_IF_AGC() with the corresponding function. ++ -# The range of IF AGC value is (-pow(2, 13)) ~ (pow(2, 13) - 1). ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_IF_AGC)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod digital AGC getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_DI_AGC() to get DVB-T demod digital AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDiAgc Pointer to an allocated memory for storing digital AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod digital AGC value successfully. ++@retval FUNCTION_ERROR Get demod digital AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_DI_AGC() with the corresponding function. ++ -# The range of digital AGC value is 0 ~ (pow(2, 8) - 1). ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_DI_AGC)( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDiAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod TR offset getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get demod TR offset successfully. ++@retval FUNCTION_ERROR Get demod TR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_TR_OFFSET_PPM)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod CR offset getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod CR offset successfully. ++@retval FUNCTION_ERROR Get demod CR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_CR_OFFSET_HZ)( ++ DVBT_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod constellation mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CONSTELLATION() to get DVB-T demod constellation mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pConstellation Pointer to an allocated memory for storing demod constellation mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod constellation mode successfully. ++@retval FUNCTION_ERROR Get demod constellation mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CONSTELLATION() with the corresponding function. ++ ++ ++@see DVBT_CONSTELLATION_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_CONSTELLATION)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pConstellation ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod hierarchy mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_HIERARCHY() to get DVB-T demod hierarchy mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pHierarchy Pointer to an allocated memory for storing demod hierarchy mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod hierarchy mode successfully. ++@retval FUNCTION_ERROR Get demod hierarchy mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_HIERARCHY() with the corresponding function. ++ ++ ++@see DVBT_HIERARCHY_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_HIERARCHY)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pHierarchy ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod low-priority code rate mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CODE_RATE_LP() to get DVB-T demod low-priority code rate mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCodeRateLp Pointer to an allocated memory for storing demod low-priority code rate mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod low-priority code rate mode successfully. ++@retval FUNCTION_ERROR Get demod low-priority code rate mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CODE_RATE_LP() with the corresponding function. ++ ++ ++@see DVBT_CODE_RATE_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_CODE_RATE_LP)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateLp ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod high-priority code rate mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_CODE_RATE_HP() to get DVB-T demod high-priority code rate mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCodeRateHp Pointer to an allocated memory for storing demod high-priority code rate mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod high-priority code rate mode successfully. ++@retval FUNCTION_ERROR Get demod high-priority code rate mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_CODE_RATE_HP() with the corresponding function. ++ ++ ++@see DVBT_CODE_RATE_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_CODE_RATE_HP)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pCodeRateHp ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod guard interval mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_GUARD_INTERVAL() to get DVB-T demod guard interval mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pGuardInterval Pointer to an allocated memory for storing demod guard interval mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod guard interval mode successfully. ++@retval FUNCTION_ERROR Get demod guard interval mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_GUARD_INTERVAL() with the corresponding function. ++ ++ ++@see DVBT_GUARD_INTERVAL_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_GUARD_INTERVAL)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pGuardInterval ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod FFT mode getting function pointer ++ ++One can use DVBT_DEMOD_FP_GET_FFT_MODE() to get DVB-T demod FFT mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pFftMode Pointer to an allocated memory for storing demod FFT mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod FFT mode successfully. ++@retval FUNCTION_ERROR Get demod FFT mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_GET_FFT_MODE() with the corresponding function. ++ ++ ++@see DVBT_FFT_MODE_MODE ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_GET_FFT_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pFftMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod updating function pointer ++ ++One can use DVBT_DEMOD_FP_UPDATE_FUNCTION() to update demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod setting successfully. ++@retval FUNCTION_ERROR Update demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_UPDATE_FUNCTION)( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod reseting function pointer ++ ++One can use DVBT_DEMOD_FP_RESET_FUNCTION() to reset demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod setting successfully. ++@retval FUNCTION_ERROR Reset demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set DVBT_DEMOD_FP_RESET_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbtDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_DEMOD_FP_RESET_FUNCTION)( ++ DVBT_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/// RTL2830 extra module ++ ++// Definitions for Function 4 ++#define DVBT_FUNC4_REG_VALUE_NUM 5 ++ ++typedef struct RTL2830_EXTRA_MODULE_TAG RTL2830_EXTRA_MODULE; ++ ++/* ++ ++@brief RTL2830 application mode getting function pointer ++ ++One can use RTL2830_FP_GET_APP_MODE() to get RTL2830 application mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAppMode Pointer to an allocated memory for storing demod application mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod application mode successfully. ++@retval FUNCTION_ERROR Get demod application mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set RTL2830_FP_GET_APP_MODE() with the corresponding function. ++ ++ ++@see RTL2830_APPLICATION_MODE ++ ++*/ ++typedef void ++(*RTL2830_FP_GET_APP_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAppMode ++ ); ++ ++struct RTL2830_EXTRA_MODULE_TAG ++{ ++ // RTL2830 variables ++ int AppMode; ++ ++ // RTL2830 update procedure enabling status ++ int IsFunction2Enabled; ++ int IsFunction3Enabled; ++ int IsFunction4Enabled; ++ int IsFunction5Enabled; ++ ++ // RTL2830 update procedure variables ++ unsigned char Func2Executing; ++ unsigned char Func3State; ++ unsigned char Func3Executing; ++ unsigned char Func4State; ++ unsigned long Func4DelayCnt; ++ unsigned long Func4DelayCntMax; ++ unsigned char Func4ParamSetting; ++ unsigned long Func4RegValue[DVBT_FUNC4_REG_VALUE_NUM]; ++ unsigned char Func5State; ++ unsigned char Func5QamBak; ++ unsigned char Func5HierBak; ++ unsigned char Func5LpCrBak; ++ unsigned char Func5HpCrBak; ++ unsigned char Func5GiBak; ++ unsigned char Func5FftBak; ++ ++ // RTL2830 extra function pointers ++ RTL2830_FP_GET_APP_MODE GetAppMode; ++}; ++ ++ ++ ++ ++ ++/// RTL2832 extra module ++typedef struct RTL2832_EXTRA_MODULE_TAG RTL2832_EXTRA_MODULE; ++ ++/* ++ ++@brief RTL2832 application mode getting function pointer ++ ++One can use RTL2832_FP_GET_APP_MODE() to get RTL2832 application mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAppMode Pointer to an allocated memory for storing demod application mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod application mode successfully. ++@retval FUNCTION_ERROR Get demod application mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set RTL2832_FP_GET_APP_MODE() with the corresponding function. ++ ++ ++@see RTL2832_APPLICATION_MODE ++ ++*/ ++typedef void ++(*RTL2832_FP_GET_APP_MODE)( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pAppMode ++ ); ++ ++struct RTL2832_EXTRA_MODULE_TAG ++{ ++ // RTL2832 extra variables ++ int AppMode; ++ ++ // RTL2832 update procedure enabling status ++ int IsFunc1Enabled; ++ ++ // RTL2832 update Function 1 variables ++ int Func1State; ++ ++ int Func1WaitTimeMax; ++ int Func1GettingTimeMax; ++ int Func1GettingNumEachTime; ++ ++ int Func1WaitTime; ++ int Func1GettingTime; ++ ++ unsigned long Func1RsdBerEstSumNormal; ++ unsigned long Func1RsdBerEstSumConfig1; ++ unsigned long Func1RsdBerEstSumConfig2; ++ unsigned long Func1RsdBerEstSumConfig3; ++ ++ int Func1QamBak; ++ int Func1HierBak; ++ int Func1LpCrBak; ++ int Func1HpCrBak; ++ int Func1GiBak; ++ int Func1FftBak; ++ ++ // RTL2832 extra function pointers ++ RTL2832_FP_GET_APP_MODE GetAppMode; ++}; ++ ++ ++ ++ ++ ++/// DVB-T demod module structure ++struct DVBT_DEMOD_MODULE_TAG ++{ ++ unsigned long CurrentPageNo; ++ // Private variables ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ int TsInterfaceMode; ++ ++ int BandwidthMode; ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int IsBandwidthModeSet; ++ int IsIfFreqHzSet; ++ int IsSpectrumModeSet; ++ ++ union ///< Demod extra module used by driving module ++ { ++ RTL2830_EXTRA_MODULE Rtl2830; ++ RTL2832_EXTRA_MODULE Rtl2832; ++ } ++ Extra; ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ // Demod register table ++ DVBT_REG_ENTRY RegTable[DVBT_REG_TABLE_LEN_MAX]; ++ ++ ++ // Demod I2C function pointers ++ DVBT_DEMOD_FP_SET_REG_PAGE SetRegPage; ++ DVBT_DEMOD_FP_SET_REG_BYTES SetRegBytes; ++ DVBT_DEMOD_FP_GET_REG_BYTES GetRegBytes; ++ DVBT_DEMOD_FP_SET_REG_MASK_BITS SetRegMaskBits; ++ DVBT_DEMOD_FP_GET_REG_MASK_BITS GetRegMaskBits; ++ DVBT_DEMOD_FP_SET_REG_BITS SetRegBits; ++ DVBT_DEMOD_FP_GET_REG_BITS GetRegBits; ++ DVBT_DEMOD_FP_SET_REG_BITS_WITH_PAGE SetRegBitsWithPage; ++ DVBT_DEMOD_FP_GET_REG_BITS_WITH_PAGE GetRegBitsWithPage; ++ ++ ++ // Demod manipulating function pointers ++ DVBT_DEMOD_FP_GET_DEMOD_TYPE GetDemodType; ++ DVBT_DEMOD_FP_GET_DEVICE_ADDR GetDeviceAddr; ++ DVBT_DEMOD_FP_GET_CRYSTAL_FREQ_HZ GetCrystalFreqHz; ++ ++ DVBT_DEMOD_FP_IS_CONNECTED_TO_I2C IsConnectedToI2c; ++ ++ DVBT_DEMOD_FP_SOFTWARE_RESET SoftwareReset; ++ ++ DVBT_DEMOD_FP_INITIALIZE Initialize; ++ DVBT_DEMOD_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ DVBT_DEMOD_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ DVBT_DEMOD_FP_SET_SPECTRUM_MODE SetSpectrumMode; ++ DVBT_DEMOD_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++ DVBT_DEMOD_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++ DVBT_DEMOD_FP_GET_SPECTRUM_MODE GetSpectrumMode; ++ ++ DVBT_DEMOD_FP_IS_TPS_LOCKED IsTpsLocked; ++ DVBT_DEMOD_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ ++ DVBT_DEMOD_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ DVBT_DEMOD_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ ++ DVBT_DEMOD_FP_GET_BER GetBer; ++ DVBT_DEMOD_FP_GET_SNR_DB GetSnrDb; ++ ++ DVBT_DEMOD_FP_GET_RF_AGC GetRfAgc; ++ DVBT_DEMOD_FP_GET_IF_AGC GetIfAgc; ++ DVBT_DEMOD_FP_GET_DI_AGC GetDiAgc; ++ ++ DVBT_DEMOD_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ DVBT_DEMOD_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ ++ DVBT_DEMOD_FP_GET_CONSTELLATION GetConstellation; ++ DVBT_DEMOD_FP_GET_HIERARCHY GetHierarchy; ++ DVBT_DEMOD_FP_GET_CODE_RATE_LP GetCodeRateLp; ++ DVBT_DEMOD_FP_GET_CODE_RATE_HP GetCodeRateHp; ++ DVBT_DEMOD_FP_GET_GUARD_INTERVAL GetGuardInterval; ++ DVBT_DEMOD_FP_GET_FFT_MODE GetFftMode; ++ ++ DVBT_DEMOD_FP_UPDATE_FUNCTION UpdateFunction; ++ DVBT_DEMOD_FP_RESET_FUNCTION ResetFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// DVB-T demod default I2C functions ++int ++dvbt_demod_default_SetRegPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++int ++dvbt_demod_default_SetRegBytes( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ); ++ ++int ++dvbt_demod_default_GetRegBytes( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ); ++ ++int ++dvbt_demod_default_SetRegMaskBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++dvbt_demod_default_GetRegMaskBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dvbt_demod_default_SetRegBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dvbt_demod_default_GetRegBits( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++int ++dvbt_demod_default_SetRegBitsWithPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++dvbt_demod_default_GetRegBitsWithPage( ++ DVBT_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// DVB-T demod default manipulating functions ++void ++dvbt_demod_default_GetDemodType( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++void ++dvbt_demod_default_GetDeviceAddr( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++void ++dvbt_demod_default_GetCrystalFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++int ++dvbt_demod_default_GetBandwidthMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pBandwidthMode ++ ); ++ ++int ++dvbt_demod_default_GetIfFreqHz( ++ DVBT_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++int ++dvbt_demod_default_GetSpectrumMode( ++ DVBT_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/dvbt_nim_base.c b/drivers/drivers/media/dvb/dvb-usb/dvbt_nim_base.c +--- a/drivers/media/dvb/dvb-usb/dvbt_nim_base.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/dvbt_nim_base.c 2016-04-02 19:17:52.092066030 -0300 +@@ -0,0 +1,531 @@ ++/** ++ ++@file ++ ++@brief DVB-T NIM base module definition ++ ++DVB-T NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++*/ ++ ++ ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_NIM_TYPE ++ ++*/ ++void ++dvbt_nim_default_GetNimType( ++ DVBT_NIM_MODULE *pNim, ++ int *pNimType ++ ) ++{ ++ // Get NIM type from NIM module. ++ *pNimType = pNim->NimType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++dvbt_nim_default_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_PARAMETERS ++ ++*/ ++int ++dvbt_nim_default_GetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pBandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Get tuner RF frequency in Hz. ++ if(pTuner->GetRfFreqHz(pTuner, pRfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, pBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_IS_SIGNAL_PRESENT ++ ++*/ ++int ++dvbt_nim_default_IsSignalPresent( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ DVBT_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait for signal present check. ++ for(i = 0; i < DVBT_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX_DEFAULT; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check TPS present status on demod. ++ // Note: If TPS is locked, stop signal present check. ++ if(pDemod->IsTpsLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++dvbt_nim_default_IsSignalLocked( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ DVBT_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait for signal lock check. ++ for(i = 0; i < DVBT_NIM_SINGAL_LOCK_CHECK_TIMES_MAX_DEFAULT; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check signal lock status on demod. ++ // Note: If signal is locked, stop signal lock check. ++ if(pDemod->IsSignalLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++dvbt_nim_default_GetSignalStrength( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal strength from demod. ++ if(pDemod->GetSignalStrength(pDemod, pSignalStrength) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++dvbt_nim_default_GetSignalQuality( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal quality from demod. ++ if(pDemod->GetSignalQuality(pDemod, pSignalQuality) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_BER ++ ++*/ ++int ++dvbt_nim_default_GetBer( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get BER from demod. ++ if(pDemod->GetBer(pDemod, pBerNum, pBerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_SNR_DB ++ ++*/ ++int ++dvbt_nim_default_GetSnrDb( ++ DVBT_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get SNR in dB from demod. ++ if(pDemod->GetSnrDb(pDemod, pSnrDbNum, pSnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++dvbt_nim_default_GetTrOffsetPpm( ++ DVBT_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get TR offset in ppm from demod. ++ if(pDemod->GetTrOffsetPpm(pDemod, pTrOffsetPpm) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++dvbt_nim_default_GetCrOffsetHz( ++ DVBT_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get CR offset in Hz from demod. ++ if(pDemod->GetCrOffsetHz(pDemod, pCrOffsetHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_TPS_INFO ++ ++*/ ++int ++dvbt_nim_default_GetTpsInfo( ++ DVBT_NIM_MODULE *pNim, ++ int *pConstellation, ++ int *pHierarchy, ++ int *pCodeRateLp, ++ int *pCodeRateHp, ++ int *pGuardInterval, ++ int *pFftMode ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get TPS constellation information from demod. ++ if(pDemod->GetConstellation(pDemod, pConstellation) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS hierarchy information from demod. ++ if(pDemod->GetHierarchy(pDemod, pHierarchy) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS low-priority code rate information from demod. ++ if(pDemod->GetCodeRateLp(pDemod, pCodeRateLp) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS high-priority code rate information from demod. ++ if(pDemod->GetCodeRateHp(pDemod, pCodeRateHp) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS guard interval information from demod. ++ if(pDemod->GetGuardInterval(pDemod, pGuardInterval) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get TPS FFT mode information from demod. ++ if(pDemod->GetFftMode(pDemod, pFftMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++dvbt_nim_default_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/dvbt_nim_base.h b/drivers/drivers/media/dvb/dvb-usb/dvbt_nim_base.h +--- a/drivers/media/dvb/dvb-usb/dvbt_nim_base.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/dvbt_nim_base.h 2016-04-02 19:17:52.096066035 -0300 +@@ -0,0 +1,964 @@ ++#ifndef __DVBT_NIM_BASE_H ++#define __DVBT_NIM_BASE_H ++ ++/** ++ ++@file ++ ++@brief DVB-T NIM base module definition ++ ++DVB-T NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ unsigned long RfFreqHz; ++ int BandwidthMode; ++ ++ int Answer; ++ unsigned long SignalStrength, SignalQuality; ++ unsigned long BerNum, BerDen, PerNum, PerDen; ++ double Ber, Per; ++ unsigned long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ long TrOffsetPpm, CrOffsetHz; ++ ++ int Constellation; ++ int Hierarchy; ++ int CodeRateLp; ++ int CodeRateHp; ++ int GuardInterval; ++ int FftMode; ++ ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ &DemodxExtraModuleMemory, // Employ Demod-X extra module. ++ 0x20, // The Demod-X I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The Demod-X crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The Demod-X TS interface mode is serial. ++ ... // Other arguments for Demod-X ++ ++ &TunerxExtraModuleMemory, // Employ Tuner-Y extra module. ++ 0xc0, // The Tuner-Y I2C device address is 0xc0 in 8-bit format. ++ ... // Other arguments for Tuner-Y ++ ); ++ ++ ++ ++ // Get NIM type. ++ // Note: NIM types are defined in the MODULE_TYPE enumeration. ++ pNim->GetNimType(pNim, &NimType); ++ ++ ++ ++ ++ ++ ++ ++ // ==== Initialize NIM and set its parameters ===== ++ ++ // Initialize NIM. ++ pNim->Initialize(pNim); ++ ++ // Set NIM parameters. (RF frequency, bandwdith mode) ++ // Note: In the example: ++ // 1. RF frequency is 666 MHz. ++ // 2. Bandwidth mode is 8 MHz. ++ RfFreqHz = 666000000; ++ BandwidthMode = DVBT_BANDWIDTH_8MHZ; ++ pNim->SetParameters(pNim, RfFreqHz, BandwidthMode); ++ ++ ++ ++ // Wait 1 second for demod convergence. ++ ++ ++ ++ ++ ++ // ==== Get NIM information ===== ++ ++ // Get NIM parameters. (RF frequency, bandwdith mode) ++ pNim->GetParameters(pNim, &RfFreqHz, &BandwidthMode); ++ ++ ++ // Get signal present status. ++ // Note: 1. The argument Answer is YES when the NIM module has found DVB-T signal in the RF channel. ++ // 2. The argument Answer is NO when the NIM module does not find DVB-T signal in the RF channel. ++ // Recommendation: Use the IsSignalPresent() function for channel scan. ++ pNim->IsSignalPresent(pNim, &Answer); ++ ++ // Get signal lock status. ++ // Note: 1. The argument Answer is YES when the NIM module has locked DVB-T signal in the RF channel. ++ // At the same time, the NIM module sends TS packets through TS interface hardware pins. ++ // 2. The argument Answer is NO when the NIM module does not lock DVB-T signal in the RF channel. ++ // Recommendation: Use the IsSignalLocked() function for signal lock check. ++ pNim->IsSignalLocked(pNim, &Answer); ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pNim->GetSignalStrength(pNim, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pNim->GetSignalQuality(pNim, &SignalQuality); ++ ++ ++ // Get BER. ++ pNim->GetBer(pNim, &BerNum, &BerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ ++ // Get SNR in dB. ++ pNim->GetSnrDb(pNim, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pNim->GetTrOffsetPpm(pNim, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pNim->GetCrOffsetHz(pNim, &CrOffsetHz); ++ ++ ++ // Get TPS information. ++ // Note: One can find TPS information definitions in the enumerations as follows: ++ // 1. DVBT_CONSTELLATION_MODE. ++ // 2. DVBT_HIERARCHY_MODE. ++ // 3. DVBT_CODE_RATE_MODE. (for low-priority and high-priority code rate) ++ // 4. DVBT_GUARD_INTERVAL_MODE. ++ // 5. DVBT_FFT_MODE_MODE ++ pNim->GetTpsInfo(pNim, &Constellation, &Hierarchy, &CodeRateLp, &CodeRateHp, &GuardInterval, &FftMode); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++#include "tuner_base.h" ++#include "dvbt_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define DVBT_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX_DEFAULT 1 ++#define DVBT_NIM_SINGAL_LOCK_CHECK_TIMES_MAX_DEFAULT 1 ++ ++ ++ ++ ++ ++/// DVB-T NIM module pre-definition ++typedef struct DVBT_NIM_MODULE_TAG DVBT_NIM_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T demod type getting function pointer ++ ++One can use DVBT_NIM_FP_GET_NIM_TYPE() to get DVB-T NIM type. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pNimType Pointer to an allocated memory for storing NIM type ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_NIM_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*DVBT_NIM_FP_GET_NIM_TYPE)( ++ DVBT_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM initializing function pointer ++ ++One can use DVBT_NIM_FP_INITIALIZE() to initialie DVB-T NIM. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize NIM successfully. ++@retval FUNCTION_ERROR Initialize NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_INITIALIZE)( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM parameter setting function pointer ++ ++One can use DVBT_NIM_FP_SET_PARAMETERS() to set DVB-T NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [in] RfFreqHz RF frequency in Hz for setting ++@param [in] BandwidthMode Bandwidth mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set NIM parameters successfully. ++@retval FUNCTION_ERROR Set NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_SET_PARAMETERS() with the corresponding function. ++ ++ ++@see DVBT_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_SET_PARAMETERS)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM parameter getting function pointer ++ ++One can use DVBT_NIM_FP_GET_PARAMETERS() to get DVB-T NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pRfFreqHz Pointer to an allocated memory for storing NIM RF frequency in Hz ++@param [out] pBandwidthMode Pointer to an allocated memory for storing NIM bandwidth mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM parameters successfully. ++@retval FUNCTION_ERROR Get NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_PARAMETERS() with the corresponding function. ++ ++ ++@see DVBT_BANDWIDTH_MODE ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_PARAMETERS)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM signal present asking function pointer ++ ++One can use DVBT_NIM_FP_IS_SIGNAL_PRESENT() to ask DVB-T NIM if signal is present. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal present asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal present asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_IS_SIGNAL_PRESENT() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_IS_SIGNAL_PRESENT)( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM signal lock asking function pointer ++ ++One can use DVBT_NIM_FP_IS_SIGNAL_LOCKED() to ask DVB-T NIM if signal is locked. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_IS_SIGNAL_LOCKED)( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM signal strength getting function pointer ++ ++One can use DVBT_NIM_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal strength successfully. ++@retval FUNCTION_ERROR Get NIM signal strength unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_SIGNAL_STRENGTH)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM signal quality getting function pointer ++ ++One can use DVBT_NIM_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal quality successfully. ++@retval FUNCTION_ERROR Get NIM signal quality unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_SIGNAL_QUALITY)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM BER value getting function pointer ++ ++One can use DVBT_NIM_FP_GET_BER() to get BER. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM BER value successfully. ++@retval FUNCTION_ERROR Get NIM BER value unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_BER() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_BER)( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM SNR getting function pointer ++ ++One can use DVBT_NIM_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM SNR successfully. ++@retval FUNCTION_ERROR Get NIM SNR unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_SNR_DB)( ++ DVBT_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM TR offset getting function pointer ++ ++One can use DVBT_NIM_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get NIM TR offset successfully. ++@retval FUNCTION_ERROR Get NIM TR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_TR_OFFSET_PPM)( ++ DVBT_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM CR offset getting function pointer ++ ++One can use DVBT_NIM_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get NIM CR offset successfully. ++@retval FUNCTION_ERROR Get NIM CR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_CR_OFFSET_HZ)( ++ DVBT_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM TPS information getting function pointer ++ ++One can use DVBT_NIM_FP_GET_TPS_INFO() to get TPS information. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pConstellation Pointer to an allocated memory for storing demod constellation mode ++@param [out] pHierarchy Pointer to an allocated memory for storing demod hierarchy mode ++@param [out] pCodeRateLp Pointer to an allocated memory for storing demod low-priority code rate mode ++@param [out] pCodeRateHp Pointer to an allocated memory for storing demod high-priority code rate mode ++@param [out] pGuardInterval Pointer to an allocated memory for storing demod guard interval mode ++@param [out] pFftMode Pointer to an allocated memory for storing demod FFT mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM TPS information successfully. ++@retval FUNCTION_ERROR Get NIM TPS information unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_GET_TPS_INFO() with the corresponding function. ++ ++ ++@see DVBT_CONSTELLATION_MODE, DVBT_HIERARCHY_MODE, DVBT_CODE_RATE_MODE, DVBT_GUARD_INTERVAL_MODE, DVBT_FFT_MODE_MODE ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_GET_TPS_INFO)( ++ DVBT_NIM_MODULE *pNim, ++ int *pConstellation, ++ int *pHierarchy, ++ int *pCodeRateLp, ++ int *pCodeRateHp, ++ int *pGuardInterval, ++ int *pFftMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief DVB-T NIM updating function pointer ++ ++One can use DVBT_NIM_FP_UPDATE_FUNCTION() to update NIM register setting. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update NIM setting successfully. ++@retval FUNCTION_ERROR Update NIM setting unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set DVBT_NIM_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ ... ++ ); ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pNim->UpdateFunction(pNim); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*DVBT_NIM_FP_UPDATE_FUNCTION)( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++// RTL2832 MT2266 extra module ++typedef struct RTL2832_MT2266_EXTRA_MODULE_TAG RTL2832_MT2266_EXTRA_MODULE; ++struct RTL2832_MT2266_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned char LnaConfig; ++ unsigned char UhfSens; ++ unsigned char AgcCurrentState; ++ unsigned long LnaGainOld; ++}; ++ ++ ++ ++ ++ ++// RTL2832 E4000 extra module ++typedef struct RTL2832_E4000_EXTRA_MODULE_TAG RTL2832_E4000_EXTRA_MODULE; ++struct RTL2832_E4000_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long TunerModeUpdateWaitTimeMax; ++ unsigned long TunerModeUpdateWaitTime; ++ unsigned char TunerGainMode; ++}; ++ ++ ++ ++ ++ ++// RTL2832 E4005 extra module ++typedef struct RTL2832_E4005_EXTRA_MODULE_TAG RTL2832_E4005_EXTRA_MODULE; ++struct RTL2832_E4005_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long TunerModeUpdateWaitTimeMax; ++ unsigned long TunerModeUpdateWaitTime; ++ unsigned char TunerGainMode; ++}; ++ ++ ++ ++ ++ ++// RTL2832 MT2063 extra module ++typedef struct RTL2832_MT2063_EXTRA_MODULE_TAG RTL2832_MT2063_EXTRA_MODULE; ++struct RTL2832_MT2063_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long IfFreqHz; ++}; ++ ++ ++ ++ ++ ++// RTL2832 FC0012 extra module ++typedef struct RTL2832_FC0012_EXTRA_MODULE_TAG RTL2832_FC0012_EXTRA_MODULE; ++struct RTL2832_FC0012_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long LnaUpdateWaitTimeMax; ++ unsigned long LnaUpdateWaitTime; ++ unsigned long RssiRCalOn; ++}; ++ ++ ++ ++ ++ ++// RTL2832 FC0013 extra module ++typedef struct RTL2832_FC0013_EXTRA_MODULE_TAG RTL2832_FC0013_EXTRA_MODULE; ++struct RTL2832_FC0013_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long LnaUpdateWaitTimeMax; ++ unsigned long LnaUpdateWaitTime; ++ unsigned long RssiRCalOn; ++}; ++ ++ ++ ++ ++ ++// RTL2832 FC0013B extra module ++typedef struct RTL2832_FC0013B_EXTRA_MODULE_TAG RTL2832_FC0013B_EXTRA_MODULE; ++struct RTL2832_FC0013B_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long LnaUpdateWaitTimeMax; ++ unsigned long LnaUpdateWaitTime; ++ unsigned long RssiRCalOn; ++}; ++ ++ ++ ++ ++ ++/// DVB-T NIM module structure ++struct DVBT_NIM_MODULE_TAG ++{ ++ // Private variables ++ int NimType; ++ ++ union ///< NIM extra module used by driving module ++ { ++ RTL2832_MT2266_EXTRA_MODULE Rtl2832Mt2266; ++ RTL2832_E4000_EXTRA_MODULE Rtl2832E4000; ++ RTL2832_E4005_EXTRA_MODULE Rtl2832E4005; ++ RTL2832_MT2063_EXTRA_MODULE Rtl2832Mt2063; ++ RTL2832_FC0012_EXTRA_MODULE Rtl2832Fc0012; ++ RTL2832_FC0013_EXTRA_MODULE Rtl2832Fc0013; ++ RTL2832_FC0013B_EXTRA_MODULE Rtl2832Fc0013b; ++ } ++ Extra; ++ ++ ++ // Modules ++ BASE_INTERFACE_MODULE *pBaseInterface; ///< Base interface module pointer ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ///< Base interface module memory ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ///< I2C bridge module pointer ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ///< I2C bridge module memory ++ ++ TUNER_MODULE *pTuner; ///< Tuner module pointer ++ TUNER_MODULE TunerModuleMemory; ///< Tuner module memory ++ ++ DVBT_DEMOD_MODULE *pDemod; ///< DVB-T demod module pointer ++ DVBT_DEMOD_MODULE DvbtDemodModuleMemory; ///< DVB-T demod module memory ++ ++ ++ // NIM manipulating functions ++ DVBT_NIM_FP_GET_NIM_TYPE GetNimType; ++ DVBT_NIM_FP_INITIALIZE Initialize; ++ DVBT_NIM_FP_SET_PARAMETERS SetParameters; ++ DVBT_NIM_FP_GET_PARAMETERS GetParameters; ++ DVBT_NIM_FP_IS_SIGNAL_PRESENT IsSignalPresent; ++ DVBT_NIM_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ DVBT_NIM_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ DVBT_NIM_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ DVBT_NIM_FP_GET_BER GetBer; ++ DVBT_NIM_FP_GET_SNR_DB GetSnrDb; ++ DVBT_NIM_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ DVBT_NIM_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ DVBT_NIM_FP_GET_TPS_INFO GetTpsInfo; ++ DVBT_NIM_FP_UPDATE_FUNCTION UpdateFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// DVB-T NIM default manipulaing functions ++void ++dvbt_nim_default_GetNimType( ++ DVBT_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++int ++dvbt_nim_default_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++dvbt_nim_default_GetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pBandwidthMode ++ ); ++ ++int ++dvbt_nim_default_IsSignalPresent( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++dvbt_nim_default_IsSignalLocked( ++ DVBT_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++dvbt_nim_default_GetSignalStrength( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++dvbt_nim_default_GetSignalQuality( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++dvbt_nim_default_GetBer( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen ++ ); ++ ++int ++dvbt_nim_default_GetSnrDb( ++ DVBT_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++dvbt_nim_default_GetTrOffsetPpm( ++ DVBT_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++int ++dvbt_nim_default_GetCrOffsetHz( ++ DVBT_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++int ++dvbt_nim_default_GetTpsInfo( ++ DVBT_NIM_MODULE *pNim, ++ int *pConstellation, ++ int *pHierarchy, ++ int *pCodeRateLp, ++ int *pCodeRateHp, ++ int *pGuardInterval, ++ int *pFftMode ++ ); ++ ++int ++dvbt_nim_default_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/foundation.c b/drivers/drivers/media/dvb/dvb-usb/foundation.c +--- a/drivers/media/dvb/dvb-usb/foundation.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/foundation.c 2016-04-02 19:17:52.096066035 -0300 +@@ -0,0 +1,352 @@ ++/** ++ ++@file ++ ++@brief Fundamental interface definition ++ ++Fundamental interface contains base function pointers and some mathematics tools. ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++// Base interface builder ++void ++BuildBaseInterface( ++ BASE_INTERFACE_MODULE **ppBaseInterface, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ unsigned long I2cReadingByteNumMax, ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs ++ ) ++{ ++ // Set base interface module pointer. ++ *ppBaseInterface = pBaseInterfaceModuleMemory; ++ ++ ++ // Set all base interface function pointers and arguments. ++ (*ppBaseInterface)->I2cReadingByteNumMax = I2cReadingByteNumMax; ++ (*ppBaseInterface)->I2cWritingByteNumMax = I2cWritingByteNumMax; ++ (*ppBaseInterface)->I2cRead = I2cRead; ++ (*ppBaseInterface)->I2cWrite = I2cWrite; ++ (*ppBaseInterface)->WaitMs = WaitMs; ++ (*ppBaseInterface)->SetUserDefinedDataPointer = base_interface_SetUserDefinedDataPointer; ++ (*ppBaseInterface)->GetUserDefinedDataPointer = base_interface_GetUserDefinedDataPointer; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set user defined data pointer of base interface structure for custom basic function implementation. ++ ++@note ++ -# Base interface builder will set BASE_FP_SET_USER_DEFINED_DATA_POINTER() function pointer with ++ base_interface_SetUserDefinedDataPointer(). ++ ++@see BASE_FP_SET_USER_DEFINED_DATA_POINTER ++ ++*/ ++void ++base_interface_SetUserDefinedDataPointer( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void *pUserDefinedData ++ ) ++{ ++ // Set user defined data pointer of base interface structure with user defined data pointer argument. ++ pBaseInterface->pUserDefinedData = pUserDefinedData; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get user defined data pointer of base interface structure for custom basic function implementation. ++ ++@note ++ -# Base interface builder will set BASE_FP_GET_USER_DEFINED_DATA_POINTER() function pointer with ++ base_interface_GetUserDefinedDataPointer(). ++ ++@see BASE_FP_GET_USER_DEFINED_DATA_POINTER ++ ++*/ ++void ++base_interface_GetUserDefinedDataPointer( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void **ppUserDefinedData ++ ) ++{ ++ // Get user defined data pointer from base interface structure to the caller user defined data pointer. ++ *ppUserDefinedData = pBaseInterface->pUserDefinedData; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Convert signed integer to binary. ++ ++Convert 2's complement signed integer to binary with bit number. ++ ++ ++@param [in] Value the converting value in 2's complement format ++@param [in] BitNum the bit number of the converting value ++ ++ ++@return Converted binary ++ ++ ++@note ++ The converting value must be -pow(2, BitNum - 1) ~ (pow(2, BitNum - 1) -1). ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++int main(void) ++{ ++ long Value = -345; ++ unsigned long Binary; ++ ++ ++ // Convert 2's complement integer to binary with 10 bit number. ++ Binary = SignedIntToBin(Value, 10); ++ ++ ++ // Result in base 2: ++ // Value = 1111 1111 1111 1111 1111 1110 1010 0111 b = -345 (in 32-bit 2's complement format) ++ // Binary = 0000 0000 0000 0000 0000 0010 1010 0111 b = 679 (in 10-bit binary format) ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++unsigned long ++SignedIntToBin( ++ long Value, ++ unsigned char BitNum ++ ) ++{ ++ unsigned int i; ++ unsigned long Mask, Binary; ++ ++ ++ ++ // Generate Mask according to BitNum. ++ Mask = 0; ++ for(i = 0; i < BitNum; i++) ++ Mask |= 0x1 << i; ++ ++ ++ // Convert signed integer to binary with Mask. ++ Binary = Value & Mask; ++ ++ ++ return Binary; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Convert binary to signed integer. ++ ++Convert binary to 2's complement signed integer with bit number. ++ ++ ++@param [in] Binary the converting binary ++@param [in] BitNum the bit number of the converting binary ++ ++ ++@return Converted 2's complement signed integer ++ ++ ++@note ++ The converting binary must be 0 ~ (pow(2, BitNum) - 1). ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++int main(void) ++{ ++ unsigned long Binary = 679; ++ long Value; ++ ++ ++ // Convert binary to 2's complement integer with 10 bit number. ++ Value = BinToSignedInt(Binary, 10); ++ ++ ++ // Result in base 2: ++ // Binary = 0000 0000 0000 0000 0000 0010 1010 0111 b = 679 (in 10-bit binary format) ++ // Value = 1111 1111 1111 1111 1111 1110 1010 0111 b = -345 (in 32-bit 2's complement format) ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++long ++BinToSignedInt( ++ unsigned long Binary, ++ unsigned char BitNum ++ ) ++{ ++ int i; ++ ++ unsigned char SignedBit; ++ unsigned long SignedBitExtension; ++ ++ long Value; ++ ++ ++ ++ // Get signed bit. ++ SignedBit = (unsigned char)((Binary >> (BitNum - 1)) & BIT_0_MASK); ++ ++ ++ // Generate signed bit extension. ++ SignedBitExtension = 0; ++ ++ for(i = BitNum; i < LONG_BIT_NUM; i++) ++ SignedBitExtension |= SignedBit << i; ++ ++ ++ // Combine binary value and signed bit extension to signed integer value. ++ Value = (long)(Binary | SignedBitExtension); ++ ++ ++ return Value; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get devision reult with ceiling. ++ ++Get unsigned devision reult with ceiling. ++ ++ ++@param [in] Dividend the dividend ++@param [in] Divisor the divisor ++ ++ ++@return Result with ceiling ++ ++ ++@note ++ The dividend and divisor must be unsigned integer. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++int main(void) ++{ ++ long Value; ++ ++ ++ // Get ceil(100 / 20) reult. ++ Value = DivideWithCeiling(100, 20); ++ ++ // Result: Value = 5 ++ ++ ++ // Get ceil(100 / 30) reult. ++ Value = DivideWithCeiling(100, 30); ++ ++ // Result: Value = 4 ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++unsigned long ++DivideWithCeiling( ++ unsigned long Dividend, ++ unsigned long Divisor ++ ) ++{ ++ unsigned long Result; ++ ++ ++ // Get primitive division result. ++ Result = Dividend / Divisor; ++ ++ // Adjust primitive result with ceiling. ++ if(Dividend % Divisor > 0) ++ Result += 1; ++ ++ ++ return Result; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/foundation.h b/drivers/drivers/media/dvb/dvb-usb/foundation.h +--- a/drivers/media/dvb/dvb-usb/foundation.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/foundation.h 2016-04-02 19:17:52.096066035 -0300 +@@ -0,0 +1,1026 @@ ++#ifndef __FOUNDATION_H ++#define __FOUNDATION_H ++ ++/** ++ ++@file ++ ++@brief Fundamental interface declaration ++ ++Fundamental interface contains base function pointers and some mathematics tools. ++ ++*/ ++ ++ ++#include "i2c_bridge.h" ++#include "math_mpi.h" ++ ++ ++#include "dvb-usb.h" ++#include "rtl2832u_io.h" ++ ++ ++ ++// Definitions ++ ++// API version ++#define REALTEK_NIM_API_VERSION "Realtek NIM API 2012.03.30" ++ ++ ++ ++// Constants ++#define INVALID_POINTER_VALUE 0 ++#define NO_USE 0 ++ ++#define LEN_1_BYTE 1 ++#define LEN_2_BYTE 2 ++#define LEN_3_BYTE 3 ++#define LEN_4_BYTE 4 ++#define LEN_5_BYTE 5 ++#define LEN_6_BYTE 6 ++#define LEN_11_BYTE 11 ++ ++#define LEN_1_BIT 1 ++ ++#define BYTE_MASK 0xff ++#define BYTE_SHIFT 8 ++#define HEX_DIGIT_MASK 0xf ++#define BYTE_BIT_NUM 8 ++#define LONG_BIT_NUM 32 ++ ++#define BIT_0_MASK 0x1 ++#define BIT_1_MASK 0x2 ++#define BIT_2_MASK 0x4 ++#define BIT_3_MASK 0x8 ++ ++#define BIT_4_MASK 0x10 ++#define BIT_5_MASK 0x20 ++#define BIT_6_MASK 0x40 ++#define BIT_7_MASK 0x80 ++ ++ ++#define BIT_8_MASK 0x100 ++#define BIT_7_SHIFT 7 ++#define BIT_8_SHIFT 8 ++ ++ ++ ++// I2C buffer length ++// Note: I2C_BUFFER_LEN must be greater than I2cReadingByteNumMax and I2cWritingByteNumMax in BASE_INTERFACE_MODULE. ++#define I2C_BUFFER_LEN 128 ++ ++ ++ ++ ++ ++/// Module types ++enum MODULE_TYPE ++{ ++ // DVB-T demod ++ DVBT_DEMOD_TYPE_RTL2830, ///< RTL2830 DVB-T demod ++ DVBT_DEMOD_TYPE_RTL2832, ///< RTL2832 DVB-T demod ++ ++ // QAM demod ++ QAM_DEMOD_TYPE_RTL2840, ///< RTL2840 DVB-C demod ++ QAM_DEMOD_TYPE_RTL2810_OC, ///< RTL2810 OpenCable demod ++ QAM_DEMOD_TYPE_RTL2820_OC, ///< RTL2820 OpenCable demod ++ QAM_DEMOD_TYPE_RTD2885_QAM, ///< RTD2885 QAM demod ++ QAM_DEMOD_TYPE_RTD2932_QAM, ///< RTD2932 QAM demod ++ QAM_DEMOD_TYPE_RTL2836B_DVBC, ///< RTL2836 DVB-C demod ++ QAM_DEMOD_TYPE_RTL2810B_QAM, ///< RTL2810B QAM demod ++ QAM_DEMOD_TYPE_RTD2840B_QAM, ///< RTD2840B QAM demod ++ QAM_DEMOD_TYPE_RTD2648_QAM, ///< RTD2648 QAM demod ++ ++ // OOB demod ++ OOB_DEMOD_TYPE_RTL2820_OOB, ///< RTL2820 OOB demod ++ ++ // ATSC demod ++ ATSC_DEMOD_TYPE_RTL2820_ATSC, ///< RTL2820 ATSC demod ++ ATSC_DEMOD_TYPE_RTD2885_ATSC, ///< RTD2885 ATSC demod ++ ATSC_DEMOD_TYPE_RTD2932_ATSC, ///< RTD2932 ATSC demod ++ ATSC_DEMOD_TYPE_RTL2810B_ATSC, ///< RTL2810B ATSC demod ++ ATSC_DEMOD_TYPE_RTD2648_ATSC, ///< RTD2648 ATSC demod ++ ++ // DTMB demod ++ DTMB_DEMOD_TYPE_RTL2836, ///< RTL2836 DTMB demod ++ DTMB_DEMOD_TYPE_RTL2836B_DTMB, ///< RTL2836B DTMB demod ++ DTMB_DEMOD_TYPE_RTD2974_DTMB, ///< RTD2974 DTMB demod ++ ++ // ISDB-T demod ++ ISDBT_DEMOD_TYPE_RTD2648_ISDBT, ///< RTD2648 ISDB-T demod ++ ++ // Tuner ++ TUNER_TYPE_TDCGG052D, ///< TDCG-G052D tuner (QAM) ++ TUNER_TYPE_TDCHG001D, ///< TDCH-G001D tuner (QAM) ++ TUNER_TYPE_TDQE3003A, ///< TDQE3-003A tuner (QAM) ++ TUNER_TYPE_DCT7045, ///< DCT-7045 tuner (QAM) ++ TUNER_TYPE_MT2062, ///< MT2062 tuner (QAM) ++ TUNER_TYPE_MXL5005S, ///< MxL5005S tuner (DVB-T, ATSC) ++ TUNER_TYPE_TDVMH715P, ///< TDVM-H751P tuner (QAM, OOB, ATSC) ++ TUNER_TYPE_UBA00AL, ///< UBA00AL tuner (QAM, ATSC) ++ TUNER_TYPE_MT2266, ///< MT2266 tuner (DVB-T) ++ TUNER_TYPE_FC2580, ///< FC2580 tuner (DVB-T, DTMB) ++ TUNER_TYPE_TUA9001, ///< TUA9001 tuner (DVB-T) ++ TUNER_TYPE_DTT75300, ///< DTT-75300 tuner (DVB-T) ++ TUNER_TYPE_MXL5007T, ///< MxL5007T tuner (DVB-T, ATSC) ++ TUNER_TYPE_VA1T1ED6093, ///< VA1T1ED6093 tuner (DTMB) ++ TUNER_TYPE_TUA8010, ///< TUA8010 tuner (DVB-T) ++ TUNER_TYPE_E4000, ///< E4000 tuner (DVB-T) ++ TUNER_TYPE_E4005, ///< E4005 tuner (DVB-T) ++ TUNER_TYPE_DCT70704, ///< DCT-70704 tuner (QAM) ++ TUNER_TYPE_MT2063, ///< MT2063 tuner (DVB-T, QAM) ++ TUNER_TYPE_FC0012, ///< FC0012 tuner (DVB-T, DTMB) ++ TUNER_TYPE_TDAG, ///< TDAG tuner (DTMB) ++ TUNER_TYPE_ADMTV804, ///< ADMTV804 tuner (DVB-T, DTMB) ++ TUNER_TYPE_MAX3543, ///< MAX3543 tuner (DVB-T) ++ TUNER_TYPE_TDA18272, ///< TDA18272 tuner (DVB-T, QAM, DTMB) ++ TUNER_TYPE_TDA18250, ///< TDA18250 tuner (DVB-T, QAM, DTMB) ++ TUNER_TYPE_FC0013, ///< FC0013 tuner (DVB-T, DTMB) ++ TUNER_TYPE_FC0013B, ///< FC0013B tuner (DVB-T, DTMB) ++ TUNER_TYPE_VA1E1ED2403, ///< VA1E1ED2403 tuner (DTMB) ++ TUNER_TYPE_AVALON, ///< AVALON tuner (DTMB) ++ TUNER_TYPE_SUTRE201, ///< SUTRE201 tuner (DTMB) ++ TUNER_TYPE_MR1300, ///< MR1300 tuner (ISDB-T 1-Seg) ++ TUNER_TYPE_TDAC7, ///< TDAC7 tuner (DTMB, QAM) ++ TUNER_TYPE_VA1T1ER2094, ///< VA1T1ER2094 tuner (DTMB) ++ TUNER_TYPE_TDAC3, ///< TDAC3 tuner (DTMB) ++ TUNER_TYPE_RT910, ///< RT910 tuner (DVB-T) ++ TUNER_TYPE_DTM4C20, ///< DTM4C20 tuner (DTMB) ++ TUNER_TYPE_GTFD32, ///< GTFD32 tuner (DTMB) ++ TUNER_TYPE_GTLP10, ///< GTLP10 tuner (DTMB) ++ TUNER_TYPE_JSS66T, ///< JSS66T tuner (DTMB) ++ TUNER_TYPE_NONE, ///< NONE tuner (DTMB) ++ TUNER_TYPE_MR1500, ///< MR1500 tuner (ISDB-T full-Seg) ++ TUNER_TYPE_R820T, ///< R820T tuner (DVB-T) ++ TUNER_TYPE_YTMB04, ///< YTMB-04 tuner (DTMB) ++ TUNER_TYPE_DTI7, ///< DTI7 tuner (DTMB) ++ ++ // DVB-T NIM ++ DVBT_NIM_USER_DEFINITION, ///< DVB-T NIM: User definition ++ DVBT_NIM_RTL2832_MT2266, ///< DVB-T NIM: RTL2832 + MT2266 ++ DVBT_NIM_RTL2832_FC2580, ///< DVB-T NIM: RTL2832 + FC2580 ++ DVBT_NIM_RTL2832_TUA9001, ///< DVB-T NIM: RTL2832 + TUA9001 ++ DVBT_NIM_RTL2832_MXL5005S, ///< DVB-T NIM: RTL2832 + MxL5005S ++ DVBT_NIM_RTL2832_DTT75300, ///< DVB-T NIM: RTL2832 + DTT-75300 ++ DVBT_NIM_RTL2832_MXL5007T, ///< DVB-T NIM: RTL2832 + MxL5007T ++ DVBT_NIM_RTL2832_TUA8010, ///< DVB-T NIM: RTL2832 + TUA8010 ++ DVBT_NIM_RTL2832_E4000, ///< DVB-T NIM: RTL2832 + E4000 ++ DVBT_NIM_RTL2832_E4005, ///< DVB-T NIM: RTL2832 + E4005 ++ DVBT_NIM_RTL2832_MT2063, ///< DVB-T NIM: RTL2832 + MT2063 ++ DVBT_NIM_RTL2832_FC0012, ///< DVB-T NIM: RTL2832 + FC0012 ++ DVBT_NIM_RTL2832_ADMTV804, ///< DVB-T NIM: RTL2832 + ADMTV804 ++ DVBT_NIM_RTL2832_MAX3543, ///< DVB-T NIM: RTL2832 + MAX3543 ++ DVBT_NIM_RTL2832_TDA18272, ///< DVB-T NIM: RTL2832 + TDA18272 ++ DVBT_NIM_RTL2832_FC0013, ///< DVB-T NIM: RTL2832 + FC0013 ++ DVBT_NIM_RTL2832_RT910, ///< DVB-T NIM: RTL2832 + RT910 ++ DVBT_NIM_RTL2832_FC0013B, ///< DVB-T NIM: RTL2832 + FC0013B ++ DVBT_NIM_RTL2832_R820T, ///< DVB-T NIM: RTL2832 + R820T ++ ++ // QAM NIM ++ QAM_NIM_USER_DEFINITION, ///< QAM NIM: User definition ++ QAM_NIM_RTL2840_TDQE3003A, ///< QAM NIM: RTL2840 + TDQE3-003A ++ QAM_NIM_RTL2840_DCT7045, ///< QAM NIM: RTL2840 + DCT-7045 ++ QAM_NIM_RTL2840_DCT7046, ///< QAM NIM: RTL2840 + DCT-7046 ++ QAM_NIM_RTL2840_MT2062, ///< QAM NIM: RTL2840 + MT2062 ++ QAM_NIM_RTL2840_DCT70704, ///< QAM NIM: RTL2840 + DCT-70704 ++ QAM_NIM_RTL2840_MT2063, ///< QAM NIM: RTL2840 + MT2063 ++ QAM_NIM_RTL2840_MAX3543, ///< QAM NIM: RTL2840 + MAX3543 ++ QAM_NIM_RTL2836B_DVBC_VA1T1ED6093, ///< QAM NIM: RTL2836B DVB-C + VA1T1ED6093 ++ QAM_NIM_RTD2885_QAM_TDA18272, ///< QAM NIM: RTD2885 QAM + TDA18272 ++ QAM_NIM_RTL2836B_DVBC_VA1E1ED2403, ///< QAM NIM: RTL2836B DVB-C + VA1E1ED2403 ++ QAM_NIM_RTD2840B_QAM_MT2062, ///< QAM NIM: RTD2840B QAM + MT2062 ++ QAM_NIM_RTL2840_TDA18272, ///< QAM NIM: RTL2840 + TDA18272 ++ QAM_NIM_RTL2840_TDA18250, ///< QAM NIM: RTL2840 + TDA18250 ++ QAM_NIM_RTL2836B_DVBC_FC0013B, ///< QAM NIM: RTL2836B DVB-C + FC0013B ++ QAM_NIM_RTL2836B_DVBC_TDA18272, ///< QAM NIM: RTL2836B DVB-C + TDA18272 ++ ++ // DCR NIM ++ DCR_NIM_RTL2820_TDVMH715P, ///< DCR NIM: RTL2820 + TDVM-H751P ++ DCR_NIM_RTD2885_UBA00AL, ///< DCR NIM: RTD2885 + UBA00AL ++ ++ // ATSC NIM ++ ATSC_NIM_RTD2885_ATSC_TDA18272, ///< ATSC NIM: RTD2885 ATSC + TDA18272 ++ ++ // DTMB NIM ++ DTMB_NIM_RTL2836_FC2580, ///< DTMB NIM: RTL2836 + FC2580 ++ DTMB_NIM_RTL2836_VA1T1ED6093, ///< DTMB NIM: RTL2836 + VA1T1ED6093 ++ DTMB_NIM_RTL2836_TDAG, ///< DTMB NIM: RTL2836 + TDAG ++ DTMB_NIM_RTL2836_MXL5007T, ///< DTMB NIM: RTL2836 + MxL5007T ++ DTMB_NIM_RTL2836_E4000, ///< DTMB NIM: RTL2836 + E4000 ++ DTMB_NIM_RTL2836_TDA18272, ///< DTMB NIM: RTL2836 + TDA18272 ++ DTMB_NIM_RTL2836B_DTMB_VA1T1ED6093, ///< DTMB NIM: RTL2836B DTMB + VA1T1ED6093 ++ DTMB_NIM_RTL2836B_DTMB_ADMTV804, ///< DTMB NIM: RTL2836B DTMB + ADMTV804 ++ DTMB_NIM_RTL2836B_DTMB_E4000, ///< DTMB NIM: RTL2836B DTMB + E4000 ++ DTMB_NIM_RTL2836B_DTMB_FC0012, ///< DTMB NIM: RTL2836B DTMB + FC0012 ++ DTMB_NIM_RTL2836B_DTMB_VA1E1ED2403, ///< DTMB NIM: RTL2836B DTMB + VA1E1ED2403 ++ DTMB_NIM_RTL2836B_DTMB_TDA18272, ///< DTMB NIM: RTL2836B DTMB + TDA18272 ++ DTMB_NIM_RTL2836B_DTMB_AVALON, ///< DTMB NIM: RTL2836B DTMB + AVALON ++ DTMB_NIM_RTL2836B_DTMB_SUTRE201, ///< DTMB NIM: RTL2836B DTMB + SUTRE201 ++ DTMB_NIM_RTL2836B_DTMB_TDAC7, ///< DTMB NIM: RTL2836B DTMB + ALPS TDAC7 ++ DTMB_NIM_RTL2836B_DTMB_FC0013B, ///< DTMB NIM: RTL2836B DTMB + FC0013B ++ DTMB_NIM_RTL2836B_DTMB_VA1T1ER2094, ///< DTMB NIM: RTL2836B DTMB + VA1T1ER2094 ++ DTMB_NIM_RTL2836B_DTMB_TDAC3, ///< DTMB NIM: RTL2836B DTMB + ALPS TDAC3 ++ DTMB_NIM_RTL2836B_DTMB_DTM4C20, ///< DTMB NIM: RTL2836B DTMB + DTM4C20 ++ DTMB_NIM_RTL2836B_DTMB_GTFD32, ///< DTMB NIM: RTL2836B DTMB + GTFD32 ++ DTMB_NIM_RTL2836B_DTMB_GTLP10, ///< DTMB NIM: RTL2836B DTMB + GTFD32 ++ DTMB_NIM_RTL2836B_DTMB_JSS66T, ///< DTMB NIM: RTL2836B DTMB + JSS66T ++ DTMB_NIM_RTL2836B_DTMB_NONE, ///< DTMB NIM: RTL2836B DTMB + NONE TUNER ++ DTMB_NIM_RTD2974_DTMB_VA1E1ED2403, ///< DTMB NIM: RTD2974 DTMB + VA1E1ED2403 ++ DTMB_NIM_RTL2836B_DTMB_E4005, ///< DTMB NIM: RTL2836B DTMB + E4005 ++ DTMB_NIM_RTL2836B_DTMB_MR1500, ///< DTMB NIM: RTL2836B DTMB + MR1500 ++ DTMB_NIM_RTL2836B_DTMB_MXL5007T, ///< DTMB NIM: RTL2836B DTMB + MxL5007T ++ DTMB_NIM_RTL2836B_DTMB_YTMB04, ///< DTMB NIM: RTL2836B DTMB + YTMB-04 ++ DTMB_NIM_RTL2836B_DTMB_DTI7, ///< DTMB NIM: RTL2836B DTMB + DTI7 ++}; ++ ++ ++ ++ ++ ++/// On/off status ++enum ON_OFF_STATUS ++{ ++ OFF, ///< Off ++ ON, ///< On ++}; ++ ++ ++/// Yes/no status ++enum YES_NO_STATUS ++{ ++ NO, ///< No ++ YES, ///< Yes ++}; ++ ++ ++/// Lock status ++enum LOCK_STATUS ++{ ++ NOT_LOCKED, ///< Not locked ++ LOCKED, ///< Locked ++}; ++ ++ ++/// Loss status ++enum LOSS_STATUS ++{ ++ NOT_LOST, ///< Not lost ++ LOST, ///< Lost ++}; ++ ++ ++/// Function return status ++enum FUNCTION_RETURN_STATUS ++{ ++ FUNCTION_SUCCESS, ///< Execute function successfully. ++ FUNCTION_ERROR, ///< Execute function unsuccessfully. ++}; ++ ++ ++/// Crystal frequency ++enum CRYSTAL_FREQ_HZ ++{ ++ CRYSTAL_FREQ_4000000HZ = 4000000, ///< Crystal frequency = 4.0 MHz ++ CRYSTAL_FREQ_16000000HZ = 16000000, ///< Crystal frequency = 16.0 MHz ++ CRYSTAL_FREQ_16384000HZ = 16384000, ///< Crystal frequency = 16.384 MHz ++ CRYSTAL_FREQ_16457143HZ = 16457143, ///< Crystal frequency = 16.457 MHz ++ CRYSTAL_FREQ_20000000HZ = 20000000, ///< Crystal frequency = 20.0 MHz ++ CRYSTAL_FREQ_20250000HZ = 20250000, ///< Crystal frequency = 20.25 MHz ++ CRYSTAL_FREQ_20480000HZ = 20480000, ///< Crystal frequency = 20.48 MHz ++ CRYSTAL_FREQ_24000000HZ = 24000000, ///< Crystal frequency = 24.0 MHz ++ CRYSTAL_FREQ_25000000HZ = 25000000, ///< Crystal frequency = 25.0 MHz ++ CRYSTAL_FREQ_25200000HZ = 25200000, ///< Crystal frequency = 25.2 MHz ++ CRYSTAL_FREQ_26000000HZ = 26000000, ///< Crystal frequency = 26.0 MHz ++ CRYSTAL_FREQ_26690000HZ = 26690000, ///< Crystal frequency = 26.69 MHz ++ CRYSTAL_FREQ_27000000HZ = 27000000, ///< Crystal frequency = 27.0 MHz ++ CRYSTAL_FREQ_28800000HZ = 28800000, ///< Crystal frequency = 28.8 MHz ++ CRYSTAL_FREQ_32000000HZ = 32000000, ///< Crystal frequency = 32.0 MHz ++ CRYSTAL_FREQ_36000000HZ = 36000000, ///< Crystal frequency = 36.0 MHz ++}; ++ ++ ++/// IF frequency ++enum IF_FREQ_HZ ++{ ++ IF_FREQ_0HZ = 0, ///< IF frequency = 0 MHz ++ IF_FREQ_3250000HZ = 3250000, ///< IF frequency = 3.25 MHz ++ IF_FREQ_3570000HZ = 3570000, ///< IF frequency = 3.57 MHz ++ IF_FREQ_4000000HZ = 4000000, ///< IF frequency = 4.0 MHz ++ IF_FREQ_4570000HZ = 4570000, ///< IF frequency = 4.57 MHz ++ IF_FREQ_4571429HZ = 4571429, ///< IF frequency = 4.571 MHz ++ IF_FREQ_5000000HZ = 5000000, ///< IF frequency = 5.0 MHz ++ IF_FREQ_36000000HZ = 36000000, ///< IF frequency = 36.0 MHz ++ IF_FREQ_36125000HZ = 36125000, ///< IF frequency = 36.125 MHz ++ IF_FREQ_36150000HZ = 36150000, ///< IF frequency = 36.15 MHz ++ IF_FREQ_36166667HZ = 36166667, ///< IF frequency = 36.167 MHz ++ IF_FREQ_36170000HZ = 36170000, ///< IF frequency = 36.17 MHz ++ IF_FREQ_43750000HZ = 43750000, ///< IF frequency = 43.75 MHz ++ IF_FREQ_44000000HZ = 44000000, ///< IF frequency = 44.0 MHz ++}; ++ ++ ++/// Spectrum mode ++enum SPECTRUM_MODE ++{ ++ SPECTRUM_NORMAL, ///< Normal spectrum ++ SPECTRUM_INVERSE, ///< Inverse spectrum ++}; ++#define SPECTRUM_MODE_NUM 2 ++ ++ ++/// TS interface mode ++enum TS_INTERFACE_MODE ++{ ++ TS_INTERFACE_PARALLEL, ///< Parallel TS interface ++ TS_INTERFACE_SERIAL, ///< Serial TS interface ++}; ++#define TS_INTERFACE_MODE_NUM 2 ++ ++ ++/// Diversity mode ++enum DIVERSITY_PIP_MODE ++{ ++ DIVERSITY_PIP_OFF, ///< Diversity disable and PIP disable ++ DIVERSITY_ON_MASTER, ///< Diversity enable for Master Demod ++ DIVERSITY_ON_SLAVE, ///< Diversity enable for Slave Demod ++ PIP_ON_MASTER, ///< PIP enable for Master Demod ++ PIP_ON_SLAVE, ///< PIP enable for Slave Demod ++}; ++#define DIVERSITY_PIP_MODE_NUM 5 ++ ++ ++ ++ ++ ++/// Base interface module alias ++typedef struct BASE_INTERFACE_MODULE_TAG BASE_INTERFACE_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief Basic I2C reading function pointer ++ ++Upper layer functions will use BASE_FP_I2C_READ() to read ByteNum bytes from I2C device to pReadingBytes buffer. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] DeviceAddr I2C device address in 8-bit format ++@param [out] pReadingBytes Buffer pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Read bytes from I2C device with reading byte number successfully. ++@retval FUNCTION_ERROR Read bytes from I2C device unsuccessfully. ++ ++ ++@note ++ The requirements of BASE_FP_I2C_READ() function are described as follows: ++ -# Follow the I2C format for BASE_FP_I2C_READ(). \n ++ start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ -# Don't allocate memory on pReadingBytes. ++ -# Upper layer functions should allocate memory on pReadingBytes before using BASE_FP_I2C_READ(). ++ -# Need to assign I2C reading funtion to BASE_FP_I2C_READ() for upper layer functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer. ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ unsigned char ReadingBytes[100]; ++ ++ ++ // Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...); ++ ++ ... ++ ++ // Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes. ++ pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*BASE_FP_I2C_READ)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Basic I2C writing function pointer ++ ++Upper layer functions will use BASE_FP_I2C_WRITE() to write ByteNum bytes from pWritingBytes buffer to I2C device. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] DeviceAddr I2C device address in 8-bit format ++@param [in] pWritingBytes Buffer pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Write bytes to I2C device with writing bytes successfully. ++@retval FUNCTION_ERROR Write bytes to I2C device unsuccessfully. ++ ++ ++@note ++ The requirements of BASE_FP_I2C_WRITE() function are described as follows: ++ -# Follow the I2C format for BASE_FP_I2C_WRITE(). \n ++ start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ -# Need to assign I2C writing funtion to BASE_FP_I2C_WRITE() for upper layer functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C writing funciton for BASE_FP_I2C_WRITE function pointer. ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ unsigned char WritingBytes[100]; ++ ++ ++ // Assign implemented I2C writing funciton to BASE_FP_I2C_WRITE in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., ..., CustomI2cWrite, ...); ++ ++ ... ++ ++ // Use I2cWrite() to write 33 bytes from WritingBytes to I2C device. ++ pBaseInterface->I2cWrite(pBaseInterface, 0x20, WritingBytes, 33); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*BASE_FP_I2C_WRITE)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Basic waiting function pointer ++ ++Upper layer functions will use BASE_FP_WAIT_MS() to wait WaitTimeMs milliseconds. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] WaitTimeMs Waiting time in millisecond ++ ++ ++@note ++ The requirements of BASE_FP_WAIT_MS() function are described as follows: ++ -# Need to assign a waiting function to BASE_FP_WAIT_MS() for upper layer functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement waiting funciton for BASE_FP_WAIT_MS function pointer. ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ ... ++ ++ return; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ ++ // Assign implemented waiting funciton to BASE_FP_WAIT_MS in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., ..., ..., CustomWaitMs); ++ ++ ... ++ ++ // Use WaitMs() to wait 30 millisecond. ++ pBaseInterface->WaitMs(pBaseInterface, 30); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef void ++(*BASE_FP_WAIT_MS)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief User defined data pointer setting function pointer ++ ++One can use BASE_FP_SET_USER_DEFINED_DATA_POINTER() to set user defined data pointer of base interface structure for ++custom basic function implementation. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] pUserDefinedData Pointer to user defined data ++ ++ ++@note ++ One can use BASE_FP_GET_USER_DEFINED_DATA_POINTER() to get user defined data pointer of base interface structure for ++ custom basic function implementation. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer. ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ CUSTOM_USER_DEFINED_DATA *pUserDefinedData; ++ ++ ++ // Get user defined data pointer of base interface structure for custom I2C reading function. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&pUserDefinedData); ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ unsigned char ReadingBytes[100]; ++ ++ CUSTOM_USER_DEFINED_DATA UserDefinedData; ++ ++ ++ // Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...); ++ ++ ... ++ ++ // Set user defined data pointer of base interface structure for custom basic functions. ++ pBaseInterface->SetUserDefinedDataPointer(pBaseInterface, &UserDefinedData); ++ ++ // Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes. ++ pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef void ++(*BASE_FP_SET_USER_DEFINED_DATA_POINTER)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void *pUserDefinedData ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief User defined data pointer getting function pointer ++ ++One can use BASE_FP_GET_USER_DEFINED_DATA_POINTER() to get user defined data pointer of base interface structure for ++custom basic function implementation. ++ ++ ++@param [in] pBaseInterface The base interface module pointer ++@param [in] ppUserDefinedData Pointer to user defined data pointer ++ ++ ++@note ++ One can use BASE_FP_SET_USER_DEFINED_DATA_POINTER() to set user defined data pointer of base interface structure for ++ custom basic function implementation. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer. ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ CUSTOM_USER_DEFINED_DATA *pUserDefinedData; ++ ++ ++ // Get user defined data pointer of base interface structure for custom I2C reading function. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&pUserDefinedData); ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ unsigned char ReadingBytes[100]; ++ ++ CUSTOM_USER_DEFINED_DATA UserDefinedData; ++ ++ ++ // Assign implemented I2C reading funciton to BASE_FP_I2C_READ in base interface module. ++ BuildBaseInterface(&pBaseInterface, &BaseInterfaceModuleMemory, ..., ..., CustomI2cRead, ..., ...); ++ ++ ... ++ ++ // Set user defined data pointer of base interface structure for custom basic functions. ++ pBaseInterface->SetUserDefinedDataPointer(pBaseInterface, &UserDefinedData); ++ ++ // Use I2cRead() to read 33 bytes from I2C device and store reading bytes to ReadingBytes. ++ pBaseInterface->I2cRead(pBaseInterface, 0x20, ReadingBytes, 33); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef void ++(*BASE_FP_GET_USER_DEFINED_DATA_POINTER)( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void **ppUserDefinedData ++ ); ++ ++ ++ ++ ++ ++/// Base interface module structure ++struct BASE_INTERFACE_MODULE_TAG ++{ ++ // Variables and function pointers ++ unsigned long I2cReadingByteNumMax; ++ unsigned long I2cWritingByteNumMax; ++ ++ BASE_FP_I2C_READ I2cRead; ++ BASE_FP_I2C_WRITE I2cWrite; ++ BASE_FP_WAIT_MS WaitMs; ++ ++ BASE_FP_SET_USER_DEFINED_DATA_POINTER SetUserDefinedDataPointer; ++ BASE_FP_GET_USER_DEFINED_DATA_POINTER GetUserDefinedDataPointer; ++ ++ ++ // User defined data ++ void *pUserDefinedData; ++}; ++ ++ ++ ++ ++ ++/** ++ ++@brief Base interface builder ++ ++Use BuildBaseInterface() to build base interface for module functions to access basic functions. ++ ++ ++@param [in] ppBaseInterface Pointer to base interface module pointer ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++ ++ ++@note ++ -# One should build base interface before using module functions. ++ -# The I2C reading format is described as follows: ++ start_bit + (device_addr | reading_bit) + reading_byte * byte_num + stop_bit ++ -# The I2cReadingByteNumMax is the maximum byte_num of the I2C reading format. ++ -# The I2C writing format is described as follows: ++ start_bit + (device_addr | writing_bit) + writing_byte * byte_num + stop_bit ++ -# The I2cWritingByteNumMax is the maximum byte_num of the I2C writing format. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "foundation.h" ++ ++ ++// Implement I2C reading funciton for BASE_FP_I2C_READ function pointer. ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++// Implement I2C writing funciton for BASE_FP_I2C_WRITE function pointer. ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ ++ return FUNCTION_ERROR; ++} ++ ++ ++// Implement waiting funciton for BASE_FP_WAIT_MS function pointer. ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ ... ++ ++ return; ++} ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ ++ // Build base interface with the following settings. ++ // ++ // 1. Assign 9 to maximum I2C reading byte number. ++ // 2. Assign 8 to maximum I2C writing byte number. ++ // 3. Assign CustomI2cRead() to basic I2C reading function pointer. ++ // 4. Assign CustomI2cWrite() to basic I2C writing function pointer. ++ // 5. Assign CustomWaitMs() to basic waiting function pointer. ++ // ++ BuildBaseInterface( ++ &pBaseInterface, ++ &BaseInterfaceModuleMemory, ++ 9, ++ 8, ++ CustomI2cRead, ++ CustomI2cWrite, ++ CustomWaitMs ++ ); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++void ++BuildBaseInterface( ++ BASE_INTERFACE_MODULE **ppBaseInterface, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ unsigned long I2cReadingByteNumMax, ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs ++ ); ++ ++ ++ ++ ++ ++// User data pointer of base interface structure setting and getting functions ++void ++base_interface_SetUserDefinedDataPointer( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void *pUserDefinedData ++ ); ++ ++void ++base_interface_GetUserDefinedDataPointer( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ void **ppUserDefinedData ++ ); ++ ++ ++ ++ ++ ++// Math functions ++ ++// Binary and signed integer converter ++unsigned long ++SignedIntToBin( ++ long Value, ++ unsigned char BitNum ++ ); ++ ++long ++BinToSignedInt( ++ unsigned long Binary, ++ unsigned char BitNum ++ ); ++ ++ ++ ++// Arithmetic ++unsigned long ++DivideWithCeiling( ++ unsigned long Dividend, ++ unsigned long Divisor ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++/** ++ ++@mainpage Realtek demod Source Code Manual ++ ++@note ++ -# The Realtek demod API source code is designed for demod IC driver porting. ++ -# The API source code is written in C language without floating-point arithmetic. ++ -# One can use the API to manipulate Realtek demod IC. ++ -# The API will call custom underlayer functions through API base interface module. ++ ++ ++@par Important: ++ -# Please assign API base interface module with custom underlayer functions instead of modifying API source code. ++ -# Please see the example code to understand the relation bewteen API and custom system. ++ ++*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/i2c_bridge.h b/drivers/drivers/media/dvb/dvb-usb/i2c_bridge.h +--- a/drivers/media/dvb/dvb-usb/i2c_bridge.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/i2c_bridge.h 2016-04-02 19:17:52.096066035 -0300 +@@ -0,0 +1,122 @@ ++#ifndef __I2C_BRIDGE_H ++#define __I2C_BRIDGE_H ++ ++/** ++ ++@file ++ ++@brief I2C bridge module ++ ++I2C bridge module contains I2C forwarding function pointers. ++ ++*/ ++ ++ ++ ++ ++ ++/// I2C bridge module pre-definition ++typedef struct I2C_BRIDGE_MODULE_TAG I2C_BRIDGE_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief I2C reading command forwarding function pointer ++ ++Tuner upper level functions will use I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD() to send tuner I2C reading command through ++demod. ++ ++ ++@param [in] pI2cBridge The I2C bridge module pointer ++@param [in] DeviceAddr I2C device address in 8-bit format ++@param [out] pReadingBytes Pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Forwarding I2C reading command successfully. ++@retval FUNCTION_ERROR Forwarding I2C reading command unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD() with the corresponding function. ++ ++*/ ++typedef int ++(*I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD)( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief I2C writing command forwarding function pointer ++ ++Tuner upper level functions will use I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD() to send tuner I2C writing command through ++demod. ++ ++ ++@param [in] pI2cBridge The I2C bridge module pointer ++@param [in] DeviceAddr I2C device address in 8-bit format ++@param [out] pWritingBytes Pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Forwarding I2C writing command successfully. ++@retval FUNCTION_ERROR Forwarding I2C writing command unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD() with the corresponding function. ++ ++*/ ++typedef int ++(*I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD)( ++ I2C_BRIDGE_MODULE *pI2cBridge, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/// I2C bridge module structure ++struct I2C_BRIDGE_MODULE_TAG ++{ ++ // Private variables ++ void *pPrivateData; ++ ++ ++ // I2C bridge function pointers ++ I2C_BRIDGE_FP_FORWARD_I2C_READING_CMD ForwardI2cReadingCmd; ///< I2C reading command forwading function pointer ++ I2C_BRIDGE_FP_FORWARD_I2C_WRITING_CMD ForwardI2cWritingCmd; ///< I2C writing command forwading function pointer ++ ++}; ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/math_mpi.c b/drivers/drivers/media/dvb/dvb-usb/math_mpi.c +--- a/drivers/media/dvb/dvb-usb/math_mpi.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/math_mpi.c 2016-04-02 19:17:52.096066035 -0300 +@@ -0,0 +1,1054 @@ ++/** ++ ++@file ++ ++@brief Mutliple precision integer (MPI) arithmetic definition ++ ++One can use to mutliple precision arithmetic to manipulate large signed integers. ++ ++*/ ++ ++ ++#include "math_mpi.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief Set multiple precision signed integer value. ++ ++Use MpiSetValue() to set multiple precision signed integer MPI value. ++ ++ ++@param [in] pMpiVar Pointer to an MPI variable ++@param [in] Value Value for setting ++ ++ ++@note ++ The MPI bit number will be minimized in MpiSetValue(). ++ ++*/ ++void ++MpiSetValue( ++ MPI *pMpiVar, ++ long Value ++ ) ++{ ++ int i; ++ unsigned char SignedBit; ++ unsigned char ExtensionByte; ++ ++ ++ ++ // Set MPI value according to ansigned value. ++ for(i = 0; i < MPI_LONG_BYTE_NUM; i++) ++ pMpiVar->Value[i] = (unsigned char)((Value >> (MPI_BYTE_SHIFT * i)) & MPI_BYTE_MASK); ++ ++ ++ // Get extension byte according to signed bit. ++ SignedBit = (unsigned char)((Value >> (MPI_LONG_BIT_NUM - 1)) & MPI_BIT_0_MASK); ++ ExtensionByte = (SignedBit == 0x0) ? 0x00 : 0xff; ++ ++ ++ // Extend MPI signed bit with extension byte stuff. ++ for(i = MPI_LONG_BYTE_NUM; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ pMpiVar->Value[i] = ExtensionByte; ++ ++ ++ // Minimize MPI bit number. ++ MpiMinimizeBitNum(pMpiVar); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get multiple precision signed integer value. ++ ++Use MpiGetValue() to get multiple precision unsigned integer MPI value. ++ ++ ++@param [in] MpiVar Pointer to an MPI variable ++@param [out] pValue Pointer to an allocated memory for getting MPI value ++ ++ ++@note ++ The necessary bit number of MPI value must be less than or equal to 32 bits. ++ ++*/ ++void ++MpiGetValue( ++ MPI MpiVar, ++ long *pValue ++ ) ++{ ++ int i; ++ unsigned long Value; ++ ++ ++ ++ // Set value with zero. ++ Value = 0x0; ++ ++ ++ // Combine MPI value bytes into value. ++ for(i = 0; i < MPI_LONG_BYTE_NUM; i++) ++ Value |= MpiVar.Value[i] << (MPI_BYTE_SHIFT * i); ++ ++ ++ // Assigned value to value pointer. ++ *pValue = (long)Value; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set multiple precision signed integer bit value. ++ ++Use MpiSetBit() to set multiple precision signed integer MPI bit value. ++ ++ ++@param [in] pMpiVar Pointer to an MPI variable ++@param [in] BitPosition Bit position with zero-based index ++@param [in] BitValue Bit value for setting ++ ++ ++@note ++ Bit position must be 0 ~ (MPI bit number). ++ ++*/ ++void ++MpiSetBit( ++ MPI *pMpiVar, ++ unsigned long BitPosition, ++ unsigned char BitValue ++ ) ++{ ++ unsigned long TargetBytePos, TargetBitPos; ++ ++ ++ ++ // Calculate target byte and bit position. ++ TargetBytePos = BitPosition / MPI_BYTE_BIT_NUM; ++ TargetBitPos = BitPosition % MPI_BYTE_BIT_NUM; ++ ++ ++ // Set MPI bit value according to calculated target byte and bit position. ++ pMpiVar->Value[TargetBytePos] &= (unsigned char)(~(0x1 << TargetBitPos)); ++ pMpiVar->Value[TargetBytePos] |= (BitValue & MPI_BIT_0_MASK) << TargetBitPos; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++/** ++ ++@brief Get multiple precision signed integer bit value. ++ ++Use MpiGetBit() to get multiple precision unsigned integer MPI bit value. ++ ++ ++@param [in] MpiVar Pointer to an MPI variable ++@param [in] BitPosition Bit position with zero-based index ++@param [out] pBitValue Pointer to an allocated memory for getting MPI bit value ++ ++ ++@note ++ Bit position must be 0 ~ (MPI bit number). ++ ++*/ ++void ++MpiGetBit( ++ MPI MpiVar, ++ unsigned long BitPosition, ++ unsigned char *pBitValue ++ ) ++{ ++ unsigned long TargetBytePos, TargetBitPos; ++ ++ ++ ++ // Calculate target byte and bit position. ++ TargetBytePos = BitPosition / MPI_BYTE_BIT_NUM; ++ TargetBitPos = BitPosition % MPI_BYTE_BIT_NUM; ++ ++ ++ // Get MPI bit value according to calculated target byte and bit position. ++ *pBitValue = (MpiVar.Value[TargetBytePos] >> TargetBitPos) & MPI_BIT_0_MASK; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get multiple precision signed integer signed bit value. ++ ++Use MpiGetBit() to get multiple precision unsigned integer MPI signed bit value. ++ ++ ++@param [in] MpiVar Pointer to an MPI variable ++@param [out] pSignedBitValue Pointer to an allocated memory for getting MPI signed bit value ++ ++*/ ++void ++MpiGetSignedBit( ++ MPI MpiVar, ++ unsigned char *pSignedBitValue ++ ) ++{ ++ // Get MPI variable signed bit. ++ MpiGetBit(MpiVar, MPI_VALUE_BIT_NUM_MAX - 1, pSignedBitValue); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Assign multiple precision signed integer with another one. ++ ++Use MpiAssign() to assign multiple precision signed integer with another one. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result ++@param [in] Operand Operand ++ ++ ++@note ++ The result bit number will be minimized in MpiAssign(). ++ ++*/ ++void ++MpiAssign( ++ MPI *pResult, ++ MPI Operand ++ ) ++{ ++ unsigned int i; ++ ++ ++ ++ // Copy value bytes from operand to result. ++ for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ pResult->Value[i] = Operand.Value[i]; ++ ++ ++ // Minimize result bit nubmer. ++ MpiMinimizeBitNum(pResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Minus unary multiple precision signed integer. ++ ++Use MpiUnaryMinus() to minus unary multiple precision signed integer. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result ++@param [in] Operand Operand ++ ++ ++@note ++ The result bit number will be minimized in MpiUnaryMinus(). ++ ++*/ ++void ++MpiUnaryMinus( ++ MPI *pResult, ++ MPI Operand ++ ) ++{ ++ unsigned int i; ++ MPI Const; ++ ++ ++ ++ // Set result value byte with operand bitwise complement value byte. ++ for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ pResult->Value[i] = ~Operand.Value[i]; ++ ++ ++ // Add result with 0x1. ++ // Note: MpiAdd() will minimize result bit number. ++ MpiSetValue(&Const, 0x1); ++ MpiAdd(pResult, *pResult, Const); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Add multiple precision signed integers. ++ ++Use MpiAdd() to add multiple precision signed integers. ++ ++ ++@param [out] pSum Pointer to an allocated memory for storing sum ++@param [in] Augend Augend ++@param [in] Addend Addend ++ ++ ++@note ++ The sum bit number will be minimized in MpiAdd(). ++ ++*/ ++void ++MpiAdd( ++ MPI *pSum, ++ MPI Augend, ++ MPI Addend ++ ) ++{ ++ unsigned int i; ++ unsigned long MiddleResult; ++ unsigned char Carry; ++ ++ ++ // Add augend and addend to sum form value LSB byte to value MSB byte. ++ Carry = 0; ++ ++ for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ { ++ // Set current sum value byte and determine carry. ++ MiddleResult = Augend.Value[i] + Addend.Value[i] + Carry; ++ pSum->Value[i] = (unsigned char)(MiddleResult & MPI_BYTE_MASK); ++ Carry = (unsigned char)((MiddleResult >> MPI_BYTE_SHIFT) & MPI_BYTE_MASK); ++ } ++ ++ ++ // Minimize sum bit nubmer. ++ MpiMinimizeBitNum(pSum); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief subtract multiple precision signed integers. ++ ++Use MpiSub() to subtract multiple precision signed integers. ++ ++ ++@param [out] pDifference Pointer to an allocated memory for storing difference ++@param [in] Minuend Minuend ++@param [in] Subtrahend Subtrahend ++ ++ ++@note ++ The difference bit number will be minimized in MpiSub(). ++ ++*/ ++void ++MpiSub( ++ MPI *pDifference, ++ MPI Minuend, ++ MPI Subtrahend ++ ) ++{ ++ MPI MiddleResult; ++ ++ ++ ++ // Take subtrahend unary minus value. ++ MpiUnaryMinus(&MiddleResult, Subtrahend); ++ ++ ++ // Add minuend and subtrahend unary minus value to difference. ++ // Note: MpiAdd() will minimize result bit number. ++ MpiAdd(pDifference, Minuend, MiddleResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Multiply arbitrary precision signed integers. ++ ++Use MpiMul() to multiply arbitrary precision signed integers. ++ ++ ++@param [out] pProduct Pointer to an allocated memory for storing product ++@param [in] Multiplicand Multiplicand ++@param [in] Multiplicator Multiplicator ++ ++ ++@note ++ -# The sum of multiplicand and multiplicator bit number must be less MPI_VALUE_BIT_NUM_MAX. ++ -# The product bit number will be minimized in MpiMul(). ++ ++*/ ++void ++MpiMul( ++ MPI *pProduct, ++ MPI Multiplicand, ++ MPI Multiplicator ++ ) ++{ ++ int i; ++ ++ unsigned char MultiplicandSignedBit, MultiplicatorSignedBit; ++ MPI MultiplicandAbs, MultiplicatorAbs; ++ ++ unsigned char CurrentBit; ++ ++ ++ ++ // Get multiplicand signed bit. ++ MpiGetSignedBit(Multiplicand, &MultiplicandSignedBit); ++ ++ // Take absolute value of multiplicand. ++ if(MultiplicandSignedBit == 0x0) ++ MpiAssign(&MultiplicandAbs, Multiplicand); ++ else ++ MpiUnaryMinus(&MultiplicandAbs, Multiplicand); ++ ++ ++ // Get multiplicator signed bit. ++ MpiGetSignedBit(Multiplicator, &MultiplicatorSignedBit); ++ ++ // Take absolute value of multiplicator. ++ if(MultiplicatorSignedBit == 0x0) ++ MpiAssign(&MultiplicatorAbs, Multiplicator); ++ else ++ MpiUnaryMinus(&MultiplicatorAbs, Multiplicator); ++ ++ ++ // Multiply multiplicand and multiplicator from LSB bit to MSB bit. ++ MpiSetValue(pProduct, 0x0); ++ ++ for(i = MPI_VALUE_BIT_NUM_MAX - 1; i > -1; i--) ++ { ++ // Shift product toward left with one bit. ++ MpiLeftShift(pProduct, *pProduct, 1); ++ ++ // Get current absolute multiplicator bit value. ++ MpiGetBit(MultiplicatorAbs, i, &CurrentBit); ++ ++ // If current multiplicator bit is 0x1, add absolute multiplicand value to product. ++ // Note: MpiAdd() will minimize result bit number. ++ if(CurrentBit == 0x1) ++ MpiAdd(pProduct, *pProduct, MultiplicandAbs); ++ } ++ ++ ++ // Determine the signed bit of product according to signed bits of multiplicand and multiplicator. ++ // Note: MpiUnaryMinus() will minimize result bit number. ++ if(MultiplicandSignedBit != MultiplicatorSignedBit) ++ MpiUnaryMinus(pProduct, *pProduct); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Divide arbitrary precision signed integers. ++ ++Use MpiDiv() to divide arbitrary precision signed integers. ++ ++ ++@param [out] pQuotient Pointer to an allocated memory for storing quotient ++@param [out] pRemainder Pointer to an allocated memory for storing remainder ++@param [in] Dividend Dividend ++@param [in] Divisor Divisor ++ ++ ++@note ++ -# The dividend bit number must be minimized. ++ -# The divisor must be not equal to zero. ++ -# The product bit number will be minimized in MpiDiv(). ++ ++*/ ++void ++MpiDiv( ++ MPI *pQuotient, ++ MPI *pRemainder, ++ MPI Dividend, ++ MPI Divisor ++ ) ++{ ++ unsigned int i; ++ ++ unsigned char DividendSignedBit, DivisorSignedBit; ++ MPI DividendAbs, DivisorAbs; ++ ++ unsigned long PrimaryDividendBitNum; ++ unsigned char ShiftBit; ++ ++ MPI Const; ++ MPI MiddleResult; ++ ++ ++ ++ // Get dividend signed bit. ++ MpiGetSignedBit(Dividend, &DividendSignedBit); ++ ++ // Take absolute value of dividend. ++ if(DividendSignedBit == 0x0) ++ MpiAssign(&DividendAbs, Dividend); ++ else ++ MpiUnaryMinus(&DividendAbs, Dividend); ++ ++ ++ // Get divisor signed bit. ++ MpiGetSignedBit(Divisor, &DivisorSignedBit); ++ ++ // Take absolute value of divisor. ++ if(DivisorSignedBit == 0x0) ++ MpiAssign(&DivisorAbs, Divisor); ++ else ++ MpiUnaryMinus(&DivisorAbs, Divisor); ++ ++ ++ // Get primary absolute dividend bit number. ++ PrimaryDividendBitNum = DividendAbs.BitNum; ++ ++ ++ // Get quotient and remainder by division algorithm. ++ MpiSetValue(pQuotient, 0x0); ++ MpiSetValue(pRemainder, 0x0); ++ ++ for(i = 0; i < PrimaryDividendBitNum; i++) ++ { ++ // Shift quotient toward left with one bit. ++ // Note: MpiLeftShift() will minimize result bit number. ++ MpiLeftShift(pQuotient, *pQuotient, 1); ++ ++ // Shift remainder toward left with one bit. ++ MpiLeftShift(pRemainder, *pRemainder, 1); ++ ++ // Shift absolute dividend toward left with one bit. ++ MpiLeftShift(&DividendAbs, DividendAbs, 1); ++ ++ // Set remainder LSB according to absolute dividend. ++ MpiGetBit(DividendAbs, PrimaryDividendBitNum, &ShiftBit); ++ MpiSetBit(pRemainder, 0, ShiftBit); ++ ++ // If remainder is greater than or equal to absolute divisor, ++ // substract absolute divisor from remainder and set quotient LSB with one. ++ if(MpiGreaterThan(*pRemainder, DivisorAbs) || MpiEqualTo(*pRemainder, DivisorAbs)) ++ { ++ MpiSub(pRemainder, *pRemainder, DivisorAbs); ++ MpiSetBit(pQuotient, 0, 0x1); ++ } ++ } ++ ++ ++ // Modify quotient according to dividend signed bit, divisor signed bit, and remainder. ++ ++ // Determine the signed bit of quotient. ++ if(DividendSignedBit != DivisorSignedBit) ++ { ++ // Take unary minus quotient. ++ // Note: MpiUnaryMinus() will minimize result bit number. ++ MpiUnaryMinus(pQuotient, *pQuotient); ++ ++ // If remainder is greater than zero, subtract 1 from quotient. ++ // Note: MpiSub() will minimize result bit number. ++ MpiSetValue(&Const, 0x0); ++ ++ if(MpiGreaterThan(*pRemainder, Const)) ++ { ++ MpiSetValue(&Const, 0x1); ++ MpiSub(pQuotient, *pQuotient, Const); ++ } ++ } ++ ++ ++ // Modify remainder according to dividend, divisor, and quotient. ++ ++ // Remainder = dividend - divisor * quotient; ++ // Note: MpiSub() will minimize result bit number. ++ MpiMul(&MiddleResult, Divisor, *pQuotient); ++ MpiSub(pRemainder, Dividend, MiddleResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Shift multiple precision signed integer toward right. ++ ++Use MpiRightShift() to shift arbitrary precision signed integer toward right with assigned bit number. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result ++@param [in] Operand Operand ++@param [in] ShiftBitNum Shift bit number ++ ++ ++@note ++ -# The result MSB bits will be stuffed with signed bit ++ -# The result bit number will be minimized in MpiRightShift(). ++ ++*/ ++void ++MpiRightShift( ++ MPI *pResult, ++ MPI Operand, ++ unsigned long ShiftBitNum ++ ) ++{ ++ unsigned int i; ++ unsigned long StuffBitNum; ++ unsigned char CurrentBit; ++ unsigned char SignedBit; ++ ++ ++ ++ // Determine stuff bit number according to shift bit nubmer. ++ StuffBitNum = (ShiftBitNum < MPI_VALUE_BIT_NUM_MAX) ? ShiftBitNum : MPI_VALUE_BIT_NUM_MAX; ++ ++ ++ // Copy operand bits to result with stuff bit number. ++ for(i = 0; i < (MPI_VALUE_BIT_NUM_MAX - StuffBitNum); i++) ++ { ++ MpiGetBit(Operand, i + StuffBitNum, &CurrentBit); ++ MpiSetBit(pResult, i, CurrentBit); ++ } ++ ++ ++ // Get operand signed bit. ++ MpiGetSignedBit(Operand, &SignedBit); ++ ++ ++ // Stuff result MSB bits with signed bit. ++ for(i = (MPI_VALUE_BIT_NUM_MAX - StuffBitNum); i < MPI_VALUE_BIT_NUM_MAX; i++) ++ MpiSetBit(pResult, i, SignedBit); ++ ++ ++ // Minimize result bit number. ++ MpiMinimizeBitNum(pResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Shift multiple precision signed integer toward left. ++ ++Use MpiLeftShift() to shift arbitrary precision signed integer toward left with assigned bit number. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result ++@param [in] Operand Operand ++@param [in] ShiftBitNum Shift bit number ++ ++ ++@note ++ The result bit number will be minimized in MpiLeftShift(). ++ ++*/ ++void ++MpiLeftShift( ++ MPI *pResult, ++ MPI Operand, ++ unsigned long ShiftBitNum ++ ) ++{ ++ unsigned int i; ++ unsigned long StuffBitNum; ++ unsigned char CurrentBit; ++ ++ ++ // Determine stuff bit number according to shift bit nubmer. ++ StuffBitNum = (ShiftBitNum < MPI_VALUE_BIT_NUM_MAX) ? ShiftBitNum : MPI_VALUE_BIT_NUM_MAX; ++ ++ ++ // Stuff result LSB bits with zeros ++ for(i = 0; i < StuffBitNum; i++) ++ MpiSetBit(pResult, i, 0x0); ++ ++ ++ // Copy operand bits to result with stuff bit number. ++ for(i = StuffBitNum; i < MPI_VALUE_BIT_NUM_MAX; i++) ++ { ++ MpiGetBit(Operand, i - StuffBitNum, &CurrentBit); ++ MpiSetBit(pResult, i, CurrentBit); ++ } ++ ++ ++ // Minimize result bit number. ++ MpiMinimizeBitNum(pResult); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Compare multiple precision signed integes with equal-to criterion. ++ ++Use MpiEqualTo() to compare multiple precision signed integes with equal-to criterion. ++ ++ ++@param [in] MpiLeft Left MPI ++@param [in] MpiRight Right MPI ++ ++ ++@retval MPI_NO "Left MPI == Right MPI" is false. ++@retval MPI_YES "Left MPI == Right MPI" is true. ++ ++ ++@note ++ The constants MPI_YES and MPI_NO are defined in MPI_YES_NO_STATUS enumeration. ++ ++*/ ++int ++MpiEqualTo( ++ MPI MpiLeft, ++ MPI MpiRight ++ ) ++{ ++ unsigned int i; ++ ++ ++ ++ // Check not-equal-to condition. ++ for(i = 0; i < MPI_VALUE_BYTE_NUM_MAX; i++) ++ { ++ if(MpiLeft.Value[i] != MpiRight.Value[i]) ++ goto condition_others; ++ } ++ ++ ++ // Right MPI is greater than left MPI. ++ return MPI_YES; ++ ++ ++condition_others: ++ ++ ++ // Other conditions. ++ return MPI_NO; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Compare multiple precision signed integes with greater-than criterion. ++ ++Use MpiGreaterThan() to compare multiple precision signed integes with greater-than criterion. ++ ++ ++@param [in] MpiLeft Left MPI ++@param [in] MpiRight Right MPI ++ ++ ++@retval MPI_NO "Left MPI > Right MPI" is false. ++@retval MPI_YES "Left MPI > Right MPI" is true. ++ ++ ++@note ++ The constants MPI_YES and MPI_NO are defined in MPI_YES_NO_STATUS enumeration. ++ ++*/ ++int ++MpiGreaterThan( ++ MPI MpiLeft, ++ MPI MpiRight ++ ) ++{ ++ MPI MiddleResult; ++ unsigned char SignedBit; ++ ++ ++ ++ // Check equal-to condition. ++ if(MpiEqualTo(MpiLeft, MpiRight) == MPI_YES) ++ goto condition_others; ++ ++ ++ // Subtract right MPI form left MPI. ++ MpiSub(&MiddleResult, MpiLeft, MpiRight); ++ ++ ++ // Check less-than condition. ++ MpiGetSignedBit(MiddleResult, &SignedBit); ++ ++ if(SignedBit == 0x1) ++ goto condition_others; ++ ++ ++ // Right MPI is greater than left MPI. ++ return MPI_YES; ++ ++ ++condition_others: ++ ++ ++ // Other conditions. ++ return MPI_NO; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Compare multiple precision signed integes with less-than criterion. ++ ++Use MpiLessThan() to compare multiple precision signed integes with less-than criterion. ++ ++ ++@param [in] MpiLeft Left MPI ++@param [in] MpiRight Right MPI ++ ++ ++@retval MPI_NO "Left MPI < Right MPI" is false. ++@retval MPI_YES "Left MPI < Right MPI" is true. ++ ++ ++@note ++ The constants MPI_YES and MPI_NO are defined in MPI_YES_NO_STATUS enumeration. ++ ++*/ ++int ++MpiLessThan( ++ MPI MpiLeft, ++ MPI MpiRight ++ ) ++{ ++ MPI MiddleResult; ++ unsigned char SignedBit; ++ ++ ++ ++ // Check equal-to condition. ++ if(MpiEqualTo(MpiLeft, MpiRight) == MPI_YES) ++ goto condition_others; ++ ++ ++ // Subtract right MPI form left MPI. ++ MpiSub(&MiddleResult, MpiLeft, MpiRight); ++ ++ ++ // Check greater-than condition. ++ MpiGetSignedBit(MiddleResult, &SignedBit); ++ ++ if(SignedBit == 0x0) ++ goto condition_others; ++ ++ ++ // Right MPI is less than left MPI. ++ return MPI_YES; ++ ++ ++condition_others: ++ ++ ++ // Other conditions. ++ return MPI_NO; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Minimize multiple precision signed integer bit number. ++ ++Use MpiMinimizeBitNum() to minimize multiple precision signed integer MPI bit number. ++ ++ ++@param [in] pMpiVar Pointer to an allocated memory for storing result ++ ++*/ ++void ++MpiMinimizeBitNum( ++ MPI *pMpiVar ++ ) ++{ ++ int i; ++ unsigned char SignedBit; ++ unsigned char BitValue; ++ ++ ++ ++ // Get signed bit form MPI; ++ MpiGetSignedBit(*pMpiVar, &SignedBit); ++ ++ ++ // Find MPI MSB position. ++ // Note: The MSB of signed integer is the rightest signed bit. ++ for(i = (MPI_VALUE_BIT_NUM_MAX - 2); i > -1; i--) ++ { ++ // Get current bit value. ++ MpiGetBit(*pMpiVar, i, &BitValue); ++ ++ // Compare current bit with signed bit. ++ if(BitValue != SignedBit) ++ break; ++ } ++ ++ ++ // Set MPI bit number. ++ // Note: MPI bit number must be greater than one. ++ pMpiVar->BitNum = (i == -1) ? 2 : (i + 2); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++/** ++ ++@brief Calculate multiple precision signed integer logarithm with base 2. ++ ++Use MpiMinimizeBitNum() to calculate multiple precision signed integer logarithm with base 2. ++ ++ ++@param [out] pResult Pointer to an allocated memory for storing result (unit: pow(2, - ResultFracBitNum)) ++@param [in] MpiVar MPI variable for calculating ++@param [in] ResultFracBitNum Result fraction bit number ++ ++ ++@note ++ -# MPI variable bit number must be minimized. ++ -# MPI variable bit number must be less than (MPI_VALUE_BIT_NUM_MAX / 2 + 1). ++ -# MPI variable must be greater than zero. ++ -# If MPI variable is zero, the result is zero in MpiLog2(). ++ -# The result bit number will be minimized in MpiLog2(). ++ ++*/ ++void ++MpiLog2( ++ MPI *pResult, ++ MPI MpiVar, ++ unsigned long ResultFracBitNum ++ ) ++{ ++ unsigned int i; ++ MPI MiddleResult; ++ unsigned char BitValue; ++ ++ ++ ++ // Get integer part of MPI logarithm result with base 2. ++ MpiSetValue(pResult, (long)(MpiVar.BitNum - 2)); ++ ++ ++ // Get fraction part of MPI logarithm result with base 2 by logarithm algorithm. ++ // Note: Take middle result format as follows: ++ // x x . x x ~ x ++ // (integer part 2 bits) . (fraction part MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM bits) ++ ++ // Set middle result with initial value. ++ MpiLeftShift(&MiddleResult, MpiVar, (MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM - MpiVar.BitNum + 2)); ++ ++ // Calculate result fraction bits. ++ for(i = 0; i < ResultFracBitNum; i++) ++ { ++ // Shift result toward left with one bit. ++ // Note: MpiLeftShift() will minimize result bit number. ++ MpiLeftShift(pResult, *pResult, 1); ++ ++ // Square middle result. ++ MpiMul(&MiddleResult, MiddleResult, MiddleResult); ++ ++ // Shift middle result toward right with fraction bit num. ++ MpiRightShift(&MiddleResult, MiddleResult, MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM); ++ ++ // Get middle result integer part bit 1. ++ MpiGetBit(MiddleResult, MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM + 1, &BitValue); ++ ++ // If middle result integer part bit 1 is equal to 0x1, ++ // shift middle result with one bit toward right and set result LSB with one. ++ if(BitValue == 0x1) ++ { ++ MpiRightShift(&MiddleResult, MiddleResult, 1); ++ MpiSetBit(pResult, 0, 0x1); ++ } ++ } ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/math_mpi.h b/drivers/drivers/media/dvb/dvb-usb/math_mpi.h +--- a/drivers/media/dvb/dvb-usb/math_mpi.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/math_mpi.h 2016-04-02 19:17:52.096066035 -0300 +@@ -0,0 +1,201 @@ ++#ifndef __MATH_MPI_H ++#define __MATH_MPI_H ++ ++/** ++ ++@file ++ ++@brief Mutliple precision integer (MPI) arithmetic declaration ++ ++One can use to mutliple precision arithmetic to manipulate large signed integers. ++ ++*/ ++ ++ ++ ++ ++ ++// Constant ++#define MPI_BYTE_BIT_NUM 8 ++#define MPI_LONG_BYTE_NUM 4 ++#define MPI_LONG_BIT_NUM 32 ++ ++ ++ ++// Mask and shift ++#define MPI_BYTE_MASK 0xff ++#define MPI_BYTE_SHIFT 8 ++ ++#define MPI_BIT_0_MASK 0x1 ++#define MPI_BIT_7_SHIFT 7 ++ ++ ++ ++// Multiple precision integer definition ++#define MPI_VALUE_BYTE_NUM_MAX 10 ///< Maximum MPI value byte number ++#define MPI_VALUE_BIT_NUM_MAX (MPI_VALUE_BYTE_NUM_MAX * MPI_BYTE_BIT_NUM) ///< Maximum MPI value bit number ++ ++/// Multiple precision integer structure ++typedef struct ++{ ++ unsigned long BitNum; ++ unsigned char Value[MPI_VALUE_BYTE_NUM_MAX]; ++} ++MPI; ++ ++ ++ ++/// MPI yes/no status ++enum MPI_YES_NO_STATUS ++{ ++ MPI_NO, ///< No ++ MPI_YES, ///< Yes ++}; ++ ++ ++ ++// Logarithm with base 2 ++#define MPI_LOG_MIDDLE_RESULT_FRAC_BIT_NUM (MPI_VALUE_BIT_NUM_MAX / 2 - 2) ++ ++ ++ ++ ++ ++// MPI access ++void ++MpiSetValue( ++ MPI *pMpiVar, ++ long Value ++ ); ++ ++void ++MpiGetValue( ++ MPI MpiVar, ++ long *pValue ++ ); ++ ++void ++MpiSetBit( ++ MPI *pMpiVar, ++ unsigned long BitPosition, ++ unsigned char BitValue ++ ); ++ ++void ++MpiGetBit( ++ MPI MpiVar, ++ unsigned long BitPosition, ++ unsigned char *pBitValue ++ ); ++ ++void ++MpiGetSignedBit( ++ MPI MpiVar, ++ unsigned char *pSignedBit ++ ); ++ ++ ++ ++// MPI operator ++void ++MpiAssign( ++ MPI *pResult, ++ MPI Operand ++ ); ++ ++void ++MpiUnaryMinus( ++ MPI *pResult, ++ MPI Operand ++ ); ++ ++void ++MpiAdd( ++ MPI *pSum, ++ MPI Augend, ++ MPI Addend ++ ); ++ ++void ++MpiSub( ++ MPI *pDifference, ++ MPI Minuend, ++ MPI Subtrahend ++ ); ++ ++void ++MpiMul( ++ MPI *pProduct, ++ MPI Multiplicand, ++ MPI Multiplicator ++ ); ++ ++void ++MpiDiv( ++ MPI *pQuotient, ++ MPI *pRemainder, ++ MPI Dividend, ++ MPI Divisor ++ ); ++ ++void ++MpiRightShift( ++ MPI *pResult, ++ MPI Operand, ++ unsigned long ShiftBitNum ++ ); ++ ++void ++MpiLeftShift( ++ MPI *pResult, ++ MPI Operand, ++ unsigned long ShiftBitNum ++ ); ++ ++int ++MpiEqualTo( ++ MPI MpiLeft, ++ MPI MpiRight ++ ); ++ ++int ++MpiGreaterThan( ++ MPI MpiLeft, ++ MPI MpiRight ++ ); ++ ++int ++MpiLessThan( ++ MPI MpiLeft, ++ MPI MpiRight ++ ); ++ ++void ++MpiMinimizeBitNum( ++ MPI *pMpiVar ++ ); ++ ++ ++ ++// MPI special function ++void ++MpiLog2( ++ MPI *pResult, ++ MPI MpiVar, ++ unsigned long ResultFracBitNum ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.c 2016-04-02 19:17:52.096066035 -0300 +@@ -0,0 +1,1001 @@ ++/** ++ ++@file ++ ++@brief RTL2832 E4000 NIM module definition ++ ++One can manipulate RTL2832 E4000 NIM through RTL2832 E4000 NIM module. ++RTL2832 E4000 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_e4000.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 E4000 NIM module builder ++ ++Use BuildRtl2832E4000Module() to build RTL2832 E4000 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 E4000 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr E4000 I2C device address ++@param [in] TunerCrystalFreqHz E4000 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2832E4000Module() to build RTL2832 E4000 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832E4000Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ RTL2832_E4000_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832E4000); ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_E4000; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build E4000 tuner module. ++ BuildE4000Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_e4000_Initialize; ++ pNim->SetParameters = rtl2832_e4000_SetParameters; ++ pNim->UpdateFunction = rtl2832_e4000_UpdateFunction; ++ ++ ++ // Initialize NIM extra module variables. ++ pNimExtra->TunerModeUpdateWaitTimeMax = ++ DivideWithCeiling(RTL2832_E4000_TUNER_MODE_UPDATE_WAIT_TIME_MS, DemodUpdateFuncRefPeriodMs); ++ pNimExtra->TunerModeUpdateWaitTime = 0; ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_NORMAL; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_e4000_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_E4000_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x5a }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x18 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x8 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x18 }, ++ ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ {DVBT_EN_GI_PGA, 0x0 }, ++ {DVBT_THD_LOCK_UP, 0x0 }, ++ {DVBT_THD_LOCK_DW, 0x0 }, ++ {DVBT_THD_UP1, 0x14 }, ++ {DVBT_THD_DW1, 0xec }, ++ ++ {DVBT_INTER_CNT_LEN, 0xc }, ++ {DVBT_GI_PGA_STATE, 0x0 }, ++ {DVBT_EN_AGC_PGA, 0x1 }, ++ ++ {DVBT_REG_GPE, 0x1 }, ++ {DVBT_REG_GPO, 0x1 }, ++ {DVBT_REG_MONSEL, 0x1 }, ++ {DVBT_REG_MON, 0x1 }, ++ {DVBT_REG_4MSEL, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_E4000_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++int ++rtl2832_e4000_Initialize_fm( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_E4000_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x5a }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x18 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x8 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x18 }, ++ ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ {DVBT_EN_GI_PGA, 0x0 }, ++ {DVBT_THD_LOCK_UP, 0x0 }, ++ {DVBT_THD_LOCK_DW, 0x0 }, ++ {DVBT_THD_UP1, 0x14 }, ++ {DVBT_THD_DW1, 0xec }, ++ ++ {DVBT_INTER_CNT_LEN, 0xc }, ++ {DVBT_GI_PGA_STATE, 0x0 }, ++ {DVBT_EN_AGC_PGA, 0x1 }, ++ ++ {DVBT_REG_GPE, 0x1 }, ++ {DVBT_REG_GPO, 0x1 }, ++ {DVBT_REG_MONSEL, 0x1 }, ++ {DVBT_REG_MON, 0x1 }, ++ {DVBT_REG_4MSEL, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ //if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ // goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ //if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ // goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ //if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ // goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_E4000_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_e4000_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ E4000_EXTRA_MODULE *pTunerExtra; ++ RTL2832_E4000_EXTRA_MODULE *pNimExtra; ++ ++ unsigned long TunerBandwidthHz; ++ ++ int RfFreqKhz; ++ int BandwidthKhz; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.E4000); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832E4000); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS)//added by annie ++ goto error_status_execute_function; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthHz according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthHz = E4000_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthHz = E4000_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthHz = E4000_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth Hz with TunerBandwidthHz. ++ if(pTunerExtra->SetBandwidthHz(pTuner, TunerBandwidthHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner gain mode with normal condition for update procedure. ++ RfFreqKhz = (int)((RfFreqHz + 500) / 1000); ++ BandwidthKhz = (int)((TunerBandwidthHz + 500) / 1000); ++ ++ if(E4000_nominal(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++// if(E4000_sensitivity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++// if(E4000_linearity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_NORMAL; ++ ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++int ++rtl2832_e4000_SetParameters_fm( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ E4000_EXTRA_MODULE *pTunerExtra; ++ RTL2832_E4000_EXTRA_MODULE *pNimExtra; ++ ++ unsigned long TunerBandwidthHz; ++ ++ int RfFreqKhz; ++ int BandwidthKhz; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.E4000); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832E4000); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS)//added by annie ++ goto error_status_execute_function; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthHz according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthHz = E4000_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthHz = E4000_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthHz = E4000_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth Hz with TunerBandwidthHz. ++ if(pTunerExtra->SetBandwidthHz(pTuner, TunerBandwidthHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner gain mode with normal condition for update procedure. ++ RfFreqKhz = (int)((RfFreqHz + 500) / 1000); ++ BandwidthKhz = (int)((TunerBandwidthHz + 500) / 1000); ++ ++ if(E4000_nominal(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS)//change by annie ++// if(E4000_sensitivity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++// if(E4000_linearity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_NORMAL; ++ ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++/** ++ ++@see DVBT_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2832_e4000_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ RTL2832_E4000_EXTRA_MODULE *pNimExtra; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832E4000); ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Increase tuner mode update waiting time. ++ pNimExtra->TunerModeUpdateWaitTime += 1; ++ ++ ++ // Check if need to update tuner mode according to update waiting time. ++ if(pNimExtra->TunerModeUpdateWaitTime == pNimExtra->TunerModeUpdateWaitTimeMax) ++ { ++ // Reset update waiting time. ++ pNimExtra->TunerModeUpdateWaitTime = 0; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Update tuner mode. ++ if(rtl2832_e4000_UpdateTunerMode(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update tuner mode. ++ ++One can use rtl2832_e4000_UpdateTunerMode() to update tuner mode. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update tuner mode successfully. ++@retval FUNCTION_ERROR Update tuner mode unsuccessfully. ++ ++*/ ++int ++rtl2832_e4000_UpdateTunerMode( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ static const long LnaGainTable[RTL2832_E4000_LNA_GAIN_TABLE_LEN][RTL2832_E4000_LNA_GAIN_BAND_NUM] = ++ { ++ // VHF Gain, UHF Gain, ReadingByte ++ {-50, -50 }, // 0x0 ++ {-25, -25 }, // 0x1 ++ {-50, -50 }, // 0x2 ++ {-25, -25 }, // 0x3 ++ {0, 0 }, // 0x4 ++ {25, 25 }, // 0x5 ++ {50, 50 }, // 0x6 ++ {75, 75 }, // 0x7 ++ {100, 100 }, // 0x8 ++ {125, 125 }, // 0x9 ++ {150, 150 }, // 0xa ++ {175, 175 }, // 0xb ++ {200, 200 }, // 0xc ++ {225, 250 }, // 0xd ++ {250, 280 }, // 0xe ++ {250, 280 }, // 0xf ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long LnaGainAddTable[RTL2832_E4000_LNA_GAIN_ADD_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ NO_USE, // 0x0 ++ NO_USE, // 0x1 ++ NO_USE, // 0x2 ++ 0, // 0x3 ++ NO_USE, // 0x4 ++ 20, // 0x5 ++ NO_USE, // 0x6 ++ 70, // 0x7 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long MixerGainTable[RTL2832_E4000_MIXER_GAIN_TABLE_LEN][RTL2832_E4000_MIXER_GAIN_BAND_NUM] = ++ { ++ // VHF Gain, UHF Gain, ReadingByte ++ {90, 40 }, // 0x0 ++ {170, 120 }, // 0x1 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage1GainTable[RTL2832_E4000_IF_STAGE_1_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ -30, // 0x0 ++ 60, // 0x1 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage2GainTable[RTL2832_E4000_IF_STAGE_2_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 30, // 0x1 ++ 60, // 0x2 ++ 90, // 0x3 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage3GainTable[RTL2832_E4000_IF_STAGE_3_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 30, // 0x1 ++ 60, // 0x2 ++ 90, // 0x3 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage4GainTable[RTL2832_E4000_IF_STAGE_4_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 10, // 0x1 ++ 20, // 0x2 ++ 20, // 0x3 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage5GainTable[RTL2832_E4000_IF_STAGE_5_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 30, // 0x1 ++ 60, // 0x2 ++ 90, // 0x3 ++ 120, // 0x4 ++ 120, // 0x5 ++ 120, // 0x6 ++ 120, // 0x7 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ static const long IfStage6GainTable[RTL2832_E4000_IF_STAGE_6_GAIN_TABLE_LEN] = ++ { ++ // Gain, ReadingByte ++ 0, // 0x0 ++ 30, // 0x1 ++ 60, // 0x2 ++ 90, // 0x3 ++ 120, // 0x4 ++ 120, // 0x5 ++ 120, // 0x6 ++ 120, // 0x7 ++ ++ // Note: The gain unit is 0.1 dB. ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ E4000_EXTRA_MODULE *pTunerExtra; ++ RTL2832_E4000_EXTRA_MODULE *pNimExtra; ++ ++ unsigned long RfFreqHz; ++ int RfFreqKhz; ++ unsigned long BandwidthHz; ++ int BandwidthKhz; ++ ++ unsigned char ReadingByte; ++ int BandIndex; ++ ++ unsigned char TunerBitsLna, TunerBitsLnaAdd, TunerBitsMixer; ++ unsigned char TunerBitsIfStage1, TunerBitsIfStage2, TunerBitsIfStage3, TunerBitsIfStage4; ++ unsigned char TunerBitsIfStage5, TunerBitsIfStage6; ++ ++ long TunerGainLna, TunerGainLnaAdd, TunerGainMixer; ++ long TunerGainIfStage1, TunerGainIfStage2, TunerGainIfStage3, TunerGainIfStage4; ++ long TunerGainIfStage5, TunerGainIfStage6; ++ ++ long TunerGainTotal; ++ long TunerInputPower; ++ ++ ++ // Get tuner module. ++ pTuner = pNim->pTuner; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.E4000); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832E4000); ++ ++ ++ // Get tuner RF frequency in KHz. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ if(pTuner->GetRfFreqHz(pTuner, &RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ RfFreqKhz = (int)((RfFreqHz + 500) / 1000); ++ ++ // Get tuner bandwidth in KHz. ++ // Note: BandwidthKhz = round(BandwidthHz / 1000) ++ if(pTunerExtra->GetBandwidthHz(pTuner, &BandwidthHz) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ BandwidthKhz = (int)((BandwidthHz + 500) / 1000); ++ ++ ++ // Determine band index. ++ BandIndex = (RfFreqHz < RTL2832_E4000_RF_BAND_BOUNDARY_HZ) ? 0 : 1; ++ ++ ++ // Get tuner LNA gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_LNA_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsLna = (ReadingByte & RTL2832_E4000_LNA_GAIN_MASK) >> RTL2832_E4000_LNA_GAIN_SHIFT; ++ TunerGainLna = LnaGainTable[TunerBitsLna][BandIndex]; ++ ++ ++ // Get tuner LNA additional gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_LNA_GAIN_ADD_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsLnaAdd = (ReadingByte & RTL2832_E4000_LNA_GAIN_ADD_MASK) >> RTL2832_E4000_LNA_GAIN_ADD_SHIFT; ++ TunerGainLnaAdd = LnaGainAddTable[TunerBitsLnaAdd]; ++ ++ ++ // Get tuner mixer gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_MIXER_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsMixer = (ReadingByte & RTL2832_E4000_MIXER_GAIN_MASK) >> RTL2832_E4000_LNA_GAIN_ADD_SHIFT; ++ TunerGainMixer = MixerGainTable[TunerBitsMixer][BandIndex]; ++ ++ ++ // Get tuner IF stage 1 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_1_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage1 = (ReadingByte & RTL2832_E4000_IF_STAGE_1_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_1_GAIN_SHIFT; ++ TunerGainIfStage1 = IfStage1GainTable[TunerBitsIfStage1]; ++ ++ ++ // Get tuner IF stage 2 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_2_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage2 = (ReadingByte & RTL2832_E4000_IF_STAGE_2_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_2_GAIN_SHIFT; ++ TunerGainIfStage2 = IfStage2GainTable[TunerBitsIfStage2]; ++ ++ ++ // Get tuner IF stage 3 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_3_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage3 = (ReadingByte & RTL2832_E4000_IF_STAGE_3_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_3_GAIN_SHIFT; ++ TunerGainIfStage3 = IfStage3GainTable[TunerBitsIfStage3]; ++ ++ ++ // Get tuner IF stage 4 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_4_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage4 = (ReadingByte & RTL2832_E4000_IF_STAGE_4_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_4_GAIN_SHIFT; ++ TunerGainIfStage4 = IfStage4GainTable[TunerBitsIfStage4]; ++ ++ ++ // Get tuner IF stage 5 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_5_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage5 = (ReadingByte & RTL2832_E4000_IF_STAGE_5_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_5_GAIN_SHIFT; ++ TunerGainIfStage5 = IfStage5GainTable[TunerBitsIfStage5]; ++ ++ ++ // Get tuner IF stage 6 gain according to reading byte and table. ++ if(pTunerExtra->GetRegByte(pTuner, RTL2832_E4000_IF_STAGE_6_GAIN_ADDR, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ TunerBitsIfStage6 = (ReadingByte & RTL2832_E4000_IF_STAGE_6_GAIN_MASK) >> RTL2832_E4000_IF_STAGE_6_GAIN_SHIFT; ++ TunerGainIfStage6 = IfStage6GainTable[TunerBitsIfStage6]; ++ ++ ++ // Calculate tuner total gain. ++ // Note: The unit of tuner total gain is 0.1 dB. ++ TunerGainTotal = TunerGainLna + TunerGainLnaAdd + TunerGainMixer + ++ TunerGainIfStage1 + TunerGainIfStage2 + TunerGainIfStage3 + TunerGainIfStage4 + ++ TunerGainIfStage5 + TunerGainIfStage6; ++ ++ // Calculate tuner input power. ++ // Note: The unit of tuner input power is 0.1 dBm ++ TunerInputPower = RTL2832_E4000_TUNER_OUTPUT_POWER_UNIT_0P1_DBM - TunerGainTotal; ++ ++ ++ // Determine tuner gain mode according to tuner input power. ++ // Note: The unit of tuner input power is 0.1 dBm ++ switch(pNimExtra->TunerGainMode) ++ { ++ default: ++ case RTL2832_E4000_TUNER_GAIN_SENSITIVE: ++ ++ if(TunerInputPower > -650) ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_NORMAL; ++ ++ break; ++ ++ ++ case RTL2832_E4000_TUNER_GAIN_NORMAL: ++ ++ if(TunerInputPower < -750) ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_SENSITIVE; ++ ++ if(TunerInputPower > -400) ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_LINEAR; ++ ++ break; ++ ++ ++ case RTL2832_E4000_TUNER_GAIN_LINEAR: ++ ++ if(TunerInputPower < -500) ++ pNimExtra->TunerGainMode = RTL2832_E4000_TUNER_GAIN_NORMAL; ++ ++ break; ++ } ++ ++ ++ // Set tuner gain mode. ++ switch(pNimExtra->TunerGainMode) ++ { ++ default: ++ case RTL2832_E4000_TUNER_GAIN_SENSITIVE: ++ ++ if(E4000_sensitivity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ case RTL2832_E4000_TUNER_GAIN_NORMAL: ++ ++ if(E4000_nominal(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ case RTL2832_E4000_TUNER_GAIN_LINEAR: ++ ++ if(E4000_linearity(pTuner, RfFreqKhz, BandwidthKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_get_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_e4000.h 2016-04-02 19:17:52.100066046 -0300 +@@ -0,0 +1,226 @@ ++#ifndef __NIM_RTL2832_E4000 ++#define __NIM_RTL2832_E4000 ++ ++/** ++ ++@file ++ ++@brief RTL2832 E4000 NIM module declaration ++ ++One can manipulate RTL2832 E4000 NIM through RTL2832 E4000 NIM module. ++RTL2832 E4000 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_e4000.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 E4000 NIM module. ++ BuildRtl2832E4000Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc8, // The E4000 I2C device address is 0xc8 in 8-bit format. ++ CRYSTAL_FREQ_26000000HZ // The E4000 crystal frequency is 26 MHz. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_e4000.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_E4000_ADDITIONAL_INIT_REG_TABLE_LEN 34 ++ ++#define RTL2832_E4000_LNA_GAIN_TABLE_LEN 16 ++#define RTL2832_E4000_LNA_GAIN_ADD_TABLE_LEN 8 ++#define RTL2832_E4000_MIXER_GAIN_TABLE_LEN 2 ++#define RTL2832_E4000_IF_STAGE_1_GAIN_TABLE_LEN 2 ++#define RTL2832_E4000_IF_STAGE_2_GAIN_TABLE_LEN 4 ++#define RTL2832_E4000_IF_STAGE_3_GAIN_TABLE_LEN 4 ++#define RTL2832_E4000_IF_STAGE_4_GAIN_TABLE_LEN 4 ++#define RTL2832_E4000_IF_STAGE_5_GAIN_TABLE_LEN 8 ++#define RTL2832_E4000_IF_STAGE_6_GAIN_TABLE_LEN 8 ++ ++#define RTL2832_E4000_LNA_GAIN_BAND_NUM 2 ++#define RTL2832_E4000_MIXER_GAIN_BAND_NUM 2 ++ ++#define RTL2832_E4000_RF_BAND_BOUNDARY_HZ 300000000 ++ ++#define RTL2832_E4000_LNA_GAIN_ADDR 0x14 ++#define RTL2832_E4000_LNA_GAIN_MASK 0xf ++#define RTL2832_E4000_LNA_GAIN_SHIFT 0 ++ ++#define RTL2832_E4000_LNA_GAIN_ADD_ADDR 0x24 ++#define RTL2832_E4000_LNA_GAIN_ADD_MASK 0x7 ++#define RTL2832_E4000_LNA_GAIN_ADD_SHIFT 0 ++ ++#define RTL2832_E4000_MIXER_GAIN_ADDR 0x15 ++#define RTL2832_E4000_MIXER_GAIN_MASK 0x1 ++#define RTL2832_E4000_MIXER_GAIN_SHIFT 0 ++ ++#define RTL2832_E4000_IF_STAGE_1_GAIN_ADDR 0x16 ++#define RTL2832_E4000_IF_STAGE_1_GAIN_MASK 0x1 ++#define RTL2832_E4000_IF_STAGE_1_GAIN_SHIFT 0 ++ ++#define RTL2832_E4000_IF_STAGE_2_GAIN_ADDR 0x16 ++#define RTL2832_E4000_IF_STAGE_2_GAIN_MASK 0x6 ++#define RTL2832_E4000_IF_STAGE_2_GAIN_SHIFT 1 ++ ++#define RTL2832_E4000_IF_STAGE_3_GAIN_ADDR 0x16 ++#define RTL2832_E4000_IF_STAGE_3_GAIN_MASK 0x18 ++#define RTL2832_E4000_IF_STAGE_3_GAIN_SHIFT 3 ++ ++#define RTL2832_E4000_IF_STAGE_4_GAIN_ADDR 0x16 ++#define RTL2832_E4000_IF_STAGE_4_GAIN_MASK 0x60 ++#define RTL2832_E4000_IF_STAGE_4_GAIN_SHIFT 5 ++ ++#define RTL2832_E4000_IF_STAGE_5_GAIN_ADDR 0x17 ++#define RTL2832_E4000_IF_STAGE_5_GAIN_MASK 0x7 ++#define RTL2832_E4000_IF_STAGE_5_GAIN_SHIFT 0 ++ ++#define RTL2832_E4000_IF_STAGE_6_GAIN_ADDR 0x17 ++#define RTL2832_E4000_IF_STAGE_6_GAIN_MASK 0x38 ++#define RTL2832_E4000_IF_STAGE_6_GAIN_SHIFT 3 ++ ++#define RTL2832_E4000_TUNER_OUTPUT_POWER_UNIT_0P1_DBM -100 ++ ++#define RTL2832_E4000_TUNER_MODE_UPDATE_WAIT_TIME_MS 1000 ++ ++ ++// Tuner gain mode ++enum RTL2832_E4000_TUNER_GAIN_MODE ++{ ++ RTL2832_E4000_TUNER_GAIN_SENSITIVE, ++ RTL2832_E4000_TUNER_GAIN_NORMAL, ++ RTL2832_E4000_TUNER_GAIN_LINEAR, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832E4000Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// RTL2832 E4000 NIM manipulaing functions ++int ++rtl2832_e4000_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_e4000_Initialize_fm( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++int ++rtl2832_e4000_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_e4000_SetParameters_fm( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_e4000_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_e4000_UpdateTunerMode( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.c 2016-04-02 19:17:52.100066046 -0300 +@@ -0,0 +1,840 @@ ++/** ++ ++@file ++ ++@brief RTL2832 FC0012 NIM module definition ++ ++One can manipulate RTL2832 FC0012 NIM through RTL2832 FC0012 NIM module. ++RTL2832 FC0012 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_fc0012.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 FC0012 NIM module builder ++ ++Use BuildRtl2832Fc0012Module() to build RTL2832 FC0012 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 FC0012 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr FC0012 I2C device address ++@param [in] TunerCrystalFreqHz FC0012 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2832Fc0012Module() to build RTL2832 FC0012 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Fc0012Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ RTL2832_FC0012_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0012); ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_FC0012; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build FC0012 tuner module. ++ BuildFc0012Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_fc0012_Initialize; ++ pNim->SetParameters = rtl2832_fc0012_SetParameters; ++ pNim->UpdateFunction = rtl2832_fc0012_UpdateFunction; ++ ++ ++ // Initialize NIM extra module variables. ++ pNimExtra->LnaUpdateWaitTimeMax = DivideWithCeiling(RTL2832_FC0012_LNA_UPDATE_WAIT_TIME_MS, DemodUpdateFuncRefPeriodMs); ++ pNimExtra->LnaUpdateWaitTime = 0; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_fc0012_Initialize_fm( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_FC0012_DAB_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x5a }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9bf }, ++ {DVBT_EN_GI_PGA, 0x0 }, ++ {DVBT_THD_LOCK_UP, 0x0 }, ++ {DVBT_THD_LOCK_DW, 0x0 }, ++ {DVBT_THD_UP1, 0x11 }, ++ {DVBT_THD_DW1, 0xef }, ++ {DVBT_INTER_CNT_LEN, 0xc }, ++ {DVBT_GI_PGA_STATE, 0x0 }, ++ {DVBT_EN_AGC_PGA, 0x1 }, ++ ++ //test ++ {DVBT_AD_EN_REG, 0x1 }, ++ {DVBT_AD_EN_REG1, 0x1 }, ++// {DVBT_EN_BK_TRK, 0x0 }, ++// {DVBT_AD_AV_REF, 0x2a }, ++// {DVBT_REG_PI, 0x3 }, ++ //---------- ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner registers. ++ if(fc0012_SetRegMaskBits(pTuner, 0xd, 7, 0, 0x2) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner registers. ++ if(fc0012_SetRegMaskBits(pTuner, 0x11, 7, 0, 0x0) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner registers. ++ if(fc0012_SetRegMaskBits(pTuner, 0x15, 7, 0, 0x4) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ //if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ // goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ //if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ // goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_FC0012_DAB_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Get tuner RSSI value when calibration is on. ++ // Note: Need to execute rtl2832_fc0012_GetTunerRssiCalOn() after demod AD7 is on. ++ if(rtl2832_fc0012_GetTunerRssiCalOn(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_fc0012_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_FC0012_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x5a }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9bf }, ++ {DVBT_EN_GI_PGA, 0x0 }, ++ {DVBT_THD_LOCK_UP, 0x0 }, ++ {DVBT_THD_LOCK_DW, 0x0 }, ++ {DVBT_THD_UP1, 0x11 }, ++ {DVBT_THD_DW1, 0xef }, ++ {DVBT_INTER_CNT_LEN, 0xc }, ++ {DVBT_GI_PGA_STATE, 0x0 }, ++ {DVBT_EN_AGC_PGA, 0x1 }, ++// {DVBT_REG_GPE, 0x1 }, ++// {DVBT_REG_GPO, 0x0 }, ++// {DVBT_REG_MONSEL, 0x0 }, ++// {DVBT_REG_MON, 0x3 }, ++// {DVBT_REG_4MSEL, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner registers. ++ if(fc0012_SetRegMaskBits(pTuner, 0xd, 7, 0, 0x2) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner registers. ++ if(fc0012_SetRegMaskBits(pTuner, 0x11, 7, 0, 0x0) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner registers. ++ if(fc0012_SetRegMaskBits(pTuner, 0x15, 7, 0, 0x4) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_FC0012_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Get tuner RSSI value when calibration is on. ++ // Note: Need to execute rtl2832_fc0012_GetTunerRssiCalOn() after demod AD7 is on. ++ if(rtl2832_fc0012_GetTunerRssiCalOn(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_fc0012_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ FC0012_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = FC0012_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = FC0012_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = FC0012_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_fc0012_SetParameters_fm( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ FC0012_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = FC0012_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = FC0012_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = FC0012_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2832_fc0012_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ RTL2832_FC0012_EXTRA_MODULE *pNimExtra; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0012); ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Increase tuner LNA_GAIN update waiting time. ++ pNimExtra->LnaUpdateWaitTime += 1; ++ ++ ++ // Check if need to update tuner LNA_GAIN according to update waiting time. ++ if(pNimExtra->LnaUpdateWaitTime == pNimExtra->LnaUpdateWaitTimeMax) ++ { ++ // Reset update waiting time. ++ pNimExtra->LnaUpdateWaitTime = 0; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Update tuner LNA gain with RSSI. ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get tuner RSSI value when calibration is on. ++ ++One can use rtl2832_fc0012_GetTunerRssiCalOn() to get tuner calibration-on RSSI value. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Get tuner calibration-on RSSI value successfully. ++@retval FUNCTION_ERROR Get tuner calibration-on RSSI value unsuccessfully. ++ ++*/ ++int ++rtl2832_fc0012_GetTunerRssiCalOn( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ FC0012_EXTRA_MODULE *pTunerExtra; ++ RTL2832_FC0012_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0012); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0012); ++ ++ ++ // Set tuner EN_CAL_RSSI to 0x1. ++ if(fc0012_SetRegMaskBits(pTuner, 0x9, 4, 4, 0x1) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner LNA_POWER_DOWN to 0x1. ++ if(fc0012_SetRegMaskBits(pTuner, 0x6, 0, 0, 0x1) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Get demod RSSI_R when tuner RSSI calibration is on. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSSI_R, &(pNimExtra->RssiRCalOn)) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set tuner EN_CAL_RSSI to 0x0. ++ if(fc0012_SetRegMaskBits(pTuner, 0x9, 4, 4, 0x0) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner LNA_POWER_DOWN to 0x0. ++ if(fc0012_SetRegMaskBits(pTuner, 0x6, 0, 0, 0x0) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update tuner LNA_GAIN with RSSI. ++ ++One can use rtl2832_fc0012_UpdateTunerLnaGainWithRssi() to update tuner LNA_GAIN with RSSI. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update tuner LNA_GAIN with RSSI successfully. ++@retval FUNCTION_ERROR Update tuner LNA_GAIN with RSSI unsuccessfully. ++ ++*/ ++int ++rtl2832_fc0012_UpdateTunerLnaGainWithRssi( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ FC0012_EXTRA_MODULE *pTunerExtra; ++ RTL2832_FC0012_EXTRA_MODULE *pNimExtra; ++ ++ unsigned long RssiRCalOff; ++ long RssiRDiff; ++ unsigned char LnaGain; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0012); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0012); ++ ++ ++ // Get demod RSSI_R when tuner RSSI calibration in off. ++ // Note: Tuner EN_CAL_RSSI and LNA_POWER_DOWN are set to 0x0 after rtl2832_fc0012_GetTunerRssiCalOn() executing. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSSI_R, &RssiRCalOff) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Calculate RSSI_R difference. ++ RssiRDiff = RssiRCalOff - pNimExtra->RssiRCalOn; ++ ++ // Get tuner LNA_GAIN. ++ if(fc0012_GetRegMaskBits(pTuner, 0x13, 4, 3, &LnaGain) != FC0012_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ deb_info("%s: current LnaGain = %d\n", __FUNCTION__, LnaGain); ++ ++ // Determine next LNA_GAIN according to RSSI_R difference and current LNA_GAIN. ++ switch(LnaGain) ++ { ++ default: ++ case FC0012_LNA_GAIN_LOW: ++ ++ if(RssiRDiff <= 0) ++ LnaGain = FC0012_LNA_GAIN_MIDDLE; ++ ++ break; ++ ++ ++ case FC0012_LNA_GAIN_MIDDLE: ++ ++ if(RssiRDiff >= 34) ++ LnaGain = FC0012_LNA_GAIN_LOW; ++ ++ if(RssiRDiff <= 0) ++ LnaGain = FC0012_LNA_GAIN_HIGH; ++ ++ break; ++ ++ ++ case FC0012_LNA_GAIN_HIGH: ++ ++ if(RssiRDiff >= 8) ++ LnaGain = FC0012_LNA_GAIN_MIDDLE; ++ ++ break; ++ } ++ ++ ++ deb_info("%s: next LnaGain = %d\n", __FUNCTION__, LnaGain); ++ ++ ++ // Set tuner LNA_GAIN. ++ if(fc0012_SetRegMaskBits(pTuner, 0x13, 4, 3, LnaGain) != FC0012_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0012.h 2016-04-02 19:17:52.100066046 -0300 +@@ -0,0 +1,168 @@ ++#ifndef __NIM_RTL2832_FC0012 ++#define __NIM_RTL2832_FC0012 ++ ++/** ++ ++@file ++ ++@brief RTL2832 FC0012 NIM module declaration ++ ++One can manipulate RTL2832 FC0012 NIM through RTL2832 FC0012 NIM module. ++RTL2832 FC0012 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_fc0012.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 FC0012 NIM module. ++ BuildRtl2832Fc0012Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc6, // The FC0012 I2C device address is 0xc6 in 8-bit format. ++ CRYSTAL_FREQ_36000000HZ // The FC0012 crystal frequency is 36.0 MHz. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_fc0012.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_FC0012_DAB_ADDITIONAL_INIT_REG_TABLE_LEN 31 ++#define RTL2832_FC0012_ADDITIONAL_INIT_REG_TABLE_LEN 29 ++#define RTL2832_FC0012_LNA_UPDATE_WAIT_TIME_MS 1000 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Fc0012Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// RTL2832 FC0012 NIM manipulaing functions ++int ++rtl2832_fc0012_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc0012_Initialize_fm( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc0012_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_fc0012_SetParameters_fm( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_fc0012_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc0012_GetTunerRssiCalOn( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc0012_UpdateTunerLnaGainWithRssi( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0013.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0013.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0013.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0013.c 2016-04-02 19:17:52.100066046 -0300 +@@ -0,0 +1,1053 @@ ++/** ++ ++@file ++ ++@brief RTL2832 FC0013 NIM module definition ++ ++One can manipulate RTL2832 FC0013 NIM through RTL2832 FC0013 NIM module. ++RTL2832 FC0013 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_fc0013.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 FC0013 NIM module builder ++ ++Use BuildRtl2832Fc0013Module() to build RTL2832 FC0013 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 FC0013 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr FC0013 I2C device address ++@param [in] TunerCrystalFreqHz FC0013 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2832Fc0013Module() to build RTL2832 FC0013 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Fc0013Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ RTL2832_FC0013_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0013); ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_FC0013; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build FC0013 tuner module. ++ BuildFc0013Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_fc0013_Initialize; ++ pNim->SetParameters = rtl2832_fc0013_SetParameters; ++ pNim->UpdateFunction = rtl2832_fc0013_UpdateFunction; ++ ++ ++ // Initialize NIM extra module variables. ++ pNimExtra->LnaUpdateWaitTimeMax = DivideWithCeiling(RTL2832_FC0013_LNA_UPDATE_WAIT_TIME_MS, DemodUpdateFuncRefPeriodMs); ++ pNimExtra->LnaUpdateWaitTime = 0; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_fc0013_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_FC0013_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x5a }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9bf }, ++ {DVBT_EN_GI_PGA, 0x0 }, ++ {DVBT_THD_LOCK_UP, 0x0 }, ++ {DVBT_THD_LOCK_DW, 0x0 }, ++ {DVBT_THD_UP1, 0x11 }, ++ {DVBT_THD_DW1, 0xef }, ++ {DVBT_INTER_CNT_LEN, 0xc }, ++ {DVBT_GI_PGA_STATE, 0x0 }, ++ {DVBT_EN_AGC_PGA, 0x1 }, ++// {DVBT_REG_GPE, 0x1 }, ++// {DVBT_REG_GPO, 0x0 }, ++// {DVBT_REG_MONSEL, 0x0 }, ++// {DVBT_REG_MON, 0x3 }, ++// {DVBT_REG_4MSEL, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set FC0013 up-dowm AGC. ++ //(0xFE for master of dual). ++ //(0xFC for slave of dual, and for 2832 mini dongle). ++ if(fc0013_SetRegMaskBits(pTuner, 0x0c, 7, 0, 0xFC) != FC0013_I2C_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_FC0013_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Get tuner RSSI value when calibration is on. ++ // Note: Need to execute rtl2832_fc0013_GetTunerRssiCalOn() after demod AD7 is on. ++ if(rtl2832_fc0013_GetTunerRssiCalOn(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++error_status_set_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_fc0013_Initialize_fm( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_FC0013_DAB_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x5a }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9bf }, ++ {DVBT_EN_GI_PGA, 0x0 }, ++ {DVBT_THD_LOCK_UP, 0x0 }, ++ {DVBT_THD_LOCK_DW, 0x0 }, ++ {DVBT_THD_UP1, 0x11 }, ++ {DVBT_THD_DW1, 0xef }, ++ {DVBT_INTER_CNT_LEN, 0xc }, ++ {DVBT_GI_PGA_STATE, 0x0 }, ++ {DVBT_EN_AGC_PGA, 0x1 }, ++ ++ //test ++ {DVBT_AD_EN_REG, 0x1 }, ++ {DVBT_AD_EN_REG1, 0x1 }, ++// {DVBT_EN_BK_TRK, 0x0 }, ++// {DVBT_AD_AV_REF, 0x2a }, ++// {DVBT_REG_PI, 0x3 }, ++ //---------- ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set FC0013 up-dowm AGC. ++ //(0xFE for master of dual). ++ //(0xFC for slave of dual, and for 2832 mini dongle). ++ if(fc0013_SetRegMaskBits(pTuner, 0x0c, 7, 0, 0xFC) != FC0013_I2C_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ //if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ //goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ //if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ // goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ //if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ // goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_FC0013_DAB_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Get tuner RSSI value when calibration is on. ++ // Note: Need to execute rtl2832_fc0013_GetTunerRssiCalOn() after demod AD7 is on. ++ if(rtl2832_fc0013_GetTunerRssiCalOn(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++error_status_set_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_fc0013_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ FC0013_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0013); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = FC0013_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = FC0013_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = FC0013_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset tuner IQ LPF BW. ++ if(pTunerExtra->RcCalReset(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner IQ LPF BW, val=-2 for D-book ACI test. ++ if(pTunerExtra->RcCalAdd(pTuner, -2) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_fc0013_SetParameters_fm( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ FC0013_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0013); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = FC0013_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = FC0013_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = FC0013_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset tuner IQ LPF BW. ++ if(pTunerExtra->RcCalReset(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner IQ LPF BW, val=-2 for D-book ACI test. ++ if(pTunerExtra->RcCalAdd(pTuner, -2) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2832_fc0013_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ RTL2832_FC0013_EXTRA_MODULE *pNimExtra; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0013); ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Increase tuner LNA_GAIN update waiting time. ++ pNimExtra->LnaUpdateWaitTime += 1; ++ ++ ++ // Check if need to update tuner LNA_GAIN according to update waiting time. ++ if(pNimExtra->LnaUpdateWaitTime == pNimExtra->LnaUpdateWaitTimeMax) ++ { ++ // Reset update waiting time. ++ pNimExtra->LnaUpdateWaitTime = 0; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Update tuner LNA gain with RSSI. ++ if(rtl2832_fc0013_UpdateTunerLnaGainWithRssi(pNim) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get tuner RSSI value when calibration is on. ++ ++One can use rtl2832_fc0013_GetTunerRssiCalOn() to get tuner calibration-on RSSI value. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Get tuner calibration-on RSSI value successfully. ++@retval FUNCTION_ERROR Get tuner calibration-on RSSI value unsuccessfully. ++ ++*/ ++int ++rtl2832_fc0013_GetTunerRssiCalOn( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ FC0013_EXTRA_MODULE *pTunerExtra; ++ RTL2832_FC0013_EXTRA_MODULE *pNimExtra; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0013); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0013); ++ ++ // Get NIM base interface. ++ pBaseInterface = pNim->pBaseInterface; ++ ++ ++ // Set tuner EN_CAL_RSSI to 0x1. ++ if(fc0013_SetRegMaskBits(pTuner, 0x9, 4, 4, 0x1) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner LNA_POWER_DOWN to 0x1. ++ if(fc0013_SetRegMaskBits(pTuner, 0x6, 0, 0, 0x1) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Wait 100 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 100); ++ ++ // Get demod RSSI_R when tuner RSSI calibration is on. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSSI_R, &(pNimExtra->RssiRCalOn)) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Set tuner EN_CAL_RSSI to 0x0. ++ if(fc0013_SetRegMaskBits(pTuner, 0x9, 4, 4, 0x0) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner LNA_POWER_DOWN to 0x0. ++ if(fc0013_SetRegMaskBits(pTuner, 0x6, 0, 0, 0x0) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Update tuner LNA_GAIN with RSSI. ++ ++One can use rtl2832_fc0013_UpdateTunerLnaGainWithRssi() to update tuner LNA_GAIN with RSSI. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update tuner LNA_GAIN with RSSI successfully. ++@retval FUNCTION_ERROR Update tuner LNA_GAIN with RSSI unsuccessfully. ++ ++*/ ++int ++rtl2832_fc0013_UpdateTunerLnaGainWithRssi( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ FC0013_EXTRA_MODULE *pTunerExtra; ++ RTL2832_FC0013_EXTRA_MODULE *pNimExtra; ++ ++ unsigned long RssiRCalOff; ++ long RssiRDiff; ++ unsigned char LnaGain; ++ unsigned char ReadValue; ++ ++ // added from Fitipower, 2011-2-23, v0.8 ++ int boolVhfFlag; // 0:false, 1:true ++ int boolEnInChgFlag; // 0:false, 1:true ++ int intGainShift; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0013); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Fc0013); ++ ++ ++ // Get demod RSSI_R when tuner RSSI calibration in off. ++ // Note: Tuner EN_CAL_RSSI and LNA_POWER_DOWN are set to 0x0 after rtl2832_fc0013_GetTunerRssiCalOn() executing. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSSI_R, &RssiRCalOff) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // To avoid the wrong rssi calibration value in the environment with strong RF pulse signal. ++ if(RssiRCalOff < pNimExtra->RssiRCalOn) ++ pNimExtra->RssiRCalOn = RssiRCalOff; ++ ++ ++ // Calculate RSSI_R difference. ++ RssiRDiff = RssiRCalOff - pNimExtra->RssiRCalOn; ++ ++ // Get tuner LNA_GAIN. ++ if(fc0013_GetRegMaskBits(pTuner, 0x14, 4, 0, &LnaGain) != FC0013_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Determine next LNA_GAIN according to RSSI_R difference and current LNA_GAIN. ++ switch(LnaGain) ++ { ++ default: ++ ++ boolVhfFlag = 0; ++ boolEnInChgFlag = 1; ++ intGainShift = 10; ++ LnaGain = FC0013_LNA_GAIN_HIGH_19; ++ ++ // Set tuner LNA_GAIN. ++ if(fc0013_SetRegMaskBits(pTuner, 0x14, 4, 0, LnaGain) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ ++ ++ case FC0013_LNA_GAIN_HIGH_19: ++ ++ if(RssiRDiff >= 10) ++ { ++ boolVhfFlag = 1; ++ boolEnInChgFlag = 0; ++ intGainShift = 10; ++ LnaGain = FC0013_LNA_GAIN_HIGH_17; ++ ++ // Set tuner LNA_GAIN. ++ if(fc0013_SetRegMaskBits(pTuner, 0x14, 4, 0, LnaGain) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ } ++ else ++ { ++ goto success_status_Lna_Gain_No_Change; ++ } ++ ++ ++ case FC0013_LNA_GAIN_HIGH_17: ++ ++ if(RssiRDiff <= 2) ++ { ++ boolVhfFlag = 0; ++ boolEnInChgFlag = 1; ++ intGainShift = 10; ++ LnaGain = FC0013_LNA_GAIN_HIGH_19; ++ ++ // Set tuner LNA_GAIN. ++ if(fc0013_SetRegMaskBits(pTuner, 0x14, 4, 0, LnaGain) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ } ++ ++ else if(RssiRDiff >= 24) ++ { ++ boolVhfFlag = 0; ++ boolEnInChgFlag = 0; ++ intGainShift = 7; ++ LnaGain = FC0013_LNA_GAIN_MIDDLE; ++ ++ // Set tuner LNA_GAIN. ++ if(fc0013_SetRegMaskBits(pTuner, 0x14, 4, 0, LnaGain) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ } ++ ++ else ++ { ++ goto success_status_Lna_Gain_No_Change; ++ } ++ ++ ++ case FC0013_LNA_GAIN_MIDDLE: ++ ++ if(RssiRDiff >= 38) ++ { ++ boolVhfFlag = 0; ++ boolEnInChgFlag = 0; ++ intGainShift = 7; ++ LnaGain = FC0013_LNA_GAIN_LOW; ++ ++ // Set tuner LNA_GAIN. ++ if(fc0013_SetRegMaskBits(pTuner, 0x14, 4, 0, LnaGain) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ } ++ ++ else if(RssiRDiff <= 5) ++ { ++ boolVhfFlag = 1; ++ boolEnInChgFlag = 0; ++ intGainShift = 10; ++ LnaGain = FC0013_LNA_GAIN_HIGH_17; ++ ++ // Set tuner LNA_GAIN. ++ if(fc0013_SetRegMaskBits(pTuner, 0x14, 4, 0, LnaGain) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ } ++ ++ else ++ { ++ goto success_status_Lna_Gain_No_Change; ++ } ++ ++ ++ case FC0013_LNA_GAIN_LOW: ++ ++ if(RssiRDiff <= 2) ++ { ++ boolVhfFlag = 0; ++ boolEnInChgFlag = 0; ++ intGainShift = 7; ++ LnaGain = FC0013_LNA_GAIN_MIDDLE; ++ ++ // Set tuner LNA_GAIN. ++ if(fc0013_SetRegMaskBits(pTuner, 0x14, 4, 0, LnaGain) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ ++ break; ++ } ++ ++ else ++ { ++ goto success_status_Lna_Gain_No_Change; ++ } ++ } ++ ++ ++ if(fc0013_GetRegMaskBits(pTuner, 0x14, 7, 0, &ReadValue) != FC0013_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ if( (ReadValue & 0x60) == 0 ) // disable UHF & GPS ==> lock VHF frequency ++ { ++ boolVhfFlag = 1; ++ } ++ ++ ++ if( boolVhfFlag == 1 ) ++ { ++ //FC0013_Write(0x07, (FC0013_Read(0x07) | 0x10)); // VHF = 1 ++ if(fc0013_GetRegMaskBits(pTuner, 0x07, 7, 0, &ReadValue) != FC0013_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(fc0013_SetRegMaskBits(pTuner, 0x07, 7, 0, ReadValue | 0x10) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ } ++ else ++ { ++ //FC0013_Write(0x07, (FC0013_Read(0x07) & 0xEF)); // VHF = 0 ++ if(fc0013_GetRegMaskBits(pTuner, 0x07, 7, 0, &ReadValue) != FC0013_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(fc0013_SetRegMaskBits(pTuner, 0x07, 7, 0, ReadValue & 0xEF) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ if( boolEnInChgFlag == 1 ) ++ { ++ //FC0013_Write(0x0A, (FC0013_Read(0x0A) | 0x20)); // EN_IN_CHG = 1 ++ if(fc0013_GetRegMaskBits(pTuner, 0x0A, 7, 0, &ReadValue) != FC0013_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(fc0013_SetRegMaskBits(pTuner, 0x0A, 7, 0, ReadValue | 0x20) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ } ++ else ++ { ++ //FC0013_Write(0x0A, (FC0013_Read(0x0A) & 0xDF)); // EN_IN_CHG = 0 ++ if(fc0013_GetRegMaskBits(pTuner, 0x0A, 7, 0, &ReadValue) != FC0013_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(fc0013_SetRegMaskBits(pTuner, 0x0A, 7, 0, ReadValue & 0xDF) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ if( intGainShift == 10 ) ++ { ++ //FC0013_Write(0x07, (FC0013_Read(0x07) & 0xF0) | 0x0A); // GS = 10 ++ if(fc0013_GetRegMaskBits(pTuner, 0x07, 7, 0, &ReadValue) != FC0013_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(fc0013_SetRegMaskBits(pTuner, 0x07, 7, 0, (ReadValue & 0xF0) | 0x0A) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ } ++ else ++ { ++ //FC0013_Write(0x07, (FC0013_Read(0x07) & 0xF0) | 0x07); // GS = 7 ++ if(fc0013_GetRegMaskBits(pTuner, 0x07, 7, 0, &ReadValue) != FC0013_I2C_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(fc0013_SetRegMaskBits(pTuner, 0x07, 7, 0, (ReadValue & 0xF0) | 0x07) != FC0013_I2C_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++success_status_Lna_Gain_No_Change: ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0013.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0013.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0013.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc0013.h 2016-04-02 19:17:52.100066046 -0300 +@@ -0,0 +1,170 @@ ++#ifndef __NIM_RTL2832_FC0013 ++#define __NIM_RTL2832_FC0013 ++ ++/** ++ ++@file ++ ++@brief RTL2832 FC0013 NIM module declaration ++ ++One can manipulate RTL2832 FC0013 NIM through RTL2832 FC0013 NIM module. ++RTL2832 FC0013 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_fc0013.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 FC0013 NIM module. ++ BuildRtl2832Fc0013Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc6, // The FC0013 I2C device address is 0xc6 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ // The FC0013 crystal frequency is 28.8 MHz. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_fc0013.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_FC0013_ADDITIONAL_INIT_REG_TABLE_LEN 29 ++#define RTL2832_FC0013_DAB_ADDITIONAL_INIT_REG_TABLE_LEN 31 ++#define RTL2832_FC0013_LNA_UPDATE_WAIT_TIME_MS 1000 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Fc0013Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// RTL2832 FC0013 NIM manipulaing functions ++int ++rtl2832_fc0013_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++int ++rtl2832_fc0013_Initialize_fm( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++int ++rtl2832_fc0013_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_fc0013_SetParameters_fm( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_fc0013_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc0013_GetTunerRssiCalOn( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc0013_UpdateTunerLnaGainWithRssi( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.c 2016-04-02 19:17:52.100066046 -0300 +@@ -0,0 +1,343 @@ ++/** ++ ++@file ++ ++@brief RTL2832 FC2580 NIM module definition ++ ++One can manipulate RTL2832 FC2580 NIM through RTL2832 FC2580 NIM module. ++RTL2832 FC2580 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_fc2580.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 FC2580 NIM module builder ++ ++Use BuildRtl2832Fc2580Module() to build RTL2832 FC2580 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 FC2580 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr FC2580 I2C device address ++@param [in] TunerCrystalFreqHz FC2580 crystal frequency in Hz ++@param [in] TunerAgcMode FC2580 AGC mode ++ ++ ++@note ++ -# One should call BuildRtl2832Fc2580Module() to build RTL2832 FC2580 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Fc2580Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerAgcMode ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_FC2580; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build FC2580 tuner module. ++ BuildFc2580Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ TunerAgcMode ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_fc2580_Initialize; ++ pNim->SetParameters = rtl2832_fc2580_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_fc2580_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x9c }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9f4 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_fc2580_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ FC2580_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = FC2580_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = FC2580_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = FC2580_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_fc2580.h 2016-04-02 19:17:52.100066046 -0300 +@@ -0,0 +1,141 @@ ++#ifndef __NIM_RTL2832_FC2580 ++#define __NIM_RTL2832_FC2580 ++ ++/** ++ ++@file ++ ++@brief RTL2832 FC2580 NIM module declaration ++ ++One can manipulate RTL2832 FC2580 NIM through RTL2832 FC2580 NIM module. ++RTL2832 FC2580 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_fc2580.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 FC2580 NIM module. ++ BuildRtl2832Fc2580Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xac, // The FC2580 I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // The FC2580 crystal frequency is 16.384 MHz. ++ FC2580_AGC_EXTERNAL // The FC2580 AGC mode is external AGC mode. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_fc2580.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN 21 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Fc2580Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerAgcMode ++ ); ++ ++ ++ ++ ++ ++// RTL2832 FC2580 NIM manipulaing functions ++int ++rtl2832_fc2580_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_fc2580_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.c 2016-04-02 19:17:52.100066046 -0300 +@@ -0,0 +1,346 @@ ++/** ++ ++@file ++ ++@brief RTL2832 MAX3543 NIM module definition ++ ++One can manipulate RTL2832 MAX3543 NIM through RTL2832 MAX3543 NIM module. ++RTL2832 MAX3543 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_max3543.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 MAX3543 NIM module builder ++ ++Use BuildRtl2832Max3543Module() to build RTL2832 MAX3543 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 MAX3543 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr MAX3543 I2C device address ++@param [in] TunerCrystalFreqHz MAX3543 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2832Max3543Module() to build RTL2832 MAX3543 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Max3543Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_MAX3543; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build MAX3543 tuner module. ++ BuildMax3543Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ RTL2832_MAX3543_STANDARD_MODE_DEFAULT, ++ RTL2832_MAX3543_IF_FREQ_HZ_DEFAULT, ++ RTL2832_MAX3543_SAW_INPUT_TYPE_DEFAULT ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_max3543_Initialize; ++ pNim->SetParameters = rtl2832_max3543_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_max3543_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x4b }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ {DVBT_AD_EN_REG1, 0x0 }, ++ {DVBT_CKOUT_PWR_PID, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with NIM default. ++ if(pDemod->SetIfFreqHz(pDemod, RTL2832_MAX3543_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ if(pDemod->SetSpectrumMode(pDemod, RTL2832_MAX3543_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_max3543_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ MAX3543_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ // Note: MAX3543 tuner only has 7 MHz and 8 MHz settings. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = MAX3543_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = MAX3543_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = MAX3543_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_max3543.h 2016-04-02 19:17:52.100066046 -0300 +@@ -0,0 +1,145 @@ ++#ifndef __NIM_RTL2832_MAX3543 ++#define __NIM_RTL2832_MAX3543 ++ ++/** ++ ++@file ++ ++@brief RTL2832 MAX3543 NIM module declaration ++ ++One can manipulate RTL2832 MAX3543 NIM through RTL2832 MAX3543 NIM module. ++RTL2832 MAX3543 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_max3543.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 MAX3543 NIM module. ++ BuildRtl2832Max3543Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0, // The MAX3543 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ // The MAX3543 Crystal frequency is 16.0 MHz. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_max3543.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN 23 ++ ++// Default ++#define RTL2832_MAX3543_STANDARD_MODE_DEFAULT MAX3543_STANDARD_DVBT ++#define RTL2832_MAX3543_IF_FREQ_HZ_DEFAULT IF_FREQ_36170000HZ ++#define RTL2832_MAX3543_SPECTRUM_MODE_DEFAULT SPECTRUM_INVERSE ++#define RTL2832_MAX3543_SAW_INPUT_TYPE_DEFAULT MAX3543_SAW_INPUT_SE ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Max3543Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// RTL2832 MAX3543 NIM manipulaing functions ++int ++rtl2832_max3543_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_max3543_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.c 2016-04-02 19:17:52.104066053 -0300 +@@ -0,0 +1,360 @@ ++/** ++ ++@file ++ ++@brief RTL2832 MT2063 NIM module definition ++ ++One can manipulate RTL2832 MT2063 NIM through RTL2832 MT2063 NIM module. ++RTL2832 MT2063 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_mt2063.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 MT2063 NIM module builder ++ ++Use BuildRtl2832Mt2063Module() to build RTL2832 MT2063 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 MT2063 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr MT2063 I2C device address ++@param [in] TunerAgcMode MT2063 AGC mode ++ ++ ++@note ++ -# One should call BuildRtl2832Mt2063Module() to build RTL2832 MT2063 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Mt2063Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ unsigned long NimIfFreqHz, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ RTL2832_MT2063_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2063); ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_MT2063; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build MT2063 tuner module. ++ BuildMt2063Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ MT2063_STANDARD_DVBT, ++ MT2063_VGAGC_0X3 ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_mt2063_Initialize; ++ pNim->SetParameters = rtl2832_mt2063_SetParameters; ++ ++ ++ // Set NIM extra module variables. ++ pNimExtra->IfFreqHz = NimIfFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_mt2063_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++// {DVBT_AGC_TARG_VAL_8_1, 0x32 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x19 }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ RTL2832_MT2063_EXTRA_MODULE *pNimExtra; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2063); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner IF frequency in Hz. ++ if(pTunerExtra->SetIfFreqHz(pTuner, pNimExtra->IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency in Hz. ++ if(pDemod->SetIfFreqHz(pDemod, pNimExtra->IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_INVERSE. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_mt2063_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ unsigned long BandwidthHz; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Determine BandwidthHz according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: BandwidthHz = MT2063_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: BandwidthHz = MT2063_BANDWIDTH_7MHZ; break; ++ case DVBT_BANDWIDTH_8MHZ: BandwidthHz = MT2063_BANDWIDTH_8MHZ; break; ++ } ++ ++ // Set tuner bandwidth in Hz with BandwidthHz. ++ // Note: Need to execute SetBandwidthHz() before SetRfFreqHz() for MT2063, ++ // because MT2063 bandwidth setting API only sets software variables. ++ if(pTunerExtra->SetBandwidthHz(pTuner, BandwidthHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2063.h 2016-04-02 19:17:52.104066053 -0300 +@@ -0,0 +1,160 @@ ++#ifndef __NIM_RTL2832_MT2063 ++#define __NIM_RTL2832_MT2063 ++ ++/** ++ ++@file ++ ++@brief RTL2832 MT2063 NIM module declaration ++ ++One can manipulate RTL2832 MT2063 NIM through RTL2832 MT2063 NIM module. ++RTL2832 MT2063 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_mt2063.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 MT2063 NIM module. ++ BuildRtl2832Mt2063Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ IF_FREQ_36125000HZ, // The RTL2832 and MT2063 IF frequency is 36.125 MHz. ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0 // The MT2063 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2063 tuner extra module. ++ pTuner = pNim->pTuner; ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ ++ // Open MT2063 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ ++ ++ ++ // Close MT2063 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_mt2063.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN 21 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Mt2063Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ unsigned long NimIfFreqHz, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ); ++ ++ ++ ++ ++ ++// RTL2832 MT2063 NIM manipulaing functions ++int ++rtl2832_mt2063_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_mt2063_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.c 2016-04-02 19:17:52.104066053 -0300 +@@ -0,0 +1,1082 @@ ++/** ++ ++@file ++ ++@brief RTL2832 MT2266 NIM module definition ++ ++One can manipulate RTL2832 MT2266 NIM through RTL2832 MT2266 NIM module. ++RTL2832 MT2266 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_mt2266.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 MT2266 NIM module builder ++ ++Use BuildRtl2832Mt2266Module() to build RTL2832 MT2266 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 MT2266 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr MT2266 I2C device address ++ ++ ++@note ++ -# One should call BuildRtl2832Mt2266Module() to build RTL2832 MT2266 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Mt2266Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ RTL2832_MT2266_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2266); ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_MT2266; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build MT2266 tuner module. ++ BuildMt2266Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_mt2266_Initialize; ++ pNim->SetParameters = rtl2832_mt2266_SetParameters; ++ pNim->UpdateFunction = rtl2832_mt2266_UpdateFunction; ++ ++ ++ // Initialize NIM extra module variables. ++ pNimExtra->LnaConfig = 0xff; ++ pNimExtra->UhfSens = 0xff; ++ pNimExtra->AgcCurrentState = 0xff; ++ pNimExtra->LnaGainOld = 0xffffffff; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_mt2266_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MT2266_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0xc0 }, // Note: The IF_AGC_MIN value will be set again by demod_pdcontrol_reset(). ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x9c }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x1 }, ++ {DVBT_POLAR_IF_AGC, 0x1 }, ++ {DVBT_AD7_SETTING, 0xe9f4 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_MT2266_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_mt2266_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ MT2266_EXTRA_MODULE *pTunerExtra; ++ Handle_t Mt2266Handle; ++ unsigned long BandwidthHz; ++ ++ RTL2832_MT2266_EXTRA_MODULE *pNimExtra; ++ ++ UData_t Status; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ Mt2266Handle = pTunerExtra->DeviceHandle; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2266); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine BandwidthHz according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: BandwidthHz = MT2266_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: BandwidthHz = MT2266_BANDWIDTH_7MHZ; break; ++ case DVBT_BANDWIDTH_8MHZ: BandwidthHz = MT2266_BANDWIDTH_8MHZ; break; ++ } ++ ++ // Set tuner bandwidth in Hz with BandwidthHz. ++ if(pTunerExtra->SetBandwidthHz(pTuner, BandwidthHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Reset MT2266 update procedure. ++ Status = demod_pdcontrol_reset(pDemod, Mt2266Handle, &pNimExtra->AgcCurrentState); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++rtl2832_mt2266_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ MT2266_EXTRA_MODULE *pTunerExtra; ++ RTL2832_MT2266_EXTRA_MODULE *pNimExtra; ++ ++ Handle_t Mt2266Handle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module and tuner handle. ++ pTunerExtra = &(pTuner->Extra.Mt2266); ++ pTunerExtra->GetHandle(pTuner, &Mt2266Handle); ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2832Mt2266); ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Update demod and tuner register setting. ++ Status = demod_pdcontrol( ++ pDemod, ++ Mt2266Handle, ++ &pNimExtra->LnaConfig, ++ &pNimExtra->UhfSens, ++ &pNimExtra->AgcCurrentState, ++ &pNimExtra->LnaGainOld ++ ); ++ ++/* ++ handle_t demod_handle, ++ handle_t tuner_handle, ++ unsigned char* lna_config, ++ unsigned char* uhf_sens, ++ unsigned char *agc_current_state, ++ unsigned long *lna_gain_old ++ ++ unsigned char LnaConfig; ++ unsigned char UhfSens; ++ unsigned char AgcCurrentState; ++ unsigned long LnaGainOld; ++ ++*/ ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Additional definition for mt_control.c ++UData_t ++demod_get_pd( ++ handle_t demod_handle, ++ unsigned short *pd_value ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ unsigned long RssiR; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get RSSI_R value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_RSSI_R, &RssiR) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Set pd_value according to RSSI_R. ++ *pd_value = (unsigned short)RssiR; ++ ++ ++ return MT_OK; ++ ++ ++error_status_get_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++UData_t ++demod_get_agc( ++ handle_t demod_handle, ++ unsigned short *rf_level, ++ unsigned short *bb_level ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ unsigned long RfAgc; ++ unsigned long IfAgc; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get RF and IF AGC value. ++ if(pDemod->GetRfAgc(pDemod, &RfAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetIfAgc(pDemod, &IfAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Convert RF and IF AGC value to proper format. ++ *rf_level = (unsigned short)((RfAgc + (1 << (RTL2832_RF_AGC_REG_BIT_NUM - 1))) * ++ (1 << (MT2266_DEMOD_ASSUMED_AGC_REG_BIT_NUM - RTL2832_RF_AGC_REG_BIT_NUM))); ++ ++ *bb_level = (unsigned short)((IfAgc + (1 << (RTL2832_IF_AGC_REG_BIT_NUM - 1))) * ++ (1 << (MT2266_DEMOD_ASSUMED_AGC_REG_BIT_NUM - RTL2832_IF_AGC_REG_BIT_NUM))); ++ ++ ++ return MT_OK; ++ ++ ++error_status_get_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++UData_t ++demod_set_bbagclim( ++ handle_t demod_handle, ++ int on_off_status ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ unsigned long IfAgcMinBinary; ++ long IfAgcMinInt; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get IF_AGC_MIN binary value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_IF_AGC_MIN, &IfAgcMinBinary) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Convert IF_AGC_MIN binary value to integer. ++ IfAgcMinInt = BinToSignedInt(IfAgcMinBinary, RTL2832_MT2266_IF_AGC_MIN_BIT_NUM); ++ ++ // Modify IF_AGC_MIN integer according to on_off_status. ++ switch(on_off_status) ++ { ++ case 1: ++ ++ IfAgcMinInt += RTL2832_MT2266_IF_AGC_MIN_INT_STEP; ++ ++ if(IfAgcMinInt > RTL2832_MT2266_IF_AGC_MIN_INT_MAX) ++ IfAgcMinInt = RTL2832_MT2266_IF_AGC_MIN_INT_MAX; ++ ++ break; ++ ++ default: ++ case 0: ++ ++ IfAgcMinInt -= RTL2832_MT2266_IF_AGC_MIN_INT_STEP; ++ ++ if(IfAgcMinInt < RTL2832_MT2266_IF_AGC_MIN_INT_MIN) ++ IfAgcMinInt = RTL2832_MT2266_IF_AGC_MIN_INT_MIN; ++ ++ break; ++ } ++ ++ // Convert modified IF_AGC_MIN integer to binary value. ++ IfAgcMinBinary = SignedIntToBin(IfAgcMinInt, RTL2832_MT2266_IF_AGC_MIN_BIT_NUM); ++ ++ // Set IF_AGC_MIN with modified binary value. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IF_AGC_MIN, IfAgcMinBinary) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_registers: ++error_status_get_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++ ++ ++UData_t ++tuner_set_bw_normal( ++ handle_t tuner_handle, ++ handle_t demod_handle ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int DemodBandwidthMode; ++ unsigned int TunerBandwidthHz; ++ unsigned int TargetTunerBandwidthHz; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get demod bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &DemodBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine tuner target bandwidth. ++ switch(DemodBandwidthMode) ++ { ++ case DVBT_BANDWIDTH_6MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_7MHZ; break; ++ default: ++ case DVBT_BANDWIDTH_8MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_8MHZ; break; ++ } ++ ++ // Get tuner bandwidth. ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_OUTPUT_BW, &TunerBandwidthHz))) ++ goto error_status_get_tuner_bandwidth; ++ ++ // Set tuner bandwidth with normal setting according to demod bandwidth mode. ++ if(TunerBandwidthHz != TargetTunerBandwidthHz) ++ { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle, MT2266_OUTPUT_BW, TargetTunerBandwidthHz))) ++ goto error_status_set_tuner_bandwidth; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_bandwidth: ++error_status_get_tuner_bandwidth: ++error_status_execute_function: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++ ++ ++UData_t ++tuner_set_bw_narrow( ++ handle_t tuner_handle, ++ handle_t demod_handle ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int DemodBandwidthMode; ++ unsigned long AciDetInd; ++ unsigned int TunerBandwidthHz; ++ unsigned int TargetTunerBandwidthHz; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Get demod bandwidth mode. ++ if(pDemod->GetBandwidthMode(pDemod, &DemodBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod ACI_DET_IND. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_ACI_DET_IND, &AciDetInd) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ // Determine tuner target bandwidth according to ACI_DET_IND. ++ if(AciDetInd == 0x1) ++ { ++ // Choose narrow target bandwidth. ++ switch(DemodBandwidthMode) ++ { ++ case DVBT_BANDWIDTH_6MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_5MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_6MHZ; break; ++ default: ++ case DVBT_BANDWIDTH_8MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_7MHZ; break; ++ } ++ } ++ else ++ { ++ // Choose normal target bandwidth. ++ switch(DemodBandwidthMode) ++ { ++ case DVBT_BANDWIDTH_6MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_7MHZ; break; ++ default: ++ case DVBT_BANDWIDTH_8MHZ: TargetTunerBandwidthHz = MT2266_BANDWIDTH_8MHZ; break; ++ } ++ } ++ ++ // Get tuner bandwidth. ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_OUTPUT_BW, &TunerBandwidthHz))) ++ goto error_status_get_tuner_bandwidth; ++ ++ // Set tuner bandwidth with normal setting according to demod bandwidth mode. ++ if(TunerBandwidthHz != TargetTunerBandwidthHz) ++ { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle, MT2266_OUTPUT_BW, TargetTunerBandwidthHz))) ++ goto error_status_set_tuner_bandwidth; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_bandwidth: ++error_status_get_tuner_bandwidth: ++error_status_get_registers: ++error_status_execute_function: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++ ++ ++// Microtune source code - mt_control.c ++ ++ ++ ++UData_t demod_pdcontrol_reset(handle_t demod_handle, handle_t tuner_handle, unsigned char *agc_current_state) { ++ ++ DVBT_DEMOD_MODULE *pDemod; ++ unsigned long BinaryValue; ++ ++ ++ // Get demod module. ++ pDemod = (DVBT_DEMOD_MODULE *)demod_handle; ++ ++ // Reset AGC current state. ++ *agc_current_state = AGC_STATE_START; ++ ++ // Calculate RTL2832_MT2266_IF_AGC_MIN_INT_MIN binary value. ++ BinaryValue = SignedIntToBin(RTL2832_MT2266_IF_AGC_MIN_INT_MIN, RTL2832_MT2266_IF_AGC_MIN_BIT_NUM); ++ ++ // Set IF_AGC_MIN with binary value. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IF_AGC_MIN, BinaryValue) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner bandwidth with normal setting. ++ if(MT_IS_ERROR(tuner_set_bw_normal(tuner_handle, demod_handle))) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_bandwidth: ++error_status_set_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++ ++UData_t demod_pdcontrol(handle_t demod_handle, handle_t tuner_handle, unsigned char* lna_config, unsigned char* uhf_sens, ++ unsigned char *agc_current_state, unsigned long *lna_gain_old) { ++ ++ unsigned short pd_value; ++ unsigned short rf_level, bb_level; ++ unsigned long lna_gain; ++ unsigned char zin=0; ++ unsigned int tmp_freq=0,tmp_lna_gain=0; ++ ++// unsigned char temp[2]; ++// unsigned char agc_bb_min; ++// demod_data_t* local_data; ++ ++ ++ unsigned char band=1; /* band=0: vhf, band=1: uhf low, band=2: uhf high */ ++ unsigned long freq; ++ ++ // AGC threshold values ++ unsigned short sens_on[] = {11479, 11479, 32763}; ++ unsigned short sens_off[] = {36867, 36867, 44767}; ++ unsigned short lin_off[] = {23619, 23619, 23619}; ++ unsigned short lin_on[] = {38355, 38355, 38355}; ++ unsigned short pd_upper[] = {85, 85, 85}; ++ unsigned short pd_lower[] = {74, 74, 74}; ++ unsigned char next_state; ++ ++ // demod_data_t* local_data = (demod_data_t*)demod_handle; ++ ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_INPUT_FREQ, &tmp_freq))) goto error_status; ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_LNA_GAIN, &tmp_lna_gain))) goto error_status; ++ if(MT_IS_ERROR(MT2266_GetReg(tuner_handle,0x1e,&zin))) goto error_status; ++ ++ freq=(unsigned long)(tmp_freq); ++ lna_gain=(unsigned long)(tmp_lna_gain); ++ ++ if (freq <= 250000000) band=0; ++ else if (freq < 660000000) band=1; ++ else band=2; ++ ++ if(MT_IS_ERROR(demod_get_pd(demod_handle, &pd_value))) goto error_status; ++ if(MT_IS_ERROR(demod_get_agc(demod_handle, &rf_level, &bb_level))) goto error_status; ++ ++ rf_level=0xffff-rf_level; ++ bb_level=0xffff-bb_level; ++ ++/* ++#ifndef _HOST_DLL ++ uart_write_nr("St:"); ++ uart_writedez(agc_current_state[num]); ++ ++ uart_write_nr(" PD: "); ++ uart_writehex16(pd_value); ++ ++ uart_write_nr(" AGC: "); ++ uart_writehex16(rf_level); ++ uart_writehex16(bb_level); ++#endif ++*/ ++ ++ next_state = *agc_current_state; ++ ++ switch (*agc_current_state) { ++ ++ case AGC_STATE_START : { ++ if ((int)lna_gain < LNAGAIN_MIN) ++ next_state=AGC_STATE_LNAGAIN_BELOW_MIN; ++ else if (lna_gain > LNAGAIN_MAX) ++ next_state=AGC_STATE_LNAGAIN_ABOVE_MAX; ++ else ++ next_state=AGC_STATE_NORMAL; ++ break; ++ } ++ ++ case AGC_STATE_LNAGAIN_BELOW_MIN : { ++ if ((int)lna_gain < LNAGAIN_MIN ) ++ next_state=AGC_STATE_LNAGAIN_BELOW_MIN; ++ else next_state=AGC_STATE_NORMAL; ++ ++ break; ++ } ++ ++ case AGC_STATE_LNAGAIN_ABOVE_MAX : { ++ if (lna_gain > LNAGAIN_MAX ) ++ next_state=AGC_STATE_LNAGAIN_ABOVE_MAX; ++ else next_state=AGC_STATE_NORMAL; ++ break; ++ } ++ ++ case AGC_STATE_NORMAL : { ++ if (rf_level > lin_on[band] ) { ++ *lna_gain_old = lna_gain; ++ next_state = AGC_STATE_MAS_GRANDE_SIGNAL; ++ } ++ else if (pd_value > pd_upper[band]) { ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ } ++ else if ( (pd_value < pd_lower[band]) && (lna_gain < LNAGAIN_MAX) ) { ++ next_state = AGC_STATE_NO_INTERFERER; ++ } ++ else if ( bb_level < sens_on[band]) { ++ next_state = AGC_STATE_SMALL_SIGNAL; ++ } ++ break; ++ } ++ ++ case AGC_STATE_NO_INTERFERER : { ++ if (pd_value > pd_lower[band] ) ++ next_state = AGC_STATE_MEDIUM_INTERFERER; ++ else if (pd_value < pd_lower[band] ) ++ next_state = AGC_STATE_NORMAL; ++ else if ( lna_gain == LNAGAIN_MAX ) ++ next_state = AGC_STATE_NORMAL; ++ break; ++ } ++ ++ case AGC_STATE_MEDIUM_INTERFERER : { ++ if (pd_value > pd_upper[band] ) ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ else if (pd_value < pd_lower[band] ) ++ next_state = AGC_STATE_NO_INTERFERER; ++ break; ++ } ++ ++ ++ case AGC_STATE_GRANDE_INTERFERER : { ++ if (pd_value < pd_upper[band] ) ++ next_state = AGC_STATE_MEDIUM_INTERFERER; ++ break; ++ } ++ ++ case AGC_STATE_MAS_GRANDE_SIGNAL : { ++ if (rf_level < lin_on[band]) ++ next_state = AGC_STATE_GRANDE_SIGNAL; ++ else if (pd_value > pd_upper[band]) { ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ } ++ break; ++ } ++ ++ case AGC_STATE_MEDIUM_SIGNAL : { ++ if (rf_level > lin_off[band]) ++ next_state = AGC_STATE_GRANDE_SIGNAL; ++ else if (lna_gain >= *lna_gain_old) ++ next_state = AGC_STATE_NORMAL; ++ else if (pd_value > pd_upper[band]) ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ break; ++ } ++ ++ case AGC_STATE_GRANDE_SIGNAL : { ++ if (rf_level > lin_on[band]) ++ next_state = AGC_STATE_MAS_GRANDE_SIGNAL; ++ else if (rf_level < lin_off[band]) ++ next_state = AGC_STATE_MEDIUM_SIGNAL; ++ else if (pd_value > pd_upper[band]) ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ break; ++ } ++ ++ case AGC_STATE_SMALL_SIGNAL : { ++ if (pd_value > pd_upper[band] ) ++ next_state = AGC_STATE_GRANDE_INTERFERER; ++ else if (bb_level > sens_off[band]) ++ next_state = AGC_STATE_NORMAL; ++ else if ( (bb_level < sens_on[band]) && (lna_gain == LNAGAIN_MAX) ) ++ next_state = AGC_STATE_MAX_SENSITIVITY; ++ break; ++ } ++ ++ case AGC_STATE_MAX_SENSITIVITY : { ++ if (bb_level > sens_off[band]) ++ next_state = AGC_STATE_SMALL_SIGNAL; ++ break; ++ } ++ ++ } ++ ++ *agc_current_state = next_state; ++ ++ ++ switch (*agc_current_state) { ++ ++ case AGC_STATE_LNAGAIN_BELOW_MIN : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_LNAGAIN_ABOVE_MAX : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_DECR, LNAGAIN_MIN))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_NORMAL : { ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ break; ++ } ++ ++ case AGC_STATE_NO_INTERFERER : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_MEDIUM_INTERFERER : { ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ ++ // Additional setting ++ // Set tuner with normal bandwidth. ++ if(MT_IS_ERROR(tuner_set_bw_normal(tuner_handle, demod_handle))) goto error_status; ++ ++ break; ++ } ++ ++ case AGC_STATE_GRANDE_INTERFERER : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_DECR, LNAGAIN_MIN))) goto error_status; ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,1))) goto error_status; ++ ++ // Additional setting ++ // Set tuner with narrow bandwidth. ++ if(MT_IS_ERROR(tuner_set_bw_narrow(tuner_handle, demod_handle))) goto error_status; ++ ++ break; ++ } ++ ++ case AGC_STATE_MEDIUM_SIGNAL : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_GRANDE_SIGNAL : { ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_MAS_GRANDE_SIGNAL : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_DECR, LNAGAIN_MIN))) goto error_status; ++ if (lna_gain==0) { ++ if (zin <= 64) { ++ zin += 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ } ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ break; ++ } ++ ++ case AGC_STATE_SMALL_SIGNAL : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_LNA_GAIN_INCR, LNAGAIN_MAX))) goto error_status; ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_UHF_NORMAL,1))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ *uhf_sens=0; ++ break; ++ } ++ ++ case AGC_STATE_MAX_SENSITIVITY : { ++ if(MT_IS_ERROR(MT2266_SetParam(tuner_handle,MT2266_UHF_MAXSENS,1))) goto error_status; ++ if (zin >= 2) { ++ zin -= 2; ++ if(MT_IS_ERROR(MT2266_SetReg(tuner_handle,0x1e,zin))) goto error_status; ++ } ++ if(MT_IS_ERROR(demod_set_bbagclim(demod_handle,0))) goto error_status; ++ *uhf_sens=1; ++ break; ++ } ++ } ++ ++ if(MT_IS_ERROR(MT2266_GetParam(tuner_handle, MT2266_LNA_GAIN,&tmp_lna_gain))) goto error_status; ++ lna_gain=(unsigned long)(tmp_lna_gain); ++ ++ *lna_config=(unsigned char)lna_gain; ++ ++/* ++#ifndef _HOST_DLL ++ uart_write_nr(" LNA "); ++ uart_writedez(lna_gain); ++ uart_write_nr(" SENS "); ++ uart_writedez(*uhf_sens); ++ uart_write_nr(" Z "); ++ uart_writedez(zin); ++ uart_write(" "); ++#endif ++*/ ++ ++ ++ ++ return MT_OK; ++ ++ ++error_status: ++ return MT_COMM_ERR; ++} ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mt2266.h 2016-04-02 19:17:52.104066053 -0300 +@@ -0,0 +1,264 @@ ++#ifndef __NIM_RTL2832_MT2266 ++#define __NIM_RTL2832_MT2266 ++ ++/** ++ ++@file ++ ++@brief RTL2832 MT2266 NIM module declaration ++ ++One can manipulate RTL2832 MT2266 NIM through RTL2832 MT2266 NIM module. ++RTL2832 MT2266 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_mt2266.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ TUNER_MODULE *pTuner; ++ MT2266_EXTRA_MODULE *pTunerExtra; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 MT2266 NIM module. ++ BuildRtl2832Mt2266Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0 // The MT2266 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2266 tuner extra module. ++ pTuner = pNim->pTuner; ++ pTunerExtra = &(pTuner->Extra.Mt2266); ++ ++ // Open MT2266 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ ++ ++ ++ // Close MT2266 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_mt2266.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_MT2266_ADDITIONAL_INIT_REG_TABLE_LEN 21 ++ ++#define RTL2832_MT2266_IF_AGC_MIN_BIT_NUM 8 ++#define RTL2832_MT2266_IF_AGC_MIN_INT_MAX 36 ++#define RTL2832_MT2266_IF_AGC_MIN_INT_MIN -64 ++#define RTL2832_MT2266_IF_AGC_MIN_INT_STEP 0 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Mt2266Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ); ++ ++ ++ ++ ++ ++// RTL2832 MT2266 NIM manipulaing functions ++int ++rtl2832_mt2266_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_mt2266_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_mt2266_UpdateFunction( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Additional definition for mt_control.c ++typedef void * handle_t; ++ ++#define MT2266_DEMOD_ASSUMED_AGC_REG_BIT_NUM 16 ++ ++ ++ ++// Microtune source code - mt_control.c ++ ++ ++ ++/* $Id: mt_control.c,v 1.6 2008/01/02 12:04:39 tune\tpinz Exp $ */ ++/*! ++ * \file mt_control.c ++ * \author Thomas Pinz, Microtune GmbH&Co KG ++ * \author Marie-Curie-Str. 1, 85055 Ingolstadt ++ * \author E-Mail: thomas.pinz@microtune.com ++ */ ++ ++ ++#define LNAGAIN_MIN 0 ++#define LNAGAIN_MAX 14 ++ ++#define AGC_STATE_START 0 ++#define AGC_STATE_LNAGAIN_BELOW_MIN 1 ++#define AGC_STATE_LNAGAIN_ABOVE_MAX 2 ++#define AGC_STATE_NORMAL 3 ++#define AGC_STATE_NO_INTERFERER 4 ++#define AGC_STATE_MEDIUM_INTERFERER 5 ++#define AGC_STATE_GRANDE_INTERFERER 6 ++#define AGC_STATE_MEDIUM_SIGNAL 7 ++#define AGC_STATE_GRANDE_SIGNAL 8 ++#define AGC_STATE_MAS_GRANDE_SIGNAL 9 ++#define AGC_STATE_MAX_SENSITIVITY 10 ++#define AGC_STATE_SMALL_SIGNAL 11 ++ ++ ++UData_t ++demod_get_pd( ++ handle_t demod_handle, ++ unsigned short *pd_value ++ ); ++ ++UData_t ++demod_get_agc( ++ handle_t demod_handle, ++ unsigned short *rf_level, ++ unsigned short *bb_level ++ ); ++ ++UData_t ++demod_set_bbagclim( ++ handle_t demod_handle, ++ int on_off_status ++ ); ++ ++UData_t ++tuner_set_bw_normal( ++ handle_t tuner_handle, ++ handle_t demod_handle ++ ); ++ ++UData_t ++tuner_set_bw_narrow( ++ handle_t tuner_handle, ++ handle_t demod_handle ++ ); ++ ++UData_t ++demod_pdcontrol_reset( ++ handle_t demod_handle, ++ handle_t tuner_handle, ++ unsigned char *agc_current_state ++ ); ++ ++UData_t ++demod_pdcontrol( ++ handle_t demod_handle, ++ handle_t tuner_handle, ++ unsigned char* lna_config, ++ unsigned char* uhf_sens, ++ unsigned char *agc_current_state, ++ unsigned long *lna_gain_old ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.c 2016-04-02 19:17:52.104066053 -0300 +@@ -0,0 +1,517 @@ ++/** ++ ++@file ++ ++@brief RTL2832 MxL5007T NIM module definition ++ ++One can manipulate RTL2832 MxL5007T NIM through RTL2832 MxL5007T NIM module. ++RTL2832 MxL5007T NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_mxl5007t.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 MxL5007T NIM module builder ++ ++Use BuildRtl2832Mxl5007tModule() to build RTL2832 MxL5007T NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 MxL5007T NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr MxL5007T I2C device address ++@param [in] TunerCrystalFreqHz MxL5007T crystal frequency in Hz ++@param [in] TunerLoopThroughMode MxL5007T loop-through mode ++@param [in] TunerClkOutMode MxL5007T clock output mode ++@param [in] TunerClkOutAmpMode MxL5007T clock output amplitude mode ++ ++ ++@note ++ -# One should call BuildRtl2832Mxl5007tModule() to build RTL2832 MxL5007T NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Mxl5007tModule( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerLoopThroughMode, ++ int TunerClkOutMode, ++ int TunerClkOutAmpMode ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_MXL5007T; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build Mxl5007T tuner module. ++ BuildMxl5007tModule( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ RTL2832_MXL5007T_STANDARD_MODE_DEFAULT, ++ RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT, ++ RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT, ++ TunerLoopThroughMode, ++ TunerClkOutMode, ++ TunerClkOutAmpMode, ++ RTL2832_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_mxl5007t_Initialize; ++ pNim->SetParameters = rtl2832_mxl5007t_SetParameters; ++ ++ ++ return; ++} ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_mxl5007t_Initialize_fm( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x4b }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ {DVBT_AD_EN_REG1, 0x0 }, ++ {DVBT_CKOUT_PWR_PID, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ //if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ //goto error_status_execute_function; ++ ++ // Set demod IF frequency with NIM default. ++ //if(pDemod->SetIfFreqHz(pDemod, RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ // goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ //if(pDemod->SetSpectrumMode(pDemod, RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ // goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_mxl5007t_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x4b }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9d4 }, ++ {DVBT_AD_EN_REG1, 0x0 }, ++ {DVBT_CKOUT_PWR_PID, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with NIM default. ++ if(pDemod->SetIfFreqHz(pDemod, RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ if(pDemod->SetSpectrumMode(pDemod, RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_mxl5007t_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ MXL5007T_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mxl5007t); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = MXL5007T_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = MXL5007T_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = MXL5007T_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++int ++rtl2832_mxl5007t_SetParameters_fm( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ MXL5007T_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mxl5007t); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = MXL5007T_BANDWIDTH_6000000HZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = MXL5007T_BANDWIDTH_7000000HZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = MXL5007T_BANDWIDTH_8000000HZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_mxl5007t.h 2016-04-02 19:17:52.104066053 -0300 +@@ -0,0 +1,165 @@ ++#ifndef __NIM_RTL2832_MXL5007T ++#define __NIM_RTL2832_MXL5007T ++ ++/** ++ ++@file ++ ++@brief RTL2832 MxL5007T NIM module declaration ++ ++One can manipulate RTL2832 MxL5007T NIM through RTL2832 MxL5007T NIM module. ++RTL2832 MxL5007T NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_mxl5007t.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ RTL2832_EXTRA_MODULE Rtl2832ExtraModuleMemory; ++ MXL5007T_EXTRA_MODULE Mxl5007tExtraModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 MxL5007T NIM module. ++ BuildRtl2832Mxl5007tModule( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ &Rtl2832ExtraModuleMemory, // Employ RTL2832 extra module for RTL2832 module. ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ ON, // The RTL2832 Function 1 enabling status is on. ++ ++ &Mxl5007tExtraModuleMemory, // Employ Mxl5007T extra module for Mxl5007T module. ++ 0xc0, // The MxL5007T I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The MxL5007T Crystal frequency is 16.0 MHz. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0 // The MxL5007T clock output amplitude is 0. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_mxl5007t.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN 23 ++ ++// Default ++#define RTL2832_MXL5007T_STANDARD_MODE_DEFAULT MXL5007T_STANDARD_DVBT ++#define RTL2832_MXL5007T_IF_FREQ_HZ_DEFAULT IF_FREQ_4570000HZ ++#define RTL2832_MXL5007T_SPECTRUM_MODE_DEFAULT SPECTRUM_NORMAL ++#define RTL2832_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT 0 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Mxl5007tModule( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerLoopThroughMode, ++ int TunerClkOutMode, ++ int TunerClkOutAmpMode ++ ); ++ ++ ++ ++int ++rtl2832_mxl5007t_Initialize_fm( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++// RTL2832 MxL5007T NIM manipulaing functions ++int ++rtl2832_mxl5007t_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_mxl5007t_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_mxl5007t_SetParameters_fm( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_r820t.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_r820t.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_r820t.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_r820t.c 2016-04-02 19:17:52.104066053 -0300 +@@ -0,0 +1,356 @@ ++/** ++ ++@file ++ ++@brief RTL2832 R820T NIM module definition ++ ++One can manipulate RTL2832 R820T NIM through RTL2832 R820T NIM module. ++RTL2832 R820T NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_r820t.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 R820T NIM module builder ++ ++Use BuildRtl2832R820tModule() to build RTL2832 R820T NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 R820T NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr R820T I2C device address ++@param [in] TunerCrystalFreqHz R820T crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2832R820tModule() to build RTL2832 R820T NIM module before using it. ++ ++*/ ++void ++BuildRtl2832R820tModule( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_R820T; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build R820T tuner module. ++ BuildR820tModule( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ R820T ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_r820t_Initialize; ++ pNim->SetParameters = rtl2832_r820t_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_r820t_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_R820T_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x40 }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x8 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x18 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9f4 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_INVERSE. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_R820T_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++//error_status_set_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_r820t_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ R820T_EXTRA_MODULE *pTunerExtra; ++ int TunerStandardMode; ++ ++ unsigned long IfFreqHz; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.R820t); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: ++ TunerStandardMode = R820T_DVBT_BANDWIDTH_6000000HZ; ++ IfFreqHz = IF_FREQ_3570000HZ; ++ break; ++ case DVBT_BANDWIDTH_7MHZ: ++ TunerStandardMode = R820T_DVBT_BANDWIDTH_7000000HZ; ++ IfFreqHz = IF_FREQ_4570000HZ; ++ break; ++ case DVBT_BANDWIDTH_8MHZ: ++ TunerStandardMode = R820T_DVBT_BANDWIDTH_8000000HZ; ++ IfFreqHz = IF_FREQ_4570000HZ; ++ break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetStandardMode(pTuner, TunerStandardMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set demod IF frequency. ++ if(pDemod->SetIfFreqHz(pDemod, IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_r820t.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_r820t.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_r820t.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_r820t.h 2016-04-02 19:17:52.104066053 -0300 +@@ -0,0 +1,143 @@ ++#ifndef __NIM_RTL2832_R820T ++#define __NIM_RTL2832_R820T ++ ++/** ++ ++@file ++ ++@brief RTL2832 R820T NIM module declaration ++ ++One can manipulate RTL2832 R820T NIM through RTL2832 R820T NIM module. ++RTL2832 R820T NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_r820t.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 R820T NIM module. ++ BuildRtl2832R820tModule( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc6 // The R820T I2C device address is 0xc6 in 8-bit format. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_r820t.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_R820T_ADDITIONAL_INIT_REG_TABLE_LEN 21 ++#define RTL2832_R820T_LNA_UPDATE_WAIT_TIME_MS 1000 ++ ++ ++ ++#define R820T_DVBT_BANDWIDTH_6000000HZ DVB_T_6M ++#define R820T_DVBT_BANDWIDTH_7000000HZ DVB_T_7M_2 ++#define R820T_DVBT_BANDWIDTH_8000000HZ DVB_T_8M ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832R820tModule( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ); ++ ++ ++ ++ ++// RTL2832 R820T NIM manipulaing functions ++int ++rtl2832_r820t_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_r820t_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_tda18272.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_tda18272.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_tda18272.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_tda18272.c 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,408 @@ ++/** ++ ++@file ++ ++@brief RTL2832 TDA18272 NIM module definition ++ ++One can manipulate RTL2832 TDA18272 NIM through RTL2832 TDA18272 NIM module. ++RTL2832 TDA18272 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_tda18272.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 TDA18272 NIM module builder ++ ++Use BuildRtl2832Tda18272Module() to build RTL2832 TDA18272 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 TDA18272 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr TDA18272 I2C device address ++@param [in] TunerCrystalFreqHz TDA18272 crystal frequency in Hz ++@param [in] TunerUnitNo TDA18272 unit number ++@param [in] TunerIfOutputVppMode TDA18272 IF output Vp-p mode ++ ++ ++@note ++ -# One should call BuildRtl2832Tda18272Module() to build RTL2832 TDA18272 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Tda18272Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerUnitNo, ++ int TunerIfOutputVppMode ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_TDA18272; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build TDA18272 tuner module. ++ BuildTda18272Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ TunerUnitNo, ++ TunerIfOutputVppMode ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_tda18272_Initialize; ++ pNim->SetParameters = rtl2832_tda18272_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_tda18272_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_TDA18272_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x40 }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x8 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x18 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x80 }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9f4 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ // Note: TDA18272 tuner uses dynamic IF frequency, so we will set demod IF frequency in SetParameters(). ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_INVERSE. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_TDA18272_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_tda18272_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ TDA18272_EXTRA_MODULE *pTunerExtra; ++ int TunerStandardBandwidthMode; ++ unsigned long IfFreqHz; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Tda18272); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerStandardBandwidthMode = TDA18272_STANDARD_BANDWIDTH_DVBT_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerStandardBandwidthMode = TDA18272_STANDARD_BANDWIDTH_DVBT_7MHZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerStandardBandwidthMode = TDA18272_STANDARD_BANDWIDTH_DVBT_8MHZ; break; ++ } ++ ++ // Set tuner standard and bandwidth mode with TunerStandardBandwidthMode. ++ if(pTunerExtra->SetStandardBandwidthMode(pTuner, TunerStandardBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner RF frequency in Hz. ++ // Note: Must run SetRfFreqHz() after SetStandardBandwidthMode(), because SetRfFreqHz() needs some ++ // SetStandardBandwidthMode() information. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get tuner IF frequency in Hz. ++ // Note: 1. Must run GetIfFreqHz() after SetRfFreqHz(), because GetIfFreqHz() needs some SetRfFreqHz() information. ++ // 2. TDA18272 tuner uses dynamic IF frequency. ++ if(pTunerExtra->GetIfFreqHz(pTuner, &IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod IF frequency according to IfFreqHz. ++ // Note: TDA18272 tuner uses dynamic IF frequency. ++ if(pDemod->SetIfFreqHz(pDemod, IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_GET_RF_POWER_LEVEL_DBM ++ ++*/ ++int ++rtl2832_tda18272_GetRfPowerLevelDbm( ++ DVBT_NIM_MODULE *pNim, ++ long *pRfPowerLevelDbm ++ ) ++{ ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ unsigned long FsmStage; ++ long IfAgc; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get FSM stage and IF AGC value. ++ if(pDemod->GetRegBitsWithPage(pDemod, DVBT_FSM_STAGE, &FsmStage) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ if(pDemod->GetIfAgc(pDemod, &IfAgc) != FUNCTION_SUCCESS) ++ goto error_status_get_registers; ++ ++ ++ // Determine signal strength according to FSM stage and IF AGC value. ++ if(FsmStage < 10) ++ *pRfPowerLevelDbm = -120; ++ else ++ { ++ if(IfAgc > -1250) ++ *pRfPowerLevelDbm = -71 - (IfAgc / 165); ++ else ++ *pRfPowerLevelDbm = -60; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_tda18272.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_tda18272.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_tda18272.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_tda18272.h 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,148 @@ ++#ifndef __NIM_RTL2832_TDA18272 ++#define __NIM_RTL2832_TDA18272 ++ ++/** ++ ++@file ++ ++@brief RTL2832 TDA18272 NIM module declaration ++ ++One can manipulate RTL2832 TDA18272 NIM through RTL2832 TDA18272 NIM module. ++RTL2832 TDA18272 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_tda18272.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 TDA18272 NIM module. ++ BuildRtl2832Tda18272Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0, // The TDA18272 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The TDA18272 crystal frequency is 16.0 MHz. ++ TDA18272_UNIT_0, // The TDA18272 unit number is 0. ++ TDA18272_IF_OUTPUT_VPP_0P7V // The TDA18272 IF output Vp-p is 0.7 V. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_tda18272.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_TDA18272_ADDITIONAL_INIT_REG_TABLE_LEN 21 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Tda18272Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerUnitNo, ++ int TunerIfOutputVppMode ++ ); ++ ++ ++ ++ ++ ++// RTL2832 TDA18272 NIM manipulaing functions ++int ++rtl2832_tda18272_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_tda18272_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++int ++rtl2832_tda18272_GetRfPowerLevelDbm( ++ DVBT_NIM_MODULE *pNim, ++ long *pRfPowerLevelDbm ++ ); ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.c 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,340 @@ ++/** ++ ++@file ++ ++@brief RTL2832 TUA9001 NIM module definition ++ ++One can manipulate RTL2832 TUA9001 NIM through RTL2832 TUA9001 NIM module. ++RTL2832 TUA9001 NIM module is derived from DVB-T NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2832_tua9001.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2832 TUA9001 NIM module builder ++ ++Use BuildRtl2832Tua9001Module() to build RTL2832 TUA9001 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2832 TUA9001 NIM module pointer ++@param [in] pDvbtNimModuleMemory Pointer to an allocated DVB-T NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2832 I2C device address ++@param [in] DemodCrystalFreqHz RTL2832 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2832 TS interface mode for setting ++@param [in] DemodAppMode RTL2832 application mode for setting ++@param [in] DemodUpdateFuncRefPeriodMs RTL2832 update function reference period in millisecond for setting ++@param [in] DemodIsFunc1Enabled RTL2832 Function 1 enabling status for setting ++@param [in] TunerDeviceAddr TUA9001 I2C device address ++ ++ ++@note ++ -# One should call BuildRtl2832Tua9001Module() to build RTL2832 TUA9001 NIM module before using it. ++ ++*/ ++void ++BuildRtl2832Tua9001Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ) ++{ ++ DVBT_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDvbtNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DVBT_NIM_RTL2832_TUA9001; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2832 demod module. ++ BuildRtl2832Module( ++ &pNim->pDemod, ++ &pNim->DvbtDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodAppMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled ++ ); ++ ++ // Build TUA9001 tuner module. ++ BuildTua9001Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dvbt_nim_default_GetNimType; ++ pNim->GetParameters = dvbt_nim_default_GetParameters; ++ pNim->IsSignalPresent = dvbt_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dvbt_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dvbt_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dvbt_nim_default_GetSignalQuality; ++ pNim->GetBer = dvbt_nim_default_GetBer; ++ pNim->GetSnrDb = dvbt_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dvbt_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dvbt_nim_default_GetCrOffsetHz; ++ pNim->GetTpsInfo = dvbt_nim_default_GetTpsInfo; ++ pNim->UpdateFunction = dvbt_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2832_tua9001_Initialize; ++ pNim->SetParameters = rtl2832_tua9001_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2832_tua9001_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2832_TUA9001_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DVBT_DAGC_TRG_VAL, 0x39 }, ++ {DVBT_AGC_TARG_VAL_0, 0x0 }, ++ {DVBT_AGC_TARG_VAL_8_1, 0x5a }, ++ {DVBT_AAGC_LOOP_GAIN, 0x16 }, ++ {DVBT_LOOP_GAIN2_3_0, 0x6 }, ++ {DVBT_LOOP_GAIN2_4, 0x1 }, ++ {DVBT_LOOP_GAIN3, 0x16 }, ++ {DVBT_VTOP1, 0x35 }, ++ {DVBT_VTOP2, 0x21 }, ++ {DVBT_VTOP3, 0x21 }, ++ {DVBT_KRF1, 0x0 }, ++ {DVBT_KRF2, 0x40 }, ++ {DVBT_KRF3, 0x10 }, ++ {DVBT_KRF4, 0x10 }, ++ {DVBT_IF_AGC_MIN, 0x80 }, ++ {DVBT_IF_AGC_MAX, 0x7f }, ++ {DVBT_RF_AGC_MIN, 0x9c }, ++ {DVBT_RF_AGC_MAX, 0x7f }, ++ {DVBT_POLAR_RF_AGC, 0x0 }, ++ {DVBT_POLAR_IF_AGC, 0x0 }, ++ {DVBT_AD7_SETTING, 0xe9f4 }, ++ {DVBT_OPT_ADC_IQ, 0x1 }, ++ {DVBT_AD_AVI, 0x0 }, ++ {DVBT_AD_AVQ, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2832_TUA9001_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DVBT_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2832_tua9001_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DVBT_DEMOD_MODULE *pDemod; ++ ++ TUA9001_EXTRA_MODULE *pTunerExtra; ++ int TunerBandwidthMode; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Tua9001); ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Determine TunerBandwidthMode according to bandwidth mode. ++ switch(BandwidthMode) ++ { ++ default: ++ case DVBT_BANDWIDTH_6MHZ: TunerBandwidthMode = TUA9001_BANDWIDTH_6MHZ; break; ++ case DVBT_BANDWIDTH_7MHZ: TunerBandwidthMode = TUA9001_BANDWIDTH_7MHZ; break; ++ case DVBT_BANDWIDTH_8MHZ: TunerBandwidthMode = TUA9001_BANDWIDTH_8MHZ; break; ++ } ++ ++ // Set tuner bandwidth mode with TunerBandwidthMode. ++ if(pTunerExtra->SetBandwidthMode(pTuner, TunerBandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Set demod bandwidth mode. ++ if(pDemod->SetBandwidthMode(pDemod, BandwidthMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2832_tua9001.h 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,137 @@ ++#ifndef __NIM_RTL2832_TUA9001 ++#define __NIM_RTL2832_TUA9001 ++ ++/** ++ ++@file ++ ++@brief RTL2832 TUA9001 NIM module declaration ++ ++One can manipulate RTL2832 TUA9001 NIM through RTL2832 TUA9001 NIM module. ++RTL2832 TUA9001 NIM module is derived from DVB-T NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dvbt_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2832_tua9001.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DVBT_NIM_MODULE *pNim; ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2832 TUA9001 NIM module. ++ BuildRtl2832Tua9001Module( ++ &pNim, ++ &DvbtNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x20, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_STB, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ 0xc0 // The TUA9001 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dvbt_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2832.h" ++#include "tuner_tua9001.h" ++#include "dvbt_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2832_TUA9001_ADDITIONAL_INIT_REG_TABLE_LEN 24 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2832Tua9001Module( ++ DVBT_NIM_MODULE **ppNim, // DVB-T NIM dependence ++ DVBT_NIM_MODULE *pDvbtNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodAppMode, ++ unsigned long UpdateFuncRefPeriodMs, ++ int IsFunc1Enabled, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ); ++ ++ ++ ++ ++ ++// RTL2832 TUA9001 NIM manipulaing functions ++int ++rtl2832_tua9001_Initialize( ++ DVBT_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2832_tua9001_SetParameters( ++ DVBT_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int BandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.c 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,308 @@ ++/** ++ ++@file ++ ++@brief RTL2836 FC2580 NIM module definition ++ ++One can manipulate RTL2836 FC2580 NIM through RTL2836 FC2580 NIM module. ++RTL2836 FC2580 NIM module is derived from DTMB NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2836_fc2580.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2836 FC2580 NIM module builder ++ ++Use BuildRtl2836Fc2580Module() to build RTL2836 FC2580 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2836 FC2580 NIM module pointer ++@param [in] pDtmbNimModuleMemory Pointer to an allocated DTMB NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2836 I2C device address ++@param [in] DemodCrystalFreqHz RTL2836 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2836 TS interface mode ++@param [in] DemodUpdateFuncRefPeriodMs RTL2836 update function reference period in millisecond ++@param [in] DemodIsFunc1Enabled RTL2836 Function 1 enabling status for setting ++@param [in] DemodIsFunc2Enabled RTL2836 Function 2 enabling status for setting ++@param [in] TunerDeviceAddr FC2580 I2C device address ++@param [in] TunerCrystalFreqHz FC2580 crystal frequency in Hz ++@param [in] TunerAgcMode FC2580 AGC mode ++ ++ ++@note ++ -# One should call BuildRtl2836Fc2580Module() to build RTL2836 FC2580 NIM module before using it. ++ ++*/ ++void ++BuildRtl2836Fc2580Module( ++ DTMB_NIM_MODULE **ppNim, // DTMB NIM dependence ++ DTMB_NIM_MODULE *pDtmbNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ int DemodIsFunc2Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerAgcMode ++ ) ++{ ++ DTMB_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDtmbNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DTMB_NIM_RTL2836_FC2580; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2836 demod module. ++ BuildRtl2836Module( ++ &pNim->pDemod, ++ &pNim->DtmbDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled, ++ DemodIsFunc2Enabled ++ ); ++ ++ // Build FC2580 tuner module. ++ BuildFc2580Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ TunerAgcMode ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dtmb_nim_default_GetNimType; ++ pNim->GetParameters = dtmb_nim_default_GetParameters; ++ pNim->IsSignalPresent = dtmb_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dtmb_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dtmb_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dtmb_nim_default_GetSignalQuality; ++ pNim->GetBer = dtmb_nim_default_GetBer; ++ pNim->GetPer = dtmb_nim_default_GetPer; ++ pNim->GetSnrDb = dtmb_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dtmb_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dtmb_nim_default_GetCrOffsetHz; ++ pNim->GetSignalInfo = dtmb_nim_default_GetSignalInfo; ++ pNim->UpdateFunction = dtmb_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2836_fc2580_Initialize; ++ pNim->SetParameters = rtl2836_fc2580_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2836_fc2580_Initialize( ++ DTMB_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2836_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DTMB_TARGET_VAL, 0x38 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ FC2580_EXTRA_MODULE *pTunerExtra; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner bandwidth mode with 8 MHz. ++ if(pTunerExtra->SetBandwidthMode(pTuner, FC2580_BANDWIDTH_8000000HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with 0 Hz. ++ if(pDemod->SetIfFreqHz(pDemod, IF_FREQ_0HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_NORMAL. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_NORMAL) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2836_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2836_fc2580_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2836_fc2580.h 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,140 @@ ++#ifndef __NIM_RTL2836_FC2580 ++#define __NIM_RTL2836_FC2580 ++ ++/** ++ ++@file ++ ++@brief RTL2836 FC2580 NIM module declaration ++ ++One can manipulate RTL2836 FC2580 NIM through RTL2836 FC2580 NIM module. ++RTL2836 FC2580 NIM module is derived from DTMB NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dtmb_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2836_fc2580.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DTMB_NIM_MODULE *pNim; ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2836 FC2580 NIM module. ++ BuildRtl2836Fc2580Module( ++ &pNim, ++ &DtmbNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x3e, // The RTL2836 I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The RTL2836 crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2836 TS interface mode is serial. ++ 50, // The RTL2836 update function reference period is 50 millisecond ++ YES, // The RTL2836 Function 1 enabling status is YES. ++ YES, // The RTL2836 Function 2 enabling status is YES. ++ ++ 0xac, // The FC2580 I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // The FC2580 crystal frequency is 16.384 MHz. ++ FC2580_AGC_INTERNAL // The FC2580 AGC mode is internal AGC mode. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dtmb_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2836.h" ++#include "tuner_fc2580.h" ++#include "dtmb_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2836_FC2580_ADDITIONAL_INIT_REG_TABLE_LEN 1 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2836Fc2580Module( ++ DTMB_NIM_MODULE **ppNim, // DTMB NIM dependence ++ DTMB_NIM_MODULE *pDtmbNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ int DemodIsFunc2Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerAgcMode ++ ); ++ ++ ++ ++ ++ ++// RTL2836 FC2580 NIM manipulaing functions ++int ++rtl2836_fc2580_Initialize( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2836_fc2580_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.c 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,319 @@ ++/** ++ ++@file ++ ++@brief RTL2836 MxL5007T NIM module definition ++ ++One can manipulate RTL2836 MxL5007T NIM through RTL2836 MxL5007T NIM module. ++RTL2836 MxL5007T NIM module is derived from DTMB NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2836_mxl5007t.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2836 MxL5007T NIM module builder ++ ++Use BuildRtl2836Mxl5007tModule() to build RTL2836 MxL5007T NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2836 MxL5007T NIM module pointer ++@param [in] pDtmbNimModuleMemory Pointer to an allocated DTMB NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2836 I2C device address ++@param [in] DemodCrystalFreqHz RTL2836 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2836 TS interface mode ++@param [in] DemodUpdateFuncRefPeriodMs RTL2836 update function reference period in millisecond ++@param [in] DemodIsFunc1Enabled RTL2836 Function 1 enabling status for setting ++@param [in] DemodIsFunc2Enabled RTL2836 Function 2 enabling status for setting ++@param [in] TunerDeviceAddr MxL5007T I2C device address ++@param [in] TunerCrystalFreqHz MxL5007T crystal frequency in Hz ++@param [in] TunerLoopThroughMode MxL5007T loop-through mode ++@param [in] TunerClkOutMode MxL5007T clock output mode ++@param [in] TunerClkOutAmpMode MxL5007T clock output amplitude mode ++ ++ ++@note ++ -# One should call BuildRtl2836Mxl5007tModule() to build RTL2836 MxL5007T NIM module before using it. ++ ++*/ ++void ++BuildRtl2836Mxl5007tModule( ++ DTMB_NIM_MODULE **ppNim, // DTMB NIM dependence ++ DTMB_NIM_MODULE *pDtmbNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ int DemodIsFunc2Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerLoopThroughMode, ++ int TunerClkOutMode, ++ int TunerClkOutAmpMode ++ ) ++{ ++ DTMB_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pDtmbNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ ++ // Set NIM type. ++ pNim->NimType = DTMB_NIM_RTL2836_MXL5007T; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2836 demod module. ++ BuildRtl2836Module( ++ &pNim->pDemod, ++ &pNim->DtmbDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodUpdateFuncRefPeriodMs, ++ DemodIsFunc1Enabled, ++ DemodIsFunc2Enabled ++ ); ++ ++ // Build MxL5007T tuner module. ++ BuildMxl5007tModule( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ RTL2836_MXL5007T_STANDARD_MODE_DEFAULT, ++ RTL2836_MXL5007T_IF_FREQ_HZ_DEFAULT, ++ RTL2836_MXL5007T_SPECTRUM_MODE_DEFAULT, ++ TunerLoopThroughMode, ++ TunerClkOutMode, ++ TunerClkOutAmpMode, ++ RTL2836_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT ++ ); ++ ++ ++ // Set NIM module function pointers with default functions. ++ pNim->GetNimType = dtmb_nim_default_GetNimType; ++ pNim->GetParameters = dtmb_nim_default_GetParameters; ++ pNim->IsSignalPresent = dtmb_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = dtmb_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = dtmb_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = dtmb_nim_default_GetSignalQuality; ++ pNim->GetBer = dtmb_nim_default_GetBer; ++ pNim->GetPer = dtmb_nim_default_GetPer; ++ pNim->GetSnrDb = dtmb_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = dtmb_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = dtmb_nim_default_GetCrOffsetHz; ++ pNim->GetSignalInfo = dtmb_nim_default_GetSignalInfo; ++ pNim->UpdateFunction = dtmb_nim_default_UpdateFunction; ++ ++ // Set NIM module function pointers with particular functions. ++ pNim->Initialize = rtl2836_mxl5007t_Initialize; ++ pNim->SetParameters = rtl2836_mxl5007t_SetParameters; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2836_mxl5007t_Initialize( ++ DTMB_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2836_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {DTMB_TARGET_VAL, 0x38 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ MXL5007T_EXTRA_MODULE *pTunerExtra; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ // Get tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mxl5007t); ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner bandwidth mode with 8 MHz. ++ if(pTunerExtra->SetBandwidthMode(pTuner, MXL5007T_BANDWIDTH_8000000HZ) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency with NIM default. ++ if(pDemod->SetIfFreqHz(pDemod, RTL2836_MXL5007T_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ if(pDemod->SetSpectrumMode(pDemod, RTL2836_MXL5007T_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod registers. ++ for(i = 0; i < RTL2836_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see DTMB_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2836_mxl5007t_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ DTMB_DEMOD_MODULE *pDemod; ++ ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Enable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x1) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Disable demod DTMB_I2CT_EN_CTRL. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, DTMB_I2CT_EN_CTRL, 0x0) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++error_status_set_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2836_mxl5007t.h 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,150 @@ ++#ifndef __NIM_RTL2836_MXL5007T ++#define __NIM_RTL2836_MXL5007T ++ ++/** ++ ++@file ++ ++@brief RTL2836 MxL5007T NIM module declaration ++ ++One can manipulate RTL2836 MxL5007T NIM through RTL2836 MxL5007T NIM module. ++RTL2836 MxL5007T NIM module is derived from DTMB NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in dtmb_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2836_mxl5007t.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ DTMB_NIM_MODULE *pNim; ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2836 MxL5007T NIM module. ++ BuildRtl2836Mxl5007tModule( ++ &pNim, ++ &DtmbNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x3e, // The RTL2836 I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The RTL2836 crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2836 TS interface mode is serial. ++ 50, // The RTL2836 update function reference period is 50 millisecond ++ YES, // The RTL2836 Function 1 enabling status is YES. ++ YES, // The RTL2836 Function 2 enabling status is YES. ++ ++ 0xc0, // The MxL5007T I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The MxL5007T Crystal frequency is 16.0 MHz. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0 // The MxL5007T clock output amplitude is 0. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in dtmb_nim_base.h ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2836.h" ++#include "tuner_mxl5007t.h" ++#include "dtmb_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2836_MXL5007T_ADDITIONAL_INIT_REG_TABLE_LEN 1 ++ ++// Default ++#define RTL2836_MXL5007T_STANDARD_MODE_DEFAULT MXL5007T_STANDARD_DVBT ++#define RTL2836_MXL5007T_IF_FREQ_HZ_DEFAULT IF_FREQ_4570000HZ ++#define RTL2836_MXL5007T_SPECTRUM_MODE_DEFAULT SPECTRUM_NORMAL ++#define RTL2836_MXL5007T_QAM_IF_DIFF_OUT_LEVEL_DEFAULT 0 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2836Mxl5007tModule( ++ DTMB_NIM_MODULE **ppNim, // DTMB NIM dependence ++ DTMB_NIM_MODULE *pDtmbNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ unsigned long DemodUpdateFuncRefPeriodMs, ++ int DemodIsFunc1Enabled, ++ int DemodIsFunc2Enabled, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz, ++ int TunerLoopThroughMode, ++ int TunerClkOutMode, ++ int TunerClkOutAmpMode ++ ); ++ ++ ++ ++ ++ ++// RTL2836 MxL5007T NIM manipulaing functions ++int ++rtl2836_mxl5007t_Initialize( ++ DTMB_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2836_mxl5007t_SetParameters( ++ DTMB_NIM_MODULE *pNim, ++ unsigned long RfFreqHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.c 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,341 @@ ++/** ++ ++@file ++ ++@brief RTL2840 MAX3543 NIM module definition ++ ++One can manipulate RTL2840 MAX3543 NIM through RTL2840 MAX3543 NIM module. ++RTL2840 MAX3543 NIM module is derived from QAM NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2840_max3543.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2840 MAX3543 NIM module builder ++ ++Use BuildRtl2840Max3543Module() to build RTL2840 MAX3543 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2840 MAX3543 NIM module pointer ++@param [in] pQamNimModuleMemory Pointer to an allocated QAM NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2840 I2C device address ++@param [in] DemodCrystalFreqHz RTL2840 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2840 TS interface mode for setting ++@param [in] DemodEnhancementMode RTL2840 enhancement mode for setting ++@param [in] TunerDeviceAddr MAX3543 I2C device address ++@param [in] TunerCrystalFreqHz MAX3543 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildRtl2840Max3543Module() to build RTL2840 MAX3543 NIM module before using it. ++ ++*/ ++void ++BuildRtl2840Max3543Module( ++ QAM_NIM_MODULE **ppNim, // QAM NIM dependence ++ QAM_NIM_MODULE *pQamNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodEnhancementMode, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ) ++{ ++ QAM_NIM_MODULE *pNim; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pQamNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Set enhancement mode in NIM module. ++ pNim->EnhancementMode = DemodEnhancementMode; ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2840 QAM demod module. ++ BuildRtl2840Module( ++ &pNim->pDemod, ++ &pNim->QamDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodEnhancementMode ++ ); ++ ++ // Build MAX3543 tuner module. ++ BuildMax3543Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++ TunerCrystalFreqHz, ++ RTL2840_MAX3543_STANDARD_MODE_DEFAULT, ++ RTL2840_MAX3543_IF_FREQ_HZ_DEFAULT, ++ RTL2840_MAX3543_SAW_INPUT_TYPE_DEFAULT ++ ); ++ ++ ++ // Set NIM module manipulating function pointers. ++ pNim->Initialize = rtl2840_max3543_Initialize; ++ pNim->SetParameters = rtl2840_max3543_SetParameters; ++ ++ // Set NIM module manipulating function pointers with default. ++ pNim->GetNimType = qam_nim_default_GetNimType; ++ pNim->GetParameters = qam_nim_default_GetParameters; ++ pNim->IsSignalPresent = qam_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = qam_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = qam_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = qam_nim_default_GetSignalQuality; ++ pNim->GetErrorRate = qam_nim_default_GetErrorRate; ++ pNim->GetSnrDb = qam_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = qam_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = qam_nim_default_GetCrOffsetHz; ++ pNim->UpdateFunction = qam_nim_default_UpdateFunction; ++ ++ ++ // Set NIM type. ++ pNim->NimType = QAM_NIM_RTL2840_MAX3543; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2840_max3543_Initialize( ++ QAM_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2840_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {QAM_OPT_RF_AAGC_DRIVE, 0x1 }, ++ {QAM_OPT_IF_AAGC_DRIVE, 0x1 }, ++ {QAM_OPT_RF_AAGC_OEN, 0x1 }, ++ {QAM_OPT_IF_AAGC_OEN, 0x1 }, ++ {QAM_RF_AAGC_MAX, 0xff }, ++ {QAM_RF_AAGC_MIN, 0x0 }, ++ {QAM_IF_AAGC_MAX, 0xff }, ++ {QAM_IF_AAGC_MIN, 0x0 }, ++ {QAM_AAGC_MODE_SEL, 0x0 }, ++ }; ++ ++ ++ QAM_DEMOD_MODULE *pDemod; ++ TUNER_MODULE *pTuner; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ // Get demod module and tuner module. ++ pDemod = pNim->pDemod; ++ pTuner = pNim->pTuner; ++ ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency in Hz with NIM default. ++ if(pDemod->SetIfFreqHz(pDemod, RTL2840_MAX3543_IF_FREQ_HZ_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with NIM default. ++ if(pDemod->SetSpectrumMode(pDemod, RTL2840_MAX3543_SPECTRUM_MODE_DEFAULT) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod AAGC registers. ++ // Note: SetParameters() will set QAM_AAGC_TARGET and QAM_VTOP according to parameters. ++ for(i = 0; i < RTL2840_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2840_max3543_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ TUNER_MODULE *pTuner; ++ ++ ++ // Get demod module and tuner module. ++ pDemod = pNim->pDemod; ++ pTuner = pNim->pTuner; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod QAM mode. ++ if(pDemod->SetQamMode(pDemod, QamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod symbol rate in Hz. ++ if(pDemod->SetSymbolRateHz(pDemod, SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod alpha mode. ++ if(pDemod->SetAlphaMode(pDemod, AlphaMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set demod QAM_AAGC_TARGET and QAM_VTOP according to QAM mode and enhancement mode. ++ switch(QamMode) ++ { ++ default: ++ case QAM_QAM_4: ++ case QAM_QAM_16: ++ case QAM_QAM_32: ++ case QAM_QAM_64: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_VTOP, 0x3f) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ switch(pNim->EnhancementMode) ++ { ++ case QAM_DEMOD_EN_NONE: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_AAGC_TARGET, 0x6b) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ ++ default: ++ case QAM_DEMOD_EN_AM_HUM: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_AAGC_TARGET, 0x64) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ break; ++ ++ case QAM_QAM_128: ++ case QAM_QAM_256: ++ case QAM_QAM_512: ++ case QAM_QAM_1024: ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_VTOP, 0x38) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_AAGC_TARGET, 0x6b) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2840_max3543.h 2016-04-02 19:17:52.108066054 -0300 +@@ -0,0 +1,146 @@ ++#ifndef __NIM_RTL2840_MAX3543_H ++#define __NIM_RTL2840_MAX3543_H ++ ++/** ++ ++@file ++ ++@brief RTL2840 MAX3543 NIM module definition ++ ++One can manipulate RTL2840 MAX3543 NIM through RTL2840 MAX3543 NIM module. ++RTL2840 MAX3543 NIM module is derived from QAM NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in qam_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2840_max3543.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ QAM_NIM_MODULE *pNim; ++ QAM_NIM_MODULE QamNimModuleMemory; ++ ++ ... ++ ++ ++ ++ // Build RTL2840 MAX3543 NIM module. ++ BuildRtl2840Max3543Module( ++ &pNim, ++ &QamNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x44, // The RTL2840 I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2840 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2840 TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM, // Use AM-hum enhancement mode. ++ ++ 0xc0, // The MAX3543 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ // The MAX3543 Crystal frequency is 16.0 MHz. ++ ); ++ ++ ++ ++ // See the example for other NIM functions in qam_nim_base.h ++ ... ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2840.h" ++#include "tuner_max3543.h" ++#include "qam_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2840_MAX3543_ADDITIONAL_INIT_REG_TABLE_LEN 9 ++ ++// Default ++#define RTL2840_MAX3543_STANDARD_MODE_DEFAULT MAX3543_STANDARD_QAM ++#define RTL2840_MAX3543_IF_FREQ_HZ_DEFAULT IF_FREQ_36170000HZ ++#define RTL2840_MAX3543_SPECTRUM_MODE_DEFAULT SPECTRUM_INVERSE ++#define RTL2840_MAX3543_SAW_INPUT_TYPE_DEFAULT MAX3543_SAW_INPUT_SE ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2840Max3543Module( ++ QAM_NIM_MODULE **ppNim, // QAM NIM dependence ++ QAM_NIM_MODULE *pQamNimModuleMemory, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodEnhancementMode, ++ ++ unsigned char TunerDeviceAddr, // Tuner dependence ++ unsigned long TunerCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// RTL2840 MAX3543 NIM manipulaing functions ++int ++rtl2840_max3543_Initialize( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2840_max3543_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.c b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.c +--- a/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.c 2016-04-02 19:17:52.112066051 -0300 +@@ -0,0 +1,307 @@ ++/** ++ ++@file ++ ++@brief RTL2840 MT2063 NIM module definition ++ ++One can manipulate RTL2840 MT2063 NIM through RTL2840 MT2063 NIM module. ++RTL2840 MT2063 NIM module is derived from QAM NIM module. ++ ++*/ ++ ++ ++#include "nim_rtl2840_mt2063.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief RTL2840 MT2063 NIM module builder ++ ++Use BuildRtl2840Mt2063Module() to build RTL2840 MT2063 NIM module, set all module function pointers with the ++corresponding functions, and initialize module private variables. ++ ++ ++@param [in] ppNim Pointer to RTL2840 MT2063 NIM module pointer ++@param [in] pQamNimModuleMemory Pointer to an allocated QAM NIM module memory ++@param [in] I2cReadingByteNumMax Maximum I2C reading byte number for basic I2C reading function ++@param [in] I2cWritingByteNumMax Maximum I2C writing byte number for basic I2C writing function ++@param [in] I2cRead Basic I2C reading function pointer ++@param [in] I2cWrite Basic I2C writing function pointer ++@param [in] WaitMs Basic waiting function pointer ++@param [in] DemodDeviceAddr RTL2840 I2C device address ++@param [in] DemodCrystalFreqHz RTL2840 crystal frequency in Hz ++@param [in] DemodTsInterfaceMode RTL2840 TS interface mode for setting ++@param [in] DemodEnhancementMode RTL2840 enhancement mode for setting ++@param [in] TunerDeviceAddr MT2063 I2C device address ++ ++ ++@note ++ -# One should call BuildRtl2840Mt2063Module() to build RTL2840 MT2063 NIM module before using it. ++ ++*/ ++void ++BuildRtl2840Mt2063Module( ++ QAM_NIM_MODULE **ppNim, // QAM NIM dependence ++ QAM_NIM_MODULE *pQamNimModuleMemory, ++ unsigned long NimIfFreqHz, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodEnhancementMode, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ) ++{ ++ QAM_NIM_MODULE *pNim; ++ RTL2840_MT2063_EXTRA_MODULE *pNimExtra; ++ ++ ++ ++ // Set NIM module pointer with NIM module memory. ++ *ppNim = pQamNimModuleMemory; ++ ++ // Get NIM module. ++ pNim = *ppNim; ++ ++ // Set I2C bridge module pointer with I2C bridge module memory. ++ pNim->pI2cBridge = &pNim->I2cBridgeModuleMemory; ++ ++ // Get NIM extra module. ++ pNimExtra = &(pNim->Extra.Rtl2840Mt2063); ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pNim->pBaseInterface, ++ &pNim->BaseInterfaceModuleMemory, ++ I2cReadingByteNumMax, ++ I2cWritingByteNumMax, ++ I2cRead, ++ I2cWrite, ++ WaitMs ++ ); ++ ++ // Build RTL2840 QAM demod module. ++ BuildRtl2840Module( ++ &pNim->pDemod, ++ &pNim->QamDemodModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ DemodDeviceAddr, ++ DemodCrystalFreqHz, ++ DemodTsInterfaceMode, ++ DemodEnhancementMode ++ ); ++ ++ // Build MT2063 tuner module. ++ BuildMt2063Module( ++ &pNim->pTuner, ++ &pNim->TunerModuleMemory, ++ &pNim->BaseInterfaceModuleMemory, ++ &pNim->I2cBridgeModuleMemory, ++ TunerDeviceAddr, ++// MT2063_STANDARD_QAM, ++ MT2063_STANDARD_DVBT, ++ MT2063_VGAGC_0X1 ++ ); ++ ++ ++ // Set NIM module manipulating function pointers. ++ pNim->Initialize = rtl2840_mt2063_Initialize; ++ pNim->SetParameters = rtl2840_mt2063_SetParameters; ++ ++ // Set NIM module manipulating function pointers with default. ++ pNim->GetNimType = qam_nim_default_GetNimType; ++ pNim->GetParameters = qam_nim_default_GetParameters; ++ pNim->IsSignalPresent = qam_nim_default_IsSignalPresent; ++ pNim->IsSignalLocked = qam_nim_default_IsSignalLocked; ++ pNim->GetSignalStrength = qam_nim_default_GetSignalStrength; ++ pNim->GetSignalQuality = qam_nim_default_GetSignalQuality; ++ pNim->GetErrorRate = qam_nim_default_GetErrorRate; ++ pNim->GetSnrDb = qam_nim_default_GetSnrDb; ++ pNim->GetTrOffsetPpm = qam_nim_default_GetTrOffsetPpm; ++ pNim->GetCrOffsetHz = qam_nim_default_GetCrOffsetHz; ++ pNim->UpdateFunction = qam_nim_default_UpdateFunction; ++ ++ ++ // Set NIM type. ++ pNim->NimType = QAM_NIM_RTL2840_MT2063; ++ ++ // Set enhancement mode in NIM module. ++ pNim->EnhancementMode = DemodEnhancementMode; ++ ++ // Set IF frequency variable in NIM extra module. ++ pNimExtra->IfFreqHz = NimIfFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_INITIALIZE ++ ++*/ ++int ++rtl2840_mt2063_Initialize( ++ QAM_NIM_MODULE *pNim ++ ) ++{ ++ typedef struct ++ { ++ int RegBitName; ++ unsigned long Value; ++ } ++ REG_VALUE_ENTRY; ++ ++ ++ static const REG_VALUE_ENTRY AdditionalInitRegValueTable[RTL2840_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN] = ++ { ++ // RegBitName, Value ++ {QAM_OPT_RF_AAGC_DRIVE, 0x1 }, ++ {QAM_OPT_IF_AAGC_DRIVE, 0x1 }, ++ {QAM_OPT_RF_AAGC_OEN, 0x1 }, ++ {QAM_OPT_IF_AAGC_OEN, 0x1 }, ++ {QAM_RF_AAGC_MAX, 0x80 }, ++ {QAM_RF_AAGC_MIN, 0x80 }, ++ {QAM_IF_AAGC_MAX, 0xff }, ++ {QAM_IF_AAGC_MIN, 0x0 }, ++ {QAM_AAGC_MODE_SEL, 0x0 }, ++ }; ++ ++ ++ TUNER_MODULE *pTuner; ++ QAM_DEMOD_MODULE *pDemod; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ RTL2840_MT2063_EXTRA_MODULE *pNimExtra; ++ ++ int i; ++ ++ int RegBitName; ++ unsigned long Value; ++ ++ ++ // Get modules. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ pNimExtra = &(pNim->Extra.Rtl2840Mt2063); ++ ++ ++ // Initialize tuner. ++ if(pTuner->Initialize(pTuner) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner IF frequency in Hz. ++ if(pTunerExtra->SetIfFreqHz(pTuner, pNimExtra->IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Initialize demod. ++ if(pDemod->Initialize(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod IF frequency in Hz. ++ if(pDemod->SetIfFreqHz(pDemod, pNimExtra->IfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod spectrum mode with SPECTRUM_INVERSE. ++ if(pDemod->SetSpectrumMode(pDemod, SPECTRUM_INVERSE) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod AAGC registers. ++ // Note: SetParameters() will set QAM_AAGC_TARGET and QAM_VTOP according to parameters. ++ for(i = 0; i < RTL2840_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN; i++) ++ { ++ // Get register bit name and its value. ++ RegBitName = AdditionalInitRegValueTable[i].RegBitName; ++ Value = AdditionalInitRegValueTable[i].Value; ++ ++ // Set demod registers ++ if(pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, RegBitName, Value) != FUNCTION_SUCCESS) ++ goto error_status_set_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_registers: ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++rtl2840_mt2063_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module and tuner module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod QAM mode. ++ if(pDemod->SetQamMode(pDemod, QamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod symbol rate in Hz. ++ if(pDemod->SetSymbolRateHz(pDemod, SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod alpha mode. ++ if(pDemod->SetAlphaMode(pDemod, AlphaMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.h b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.h +--- a/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/nim_rtl2840_mt2063.h 2016-04-02 19:17:52.112066051 -0300 +@@ -0,0 +1,163 @@ ++#ifndef __NIM_RTL2840_MT2063_H ++#define __NIM_RTL2840_MT2063_H ++ ++/** ++ ++@file ++ ++@brief RTL2840 MT2063 NIM module definition ++ ++One can manipulate RTL2840 MT2063 NIM through RTL2840 MT2063 NIM module. ++RTL2840 MT2063 NIM module is derived from QAM NIM module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the NIM example in qam_nim_base.h except the listed lines. ++ ++ ++ ++#include "nim_rtl2840_mt2063.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ QAM_NIM_MODULE *pNim; ++ QAM_NIM_MODULE QamNimModuleMemory; ++ TUNER_MODULE *pTuner; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ ++ ... ++ ++ ++ ++ // Build RTL2840 MT2063 NIM module. ++ BuildRtl2840Mt2063Module( ++ &pNim, ++ &QamNimModuleMemory, ++ IF_FREQ_36125000HZ, // The RTL2840 and MT2063 IF frequency is 36.125 MHz. ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ 0x44, // The RTL2840 I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2840 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2840 TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM, // Use AM-hum enhancement mode. ++ ++ 0xc0 // The MT2063 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2063 tuner extra module. ++ pTuner = pNim->pTuner; ++ pTunerExtra = &(pTuner->Extra.Mt2063); ++ ++ // Open MT2063 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // See the example for other NIM functions in qam_nim_base.h ++ ... ++ ++ ++ ++ ++ ++ // Close MT2063 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "demod_rtl2840.h" ++#include "tuner_mt2063.h" ++#include "qam_nim_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define RTL2840_MT2063_ADDITIONAL_INIT_REG_TABLE_LEN 9 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildRtl2840Mt2063Module( ++ QAM_NIM_MODULE **ppNim, // QAM NIM dependence ++ QAM_NIM_MODULE *pQamNimModuleMemory, ++ unsigned long NimIfFreqHz, ++ ++ unsigned long I2cReadingByteNumMax, // Base interface dependence ++ unsigned long I2cWritingByteNumMax, ++ BASE_FP_I2C_READ I2cRead, ++ BASE_FP_I2C_WRITE I2cWrite, ++ BASE_FP_WAIT_MS WaitMs, ++ ++ unsigned char DemodDeviceAddr, // Demod dependence ++ unsigned long DemodCrystalFreqHz, ++ int DemodTsInterfaceMode, ++ int DemodEnhancementMode, ++ ++ unsigned char TunerDeviceAddr // Tuner dependence ++ ); ++ ++ ++ ++ ++ ++// RTL2840 MT2063 NIM manipulaing functions ++int ++rtl2840_mt2063_Initialize( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++int ++rtl2840_mt2063_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/qam_demod_base.c b/drivers/drivers/media/dvb/dvb-usb/qam_demod_base.c +--- a/drivers/media/dvb/dvb-usb/qam_demod_base.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/qam_demod_base.c 2016-04-02 19:17:52.112066051 -0300 +@@ -0,0 +1,1289 @@ ++/** ++ ++@file ++ ++@brief QAM demod default function definition ++ ++QAM demod default functions. ++ ++*/ ++ ++#include "qam_demod_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegPage( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBytes[LEN_2_BYTE]; ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Set demod register page with page number. ++ // Note: The I2C format of demod register page setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + QAM_DEMOD_PAGE_REG_ADDR + PageNo + stop_bit ++ WritingBytes[0] = QAM_DEMOD_PAGE_REG_ADDR; ++ WritingBytes[1] = (unsigned char)PageNo; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBytes, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ if( mutex_lock_interruptible(&d->usb_mutex) ) goto error; ++ ++ pDemod->CurrentPageNo = PageNo; ++ ++ mutex_unlock(&d->usb_mutex); ++ ++ return FUNCTION_SUCCESS; ++ ++error: ++ ++ return FUNCTION_ERROR; ++ ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = (unsigned char)(RegStartAddr + i); ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + ++ // stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned char WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ unsigned long PageNo=0; ++ ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ PageNo=pDemod->CurrentPageNo; ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(write_demod_register(d, DeviceAddr, PageNo, WritingBuffer[0], WritingBuffer+1, WritingByteNum)) ++ goto error_status_set_demod_registers; ++ ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++qam_demod_addr_8bit_default_GetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = (unsigned char)(RegStartAddr + i); ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned int i; ++ unsigned char DeviceAddr; ++ unsigned char ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ unsigned long PageNo; ++ ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); //add by chialing ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ PageNo=pDemod->CurrentPageNo; ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ // Get demod register bytes. ++ if(read_demod_register(d, DeviceAddr, PageNo, RegReadingAddr, pReadingBytes, ReadingByteNum)) ++ goto error_status_get_demod_registers; ++ ++ ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++//error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value LSB. ++ // Pick up upper address byte from value MSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * i)) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++qam_demod_addr_8bit_default_GetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->BaseRegTable.Addr8Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from base register table with register bit name key. ++ RegStartAddr = pDemod->BaseRegTable.Addr8Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->BaseRegTable.Addr8Bit[RegBitName].Msb; ++ Lsb = pDemod->BaseRegTable.Addr8Bit[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++qam_demod_addr_8bit_default_GetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->BaseRegTable.Addr8Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from base register table with register bit name key. ++ RegStartAddr = pDemod->BaseRegTable.Addr8Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->BaseRegTable.Addr8Bit[RegBitName].Msb; ++ Lsb = pDemod->BaseRegTable.Addr8Bit[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->RegAccess.Addr8Bit.GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++qam_demod_addr_8bit_default_SetRegBitsWithPage( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned char PageNo; ++ ++ ++ // Get register page number from base register table with register bit name key. ++ PageNo = pDemod->BaseRegTable.Addr8Bit[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Set register mask bits with register bit name key. ++ if(pDemod->RegAccess.Addr8Bit.SetRegBits(pDemod, RegBitName, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++*/ ++int ++qam_demod_addr_8bit_default_GetRegBitsWithPage( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned char PageNo; ++ ++ ++ // Get register page number from base register table with register bit name key. ++ PageNo = pDemod->BaseRegTable.Addr8Bit[RegBitName].PageNo; ++ ++ ++ // Set register page number. ++ if(pDemod->RegAccess.Addr8Bit.SetRegPage(pDemod, PageNo) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ // Get register mask bits with register bit name key. ++ if(pDemod->RegAccess.Addr8Bit.GetRegBits(pDemod, RegBitName, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BYTES ++ ++*/ ++int ++qam_demod_addr_16bit_default_SetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i, j; ++ ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned short RegWritingAddr; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set demod register bytes with writing bytes. ++ // Note: Set demod register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = (unsigned short)(RegStartAddr + i); ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddrMsb + RegWritingAddrLsb + ++ // writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = (RegWritingAddr >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = RegWritingAddr & BYTE_MASK; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_2_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set demod register bytes with writing buffer. ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, WritingByteNum + LEN_2_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BYTES ++ ++*/ ++int ++qam_demod_addr_16bit_default_GetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned long i; ++ unsigned char DeviceAddr; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned short RegReadingAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ ++ // Get base interface. ++ pBaseInterface = pDemod->pBaseInterface; ++ ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get demod register bytes. ++ // Note: Get demod register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = (unsigned short)(RegStartAddr + i); ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set demod register reading address. ++ // Note: The I2C format of demod register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddrMsb + RegReadingAddrLsb + stop_bit ++ WritingBuffer[0] = (RegReadingAddr >> BYTE_SHIFT) & BYTE_MASK; ++ WritingBuffer[1] = RegReadingAddr & BYTE_MASK; ++ ++ if(pBaseInterface->I2cWrite(pBaseInterface, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_register_reading_address; ++ ++ // Get demod register bytes. ++ // Note: The I2C format of demod register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pBaseInterface->I2cRead(pBaseInterface, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_register_reading_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_MASK_BITS ++ ++*/ ++int ++qam_demod_addr_16bit_default_SetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ unsigned char WritingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr16Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Reserve unsigned integer value unmask bit with mask and inlay writing value into it. ++ Value &= ~Mask; ++ Value |= (WritingValue << Shift) & Mask; ++ ++ ++ // Separate unsigned integer value into writing bytes. ++ // Note: Pick up lower address byte from value LSB. ++ // Pick up upper address byte from value MSB. ++ for(i = 0; i < ByteNum; i++) ++ WritingBytes[i] = (unsigned char)((Value >> (BYTE_SHIFT * i)) & BYTE_MASK); ++ ++ ++ // Write demod register bytes with writing bytes. ++ if(pDemod->RegAccess.Addr16Bit.SetRegBytes(pDemod, RegStartAddr, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_MASK_BITS ++ ++*/ ++int ++qam_demod_addr_16bit_default_GetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingBytes[LEN_4_BYTE]; ++ ++ unsigned char ByteNum; ++ unsigned long Mask; ++ unsigned char Shift; ++ ++ unsigned long Value; ++ ++ ++ // Calculate writing byte number according to MSB. ++ ByteNum = Msb / BYTE_BIT_NUM + LEN_1_BYTE; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (unsigned char)(Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get demod register bytes according to register start adddress and byte number. ++ if(pDemod->RegAccess.Addr16Bit.GetRegBytes(pDemod, RegStartAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ // Combine reading bytes into an unsigned integer value. ++ // Note: Put lower address byte on value LSB. ++ // Put upper address byte on value MSB. ++ Value = 0; ++ ++ for(i = 0; i < ByteNum; i++) ++ Value |= (unsigned long)ReadingBytes[i] << (BYTE_SHIFT * i); ++ ++ ++ // Get register bits from unsigned integaer value with mask and shift ++ *pReadingValue = (Value & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_SET_REG_BITS ++ ++*/ ++int ++qam_demod_addr_16bit_default_SetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ) ++{ ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->BaseRegTable.Addr16Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from base register table with register bit name key. ++ RegStartAddr = pDemod->BaseRegTable.Addr16Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->BaseRegTable.Addr16Bit[RegBitName].Msb; ++ Lsb = pDemod->BaseRegTable.Addr16Bit[RegBitName].Lsb; ++ ++ ++ // Set register mask bits. ++ if(pDemod->RegAccess.Addr16Bit.SetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, WritingValue) != FUNCTION_SUCCESS) ++ goto error_status_set_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_set_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_REG_BITS ++ ++*/ ++int ++qam_demod_addr_16bit_default_GetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ) ++{ ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++ ++ ++ // Check if register bit name is available. ++ if(pDemod->BaseRegTable.Addr16Bit[RegBitName].IsAvailable == NO) ++ goto error_status_register_bit_name; ++ ++ ++ // Get register start address, MSB, and LSB from base register table with register bit name key. ++ RegStartAddr = pDemod->BaseRegTable.Addr16Bit[RegBitName].RegStartAddr; ++ Msb = pDemod->BaseRegTable.Addr16Bit[RegBitName].Msb; ++ Lsb = pDemod->BaseRegTable.Addr16Bit[RegBitName].Lsb; ++ ++ ++ // Get register mask bits. ++ if(pDemod->RegAccess.Addr16Bit.GetRegMaskBits(pDemod, RegStartAddr, Msb, Lsb, pReadingValue) != FUNCTION_SUCCESS) ++ goto error_status_get_demod_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_register_bit_name: ++error_status_get_demod_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_DEMOD_TYPE ++ ++*/ ++void ++qam_demod_default_GetDemodType( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ) ++{ ++ // Get demod type from demod module. ++ *pDemodType = pDemod->DemodType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++qam_demod_default_GetDeviceAddr( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get demod I2C device address from demod module. ++ *pDeviceAddr = pDemod->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ ++ ++*/ ++void ++qam_demod_default_GetCrystalFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ) ++{ ++ // Get demod crystal frequency in Hz from demod module. ++ *pCrystalFreqHz = pDemod->CrystalFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_QAM_MODE ++ ++*/ ++int ++qam_demod_default_GetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ) ++{ ++ // Get demod QAM mode from demod module. ++ if(pDemod->IsQamModeSet != YES) ++ goto error_status_get_demod_qam_mode; ++ ++ *pQamMode = pDemod->QamMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_qam_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ ++ ++*/ ++int ++qam_demod_default_GetSymbolRateHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSymbolRateHz ++ ) ++{ ++ // Get demod symbol rate in Hz from demod module. ++ if(pDemod->IsSymbolRateHzSet != YES) ++ goto error_status_get_demod_symbol_rate; ++ ++ *pSymbolRateHz = pDemod->SymbolRateHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_symbol_rate: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_ALPHA_MODE ++ ++*/ ++int ++qam_demod_default_GetAlphaMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAlphaMode ++ ) ++{ ++ // Get demod alpha mode from demod module. ++ if(pDemod->IsAlphaModeSet != YES) ++ goto error_status_get_demod_alpha_mode; ++ ++ *pAlphaMode = pDemod->AlphaMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_alpha_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_IF_FREQ_HZ ++ ++*/ ++int ++qam_demod_default_GetIfFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ) ++{ ++ // Get demod IF frequency in Hz from demod module. ++ if(pDemod->IsIfFreqHzSet != YES) ++ goto error_status_get_demod_if_frequency; ++ ++ *pIfFreqHz = pDemod->IfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_if_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_DEMOD_FP_GET_SPECTRUM_MODE ++ ++*/ ++int ++qam_demod_default_GetSpectrumMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ) ++{ ++ // Get demod spectrum mode from demod module. ++ if(pDemod->IsSpectrumModeSet != YES) ++ goto error_status_get_demod_spectrum_mode; ++ ++ *pSpectrumMode = pDemod->SpectrumMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_spectrum_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/qam_demod_base.h b/drivers/drivers/media/dvb/dvb-usb/qam_demod_base.h +--- a/drivers/media/dvb/dvb-usb/qam_demod_base.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/qam_demod_base.h 2016-04-02 19:17:52.112066051 -0300 +@@ -0,0 +1,2818 @@ ++#ifndef __QAM_DEMOD_BASE_H ++#define __QAM_DEMOD_BASE_H ++ ++/** ++ ++@file ++ ++@brief QAM demod base module definition ++ ++QAM demod base module definitions contains demod module structure, demod funciton pointers, and demod definitions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_xxx.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ++ ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ int QamMode; ++ unsigned long SymbolRateHz; ++ int AlphaMode; ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ ++ long RfAgc, IfAgc; ++ unsigned long DiAgc; ++ ++ int Answer; ++ long TrOffsetPpm, CrOffsetHz; ++ unsigned long BerNum, BerDen, PerNum, PerDen; ++ double Ber, Per; ++ long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ unsigned long SignalStrength, SignalQuality; ++ ++ ++ ++ // Build base interface module. ++ BuildBaseInterface( ++ &pBaseInterface, ++ &BaseInterfaceModuleMemory, ++ 9, // Set maximum I2C reading byte number with 9. ++ 8, // Set maximum I2C writing byte number with 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs // Employ CustomWaitMs() as basic waiting function. ++ ); ++ ++ ++ // Build QAM demod XXX module. ++ BuildXxxModule( ++ &pDemod, ++ &QamDemodModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0x44, // Demod I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // Demod crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // Demod TS interface mode is serial. ++ ... // Other arguments by each demod module ++ ); ++ ++ ++ ++ ++ ++ // ==== Initialize QAM demod and set its parameters ===== ++ ++ // Initialize demod. ++ pDemod->Initialize(pDemod); ++ ++ ++ // Set demod parameters. (QAM mode, symbol rate, alpha mode, IF frequency, spectrum mode) ++ // Note: In the example: ++ // 1. QAM is 64. ++ // 2. Symbol rate is 6.952 MHz. ++ // 3. Alpha is 0.15. ++ // 4. IF frequency is 36 MHz. ++ // 5. Spectrum mode is SPECTRUM_INVERSE. ++ QamMode = QAM_QAM_64; ++ SymbolRateHz = 6952000; ++ AlphaMode = QAM_ALPHA_0P15; ++ IfFreqHz = IF_FREQ_36000000HZ; ++ SpectrumMode = SPECTRUM_INVERSE; ++ ++ pDemod->SetQamMode(pDemod, QamMode); ++ pDemod->SetSymbolRateHz(pDemod, SymbolRateHz); ++ pDemod->SetAlphaMode(pDemod, AlphaMode); ++ pDemod->SetIfFreqHz(pDemod, IfFreqHz); ++ pDemod->SetSpectrumMode(pDemod, SpectrumMode); ++ ++ ++ // Need to set tuner before demod software reset. ++ // The order to set demod and tuner is not important. ++ // Note: 1. For 8-bit register address demod, one can use ++ // "pDemod->RegAccess.Addr8Bit.SetRegBitsWithPage(pDemod, QAM_OPT_I2C_RELAY, 0x1);" ++ // for tuner I2C command forwarding. ++ // 2. For 16-bit register address demod, one can use ++ // "pDemod->RegAccess.Addr16Bit.SetRegBits(pDemod, QAM_OPT_I2C_RELAY, 0x1);" ++ // for tuner I2C command forwarding. ++ ++ ++ // Reset demod by software reset. ++ pDemod->SoftwareReset(pDemod); ++ ++ ++ // Wait maximum 1000 ms for demod converge. ++ for(i = 0; i < 25; i++) ++ { ++ // Wait 40 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 40); ++ ++ // Check signal lock status through frame lock. ++ // Note: If Answer is YES, frame is locked. ++ // If Answer is NO, frame is not locked. ++ pDemod->IsFrameLocked(pDemod, &Answer); ++ ++ if(Answer == YES) ++ { ++ // Signal is locked. ++ break; ++ } ++ } ++ ++ ++ ++ ++ ++ // ==== Get QAM demod information ===== ++ ++ // Get demod type. ++ // Note: One can find demod type in MODULE_TYPE enumeration. ++ pDemod->GetDemodType(pDemod, &DemodType); ++ ++ // Get demod I2C device address. ++ pDemod->GetDeviceAddr(pDemod, &DeviceAddr); ++ ++ // Get demod crystal frequency in Hz. ++ pDemod->GetCrystalFreqHz(pDemod, &CrystalFreqHz); ++ ++ ++ // Ask demod if it is connected to I2C bus. ++ // Note: If Answer is YES, demod is connected to I2C bus. ++ // If Answer is NO, demod is not connected to I2C bus. ++ pDemod->IsConnectedToI2c(pDemod, &Answer); ++ ++ ++ // Get demod parameters. (QAM mode, symbol rate, alpha mode, IF frequency, spectrum mode) ++ pDemod->GetQamMode(pDemod, &QamMode); ++ pDemod->GetSymbolRateHz(pDemod, &SymbolRateHz); ++ pDemod->GetAlphaMode(pDemod, &AlphaMode); ++ pDemod->GetIfFreqHz(pDemod, &IfFreqHz); ++ pDemod->GetSpectrumMode(pDemod, &SpectrumMode); ++ ++ ++ // Get demod AGC value. ++ // Note: The range of RF AGC and IF AGC value is -1024 ~ 1023. ++ // The range of digital AGC value is 0 ~ 134217727. ++ pDemod->GetRfAgc(pDemod, &RfAgc); ++ pDemod->GetIfAgc(pDemod, &IfAgc); ++ pDemod->GetDiAgc(pDemod, &DiAgc); ++ ++ ++ // Get demod lock status. ++ // Note: If Answer is YES, it is locked. ++ // If Answer is NO, it is not locked. ++ pDemod->IsAagcLocked(pDemod, &Answer); ++ pDemod->IsEqLocked(pDemod, &Answer); ++ pDemod->IsFrameLocked(pDemod, &Answer); ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pDemod->GetTrOffsetPpm(pDemod, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pDemod->GetCrOffsetHz(pDemod, &CrOffsetHz); ++ ++ ++ // Get BER and PER. ++ // Note: Test packet number = pow(2, (2 * 5 + 4)) = 16384 ++ // Maximum wait time = 1000 ms = 1 second ++ pDemod->GetErrorRate(pDemod, 5, 1000, &BerNum, &BerDen, &PerNum, &PerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ Per = (double)PerNum / (double)PerDen; ++ ++ // Get SNR in dB. ++ pDemod->GetSnrDb(pDemod, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pDemod->GetSignalStrength(pDemod, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pDemod->GetSignalQuality(pDemod, &SignalQuality); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// Page register address ++#define QAM_DEMOD_PAGE_REG_ADDR 0x0 ++ ++ ++/// QAM QAM modes ++enum QAM_QAM_MODE ++{ ++ QAM_QAM_4, ///< QPSK ++ QAM_QAM_16, ///< 16 QAM ++ QAM_QAM_32, ///< 32 QAM ++ QAM_QAM_64, ///< 64 QAM ++ QAM_QAM_128, ///< 128 QAM ++ QAM_QAM_256, ///< 256 QAM ++ QAM_QAM_512, ///< 512 QAM ++ QAM_QAM_1024, ///< 1024 QAM ++}; ++#define QAM_QAM_MODE_NUM 8 ++ ++ ++/// QAM alpha modes ++enum QAM_ALPHA_MODE ++{ ++ QAM_ALPHA_0P12, ///< Alpha = 0.12 ++ QAM_ALPHA_0P13, ///< Alpha = 0.13 ++ QAM_ALPHA_0P15, ///< Alpha = 0.15 ++ QAM_ALPHA_0P18, ///< Alpha = 0.18 ++ QAM_ALPHA_0P20, ///< Alpha = 0.20 ++}; ++#define QAM_ALPHA_MODE_NUM 5 ++ ++ ++/// QAM demod enhancement modes ++enum QAM_DEMOD_EN_MODE ++{ ++ QAM_DEMOD_EN_NONE, ///< None demod enhancement ++ QAM_DEMOD_EN_AM_HUM, ///< AM-hum demod enhancement ++}; ++#define QAM_DEMOD_EN_MODE_NUM 2 ++ ++ ++/// QAM demod configuration mode ++enum QAM_DEMOD_CONFIG_MODE ++{ ++ QAM_DEMOD_CONFIG_OC, ///< OpenCable demod configuration ++ QAM_DEMOD_CONFIG_DVBC, ///< DVB-C demod configuration ++}; ++#define QAM_DEMOD_CONFIG_MODE_NUM 2 ++ ++ ++ ++ ++ ++// Register entry definitions ++ ++// Base register entry for 8-bit address ++typedef struct ++{ ++ int IsAvailable; ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++QAM_BASE_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Primary base register entry for 8-bit address ++typedef struct ++{ ++ int RegBitName; ++ unsigned char PageNo; ++ unsigned char RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++QAM_PRIMARY_BASE_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Monitor register entry for 8-bit address ++#define QAM_MONITOR_REG_INFO_TABLE_LEN 2 ++typedef struct ++{ ++ int IsAvailable; ++ unsigned char InfoNum; ++ ++ struct ++ { ++ unsigned char SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ } ++ InfoTable[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++} ++QAM_MONITOR_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Primary monitor register entry for 8-bit address ++typedef struct ++{ ++ int MonitorRegBitName; ++ unsigned char InfoNum; ++ ++ struct ++ { ++ unsigned char SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ } ++ InfoTable[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++} ++QAM_PRIMARY_MONITOR_REG_ENTRY_ADDR_8BIT; ++ ++ ++ ++// Base register entry for 16-bit address ++typedef struct ++{ ++ int IsAvailable; ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++QAM_BASE_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++// Primary base register entry for 16-bit address ++typedef struct ++{ ++ int RegBitName; ++ unsigned short RegStartAddr; ++ unsigned char Msb; ++ unsigned char Lsb; ++} ++QAM_PRIMARY_BASE_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++// Monitor register entry for 16-bit address ++#define QAM_MONITOR_REG_INFO_TABLE_LEN 2 ++typedef struct ++{ ++ int IsAvailable; ++ unsigned char InfoNum; ++ ++ struct ++ { ++ unsigned short SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ } ++ InfoTable[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++} ++QAM_MONITOR_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++// Primary monitor register entry for 16-bit address ++typedef struct ++{ ++ int MonitorRegBitName; ++ unsigned char InfoNum; ++ ++ struct ++ { ++ unsigned short SelRegAddr; ++ unsigned char SelValue; ++ int RegBitName; ++ unsigned char Shift; ++ } ++ InfoTable[QAM_MONITOR_REG_INFO_TABLE_LEN]; ++} ++QAM_PRIMARY_MONITOR_REG_ENTRY_ADDR_16BIT; ++ ++ ++ ++ ++ ++// Register bit name definitions ++ ++/// Base register bit name ++enum QAM_REG_BIT_NAME ++{ ++ // Generality ++ QAM_SYS_VERSION, ++ QAM_OPT_I2C_RELAY, ++ QAM_I2CT_EN_CTRL, // for RTL2836B DVB-C only ++ QAM_SOFT_RESET, ++ QAM_SOFT_RESET_FF, ++ ++ // Miscellany ++ QAM_OPT_I2C_DRIVE_CURRENT, ++ QAM_GPIO2_OEN, ++ QAM_GPIO3_OEN, ++ QAM_GPIO2_O, ++ QAM_GPIO3_O, ++ QAM_GPIO2_I, ++ QAM_GPIO3_I, ++ QAM_INNER_DATA_STROBE, ++ QAM_INNER_DATA_SEL1, ++ QAM_INNER_DATA_SEL2, ++ QAM_INNER_DATA1, ++ QAM_INNER_DATA2, ++ ++ // QAM mode ++ QAM_QAM_MODE, ++ ++ // AD ++ QAM_AD_AV, // for RTL2840 only ++ ++ // AAGC ++ QAM_OPT_RF_AAGC_DRIVE_CURRENT, // for RTL2840, RTD2885 QAM only ++ QAM_OPT_IF_AAGC_DRIVE_CURRENT, // for RTL2840, RTD2885 QAM only ++ QAM_AGC_DRIVE_LV, // for RTL2836B DVB-C only ++ QAM_DVBC_RSSI_R, // for RTL2836B DVB-C only ++ QAM_OPT_RF_AAGC_DRIVE, ++ QAM_OPT_IF_AAGC_DRIVE, ++ QAM_OPT_RF_AAGC_OEN, // for RTL2840 only ++ QAM_OPT_IF_AAGC_OEN, // for RTL2840 only ++ QAM_PAR_RF_SD_IB, ++ QAM_PAR_IF_SD_IB, ++ QAM_AAGC_FZ_OPTION, ++ QAM_AAGC_TARGET, ++ QAM_RF_AAGC_MAX, ++ QAM_RF_AAGC_MIN, ++ QAM_IF_AAGC_MAX, ++ QAM_IF_AAGC_MIN, ++ QAM_VTOP, ++ QAM_KRF, // for RTD2885 QAM only ++ QAM_KRF_MSB, ++ QAM_KRF_LSB, ++ QAM_AAGC_MODE_SEL, ++ QAM_AAGC_LD, ++ QAM_OPT_RF_AAGC_OE, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_OPT_IF_AAGC_OE, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_IF_AGC_DRIVING, // for RTL2820 OpenCable only ++ QAM_RF_AGC_DRIVING, // for RTL2820 OpenCable only ++ QAM_AAGC_INIT_LEVEL, ++ ++ // DDC ++ QAM_DDC_FREQ, ++ QAM_SPEC_INV, ++ ++ // Timing recovery ++ QAM_TR_DECI_RATIO, ++ ++ // Carrier recovery ++ QAM_CR_LD, ++ ++ // Equalizer ++ QAM_EQ_LD, ++ QAM_MSE, ++ ++ // Frame sync. indicator ++ QAM_SYNCLOST, // for RTL2840, RTD2885 QAM only ++ QAM_FS_SYNC_STROBE, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_FS_SYNC_LOST, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_OC_MPEG_SYNC_MODE, ++ ++ ++ // BER ++ QAM_BER_RD_STROBE, ++ QAM_BERT_EN, ++ QAM_BERT_HOLD, ++ QAM_DIS_AUTO_MODE, ++ QAM_TEST_VOLUME, ++ QAM_BER_REG0, ++ QAM_BER_REG1, ++ QAM_BER_REG2_15_0, ++ QAM_BER_REG2_18_16, ++ ++ QAM_OC_BER_RD_STROBE, // for RTD2885 QAM only ++ QAM_OC_BERT_EN, // for RTD2885 QAM only ++ QAM_OC_BERT_HOLD, // for RTD2885 QAM only ++ QAM_OC_DIS_AUTO_MODE, // for RTD2885 QAM only ++ QAM_OC_TEST_VOLUME, // for RTD2885 QAM only ++ QAM_OC_BER_REG0, // for RTD2885 QAM only ++ QAM_OC_BER_REG1, // for RTD2885 QAM only ++ QAM_OC_BER_REG2_15_0, // for RTD2885 QAM only ++ QAM_OC_BER_REG2_18_16, // for RTD2885 QAM only ++ ++ QAM_DVBC_BER_RD_STROBE, // for RTD2885 QAM only ++ QAM_DVBC_BERT_EN, // for RTD2885 QAM only ++ QAM_DVBC_BERT_HOLD, // for RTD2885 QAM only ++ QAM_DVBC_DIS_AUTO_MODE, // for RTD2885 QAM only ++ QAM_DVBC_TEST_VOLUME, // for RTD2885 QAM only ++ QAM_DVBC_BER_REG0, // for RTD2885 QAM only ++ QAM_DVBC_BER_REG1, // for RTD2885 QAM only ++ QAM_DVBC_BER_REG2_15_0, // for RTD2885 QAM only ++ QAM_DVBC_BER_REG2_18_16, // for RTD2885 QAM only ++ ++ ++ // MPEG TS output interface ++ QAM_OPT_MPEG_OUT_SEL, // for RTD2648 QAM only ++ QAM_CKOUTPAR, ++ QAM_CKOUT_PWR, ++ QAM_CDIV_PH0, ++ QAM_CDIV_PH1, ++ QAM_MPEG_OUT_EN, // for RTL2840 only ++ QAM_OPT_MPEG_DRIVE_CURRENT, // for RTL2840 only ++ QAM_NO_REINVERT, // for RTL2840 only ++ QAM_FIX_TEI, // for RTL2840 only ++ QAM_SERIAL, // for RTL2840 only ++ QAM_OPT_MPEG_IO, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_OPT_M_OEN, // for RTL2820 OpenCable, RTD2885 QAM only ++ QAM_REPLA_SD_EN, // for RTL2820 OpenCable only ++ QAM_TEI_SD_ERR_EN, // for RTL2820 OpenCable only ++ QAM_TEI_RS_ERR_EN, // for RTL2820 OpenCable only ++ QAM_SET_MPEG_ERR, // for RTL2820 OpenCable only ++ ++ QAM_OC_CKOUTPAR, // for RTD2885 QAM only ++ QAM_OC_CKOUT_PWR, // for RTD2885 QAM only ++ QAM_OC_CDIV_PH0, // for RTD2885 QAM only ++ QAM_OC_CDIV_PH1, // for RTD2885 QAM only ++ QAM_OC_SERIAL, // for RTD2885 QAM only ++ ++ QAM_DVBC_CKOUTPAR, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_CKOUT_PWR, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_CDIV_PH0, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_CDIV_PH1, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_NO_REINVERT, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_FIX_TEI, // for RTD2885 QAM, RTL2836B DVB-C only ++ QAM_DVBC_SERIAL, // for RTD2885 QAM, RTL2836B DVB-C only ++ ++ ++ // Monitor ++ QAM_ADC_CLIP_CNT_REC, ++ QAM_DAGC_LEVEL_26_11, ++ QAM_DAGC_LEVEL_10_0, ++ QAM_RF_AAGC_SD_IN, ++ QAM_IF_AAGC_SD_IN, ++ QAM_KI_TR_OUT_30_15, ++ QAM_KI_TR_OUT_14_0, ++ QAM_KI_CR_OUT_15_0, ++ QAM_KI_CR_OUT_31_16, ++ ++ // Specific register ++ QAM_SPEC_SIGNAL_INDICATOR, ++ QAM_SPEC_ALPHA_STROBE, ++ QAM_SPEC_ALPHA_SEL, ++ QAM_SPEC_ALPHA_VAL, ++ QAM_SPEC_SYMBOL_RATE_REG_0, ++ QAM_SPEC_SYMBOL_RATE_STROBE, ++ QAM_SPEC_SYMBOL_RATE_SEL, ++ QAM_SPEC_SYMBOL_RATE_VAL, ++ QAM_SPEC_REG_0_STROBE, ++ QAM_SPEC_REG_0_SEL, ++ QAM_SPEC_INIT_A0, // for RTL2840 only ++ QAM_SPEC_INIT_A1, // for RTL2840 only ++ QAM_SPEC_INIT_A2, // for RTL2840 only ++ QAM_SPEC_INIT_B0, // for RTL2820 OpenCable only ++ QAM_SPEC_INIT_C1, // for RTL2820 OpenCable only ++ QAM_SPEC_INIT_C2, // for RTL2820 OpenCable only ++ QAM_SPEC_INIT_C3, // for RTL2820 OpenCable only ++ ++ // GPIO ++ QAM_OPT_GPIOA_OE, // for RTL2836B DVB-C only ++ ++ // Pseudo register for test only ++ QAM_TEST_REG_0, ++ QAM_TEST_REG_1, ++ QAM_TEST_REG_2, ++ QAM_TEST_REG_3, ++ ++ ++ // Item terminator ++ QAM_REG_BIT_NAME_ITEM_TERMINATOR, ++}; ++ ++ ++/// Monitor register bit name ++enum QAM_MONITOR_REG_BIT_NAME ++{ ++ // Generality ++ QAM_ADC_CLIP_CNT, ++ QAM_DAGC_VALUE, ++ QAM_RF_AGC_VALUE, ++ QAM_IF_AGC_VALUE, ++ QAM_TR_OFFSET, ++ QAM_CR_OFFSET, ++ ++ // Specific monitor register ++ QAM_SPEC_MONITER_INIT_0, ++ ++ // Item terminator ++ QAM_MONITOR_REG_BIT_NAME_ITEM_TERMINATOR, ++}; ++ ++ ++ ++// Register table length definitions ++#define QAM_BASE_REG_TABLE_LEN_MAX QAM_REG_BIT_NAME_ITEM_TERMINATOR ++#define QAM_MONITOR_REG_TABLE_LEN_MAX QAM_MONITOR_REG_BIT_NAME_ITEM_TERMINATOR ++ ++ ++ ++ ++ ++/// QAM demod module pre-definition ++typedef struct QAM_DEMOD_MODULE_TAG QAM_DEMOD_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register page setting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_PAGE() to set demod register page. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] PageNo Page number ++ ++ ++@retval FUNCTION_SUCCESS Set register page successfully with page number. ++@retval FUNCTION_ERROR Set register page unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_PAGE() with the corresponding function. ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register page with page number 2. ++ pDemod->SetRegPage(pDemod, 2); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_PAGE)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register byte setting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_BYTES() to set demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] pWritingBytes Pointer to writing bytes ++@param [in] ByteNum Writing byte number ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bytes successfully with writing bytes. ++@retval FUNCTION_ERROR Set demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by QAM_DEMOD_FP_SET_REG_PAGE() before using QAM_DEMOD_FP_SET_REG_BYTES(). ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_GET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char WritingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bytes (page 1, address 0x17 ~ 0x1b) with 5 writing bytes. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBytes(pDemod, 0x17, WritingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BYTES)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_SET_REG_BYTES)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register byte getting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_GET_REG_BYTES() to get demod register bytes. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [out] pReadingBytes Pointer to an allocated memory for storing reading bytes ++@param [in] ByteNum Reading byte number ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bytes successfully with reading byte number. ++@retval FUNCTION_ERROR Get demod register bytes unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_REG_BYTES() with the corresponding function. ++ -# Need to set register page by QAM_DEMOD_FP_SET_REG_PAGE() before using QAM_DEMOD_FP_GET_REG_BYTES(). ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_SET_REG_BYTES ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned char ReadingBytes[10]; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bytes (page 1, address 0x17 ~ 0x1b) with reading byte number 5. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBytes(pDemod, 0x17, ReadingBytes, 5); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BYTES)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_GET_REG_BYTES)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register mask bits setting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_MASK_BITS() to set demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register mask bits successfully with writing value. ++@retval FUNCTION_ERROR Set demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by QAM_DEMOD_FP_SET_REG_PAGE() before using QAM_DEMOD_FP_SET_REG_MASK_BITS(). ++ -# The constraints of QAM_DEMOD_FP_SET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_GET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits (page 1, address {0x18, 0x17} [12:5]) with writing value 0x1d. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegMaskBits(pDemod, 0x17, 12, 5, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_MASK_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_SET_REG_MASK_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register mask bits getting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_GET_REG_MASK_BITS() to get demod register mask bits. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegStartAddr Demod register start address ++@param [in] Msb Mask MSB with 0-based index ++@param [in] Lsb Mask LSB with 0-based index ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register mask bits successfully. ++@retval FUNCTION_ERROR Get demod register mask bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_REG_MASK_BITS() with the corresponding function. ++ -# Need to set register page by QAM_DEMOD_FP_SET_REG_PAGE() before using QAM_DEMOD_FP_GET_REG_MASK_BITS(). ++ -# The constraints of QAM_DEMOD_FP_GET_REG_MASK_BITS() function usage are described as follows: ++ -# The mask MSB and LSB must be 0~31. ++ -# The mask MSB must be greater than or equal to LSB. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_SET_REG_MASK_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits (page 1, address {0x18, 0x17} [12:5]). ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegMaskBits(pDemod, 0x17, 12, 5, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_GET_REG_MASK_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_GET_REG_MASK_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register bits setting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_BITS() to set demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using QAM_DEMOD_FP_SET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_GET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->SetRegBits(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_SET_REG_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register bits getting function pointer ++ ++Demod upper level functions will use QAM_DEMOD_FP_GET_REG_BITS() to get demod register bits with bit name. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_REG_BITS() with the corresponding function. ++ -# Need to set register page before using QAM_DEMOD_FP_GET_REG_BITS(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_PAGE, QAM_DEMOD_FP_SET_REG_BITS ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegPage(pDemod, 1); ++ pDemod->GetRegBits(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++typedef int ++(*QAM_DEMOD_FP_ADDR_16BIT_GET_REG_BITS)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register bits setting function pointer (with page setting) ++ ++Demod upper level functions will use QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE() to set demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [in] WritingValue The mask bits writing value ++ ++ ++@retval FUNCTION_SUCCESS Set demod register bits successfully with bit name, page setting, and writing value. ++@retval FUNCTION_ERROR Set demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Set demod register bits with bit name PSEUDO_REG_BIT_NAME and writing value 0x1d. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->SetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, 0x1d); ++ ++ ++ // Result: ++ // ++ // Writing value = 0x1d = 0001 1101 b ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BITS_WITH_PAGE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod register bits getting function pointer (with page setting) ++ ++Demod upper level functions will use QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE() to get demod register bits with bit name and ++page setting. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] RegBitName Pre-defined demod register bit name ++@param [out] pReadingValue Pointer to an allocated memory for storing reading value ++ ++ ++@retval FUNCTION_SUCCESS Get demod register bits successfully with bit name and page setting. ++@retval FUNCTION_ERROR Get demod register bits unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE() with the corresponding function. ++ -# Don't need to set register page before using QAM_DEMOD_FP_GET_REG_BITS_WITH_PAGE(). ++ -# Register bit names are pre-defined keys for bit access, and one can find these in demod header file. ++ ++ ++@see QAM_DEMOD_FP_SET_REG_BITS_WITH_PAGE ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE DvbcDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ unsigned long ReadingValue; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &DvbcDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Get demod register bits with bit name PSEUDO_REG_BIT_NAME. ++ // The corresponding information of PSEUDO_REG_BIT_NAME is address {0x18, 0x17} [12:5] on page 1. ++ pDemod->GetRegBitsWithPage(pDemod, PSEUDO_REG_BIT_NAME, &ReadingValue); ++ ++ ++ // Result: ++ // ++ // Page 1 ++ // Register address 0x18 0x17 ++ // Register value xxx0 0011 b 101x xxxx b ++ // ++ // Reading value = 0001 1101 b = 0x1d ++ ++ ... ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BITS_WITH_PAGE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// Demod register access for 8-bit address ++typedef struct ++{ ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_PAGE SetRegPage; ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BYTES SetRegBytes; ++ QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BYTES GetRegBytes; ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_MASK_BITS SetRegMaskBits; ++ QAM_DEMOD_FP_ADDR_8BIT_GET_REG_MASK_BITS GetRegMaskBits; ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BITS SetRegBits; ++ QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BITS GetRegBits; ++ QAM_DEMOD_FP_ADDR_8BIT_SET_REG_BITS_WITH_PAGE SetRegBitsWithPage; ++ QAM_DEMOD_FP_ADDR_8BIT_GET_REG_BITS_WITH_PAGE GetRegBitsWithPage; ++} ++QAM_DEMOD_REG_ACCESS_ADDR_8BIT; ++ ++ ++ ++ ++ ++// Demod register access for 16-bit address ++typedef struct ++{ ++ QAM_DEMOD_FP_ADDR_16BIT_SET_REG_BYTES SetRegBytes; ++ QAM_DEMOD_FP_ADDR_16BIT_GET_REG_BYTES GetRegBytes; ++ QAM_DEMOD_FP_ADDR_16BIT_SET_REG_MASK_BITS SetRegMaskBits; ++ QAM_DEMOD_FP_ADDR_16BIT_GET_REG_MASK_BITS GetRegMaskBits; ++ QAM_DEMOD_FP_ADDR_16BIT_SET_REG_BITS SetRegBits; ++ QAM_DEMOD_FP_ADDR_16BIT_GET_REG_BITS GetRegBits; ++} ++QAM_DEMOD_REG_ACCESS_ADDR_16BIT; ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod type getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_DEMOD_TYPE() to get QAM demod type. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDemodType Pointer to an allocated memory for storing demod type ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_DEMOD_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*QAM_DEMOD_FP_GET_DEMOD_TYPE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod I2C device address getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_DEVICE_ADDR() to get QAM demod I2C device address. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDeviceAddr Pointer to an allocated memory for storing demod I2C device address ++ ++ ++@retval FUNCTION_SUCCESS Get demod device address successfully. ++@retval FUNCTION_ERROR Get demod device address unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_DEVICE_ADDR() with the corresponding function. ++ ++*/ ++typedef void ++(*QAM_DEMOD_FP_GET_DEVICE_ADDR)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod crystal frequency getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() to get QAM demod crystal frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrystalFreqHz Pointer to an allocated memory for storing demod crystal frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod crystal frequency successfully. ++@retval FUNCTION_ERROR Get demod crystal frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef void ++(*QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod I2C bus connection asking function pointer ++ ++One can use QAM_DEMOD_FP_IS_CONNECTED_TO_I2C() to ask QAM demod if it is connected to I2C bus. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_IS_CONNECTED_TO_I2C() with the corresponding function. ++ ++*/ ++typedef void ++(*QAM_DEMOD_FP_IS_CONNECTED_TO_I2C)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod software resetting function pointer ++ ++One can use QAM_DEMOD_FP_SOFTWARE_RESET() to reset QAM demod by software reset. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod by software reset successfully. ++@retval FUNCTION_ERROR Reset demod by software reset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SOFTWARE_RESET() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SOFTWARE_RESET)( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod initializing function pointer ++ ++One can use QAM_DEMOD_FP_INITIALIZE() to initialie QAM demod. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize demod successfully. ++@retval FUNCTION_ERROR Initialize demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_INITIALIZE)( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod QAM mode setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_QAM_MODE() to set QAM demod QAM mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] QamMode QAM mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod QAM mode successfully. ++@retval FUNCTION_ERROR Set demod QAM mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_QAM_MODE() with the corresponding function. ++ ++ ++@see QAM_QAM_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_QAM_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int QamMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod symbol rate setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ() to set QAM demod symbol rate in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] SymbolRateHz Symbol rate in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod symbol rate successfully. ++@retval FUNCTION_ERROR Set demod symbol rate unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long SymbolRateHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod alpha mode setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_ALPHA_MODE() to set QAM demod alpha mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] AlphaMode Alpha mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod alpha mode successfully. ++@retval FUNCTION_ERROR Set demod alpha mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_ALPHA_MODE() with the corresponding function. ++ ++ ++@see QAM_ALPHA_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_ALPHA_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int AlphaMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod IF frequency setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_IF_FREQ_HZ() to set QAM demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] IfFreqHz IF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod IF frequency successfully. ++@retval FUNCTION_ERROR Set demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_IF_FREQ_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long IfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod spectrum mode setting function pointer ++ ++One can use QAM_DEMOD_FP_SET_SPECTRUM_MODE() to set QAM demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] SpectrumMode Spectrum mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set demod spectrum mode successfully. ++@retval FUNCTION_ERROR Set demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_SET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_SET_SPECTRUM_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int SpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod QAM mode getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_QAM_MODE() to get QAM demod QAM mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pQamMode Pointer to an allocated memory for storing demod QAM mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod QAM mode successfully. ++@retval FUNCTION_ERROR Get demod QAM mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_QAM_MODE() with the corresponding function. ++ ++ ++@see QAM_QAM_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_QAM_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod symbol rate getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ() to get QAM demod symbol rate in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSymbolRateHz Pointer to an allocated memory for storing demod symbol rate in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod symbol rate successfully. ++@retval FUNCTION_ERROR Get demod symbol rate unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSymbolRateHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod alpha mode getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_ALPHA_MODE() to get QAM demod alpha mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAlphaMode Pointer to an allocated memory for storing demod alpha mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod alpha mode successfully. ++@retval FUNCTION_ERROR Get demod alpha mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_ALPHA_MODE() with the corresponding function. ++ ++ ++@see QAM_ALPHA_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_ALPHA_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAlphaMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod IF frequency getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_IF_FREQ_HZ() to get QAM demod IF frequency in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfFreqHz Pointer to an allocated memory for storing demod IF frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF frequency successfully. ++@retval FUNCTION_ERROR Get demod IF frequency unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_IF_FREQ_HZ() with the corresponding function. ++ ++ ++@see IF_FREQ_HZ ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_IF_FREQ_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod spectrum mode getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SPECTRUM_MODE() to get QAM demod spectrum mode. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSpectrumMode Pointer to an allocated memory for storing demod spectrum mode ++ ++ ++@retval FUNCTION_SUCCESS Get demod spectrum mode successfully. ++@retval FUNCTION_ERROR Get demod spectrum mode unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SPECTRUM_MODE() with the corresponding function. ++ ++ ++@see SPECTRUM_MODE ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SPECTRUM_MODE)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod RF AGC getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_RF_AGC() to get QAM demod RF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pRfAgc Pointer to an allocated memory for storing RF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod RF AGC value successfully. ++@retval FUNCTION_ERROR Get demod RF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_RF_AGC() with the corresponding function. ++ -# The range of RF AGC value is (-pow(2, 10)) ~ (pow(2, 10) - 1). ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_RF_AGC)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pRfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod IF AGC getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_IF_AGC() to get QAM demod IF AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pIfAgc Pointer to an allocated memory for storing IF AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod IF AGC value successfully. ++@retval FUNCTION_ERROR Get demod IF AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_IF_AGC() with the corresponding function. ++ -# The range of IF AGC value is (-pow(2, 10)) ~ (pow(2, 10) - 1). ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_IF_AGC)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pIfAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod digital AGC getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_DI_AGC() to get QAM demod digital AGC value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pDiAgc Pointer to an allocated memory for storing digital AGC value ++ ++ ++@retval FUNCTION_SUCCESS Get demod digital AGC value successfully. ++@retval FUNCTION_ERROR Get demod digital AGC value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_DI_AGC() with the corresponding function. ++ -# The range of digital AGC value is 0 ~ (pow(2, 27) - 1). ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_DI_AGC)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pDiAgc ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod TR offset getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get demod TR offset successfully. ++@retval FUNCTION_ERROR Get demod TR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_TR_OFFSET_PPM)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod CR offset getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get demod CR offset successfully. ++@retval FUNCTION_ERROR Get demod CR offset unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_CR_OFFSET_HZ)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod AAGC lock asking function pointer ++ ++One can use QAM_DEMOD_FP_IS_AAGC_LOCKED() to ask QAM demod if it is AAGC-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform AAGC lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform AAGC lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_IS_AAGC_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_IS_AAGC_LOCKED)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod EQ lock asking function pointer ++ ++One can use QAM_DEMOD_FP_IS_EQ_LOCKED() to ask QAM demod if it is EQ-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform EQ lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform EQ lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_IS_EQ_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_IS_EQ_LOCKED)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod frame lock asking function pointer ++ ++One can use QAM_DEMOD_FP_IS_FRAME_LOCKED() to ask QAM demod if it is frame-locked. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform frame lock asking to demod successfully. ++@retval FUNCTION_ERROR Perform frame lock asking to demod unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_IS_FRAME_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_IS_FRAME_LOCKED)( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod error rate value getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_ERROR_RATE() to get error rate value. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [in] TestVolume Test volume for setting ++@param [in] WaitTimeMsMax Maximum waiting time in ms ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++@param [out] pPerNum Pointer to an allocated memory for storing PER numerator ++@param [out] pPerDen Pointer to an allocated memory for storing PER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod error rate value successfully. ++@retval FUNCTION_ERROR Get demod error rate value unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_ERROR_RATE() with the corresponding function. ++ -# The error test packet number is pow(2, (2 * TestVolume + 4)). ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_ERROR_RATE)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod SNR getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get demod SNR successfully. ++@retval FUNCTION_ERROR Get demod SNR unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SNR_DB)( ++ QAM_DEMOD_MODULE *pDemod, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod signal strength getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal strength successfully. ++@retval FUNCTION_ERROR Get demod signal strength unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SIGNAL_STRENGTH)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod signal quality getting function pointer ++ ++One can use QAM_DEMOD_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pDemod The demod module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get demod signal quality successfully. ++@retval FUNCTION_ERROR Get demod signal quality unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_GET_SIGNAL_QUALITY)( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod updating function pointer ++ ++One can use QAM_DEMOD_FP_UPDATE_FUNCTION() to update demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update demod setting successfully. ++@retval FUNCTION_ERROR Update demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &QamDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_UPDATE_FUNCTION)( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod reseting function pointer ++ ++One can use QAM_DEMOD_FP_RESET_FUNCTION() to reset demod register setting. ++ ++ ++@param [in] pDemod The demod module pointer ++ ++ ++@retval FUNCTION_SUCCESS Reset demod setting successfully. ++@retval FUNCTION_ERROR Reset demod setting unsuccessfully. ++ ++ ++@note ++ -# Demod building function will set QAM_DEMOD_FP_RESET_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "demod_pseudo.h" ++ ++ ++int main(void) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ++ PSEUDO_EXTRA_MODULE PseudoExtraModuleMemory; ++ ++ ++ // Build pseudo demod module. ++ BuildPseudoDemodModule(&pDemod, &QamDemodModuleMemory, &PseudoExtraModuleMemory); ++ ++ ... ++ ++ // Execute ResetFunction() before demod software reset. ++ pDemod->ResetFunction(pDemod); ++ ++ // Reset demod by software. ++ pDemod->SoftwareReset(pDemod); ++ ++ ... ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pDemod->UpdateFunction(pDemod); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_DEMOD_FP_RESET_FUNCTION)( ++ QAM_DEMOD_MODULE *pDemod ++ ); ++ ++ ++ ++ ++ ++/// RTD2885 QAM extra module ++typedef struct RTD2885_QAM_EXTRA_MODULE_TAG RTD2885_QAM_EXTRA_MODULE; ++ ++// RTD2885 QAM extra module ++struct RTD2885_QAM_EXTRA_MODULE_TAG ++{ ++ // Variables ++ int ConfigMode; ++ unsigned char Func1TickNum; ++}; ++ ++ ++ ++ ++ ++/// RTD2840B QAM extra module ++typedef struct RTD2840B_QAM_EXTRA_MODULE_TAG RTD2840B_QAM_EXTRA_MODULE; ++ ++// RTD2840B QAM extra module ++struct RTD2840B_QAM_EXTRA_MODULE_TAG ++{ ++ // Variables ++ int ConfigMode; ++ unsigned char Func1TickNum; ++}; ++ ++ ++ ++ ++ ++/// RTD2932 QAM extra module alias ++typedef struct RTD2932_QAM_EXTRA_MODULE_TAG RTD2932_QAM_EXTRA_MODULE; ++ ++// RTD2932 QAM extra module ++struct RTD2932_QAM_EXTRA_MODULE_TAG ++{ ++ // Variables ++ int ConfigMode; ++ unsigned char Func1TickNum; ++}; ++ ++ ++ ++ ++ ++/// RTL2820 OpenCable extra module alias ++typedef struct RTL2820_OC_EXTRA_MODULE_TAG RTL2820_OC_EXTRA_MODULE; ++ ++// RTL2820 OpenCable extra module ++struct RTL2820_OC_EXTRA_MODULE_TAG ++{ ++ // Variables ++ unsigned char Func1TickNum; ++}; ++ ++ ++ ++ ++ ++/// RTD2648 QAM extra module alias ++typedef struct RTD2648_QAM_EXTRA_MODULE_TAG RTD2648_QAM_EXTRA_MODULE; ++ ++// RTD2648 QAM extra module ++struct RTD2648_QAM_EXTRA_MODULE_TAG ++{ ++ // Variables ++ int ConfigMode; ++}; ++ ++ ++ ++ ++ ++/// QAM demod module structure ++struct QAM_DEMOD_MODULE_TAG ++{ ++ unsigned long CurrentPageNo; ++ // Private variables ++ int DemodType; ++ unsigned char DeviceAddr; ++ unsigned long CrystalFreqHz; ++ int TsInterfaceMode; ++ ++ int QamMode; ++ unsigned long SymbolRateHz; ++ int AlphaMode; ++ unsigned long IfFreqHz; ++ int SpectrumMode; ++ ++ int IsQamModeSet; ++ int IsSymbolRateHzSet; ++ int IsAlphaModeSet; ++ int IsIfFreqHzSet; ++ int IsSpectrumModeSet; ++ ++ union ///< Demod extra module used by driving module ++ { ++ RTD2885_QAM_EXTRA_MODULE Rtd2885Qam; ++ RTD2840B_QAM_EXTRA_MODULE Rtd2840bQam; ++ RTD2932_QAM_EXTRA_MODULE Rtd2932Qam; ++ RTL2820_OC_EXTRA_MODULE Rtl2820Oc; ++ RTD2648_QAM_EXTRA_MODULE Rtd2648Qam; ++ } ++ Extra; ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ ++ // Register tables ++ union ++ { ++ QAM_BASE_REG_ENTRY_ADDR_8BIT Addr8Bit[QAM_BASE_REG_TABLE_LEN_MAX]; ++ QAM_BASE_REG_ENTRY_ADDR_16BIT Addr16Bit[QAM_BASE_REG_TABLE_LEN_MAX]; ++ } ++ BaseRegTable; ++ ++ union ++ { ++ QAM_MONITOR_REG_ENTRY_ADDR_8BIT Addr8Bit[QAM_MONITOR_REG_TABLE_LEN_MAX]; ++ QAM_MONITOR_REG_ENTRY_ADDR_16BIT Addr16Bit[QAM_MONITOR_REG_TABLE_LEN_MAX]; ++ } ++ MonitorRegTable; ++ ++ ++ // Demod I2C function pointers ++ union ++ { ++ QAM_DEMOD_REG_ACCESS_ADDR_8BIT Addr8Bit; ++ QAM_DEMOD_REG_ACCESS_ADDR_16BIT Addr16Bit; ++ } ++ RegAccess; ++ ++ ++ // Demod manipulating function pointers ++ QAM_DEMOD_FP_GET_DEMOD_TYPE GetDemodType; ++ QAM_DEMOD_FP_GET_DEVICE_ADDR GetDeviceAddr; ++ QAM_DEMOD_FP_GET_CRYSTAL_FREQ_HZ GetCrystalFreqHz; ++ ++ QAM_DEMOD_FP_IS_CONNECTED_TO_I2C IsConnectedToI2c; ++ QAM_DEMOD_FP_SOFTWARE_RESET SoftwareReset; ++ ++ QAM_DEMOD_FP_INITIALIZE Initialize; ++ QAM_DEMOD_FP_SET_QAM_MODE SetQamMode; ++ QAM_DEMOD_FP_SET_SYMBOL_RATE_HZ SetSymbolRateHz; ++ QAM_DEMOD_FP_SET_ALPHA_MODE SetAlphaMode; ++ QAM_DEMOD_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ QAM_DEMOD_FP_SET_SPECTRUM_MODE SetSpectrumMode; ++ QAM_DEMOD_FP_GET_QAM_MODE GetQamMode; ++ QAM_DEMOD_FP_GET_SYMBOL_RATE_HZ GetSymbolRateHz; ++ QAM_DEMOD_FP_GET_ALPHA_MODE GetAlphaMode; ++ QAM_DEMOD_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++ QAM_DEMOD_FP_GET_SPECTRUM_MODE GetSpectrumMode; ++ ++ QAM_DEMOD_FP_GET_RF_AGC GetRfAgc; ++ QAM_DEMOD_FP_GET_IF_AGC GetIfAgc; ++ QAM_DEMOD_FP_GET_DI_AGC GetDiAgc; ++ QAM_DEMOD_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ QAM_DEMOD_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ ++ QAM_DEMOD_FP_IS_AAGC_LOCKED IsAagcLocked; ++ QAM_DEMOD_FP_IS_EQ_LOCKED IsEqLocked; ++ QAM_DEMOD_FP_IS_FRAME_LOCKED IsFrameLocked; ++ ++ QAM_DEMOD_FP_GET_ERROR_RATE GetErrorRate; ++ QAM_DEMOD_FP_GET_SNR_DB GetSnrDb; ++ ++ QAM_DEMOD_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ QAM_DEMOD_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ ++ QAM_DEMOD_FP_UPDATE_FUNCTION UpdateFunction; ++ QAM_DEMOD_FP_RESET_FUNCTION ResetFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// QAM demod default I2C functions for 8-bit address ++int ++qam_demod_addr_8bit_default_SetRegPage( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long PageNo ++ ); ++ ++int ++qam_demod_addr_8bit_default_SetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++qam_demod_addr_8bit_default_GetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++qam_demod_addr_8bit_default_SetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_GetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_SetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_GetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_SetRegBitsWithPage( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_8bit_default_GetRegBitsWithPage( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// QAM demod default I2C functions for 16-bit address ++int ++qam_demod_addr_16bit_default_SetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++qam_demod_addr_16bit_default_GetRegBytes( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ); ++ ++int ++qam_demod_addr_16bit_default_SetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_16bit_default_GetRegMaskBits( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned short RegStartAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned long *pReadingValue ++ ); ++ ++int ++qam_demod_addr_16bit_default_SetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ const unsigned long WritingValue ++ ); ++ ++int ++qam_demod_addr_16bit_default_GetRegBits( ++ QAM_DEMOD_MODULE *pDemod, ++ int RegBitName, ++ unsigned long *pReadingValue ++ ); ++ ++ ++ ++ ++ ++// QAM demod default manipulating functions ++void ++qam_demod_default_GetDemodType( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pDemodType ++ ); ++ ++void ++qam_demod_default_GetDeviceAddr( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned char *pDeviceAddr ++ ); ++ ++void ++qam_demod_default_GetCrystalFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pCrystalFreqHz ++ ); ++ ++int ++qam_demod_default_GetQamMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pQamMode ++ ); ++ ++int ++qam_demod_default_GetSymbolRateHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pSymbolRateHz ++ ); ++ ++int ++qam_demod_default_GetAlphaMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pAlphaMode ++ ); ++ ++int ++qam_demod_default_GetIfFreqHz( ++ QAM_DEMOD_MODULE *pDemod, ++ unsigned long *pIfFreqHz ++ ); ++ ++int ++qam_demod_default_GetSpectrumMode( ++ QAM_DEMOD_MODULE *pDemod, ++ int *pSpectrumMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/qam_nim_base.c b/drivers/drivers/media/dvb/dvb-usb/qam_nim_base.c +--- a/drivers/media/dvb/dvb-usb/qam_nim_base.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/qam_nim_base.c 2016-04-02 19:17:52.116066048 -0300 +@@ -0,0 +1,496 @@ ++/** ++ ++@file ++ ++@brief QAM NIM base module definition ++ ++QAM NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++*/ ++ ++ ++#include "qam_nim_base.h" ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_NIM_TYPE ++ ++*/ ++void ++qam_nim_default_GetNimType( ++ QAM_NIM_MODULE *pNim, ++ int *pNimType ++ ) ++{ ++ // Get NIM type from NIM module. ++ *pNimType = pNim->NimType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_SET_PARAMETERS ++ ++*/ ++int ++qam_nim_default_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Set tuner RF frequency in Hz. ++ if(pTuner->SetRfFreqHz(pTuner, RfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod QAM mode. ++ if(pDemod->SetQamMode(pDemod, QamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod symbol rate in Hz. ++ if(pDemod->SetSymbolRateHz(pDemod, SymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set demod alpha mode. ++ if(pDemod->SetAlphaMode(pDemod, AlphaMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod particular registers. ++ if(pDemod->ResetFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Reset demod by software reset. ++ if(pDemod->SoftwareReset(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_PARAMETERS ++ ++*/ ++int ++qam_nim_default_GetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pQamMode, ++ unsigned long *pSymbolRateHz, ++ int *pAlphaMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get tuner module and demod module. ++ pTuner = pNim->pTuner; ++ pDemod = pNim->pDemod; ++ ++ ++ // Get tuner RF frequency in Hz. ++ if(pTuner->GetRfFreqHz(pTuner, pRfFreqHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod QAM mode. ++ if(pDemod->GetQamMode(pDemod, pQamMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod symbol rate in Hz. ++ if(pDemod->GetSymbolRateHz(pDemod, pSymbolRateHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Get demod alpha mode. ++ if(pDemod->GetAlphaMode(pDemod, pAlphaMode) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_IS_SIGNAL_PRESENT ++ ++*/ ++int ++qam_nim_default_IsSignalPresent( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ QAM_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait maximum 1000 ms for signal present check. ++ for(i = 0; i < DEFAULT_QAM_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check signal present status on demod. ++ // Note: If frame is locked, stop signal present check. ++ if(pDemod->IsFrameLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_IS_SIGNAL_LOCKED ++ ++*/ ++int ++qam_nim_default_IsSignalLocked( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ QAM_DEMOD_MODULE *pDemod; ++ int i; ++ ++ ++ // Get base interface and demod module. ++ pBaseInterface = pNim->pBaseInterface; ++ pDemod = pNim->pDemod; ++ ++ ++ // Wait maximum 1000 ms for signal lock check. ++ for(i = 0; i < DEFAULT_QAM_NIM_SINGAL_LOCK_CHECK_TIMES_MAX; i++) ++ { ++ // Wait 20 ms. ++ pBaseInterface->WaitMs(pBaseInterface, 20); ++ ++ // Check frame lock status on demod. ++ // Note: If frame is locked, stop signal lock check. ++ if(pDemod->IsFrameLocked(pDemod, pAnswer) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(*pAnswer == YES) ++ break; ++ } ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_SIGNAL_STRENGTH ++ ++*/ ++int ++qam_nim_default_GetSignalStrength( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal strength from demod. ++ if(pDemod->GetSignalStrength(pDemod, pSignalStrength) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_SIGNAL_QUALITY ++ ++*/ ++int ++qam_nim_default_GetSignalQuality( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get signal quality from demod. ++ if(pDemod->GetSignalQuality(pDemod, pSignalQuality) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_ERROR_RATE ++ ++*/ ++int ++qam_nim_default_GetErrorRate( ++ QAM_NIM_MODULE *pNim, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get error rate from demod. ++ if(pDemod->GetErrorRate(pDemod, TestVolume, WaitTimeMsMax, pBerNum, pBerDen, pPerNum, pPerDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_SNR_DB ++ ++*/ ++int ++qam_nim_default_GetSnrDb( ++ QAM_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get SNR in dB from demod. ++ if(pDemod->GetSnrDb(pDemod, pSnrDbNum, pSnrDbDen) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_TR_OFFSET_PPM ++ ++*/ ++int ++qam_nim_default_GetTrOffsetPpm( ++ QAM_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get TR offset in ppm from demod. ++ if(pDemod->GetTrOffsetPpm(pDemod, pTrOffsetPpm) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_GET_CR_OFFSET_HZ ++ ++*/ ++int ++qam_nim_default_GetCrOffsetHz( ++ QAM_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Get CR offset in Hz from demod. ++ if(pDemod->GetCrOffsetHz(pDemod, pCrOffsetHz) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see QAM_NIM_FP_UPDATE_FUNCTION ++ ++*/ ++int ++qam_nim_default_UpdateFunction( ++ QAM_NIM_MODULE *pNim ++ ) ++{ ++ QAM_DEMOD_MODULE *pDemod; ++ ++ ++ // Get demod module. ++ pDemod = pNim->pDemod; ++ ++ ++ // Update demod particular registers. ++ if(pDemod->UpdateFunction(pDemod) != FUNCTION_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/qam_nim_base.h b/drivers/drivers/media/dvb/dvb-usb/qam_nim_base.h +--- a/drivers/media/dvb/dvb-usb/qam_nim_base.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/qam_nim_base.h 2016-04-02 19:17:52.116066048 -0300 +@@ -0,0 +1,879 @@ ++#ifndef __QAM_NIM_BASE_H ++#define __QAM_NIM_BASE_H ++ ++/** ++ ++@file ++ ++@brief QAM NIM base module definition ++ ++QAM NIM base module definitions contains NIM module structure, NIM funciton pointers, NIM definitions, and NIM default ++functions. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++ ++int ++CustomI2cRead( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C reading format: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++int ++CustomI2cWrite( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char *pWritingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ // I2C writing format: ++ // start_bit + (DeviceAddr | writing_bit) + writing_byte * ByteNum + stop_bit ++ ++ ... ++ ++ return FUNCTION_SUCCESS; ++ ++error_status: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++void ++CustomWaitMs( ++ BASE_INTERFACE_MODULE *pBaseInterface, ++ unsigned long WaitTimeMs ++ ) ++{ ++ // Wait WaitTimeMs milliseconds. ++ ++ ... ++ ++ return; ++} ++ ++ ++ ++int main(void) ++{ ++ QAM_NIM_MODULE *pNim; ++ QAM_NIM_MODULE QamNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ unsigned long RfFreqHz; ++ int QamMode; ++ unsigned long SymbolRateHz; ++ int AlphaMode; ++ ++ int Answer; ++ unsigned long SignalStrength, SignalQuality; ++ unsigned long BerNum, BerDen, PerNum, PerDen; ++ double Ber, Per; ++ unsigned long SnrDbNum, SnrDbDen; ++ double SnrDb; ++ long TrOffsetPpm, CrOffsetHz; ++ ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ &pNim, ++ &QamNimModuleMemory, ++ ++ 9, // Maximum I2C reading byte number is 9. ++ 8, // Maximum I2C writing byte number is 8. ++ CustomI2cRead, // Employ CustomI2cRead() as basic I2C reading function. ++ CustomI2cWrite, // Employ CustomI2cWrite() as basic I2C writing function. ++ CustomWaitMs, // Employ CustomWaitMs() as basic waiting function. ++ ++ &DemodxExtraModuleMemory, // Employ Demod-X extra module. ++ 0x44, // The Demod-X I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The Demod-X crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The Demod-X TS interface mode is serial. ++ ... // Other arguments for Demod-X ++ ++ &TunerxExtraModuleMemory, // Employ Tuner-Y extra module. ++ 0xc0, // The Tuner-Y I2C device address is 0xc0 in 8-bit format. ++ ... // Other arguments for Tuner-Y ++ ); ++ ++ ++ ++ // Get NIM type. ++ // Note: NIM types are defined in the MODULE_TYPE enumeration. ++ pNim->GetNimType(pNim, &NimType); ++ ++ ++ ++ ++ ++ ++ ++ // ==== Initialize NIM and set its parameters ===== ++ ++ // Initialize NIM. ++ pNim->Initialize(pNim); ++ ++ // Set NIM parameters. (RF frequency, QAM mode, symbol rate, alpha mode) ++ // Note: In the example: ++ // 1. RF frequency is 738 MHz. ++ // 2. QAM is 64. ++ // 3. Symbol rate is 6.952 MHz. ++ // 4. Alpha is 0.15. ++ RfFreqHz = 738000000; ++ QamMode = QAM_QAM_64; ++ SymbolRateHz = 6952000; ++ AlphaMode = QAM_ALPHA_0P15; ++ pNim->SetParameters(pNim, RfFreqHz, QamMode, SymbolRateHz, AlphaMode); ++ ++ ++ ++ // Wait 1 second for demod convergence. ++ ++ ++ ++ ++ ++ // ==== Get NIM information ===== ++ ++ // Get NIM parameters. (RF frequency, QAM mode, symbol rate, alpha mode) ++ pNim->GetParameters(pNim, &RfFreqHz, &QamMode, &SymbolRateHz, &AlphaMode); ++ ++ ++ // Get signal present status. ++ // Note: 1. The argument Answer is YES when the NIM module has found QAM signal in the RF channel. ++ // 2. The argument Answer is NO when the NIM module does not find QAM signal in the RF channel. ++ // Recommendation: Use the IsSignalPresent() function for channel scan. ++ pNim->IsSignalPresent(pNim, &Answer); ++ ++ // Get signal lock status. ++ // Note: 1. The argument Answer is YES when the NIM module has locked QAM signal in the RF channel. ++ // At the same time, the NIM module sends TS packets through TS interface hardware pins. ++ // 2. The argument Answer is NO when the NIM module does not lock QAM signal in the RF channel. ++ // Recommendation: Use the IsSignalLocked() function for signal lock check. ++ pNim->IsSignalLocked(pNim, &Answer); ++ ++ ++ // Get signal strength. ++ // Note: 1. The range of SignalStrength is 0~100. ++ // 2. Need to map SignalStrength value to UI signal strength bar manually. ++ pNim->GetSignalStrength(pNim, &SignalStrength); ++ ++ // Get signal quality. ++ // Note: 1. The range of SignalQuality is 0~100. ++ // 2. Need to map SignalQuality value to UI signal quality bar manually. ++ pNim->GetSignalQuality(pNim, &SignalQuality); ++ ++ ++ // Get BER and PER. ++ // Note: Test packet number = pow(2, (2 * 4 + 4)) = 4096 ++ // Maximum wait time = 1000 ms = 1 second ++ pNim->GetErrorRate(pNim, 4, 1000, &BerNum, &BerDen, &PerNum, &PerDen); ++ Ber = (double)BerNum / (double)BerDen; ++ Per = (double)PerNum / (double)PerDen; ++ ++ // Get SNR in dB. ++ pNim->GetSnrDb(pNim, &SnrDbNum, &SnrDbDen); ++ SnrDb = (double)SnrDbNum / (double)SnrDbDen; ++ ++ ++ // Get TR offset (symbol timing offset) in ppm. ++ pNim->GetTrOffsetPpm(pNim, &TrOffsetPpm); ++ ++ // Get CR offset (RF frequency offset) in Hz. ++ pNim->GetCrOffsetHz(pNim, &CrOffsetHz); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++#include "tuner_base.h" ++#include "qam_demod_base.h" ++ ++ ++ ++ ++ ++// Definitions ++#define DEFAULT_QAM_NIM_SINGAL_PRESENT_CHECK_TIMES_MAX 1 ++#define DEFAULT_QAM_NIM_SINGAL_LOCK_CHECK_TIMES_MAX 1 ++ ++ ++ ++ ++ ++/// QAM NIM module pre-definition ++typedef struct QAM_NIM_MODULE_TAG QAM_NIM_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM demod type getting function pointer ++ ++One can use QAM_NIM_FP_GET_NIM_TYPE() to get QAM NIM type. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pNimType Pointer to an allocated memory for storing NIM type ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_NIM_TYPE() with the corresponding function. ++ ++ ++@see MODULE_TYPE ++ ++*/ ++typedef void ++(*QAM_NIM_FP_GET_NIM_TYPE)( ++ QAM_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM initializing function pointer ++ ++One can use QAM_NIM_FP_INITIALIZE() to initialie QAM NIM. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize NIM successfully. ++@retval FUNCTION_ERROR Initialize NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_INITIALIZE)( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM parameter setting function pointer ++ ++One can use QAM_NIM_FP_SET_PARAMETERS() to set QAM NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [in] RfFreqHz RF frequency in Hz for setting ++@param [in] QamMode QAM mode for setting ++@param [in] SymbolRateHz Symbol rate in Hz for setting ++@param [in] AlphaMode Alpha mode for setting ++ ++ ++@retval FUNCTION_SUCCESS Set NIM parameters successfully. ++@retval FUNCTION_ERROR Set NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_SET_PARAMETERS() with the corresponding function. ++ ++ ++@see QAM_QAM_MODE, QAM_ALPHA_MODE ++ ++*/ ++typedef int ++(*QAM_NIM_FP_SET_PARAMETERS)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM parameter getting function pointer ++ ++One can use QAM_NIM_FP_GET_PARAMETERS() to get QAM NIM parameters. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pRfFreqHz Pointer to an allocated memory for storing NIM RF frequency in Hz ++@param [out] pQamMode Pointer to an allocated memory for storing NIM QAM mode ++@param [out] pSymbolRateHz Pointer to an allocated memory for storing NIM symbol rate in Hz ++@param [out] pAlphaMode Pointer to an allocated memory for storing NIM alpha mode ++ ++ ++@retval FUNCTION_SUCCESS Get NIM parameters successfully. ++@retval FUNCTION_ERROR Get NIM parameters unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_PARAMETERS() with the corresponding function. ++ ++ ++@see QAM_QAM_MODE, QAM_ALPHA_MODE ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_PARAMETERS)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pQamMode, ++ unsigned long *pSymbolRateHz, ++ int *pAlphaMode ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM signal present asking function pointer ++ ++One can use QAM_NIM_FP_IS_SIGNAL_PRESENT() to ask QAM NIM if signal is present. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal present asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal present asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_IS_SIGNAL_PRESENT() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_IS_SIGNAL_PRESENT)( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM signal lock asking function pointer ++ ++One can use QAM_NIM_FP_IS_SIGNAL_LOCKED() to ask QAM NIM if signal is locked. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pAnswer Pointer to an allocated memory for storing answer ++ ++ ++@retval FUNCTION_SUCCESS Perform signal lock asking to NIM successfully. ++@retval FUNCTION_ERROR Perform signal lock asking to NIM unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_IS_SIGNAL_LOCKED() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_IS_SIGNAL_LOCKED)( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM signal strength getting function pointer ++ ++One can use QAM_NIM_FP_GET_SIGNAL_STRENGTH() to get signal strength. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalStrength Pointer to an allocated memory for storing signal strength (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal strength successfully. ++@retval FUNCTION_ERROR Get NIM signal strength unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_SIGNAL_STRENGTH() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_SIGNAL_STRENGTH)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM signal quality getting function pointer ++ ++One can use QAM_NIM_FP_GET_SIGNAL_QUALITY() to get signal quality. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSignalQuality Pointer to an allocated memory for storing signal quality (value = 0 ~ 100) ++ ++ ++@retval FUNCTION_SUCCESS Get NIM signal quality successfully. ++@retval FUNCTION_ERROR Get NIM signal quality unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_SIGNAL_QUALITY() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_SIGNAL_QUALITY)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM error rate value getting function pointer ++ ++One can use QAM_NIM_FP_GET_ERROR_RATE() to get error rate value. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [in] TestVolume Test volume for setting ++@param [in] WaitTimeMsMax Maximum waiting time in ms ++@param [out] pBerNum Pointer to an allocated memory for storing BER numerator ++@param [out] pBerDen Pointer to an allocated memory for storing BER denominator ++@param [out] pPerNum Pointer to an allocated memory for storing PER numerator ++@param [out] pPerDen Pointer to an allocated memory for storing PER denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM error rate value successfully. ++@retval FUNCTION_ERROR Get NIM error rate value unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_ERROR_RATE() with the corresponding function. ++ -# The error test packet number is pow(2, (2 * TestVolume + 4)). ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_ERROR_RATE)( ++ QAM_NIM_MODULE *pNim, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM SNR getting function pointer ++ ++One can use QAM_NIM_FP_GET_SNR_DB() to get SNR in dB. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pSnrDbNum Pointer to an allocated memory for storing SNR dB numerator ++@param [out] pSnrDbDen Pointer to an allocated memory for storing SNR dB denominator ++ ++ ++@retval FUNCTION_SUCCESS Get NIM SNR successfully. ++@retval FUNCTION_ERROR Get NIM SNR unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_SNR_DB() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_SNR_DB)( ++ QAM_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM TR offset getting function pointer ++ ++One can use QAM_NIM_FP_GET_TR_OFFSET_PPM() to get TR offset in ppm. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pTrOffsetPpm Pointer to an allocated memory for storing TR offset in ppm ++ ++ ++@retval FUNCTION_SUCCESS Get NIM TR offset successfully. ++@retval FUNCTION_ERROR Get NIM TR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_TR_OFFSET_PPM() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_TR_OFFSET_PPM)( ++ QAM_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM CR offset getting function pointer ++ ++One can use QAM_NIM_FP_GET_CR_OFFSET_HZ() to get CR offset in Hz. ++ ++ ++@param [in] pNim The NIM module pointer ++@param [out] pCrOffsetHz Pointer to an allocated memory for storing CR offset in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get NIM CR offset successfully. ++@retval FUNCTION_ERROR Get NIM CR offset unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_GET_CR_OFFSET_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*QAM_NIM_FP_GET_CR_OFFSET_HZ)( ++ QAM_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief QAM NIM updating function pointer ++ ++One can use QAM_NIM_FP_UPDATE_FUNCTION() to update NIM register setting. ++ ++ ++@param [in] pNim The NIM module pointer ++ ++ ++@retval FUNCTION_SUCCESS Update NIM setting successfully. ++@retval FUNCTION_ERROR Update NIM setting unsuccessfully. ++ ++ ++@note ++ -# NIM building function will set QAM_NIM_FP_UPDATE_FUNCTION() with the corresponding function. ++ ++ ++ ++@par Example: ++@code ++ ++ ++#include "nim_demodx_tunery.h" ++ ++ ++int main(void) ++{ ++ QAM_NIM_MODULE *pNim; ++ QAM_NIM_MODULE QamNimModuleMemory; ++ DEMODX_EXTRA_MODULE DemodxExtraModuleMemory; ++ TUNERY_EXTRA_MODULE TuneryExtraModuleMemory; ++ ++ ++ // Build Demod-X Tuner-Y NIM module. ++ BuildDemodxTuneryModule( ++ ... ++ ); ++ ++ ... ++ ++ ++ return 0; ++} ++ ++ ++void PeriodicallyExecutingFunction ++{ ++ // Executing UpdateFunction() periodically. ++ pNim->UpdateFunction(pNim); ++} ++ ++ ++@endcode ++ ++*/ ++typedef int ++(*QAM_NIM_FP_UPDATE_FUNCTION)( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++// RTL2840 MT2062 extra module ++typedef struct RTL2840_MT2062_EXTRA_MODULE_TAG RTL2840_MT2062_EXTRA_MODULE; ++struct RTL2840_MT2062_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long IfFreqHz; ++}; ++ ++ ++ ++ ++ ++// RTL2840 MT2063 extra module ++typedef struct RTL2840_MT2063_EXTRA_MODULE_TAG RTL2840_MT2063_EXTRA_MODULE; ++struct RTL2840_MT2063_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long IfFreqHz; ++}; ++ ++ ++ ++ ++ ++// RTD2840B QAM MT2062 extra module ++typedef struct RTD2840B_QAM_MT2062_EXTRA_MODULE_TAG RTD2840B_QAM_MT2062_EXTRA_MODULE; ++struct RTD2840B_QAM_MT2062_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long IfFreqHz; ++}; ++ ++ ++ ++ ++ ++// RTL2836B DVBC FC0013B extra module ++typedef struct RTL2836B_DVBC_FC0013B_EXTRA_MODULE_TAG RTL2836B_DVBC_FC0013B_EXTRA_MODULE; ++struct RTL2836B_DVBC_FC0013B_EXTRA_MODULE_TAG ++{ ++ // Extra variables ++ unsigned long LnaUpdateWaitTimeMax; ++ unsigned long LnaUpdateWaitTime; ++ unsigned long RssiRCalOn; ++}; ++ ++ ++ ++ ++ ++/// QAM NIM module structure ++struct QAM_NIM_MODULE_TAG ++{ ++ // Private variables ++ int NimType; ++ int EnhancementMode; ++ int ConfigMode; ++ ++ union ///< NIM extra module used by driving module ++ { ++ RTL2840_MT2062_EXTRA_MODULE Rtl2840Mt2062; ++ RTL2840_MT2063_EXTRA_MODULE Rtl2840Mt2063; ++ RTD2840B_QAM_MT2062_EXTRA_MODULE Rtd2840bQamMt2062; ++ RTL2836B_DVBC_FC0013B_EXTRA_MODULE Rtl2836bDvbcFc0013b; ++ } ++ Extra; ++ ++ ++ // Modules ++ BASE_INTERFACE_MODULE *pBaseInterface; ///< Base interface module pointer ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ///< Base interface module memory ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ///< I2C bridge module pointer ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ///< I2C bridge module memory ++ ++ TUNER_MODULE *pTuner; ///< Tuner module pointer ++ TUNER_MODULE TunerModuleMemory; ///< Tuner module memory ++ ++ QAM_DEMOD_MODULE *pDemod; ///< QAM demod module pointer ++ QAM_DEMOD_MODULE QamDemodModuleMemory; ///< QAM demod module memory ++ ++ ++ // NIM manipulating functions ++ QAM_NIM_FP_GET_NIM_TYPE GetNimType; ++ QAM_NIM_FP_INITIALIZE Initialize; ++ QAM_NIM_FP_SET_PARAMETERS SetParameters; ++ QAM_NIM_FP_GET_PARAMETERS GetParameters; ++ QAM_NIM_FP_IS_SIGNAL_PRESENT IsSignalPresent; ++ QAM_NIM_FP_IS_SIGNAL_LOCKED IsSignalLocked; ++ QAM_NIM_FP_GET_SIGNAL_STRENGTH GetSignalStrength; ++ QAM_NIM_FP_GET_SIGNAL_QUALITY GetSignalQuality; ++ QAM_NIM_FP_GET_ERROR_RATE GetErrorRate; ++ QAM_NIM_FP_GET_SNR_DB GetSnrDb; ++ QAM_NIM_FP_GET_TR_OFFSET_PPM GetTrOffsetPpm; ++ QAM_NIM_FP_GET_CR_OFFSET_HZ GetCrOffsetHz; ++ QAM_NIM_FP_UPDATE_FUNCTION UpdateFunction; ++}; ++ ++ ++ ++ ++ ++ ++ ++// QAM NIM default manipulaing functions ++void ++qam_nim_default_GetNimType( ++ QAM_NIM_MODULE *pNim, ++ int *pNimType ++ ); ++ ++int ++qam_nim_default_SetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long RfFreqHz, ++ int QamMode, ++ unsigned long SymbolRateHz, ++ int AlphaMode ++ ); ++ ++int ++qam_nim_default_GetParameters( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pRfFreqHz, ++ int *pQamMode, ++ unsigned long *pSymbolRateHz, ++ int *pAlphaMode ++ ); ++ ++int ++qam_nim_default_IsSignalPresent( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++qam_nim_default_IsSignalLocked( ++ QAM_NIM_MODULE *pNim, ++ int *pAnswer ++ ); ++ ++int ++qam_nim_default_GetSignalStrength( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalStrength ++ ); ++ ++int ++qam_nim_default_GetSignalQuality( ++ QAM_NIM_MODULE *pNim, ++ unsigned long *pSignalQuality ++ ); ++ ++int ++qam_nim_default_GetErrorRate( ++ QAM_NIM_MODULE *pNim, ++ unsigned long TestVolume, ++ unsigned int WaitTimeMsMax, ++ unsigned long *pBerNum, ++ unsigned long *pBerDen, ++ unsigned long *pPerNum, ++ unsigned long *pPerDen ++ ); ++ ++int ++qam_nim_default_GetSnrDb( ++ QAM_NIM_MODULE *pNim, ++ long *pSnrDbNum, ++ long *pSnrDbDen ++ ); ++ ++int ++qam_nim_default_GetTrOffsetPpm( ++ QAM_NIM_MODULE *pNim, ++ long *pTrOffsetPpm ++ ); ++ ++int ++qam_nim_default_GetCrOffsetHz( ++ QAM_NIM_MODULE *pNim, ++ long *pCrOffsetHz ++ ); ++ ++int ++qam_nim_default_UpdateFunction( ++ QAM_NIM_MODULE *pNim ++ ); ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/rtl2832u_audio.c b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_audio.c +--- a/drivers/media/dvb/dvb-usb/rtl2832u_audio.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_audio.c 2016-04-02 19:17:52.120066046 -0300 +@@ -0,0 +1,926 @@ ++ ++ ++#include "rtl2832u_audio.h" ++//#include "rtl2832u_ioctl.h" ++ ++#ifndef NO_FE_IOCTL_OVERRIDE ++ ++#define RTK_Demod_Byte_Write(page, offset, length, data) \ ++ ((write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, page, offset, data, length)) ? 0 : 1 ) ++ ++ ++#define RTK_Demod_Byte_Read(page, offset, length, data) \ ++ ((read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, page, offset, data, length)) ? 0 : 1 ) ++ ++ ++int Set1(struct rtl2832_state* p_state) ++{ ++ unsigned char data[1]; ++ unsigned short length = 1; ++ int hr = 1; ++ ++ data[0] = 202; ++ hr &= RTK_Demod_Byte_Write(1, 0x1C, length, data); ++ ++ data[0] = 220; ++ hr &= RTK_Demod_Byte_Write(1, 0x1D, length, data); ++ ++ data[0] = 215; ++ hr &= RTK_Demod_Byte_Write(1, 0x1E, length, data); ++ ++ data[0] = 216; ++ hr &= RTK_Demod_Byte_Write(1, 0x1F, length, data); ++ ++ data[0] = 224; ++ hr &= RTK_Demod_Byte_Write(1, 0x20, length, data); ++ ++ data[0] = 242; ++ hr &= RTK_Demod_Byte_Write(1, 0x21, length, data); ++ ++ data[0] = 14; ++ hr &= RTK_Demod_Byte_Write(1, 0x22, length, data); ++ ++ data[0] = 53; ++ hr &= RTK_Demod_Byte_Write(1, 0x23, length, data); ++ ++ data[0] = 6; ++ hr &= RTK_Demod_Byte_Write(1, 0x24, length, data); ++ ++ data[0] = 80; ++ hr &= RTK_Demod_Byte_Write(1, 0x25, length, data); ++ ++ data[0] = 156; ++ hr &= RTK_Demod_Byte_Write(1, 0x26, length, data); ++ ++ data[0] = 13; ++ hr &= RTK_Demod_Byte_Write(1, 0x27, length, data); ++ ++ data[0] = 113; ++ hr &= RTK_Demod_Byte_Write(1, 0x28, length, data); ++ ++ data[0] = 17; ++ hr &= RTK_Demod_Byte_Write(1, 0x29, length, data); ++ ++ data[0] = 20; ++ hr &= RTK_Demod_Byte_Write(1, 0x2A, length, data); ++ ++ data[0] = 113; ++ hr &= RTK_Demod_Byte_Write(1, 0x2B, length, data); ++ ++ data[0] = 116; ++ hr &= RTK_Demod_Byte_Write(1, 0x2C, length, data); ++ ++ data[0] = 25; ++ hr &= RTK_Demod_Byte_Write(1, 0x2D, length, data); ++ ++ data[0] = 65; ++ hr &= RTK_Demod_Byte_Write(1, 0x2E, length, data); ++ ++ data[0] = 165; ++ hr &= RTK_Demod_Byte_Write(1, 0x2F, length, data); ++ ++ return hr; ++} ++ ++int Set2(struct rtl2832_state* p_state) ++{ ++ UCHAR FM_coe2[6] = {-1, 1, 6, 13, 22, 27}; ++ unsigned char data[1]; ++ unsigned short addr = 0x1F; ++ ++ int i; ++ BOOL rst = 1; ++ for(i=0; i<6; i++) ++ { ++ data[0] = FM_coe2[i]; ++ ++ rst &= RTK_Demod_Byte_Write(0, addr, 1, data); ++ addr--; ++ } ++ ++ return rst; ++} ++ ++ int RTL2832_SWReset(struct rtl2832_state* p_state) ++{ ++ unsigned char data[1]; ++ int hr = 1; ++ ++ hr &= RTK_Demod_Byte_Read(1, 0x01, 1, data); ++ data[0] = data[0] | 0x04; ++ hr &= RTK_Demod_Byte_Write(1, 0x01, 1, data); ++ data[0] = data[0] & 0xFB; ++ hr &= RTK_Demod_Byte_Write(1, 0x01, 1, data); ++ ++ return hr; ++} ++ ++ int RTL2832_SWReset_2(struct rtl2832_state* p_state) ++{ ++ unsigned char data[1]; ++ unsigned char tmp; ++ int hr = 1; ++ ++ // disable ++ hr &= RTK_Demod_Byte_Read(0, 0x19, 1, data); ++ data[0] = data[0] & 0xFE; ++ tmp = data[0]; ++ hr &= RTK_Demod_Byte_Write(0, 0x19, 1, data); ++ ++ ++ // sw reset ++ hr &= RTK_Demod_Byte_Read(1, 0x01, 1, data); ++ data[0] = data[0] | 0x04; ++ hr &= RTK_Demod_Byte_Write(1, 0x01, 1, data); ++ data[0] = data[0] & 0xFB; ++ hr &= RTK_Demod_Byte_Write(1, 0x01, 1, data); ++ ++ //enable ++ tmp = tmp | 0x1; ++ hr &= RTK_Demod_Byte_Write(0, 0x19, 1, &tmp); ++ ++ return hr; ++} ++ ++ ++ ++int Initial_2832_fm(struct rtl2832_state* p_state) ++{ ++ unsigned char data[4]; ++ unsigned short length; ++ int hr = 1; ++ ++ length = 2; ++ data[0] = 0x00; ++ data[1] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x3E, length, data); ++ ++ length = 1; ++ data[0] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x15, length, data); ++ ++ length = 3; ++ data[0] = 0x00; ++ data[1] = 0x00; ++ data[2] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x16, length, data); ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ data[0] = 0x35; ++ data[1] = 0xD8; ++ data[2] = 0x2E; ++ hr &= RTK_Demod_Byte_Write(1, 0x19, 3, data); ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ { ++ data[0] = 0x00; ++ data[1] = 0x00; ++ data[2] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x19, 3, data); ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ data[0] = 0x00; ++ data[1] = 0x00; ++ data[2] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x19, 3, data); ++ } ++ ++ length = 4; ++ data[0] = 0x03; ++ data[1] = 0x84; ++ data[2] = 0x00; ++ data[3] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x9F, length, data); ++ ++ hr &= Set1(p_state); ++ ++ length = 1; ++ data[0] = 0x11; ++ hr &= RTK_Demod_Byte_Write(0, 0x17, length, data); ++ ++ length = 1; ++ data[0] = 0x10; ++ hr &= RTK_Demod_Byte_Write(0, 0x18, length, data); ++ ++ length = 1; ++ data[0] = 0x21; ++ hr &= RTK_Demod_Byte_Write(0, 0x19, length, data); ++ ++ hr &= Set2(p_state); ++ ++ length = 1; ++ data[0] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x92, length, data); ++ ++ length = 1; ++ data[0] = 0xF0; ++ hr &= RTK_Demod_Byte_Write(1, 0x93, length, data); ++ ++ length = 1; ++ data[0] = 0x0F; ++ hr &= RTK_Demod_Byte_Write(1, 0x94, length, data); ++ ++ length = 1; ++ data[0] = 0x60; ++ hr &= RTK_Demod_Byte_Write(0, 0x61, length, data);//output of PID filter ++ ++ length = 1; ++ data[0] = 0x80; ++ hr &= RTK_Demod_Byte_Write(0, 0x06, length, data); ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 || p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ { ++ data[0] = 0xCD; ++ hr &= RTK_Demod_Byte_Write(0, 0x08, 1, data); ++ ++ data[0] = 0x1; ++ hr &= RTK_Demod_Byte_Write(1, 0xB1, 1, data); ++ } ++ ++ hr &= RTL2832_SWReset(p_state); ++ if(!hr) ++ { ++ deb_info("FM Func: Initial 2832 register failed\n"); ++ } ++ ++ if(hr != 1) ++ return -1; ++ ++ return 0; ++} ++ ++ ++int Initial_2832_dab(struct rtl2832_state* p_state) ++{ ++ unsigned char data[4]; ++ unsigned short length; ++ BOOL hr = 1; ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ { ++ length = 1; ++ data[0] = 0xCD;//enable ADC_I, ADC_Q for zero-IF ++ //data[0] = 0x8D;//enable ADC_I ++ hr &= RTK_Demod_Byte_Write(0, 0x08, length, data); ++ ++ //bit 0, enable en_bbin ++ //bit 2,1 DC offset ++ //bit 4,3 IQ mismatch ++ length = 1; ++ data[0] = 0x1F;//ZeroIF //?? data[0] = 0x1E; ++ hr &= RTK_Demod_Byte_Write(1, 0xB1, length, data); ++ } ++ ++ //---------------------------------------------- ++ //set each time change ++ //en_sfreq_sync = 0 page 1, 0x3E, bit6 ++ //pset_sfreq_off default = 0 page 1, 0x{3E, 3F} ++ length = 2; ++ data[0] = 0x00; ++ data[1] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x3E, length, data); ++ //----------------------------------------------- ++ ++ //spec_inv = 0; en_aci = 0; en_cfreq_sync = 0 ++ length = 1; ++ data[0] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x15, length, data); ++ ++ //pset_cfreq_off = 0 Pre-set value of carrier frequency offset. ++ length = 3; ++ data[0] = 0x00; ++ data[1] = 0x00; ++ data[2] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x16, length, data); ++ ++ //---- DDC Setting ------ ++ //pset_iffreq IF frequency //36.125M 0x2F; 0xB8; 0xE4; ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ {//IF 4.57M ++ length = 3; ++ data[0] = 0x35; ++ data[1] = 0xD8; ++ data[2] = 0x2E; ++ hr &= RTK_Demod_Byte_Write(1, 0x19, length, data); ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ {//ZERO IF ++ length = 3; ++ data[0] = 0x00; ++ data[1] = 0x00; ++ data[2] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x19, length, data); ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ {//FC0012_TUNER is zero IF, but can set tunner to other frequency to avoid DC cancellation, frequency noise... ++ ++ //length = 3; ++ //data[0] = 0x00; ++ //data[1] = 0x00; ++ //data[2] = 0x00; ++ //hr &= RTK_Demod_Byte_Write(1, 0x19, length, data); ++ ++ // Set pset_iffreg of 2832 ++ length = 3; ++ data[0] = 0x00; ++ data[1] = 0x00; ++ data[2] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x19, length, data); ++ } ++ //20110413 add by alan ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) ++ {//FC0013_TUNER is zero IF, but can set tunner to other frequency to avoid DC cancellation, frequency noise... ++ ++ //length = 3; ++ //data[0] = 0x00; ++ //data[1] = 0x00; ++ //data[2] = 0x00; ++ //hr &= RTK_Demod_Byte_Write(1, 0x19, length, data); ++ ++ // Set pset_iffreg of 2832 ++ length = 3; ++ data[0] = 0x00; ++ data[1] = 0x00; ++ data[2] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x19, length, data); ++ } ++ //end ++ //------ Resampler Setting ------- ++ //resample ratio 28.8M --> 8.192M ++ length = 4; ++ data[0] = 0x03; ++ data[1] = 0x84; ++ data[2] = 0x00; ++ data[3] = 0x00; ++ hr &= RTK_Demod_Byte_Write(1, 0x9F, length, data); ++ ++ //------- DDC LPF coe ------------- ++ // used in OpenDevice? more possible setFreq ++ length = 1; ++ data[0] = 202; ++ hr &= RTK_Demod_Byte_Write(1, 0x1C, length, data); ++ ++ length = 1; ++ data[0] = 220; ++ hr &= RTK_Demod_Byte_Write(1, 0x1D, length, data); ++ ++ length = 1; ++ data[0] = 215; ++ hr &= RTK_Demod_Byte_Write(1, 0x1E, length, data); ++ ++ length = 1; ++ data[0] = 216; ++ hr &= RTK_Demod_Byte_Write(1, 0x1F, length, data); ++ ++ length = 1; ++ data[0] = 224; ++ hr &= RTK_Demod_Byte_Write(1, 0x20, length, data); ++ ++ length = 1; ++ data[0] = 242; ++ hr &= RTK_Demod_Byte_Write(1, 0x21, length, data); ++ ++ length = 1; ++ data[0] = 14; ++ hr &= RTK_Demod_Byte_Write(1, 0x22, length, data); ++ ++ length = 1; ++ data[0] = 53; ++ hr &= RTK_Demod_Byte_Write(1, 0x23, length, data); ++ ++ length = 1; ++ data[0] = 6; ++ hr &= RTK_Demod_Byte_Write(1, 0x24, length, data); ++ ++ length = 1; ++ data[0] = 80; ++ hr &= RTK_Demod_Byte_Write(1, 0x25, length, data); ++ ++ length = 1; ++ data[0] = 156; ++ hr &= RTK_Demod_Byte_Write(1, 0x26, length, data); ++ ++ length = 1; ++ data[0] = 13; ++ hr &= RTK_Demod_Byte_Write(1, 0x27, length, data); ++ ++ length = 1; ++ data[0] = 113; ++ hr &= RTK_Demod_Byte_Write(1, 0x28, length, data); ++ ++ length = 1; ++ data[0] = 17; ++ hr &= RTK_Demod_Byte_Write(1, 0x29, length, data); ++ ++ length = 1; ++ data[0] = 20; ++ hr &= RTK_Demod_Byte_Write(1, 0x2A, length, data); ++ ++ length = 1; ++ data[0] = 113; ++ hr &= RTK_Demod_Byte_Write(1, 0x2B, length, data); ++ ++ length = 1; ++ data[0] = 116; ++ hr &= RTK_Demod_Byte_Write(1, 0x2C, length, data); ++ ++ length = 1; ++ data[0] = 25; ++ hr &= RTK_Demod_Byte_Write(1, 0x2D, length, data); ++ ++ length = 1; ++ data[0] = 65; ++ hr &= RTK_Demod_Byte_Write(1, 0x2E, length, data); ++ ++ length = 1; ++ data[0] = 165; ++ hr &= RTK_Demod_Byte_Write(1, 0x2F, length, data); ++ ++ //-------- DAB Setting --------- ++ //dab dagc_target; (S,8,7f) when dagc on ++ length = 1; ++ data[0] = 0x11;//default: 0x13 ++ hr &= RTK_Demod_Byte_Write(0, 0x17, length, data); ++ ++ //dagc_gain_set; (S,8,1f) when dagc off ++ length = 1; ++ data[0] = 0x10;//default: 0x10 ++ hr &= RTK_Demod_Byte_Write(0, 0x18, length, data); ++ ++ //0x19 [0] 0x01 1 for dab_enable; 0 for soft reset or module disable; ++ //0x19 [2:1] 0x02 mode 10 for DAB , 00 for FM , 01/11 for pattern ++ //0x19 [4:3] 0x00 dagc_loop_gain; 0~3 for 2^-10 ~ 2^-7: ++ //0x19 [5] 0x01 dagc_on; 0 for off , 1 for on ++ length = 1; ++ data[0] = 0x25;//0x25;//0x27; ++ hr &= RTK_Demod_Byte_Write(0, 0x19, length, data); ++ //------------------------------- ++ ++ //------- hold stage ------------ ++ // stage 11 is possible ++ // hold stage 4 now ! ++ length = 1; ++ data[0] = 0x00;//0x7F;// ++ hr &= RTK_Demod_Byte_Write(1, 0x92, length, data); ++ ++ length = 1; ++ data[0] = 0xF0;//0xF7;// ++ hr &= RTK_Demod_Byte_Write(1, 0x93, length, data); ++ ++ length = 1; ++ data[0] = 0x0F;//0xFF;// ++ hr &= RTK_Demod_Byte_Write(1, 0x94, length, data); ++ //---------------------------------- ++ ++ // DAB input from PIP ? ++ length = 1; ++ data[0] = 0x60; ++ hr &= RTK_Demod_Byte_Write(0, 0x61, length, data);//output of PID filter ++ ++ //if(currentTunner == MT2266_TUNER || currentTunner == FC2580_TUNER || currentTunner == TUA9001_TUNER || currentTunner == FC0012_TUNER) ++ {//??? ++ length = 1; ++ data[0] = 0x40;//08.03.10 ++ hr &= RTK_Demod_Byte_Write(0, 0x20, length, data); ++ } ++ ++ length = 1; ++ //if(p_state->tuner_type == TUA9001_TUNER)// pay attention: for infineon tunner, exchange I and Q ++ //{ ++ // data[0] = 0x90; ++ //} ++ //else ++ { ++ data[0] = 0x80; ++ } ++ hr &= RTK_Demod_Byte_Write(0, 0x06, length, data); ++ ++ //end ++ //---- software reset ----- ++ //page 1, 0x01, bit 2, first 1 then zero ++ length = 1; ++ hr &= RTK_Demod_Byte_Read(1, 0x01, length, data); ++ data[0] = data[0] | 0x04; ++ hr &= RTK_Demod_Byte_Write(1, 0x01, length, data); ++ data[0] = data[0] & 0xFB; ++ hr &= RTK_Demod_Byte_Write(1, 0x01, length, data); ++ ++ if(!hr) ++ { ++ deb_info("DAB DLL: initial 2832 register fail\n"); ++ } ++ ++ if(hr != 1) ++ return -1; ++ ++ return 0; ++} ++ ++ ++ ++int switch_mode(struct rtl2832_state* p_state, int audio_mdoe) ++{ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->tuner_type != RTL2832_TUNER_TYPE_FC0012 && ++ p_state->tuner_type != RTL2832_TUNER_TYPE_MXL5007T && ++ p_state->tuner_type != RTL2832_TUNER_TYPE_E4000 && ++ p_state->tuner_type != RTL2832_TUNER_TYPE_FC0013) ++ { ++ deb_info("Illegal tuner type\n"); ++ goto error; ++ } ++ ++ deb_info("+switch_mode\n"); ++ ++ if(p_state->demod_support_type & SUPPORT_DVBT_MODE) ++ { ++ // if current state is 2832 ++ if(p_state->demod_type == RTL2832) ++ { ++ // Demod H/W Reset ++ if(rtl2832_hw_reset( p_state)) ++ goto error; ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ if(rtl2832_fc0012_Initialize_fm(p_state->pNim)) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ if(rtl2832_mxl5007t_Initialize_fm(p_state->pNim)) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ { ++ if(rtl2832_e4000_Initialize_fm(p_state->pNim)) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) ++ { ++ if(rtl2832_fc0013_Initialize_fm(p_state->pNim)) ++ goto error; ++ } ++ ++ ++ switch(audio_mdoe) ++ { ++ case FM_MODE: ++ if (Initial_2832_fm(p_state)) ++ { ++ deb_info("%s: fail to initial fm\n",__FUNCTION__); ++ goto error; ++ } ++ deb_info("%s: switch to fm.....\n",__FUNCTION__); ++ break; ++ ++ case DAB_MODE: ++ if (Initial_2832_dab(p_state)) ++ { ++ deb_info("%s: fail to initial dab\n",__FUNCTION__); ++ goto error; ++ } ++ deb_info("%s: switch to dab.....\n",__FUNCTION__); ++ break; ++ } ++ } ++ } ++ ++ deb_info("-switch_mode\n"); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++mutex_error: ++ return -1; ++} ++ ++ ++//3 Related to urb behavior ++struct usb_data_stream stream_cp; ++struct fm_stream_ctrl_struct ++{ ++ u8 fm_stream_buf[24064]; ++ int fm_stream_index; ++}; ++struct fm_stream_ctrl_struct fm_struct; ++struct fm_stream_ctrl_struct* fm_stream; ++ ++static void dvb_dmx_fm_filter(struct dvb_demux *demux, const u8 *buf, size_t count) ++{ ++ ++ struct dvb_demux_feed *feed; ++ int p,i,j; ++ ++ spin_lock(&demux->lock); ++ ++ list_for_each_entry(feed, &demux->feed_list, list_head) { ++ if(feed->pid != 0x2000) ++ continue; ++ ++ p = 0; ++ if (fm_stream->fm_stream_index) { ++ i = fm_stream->fm_stream_index; ++ j = 24064 - i; ++ ++ if (count < j) { ++ memcpy(&fm_stream->fm_stream_buf[i], buf, count); ++ fm_stream->fm_stream_index += count; ++ goto bailout; ++ } ++ ++ memcpy(&fm_stream->fm_stream_buf[i], buf, j); ++ feed->cb.ts(fm_stream->fm_stream_buf, 24064, NULL, 0, &feed->feed.ts, DMX_OK); ++ fm_stream->fm_stream_index = 0; ++ p += j; ++ } ++ ++ while (p < count) { ++ if (count - p >= 24064) { ++ feed->cb.ts(&buf[p], 24064, NULL, 0, &feed->feed.ts, DMX_OK); ++ p += 24064; ++ } else { ++ i = count - p; ++ memcpy(fm_stream->fm_stream_buf, &buf[p], i); ++ fm_stream->fm_stream_index = i; ++ goto bailout; ++ } ++ } ++ ++ } ++ ++bailout: ++ spin_unlock(&demux->lock); ++} ++ ++ ++//3--> dvb_usb_data_complete ++static void fm_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length) ++{ ++ struct dvb_usb_adapter *adap = stream->user_priv; ++ ++ //deb_info("%s: length %d\n ", __func__, length);//debug ++ if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) ++ dvb_dmx_fm_filter(&adap->demux, buffer, length); ++} ++ ++#ifdef V4L2_REFACTORED_MFE_CODE ++void fm_stream_ctrl(int f, struct dvb_usb_adapter* adapter) ++{ ++ if(f) ++ {//store usb_data_stream part ++ memcpy(&stream_cp, &adapter->fe_adap[0].stream, sizeof(struct usb_data_stream)); ++ adapter->fe_adap[0].stream.complete = fm_usb_data_complete; ++ } ++ else ++ {//resume dvb-t usb_data_stream part ++ memcpy(&adapter->fe_adap[0].stream, &stream_cp, sizeof(struct usb_data_stream)); ++ } ++} ++#else ++void fm_stream_ctrl(int f, struct dvb_usb_adapter* adapter) ++{ ++ if(f) ++ {//store usb_data_stream part ++ memcpy(&stream_cp, &adapter->stream, sizeof(struct usb_data_stream)); ++ adapter->stream.complete = fm_usb_data_complete; ++ } ++ else ++ {//resume dvb-t usb_data_stream part ++ memcpy(&adapter->stream, &stream_cp, sizeof(struct usb_data_stream)); ++ } ++} ++#endif ++ ++int fe_fm_cmd_ctrl(struct dvb_frontend *fe, void *parg) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ struct dvb_usb_adapter* adapter = p_state->d->adapter;//ptr to adapter[0] ++ struct fm_cmd_struct* fm_ctrl = (struct fm_cmd_struct*)parg; ++ int fm_cmd = fm_ctrl->cmd_num; ++ unsigned int tmp2; ++ unsigned char data[4]; ++ int hr; ++ struct fm_cmd_struct tmp_str; ++ unsigned int orgValue; ++ unsigned int psetValue; ++ ++ deb_info("+fe_fm_cmd_ctrl\n"); ++ ++ switch(fm_cmd) ++ { ++ case FE_ENABLE_FM: ++ ++ deb_info("FE_OPEN_FM\n"); ++ ++ if(p_state->rtl2832_audio_video_mode == RTK_AUDIO) ++ { ++ deb_info("It has been FM mode\n"); ++ return 1; ++ } ++ ++ //check whether it is legal, no dvb-t, no fm ++ ++ //switch to fm mode ++ if(switch_mode(p_state, FM_MODE)) ++ return -1; ++ ++ //change usb_data_stream part ++ //fm_stream = vmalloc(sizeof(struct fm_stream_ctrl_struct)); ++ fm_stream = &fm_struct; ++ fm_stream_ctrl(1, adapter); ++ ++ p_state->rtl2832_audio_video_mode = RTK_AUDIO;//FM or DAB ++ ++ tmp_str.tuner= p_state->tuner_type;//tuner type ++ memcpy(parg, &tmp_str, sizeof(struct fm_cmd_struct));//will be copy to user ++ ++ return 1;//break; ++ ++ case FE_ENABLE_DAB: ++ ++ deb_info("FE_OPEN_DAB\n"); ++ ++ if(p_state->rtl2832_audio_video_mode == RTK_AUDIO) ++ { ++ deb_info("It has been DAB mode\n"); ++ return 1; ++ } ++ ++ //check whether it is legal, no dvb-t, no fm ++ ++ //switch to fm mode ++ if(switch_mode(p_state, DAB_MODE)) ++ return -1; ++ ++ //change usb_data_stream part ++ //fm_stream = vmalloc(sizeof(struct fm_stream_ctrl_struct)); ++ fm_stream = &fm_struct; ++ fm_stream_ctrl(1, adapter); ++ ++ p_state->rtl2832_audio_video_mode = RTK_AUDIO;//FM or DAB ++ ++ tmp_str.tuner= p_state->tuner_type;//tuner type ++ memcpy(parg, &tmp_str, sizeof(struct fm_cmd_struct));//will be copy to user ++ ++ return 1;//break; ++ ++ ++ case FE_DISABLE_FM: ++ case FE_DISABLE_DAB: ++ ++ deb_info("FE_CLOSE_FM or DAB\n"); ++ ++ if(p_state->rtl2832_audio_video_mode != RTK_AUDIO) ++ { ++ deb_info("It is not start from FM or DAB mode\n"); ++ return 1; ++ } ++ ++ fm_stream_ctrl(0, adapter); ++ p_state->rtl2832_audio_video_mode = RTK_VIDEO; ++ return 1;//break; ++ ++ case CR_D_: ++ ++ deb_info("CR_d\n"); ++ ++ tmp2 = (fm_ctrl->cr) & 0x3FFFFF; ++ data[0] = (tmp2>>16) & 0x3F; ++ data[1] = (tmp2>>8) & 0xFF; ++ data[2] = tmp2 & 0xFF; ++ hr = RTK_Demod_Byte_Write(1, 0x16, 3, data); ++ if(!hr) ++ return -1; ++ ++ hr = RTL2832_SWReset_2(p_state); ++ if(!hr) ++ return -1; ++ ++ deb_info("CR_d done\n"); ++ return 1; ++ ++ case CR_A_: ++ ++ deb_info("CR_a\n"); ++ ++ hr = RTK_Demod_Byte_Read(1, 0x16, 3, data); ++ if(!hr) ++ { ++ return -1; ++ } ++ ++ tmp2 = (fm_ctrl->cr) & 0x3FFFFF; ++ ++ orgValue = (((unsigned int)data[0]&0x3F)<<16) | (((unsigned int)data[1])<<8) | (unsigned short)data[2]; ++ psetValue = tmp2 + orgValue; ++ ++ data[0] = (psetValue>>16) & 0x3F; ++ data[1] = (psetValue>>8) & 0xFF; ++ data[2] = psetValue & 0xFF; ++ hr = RTK_Demod_Byte_Write(1, 0x16, 3, data); ++ if(!hr) ++ return -1; ++ ++ hr = RTL2832_SWReset_2(p_state); ++ if(!hr) ++ return -1; ++ ++ deb_info("CR_a done\n"); ++ return 1; ++ ++ case TR_D: ++ ++ deb_info("TR_d \n"); ++ ++ tmp2 = (fm_ctrl->cr); ++ data[0] = (tmp2>>8) & 0x3F; ++ data[1] = tmp2 & 0xFF; ++ hr = RTK_Demod_Byte_Write(1, 0x3E, 2, data);//0x3E 0x3F ++ if(!hr) ++ return -1; ++ ++ //hr = RTL2832_SWReset(p_state); ++ //if(!hr) ++ // return -1; ++ ++ deb_info("TR_d done\n"); ++ return 1; ++ ++ case TR_A: //increasing value ++ ++ deb_info("TR_a\n"); ++ ++ hr = RTK_Demod_Byte_Read(1, 0x3E, 2, data);//0x3E, 0x3F ++ if(!hr) ++ return -1; ++ ++ tmp2 = (fm_ctrl->cr); ++ orgValue = (((unsigned int)data[0] & 0x3F) << 8) | (unsigned int)data[1]; ++ psetValue = (tmp2 & 0x3FFF) + orgValue; ++ ++ data[0] = (psetValue>>8) & 0x3F; ++ data[1] = psetValue & 0xFF; ++ ++ hr = RTK_Demod_Byte_Write(1, 0x3E, 2, data);//0x3E, 0x3F ++ if(!hr) ++ return -1; ++ ++ //hr = RTL2832_SWReset(p_state); ++ //if(!hr) ++ // return -1; ++ ++ deb_info("TR_a done\n"); ++ return 1; ++ ++ case SW_RESET: ++ ++ hr = RTL2832_SWReset(p_state); ++ if(!hr) ++ return -1; ++ ++ deb_info("RTL2832_SWReset\n"); ++ return 1; ++ ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int rtl2832_fe_ioctl_override(struct dvb_frontend *fe,unsigned int cmd, void *parg, unsigned int stage) ++{ ++ ++ //deb_info("rtl2832_fe_ioctl_override : cmd =%d\n", cmd); ++ ++ int ret = 0; ++ ++ if(stage == DVB_FE_IOCTL_PRE) ++ { ++ switch(cmd) ++ { ++ case FE_FM_CMD: ++ ++ ret = fe_fm_cmd_ctrl(fe, parg); ++ break; ++ ++ } ++ } ++ //else ++ //{ ++ //deb_info("rtl2832_fe_ioctl_override : xxxxx\n"); ++ //} ++ ++ return ret; ++} ++ ++#endif ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/rtl2832u_audio.h b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_audio.h +--- a/drivers/media/dvb/dvb-usb/rtl2832u_audio.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_audio.h 2016-04-02 19:17:52.120066046 -0300 +@@ -0,0 +1,67 @@ ++ ++#ifndef __RTL2832U_AUDIO_H__ ++#define __RTL2832U_AUDIO_H__ ++ ++#include "rtl2832u_fe.h" ++#include "rtl2832u_io.h" ++#include "dvbdev.h" ++#include "dvb_demux.h" ++#include "dvb-usb.h" ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)) || (defined V4L2_VERSION) ++#define V4L2_REFACTORED_RC_CODE ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) || (defined V4L2_VERSION) ++#define V4L2_REFACTORED_MFE_CODE ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) || (defined V4L2_VERSION) ++#define NO_FE_IOCTL_OVERRIDE ++#endif ++ ++#define UCHAR unsigned char ++ ++ ++#ifndef NO_FE_IOCTL_OVERRIDE ++struct fm_cmd_struct ++{ ++ int cmd_num; ++ int cr; ++ int tuner; ++ int tr; ++}; ++ ++ ++#define FE_FM_CMD _IOWR('o', 90, struct fm_cmd_struct) ++ ++enum ++{ ++ FE_ENABLE_FM=0, ++ FE_DISABLE_FM, ++ CR_D_, ++ CR_A_, ++ CR_S_, ++ READ_BYTE, ++ WRITE_BYTE, ++ FE_ENABLE_DAB, ++ FE_DISABLE_DAB, ++ TR_D, ++ TR_A, ++ SW_RESET, ++}; ++ ++enum ++{ ++ FM_MODE = 0, ++ DAB_MODE, ++}; ++ ++ ++ ++int rtl2832_fe_ioctl_override(struct dvb_frontend *fe,unsigned int cmd, void *parg, unsigned int stage); ++void fm_stream_ctrl(int f, struct dvb_usb_adapter* adapter); ++ ++#endif ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/rtl2832u.c b/drivers/drivers/media/dvb/dvb-usb/rtl2832u.c +--- a/drivers/media/dvb/dvb-usb/rtl2832u.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/rtl2832u.c 2016-04-02 19:17:52.116066048 -0300 +@@ -0,0 +1,1745 @@ ++ ++#include ++#include ++ ++#include "rtl2832u.h" ++#include "rtl2832u_io.h" ++#include "rtl2832u_audio.h" ++//#include "rtl2832u_ioctl.h" ++ ++int dvb_usb_rtl2832u_debug=0; ++module_param_named(debug,dvb_usb_rtl2832u_debug, int, 0644); ++MODULE_PARM_DESC(debug, "Set debugging level (1=info,xfer=2 (or-able),rc=3)." DVB_USB_DEBUG_STATUS); ++ ++int demod_default_type=0; ++module_param_named(demod, demod_default_type, int, 0644); ++MODULE_PARM_DESC(demod, "Set default demod type(0=dvb-t, 1=dtmb, 2=dvb-c)"DVB_USB_DEBUG_STATUS); ++ ++int dtmb_error_packet_discard; ++module_param_named(dtmb_err_discard, dtmb_error_packet_discard, int, 0644); ++MODULE_PARM_DESC(dtmb_err_discard, "Set error packet discard type(0=not discard, 1=discard)"DVB_USB_DEBUG_STATUS); ++ ++int dvb_use_rtl2832u_rc_mode=2; ++module_param_named(rtl2832u_rc_mode, dvb_use_rtl2832u_rc_mode, int, 0644); ++MODULE_PARM_DESC(rtl2832u_rc_mode, "Set default rtl2832u_rc_mode(0=rc6, 1=rc5, 2=nec, 3=disable rc, default=2)."DVB_USB_DEBUG_STATUS); ++ ++int dvb_use_rtl2832u_card_type=0; ++module_param_named(rtl2832u_card_type, dvb_use_rtl2832u_card_type, int, 0644); ++MODULE_PARM_DESC(rtl2832u_card_type, "Set default rtl2832u_card_type type(0=dongle, 1=mini card, default=0)."DVB_USB_DEBUG_STATUS); ++ ++int dvb_usb_rtl2832u_snrdb=0; ++module_param_named(snrdb,dvb_usb_rtl2832u_snrdb, int, 0644); ++MODULE_PARM_DESC(snrdb, "SNR type output (0=16bit, 1=dB decibel), default=0"); ++ ++ ++ ++ ++//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) ++DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); ++//#endif ++ ++#define USB_EPA_CTL 0x0148 ++ ++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++#define RT_RC_POLLING_INTERVAL_TIME_MS 287 ++#define MAX_RC_PROTOCOL_NUM 3 ++ ++/* original realtek remote control key map */ ++/* ++static struct dvb_usb_rc_key rtl2832u_rc_keys_map_table[] = {// realtek Key map ++ { 0x0400, KEY_0 }, // 0 ++ { 0x0401, KEY_1 }, // 1 ++ { 0x0402, KEY_2 }, // 2 ++ { 0x0403, KEY_3 }, // 3 ++ { 0x0404, KEY_4 }, // 4 ++ { 0x0405, KEY_5 }, // 5 ++ { 0x0406, KEY_6 }, // 6 ++ { 0x0407, KEY_7 }, // 7 ++ { 0x0408, KEY_8 }, // 8 ++ { 0x0409, KEY_9 }, // 9 ++ { 0x040c, KEY_POWER }, // POWER ++ { 0x040e, KEY_MUTE }, // MUTE ++ { 0x0410, KEY_VOLUMEUP }, // VOL UP ++ { 0x0411, KEY_VOLUMEDOWN }, // VOL DOWN ++ { 0x0412, KEY_CHANNELUP }, // CH UP ++ { 0x0413, KEY_CHANNELDOWN }, // CH DOWN ++ { 0x0416, KEY_PLAY }, // PLAY ++ { 0x0417, KEY_RECORD }, // RECORD ++ { 0x0418, KEY_PLAYPAUSE }, // PAUSE ++ { 0x0419, KEY_STOP }, // STOP ++ { 0x041e, KEY_UP}, // UP ++ { 0x041f, KEY_DOWN}, // DOWN ++ { 0x0420, KEY_LEFT }, // LEFT ++ { 0x0421, KEY_RIGHT }, // RIGHT ++ { 0x0422, KEY_ZOOM }, // FULL SCREEN -->OK ++ { 0x0447, KEY_AUDIO }, // MY AUDIO ++ { 0x045b, KEY_MENU}, // RED ++ { 0x045c, KEY_EPG }, // GREEN ++ { 0x045d, KEY_FIRST }, // YELLOW ++ { 0x045e, KEY_LAST }, // BLUE ++ { 0x045a, KEY_TEXT }, // TEXT TV ++ { 0x0423, KEY_BACK }, // <- BACK ++ { 0x0414, KEY_FORWARD } // >> ++ }; ++*/ ++ ++/* Xgazza remote control Ubuntu 11.10 key map */ ++static struct rc_map_table rtl2832u_rc_keys_map_table[] = { ++ { 0x40bf, KEY_POWER2 }, // TV POWER ++ { 0x08f7, KEY_POWER }, // PC POWER ++ { 0x58a7, KEY_REWIND }, // REWIND ++ { 0xd827, KEY_PLAY }, // PLAY ++ { 0x22dd, KEY_FASTFORWARD }, // FAST FORWARD ++ { 0x02fd, KEY_STOP }, // STOP ++ { 0x5aa5, KEY_PREVIOUS }, // SKIP BACK ++ { 0x42bd, KEY_PLAYPAUSE }, // PAUSE ++ { 0xa25d, KEY_NEXT }, // SKIP FOWARD ++ { 0x12ed, KEY_RECORD }, // RECORD ++ { 0x28d7, KEY_BACK }, // BACK ++ { 0xa857, KEY_INFO }, // MORE ++// { 0x28d7, BTN_LEFT }, // MOUSE LEFT BUTTON ++// { 0xa857, BTN_RIGHT }, // MOUSE RIGHT BUTTON ++ { 0x6897, KEY_UP}, // UP ++ { 0x48b7, KEY_DOWN}, // DOWN ++ { 0xe817, KEY_LEFT }, // LEFT ++ { 0x30cf, KEY_RIGHT }, // RIGHT ++ { 0x18e7, KEY_OK }, // OK ++ { 0xc23d, KEY_ZOOM }, // ASPECT ++// { 0xea15, KEY_??? }, // MOUSE ++ { 0x708f, KEY_RED }, // RED ++ { 0xc837, KEY_GREEN }, // GREEN ++ { 0x8877, KEY_YELLOW }, // YELLOW ++ { 0x9867, KEY_BLUE }, // BLUE ++ { 0x807f, KEY_VOLUMEUP }, // VOL UP ++ { 0x7887, KEY_VOLUMEDOWN }, // VOL DOWN ++ { 0xb04f, KEY_HOME }, // HOME ++ { 0x00ff, KEY_MUTE }, // MUTE ++ { 0xd22d, KEY_CHANNELUP }, // CH UP ++ { 0xf20d, KEY_CHANNELDOWN }, // CH DOWN ++ { 0x50af, KEY_0 }, // 0 ++ { 0xf807, KEY_1 }, // 1 ++ { 0xc03f, KEY_2 }, // 2 ++ { 0x20df, KEY_3 }, // 3 ++ { 0xa05f, KEY_4 }, // 4 ++ { 0x38c7, KEY_5 }, // 5 ++ { 0x609f, KEY_6 }, // 6 ++ { 0xe01f, KEY_7 }, // 7 ++ { 0x10ef, KEY_8 }, // 8 ++ { 0xb847, KEY_9 }, // 9 ++ { 0x906f, KEY_NUMERIC_STAR }, // * ++ { 0xd02f, KEY_NUMERIC_POUND }, // # ++ { 0x52ad, KEY_EPG }, // GUIDE ++ { 0x926d, KEY_VIDEO }, // RTV ++ { 0x32cd, KEY_HELP }, // HELP ++ { 0xca35, KEY_CYCLEWINDOWS }, // PIP(?) ++ { 0xb24d, KEY_RADIO }, // RADIO ++ { 0x0af5, KEY_DVD }, // DVD ++ { 0x8a75, KEY_AUDIO }, // AUDIO ++ { 0x4ab5, KEY_TITLE } // TITLE ++}; ++ ++//////////////////////////////////////////////////////////////////////////////////////////////////////// ++enum rc_status_define{ ++ RC_FUNCTION_SUCCESS =0, ++ RC_FUNCTION_UNSUCCESS ++}; ++ ++int rtl2832u_remote_control_state=0; ++static int SampleNum2TNum[] = ++{ ++ 0,0,0,0,0, ++ 1,1,1,1,1,1,1,1,1, ++ 2,2,2,2,2,2,2,2,2, ++ 3,3,3,3,3,3,3,3,3, ++ 4,4,4,4,4,4,4,4,4, ++ 5,5,5,5,5,5,5,5, ++ 6,6,6,6,6,6,6,6,6, ++ 7,7,7,7,7,7,7,7,7, ++ 8,8,8,8,8,8,8,8,8, ++ 9,9,9,9,9,9,9,9,9, ++ 10,10,10,10,10,10,10,10,10, ++ 11,11,11,11,11,11,11,11,11, ++ 12,12,12,12,12,12,12,12,12, ++ 13,13,13,13,13,13,13,13,13, ++ 14,14,14,14,14,14,14 ++}; ++//IRRC register table ++static const RT_rc_set_reg_struct p_rtl2832u_rc_initial_table[]= ++{ ++ {RTD2832U_SYS,RC_USE_DEMOD_CTL1 ,0x00,OP_AND,0xfb}, ++ {RTD2832U_SYS,RC_USE_DEMOD_CTL1 ,0x00,OP_AND,0xf7}, ++ {RTD2832U_USB,USB_CTRL ,0x00,OP_OR ,0x20}, ++ {RTD2832U_SYS,SYS_GPD ,0x00,OP_AND,0xf7}, ++ {RTD2832U_SYS,SYS_GPOE ,0x00,OP_OR ,0x08}, ++ {RTD2832U_SYS,SYS_GPO ,0x00,OP_OR ,0x08}, ++ {RTD2832U_RC,IR_RX_CTRL ,0x20,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_BUFFER_CTRL ,0x80,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_IF ,0xff,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_IE ,0xff,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_MAX_DURATION0 ,0xd0,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_MAX_DURATION1 ,0x07,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_IDLE_LEN0 ,0xc0,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_IDLE_LEN1 ,0x00,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_GLITCH_LEN ,0x03,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CLK ,0x09,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CONFIG ,0x1c,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_MAX_H_Tolerance_LEN ,0x1e,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_MAX_L_Tolerance_LEN ,0x1e,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CTRL ,0x80,OP_NO ,0xff} ++ ++}; ++ ++int rtl2832u_remoto_control_initial_setting(struct dvb_usb_device *d) ++{ ++ ++ ++ ++ //begin setting ++ int ret = RC_FUNCTION_SUCCESS; ++ u8 data=0,i=0,NumberOfRcInitialTable=0; ++ ++ ++ deb_rc("+rc_%s\n", __FUNCTION__); ++ ++ NumberOfRcInitialTable = sizeof(p_rtl2832u_rc_initial_table)/sizeof(RT_rc_set_reg_struct); ++ ++ ++ for (i=0;i 0) ++ { ++ ++ highestBit = (*pCode)&0x80; ++ lowBits = (*pCode) & 0x7f; ++ TNum=SampleNum2TNum[lowBits]; ++ ++ if(highestBit != 0) TNum = -TNum; ++ ++ pCode++; ++ byte_num--; ++ ++ if(TNum <= -6) state = WAITING_6T; ++ ++ if(WAITING_6T == state) ++ { ++ if(TNum <= -6) state = WAITING_2T_AFTER_6T; ++ } ++ else if(WAITING_2T_AFTER_6T == state) ++ { ++ if(2 == TNum) ++ { ++ state = WAITING_NORMAL_BITS; ++ LastTNum = 0; ++ CurrentBit = 0; ++ } ++ else state = WAITING_6T; ++ } ++ else if(WAITING_NORMAL_BITS == state) ++ { ++ if(0 == LastTNum) LastTNum = TNum; ++ else { ++ if(LastTNum < 0) ucBits[CurrentBit]=1; ++ else ucBits[CurrentBit]=0; ++ ++ CurrentBit++; ++ ++ if(CurrentBit >= frt0_bits_num) { ++ deb_rc("Bad frame received, bits num is error\n"); ++ CurrentBit = frt0_bits_num -1 ; ++ ++ } ++ if(TNum > 3) { ++ for(i=0;i>24) & frt0_BITS_mask0); ++ p_uccode[1]=(u8)((scancode>>16) & frt0_BITS_mask1); ++ p_uccode[2]=(u8)((scancode>>8) & frt0_BITS_mask2); ++ p_uccode[3]=(u8)((scancode>>0) & frt0_BITS_mask3); ++ ++ deb_rc("-rc_%s 3::rc6:%x %x %x %x \n", __FUNCTION__,p_uccode[0],p_uccode[1],p_uccode[2],p_uccode[3]); ++ ret= RC_FUNCTION_SUCCESS; ++error: ++ ++ return ret; ++} ++ ++ ++static int frt1(u8* rt_uccode,u8 byte_num,u8 *p_uccode) ++{ ++ u8 *pCode = rt_uccode; ++ u8 ucBits[frt1_bits_num]; ++ u8 i=0,CurrentBit=0,index=0; ++ u32 scancode=0; ++ int ret= RC_FUNCTION_SUCCESS; ++ ++ deb_rc("+rc_%s \n", __FUNCTION__); ++ if(byte_num < frt1_para1) { ++ deb_rc("Bad rt uc code received, byte_num = %d is error\n",byte_num); ++ ret = RC_FUNCTION_UNSUCCESS; ++ goto error; ++ } ++ ++ memset(ucBits,0,frt1_bits_num); ++ ++ for(i = 0; i < byte_num; i++) { ++ if ((pCode[i] & frt1_para2)< frt1_para3) index=frt1_para5 ; ++ else index=frt1_para6 ; ++ ++ ucBits[i]= (pCode[i] & 0x80) + index; ++ } ++ if(ucBits[0] !=frt1_para_uc_1 && ucBits[0] !=frt1_para_uc_2 ) {ret= RC_FUNCTION_UNSUCCESS; goto error;} ++ ++ if(ucBits[1] !=frt1_para5 && ucBits[1] !=frt1_para6) {ret= RC_FUNCTION_UNSUCCESS;goto error;} ++ ++ if(ucBits[2] >= frt1_para_uc_1) ucBits[2] -= 0x01; ++ else {ret= RC_FUNCTION_UNSUCCESS;goto error;} ++ ++ ++ i = 0x02; ++ CurrentBit = 0x00; ++ ++ while(i < byte_num-1) ++ { ++ if(CurrentBit >= 32) { ++ break; ++ } ++ ++ if((ucBits[i] & 0x0f) == 0x0) { ++ i++; ++ continue; ++ } ++ if(ucBits[i++] == 0x81) { ++ if(ucBits[i] >=0x01) { ++ scancode |= 0x00 << (31 - CurrentBit++); ++ } ++ } ++ else { ++ if(ucBits[i] >=0x81) { ++ scancode |= 0x01 << (31 - CurrentBit++); ++ } ++ } ++ ++ ucBits[i] -= 0x01; ++ continue; ++ } ++ p_uccode[3]=(u8)((scancode>>16) & frt1_bits_mask3); ++ p_uccode[2]=(u8)((scancode>>24) & frt1_bits_mask2); ++ p_uccode[1]=(u8)((scancode>>8) & frt1_bits_mask1); ++ p_uccode[0]=(u8)((scancode>>0) & frt1_bits_mask0); ++ ++ ++ deb_rc("-rc_%s rc5:%x %x %x %x -->scancode =%x\n", __FUNCTION__,p_uccode[0],p_uccode[1],p_uccode[2],p_uccode[3],scancode); ++ ret= RC_FUNCTION_SUCCESS; ++error: ++ return ret; ++} ++ ++static int frt2(u8* rt_uccode,u8 byte_num,u8 *p_uccode) ++{ ++ u8 *pCode = rt_uccode; ++ u8 i=0; ++ u32 scancode=0; ++ u8 out_io=0; ++ ++ int ret= RC_FUNCTION_SUCCESS; ++ ++ deb_rc("+rc_%s \n", __FUNCTION__); ++ ++ if(byte_num < frt2_para1) goto error; ++ if(pCode[0] != frt2_para2) goto error; ++ if((pCode[1] frt2_para4)) goto error; ++ ++ ++ if( (pCode[2] frt2_para6) ) ++ { ++ ++ if( (pCode[3] frt2_para8 ) &&(pCode[4]==frt2_para9 )) scancode=0xffff; ++ else goto error; ++ ++ } ++ else if( (pCode[2] frt2_para11 ) ) ++ { ++ ++ for (i = 3; i <68; i++) ++ { ++ if ((i% 2)==1) ++ { ++ if( (pCode[i]>frt2_para7 ) || (pCode[i] >24) & frt2_bits_mask0); ++ p_uccode[1]=(u8)((scancode>>16) & frt2_bits_mask1); ++ p_uccode[2]=(u8)((scancode>>8) & frt2_bits_mask2); ++ p_uccode[3]=(u8)((scancode>>0) & frt2_bits_mask3); ++ ret= RC_FUNCTION_SUCCESS; ++error: ++ ++ return ret; ++} ++#define receiveMaskFlag1 0x80 ++#define receiveMaskFlag2 0x03 ++#define flush_step_Number 0x05 ++#define rt_code_len 0x80 ++ ++static int rtl2832u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) ++{ ++ ++ static const RT_rc_set_reg_struct p_flush_table1[]={ ++ {RTD2832U_RC,IR_RX_CTRL ,0x20,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_BUFFER_CTRL ,0x80,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_IF ,0xff,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_IE ,0xff,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CTRL ,0x80,OP_NO ,0xff} ++ ++ }; ++ static const RT_rc_set_reg_struct p_flush_table2[]={ ++ {RTD2832U_RC,IR_RX_IF ,0x03,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_BUFFER_CTRL ,0x80,OP_NO ,0xff}, ++ {RTD2832U_RC,IR_RX_CTRL ,0x80,OP_NO ,0xff} ++ ++ }; ++ ++ ++ u8 data=0,i=0,byte_count=0; ++ int ret=0; ++ u8 rt_u8_code[rt_code_len]; ++ u8 ucode[4]; ++ u16 scancode=0; ++ ++ deb_rc("+%s \n", __FUNCTION__); ++ if (dvb_use_rtl2832u_rc_mode >= MAX_RC_PROTOCOL_NUM) ++ { ++ ++ deb_rc("%s : dvb_use_rtl2832u_rc_mode=%d \n", __FUNCTION__,dvb_use_rtl2832u_rc_mode); ++ return 0; ++ } ++ ++ if(rtl2832u_remote_control_state == RC_NO_SETTING) ++ { ++ deb_rc("%s : IrDA Initial Setting rtl2832u_remote_control_state=%d\n", __FUNCTION__,rtl2832u_remote_control_state); ++ ret=rtl2832u_remoto_control_initial_setting(d); ++ ++ } ++ if ( read_rc_char_bytes( d ,RTD2832U_RC, IR_RX_IF,&data ,LEN_1) ) ++ { ++ ret=-1; ++ deb_rc("%s : Read IrDA IF is failed\n", __FUNCTION__); ++ goto error; ++ } ++ /* debug */ ++ if (data != 0) ++ { ++ deb_rc("%s : IR_RX_IF= 0x%x\n", __FUNCTION__,data); ++ } ++ ++ ++ if (!(data & receiveMaskFlag1)) ++ { ++ ret =0 ; ++ goto error; ++ } ++ ++ if (data & receiveMaskFlag2) ++ { ++ /* delay */ ++ msleep(287); ++ ++ if ( read_rc_char_bytes( d ,RTD2832U_RC,IR_RX_BC,&byte_count ,LEN_1) ) ++ { ++ deb_rc("%s : rc -ir register read error! \n", __FUNCTION__); ++ ret=-1; ++ goto error; ++ } ++ if (byte_count == 0 ) ++ { ++ //ret=0; ++ goto error; ++ } ++ ++ if ((byte_count%LEN_2) == 1) byte_count+=LEN_1; ++ if (byte_count > rt_code_len) byte_count=rt_code_len; ++ ++ memset(rt_u8_code,0,rt_code_len); ++ deb_rc("%s : byte_count= %d type = %d \n", __FUNCTION__,byte_count,dvb_use_rtl2832u_rc_mode); ++ if ( read_rc_char_bytes( d ,RTD2832U_RC,IR_RX_BUF,rt_u8_code ,0x80) ) ++ { ++ deb_rc("%s : rc -ir register read error! \n", __FUNCTION__); ++ ret=-1; ++ goto error; ++ } ++ ++ memset(ucode,0,4); ++ ++ ++ ret=0; ++ if (dvb_use_rtl2832u_rc_mode == 0) ret =frt0(rt_u8_code,byte_count,ucode); ++ else if (dvb_use_rtl2832u_rc_mode == 1) ret =frt1(rt_u8_code,byte_count,ucode); ++ else if (dvb_use_rtl2832u_rc_mode== 2) ret =frt2(rt_u8_code,byte_count,ucode); ++ else ++ { ++ //deb_rc("%s : rc - unknow rc protocol set ! \n", __FUNCTION__); ++ ret=-1; ++ goto error; ++ } ++ ++ if((ret != RC_FUNCTION_SUCCESS) || (ucode[0] ==0 && ucode[1] ==0 && ucode[2] ==0 && ucode[3] ==0)) ++ { ++ //deb_rc("%s : rc-rc is error scan code ! %x %x %x %x \n", __FUNCTION__,ucode[0],ucode[1],ucode[2],ucode[3]); ++ ret=-1; ++ goto error; ++ } ++ scancode=(ucode[2]<<8) | ucode[3] ; ++ deb_info("-%s scan code %x %x %x %x,(0x%x) -- len=%d\n", __FUNCTION__,ucode[0],ucode[1],ucode[2],ucode[3],scancode,byte_count); ++ ////////// map///////////////////////////////////////////////////////////////////////////////////////////////////// ++ for (i = 0; i < ARRAY_SIZE(rtl2832u_rc_keys_map_table); i++) { ++ if(rtl2832u_rc_keys_map_table[i].scancode == scancode ){ ++#ifdef V4L2_REFACTORED_RC_CODE ++ *event = rtl2832u_rc_keys_map_table[i].keycode; ++#else ++ *event = rtl2832u_rc_keys_map_table[i].event; ++#endif ++ *state = REMOTE_KEY_PRESSED; ++ deb_rc("%s : map number = %d \n", __FUNCTION__,i); ++ break; ++ } ++ ++ } ++ ++ memset(rt_u8_code,0,rt_code_len); ++ byte_count=0; ++ for (i=0;i<3;i++){ ++ data= p_flush_table2[i].data; ++ if ( write_rc_char_bytes( d ,RTD2832U_RC, p_flush_table2[i].address,&data,LEN_1) ) { ++ deb_rc("+%s : rc -ir register write error! \n", __FUNCTION__); ++ ret=-1; ++ goto error; ++ } ++ ++ } ++ ++ ret =0; ++ return ret; ++ } ++error: ++ memset(rt_u8_code,0,rt_code_len); ++ byte_count=0; ++ for (i=0;idev , RTD2832U_USB , USB_EPA_CTL , data , 2) ) goto error; ++ } ++ else ++ { ++ data[0] = 0x10; //3stall epa, set bit 4 to 1 ++ data[1] = 0x02; //3reset epa, set bit 9 to 1 ++ if ( write_usb_sys_char_bytes( adap->dev , RTD2832U_USB , USB_EPA_CTL , data , 2) ) goto error; ++ } ++ ++ return 0; ++error: ++ return -1; ++} ++ ++ ++static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) ++{ ++#ifdef V4L2_REFACTORED_MFE_CODE ++ adap->fe_adap[0].fe = rtl2832u_fe_attach(adap->dev); ++#else ++ adap->fe = rtl2832u_fe_attach(adap->dev); ++#endif ++ return 0; ++} ++ ++ ++static void rtl2832u_usb_disconnect(struct usb_interface *intf) ++{ ++ try_module_get(THIS_MODULE); ++ dvb_usb_device_exit(intf); ++} ++ ++ ++static struct dvb_usb_device_properties rtl2832u_1st_properties; ++static struct dvb_usb_device_properties rtl2832u_2nd_properties; ++static struct dvb_usb_device_properties rtl2832u_3th_properties; ++static struct dvb_usb_device_properties rtl2832u_4th_properties; ++static struct dvb_usb_device_properties rtl2832u_5th_properties; ++static struct dvb_usb_device_properties rtl2832u_6th_properties; ++static struct dvb_usb_device_properties rtl2832u_7th_properties; ++static struct dvb_usb_device_properties rtl2832u_8th_properties; ++static struct dvb_usb_device_properties rtl2832u_9th_properties; ++ ++ ++//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) ++static int rtl2832u_usb_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ /* Thats avoids bugs with 2 instances of driver that operate same hardware */ ++ /* https://gitorious.org/rtl2832/rtl2832/commit/5495b3fda9e2c3bf4feef5d5751f6f2343380ea9 */ ++ if (!intf->altsetting->desc.bNumEndpoints) ++ return -ENODEV; ++ ++ if ( ( 0== dvb_usb_device_init(intf,&rtl2832u_1st_properties,THIS_MODULE,NULL,adapter_nr) )|| ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_2nd_properties,THIS_MODULE,NULL,adapter_nr) ) || ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_3th_properties,THIS_MODULE,NULL,adapter_nr) ) || ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_4th_properties,THIS_MODULE,NULL,adapter_nr) ) || ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_5th_properties,THIS_MODULE,NULL,adapter_nr) ) || ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_6th_properties,THIS_MODULE,NULL,adapter_nr) ) || ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_7th_properties,THIS_MODULE,NULL,adapter_nr) ) || ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_8th_properties,THIS_MODULE,NULL,adapter_nr) ) || ++ ( 0== dvb_usb_device_init(intf,&rtl2832u_9th_properties,THIS_MODULE,NULL,adapter_nr) ) ) ++ return 0; ++ ++ return -ENODEV; ++} ++ ++static struct usb_device_id rtl2832u_usb_table [] = { ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2832_WARM) }, // 0 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2838_WARM) }, // 1 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2836_WARM) }, // 2 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2839_WARM) }, // 3 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2840_WARM) }, // 4 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2841_WARM) }, // 5 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2834_WARM) }, // 6 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2837_WARM) }, // 7 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2820_WARM) }, // 8 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2821_WARM) }, // 9 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2822_WARM) }, // 10 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2823_WARM) }, // 11 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2810_WARM) }, // 12 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2811_WARM) }, // 13 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2824_WARM) }, // 14 ++ { USB_DEVICE(USB_VID_REALTEK, USB_PID_RTL2825_WARM) }, // 15 ++ ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_1101) }, // 16 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_1102) }, // 17 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_1103) }, // 18 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_1104) }, // 19 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_1105) }, // 20 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_1106) }, // 21 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_1107) }, // 22 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_1108) }, // 23 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_2101) }, // 24 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_8202) }, // 25 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_9201) }, // 26 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_3103) }, // 27 ++ { USB_DEVICE(USB_VID_DEXATEK, USB_PID_DEXATEK_9202) }, // 28 ++ ++ { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_00A9)}, // 29 ++ { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_00B3)}, // 30 ++ ++ { USB_DEVICE(USB_VID_AZUREWAVE_2, USB_PID_AZUREWAVE_3234) }, // 31 ++ { USB_DEVICE(USB_VID_AZUREWAVE_2, USB_PID_AZUREWAVE_3274) }, // 32 ++ { USB_DEVICE(USB_VID_AZUREWAVE_2, USB_PID_AZUREWAVE_3282) }, // 33 ++ ++ { USB_DEVICE(USB_VID_THP, USB_PID_THP_5013)}, // 34 ++ { USB_DEVICE(USB_VID_THP, USB_PID_THP_5020)}, // 35 ++ { USB_DEVICE(USB_VID_THP, USB_PID_THP_5026)}, // 36 ++ ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D393) }, // 37 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D394) }, // 38 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D395) }, // 39 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D396) }, // 40 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D397) }, // 41 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D398) }, // 42 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D39A) }, // 43 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D39B) }, // 44 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D39C) }, // 45 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D39E) }, // 46 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_E77B) }, // 47 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D3A1) }, // 48 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_D3A4) }, // 49 ++ { USB_DEVICE(USB_VID_KWORLD_1ST, USB_PID_KWORLD_E41D) }, // 50 ++ ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_0837)}, // 51 ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_A803)}, // 52 ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_B803)}, // 53 ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_C803)}, // 54 ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_D803)}, // 55 ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_C280)}, // 56 ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_D286)}, // 57 ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_0139)}, // 58 ++ { USB_DEVICE(USB_VID_GTEK, USB_PID_GTEK_WARM_A683)}, // 59 ++ ++ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_LEADTEK_WARM_1)}, // 60 ++ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_LEADTEK_WARM_2)}, // 61 ++ ++ { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_WARM)}, //62 ++ { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_WARM80)}, //63 ++ { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_WARM84)}, //64 ++ ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_0620)}, // 65 ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_0630)}, // 66 ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_0640)}, // 67 ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_0650)}, // 68 ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_0680)}, // 69 ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_9580)}, // 70 ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_9550)}, // 71 ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_9540)}, // 72 ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_9530)}, // 73 71 //------rtl2832u_6th_properties(6) ++ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_WARM_9520)}, // 74 ++ ++ { USB_DEVICE(USB_VID_GOLDENBRIDGE, USB_PID_GOLDENBRIDGE_WARM)}, //75 ++ ++ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_MINI)}, // 76 ++ ++ { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_00D3)}, // 77 ++ { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_00D4)}, // 78 ++ { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_00E0)}, // 79 ++ ++ { 0 }, ++}; ++ ++ ++MODULE_DEVICE_TABLE(usb, rtl2832u_usb_table); ++ ++static struct dvb_usb_device_properties rtl2832u_1st_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++#ifndef NO_FE_IOCTL_OVERRIDE ++ .fe_ioctl_override = rtl2832_fe_ioctl_override, ++#endif ++#ifdef V4L2_REFACTORED_MFE_CODE ++ .num_frontends = 1, ++ .fe = {{ ++#endif ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++#ifdef V4L2_REFACTORED_MFE_CODE ++ }}, ++#endif ++ } ++ }, ++ ++ //remote control ++ .rc.legacy = { ++#ifdef V4L2_REFACTORED_RC_CODE ++ .rc_map_table = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#else ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#endif ++ .rc_query = rtl2832u_rc_query, //use define quary function ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ }, ++ ++ .num_device_descs = 9, ++ .devices = { ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[0], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[1], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[2], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[3], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[4], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[5], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[6], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[7], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[8], NULL }, ++ }, ++ { NULL }, ++ } ++}; ++ ++ ++static struct dvb_usb_device_properties rtl2832u_2nd_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++#ifndef NO_FE_IOCTL_OVERRIDE ++ .fe_ioctl_override = rtl2832_fe_ioctl_override, ++#endif ++#ifdef V4L2_REFACTORED_MFE_CODE ++ .num_frontends = 1, ++ .fe = {{ ++#endif ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++#ifdef V4L2_REFACTORED_MFE_CODE ++ }}, ++#endif ++ } ++ }, ++ //remote control ++ .rc.legacy = { ++#ifdef V4L2_REFACTORED_RC_CODE ++ .rc_map_table = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#else ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#endif ++ .rc_query = rtl2832u_rc_query, //use define query function ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ }, ++ ++ .num_device_descs = 9, ++ .devices = { ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[9], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[10], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[11], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[12], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[13], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[14], NULL }, ++ }, ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[15], NULL }, ++ }, ++ { .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[16], NULL }, ++ }, ++ { .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[17], NULL }, ++ }, ++ { NULL }, ++ } ++}; ++ ++ ++ ++static struct dvb_usb_device_properties rtl2832u_3th_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++#ifndef NO_FE_IOCTL_OVERRIDE ++ .fe_ioctl_override = rtl2832_fe_ioctl_override, ++#endif ++#ifdef V4L2_REFACTORED_MFE_CODE ++ .num_frontends = 1, ++ .fe = {{ ++#endif ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++#ifdef V4L2_REFACTORED_MFE_CODE ++ }}, ++#endif ++ } ++ }, ++ ++ //remote control ++ .rc.legacy = { ++#ifdef V4L2_REFACTORED_RC_CODE ++ .rc_map_table = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#else ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#endif ++ .rc_query = rtl2832u_rc_query, //use define query function ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ }, ++ ++ .num_device_descs = 9, ++ .devices = { ++ { .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[18], NULL }, ++ }, ++ { .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[19], NULL }, ++ }, ++ { .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[20], NULL }, ++ }, ++ { ++ .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[21], NULL }, ++ }, ++ { ++ .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[22], NULL }, ++ }, ++ { ++ .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[23], NULL }, ++ }, ++ { ++ .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[24], NULL }, ++ }, ++ { ++ .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[25], NULL }, ++ }, ++ { ++ .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[26], NULL }, ++ } ++ } ++}; ++ ++ ++static struct dvb_usb_device_properties rtl2832u_4th_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++#ifndef NO_FE_IOCTL_OVERRIDE ++ .fe_ioctl_override = rtl2832_fe_ioctl_override, ++#endif ++#ifdef V4L2_REFACTORED_MFE_CODE ++ .num_frontends = 1, ++ .fe = {{ ++#endif ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++#ifdef V4L2_REFACTORED_MFE_CODE ++ }}, ++#endif ++ } ++ }, ++ ++ //remote control ++ .rc.legacy = { ++#ifdef V4L2_REFACTORED_RC_CODE ++ .rc_map_table = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#else ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#endif ++ .rc_query = rtl2832u_rc_query, //use define query function ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ }, ++ ++ .num_device_descs = 12, ++ .devices = { ++ { .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[27], NULL }, ++ }, ++ { .name = "DK DONGLE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[28], NULL }, ++ }, ++ { .name = "Terratec Cinergy T Stick Black", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[29], NULL }, ++ }, ++ { ++ .name = "Terratec Cinergy T Stick Black", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[30], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[31], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[32], NULL }, ++ }, ++ ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[33], NULL }, ++ }, ++ ++ { ++ .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[34], NULL }, ++ }, ++ ++ { ++ .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[35], NULL }, ++ }, ++ ++ { ++ .name = "Terratec Cinergy T Stick RC (Rev.3)", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[77], NULL }, ++ }, ++ ++ { ++ .name = "Terratec Cinergy T Stick BLACK (Rev.2)", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[78], NULL }, ++ }, ++ ++ { ++ .name = "Terratec Noxon DAB Stick (Rev.2)", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[79], NULL }, ++ }, ++ } ++}; ++ ++static struct dvb_usb_device_properties rtl2832u_5th_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++#ifndef NO_FE_IOCTL_OVERRIDE ++ .fe_ioctl_override = rtl2832_fe_ioctl_override, ++#endif ++#ifdef V4L2_REFACTORED_MFE_CODE ++ .num_frontends = 1, ++ .fe = {{ ++#endif ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++#ifdef V4L2_REFACTORED_MFE_CODE ++ }}, ++#endif ++ } ++ }, ++ ++ //remote control ++ .rc.legacy = { ++#ifdef V4L2_REFACTORED_RC_CODE ++ .rc_map_table = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#else ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#endif ++ .rc_query = rtl2832u_rc_query, //use define query function ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ }, ++ ++ .num_device_descs = 9, ++ .devices = { ++ { .name = "RTL2832U DVB-T USB DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[36], NULL }, ++ }, ++ { .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[37], NULL }, ++ }, ++ { .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[38], NULL }, ++ }, ++ { ++ .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[39], NULL }, ++ }, ++ { ++ .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[40], NULL }, ++ }, ++ { ++ .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[41], NULL }, ++ }, ++ ++ { ++ .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[42], NULL }, ++ }, ++ ++ { ++ .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[43], NULL }, ++ }, ++ ++ { ++ .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[44], NULL }, ++ }, ++ ++ ++ } ++}; ++ ++static struct dvb_usb_device_properties rtl2832u_6th_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++#ifndef NO_FE_IOCTL_OVERRIDE ++ .fe_ioctl_override = rtl2832_fe_ioctl_override, ++#endif ++#ifdef V4L2_REFACTORED_MFE_CODE ++ .num_frontends = 1, ++ .fe = {{ ++#endif ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++#ifdef V4L2_REFACTORED_MFE_CODE ++ }}, ++#endif ++ } ++ }, ++ ++ /*remote control*/ ++ .rc.legacy = { ++#ifdef V4L2_REFACTORED_RC_CODE ++ .rc_map_table = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#else ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#endif ++ .rc_query = rtl2832u_rc_query, //use define query function ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ }, ++ ++ .num_device_descs = 9, ++ .devices = { ++ { .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[45], NULL }, ++ }, ++ { .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[46], NULL }, ++ }, ++ { .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[47], NULL }, ++ }, ++ { ++ .name ="USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[48], NULL }, ++ }, ++ { ++ .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[49], NULL }, ++ }, ++ { ++ .name = "USB DVB-T DEVICE", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[50], NULL }, ++ }, ++ { ++ .name ="DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[51], NULL }, ++ }, ++ { ++ .name = "DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[52], NULL }, ++ }, ++ { ++ .name = "DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[53], NULL }, ++ }, ++ ++ { NULL }, ++ ++ ++ } ++}; ++ ++static struct dvb_usb_device_properties rtl2832u_7th_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++#ifndef NO_FE_IOCTL_OVERRIDE ++ .fe_ioctl_override = rtl2832_fe_ioctl_override, ++#endif ++#ifdef V4L2_REFACTORED_MFE_CODE ++ .num_frontends = 1, ++ .fe = {{ ++#endif ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++#ifdef V4L2_REFACTORED_MFE_CODE ++ }}, ++#endif ++ } ++ }, ++ ++ //remote control ++ .rc.legacy = { ++#ifdef V4L2_REFACTORED_RC_CODE ++ .rc_map_table = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#else ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#endif ++ .rc_query = rtl2832u_rc_query, //use define query function ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ }, ++ ++ .num_device_descs = 10, ++ .devices = { ++ { .name = "DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[54], NULL }, ++ }, ++ { .name = "DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[55], NULL }, ++ }, ++ { .name = "DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[56], NULL }, ++ }, ++ { ++ .name ="DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[57], NULL }, ++ }, ++ { .name = "DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[58], NULL }, ++ }, ++ { .name = "DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[59], NULL }, ++ }, ++ { .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[60], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[61], NULL }, ++ }, ++ { ++ .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[62], NULL }, ++ }, ++ { .name = "Leadtek WinFast DTV Dongle Mini", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[76], NULL }, ++ }, ++ { NULL }, ++ } ++}; ++ ++static struct dvb_usb_device_properties rtl2832u_8th_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++#ifndef NO_FE_IOCTL_OVERRIDE ++ .fe_ioctl_override = rtl2832_fe_ioctl_override, ++#endif ++#ifdef V4L2_REFACTORED_MFE_CODE ++ .num_frontends = 1, ++ .fe = {{ ++#endif ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++#ifdef V4L2_REFACTORED_MFE_CODE ++ }}, ++#endif ++ } ++ }, ++ ++ //remote control ++ .rc.legacy = { ++#ifdef V4L2_REFACTORED_RC_CODE ++ .rc_map_table = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#else ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#endif ++ .rc_query = rtl2832u_rc_query, //use define query function ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ }, ++ ++ .num_device_descs = 9, ++ .devices = { ++ { .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[63], NULL }, ++ }, ++ { .name = "USB DVB-T Device", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[64], NULL }, ++ }, ++ { .name = "VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[65], NULL }, ++ }, ++ { ++ .name ="VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[66], NULL }, ++ }, ++ { .name = "VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[67], NULL }, ++ }, ++ { .name = "VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[68], NULL }, ++ }, ++ { .name = "VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[69], NULL }, ++ }, ++ { ++ .name ="VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[70], NULL }, ++ }, ++ { ++ .name ="VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[71], NULL }, ++ }, ++ ++ { NULL }, ++ } ++}; ++ ++static struct dvb_usb_device_properties rtl2832u_9th_properties = { ++ ++ .num_adapters = 1, ++ .adapter = ++ { ++ { ++#ifndef NO_FE_IOCTL_OVERRIDE ++ .fe_ioctl_override = rtl2832_fe_ioctl_override, ++#endif ++#ifdef V4L2_REFACTORED_MFE_CODE ++ .num_frontends = 1, ++ .fe = {{ ++#endif ++ .streaming_ctrl = rtl2832u_streaming_ctrl, ++ .frontend_attach = rtl2832u_frontend_attach, ++ //parameter for the MPEG2-data transfer ++ .stream = ++ { ++ .type = USB_BULK, ++ .count = RTD2831_URB_NUMBER, ++ .endpoint = 0x01, //data pipe ++ .u = ++ { ++ .bulk = ++ { ++ .buffersize = RTD2831_URB_SIZE, ++ } ++ } ++ }, ++#ifdef V4L2_REFACTORED_MFE_CODE ++ }}, ++#endif ++ } ++ }, ++ ++ //remote control ++ .rc.legacy = { ++#ifdef V4L2_REFACTORED_RC_CODE ++ .rc_map_table = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#else ++ .rc_key_map = rtl2832u_rc_keys_map_table, //user define key map ++ .rc_key_map_size = ARRAY_SIZE(rtl2832u_rc_keys_map_table), //user define key map size ++#endif ++ .rc_query = rtl2832u_rc_query, //use define query function ++ .rc_interval = RT_RC_POLLING_INTERVAL_TIME_MS, ++ }, ++ ++ .num_device_descs = 4, ++ .devices = { ++ { ++ .name ="VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[72], NULL }, ++ }, ++ { ++ .name ="VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[73], NULL }, ++ }, ++ { .name = "VideoMate DTV", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[74], NULL }, ++ }, ++ { .name = "DVB-T TV Stick", ++ .cold_ids = { NULL, NULL }, ++ .warm_ids = { &rtl2832u_usb_table[75], NULL }, ++ }, ++ { NULL }, ++ } ++}; ++ ++ ++ ++ ++static struct usb_driver rtl2832u_usb_driver = { ++ .name = "dvb_usb_rtl2832u", ++ .probe = rtl2832u_usb_probe, ++ .disconnect = rtl2832u_usb_disconnect, ++ .id_table = rtl2832u_usb_table, ++}; ++ ++ ++static int __init rtl2832u_usb_module_init(void) ++{ ++ int result =0 ; ++ ++ deb_info("+info debug open_%s\n", __FUNCTION__); ++ if ((result = usb_register(&rtl2832u_usb_driver))) { ++ err("usb_register failed. (%d)",result); ++ return result; ++ } ++ ++ return 0; ++} ++ ++static void __exit rtl2832u_usb_module_exit(void) ++{ ++ usb_deregister(&rtl2832u_usb_driver); ++ ++ return ; ++} ++ ++ ++ ++module_init(rtl2832u_usb_module_init); ++module_exit(rtl2832u_usb_module_exit); ++ ++ ++MODULE_AUTHOR("Realtek"); ++MODULE_AUTHOR("Chialing Lu "); ++MODULE_AUTHOR("Dean Chung"); ++MODULE_DESCRIPTION("Driver for the RTL2832U DVB-T / RTL2836 DTMB USB2.0 device"); ++MODULE_VERSION("2.2.2"); ++MODULE_LICENSE("GPL"); ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/rtl2832u_fe.c b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_fe.c +--- a/drivers/media/dvb/dvb-usb/rtl2832u_fe.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_fe.c 2016-04-02 19:17:52.120066046 -0300 +@@ -0,0 +1,4747 @@ ++ ++#include "rtl2832u_fe.h" ++#include "rtl2832u_io.h" ++#include "rtl2832u.h" ++#include "rtl2832u_audio.h" ++//#include "rtl2832u_ioctl.h" ++ ++extern int demod_default_type; ++extern int dtmb_error_packet_discard; ++extern int dvb_use_rtl2832u_card_type; ++extern int dvb_use_rtl2832u_rc_mode; ++extern int rtl2832u_remote_control_state; ++ ++static struct rtl2832_reg_addr rtl2832_reg_map[]= { ++ /* RTD2831_RMAP_INDEX_USB_CTRL_BIT5*/ { RTD2832U_USB, USB_CTRL, 5, 5 }, ++ /* RTD2831_RMAP_INDEX_USB_STAT*/ { RTD2832U_USB, USB_STAT, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_USB_EPA_CTL*/ { RTD2832U_USB, USB_EPA_CTL, 0, 31 }, ++ /* RTD2831_RMAP_INDEX_USB_SYSCTL*/ { RTD2832U_USB, USB_SYSCTL, 0, 31 }, ++ /* RTD2831_RMAP_INDEX_USB_EPA_CFG*/ { RTD2832U_USB, USB_EPA_CFG, 0, 31 }, ++ /* RTD2831_RMAP_INDEX_USB_EPA_MAXPKT*/ { RTD2832U_USB, USB_EPA_MAXPKT, 0, 31}, ++ /* RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG*/ { RTD2832U_USB, USB_EPA_FIFO_CFG, 0, 31}, ++ ++ /* RTD2831_RMAP_INDEX_SYS_DEMOD_CTL*/ { RTD2832U_SYS, DEMOD_CTL, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL*/ { RTD2832U_SYS, GPIO_OUTPUT_VAL, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT3*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 3, 3 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT3*/ { RTD2832U_SYS, GPIO_DIR, 3, 3 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_CFG0_BIT67*/ { RTD2832U_SYS, GPIO_CFG0, 6, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1*/ { RTD2832U_SYS, DEMOD_CTL1, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT1*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 1, 1 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT1*/ { RTD2832U_SYS, GPIO_DIR, 1, 1 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT6*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 6, 6 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT6*/ { RTD2832U_SYS, GPIO_DIR, 6, 6 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT5*/{ RTD2832U_SYS, GPIO_OUTPUT_EN, 5, 5}, ++ /* RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT5*/ { RTD2832U_SYS, GPIO_DIR, 5, 5}, ++ ++#if 0 ++ /* RTD2831_RMAP_INDEX_SYS_GPD*/ { RTD2832U_SYS, GPD, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPOE*/ { RTD2832U_SYS, GPOE, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_GPO*/ { RTD2832U_SYS, GPO, 0, 7 }, ++ /* RTD2831_RMAP_INDEX_SYS_SYS_0*/ { RTD2832U_SYS, SYS_0, 0, 7 }, ++#endif ++ ++ /* DTMB related */ ++ ++ ++}; ++ ++static int rtl2832_reg_mask[32]= { ++ 0x00000001, ++ 0x00000003, ++ 0x00000007, ++ 0x0000000f, ++ 0x0000001f, ++ 0x0000003f, ++ 0x0000007f, ++ 0x000000ff, ++ 0x000001ff, ++ 0x000003ff, ++ 0x000007ff, ++ 0x00000fff, ++ 0x00001fff, ++ 0x00003fff, ++ 0x00007fff, ++ 0x0000ffff, ++ 0x0001ffff, ++ 0x0003ffff, ++ 0x0007ffff, ++ 0x000fffff, ++ 0x001fffff, ++ 0x003fffff, ++ 0x007fffff, ++ 0x00ffffff, ++ 0x01ffffff, ++ 0x03ffffff, ++ 0x07ffffff, ++ 0x0fffffff, ++ 0x1fffffff, ++ 0x3fffffff, ++ 0x7fffffff, ++ 0xffffffff ++}; ++ ++typedef struct FC0012_LNA_REG_MAP ++{ ++ unsigned char Lna_regValue; ++ long LnaGain; ++}FC0012_LNA_REG_MAP; ++ ++FC0012_LNA_REG_MAP FC0012_LNA_GAIN_TABLE[]= { ++ {0x00 , -63},{0x01 , -58},{0x02 , -99},{0x03 , -73},{0x04 , -63},{0x05 , -65} ++ ,{0x06 , -54},{0x07 , -60},{0x08 , 71 },{0x09 , 70 },{0x0a , 68 },{0x0b , 67 } ++ ,{0x0c , 65 },{0x0d , 63 },{0x0e , 61 },{0x0f , 58 },{0x10 , 197},{0x11 , 191} ++ ,{0x12 , 188},{0x13 , 186},{0x14 , 184},{0x15 , 182},{0x16 , 181},{0x17 , 179} ++}; ++ ++static int check_dtmb_support(struct rtl2832_state* p_state); ++ ++static int check_dvbc_support(struct rtl2832_state* p_state); ++ ++static int ++set_demod_2836_power( ++ struct rtl2832_state* p_state, ++ int onoff); ++ ++static int ++rtl2840_on_hwreset( ++ struct rtl2832_state* p_state); ++ ++ ++static int ++set_demod_2840_power( ++ struct rtl2832_state* p_state, ++ int onoff); ++ ++ ++static int ++demod_init_setting( ++ struct rtl2832_state * p_state); ++ ++static int ++build_nim_module( ++ struct rtl2832_state* p_state); ++ ++static int ++rtl2836_scan_procedure( ++ struct rtl2832_state * p_state); ++static int ++fc0012_get_signal_strength( ++ struct rtl2832_state *p_state, ++ unsigned long *strength); ++static int ++rtl2832_sleep_mode(struct rtl2832_state* p_state); ++ ++static void ++custom_wait_ms( ++ BASE_INTERFACE_MODULE* pBaseInterface, ++ unsigned long WaitTimeMs) ++{ ++ platform_wait(WaitTimeMs); ++ return; ++} ++ ++ ++static int ++custom_i2c_read( ++ BASE_INTERFACE_MODULE* pBaseInterface, ++ unsigned char DeviceAddr, ++ unsigned char* pReadingBytes, ++ unsigned long ByteNum ++ ) ++{ ++ struct dvb_usb_device *d; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ if ( read_rtl2832_stdi2c( d, DeviceAddr , pReadingBytes , ByteNum ) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++ ++static int ++custom_i2c_write( ++ BASE_INTERFACE_MODULE* pBaseInterface, ++ unsigned char DeviceAddr, ++ const unsigned char* pWritingBytes, ++ unsigned long ByteNum) ++{ ++ struct dvb_usb_device *d; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ if ( write_rtl2832_stdi2c( d, DeviceAddr , (unsigned char*)pWritingBytes , ByteNum ) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++ ++static int ++read_usb_sys_register( ++ struct rtl2832_state* p_state, ++ rtl2832_reg_map_index reg_map_index, ++ int* p_val) ++{ ++ RegType reg_type= rtl2832_reg_map[reg_map_index].reg_type; ++ unsigned short reg_addr= rtl2832_reg_map[reg_map_index].reg_addr; ++ int bit_low= rtl2832_reg_map[reg_map_index].bit_low; ++ int bit_high= rtl2832_reg_map[reg_map_index].bit_high; ++ ++ int n_byte_read=(bit_high>> 3)+ 1; ++ ++ *p_val= 0; ++ if (read_usb_sys_int_bytes(p_state->d, reg_type, reg_addr, n_byte_read, p_val)) goto error; ++ ++ *p_val= ((*p_val>> bit_low) & rtl2832_reg_mask[bit_high- bit_low]); ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++ ++static int ++write_usb_sys_register( ++ struct rtl2832_state* p_state, ++ rtl2832_reg_map_index reg_map_index, ++ int val_write) ++{ ++ RegType reg_type= rtl2832_reg_map[reg_map_index].reg_type; ++ unsigned short reg_addr= rtl2832_reg_map[reg_map_index].reg_addr; ++ int bit_low= rtl2832_reg_map[reg_map_index].bit_low; ++ int bit_high= rtl2832_reg_map[reg_map_index].bit_high; ++ ++ int n_byte_write= (bit_high>> 3)+ 1; ++ int val_read= 0; ++ int new_val_write; ++ ++ if (read_usb_sys_int_bytes(p_state->d, reg_type, reg_addr, n_byte_write, &val_read)) goto error; ++ ++ new_val_write= (val_read & (~(rtl2832_reg_mask[bit_high- bit_low]<< bit_low))) | (val_write<< bit_low); ++ ++ if (write_usb_sys_int_bytes(p_state->d, reg_type, reg_addr, n_byte_write, new_val_write)) goto error; ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++ ++static int ++max3543_set_power( ++ struct rtl2832_state* p_state, ++ unsigned char onoff ++ ) ++{ ++ unsigned char data; ++ unsigned char i2c_repeater; ++ ++ ++ if( p_state->tuner_type != RTL2832_TUNER_TYPE_MAX3543) return 0; ++ ++ deb_info(" %s : onoff =%d\n", __FUNCTION__, onoff); ++ ++ read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ i2c_repeater |= BIT3; ++ write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ ++ if(onoff) ++ { ++ //turn on BIT7=0 ++ read_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_SHUTDOWN_OFFSET, &data, LEN_1_BYTE); ++ data &=(~BIT_7_MASK); ++ write_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_SHUTDOWN_OFFSET, &data, LEN_1_BYTE); ++ } ++ else ++ { ++ //turn off BIT7=1 ++ read_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_SHUTDOWN_OFFSET, &data, LEN_1_BYTE); ++ data |=BIT_7_MASK; ++ write_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_SHUTDOWN_OFFSET, &data, LEN_1_BYTE); ++ } ++ ++ read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ i2c_repeater &= (~BIT3); ++ write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ ++ ++ return 0; ++ ++} ++ ++ ++static int ++set_tuner_power( ++ struct rtl2832_state* p_state, ++ unsigned char b_gpio4, ++ unsigned char onoff) ++{ ++ ++ int data; ++ ++ if(onoff==0) max3543_set_power(p_state, onoff); ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ ++ if(b_gpio4) ++ { ++ if(onoff) data &= ~(BIT4); //set bit4 to 0 ++ else data |= BIT4; //set bit4 to 1 ++ ++ } ++ else ++ { ++ if(onoff) data &= ~(BIT3); //set bit3 to 0 ++ else data |= BIT3; //set bit3 to 1 ++ } ++ ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error; ++ ++ ++ if(onoff==1) max3543_set_power(p_state, onoff); ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++static int ++set_demod_power( ++ struct rtl2832_state* p_state, ++ unsigned char onoff) ++{ ++ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ if(onoff) data &= ~(BIT0); //set bit0 to 0 ++ else data |= BIT0; //set bit0 to 1 ++ data &= ~(BIT0); //3 Demod Power always ON => hw issue. ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ return 0; ++error: ++ return 1; ++} ++ ++ ++//3//////// Set GPIO3 "OUT" => Turn ON/OFF Tuner Power ++//3//////// Set GPIO3 "IN" => Button Wake UP (USB IF) , NO implement in rtl2832u linux driver ++ ++static int ++gpio3_out_setting( ++ struct rtl2832_state* p_state) ++{ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ // GPIO3_PAD Pull-HIGH, BIT76 ++ data = 2; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_CFG0_BIT67,data) ) goto error; ++ ++ // GPO_GPIO3 = 1, GPIO3 output value = 1 ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data |= BIT3; //set bit3 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error; ++ ++ // GPD_GPIO3=0, GPIO3 output direction ++ data = 0; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT3,data) ) goto error; ++ ++ // GPOE_GPIO3=1, GPIO3 output enable ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT3,data) ) goto error; ++ ++ //BTN_WAKEUP_DIS = 1 ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_CTRL_BIT5,data) ) goto error; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++ ++ ++ ++ ++static int ++usb_epa_fifo_reset( ++ struct rtl2832_state* p_state) ++{ ++ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ //3 reset epa fifo: ++ //3[9] Reset EPA FIFO ++ //3 [5] FIFO Flush,Write 1 to flush the oldest TS packet (a 188 bytes block) ++ ++ data = 0x0210; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,data) ) goto error; ++ ++ data = 0xffff; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,&data) ) goto error; ++ ++ if( (data & 0xffff) != 0x0210) ++ { ++ deb_info("Write error RTD2831_RMAP_INDEX_USB_EPA_CTL = 0x%x\n",data); ++ goto error; ++ } ++ ++ data=0x0000; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,data) ) goto error; ++ ++ data = 0xffff; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CTL,&data) ) goto error; ++ ++ if( ( data & 0xffff) != 0x0000) ++ { ++ deb_info("Write error RTD2831_RMAP_INDEX_USB_EPA_CTL = 0x%x\n",data); ++ goto error; ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++ ++} ++ ++ ++ ++static int ++usb_init_bulk_setting( ++ struct rtl2832_state* p_state) ++{ ++ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ //3 1.FULL packer mode(for bulk) ++ //3 2.DMA enable. ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_SYSCTL, &data) ) goto error; ++ ++ data &=0xffffff00; ++ data |= 0x09; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_SYSCTL, data) ) goto error; ++ ++ data=0; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_SYSCTL, &data) ) goto error; ++ ++ if((data&0xff)!=0x09) ++ { ++ deb_info("Open bulk FULL packet mode error!!\n"); ++ goto error; ++ } ++ ++ //3check epa config, ++ //3[9-8]:00, 1 transaction per microframe ++ //3[7]:1, epa enable ++ //3[6-5]:10, bulk mode ++ //3[4]:1, device to host ++ //3[3:0]:0001, endpoint number ++ data = 0; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_CFG, &data) ) goto error; ++ if((data&0x0300)!=0x0000 || (data&0xff)!=0xd1) ++ { ++ deb_info("Open bulk EPA config error! data=0x%x \n" , data); ++ goto error; ++ } ++ ++ //3 EPA maxsize packet ++ //3 512:highspeedbulk, 64:fullspeedbulk. ++ //3 940:highspeediso, 940:fullspeediso. ++ ++ //3 get info :HIGH_SPEED or FULL_SPEED ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_STAT, &data) ) goto error; ++ if(data&0x01) ++ { ++ data = 0x00000200; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, data) ) goto error; ++ ++ data=0; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, &data) ) goto error; ++ ++ if((data&0xffff)!=0x0200) ++ { ++ deb_info("Open bulk EPA max packet size error!\n"); ++ goto error; ++ } ++ ++ deb_info("HIGH SPEED\n"); ++ } ++ else ++ { ++ data = 0x00000040; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, data) ) goto error; ++ ++ data=0; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, &data) ) goto error; ++ ++ if((data&0xffff)!=0x0200) ++ { ++ deb_info("Open bulk EPA max packet size error!\n"); ++ goto error; ++ } ++ ++ deb_info("FULL SPEED\n"); ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++static int ++usb_init_setting( ++ struct rtl2832_state* p_state) ++{ ++ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if ( usb_init_bulk_setting(p_state) ) goto error; ++ ++ //3 change fifo length of EPA ++ data = 0x00000014; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG, data) ) goto error; ++ data = 0xcccccccc; ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG, &data) ) goto error; ++ if( (data & 0xff) != 0x14) ++ { ++ deb_info("Write error RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG =0x%x\n",data); ++ goto error; ++ } ++ ++ if ( usb_epa_fifo_reset(p_state) ) goto error; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++static int ++suspend_latch_setting( ++ struct rtl2832_state* p_state, ++ unsigned char resume) ++{ ++ ++ int data; ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if (resume) ++ { ++ //3 Suspend_latch_en = 0 => Set BIT4 = 0 ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data &= (~BIT4); //set bit4 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ } ++ else ++ { ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data |= BIT4; //set bit4 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++ ++} ++ ++ ++ ++ ++ ++//3////// DEMOD_CTL1 => IR Setting , IR wakeup from suspend mode ++//3////// if resume =1, resume ++//3////// if resume = 0, suspend ++ ++ ++static int ++demod_ctl1_setting( ++ struct rtl2832_state* p_state, ++ unsigned char resume) ++{ ++ ++ int data; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if(resume) ++ { ++ // IR_suspend ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data &= (~BIT2); //set bit2 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ ++ //Clk_400k ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data &= (~BIT3); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ } ++ else ++ { ++ //Clk_400k ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data |= BIT3; //set bit3 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ ++ // IR_suspend ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, &data) ) goto error; ++ data |= BIT2; //set bit2 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1,data) ) goto error; ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++ ++} ++ ++ ++ ++ ++static int ++demod_ctl_setting( ++ struct rtl2832_state* p_state, ++ unsigned char resume, ++ unsigned char on) ++{ ++ ++ int data; ++ unsigned char tmp; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if(resume) ++ { ++ // PLL setting ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data |= BIT7; //set bit7 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ ++ ++ ++ ++ //2 + Begin LOCK ++ // Demod H/W Reset ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT5); //set bit5 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data |= BIT5; //set bit5 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ //3 reset page chache to 0 ++ if ( read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 0, 1, &tmp, 1 ) ) goto error; ++ //2 -End LOCK ++ ++ // delay 5ms ++ platform_wait(5); ++ ++ ++ if(on) ++ { ++ // ADC_Q setting on ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data |= BIT3; //set bit3 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ // ADC_I setting on ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data |= BIT6; //set bit3 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ } ++ else ++ { ++ // ADC_I setting off ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT6); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ // ADC_Q setting off ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT3); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ } ++ } ++ else ++ { ++ ++ // ADC_I setting ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT6); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ // ADC_Q setting ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT3); //set bit3 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ // PLL setting ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT7); //set bit7 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++error: ++ return 1; ++ ++} ++ ++ ++static int ++read_tuner_id_register( ++ struct rtl2832_state* p_state, ++ unsigned char tuner_addr, ++ unsigned char tuner_offset, ++ unsigned char* id_data, ++ unsigned char length) ++{ ++ unsigned char i2c_repeater; ++ struct dvb_usb_device* d = p_state->d; ++ ++ //2 + Begin LOCK ++ if(read_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ i2c_repeater |= BIT3; ++ if(write_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ ++ if(read_rtl2832_tuner_register(d, tuner_addr, tuner_offset, id_data, length)) goto error; ++ ++ if(read_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ i2c_repeater &= (~BIT3); ++ if(write_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ //2 - End LOCK ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++static int ++check_mxl5007t_chip_version( ++ struct rtl2832_state* p_state, ++ unsigned char *chipversion) ++{ ++ ++ unsigned char Buffer[LEN_2_BYTE]; ++ unsigned char i2c_repeater; ++ ++ struct dvb_usb_device* d = p_state->d; ++ ++ ++ Buffer[0] = (unsigned char)MXL5007T_I2C_READING_CONST; ++ Buffer[1] = (unsigned char)MXL5007T_CHECK_ADDRESS; ++ ++ ++ if(read_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ i2c_repeater |= BIT3; ++ if(write_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ ++ ++ write_rtl2832_stdi2c(d, MXL5007T_BASE_ADDRESS , Buffer, LEN_2_BYTE); ++ ++ read_rtl2832_stdi2c(d, MXL5007T_BASE_ADDRESS, Buffer, LEN_1_BYTE); ++ ++ if(read_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ i2c_repeater &= (~BIT3); ++ if(write_demod_register(d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 )) goto error; ++ ++ ++ ++ switch(Buffer[0]) ++ { ++ case MXL5007T_CHECK_VALUE: ++ *chipversion = MxL_5007T_V4; ++ break; ++ default: ++ *chipversion = MxL_UNKNOWN_ID; ++ break; ++ } ++ ++ return 0; ++ ++error: ++ ++ return 1; ++ ++} ++ ++ ++ ++ ++ ++ ++static int ++check_tuner_type( ++ struct rtl2832_state *p_state) ++{ ++ ++ unsigned char tuner_id_data[2]; ++ unsigned char chip_version; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ if ((!read_tuner_id_register(p_state, MT2266_TUNER_ADDR, MT2266_OFFSET, tuner_id_data, LEN_1_BYTE)) && ++ ( tuner_id_data[0] == MT2266_CHECK_VAL )) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_MT2266; ++ ++ deb_info(" -%s : MT2266 tuner on board...\n", __FUNCTION__); ++ } ++ else if ((!read_tuner_id_register(p_state, FC2580_TUNER_ADDR, FC2580_OFFSET, tuner_id_data, LEN_1_BYTE)) && ++ ((tuner_id_data[0]&(~BIT7)) == FC2580_CHECK_VAL )) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_FC2580; ++ ++ deb_info(" -%s : FC2580 tuner on board...\n", __FUNCTION__); ++ } ++ else if(( !read_tuner_id_register(p_state, MT2063_TUNER_ADDR, MT2063_CHECK_OFFSET, tuner_id_data, LEN_1_BYTE)) && ++ ( tuner_id_data[0]==MT2063_CHECK_VALUE || tuner_id_data[0]==MT2063_CHECK_VALUE_2)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_MT2063; ++ ++ deb_info(" -%s : MT2063 tuner on board...\n", __FUNCTION__); ++ ++ } ++ else if(( !read_tuner_id_register(p_state, MAX3543_TUNER_ADDR, MAX3543_CHECK_OFFSET, tuner_id_data, LEN_1_BYTE)) && ++ ( tuner_id_data[0]==MAX3543_CHECK_VALUE)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_MAX3543; ++ ++ deb_info(" -%s : MAX3543 tuner on board...\n", __FUNCTION__); ++ ++ } ++ else if ((!read_tuner_id_register(p_state, TUA9001_TUNER_ADDR, TUA9001_OFFSET, tuner_id_data, LEN_2_BYTE)) && ++ (((tuner_id_data[0]<<8)|tuner_id_data[1]) == TUA9001_CHECK_VAL )) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_TUA9001; ++ ++ deb_info(" -%s : TUA9001 tuner on board...\n", __FUNCTION__); ++ } ++ else if ((!check_mxl5007t_chip_version(p_state, &chip_version)) && ++ (chip_version == MXL5007T_CHECK_VALUE) ) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_MXL5007T; ++ ++ deb_info(" -%s : MXL5007T tuner on board...\n", __FUNCTION__); ++ } ++ else if ((!read_tuner_id_register(p_state, FC0012_BASE_ADDRESS , FC0012_CHECK_ADDRESS, tuner_id_data, LEN_1_BYTE)) && ++ (tuner_id_data[0] == FC0012_CHECK_VALUE)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_FC0012; ++ ++ deb_info(" -%s : FC0012 tuner on board...\n", __FUNCTION__); ++ } ++ else if((!read_tuner_id_register(p_state, E4000_BASE_ADDRESS, E4000_CHECK_ADDRESS, tuner_id_data, LEN_1_BYTE)) && ++ (tuner_id_data[0] == E4000_CHECK_VALUE)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_E4000; ++ deb_info(" -%s : E4000 tuner on board...\n", __FUNCTION__); ++ } ++ else if(( !read_tuner_id_register(p_state, TDA18272_TUNER_ADDR, TDA18272_CHECK_OFFSET, tuner_id_data, LEN_2_BYTE)) && ++ ( (tuner_id_data[0]==TDA18272_CHECK_VALUE1) && (tuner_id_data[1]==TDA18272_CHECK_VALUE2))) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_TDA18272; ++ ++ deb_info(" -%s : Tda18272 tuner on board...\n", __FUNCTION__); ++ ++ } ++ else if ((!read_tuner_id_register(p_state, FC0013_BASE_ADDRESS , FC0013_CHECK_ADDRESS, tuner_id_data, LEN_1_BYTE)) && ++ (tuner_id_data[0] == FC0013_CHECK_VALUE)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_FC0013; ++ ++ deb_info(" -%s : FC0013 tuner on board...\n", __FUNCTION__); ++ } ++ else if ((!read_tuner_id_register(p_state, R820T_BASE_ADDRESS , R820T_CHECK_ADDRESS, tuner_id_data, LEN_1_BYTE)) && ++ (tuner_id_data[0] == R820T_CHECK_VALUE)) ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_R820T; ++ ++ deb_info(" -%s : R820T tuner on board...\n", __FUNCTION__); ++ } ++ else ++ { ++ p_state->tuner_type = RTL2832_TUNER_TYPE_UNKNOWN; ++ ++ deb_info(" -%s : Unknown tuner on board...\n", __FUNCTION__); ++ goto error; ++ } ++ ++ return 0; ++error: ++ return -1; ++} ++ ++static int ++gpio1_output_enable_direction( ++ struct rtl2832_state* p_state) ++{ ++ int data; ++ // GPD_GPIO1=0, GPIO1 output direction ++ data = 0; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT1,data) ) goto error; ++ ++ // GPOE_GPIO1=1, GPIO1 output enable ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT1,data) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++static int ++gpio6_output_enable_direction( ++ struct rtl2832_state* p_state) ++{ ++ int data; ++ // GPD_GPIO6=0, GPIO6 output direction ++ data = 0; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT6,data) ) goto error; ++ ++ // GPOE_GPIO6=1, GPIO6 output enable ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT6,data) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++static int ++gpio5_output_enable_direction( ++ struct rtl2832_state* p_state) ++{ ++ int data; ++ // GPD_GPIO5=0, GPIO5 output direction ++ data = 0; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT5,data) ) goto error; ++ ++ // GPOE_GPIO5=1, GPIO5 output enable ++ data = 1; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT5,data) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++static int ++check_dvbt_reset_parameters( ++ ++ struct rtl2832_state* p_state, ++ unsigned long frequency, ++#ifdef V4L2_ONLY_DVB_V5 ++ unsigned long bandwidth_hz, ++#else ++ enum fe_bandwidth bandwidth, ++#endif ++ int* reset_needed) ++{ ++ ++ int is_lock; ++ unsigned int diff_ms; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ *reset_needed = 1; //3initialize "reset_needed" ++ ++#ifdef V4L2_ONLY_DVB_V5 ++ if( (p_state->current_frequency == frequency) && (p_state->current_bandwidth_hz == bandwidth_hz) ) ++#else ++ if( (p_state->current_frequency == frequency) && (p_state->current_bandwidth == bandwidth) ) ++#endif ++ { ++ if( p_state->pNim->IsSignalLocked(p_state->pNim, &is_lock) ) goto error; ++ diff_ms = 0; ++ ++ while( !(is_lock == LOCKED || diff_ms > 200) ) ++ { ++ platform_wait(40); ++ diff_ms += 40; ++ if( p_state->pNim->IsSignalLocked(p_state->pNim, &is_lock) ) goto error; ++ } ++ ++ if (is_lock==YES) ++ { ++ *reset_needed = 0; //3 set "reset_needed" = 0 ++ deb_info("%s : The same frequency = %d setting\n", __FUNCTION__, (int)frequency); ++ } ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ ++ *reset_needed = 1; //3 set "reset_needed" = 1 ++ return 1; ++} ++ ++ ++#if UPDATE_FUNC_ENABLE_2832 ++void ++rtl2832_update_functions(struct work_struct *work) ++{ ++ struct rtl2832_state* p_state = container_of( work, struct rtl2832_state, update2832_procedure_work.work); ++ //unsigned long ber_num, ber_dem; ++ //long snr_num = 0; ++ //long snr_dem = 0; ++ //long _snr= 0; ++ ++ if(p_state->pNim == NULL) ++ { ++ //deb_info("%s error\n", __FUNCTION__); ++ goto mutex_error; ++ } ++ ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ if(!p_state->is_frequency_valid) ++ { ++ //deb_info(" %s no need \n", __FUNCTION__); ++ goto advance_exit; ++ } ++ ++ // Update tuner mode ++ deb_info(" +%s run update\n", __FUNCTION__); ++ if( p_state->pNim->UpdateFunction(p_state->pNim)){ ++ deb_info(" --->%s run update fail\n", __FUNCTION__); ++ goto advance_exit; ++ } ++ ++ /* p_state->pNim->UpdateFunction(p_state->pNim); ++ p_state->pNim->GetBer( p_state->pNim , &ber_num , &ber_dem); ++ p_state->pNim->GetSnrDb(p_state->pNim, &snr_num, &snr_dem) ; ++ ++ _snr = snr_num / snr_dem; ++ if( _snr < 0 ) _snr = 0; ++ ++ deb_info("%s : ber = %lu, snr = %lu\n", __FUNCTION__,ber_num,_snr); ++ */ ++ ++advance_exit: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ schedule_delayed_work(&p_state->update2832_procedure_work, UPDATE_PROCEDURE_PERIOD_2832); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ ++ return; ++ ++mutex_error: ++ return; ++ ++} ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++void ++rtl2836_update_function(struct work_struct *work) ++{ ++ struct rtl2832_state* p_state; ++ unsigned long Per1, Per2; ++ long Data1,Data2; ++ unsigned char data; ++ DTMB_DEMOD_MODULE * pDtmbDemod; ++ ++ p_state = container_of(work , struct rtl2832_state , update2836_procedure_work.work); ++ if(p_state->pNim2836 == NULL) ++ { ++ deb_info("%s error\n", __FUNCTION__); ++ goto mutex_error; ++ } ++ pDtmbDemod = p_state->pNim2836->pDemod; ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ if(!p_state->is_frequency_valid) ++ { ++ deb_info(" %s no need \n", __FUNCTION__); ++ goto advance_exit; ++ } ++ ++ if(pDtmbDemod->UpdateFunction(pDtmbDemod)) ++ { ++ deb_info("%s -- UpdateFunction failed\n", __FUNCTION__); ++ } ++ ++ pDtmbDemod->GetPer(pDtmbDemod,&Per1,&Per2); ++ deb_info("%s -- ***GetPer= %d***\n", __FUNCTION__, (int)Per1); ++ ++ pDtmbDemod->GetSnrDb(pDtmbDemod,&Data1,&Data2); ++ deb_info("%s -- ***SNR = %d***\n",__FUNCTION__, (int)(Data1>>2)); ++ ++ read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_6, 0xc0, &data, LEN_1_BYTE); ++ deb_info("%s --***FSM = %d***\n", __FUNCTION__, (data&0x1f)); ++ ++advance_exit: ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ schedule_delayed_work(&p_state->update2836_procedure_work, UPDATE_PROCEDURE_PERIOD_2836); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return; ++ ++mutex_error: ++ return; ++ ++} ++#endif ++ ++static int ++rtl2832_init( ++ struct dvb_frontend* fe) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ //usb_reset_device(p_state->d->udev); ++ ++ if( usb_init_setting(p_state) ) goto error; ++ ++ if( gpio3_out_setting(p_state) ) goto error; //3Set GPIO3 OUT ++ ++ if( demod_ctl1_setting(p_state , 1) ) goto error; //3 DEMOD_CTL1, resume = 1 ++ ++ if (dvb_use_rtl2832u_card_type) ++ { ++ if( set_demod_power(p_state , 1) ) goto error; //3 turn ON demod power ++ } ++ ++ if( suspend_latch_setting(p_state , 1) ) goto error; //3 suspend_latch_en = 0, resume = 1 ++ ++ if( demod_ctl_setting(p_state , 1, 1) ) goto error; //3 DEMOD_CTL, resume =1; ADC on ++ ++ if( set_tuner_power(p_state, 1, 1) ) goto error; //3 turn ON tuner power ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_TUA9001) ++ { ++ if( gpio1_output_enable_direction(p_state) ) goto error; ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 MXL5007T : Set GPIO6 OUTPUT_EN & OUTPUT_DIR & OUTPUT_VAL for YUAN ++ int data; ++ if( gpio6_output_enable_direction(p_state) ) goto error; ++ ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data |= BIT6; ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error; ++ ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ int data; ++ if( gpio5_output_enable_direction(p_state)) goto error; ++ ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data |= BIT5; // set GPIO5 high ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data) ) goto error; ++ data &= ~(BIT5); // set GPIO5 low ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data) ) goto error; ++ } ++ ++ switch(p_state->demod_type) ++ { ++ case RTL2836: ++ { ++ if ( set_demod_2836_power(p_state, 1)) goto error;//32836 on ++ ++ // RTL2832 ADC_I& ADC_Q OFF ++ if( demod_ctl_setting(p_state, 1, 0)) goto error;// ADC off ++ ++ } ++ break; ++ ++ case RTL2840: ++ { ++ if ( set_demod_2840_power(p_state, 1)) goto error;//2840 on ++ ++ // RTL2832 ADC_I& ADC_Q OFF ++ if( demod_ctl_setting(p_state, 1, 0)) goto error;//ADC off ++ } ++ break; ++ } ++ ++ //3 Nim initial ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ { ++ // Nim initialize for 2832 ++ if ( p_state->pNim->Initialize(p_state->pNim) ) goto error; ++ } ++ break; ++ ++ case RTL2836: ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ // Nim initialize for 2836 ++ if ( p_state->pNim2836->Initialize(p_state->pNim2836)) goto error; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0)) goto error; ++ ++ if(dtmb_error_packet_discard) ++ { ++ unsigned char val=0; ++ if(read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x21, &val, LEN_1_BYTE)) goto error; ++ val &= ~(BIT5); ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x21, &val, LEN_1_BYTE)) goto error; ++ ++ if(read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_4, 0x26, &val, LEN_1_BYTE)) goto error; ++ val &= ~(BIT0); ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_4, 0x26, &val, LEN_1_BYTE)) goto error; ++ ++ deb_info(" dtmb discard error packets\n"); ++ } ++ else ++ { ++ deb_info(" dtmb NOT discard error packets\n"); ++ } ++ } ++ break; ++ ++ case RTL2840: ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ // Nim initialize for 2840 ++ if ( p_state->pNim2840->Initialize(p_state->pNim2840)) goto error; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0)) goto error; ++ } ++ break; ++ } ++ ++ //3 RTL2832U AGC Setting, Serial Mode Switch Setting, PIP Setting based on demod_type ++ if(demod_init_setting(p_state)) goto error; ++ ++ p_state->is_initial = 1; ++ //if(p_state->rtl2832_audio_video_mode == RTK_AUDIO) ++ //{ ++ // deb_info("%s: previous mode is audio? \n", __func__); ++ // fm_stream_ctrl(0, p_state->d->adapter); ++ //} ++ p_state->rtl2832_audio_video_mode = RTK_VIDEO; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++#if UPDATE_FUNC_ENABLE_2840 ++ if(p_state->demod_type == RTL2840) ++ schedule_delayed_work(&(p_state->update2840_procedure_work), 0);//3 Initialize update function ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ if(p_state->demod_type == RTL2836) ++ schedule_delayed_work(&(p_state->update2836_procedure_work), 0); ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ if(p_state->demod_type == RTL2832) ++ schedule_delayed_work(&(p_state->update2832_procedure_work), 0);//3 Initialize update function ++#endif ++ ++ return 0; ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ deb_info(" -%s error end\n", __FUNCTION__); ++ ++ p_state->rtl2832_audio_video_mode = RTK_UNKNOWN; ++ ++ return -1; ++} ++ ++ ++static void ++rtl2832_release( ++ struct dvb_frontend* fe) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ MT2266_EXTRA_MODULE* p_mt2266_extra=NULL; ++ MT2063_EXTRA_MODULE* p_mt2063_extra=NULL; ++ ++ TUNER_MODULE* pTuner=NULL; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return; ++ } ++ ++ if( (p_state->is_mt2266_nim_module_built) && (p_state->demod_type==RTL2832) ) ++ { ++ pTuner = p_state->pNim->pTuner; ++ p_mt2266_extra = &(pTuner->Extra.Mt2266); ++ p_mt2266_extra->CloseHandle(pTuner); ++ p_state->is_mt2266_nim_module_built = 0; ++ } ++ ++ if( p_state->is_mt2063_nim_module_built) ++ { ++ ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ pTuner=p_state->pNim->pTuner; ++ break; ++ ++ case RTL2840: ++ pTuner=p_state->pNim2840->pTuner; ++ break; ++ ++ } ++ p_mt2063_extra=&(pTuner->Extra.Mt2063); ++ p_mt2063_extra->CloseHandle(pTuner); ++ p_state->is_mt2063_nim_module_built = 0; ++ ++ } ++ ++ if(p_state->is_initial) ++ { ++#if UPDATE_FUNC_ENABLE_2840 ++ if(p_state->demod_type == RTL2840) ++ { ++ cancel_delayed_work_sync( &(p_state->update2840_procedure_work) );//cancel_rearming_delayed_work ++ flush_scheduled_work(); ++ } ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ if(p_state->demod_type == RTL2836) ++ { ++ cancel_delayed_work_sync( &(p_state->update2836_procedure_work)); ++ flush_scheduled_work(); ++ } ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ if(p_state->demod_type == RTL2832) ++ { ++ cancel_delayed_work_sync( &(p_state->update2832_procedure_work) ); ++ flush_scheduled_work(); ++ } ++#endif ++ p_state->is_initial = 0; ++ } ++ p_state->is_frequency_valid = 0; ++ p_state->rtl2832_audio_video_mode = RTK_UNKNOWN; ++ //IrDA ++ rtl2832u_remote_control_state = RC_NO_SETTING; ++ ++ kfree(p_state); ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return; ++} ++ ++ ++ ++ ++static int ++rtl2832_sleep_mode(struct rtl2832_state* p_state) ++{ ++ int data=0; ++ ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_MAX3543) ++ { ++ //+set MAX3543_CHECK_VALUE to Default value ++ unsigned char i2c_repeater; ++ unsigned char data = MAX3543_CHECK_VALUE; ++ ++ read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ i2c_repeater |= BIT3; ++ write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ ++ write_rtl2832_tuner_register(p_state->d, MAX3543_TUNER_ADDR, MAX3543_CHECK_OFFSET, &data, LEN_1_BYTE); ++ ++ read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ i2c_repeater &= (~BIT3); ++ write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 1, 1, &i2c_repeater, 1 ); ++ //-set MAX3543_CHECK_VALUE to Default value ++ } ++ ++ ++ if( p_state->is_initial ) ++ { ++ ++#if UPDATE_FUNC_ENABLE_2840 ++ if(p_state->demod_type == RTL2840) ++ { ++ cancel_delayed_work_sync( &(p_state->update2840_procedure_work)); ++ flush_scheduled_work(); ++ } ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ if(p_state->demod_type == RTL2836) ++ { ++ cancel_delayed_work_sync( &(p_state->update2836_procedure_work)); ++ flush_scheduled_work(); ++ } ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ if(p_state->demod_type == RTL2832) ++ { ++ cancel_delayed_work_sync( &(p_state->update2832_procedure_work)); ++ flush_scheduled_work(); ++ } ++#endif ++ p_state->is_initial = 0; ++ } ++ p_state->is_frequency_valid = 0; ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++#if 0 ++ //2 For debug ++ /* for( page_no = 0; page_no < 3; page_no++ )//2832 ++ { ++ pDemod->SetRegPage(pDemod, page_no); ++ for( addr_no = 0; addr_no < 256; addr_no++ ) ++ { ++ pDemod->GetRegBytes(pDemod, addr_no, ®_value, 1); ++ printk("0x%x, 0x%x, 0x%x\n", page_no, addr_no, reg_value); ++ } ++ }*/ ++ for( page_no = 0; page_no < 10; page_no++ )//2836 ++ { ++ pDemod2836->SetRegPage(pDemod2836, page_no); ++ for( addr_no = 0; addr_no < 256; addr_no++ ) ++ { ++ pDemod2836->GetRegBytes(pDemod2836, addr_no, ®_value, 1); ++ printk("0x%x, 0x%x, 0x%x\n", page_no, addr_no, reg_value); ++ } ++ } ++#endif ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 MXL5007T : Set GPIO6 OUTPUT_VAL OFF for YUAN ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data &= (~BIT6); ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL,data) ) goto error; ++ ++ } ++ ++ ++ if( demod_ctl1_setting(p_state , 0) ) goto error; //3 DEMOD_CTL1, resume = 0 ++ ++ if( set_tuner_power(p_state, 1, 0) ) goto error; //3 turn OFF tuner power ++ ++ if( demod_ctl_setting(p_state , 0, 0) ) goto error; //3 DEMOD_CTL, resume =0 ++ ++ if (p_state->demod_type != RTL2832){ ++ set_demod_2836_power(p_state, 0); //3 RTL2836 power OFF ++ deb_info(" ->%s::RTL2836 power OFF\n", __FUNCTION__); ++ set_demod_2840_power(p_state, 0); //3 RTL2840 power OFF ++ deb_info(" ->%s ::RTL2840 power OFF\n", __FUNCTION__); ++ } ++ //2 for H/W reason ++ //if( suspend_latch_setting(p_state , 0) ) goto error; //3 suspend_latch_en = 1, resume = 0 ++ if (dvb_use_rtl2832u_card_type) ++ { ++ deb_info(" -%s ::mini card mode gpio0 set high ,demod power off\n", __FUNCTION__); ++ if( set_demod_power(p_state , 0) ) goto error; //3 turn OFF demod power ++ } ++ ++#ifndef NO_FE_IOCTL_OVERRIDE ++ if(p_state->rtl2832_audio_video_mode == RTK_AUDIO) ++ { ++ fm_stream_ctrl(0, p_state->d->adapter); ++ } ++#endif ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ deb_info(" -%s fail\n", __FUNCTION__); ++ return 1; ++ ++ ++} ++static int ++rtl2832_sleep( ++ struct dvb_frontend* fe) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ ++ return rtl2832_sleep_mode(p_state); ++} ++ ++ ++ ++#ifdef V4L2_ONLY_DVB_V5 ++static int ++rtl2840_set_parameters( ++ struct dvb_frontend* fe) ++{ ++ struct dtv_frontend_properties *param = &fe->dtv_property_cache; ++ struct rtl2832_state *p_state = fe->demodulator_priv; ++ unsigned long frequency = param->frequency; ++ ++ DVBT_DEMOD_MODULE *pDemod2832; ++ int QamMode; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if(p_state->demod_type == RTL2840 && p_state->pNim2840 == NULL ) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ ++ return -1; ++ } ++ ++ ++ deb_info(" +%s Freq=%lu , Symbol rate=%u, QAM=%u\n", __FUNCTION__, frequency, param->symbol_rate, param->modulation); ++ ++ pDemod2832 = p_state->pNim->pDemod; ++ ++ switch(param->modulation) ++ { ++ case QPSK : QamMode = QAM_QAM_4; break; ++ case QAM_16 : QamMode = QAM_QAM_16; break; ++ case QAM_32 : QamMode = QAM_QAM_32; break; ++ case QAM_64 : QamMode = QAM_QAM_64; break; ++ case QAM_128 : QamMode = QAM_QAM_128; break; ++ case QAM_256 : QamMode = QAM_QAM_256; break; ++ ++ case QAM_AUTO : ++ default: ++ deb_info(" XXX %s : unknown QAM \n", __FUNCTION__); ++ goto mutex_error; ++ break; ++ ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ p_state->pNim2840->SetParameters(p_state->pNim2840, frequency, QamMode, param->symbol_rate, QAM_ALPHA_0P15); ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x0)) goto error; ++ ++ if(pDemod2832->SoftwareReset(pDemod2832))//2832 swreset ++ goto error; ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ ++ deb_info(" -XXX %s \n", __FUNCTION__); ++ ++ return 1; ++ ++} ++#else ++static int ++rtl2840_set_parameters( ++ struct dvb_frontend* fe, ++ struct dvb_frontend_parameters* param) ++{ ++ ++ struct rtl2832_state *p_state = fe->demodulator_priv; ++ struct dvb_qam_parameters *p_qam_param= ¶m->u.qam; ++ unsigned long frequency = param->frequency; ++ ++ DVBT_DEMOD_MODULE *pDemod2832; ++ int QamMode; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ if(p_state->demod_type == RTL2840 && p_state->pNim2840 == NULL ) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ ++ return -1; ++ } ++ ++ ++ deb_info(" +%s Freq=%lu , Symbol rate=%u, QAM=%u\n", __FUNCTION__, frequency, p_qam_param->symbol_rate, p_qam_param->modulation); ++ ++ pDemod2832 = p_state->pNim->pDemod; ++ ++ switch(p_qam_param->modulation) ++ { ++ case QPSK : QamMode = QAM_QAM_4; break; ++ case QAM_16 : QamMode = QAM_QAM_16; break; ++ case QAM_32 : QamMode = QAM_QAM_32; break; ++ case QAM_64 : QamMode = QAM_QAM_64; break; ++ case QAM_128 : QamMode = QAM_QAM_128; break; ++ case QAM_256 : QamMode = QAM_QAM_256; break; ++ ++ case QAM_AUTO : ++ default: ++ deb_info(" XXX %s : unknown QAM \n", __FUNCTION__); ++ goto mutex_error; ++ break; ++ ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ p_state->pNim2840->SetParameters(p_state->pNim2840, frequency, QamMode, p_qam_param->symbol_rate, QAM_ALPHA_0P15); ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x0)) goto error; ++ ++ if(pDemod2832->SoftwareReset(pDemod2832))//2832 swreset ++ goto error; ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ ++ deb_info(" -XXX %s \n", __FUNCTION__); ++ ++ return 1; ++ ++} ++#endif ++ ++ ++ ++#ifdef V4L2_ONLY_DVB_V5 ++static int ++rtl2832_set_parameters( ++ struct dvb_frontend* fe) ++{ ++ struct dtv_frontend_properties *param = &fe->dtv_property_cache; ++ struct rtl2832_state *p_state = fe->demodulator_priv; ++ ++ unsigned long frequency = param->frequency; ++ int bandwidth_mode; ++ int is_signal_present; ++ int reset_needed; ++ unsigned char data; ++ int int_data; ++ ++ ++ DTMB_DEMOD_MODULE * pDemod2836; ++ DVBT_DEMOD_MODULE * pDemod2832; ++ ++ ++ ++ if( p_state->pNim == NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if(p_state->demod_type == RTL2836 && p_state->pNim2836 == NULL ) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s frequency = %lu , bandwidth = %u\n", __FUNCTION__, frequency , param->bandwidth_hz); ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if ( check_dvbt_reset_parameters( p_state , frequency , param->bandwidth_hz, &reset_needed) ) goto error; ++ ++ if( reset_needed == 0 ) ++ { ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ return 0; ++ } ++ ++ switch (param->bandwidth_hz) ++ { ++ case 6000000: ++ bandwidth_mode = DVBT_BANDWIDTH_6MHZ; ++ break; ++ ++ case 7000000: ++ bandwidth_mode = DVBT_BANDWIDTH_7MHZ; ++ break; ++ ++ case 8000000: ++ default: ++ bandwidth_mode = DVBT_BANDWIDTH_8MHZ; ++ break; ++ } ++ ++ //add by Dean ++ if (p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 ) ++ { ++ ++ if( gpio6_output_enable_direction(p_state) ) goto error; ++ ++ ++ if (frequency > 300000000) ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &int_data); ++ int_data |= BIT6; // set GPIO6 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, int_data); ++ deb_info(" %s : Tuner :FC0012 V-band (GPIO6 high)\n", __FUNCTION__); ++ } ++ else ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &int_data); ++ int_data &= (~BIT6); // set GPIO6 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, int_data); ++ deb_info(" %s : Tuner :FC0012 U-band (GPIO6 low)\n", __FUNCTION__); ++ ++ } ++ } ++ ++ ++ ++ ++ ++ if ( p_state->pNim->SetParameters( p_state->pNim, frequency , bandwidth_mode ) ) goto error; ++ ++ if ( p_state->pNim->IsSignalPresent( p_state->pNim, &is_signal_present) ) goto error; ++ deb_info(" %s : ****** Signal Present = %d ******\n", __FUNCTION__, is_signal_present); ++ ++ ++ ++ ++ p_state->is_frequency_valid = 1; ++ ++ ++ } ++ else if(p_state->demod_type == RTL2836) ++ { ++ pDemod2836 = p_state->pNim2836->pDemod; ++ pDemod2832 = p_state->pNim->pDemod; ++ ++ //if ( check_dtmb_reset_parameters( p_state , frequency , &reset_needed) ) goto error; ++ //if( reset_needed == 0 ) ++ //{ ++ // mutex_unlock(&p_state->i2c_repeater_mutex); ++ // return 0; ++ //} ++ ++ deb_info("%s: RTL2836 Hold Stage=9\n",__FUNCTION__); ++ if(read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &data, LEN_1_BYTE)) goto error; ++ data &=(~BIT_0_MASK); //reset Reg_present ++ data &=(~BIT_1_MASK); //reset Reg_lock ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &data, LEN_1_BYTE)) goto error; ++ ++ //3 + RTL2836 Hold Stage=9 ++ data = 0x29; ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0x4d, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0xA5; ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0x4e, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x94; ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0x4f, &data, LEN_1_BYTE)) goto error; ++ //3 -RTL2836 Hold Stage=9 ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ if ( p_state->pNim2836->SetParameters( p_state->pNim2836, frequency)) goto error; //no bandwidth setting ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x0)) goto error; ++ ++ if(pDemod2832->SoftwareReset(pDemod2832))//2832 swreset ++ goto error; ++ ++ p_state->is_frequency_valid = 1; ++ if( rtl2836_scan_procedure(p_state)) goto error; ++ } ++ ++ ++//#if(UPDATE_FUNC_ENABLE_2832 == 0) ++ //3 FC0012/E4000 update begin -- ++ if(p_state->demod_type == RTL2832 && (p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 ++ || p_state->tuner_type == RTL2832_TUNER_TYPE_E4000 ++ || p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013)) ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) //fc0013 ++ { ++ if(rtl2832_fc0013_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ ++ deb_info("%s : fc0012/e4000 update first\n", __FUNCTION__); ++ ++ msleep(50); ++ ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner LNA gain with RSSI. ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if (p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) //fc0013 ++ { ++ if(rtl2832_fc0013_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ deb_info("%s : fc0012/e4000 update 2nd\n", __FUNCTION__); ++ } ++ //3 FC0012/E4000 update end -- ++ ++//#endif ++ ++ p_state->current_frequency = frequency; ++ p_state->current_bandwidth_hz = param->bandwidth_hz; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ p_state->current_frequency = 0; ++ p_state->current_bandwidth_hz = 0; ++ p_state->is_frequency_valid = 0; ++ deb_info(" -%s error end\n", __FUNCTION__); ++ ++ return -1; ++ ++} ++ ++static int ++rtl2832_set_parameters_fm( ++ struct dvb_frontend* fe) ++{ ++ struct dtv_frontend_properties *param = &fe->dtv_property_cache; ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ unsigned long frequency = param->frequency; ++ int bandwidth_mode; ++ int int_data; ++ ++ //DTMB_DEMOD_MODULE * pDemod2836; ++ //DVBT_DEMOD_MODULE * pDemod2832; ++ ++ if( p_state->pNim == NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ /* if(p_state->demod_type == RTL2836 && p_state->pNim2836 == NULL ) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ return -1; ++ } */ ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s frequency = %lu , bandwidth = %u\n", __FUNCTION__, frequency , param->bandwidth_hz); ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ bandwidth_mode = DVBT_BANDWIDTH_6MHZ; ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ if( gpio6_output_enable_direction(p_state) ) goto error; ++ ++ if (frequency > 300000000) ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &int_data); ++ int_data |= BIT6; // set GPIO6 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, int_data); ++ deb_info(" %s : Tuner :FC0012 V-band (GPIO6 high)\n", __FUNCTION__); ++ } ++ else ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &int_data); ++ int_data &= (~BIT6); // set GPIO6 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, int_data); ++ deb_info(" %s : Tuner :FC0012 U-band (GPIO6 low)\n", __FUNCTION__); ++ ++ } ++ ++ if(rtl2832_fc0012_SetParameters_fm( p_state->pNim, frequency , bandwidth_mode )) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ if(rtl2832_mxl5007t_SetParameters_fm(p_state->pNim, frequency , bandwidth_mode )) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ { ++ if(rtl2832_e4000_SetParameters_fm( p_state->pNim, frequency , bandwidth_mode )) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) ++ { ++ if(rtl2832_fc0013_SetParameters_fm( p_state->pNim, frequency , bandwidth_mode )) ++ goto error; ++ } ++ ++ p_state->is_frequency_valid = 1; ++ ++ ++ } ++ /*else if(p_state->demod_type == RTL2836) ++ { ++ }*/ ++ ++ ++//#if(UPDATE_FUNC_ENABLE_2832 == 0) ++ //3 FC0012/E4000 update begin -- ++ if(p_state->demod_type == RTL2832 && (p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 || p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)) ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner LNA gain with RSSI. ++ // if( p_state->pNim->UpdateFunction(p_state->pNim)) ++ // goto error; ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if (p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) //fc0013 ++ { ++ if(rtl2832_fc0013_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ ++ deb_info("%s : fc0012/e4000 update first\n", __FUNCTION__); ++ ++ msleep(50); ++ ++ // if( p_state->pNim->UpdateFunction(p_state->pNim)) goto error; ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner LNA gain with RSSI. ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if (p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) //fc0013 ++ { ++ if(rtl2832_fc0013_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ deb_info("%s : fc0012/e4000 update 2nd\n", __FUNCTION__); ++ } ++ //3 FC0012/E4000 update end -- ++ ++//#endif ++ ++ //p_state->current_frequency = frequency; ++ //p_state->current_bandwidth = p_ofdm_param->bandwidth; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ //p_state->current_frequency = 0; ++ //p_state->current_bandwidth = -1; ++ p_state->is_frequency_valid = 0; ++ deb_info(" -%s error end\n", __FUNCTION__); ++ ++ return -1; ++ ++} ++ ++static int ++rtl2832_get_parameters( ++ struct dvb_frontend* fe) ++{ ++ struct dtv_frontend_properties *param = &fe->dtv_property_cache; ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ int pConstellation; ++ int pHierarchy; ++ int pCodeRateLp; ++ int pCodeRateHp; ++ int pGuardInterval; ++ int pFftMode; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) ++ return -1; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ p_state->pNim->GetTpsInfo(p_state->pNim, &pConstellation, &pHierarchy, &pCodeRateLp, &pCodeRateHp, &pGuardInterval, &pFftMode); ++ ++ switch (pConstellation) { ++ case DVBT_CONSTELLATION_QPSK: ++ param->modulation = QPSK; ++ break; ++ case DVBT_CONSTELLATION_16QAM: ++ param->modulation = QAM_16; ++ break; ++ case DVBT_CONSTELLATION_64QAM: ++ param->modulation = QAM_64; ++ break; ++ } ++ ++ switch (pHierarchy) { ++ case DVBT_HIERARCHY_NONE: ++ param->hierarchy = HIERARCHY_NONE; ++ break; ++ case DVBT_HIERARCHY_ALPHA_1: ++ param->hierarchy = HIERARCHY_1; ++ break; ++ case DVBT_HIERARCHY_ALPHA_2: ++ param->hierarchy = HIERARCHY_2; ++ break; ++ case DVBT_HIERARCHY_ALPHA_4: ++ param->hierarchy = HIERARCHY_4; ++ break; ++ } ++ ++ switch (pCodeRateLp) { ++ case DVBT_CODE_RATE_1_OVER_2: ++ param->code_rate_LP = FEC_1_2; ++ break; ++ case DVBT_CODE_RATE_2_OVER_3: ++ param->code_rate_LP = FEC_2_3; ++ break; ++ case DVBT_CODE_RATE_3_OVER_4: ++ param->code_rate_LP = FEC_3_4; ++ break; ++ case DVBT_CODE_RATE_5_OVER_6: ++ param->code_rate_LP = FEC_5_6; ++ break; ++ case DVBT_CODE_RATE_7_OVER_8: ++ param->code_rate_LP = FEC_7_8; ++ break; ++ } ++ ++ switch (pCodeRateHp) { ++ case DVBT_CODE_RATE_1_OVER_2: ++ param->code_rate_HP = FEC_1_2; ++ break; ++ case DVBT_CODE_RATE_2_OVER_3: ++ param->code_rate_HP = FEC_2_3; ++ break; ++ case DVBT_CODE_RATE_3_OVER_4: ++ param->code_rate_HP = FEC_3_4; ++ break; ++ case DVBT_CODE_RATE_5_OVER_6: ++ param->code_rate_HP = FEC_5_6; ++ break; ++ case DVBT_CODE_RATE_7_OVER_8: ++ param->code_rate_HP = FEC_7_8; ++ break; ++ } ++ ++ switch (pGuardInterval) { ++ case DVBT_GUARD_INTERVAL_1_OVER_4: ++ param->guard_interval = GUARD_INTERVAL_1_4; ++ break; ++ case DVBT_GUARD_INTERVAL_1_OVER_8: ++ param->guard_interval = GUARD_INTERVAL_1_8; ++ break; ++ case DVBT_GUARD_INTERVAL_1_OVER_16: ++ param->guard_interval = GUARD_INTERVAL_1_16; ++ break; ++ case DVBT_GUARD_INTERVAL_1_OVER_32: ++ param->guard_interval = GUARD_INTERVAL_1_32; ++ break; ++ } ++ ++ switch (pFftMode) { ++ case DVBT_FFT_MODE_2K: ++ param->transmission_mode = TRANSMISSION_MODE_2K; ++ break; ++ case DVBT_FFT_MODE_8K: ++ param->transmission_mode = TRANSMISSION_MODE_8K; ++ break; ++ } ++ } ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++} ++ ++#else ++static int ++rtl2832_set_parameters( ++ struct dvb_frontend* fe, ++ struct dvb_frontend_parameters* param) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ struct dvb_ofdm_parameters* p_ofdm_param= ¶m->u.ofdm; ++ ++ unsigned long frequency = param->frequency; ++ int bandwidth_mode; ++ int is_signal_present; ++ int reset_needed; ++ unsigned char data; ++ int int_data; ++ ++ ++ //TUNER_MODULE * pTuner; ++ DTMB_DEMOD_MODULE * pDemod2836; ++ DVBT_DEMOD_MODULE * pDemod2832; ++ ++ ++ ++ if( p_state->pNim == NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if(p_state->demod_type == RTL2836 && p_state->pNim2836 == NULL ) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s frequency = %lu , bandwidth = %u\n", __FUNCTION__, frequency ,p_ofdm_param->bandwidth); ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if ( check_dvbt_reset_parameters( p_state , frequency , p_ofdm_param->bandwidth, &reset_needed) ) goto error; ++ ++ if( reset_needed == 0 ) ++ { ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ return 0; ++ } ++ ++ switch (p_ofdm_param->bandwidth) ++ { ++ case BANDWIDTH_6_MHZ: ++ bandwidth_mode = DVBT_BANDWIDTH_6MHZ; ++ break; ++ ++ case BANDWIDTH_7_MHZ: ++ bandwidth_mode = DVBT_BANDWIDTH_7MHZ; ++ break; ++ ++ case BANDWIDTH_8_MHZ: ++ default: ++ bandwidth_mode = DVBT_BANDWIDTH_8MHZ; ++ break; ++ } ++ ++ //add by Dean ++ if (p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 ) ++ { ++ ++ if( gpio6_output_enable_direction(p_state) ) goto error; ++ ++ ++ if (frequency > 300000000) ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &int_data); ++ int_data |= BIT6; // set GPIO6 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, int_data); ++ deb_info(" %s : Tuner :FC0012 V-band (GPIO6 high)\n", __FUNCTION__); ++ } ++ else ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &int_data); ++ int_data &= (~BIT6); // set GPIO6 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, int_data); ++ deb_info(" %s : Tuner :FC0012 U-band (GPIO6 low)\n", __FUNCTION__); ++ ++ } ++ } ++ ++ ++ ++ ++ ++ if ( p_state->pNim->SetParameters( p_state->pNim, frequency , bandwidth_mode ) ) goto error; ++ ++ if ( p_state->pNim->IsSignalPresent( p_state->pNim, &is_signal_present) ) goto error; ++ deb_info(" %s : ****** Signal Present = %d ******\n", __FUNCTION__, is_signal_present); ++ ++ ++ ++ ++ p_state->is_frequency_valid = 1; ++ ++ ++ } ++ else if(p_state->demod_type == RTL2836) ++ { ++ pDemod2836 = p_state->pNim2836->pDemod; ++ pDemod2832 = p_state->pNim->pDemod; ++ ++ //if ( check_dtmb_reset_parameters( p_state , frequency , &reset_needed) ) goto error; ++ //if( reset_needed == 0 ) ++ //{ ++ // mutex_unlock(&p_state->i2c_repeater_mutex); ++ // return 0; ++ //} ++ ++ deb_info(("%s: RTL2836 Hold Stage=9\n"),__FUNCTION__); ++ if(read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &data, LEN_1_BYTE)) goto error; ++ data &=(~BIT_0_MASK); //reset Reg_present ++ data &=(~BIT_1_MASK); //reset Reg_lock ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &data, LEN_1_BYTE)) goto error; ++ ++ //3 + RTL2836 Hold Stage=9 ++ data = 0x29; ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0x4d, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0xA5; ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0x4e, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x94; ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0x4f, &data, LEN_1_BYTE)) goto error; ++ //3 -RTL2836 Hold Stage=9 ++ ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x1) ) goto error; ++ ++ if ( p_state->pNim2836->SetParameters( p_state->pNim2836, frequency)) goto error; //no bandwidth setting ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod2832->SetRegBitsWithPage(pDemod2832, DVBT_IIC_REPEAT, 0x0)) goto error; ++ ++ if(pDemod2832->SoftwareReset(pDemod2832))//2832 swreset ++ goto error; ++ ++ p_state->is_frequency_valid = 1; ++ if( rtl2836_scan_procedure(p_state)) goto error; ++ } ++ ++ ++//#if(UPDATE_FUNC_ENABLE_2832 == 0) ++ //3 FC0012/E4000 update begin -- ++ if(p_state->demod_type == RTL2832 && (p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 ++ || p_state->tuner_type == RTL2832_TUNER_TYPE_E4000 ++ || p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013)) ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) //fc0013 ++ { ++ if(rtl2832_fc0013_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ ++ deb_info("%s : fc0012/e4000 update first\n", __FUNCTION__); ++ ++ msleep(50); ++ ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner LNA gain with RSSI. ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if (p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) //fc0013 ++ { ++ if(rtl2832_fc0013_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ deb_info("%s : fc0012/e4000 update 2nd\n", __FUNCTION__); ++ } ++ //3 FC0012/E4000 update end -- ++ ++//#endif ++ ++ //p_state->current_frequency = frequency; ++ //p_state->current_bandwidth = p_ofdm_param->bandwidth; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ //p_state->current_frequency = 0; ++ //p_state->current_bandwidth = -1; ++ p_state->is_frequency_valid = 0; ++ deb_info(" -%s error end\n", __FUNCTION__); ++ ++ return -1; ++ ++} ++ ++static int ++rtl2832_set_parameters_fm( ++ struct dvb_frontend* fe, ++ struct dvb_frontend_parameters* param) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ struct dvb_ofdm_parameters* p_ofdm_param= ¶m->u.ofdm; ++ unsigned long frequency = param->frequency; ++ int bandwidth_mode; ++ int int_data; ++ ++ //DTMB_DEMOD_MODULE * pDemod2836; ++ //DVBT_DEMOD_MODULE * pDemod2832; ++ ++ if( p_state->pNim == NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ /* if(p_state->demod_type == RTL2836 && p_state->pNim2836 == NULL ) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ return -1; ++ } */ ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ deb_info(" +%s frequency = %lu , bandwidth = %u\n", __FUNCTION__, frequency ,p_ofdm_param->bandwidth); ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ bandwidth_mode = DVBT_BANDWIDTH_6MHZ; ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ if( gpio6_output_enable_direction(p_state) ) goto error; ++ ++ if (frequency > 300000000) ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &int_data); ++ int_data |= BIT6; // set GPIO6 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, int_data); ++ deb_info(" %s : Tuner :FC0012 V-band (GPIO6 high)\n", __FUNCTION__); ++ } ++ else ++ { ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &int_data); ++ int_data &= (~BIT6); // set GPIO6 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, int_data); ++ deb_info(" %s : Tuner :FC0012 U-band (GPIO6 low)\n", __FUNCTION__); ++ ++ } ++ ++ if(rtl2832_fc0012_SetParameters_fm( p_state->pNim, frequency , bandwidth_mode )) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ if(rtl2832_mxl5007t_SetParameters_fm(p_state->pNim, frequency , bandwidth_mode )) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ { ++ if(rtl2832_e4000_SetParameters_fm( p_state->pNim, frequency , bandwidth_mode )) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) ++ { ++ if(rtl2832_fc0013_SetParameters_fm( p_state->pNim, frequency , bandwidth_mode )) ++ goto error; ++ } ++ ++ p_state->is_frequency_valid = 1; ++ ++ ++ } ++ /*else if(p_state->demod_type == RTL2836) ++ { ++ }*/ ++ ++ ++//#if(UPDATE_FUNC_ENABLE_2832 == 0) ++ //3 FC0012/E4000 update begin -- ++ if(p_state->demod_type == RTL2832 && (p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 || p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)) ++ { ++ // Enable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner LNA gain with RSSI. ++ // if( p_state->pNim->UpdateFunction(p_state->pNim)) ++ // goto error; ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if (p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) //fc0013 ++ { ++ if(rtl2832_fc0013_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ ++ deb_info("%s : fc0012/e4000 update first\n", __FUNCTION__); ++ ++ msleep(50); ++ ++ // if( p_state->pNim->UpdateFunction(p_state->pNim)) goto error; ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ // Update tuner LNA gain with RSSI. ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012)//fc0012 ++ { ++ if(rtl2832_fc0012_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if (p_state->tuner_type == RTL2832_TUNER_TYPE_E4000)//e4000 ++ { ++ if(rtl2832_e4000_UpdateTunerMode(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) //fc0013 ++ { ++ if(rtl2832_fc0013_UpdateTunerLnaGainWithRssi(p_state->pNim) != FUNCTION_SUCCESS) ++ goto error; ++ } ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(p_state->pNim->pDemod->SetRegBitsWithPage(p_state->pNim->pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ deb_info("%s : fc0012/e4000 update 2nd\n", __FUNCTION__); ++ } ++ //3 FC0012/E4000 update end -- ++ ++//#endif ++ ++ //p_state->current_frequency = frequency; ++ //p_state->current_bandwidth = p_ofdm_param->bandwidth; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ //p_state->current_frequency = 0; ++ //p_state->current_bandwidth = -1; ++ p_state->is_frequency_valid = 0; ++ deb_info(" -%s error end\n", __FUNCTION__); ++ ++ return -1; ++ ++} ++ ++ ++ ++static int ++rtl2832_get_parameters( ++ struct dvb_frontend* fe, ++ struct dvb_frontend_parameters* param) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ struct dvb_ofdm_parameters* p_ofdm_param = ¶m->u.ofdm; ++ int pConstellation; ++ int pHierarchy; ++ int pCodeRateLp; ++ int pCodeRateHp; ++ int pGuardInterval; ++ int pFftMode; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) ++ return -1; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ p_state->pNim->GetTpsInfo(p_state->pNim, &pConstellation, &pHierarchy, &pCodeRateLp, &pCodeRateHp, &pGuardInterval, &pFftMode); ++ ++ switch (pConstellation) { ++ case DVBT_CONSTELLATION_QPSK: ++ p_ofdm_param->constellation = QPSK; ++ break; ++ case DVBT_CONSTELLATION_16QAM: ++ p_ofdm_param->constellation = QAM_16; ++ break; ++ case DVBT_CONSTELLATION_64QAM: ++ p_ofdm_param->constellation = QAM_64; ++ break; ++ } ++ ++ switch (pHierarchy) { ++ case DVBT_HIERARCHY_NONE: ++ p_ofdm_param->hierarchy_information = HIERARCHY_NONE; ++ break; ++ case DVBT_HIERARCHY_ALPHA_1: ++ p_ofdm_param->hierarchy_information = HIERARCHY_1; ++ break; ++ case DVBT_HIERARCHY_ALPHA_2: ++ p_ofdm_param->hierarchy_information = HIERARCHY_2; ++ break; ++ case DVBT_HIERARCHY_ALPHA_4: ++ p_ofdm_param->hierarchy_information = HIERARCHY_4; ++ break; ++ } ++ ++ switch (pCodeRateLp) { ++ case DVBT_CODE_RATE_1_OVER_2: ++ p_ofdm_param->code_rate_LP = FEC_1_2; ++ break; ++ case DVBT_CODE_RATE_2_OVER_3: ++ p_ofdm_param->code_rate_LP = FEC_2_3; ++ break; ++ case DVBT_CODE_RATE_3_OVER_4: ++ p_ofdm_param->code_rate_LP = FEC_3_4; ++ break; ++ case DVBT_CODE_RATE_5_OVER_6: ++ p_ofdm_param->code_rate_LP = FEC_5_6; ++ break; ++ case DVBT_CODE_RATE_7_OVER_8: ++ p_ofdm_param->code_rate_LP = FEC_7_8; ++ break; ++ } ++ ++ switch (pCodeRateHp) { ++ case DVBT_CODE_RATE_1_OVER_2: ++ p_ofdm_param->code_rate_HP = FEC_1_2; ++ break; ++ case DVBT_CODE_RATE_2_OVER_3: ++ p_ofdm_param->code_rate_HP = FEC_2_3; ++ break; ++ case DVBT_CODE_RATE_3_OVER_4: ++ p_ofdm_param->code_rate_HP = FEC_3_4; ++ break; ++ case DVBT_CODE_RATE_5_OVER_6: ++ p_ofdm_param->code_rate_HP = FEC_5_6; ++ break; ++ case DVBT_CODE_RATE_7_OVER_8: ++ p_ofdm_param->code_rate_HP = FEC_7_8; ++ break; ++ } ++ ++ switch (pGuardInterval) { ++ case DVBT_GUARD_INTERVAL_1_OVER_4: ++ p_ofdm_param->guard_interval = GUARD_INTERVAL_1_4; ++ break; ++ case DVBT_GUARD_INTERVAL_1_OVER_8: ++ p_ofdm_param->guard_interval = GUARD_INTERVAL_1_8; ++ break; ++ case DVBT_GUARD_INTERVAL_1_OVER_16: ++ p_ofdm_param->guard_interval = GUARD_INTERVAL_1_16; ++ break; ++ case DVBT_GUARD_INTERVAL_1_OVER_32: ++ p_ofdm_param->guard_interval = GUARD_INTERVAL_1_32; ++ break; ++ } ++ ++ switch (pFftMode) { ++ case DVBT_FFT_MODE_2K: ++ p_ofdm_param->transmission_mode = TRANSMISSION_MODE_2K; ++ break; ++ case DVBT_FFT_MODE_8K: ++ p_ofdm_param->transmission_mode = TRANSMISSION_MODE_8K; ++ break; ++ } ++ } ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++} ++#endif ++ ++static int ++rtl2832_read_status( ++ struct dvb_frontend* fe, ++ fe_status_t* status) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ int is_lock; ++ unsigned long ber_num, ber_dem; ++ long snr_num, snr_dem, snr; ++ ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ *status = 0; //3initialize "status" ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ ++ if( p_state->pNim->GetBer( p_state->pNim , &ber_num , &ber_dem) ) goto error; ++ ++ if (p_state->pNim->GetSnrDb(p_state->pNim, &snr_num, &snr_dem) ) goto error; ++ ++ if( p_state->pNim->IsSignalLocked(p_state->pNim, &is_lock) ) goto error; ++ ++ if( is_lock==YES ) *status|= (FE_HAS_CARRIER| FE_HAS_VITERBI| FE_HAS_LOCK| FE_HAS_SYNC| FE_HAS_SIGNAL); ++ ++ snr = snr_num/snr_dem; ++ ++ deb_info("%s :******RTL2832 Signal Lock=%d******\n", __FUNCTION__, is_lock); ++ deb_info("%s : ber_num = %d\n", __FUNCTION__, (unsigned int)ber_num); ++ deb_info("%s : snr = %d \n", __FUNCTION__, (int)snr); ++ } ++ else if(p_state->demod_type == RTL2836)//3Need Change ? ++ { ++ unsigned char val; ++ ++ if( p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) ++ goto error; ++ ++ if(val & BIT_1_MASK) is_lock = YES; ++ else is_lock = NO; ++ ++ //if(p_state->pNim2836->pDemod->IsSignalLocked(p_state->pNim2836->pDemod, &is_lock)) ++ // goto error; ++ ++ if( is_lock==YES ) *status|= (FE_HAS_CARRIER| FE_HAS_VITERBI| FE_HAS_LOCK| FE_HAS_SYNC| FE_HAS_SIGNAL); ++ ++ deb_info("%s :******RTL2836 Signal Lock=%d******\n", __FUNCTION__, is_lock); ++ } ++ else if(p_state->demod_type == RTL2840) ++ { ++ ++ if( p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(p_state->pNim2840->IsSignalLocked(p_state->pNim2840, &is_lock) != FUNCTION_SUCCESS) goto error; ++ ++ if( is_lock==YES ) *status|= (FE_HAS_CARRIER| FE_HAS_VITERBI| FE_HAS_LOCK| FE_HAS_SYNC| FE_HAS_SIGNAL); ++ ++ deb_info("%s :******RTL2840 Signal Lock=%d******\n", __FUNCTION__, is_lock); ++ ++ } ++ ++ ++#if(UPDATE_FUNC_ENABLE_2832 == 0) ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012 || ++ p_state->tuner_type == RTL2832_TUNER_TYPE_E4000 || ++ p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013 ) ++ { ++ // Update tuner LNA gain with RSSI. ++ if( p_state->pNim->UpdateFunction(p_state->pNim)) ++ goto error; ++ }//3 ++ } ++#endif ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++ ++ ++static int ++rtl2832_read_ber( ++ struct dvb_frontend* fe, ++ u32* ber) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ unsigned long ber_num, ber_dem; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if( p_state->pNim->GetBer( p_state->pNim , &ber_num , &ber_dem) ) ++ { ++ *ber = 19616; ++ goto error; ++ } ++ *ber = ber_num; ++ deb_info(" %s : ber = 0x%x \n", __FUNCTION__, *ber); ++ } ++ else if(p_state->demod_type == RTL2836)//read PER ++ { ++ unsigned long per1, per2; ++ if( p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if( p_state->pNim2836->pDemod->GetPer(p_state->pNim2836->pDemod, &per1, &per2)) ++ { ++ *ber = 19616; ++ goto error; ++ } ++ *ber = per1; ++ deb_info(" %s : RTL2836 per = 0x%x \n", __FUNCTION__, *ber); ++ } ++ else if (p_state->demod_type == RTL2840) ++ { ++ unsigned long per1, per2, ber1, ber2; ++ ++ if( p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ if( p_state->pNim2840->GetErrorRate(p_state->pNim2840, 5, 1000, &ber1, &ber2, &per1, &per2)) ++ { ++ *ber = 19616; ++ goto error; ++ } ++ ++ *ber = ber1; ++ deb_info(" %s : RTL2840 ber = 0x%x \n", __FUNCTION__, *ber); ++ } ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++static int fc0012_get_signal_strength(struct rtl2832_state *p_state,unsigned long *strength) ++{ ++ int intTemp=0; ++ int Power=0; ++ int intTotalAGCGain=0; ++ int intLNA=0; ++ unsigned char ReadingByte=0; ++ int LnaGain_reg=0; ++ int NumberOfLnaGainTable=0; ++ int i=0; ++ int Index=0; ++ TUNER_MODULE *pTuner=NULL; ++ DVBT_DEMOD_MODULE *pDemod = NULL; ++ ++ ++ if(p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ pDemod = p_state->pNim->pDemod; ++ pTuner = p_state->pNim->pTuner; ++ ++ // Enable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x1) != FUNCTION_SUCCESS) ++ goto error; ++ ++ if(FC0012_Write(pTuner, 0x12, 0x00) != FUNCTION_SUCCESS) ++ goto error; ++ ++ if(FC0012_Read(pTuner, 0x12, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error; ++ intTemp=(int)ReadingByte; ++ ++ if(FC0012_Read(pTuner, 0x13, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error; ++ LnaGain_reg=(int)ReadingByte&0x7f; ++ ++ // Disable demod DVBT_IIC_REPEAT. ++ if(pDemod->SetRegBitsWithPage(pDemod, DVBT_IIC_REPEAT, 0x0) != FUNCTION_SUCCESS) ++ goto error; ++ ++ NumberOfLnaGainTable=sizeof(FC0012_LNA_GAIN_TABLE)/sizeof(FC0012_LNA_REG_MAP); ++ Index=-1; ++ for (i=0;i> 5) - 7) -2) * 2 + (intTemp & 0x1F) * 2); ++ ++ Power= INPUT_ADC_LEVEL - intTotalAGCGain - (intLNA/10); ++ ++ deb_info(" %s power=%d form fc0012(%x,%x,%x)\n", __FUNCTION__,Power,intTemp,LnaGain_reg,intLNA); ++ ++ //Signal Strength : map power to 0~100 ++ ++ ++ if(Power >=-45) ++ { ++ *strength=100; ++ ++ } ++ else if(Power <-95) ++ *strength=0; ++ else ++ *strength = ((Power+45)*100)/50+100; ++ return 0; ++error: ++ return -1; ++} ++ ++ ++int ++rtl2832_read_signal_strength( ++ struct dvb_frontend* fe, ++ u16* strength) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ unsigned long _strength; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ ++ if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ if (fc0012_get_signal_strength(p_state,&_strength)) ++ { ++ *strength = 0; ++ goto error; ++ } ++#if 0 ++ /* this is wrong, as _strength is in the range [0,100] */ ++ *strength = (_strength<<8) | _strength; ++#else ++ /* scale *strength in the proper range [0,0xffff] */ ++ *strength = (_strength * 0xffff) / 100; ++#endif ++ deb_info(" %s : use FC0012 strength = 0x%x(%d) \n", __FUNCTION__, *strength,*strength); ++ } ++ else if(p_state->demod_type == RTL2832) ++ { ++ if( p_state->pNim->GetSignalStrength( p_state->pNim , &_strength) ) ++ { ++ *strength = 0; ++ goto error; ++ } ++#if 0 ++ /* this is wrong, as _strength is in the range [0,100] */ ++ *strength = (_strength<<8) | _strength; ++#else ++ /* scale *strength in the proper range [0,0xffff] */ ++ *strength = (_strength * 0xffff) / 100; ++#endif ++ deb_info(" %s : RTL2832 strength = 0x%x \n", __FUNCTION__, *strength); ++ } ++ else if(p_state->demod_type == RTL2836) ++ { ++ if(p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ if(p_state->pNim2836->pDemod->GetSignalStrength( p_state->pNim2836->pDemod , &_strength))// if(p_state->pNim2836->GetSignalStrength( p_state->pNim2836 , &_strength) ) ++ { ++ *strength = 0; ++ goto error; ++ } ++#if 0 ++ /* this is wrong, as _strength is in the range [0,100] */ ++ *strength = (_strength<<8) | _strength; ++#else ++ /* scale *strength in the proper range [0,0xffff] */ ++ *strength = (_strength * 0xffff) / 100; ++#endif ++ deb_info(" %s : RTL2836 strength = 0x%x \n", __FUNCTION__, *strength); ++ } ++ else if(p_state->demod_type == RTL2840) ++ { ++ if(p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(p_state->pNim2840->pDemod->GetSignalStrength( p_state->pNim2840->pDemod , &_strength))// if(p_state->pNim2836->GetSignalStrength( p_state->pNim2836 , &_strength) ) ++ { ++ *strength = 0; ++ goto error; ++ } ++#if 0 ++ /* this is wrong, as _strength is in the range [0,100] */ ++ *strength = (_strength<<8) | _strength; ++#else ++ /* scale *strength in the proper range [0,0xffff] */ ++ *strength = (_strength * 0xffff) / 100; ++#endif ++ deb_info(" %s : RTL2840 strength = 0x%x \n", __FUNCTION__, *strength); ++ } ++ ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++ ++ ++int ++rtl2832_read_signal_quality( ++ struct dvb_frontend* fe, ++ u32* quality) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ unsigned long _quality; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if ( p_state->pNim->GetSignalQuality( p_state->pNim , &_quality) ) ++ { ++ *quality = 0; ++ goto error; ++ } ++ } ++ else if(p_state->demod_type == RTL2836) ++ { ++ if( p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if ( p_state->pNim2836->pDemod->GetSignalQuality( p_state->pNim2836->pDemod , &_quality) )//if ( p_state->pNim->GetSignalQuality( p_state->pNim , &_quality) ) ++ { ++ *quality = 0; ++ goto error; ++ } ++ } ++ else if(p_state->demod_type == RTL2840) ++ { ++ if( p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if ( p_state->pNim2840->pDemod->GetSignalQuality( p_state->pNim2840->pDemod , &_quality) )//if ( p_state->pNim->GetSignalQuality( p_state->pNim , &_quality) ) ++ { ++ *quality = 0; ++ goto error; ++ } ++ } ++ ++ *quality = _quality; ++ ++ deb_info(" %s : quality = 0x%x \n", __FUNCTION__, *quality); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++ ++ ++ ++static int ++rtl2832_read_snr( ++ struct dvb_frontend* fe, ++ u16* snr) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ long snr_num = 0; ++ long snr_dem = 0; ++ long _snr= 0; ++ int pConstellation; ++ int pHierarchy; ++ int pCodeRateLp; ++ int pCodeRateHp; ++ int pGuardInterval; ++ int pFftMode; ++ ++ // max dB for each constellation ++ static const int snrMaxDb[DVBT_CONSTELLATION_NUM] = { 23, 26, 29, }; ++ ++ if( p_state->pNim== NULL) ++ { ++ deb_info(" %s pNim = NULL \n", __FUNCTION__); ++ return -1; ++ } ++ ++ if( mutex_lock_interruptible(&p_state->i2c_repeater_mutex) ) goto mutex_error; ++ ++ if(p_state->demod_type == RTL2832) ++ { ++ if (p_state->pNim->GetSnrDb(p_state->pNim, &snr_num, &snr_dem) ) ++ { ++ *snr = 0; ++ goto error; ++ } ++ ++ if (dvb_usb_rtl2832u_snrdb == 0) ++ { ++ p_state->pNim->GetTpsInfo(p_state->pNim, &pConstellation, &pHierarchy, &pCodeRateLp, &pCodeRateHp, &pGuardInterval, &pFftMode); ++ _snr = ((snr_num / snr_dem) * 0xffff) / snrMaxDb[pConstellation]; ++ if ( _snr > 0xffff ) _snr = 0xffff; ++ if ( _snr < 0 ) _snr = 0; ++ } ++ else ++ { ++ _snr = snr_num / snr_dem; ++ if( _snr < 0 ) _snr = 0; ++ } ++ ++ *snr = _snr; ++ } ++ else if(p_state->demod_type == RTL2836) ++ { ++ if( p_state->pNim2836 == NULL) ++ { ++ deb_info(" %s pNim2836 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(p_state->pNim2836->pDemod->GetSnrDb(p_state->pNim2836->pDemod, &snr_num, &snr_dem)) ++ { ++ *snr = 0; ++ goto error; ++ } ++ *snr = snr_num>>2; ++ } ++ else if(p_state->demod_type == RTL2840) ++ { ++ if( p_state->pNim2840 == NULL) ++ { ++ deb_info(" %s pNim2840 = NULL \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if(p_state->pNim2840->pDemod->GetSnrDb(p_state->pNim2840->pDemod, &snr_num, &snr_dem)) ++ { ++ *snr = 0; ++ goto error; ++ } ++ *snr = snr_num/snr_dem; ++ } ++ ++ ++ deb_info(" %s : snr = %d \n", __FUNCTION__, *snr); ++ ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++ return 0; ++ ++error: ++ mutex_unlock(&p_state->i2c_repeater_mutex); ++ ++mutex_error: ++ return -1; ++} ++ ++ ++ ++static int ++rtl2832_get_tune_settings( ++ struct dvb_frontend* fe, ++ struct dvb_frontend_tune_settings* fe_tune_settings) ++{ ++ deb_info(" %s : Do Nothing\n", __FUNCTION__); ++ fe_tune_settings->min_delay_ms = 1000; ++ return 0; ++} ++ ++ ++static int ++rtl2832_ts_bus_ctrl( ++ struct dvb_frontend* fe, ++ int acquire) ++{ ++ deb_info(" %s : Do Nothing\n", __FUNCTION__); ++ return 0; ++} ++ ++static int ++rtl2832_get_algo(struct dvb_frontend *fe) ++{ ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ ++ if(p_state->rtl2832_audio_video_mode == RTK_AUDIO) ++ return DVBFE_ALGO_HW; ++ else ++ return DVBFE_ALGO_SW; ++} ++ ++#ifdef V4L2_ONLY_DVB_V5 ++static int ++rtl2832_tune(struct dvb_frontend *fe, ++ bool re_tune, ++ unsigned int mode_flags, ++ unsigned int *delay, ++ fe_status_t *status) ++{ ++ //struct dvb_frontend_private *fepriv = fe->frontend_priv; ++ // fe_status_t s = 0; ++ int retval = 0; ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ ++ if(p_state->rtl2832_audio_video_mode != RTK_AUDIO) ++ { ++ *status = 256; ++ deb_info("%s: can't set parameter now\n",__FUNCTION__); ++ return 0; ++ } ++ ++ if (re_tune) ++ retval = rtl2832_set_parameters_fm(fe); ++ if(retval < 0) ++ *status = 256;//FESTATE_ERROR; ++ //else ++ // status = 16;//FESTATE_TUNED; ++ ++ *delay = 10*HZ; ++ //fepriv->quality = 0; ++ ++ return 0; ++} ++#else ++static int ++rtl2832_tune(struct dvb_frontend *fe, ++ struct dvb_frontend_parameters *params, ++ unsigned int mode_flags, ++ unsigned int *delay, ++ fe_status_t *status) ++{ ++ ++ //struct dvb_frontend_private *fepriv = fe->frontend_priv; ++ // fe_status_t s = 0; ++ int retval = 0; ++ struct rtl2832_state* p_state = fe->demodulator_priv; ++ ++ if(params == NULL) ++ { ++ return 0; ++ } ++ ++ if(p_state->rtl2832_audio_video_mode != RTK_AUDIO) ++ { ++ *status = 256; ++ deb_info("%s: can't set parameter now\n",__FUNCTION__); ++ return 0; ++ } ++ ++ retval = rtl2832_set_parameters_fm(fe, params); ++ if(retval < 0) ++ *status = 256;//FESTATE_ERROR; ++ //else ++ // status = 16;//FESTATE_TUNED; ++ ++ *delay = 10*HZ; ++ //fepriv->quality = 0; ++ ++ return 0; ++ ++} ++#endif ++ ++static struct dvb_frontend_ops rtl2832_dvbt_ops; ++static struct dvb_frontend_ops rtl2840_dvbc_ops; ++static struct dvb_frontend_ops rtl2836_dtmb_ops; ++ ++ ++struct dvb_frontend* rtl2832u_fe_attach(struct dvb_usb_device *d) ++{ ++ ++ struct rtl2832_state* p_state= NULL; ++ //char tmp_set_tuner_power_gpio4; ++ ++ deb_info("+%s : chialing 2011-12-26\n", __FUNCTION__); ++ ++ //3 linux fe_attach necessary setting ++ /*allocate memory for the internal state */ ++ p_state = kzalloc(sizeof(struct rtl2832_state), GFP_KERNEL); ++ if (p_state == NULL) goto error; ++ memset(p_state,0,sizeof(*p_state)); ++ ++ p_state->is_mt2266_nim_module_built = 0; //initialize is_mt2266_nim_module_built ++ p_state->is_mt2063_nim_module_built = 0; //initialize is_mt2063_nim_module_built ++ ++ p_state->is_initial = 0; //initialize is_initial ++ p_state->is_frequency_valid = 0; ++ p_state->d = d; ++ ++ p_state->b_rtl2840_power_onoff_once = 0; ++ ++ if( usb_init_setting(p_state) ) goto error; ++ ++ if( gpio3_out_setting(p_state) ) goto error; //3Set GPIO3 OUT ++ ++ if( demod_ctl1_setting(p_state , 1) ) goto error; //3 DEMOD_CTL1, resume = 1 ++ if (dvb_use_rtl2832u_card_type) ++ { ++ if( set_demod_power(p_state , 1) ) goto error; ++ } ++ ++ if( suspend_latch_setting(p_state , 1) ) goto error; //3 suspend_latch_en = 0, resume = 1 ++ ++ if( demod_ctl_setting(p_state , 1, 1) ) goto error; //3 DEMOD_CTL, resume =1; ADC on ++ ++ //3 Auto detect Tuner Power Pin (GPIO3 or GPIO4) ++ if( set_tuner_power(p_state , 1 , 1) ) goto error; //3 turn ON tuner power, 1st try GPIO4 ++ ++ if( check_tuner_type(p_state) ) goto error; ++ ++ //3 Check if support RTL2836 DTMB. ++ p_state->demod_support_type = 0; ++ check_dtmb_support(p_state); //2836 is off in the end of check_dtmb_support() ++ check_dvbc_support(p_state); ++ ++ //3Set demod_type. ++ p_state->demod_ask_type = demod_default_type; ++ if((p_state->demod_ask_type == RTL2836) && (p_state->demod_support_type & SUPPORT_DTMB_MODE)) ++ { ++ p_state->demod_type = RTL2836; ++ } ++ else if((p_state->demod_ask_type == RTL2840) && (p_state->demod_support_type & SUPPORT_DVBC_MODE)) ++ { ++ p_state->demod_type = RTL2840; ++ } ++ else ++ { ++ p_state->demod_type = RTL2832; ++ } ++ deb_info("demod_type is %d\n", p_state->demod_type); ++ ++ //3 Build Nim Module ++ build_nim_module(p_state); ++ ++ /* setup the state */ ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ memcpy(&p_state->frontend.ops, &rtl2832_dvbt_ops, sizeof(struct dvb_frontend_ops)); ++#ifndef V4L2_ONLY_DVB_V5 ++ memset(&p_state->fep, 0, sizeof(struct dvb_frontend_parameters)); ++#endif ++ ++ break; ++ case RTL2836: ++ memcpy(&p_state->frontend.ops, &rtl2836_dtmb_ops, sizeof(struct dvb_frontend_ops)); ++#ifndef V4L2_ONLY_DVB_V5 ++ memset(&p_state->fep, 0, sizeof(struct dvb_frontend_parameters)); ++#endif ++ break; ++ ++ case RTL2840: ++ memcpy(&p_state->frontend.ops, &rtl2840_dvbc_ops, sizeof(struct dvb_frontend_ops)); ++#ifndef V4L2_ONLY_DVB_V5 ++ memset(&p_state->fep, 0, sizeof(struct dvb_frontend_parameters)); ++#endif ++ break; ++ } ++ ++ ++ /* create dvb_frontend */ ++ p_state->frontend.demodulator_priv = p_state; ++ ++#if UPDATE_FUNC_ENABLE_2840 ++ INIT_DELAYED_WORK(&(p_state->update2840_procedure_work), rtl2840_update_function); ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ INIT_DELAYED_WORK(&(p_state->update2836_procedure_work), rtl2836_update_function); ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ INIT_DELAYED_WORK(&(p_state->update2832_procedure_work), rtl2832_update_functions); ++#endif ++ mutex_init(&p_state->i2c_repeater_mutex); ++ if (dvb_use_rtl2832u_rc_mode<3){ ++ deb_info(">>%s go to sleep mode(low power mode)\n", __FUNCTION__); ++ if (rtl2832_sleep_mode(p_state)){ ++ deb_info("sleep mode is fail \n"); ++ } ++ } ++ deb_info("-%s\n", __FUNCTION__); ++ return &p_state->frontend; ++ ++error: ++ return NULL; ++ ++ ++} ++ ++ ++ ++static struct dvb_frontend_ops rtl2840_dvbc_ops = { ++#ifdef V4L2_ONLY_DVB_V5 ++ /* TODO: check if rtl2840 supports also SYS_DVBC_ANNEX_C */ ++ .delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C }, ++#endif ++ .info = { ++ .name = "Realtek DVB-C RTL2840 ", ++#ifndef V4L2_ONLY_DVB_V5 ++ .type = FE_QAM, ++#endif ++ .frequency_min = 50000000, ++ .frequency_max = 862000000, ++ .frequency_stepsize = 166667, ++ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | ++ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | ++ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | ++ FE_CAN_MUTE_TS ++ }, ++ ++ .init = rtl2832_init, ++ .release = rtl2832_release, ++ ++ .sleep = rtl2832_sleep, ++ ++ .set_frontend = rtl2840_set_parameters, ++ .get_frontend = rtl2832_get_parameters, ++ .get_tune_settings = rtl2832_get_tune_settings, ++ ++ .read_status = rtl2832_read_status, ++ .read_ber = rtl2832_read_ber, ++ .read_signal_strength = rtl2832_read_signal_strength, ++ .read_snr = rtl2832_read_snr, ++ .read_ucblocks = rtl2832_read_signal_quality, ++ .ts_bus_ctrl = rtl2832_ts_bus_ctrl, ++}; ++ ++ ++ ++ ++static struct dvb_frontend_ops rtl2832_dvbt_ops = { ++#ifdef V4L2_ONLY_DVB_V5 ++ .delsys = { SYS_DVBT }, ++#endif ++ .info = { ++ .name = "Realtek DVB-T RTL2832", ++#ifndef V4L2_ONLY_DVB_V5 ++ .type = FE_OFDM, ++#endif ++ .frequency_min = 80000000,//174000000, ++ .frequency_max = 862000000, ++ .frequency_stepsize = 166667, ++ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | ++ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | ++ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | ++ FE_CAN_MUTE_TS ++ }, ++ ++ .init = rtl2832_init, ++ .release = rtl2832_release, ++ ++ .sleep = rtl2832_sleep, ++ ++ .set_frontend = rtl2832_set_parameters, ++ .get_frontend = rtl2832_get_parameters, ++ .get_tune_settings = rtl2832_get_tune_settings, ++ ++ .read_status = rtl2832_read_status, ++ .read_ber = rtl2832_read_ber, ++ .read_signal_strength = rtl2832_read_signal_strength, ++ .read_snr = rtl2832_read_snr, ++ .read_ucblocks = rtl2832_read_signal_quality, ++ .ts_bus_ctrl = rtl2832_ts_bus_ctrl, ++ ++ .get_frontend_algo = rtl2832_get_algo, ++ .tune = rtl2832_tune, ++}; ++ ++static struct dvb_frontend_ops rtl2836_dtmb_ops = { ++#ifdef V4L2_ONLY_DVB_V5 ++ .delsys = { SYS_DMBTH }, ++#endif ++ .info = { ++ .name = "Realtek DTMB RTL2836", ++#ifndef V4L2_ONLY_DVB_V5 ++ .type = FE_OFDM, ++#endif ++ .frequency_min = 50000000, ++ .frequency_max = 862000000, ++ .frequency_stepsize = 166667, ++ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | ++ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | ++ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | ++ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | ++ FE_CAN_MUTE_TS ++ }, ++ ++ .init = rtl2832_init, ++ .release = rtl2832_release, ++ ++ .sleep = rtl2832_sleep, ++ ++ .set_frontend = rtl2832_set_parameters, ++ .get_frontend = rtl2832_get_parameters, ++ .get_tune_settings = rtl2832_get_tune_settings, ++ ++ .read_status = rtl2832_read_status, ++ .read_ber = rtl2832_read_ber, ++ .read_signal_strength = rtl2832_read_signal_strength, ++ .read_snr = rtl2832_read_snr, ++ .read_ucblocks = rtl2832_read_signal_quality, ++ .ts_bus_ctrl = rtl2832_ts_bus_ctrl, ++}; ++ ++ ++ ++/* DTMB related */ ++ ++static int ++check_dtmb_support( ++ struct rtl2832_state* p_state) ++{ ++ ++ int status; ++ unsigned char buf[LEN_2_BYTE]; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ set_demod_2836_power(p_state, 1); //on ++ ++ status = read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_5, 0x10, buf, LEN_2_BYTE); ++ ++ if(!status && ( buf[0]==0x04 ) && ( buf[1]==0x00 )) ++ { ++ p_state->demod_support_type |= SUPPORT_DTMB_MODE; ++ deb_info(" -%s RTL2836 on broad.....\n", __FUNCTION__); ++ } ++ else ++ { ++ p_state->demod_support_type &= (~SUPPORT_DTMB_MODE); ++ deb_info(" -%s RTL2836 NOT FOUND.....\n", __FUNCTION__); ++ } ++ ++ set_demod_2836_power(p_state, 0); //off ++ ++ //3 Always support DVBT ++ p_state->demod_support_type |= SUPPORT_DVBT_MODE; ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++} ++ ++ ++ ++/* DVB-C related */ ++ ++static int ++check_dvbc_support( ++ struct rtl2832_state* p_state) ++{ ++ ++ int status; ++ unsigned char buf; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ set_demod_2840_power(p_state, 1); ++ ++ status = read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ ++ if(!status) ++ { ++ p_state->demod_support_type |= SUPPORT_DVBC_MODE; ++ deb_info(" -%s RTL2840 on broad.....\n", __FUNCTION__); ++ } ++ else ++ { ++ p_state->demod_support_type &= (~SUPPORT_DVBC_MODE); ++ deb_info(" -%s RTL2840 NOT FOUND.....\n", __FUNCTION__); ++ } ++ ++ set_demod_2840_power(p_state, 0); ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++} ++ ++ ++ ++static int ++set_demod_2836_power( ++ struct rtl2832_state* p_state, ++ int onoff) ++{ ++ ++ int data; ++ unsigned char datachar; ++ ++ deb_info(" +%s onoff = %d\n", __FUNCTION__, onoff); ++ ++ //2 First RTL2836 Power ON ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 a. Set GPIO 0 LOW ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data &= ~(BIT0); // set GPIO0 low ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC2580) ++ { ++ ++ //3 b. Set GPIO 5 LOW ++ if( gpio5_output_enable_direction(p_state)) goto error; ++ ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data) ) goto error; ++ data &= ~(BIT5); // set GPIO5 low ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data) ) goto error; ++ } ++ ++ if(onoff) ++ { ++ //3 2. RTL2836 AGC = 1 ++ if ( read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_0, 0x01, &datachar, LEN_1_BYTE)) goto error; ++ datachar |=BIT_2_MASK; ++ datachar &=(~BIT_3_MASK); ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_0, 0x01, &datachar, LEN_1_BYTE)) goto error; ++ } ++ else ++ { ++ ++ //3 2. RTL2836 AGC = 0 ++ ++ if ( read_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_0, 0x01, &datachar, LEN_1_BYTE)) goto error; ++ datachar &=(~BIT_2_MASK); ++ datachar &=(~BIT_3_MASK); ++ if(write_rtl2836_demod_register(p_state->d, RTL2836_DEMOD_ADDR, PAGE_0, 0x01, &datachar, LEN_1_BYTE)) goto error; ++ ++ ++ //3 3. RTL2836 Power OFF ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 4.a. Set GPIO 0 HIGH ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data |= BIT0; // set GPIO0 high ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC2580) ++ { ++ ++ //3 4.b. Set GPIO 5 HIGH ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data |= BIT5; // set GPIO5 high ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ } ++ } ++ ++ ++ deb_info(" -%s onoff = %d\n", __FUNCTION__, onoff); ++ return 0; ++ ++error: ++ deb_info(" -%s onoff = %d fail\n", __FUNCTION__, onoff); ++ return 1; ++ ++} ++ ++ ++ ++ ++ ++ ++static int ++rtl2840_on_hwreset( ++ struct rtl2832_state* p_state) ++{ ++ unsigned char buf; ++ int data; ++ int time = 0; ++ ++ deb_info(" +%s \n", __FUNCTION__); ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data |= BIT0; // set GPIO0 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data |= BIT6; // set GPIO6 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ ++ gpio6_output_enable_direction(p_state); ++ ++ platform_wait(25); //wait 25ms ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data &= (~BIT6); // set GPIO6 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ ++ platform_wait(25); //wait 25ms ++ ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data &= (~BIT0); // set GPIO0 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ ++ platform_wait(25); //wait 25ms ++ ++ read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x01, &buf, LEN_1_BYTE); ++ ++ while( (buf!=0xa3) && (time<2) ) ++ { ++ ++ // Set GPIO 6 HIGH ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data |= BIT6; // set GPIO6 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ platform_wait(25); //wait 25ms ++ ++ // Set GPIO 0 HIGH ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data |= BIT0; // set GPIO0 high ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ platform_wait(25); //wait 25ms ++ ++ // Set GPIO 6 LOW ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data &= (~BIT6); // set GPIO6 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ platform_wait(25); //wait 25ms ++ ++ // Set GPIO 0 LOW ++ read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data); ++ data &= (~BIT0); // set GPIO0 low ++ write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data); ++ platform_wait(25); //wait 25ms ++ ++ read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x01, &buf, LEN_1_BYTE); ++ deb_info(" +%s Page 0, addr 0x01 = 0x%x\n", __FUNCTION__, buf); ++ time++; ++ } ++ ++ deb_info(" -%s \n", __FUNCTION__); ++ ++ return 0; ++ ++} ++ ++ ++ ++static int ++set_demod_2840_power( ++ struct rtl2832_state* p_state, ++ int onoff) ++{ ++ unsigned char buf; ++ int data; ++ ++ deb_info(" +%s onoff = %d\n", __FUNCTION__, onoff); ++ ++ //3 1.a RTL2840 Power ON Set GPIO 0 LOW ++ if(p_state->b_rtl2840_power_onoff_once) ++ { ++ //3 a. Set GPIO 0 LOW ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data &= ~(BIT0); // set GPIO0 low ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ ++ platform_wait(50); //wait 50ms ++ } ++ else ++ { ++ rtl2840_on_hwreset(p_state); ++ p_state->b_rtl2840_power_onoff_once = 1; ++ } ++ ++ if(onoff) ++ { ++ //3 2.a RTL2840 AGC = 1 ++ read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ buf &= (~BIT_6_MASK); ++ buf |= BIT_7_MASK; ++ write_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ } ++ else ++ { ++ ++ //3 2.b RTL2840 AGC = 0 ++ read_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ buf &= (~BIT_6_MASK); ++ buf &= (~BIT_7_MASK); ++ write_demod_register(p_state->d, RTL2840_DEMOD_ADDR, PAGE_0, 0x04, &buf, LEN_1_BYTE); ++ ++ //3 3.a RTL2840 Power OFF Set GPIO 0 HIGH ++ if( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, &data)) goto error; ++ data |=BIT0; // set GPIO0 HIGH ++ if( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, data)) goto error; ++ } ++ ++ deb_info(" -%s onoff = %d\n", __FUNCTION__, onoff); ++ ++ return 0; ++error: ++ deb_info(" - XXX %s onoff = %d\n", __FUNCTION__, onoff); ++ return 1; ++} ++ ++ ++ ++static int ++demod_init_setting( ++ struct rtl2832_state * p_state ++ ) ++{ ++ ++ unsigned char data; ++ unsigned char buf[LEN_2_BYTE]; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ { ++ deb_info("%s for RTL2832\n", __FUNCTION__); ++ //3 1. Set IF_AGC Internal IF_AGC_MAN 0x0c ++ if(read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x0c, &data, LEN_1_BYTE)) goto error; ++ data &= (~BIT6); ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x0c, &data, LEN_1_BYTE)) goto error; ++ ++ ++ /*if(!context->DAB_AP_running) ++ { ++ //3 2. Set PID filter to reject null packet(pid = 0x1fff) ++ context->pid_filter_mode = REJECT_MODE; ++ ULONG reject_pid[1] = {0x1fff}; ++ Status = PidFilterToRejectMode(context, reject_pid, 1); ++ if(!NT_SUCCESS(Status)) goto error; ++ }*/ ++ ++ } ++ break; ++ ++ case RTL2836: ++ case RTL2840: ++ { ++ ++ deb_info("%s RTL2832P for RTL2836 and RTL2840 \n", __FUNCTION__); ++ //3 1. Set IF_AGC Manual and Set IF_AGC MAX VAL ++ buf[0]=0x5F; ++ buf[1]=0xFF; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x0c, buf, LEN_2_BYTE)) goto error; ++ ++ //3 2. PIP Setting ++ data = 0xe8; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x21, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x60; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x61, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x18; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0xbc, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x00; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x62, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x00; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x63, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x00; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x64, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x00; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x65, &data, LEN_1_BYTE)) goto error; ++ ++ //3 +PIP filter Reject = 0x1FFF ++ data = 0x01; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x22, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0x1f; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x26, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0xff; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_0, 0x27, &data, LEN_1_BYTE)) goto error; ++ //3 -PIP filter Reject = 0x1FFF ++ ++ data = 0x7f; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x92, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0xf7; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x93, &data, LEN_1_BYTE)) goto error; ++ ++ data = 0xff; ++ if(write_demod_register(p_state->d, RTL2832_DEMOD_ADDR, PAGE_1, 0x94, &data, LEN_1_BYTE)) goto error; ++ } ++ break; ++ } ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return 0; ++ ++error: ++ deb_info(" -%s error \n", __FUNCTION__); ++ return 1; ++ ++} ++ ++ ++static int ++rtl2836_scan_procedure( ++ struct rtl2832_state * p_state) ++{ ++ unsigned char val; ++ int wait_num = 0; ++ unsigned long Per1, Per2; ++ long Data1,Data2,Snr; ++ DTMB_DEMOD_MODULE *pDtmbDemod; ++ struct dvb_usb_device* dev; ++ ++ ++ pDtmbDemod = p_state->pNim2836->pDemod; ++ dev = p_state->d; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ //3 Check signal present ++ wait_num = 0; ++ msleep(50); // Wait 0.05s ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_6, 0x53, &val, LEN_1_BYTE)) goto error; ++ deb_info("%s Signel Present = 0x %x\n", __FUNCTION__, val); ++ while((wait_num<3)&& (!(val&BIT_0_MASK))) ++ { ++ msleep(50); // Wait 0.05s ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_6, 0x53, &val, LEN_1_BYTE)) goto error; ++ deb_info("%s Signel Present = 0x %x\n", __FUNCTION__, val); ++ wait_num++; ++ } ++ ++ if(val&BIT_0_MASK) ++ { ++ //3 Write signal present ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ val |= BIT_0_MASK; //set Reg_present ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ ++ //3+ RTL2836 Release Stage=9 ++ val = 0x49; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4d, &val, LEN_1_BYTE)) goto error; ++ val = 0x29; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4e, &val, LEN_1_BYTE)) goto error; ++ val = 0x95; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4f, &val, LEN_1_BYTE)) goto error; ++ //3 -RTL2836 Release Stage=9 ++ deb_info("%s RTL2836 Release Stage 9\n", __FUNCTION__); ++ ++ ++ //3 Check signal lock ++ pDtmbDemod->GetPer(pDtmbDemod, &Per1, &Per2); ++ deb_info("%s --***GetPer = %d***\n", __FUNCTION__, (int)Per1); ++ ++ pDtmbDemod->GetSnrDb(pDtmbDemod, &Data1, &Data2); ++ Snr = Data1>>2; ++ deb_info("%s --***SNR= %d***\n", __FUNCTION__, (int)Snr); ++ ++ wait_num = 0; ++ while(wait_num<30 ) ++ { ++ if((Per1<1) && (Snr>0) && (Snr<40) ) ++ { ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ val |= BIT_1_MASK; //set Reg_signal ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ ++ deb_info("%s Signal Lock................\n", __FUNCTION__); ++ break; ++ } ++ ++ msleep(100); // Wait 0.1s ++ pDtmbDemod->GetPer(pDtmbDemod,&Per1,&Per2); ++ deb_info("%s --***GetPer = %d***\n", __FUNCTION__, (int)Per1); ++ ++ pDtmbDemod->GetSnrDb(pDtmbDemod,&Data1,&Data2); ++ Snr = Data1>>2; ++ deb_info("%s --***SNR= %d***\n", __FUNCTION__, (int)Snr); ++ wait_num++; ++ } ++ ++ if(! ((Per1<1) && (Snr>0) && (Snr<40))) ++ { ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ val &=(~BIT_1_MASK); //reset Reg_lock ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ } ++ } ++ else ++ { ++ if(read_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ val &=(~BIT_0_MASK); //reset Reg_present ++ val &=(~BIT_1_MASK); //reset Reg_lock ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0xf8, &val, LEN_1_BYTE)) goto error; ++ ++ //3 + RTL2836 Release Stage=9 ++ val = 0x49; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4d, &val, LEN_1_BYTE)) goto error; ++ val = 0x29; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4e, &val, LEN_1_BYTE)) goto error; ++ val = 0x95; ++ if(write_rtl2836_demod_register(dev, RTL2836_DEMOD_ADDR, PAGE_3, 0x4f, &val, LEN_1_BYTE)) goto error; ++ //3 -RTL2836 Release Stage=9 ++ ++ deb_info("%s RTL2836 Release Stage 9\n", __FUNCTION__); ++ } ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return 0; ++error: ++ ++ deb_info(" +%s error\n", __FUNCTION__); ++ return -1; ++} ++ ++ ++static int ++build_2832_nim_module( ++ struct rtl2832_state* p_state) ++{ ++ ++ MT2266_EXTRA_MODULE *p_mt2266_extra; ++ MT2063_EXTRA_MODULE *p_mt2063_extra; ++ TUNER_MODULE *pTuner; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ //3 Buile 2832 nim module ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MT2266) ++ { ++ //3 Build RTL2832 MT2266 NIM module. ++ ++ BuildRtl2832Mt2266Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2 ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ MT2266_TUNER_ADDR // The MT2266 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ // Get MT2266 tuner extra module. ++ pTuner = p_state->pNim->pTuner; ++ p_mt2266_extra = &(pTuner->Extra.Mt2266); ++ ++ // Open MT2266 handle. ++ if(p_mt2266_extra->OpenHandle(pTuner)) ++ deb_info("%s : MT2266 Open Handle Failed....\n", __FUNCTION__); ++ ++ p_state->is_mt2266_nim_module_built = 1; ++ ++ deb_info(" %s BuildRtl2832Mt2266Module\n", __FUNCTION__); ++ ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_FC2580) ++ { ++ ++ //3Build RTL2832 FC2580 NIM module. ++ BuildRtl2832Fc2580Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 9. ++ 2, // Maximum I2C writing byte number is 8. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ FC2580_TUNER_ADDR, // The FC2580 I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // The FC2580 crystal frequency is 16.384 MHz. ++ FC2580_AGC_INTERNAL // The FC2580 AGC mode is external AGC mode. ++ ); ++ deb_info(" %s BuildRtl2832Fc2580Module\n", __FUNCTION__); ++ ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_TUA9001) ++ { ++ ++ //3Build RTL2832 TUA9001 NIM module. ++ BuildRtl2832Tua9001Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ NULL, // Employ CustomI2cRead() as basic I2C reading function. ++ NULL, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 50 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ TUA9001_TUNER_ADDR // The TUA9001 I2C device address is 0xc0 in 8-bit format. ++ ); ++ deb_info(" %s BuildRtl2832Tua9001Module\n", __FUNCTION__); ++ ++ } ++ else if( p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ ++ //3Build RTL2832 MXL5007 NIM module. ++ BuildRtl2832Mxl5007tModule( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function.. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ MXL5007T_BASE_ADDRESS, // The MxL5007T I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The MxL5007T Crystal frequency is 16.0 MHz. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0 // The MxL5007T clock output amplitude is 0. ++ ); ++ deb_info(" %s BuildRtl2832Mxl5007tModule\n", __FUNCTION__); ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0012) ++ { ++ //3Build RTL2832 FC0012 NIM module. ++ BuildRtl2832Fc0012Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ FC0012_BASE_ADDRESS, // The FC0012 I2C device address is 0xc6 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ // The FC0012 crystal frequency is 36.0 MHz. ++ ); ++ deb_info(" %s BuildRtl2832Fc0012Module\n", __FUNCTION__); ++ ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_E4000) ++ { ++ //3 Build RTL2832 E4000 NIM module ++ BuildRtl2832E4000Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 50 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ E4000_BASE_ADDRESS, // The E4000 I2C device address is 0xc8 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ // The E4000 crystal frequency is 28.8 MHz. ++ ); ++ deb_info(" %s BuildRtl2832E4000Module\n", __FUNCTION__); ++ ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_MT2063) ++ { ++ ++ // Build RTL2832 MT2063 NIM module. ++ BuildRtl2832Mt2063Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ IF_FREQ_36125000HZ, // The RTL2832 and MT2063 IF frequency is 36.125 MHz. ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARRLLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ MT2063_TUNER_ADDR // The MT2063 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ // Get MT2063 tuner extra module. ++ pTuner = p_state->pNim->pTuner; ++ p_mt2063_extra = &(pTuner->Extra.Mt2063); ++ ++ // Open MT2063 handle. ++ if(p_mt2063_extra->OpenHandle(pTuner)) ++ deb_info("%s : MT2063 Open Handle Failed....\n", __FUNCTION__); ++ ++ p_state->is_mt2063_nim_module_built = 1; ++ ++ deb_info(" %s BuildRtl2832Mt2063Module\n", __FUNCTION__); ++ ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_MAX3543) ++ { ++ ++ // Build RTL2832 MAX3543 NIM module. ++ BuildRtl2832Max3543Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ MAX3543_TUNER_ADDR, // The MAX3543 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ // The MAX3543 Crystal frequency is 16.0 MHz. ++ ); ++ ++ deb_info(" %s BuildRtl2832Max3543Module\n", __FUNCTION__); ++ ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_TDA18272) ++ { ++ ++ // Build RTL2832 TDA18272 NIM module. ++ BuildRtl2832Tda18272Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is STB mode. ++ 50, // The RTL2832 update function reference period is 50 millisecond ++ YES, // The RTL2832 Function 1 enabling status is YES. ++ ++ TDA18272_TUNER_ADDR, // The TDA18272 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The TDA18272 crystal frequency is 16.0 MHz. ++ TDA18272_UNIT_0, // The TDA18272 unit number is 0. ++ TDA18272_IF_OUTPUT_VPP_0P7V // The TDA18272 IF output Vp-p is 0.7 V. ++ ); ++ ++ deb_info(" %s BuildRtl2832Tda18272Module\n", __FUNCTION__); ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_FC0013) ++ { ++ //3Build RTL2832 FC0012 NIM module. ++ BuildRtl2832Fc0013Module( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is PARALLEL. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is DONGLE mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ FC0013_BASE_ADDRESS, // The FC0012 I2C device address is 0xc6 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ // The FC0012 crystal frequency is 36.0 MHz. ++ ); ++ deb_info(" %s BuildRtl2832Fc0013Module\n", __FUNCTION__); ++ ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_R820T) ++ { ++ //3Build RTL2832 R820T NIM module. ++ BuildRtl2832R820tModule( ++ &p_state->pNim, ++ &p_state->DvbtNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 9. ++ 2, // Maximum I2C writing byte number is 8. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2832_DEMOD_ADDR, // The RTL2832 I2C device address is 0x20 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2832 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_PARALLEL, // The RTL2832 TS interface mode is serial. ++ RTL2832_APPLICATION_DONGLE, // The RTL2832 application mode is STB mode. ++ 200, // The RTL2832 update function reference period is 200 millisecond ++ OFF, // The RTL2832 Function 1 enabling status is YES. ++ ++ R820T_BASE_ADDRESS // The R820T I2C device address is 0xc6 in 8-bit format. ++ ); ++ ++ deb_info(" %s BuildRtl2832R820tModule\n", __FUNCTION__); ++ ++ } ++ else ++ { ++ deb_info(" -%s : RTL 2832 Unknown tuner on board...\n", __FUNCTION__); ++ goto error; ++ } ++ //Set user defined data pointer of base interface structure for custom basic functions. ++ p_state->pNim->pBaseInterface->SetUserDefinedDataPointer(p_state->pNim->pBaseInterface, p_state->d ); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++ ++} ++ ++ ++ ++static int ++build_2836_nim_module( ++ struct rtl2832_state* p_state) ++{ ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_FC2580) ++ { ++ //3Build RTL2836 FC2580 NIM module. ++ BuildRtl2836Fc2580Module( ++ &p_state->pNim2836, ++ &p_state->DtmbNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2836_DEMOD_ADDR, // The RTL2836 I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The RTL2836 crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2836 TS interface mode is serial. ++ 50, // The RTL2836 update function reference period is 50 millisecond ++ YES, // The RTL2836 Function 1 enabling status is YES. ++ YES, // The RTL2836 Function 2 enabling status is YES. ++ ++ FC2580_TUNER_ADDR, // The FC2580 I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // The FC2580 crystal frequency is 16.384 MHz. ++ FC2580_AGC_INTERNAL // The FC2580 AGC mode is internal AGC mode. ++ ); ++ } ++ else if(p_state->tuner_type == RTL2832_TUNER_TYPE_MXL5007T) ++ { ++ //3 Build RTL2836 MXL5007T NIM module ++ BuildRtl2836Mxl5007tModule( ++ &p_state->pNim2836, ++ &p_state->DtmbNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2836_DEMOD_ADDR, // The RTL2836 I2C device address is 0x3e in 8-bit format. ++ CRYSTAL_FREQ_27000000HZ, // The RTL2836 crystal frequency is 27.0 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2836 TS interface mode is serial. ++ 50, // The RTL2836 update function reference period is 50 millisecond ++ YES, // The RTL2836 Function 1 enabling status is YES. ++ YES, // The RTL2836 Function 2 enabling status is YES. ++ ++ MXL5007T_BASE_ADDRESS, // The MxL5007T I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // The MxL5007T Crystal frequency is 16.0 MHz. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0 // The MxL5007T clock output amplitude is 0. ++ ); ++ } ++ else ++ { ++ deb_info(" -%s : RTL2836 Unknown tuner on board...\n", __FUNCTION__); ++ goto error; ++ } ++ ++ //Set user defined data pointer of base interface structure for custom basic functions. ++ p_state->pNim2836->pBaseInterface->SetUserDefinedDataPointer(p_state->pNim2836->pBaseInterface, p_state->d ); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ ++ return 0; ++ ++error: ++ return 1; ++ ++} ++ ++ ++static int ++build_2840_nim_module( ++ struct rtl2832_state* p_state) ++{ ++ ++ MT2063_EXTRA_MODULE *p_mt2063_extra; ++ TUNER_MODULE *pTuner; ++ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ if( p_state->tuner_type == RTL2832_TUNER_TYPE_MT2063) ++ { ++ ++ BuildRtl2840Mt2063Module( ++ &p_state->pNim2840, ++ &p_state->QamNimModuleMemory, ++ IF_FREQ_36125000HZ, // The RTL2840 and MT2063 IF frequency is 36.125 MHz. ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2840_DEMOD_ADDR, // The RTL2840 I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2840 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2840 TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM, // Use AM-hum enhancement mode. ++ ++ MT2063_TUNER_ADDR // The MT2063 I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ // Get MT2063 tuner extra module. ++ pTuner = p_state->pNim2840->pTuner; ++ p_mt2063_extra = &(pTuner->Extra.Mt2063); ++ ++ if(p_mt2063_extra->OpenHandle(pTuner)) ++ deb_info("%s : MT2063 Open Handle Failed....\n", __FUNCTION__); ++ ++ p_state->is_mt2063_nim_module_built = 1; ++ ++ deb_info(" %s BuildRtl2840Mt2063Module\n", __FUNCTION__); ++ } ++ else if ( p_state->tuner_type == RTL2832_TUNER_TYPE_MAX3543) ++ { ++ // Build RTL2840 MAX3543 NIM module. ++ BuildRtl2840Max3543Module( ++ &p_state->pNim2840, ++ &p_state->QamNimModuleMemory, ++ ++ 2, // Maximum I2C reading byte number is 2. ++ 2, // Maximum I2C writing byte number is 2. ++ custom_i2c_read, // Employ CustomI2cRead() as basic I2C reading function. ++ custom_i2c_write, // Employ CustomI2cWrite() as basic I2C writing function. ++ custom_wait_ms, // Employ CustomWaitMs() as basic waiting function. ++ ++ RTL2840_DEMOD_ADDR, // The RTL2840 I2C device address is 0x44 in 8-bit format. ++ CRYSTAL_FREQ_28800000HZ, // The RTL2840 crystal frequency is 28.8 MHz. ++ TS_INTERFACE_SERIAL, // The RTL2840 TS interface mode is serial. ++ QAM_DEMOD_EN_AM_HUM, // Use AM-hum enhancement mode. ++ ++ MAX3543_TUNER_ADDR, // The MAX3543 I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ // The MAX3543 Crystal frequency is 16.0 MHz. ++ ); ++ deb_info(" %s BuildRtl2840Max3543Module\n", __FUNCTION__); ++ } ++ else ++ { ++ deb_info(" -%s : RTL2840 Unknown tuner on board...\n", __FUNCTION__); ++ goto error; ++ } ++ ++ //Set user defined data pointer of base interface structure for custom basic functions. ++ p_state->pNim2840->pBaseInterface->SetUserDefinedDataPointer(p_state->pNim2840->pBaseInterface, p_state->d ); ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++ ++static int ++build_nim_module( ++ struct rtl2832_state* p_state) ++{ ++ deb_info(" +%s\n", __FUNCTION__); ++ ++ switch(p_state->demod_type) ++ { ++ case RTL2832: ++ // Build 2832 nim module ++ build_2832_nim_module(p_state); ++ break; ++ ++ case RTL2836: ++ // Build 2836 nim module ++ build_2832_nim_module(p_state); ++ build_2836_nim_module(p_state); ++ break; ++ ++ case RTL2840: ++ //Build 2840 nim module ++ build_2832_nim_module(p_state); ++ build_2840_nim_module(p_state); ++ break; ++ } ++ ++ deb_info(" -%s\n", __FUNCTION__); ++ return 0; ++} ++ ++ ++ ++ ++ ++ ++int rtl2832_hw_reset(struct rtl2832_state *p_state) ++{ ++ int data; ++ unsigned char tmp; ++ ++ // Demod H/W Reset ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data &= (~BIT5); //set bit5 to 0 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ if ( read_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, &data) ) goto error; ++ data |= BIT5; //set bit5 to 1 ++ if ( write_usb_sys_register(p_state, RTD2831_RMAP_INDEX_SYS_DEMOD_CTL,data) ) goto error; ++ ++ //3 reset page chache to 0 ++ if ( read_demod_register(p_state->d, RTL2832_DEMOD_ADDR, 0, 1, &tmp, 1 ) ) goto error; ++ ++ // delay 5ms ++ platform_wait(5); ++ return 0; ++ ++error: ++ return -1; ++} ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/rtl2832u_fe.h b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_fe.h +--- a/drivers/media/dvb/dvb-usb/rtl2832u_fe.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_fe.h 2016-04-02 19:17:52.124066044 -0300 +@@ -0,0 +1,336 @@ ++ ++#ifndef __RTL2832U_FE_H__ ++#define __RTL2832U_FE_H__ ++ ++#include "nim_rtl2832_tua9001.h" ++#include "nim_rtl2832_mt2266.h" ++#include "nim_rtl2832_fc2580.h" ++#include "nim_rtl2832_mxl5007t.h" ++#include "nim_rtl2832_fc0012.h" ++#include "nim_rtl2832_e4000.h" ++#include "nim_rtl2832_mt2063.h" ++#include "nim_rtl2832_max3543.h" ++#include "nim_rtl2832_tda18272.h" ++#include "nim_rtl2832_fc0013.h" ++#include "nim_rtl2832_r820t.h" ++ ++#include "nim_rtl2836_fc2580.h" ++#include "nim_rtl2836_mxl5007t.h" ++ ++#include "nim_rtl2840_mt2063.h" ++#include "nim_rtl2840_max3543.h" ++ ++#include "rtl2832u_io.h" ++#include ++#include "dvb_frontend.h" ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) || (defined V4L2_VERSION) ++/* all DVB frontend drivers now work directly with the DVBv5 ++ * structure. This warrants that all drivers will be ++ * getting/setting frontend parameters on a consistent way, in ++ * order to avoid copying data from/to the DVBv3 structs ++ * without need. ++ */ ++#define V4L2_ONLY_DVB_V5 ++#endif ++ ++#define UPDATE_FUNC_ENABLE_2840 0 ++#define UPDATE_FUNC_ENABLE_2836 1 ++#define UPDATE_FUNC_ENABLE_2832 1 ++ ++#define UPDATE_PROCEDURE_PERIOD_2836 (HZ/5) //200ms = jiffies*1000/HZ ++#define UPDATE_PROCEDURE_PERIOD_2832 (HZ/5) //200ms ++ ++typedef enum{ ++ RTL2832_TUNER_TYPE_UNKNOWN = 0, ++ RTL2832_TUNER_TYPE_MT2266, ++ RTL2832_TUNER_TYPE_FC2580, ++ RTL2832_TUNER_TYPE_TUA9001, ++ RTL2832_TUNER_TYPE_MXL5007T, ++ RTL2832_TUNER_TYPE_E4000, ++ RTL2832_TUNER_TYPE_FC0012, ++ RTL2832_TUNER_TYPE_FC0013, ++ RTL2832_TUNER_TYPE_MT2063, ++ RTL2832_TUNER_TYPE_MAX3543, ++ RTL2832_TUNER_TYPE_TDA18272, ++ RTL2832_TUNER_TYPE_R820T, ++}RTL2832_TUNER_TYPE; ++ ++typedef enum{ ++ RTK_UNKNOWN = 0, ++ RTK_VIDEO, ++ RTK_AUDIO, ++}RTL2832_WORK_TYPE; ++ ++//3 state of total device ++struct rtl2832_state { ++ struct dvb_frontend frontend; ++#ifndef V4L2_ONLY_DVB_V5 ++ struct dvb_frontend_parameters fep; ++#endif ++ struct dvb_usb_device* d; ++ ++ struct mutex i2c_repeater_mutex; ++ ++ unsigned long current_frequency; ++#ifdef V4L2_ONLY_DVB_V5 ++ unsigned long current_bandwidth_hz; ++#else ++ enum fe_bandwidth current_bandwidth; ++#endif ++ ++ RTL2832_TUNER_TYPE tuner_type; ++ unsigned char is_mt2266_nim_module_built; //3 For close MT handle ++ unsigned char is_mt2063_nim_module_built; //3 For close MT handle ++ ++ ++ //3 DTMB related begin --- ++ unsigned int demod_support_type; ++ unsigned int demod_type; ++ unsigned int demod_ask_type; ++ //3 DTMB related end end --- ++ ++ ++ //3 DVBC related begin --- ++ unsigned char b_rtl2840_power_onoff_once; ++ ++ //3 DVBC related end end --- ++ ++ ++ //3if init() is called, is_initial is true ->check it to see if need to flush work queue ++ unsigned short is_initial; ++ unsigned char is_frequency_valid; ++ ++ unsigned char rtl2832_audio_video_mode; ++ ++ ++#if UPDATE_FUNC_ENABLE_2840 ++ struct delayed_work update2840_procedure_work; ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2836 ++ struct delayed_work update2836_procedure_work; ++#endif ++ ++#if UPDATE_FUNC_ENABLE_2832 ++ struct delayed_work update2832_procedure_work; ++#endif ++ ++ DVBT_NIM_MODULE* pNim;//Nim of 2832 ++ DVBT_NIM_MODULE DvbtNimModuleMemory; ++ ++ //3 DTMB related begin --- ++ DTMB_NIM_MODULE* pNim2836;//Nim of 2836 ++ DTMB_NIM_MODULE DtmbNimModuleMemory; ++ //3DTMB related end --- ++ ++ //3 DVBC related begin --- ++ QAM_NIM_MODULE* pNim2840;//Nim of 2840 ++ QAM_NIM_MODULE QamNimModuleMemory; ++ //3DVBC related end --- ++ ++}; ++ ++ ++ ++ ++#define MT2266_TUNER_ADDR 0xc0 ++#define FC2580_TUNER_ADDR 0xac ++#define TUA9001_TUNER_ADDR 0xc0 ++ ++#define MT2266_OFFSET 0x00 ++#define MT2266_CHECK_VAL 0x85 ++ ++#define FC2580_OFFSET 0x01 ++#define FC2580_CHECK_VAL 0x56 ++ ++#define TUA9001_OFFSET 0x7e ++#define TUA9001_CHECK_VAL 0x2328 ++ ++#define MXL5007T_BASE_ADDRESS 0xc0 ++#define MXL5007T_CHECK_ADDRESS 0xD9 ++#define MXL5007T_CHECK_VALUE 0x14 ++ ++#define FC0012_BASE_ADDRESS 0xc6 ++#define FC0012_CHECK_ADDRESS 0x00 ++#define FC0012_CHECK_VALUE 0xa1 ++ ++#define E4000_BASE_ADDRESS 0xc8 ++#define E4000_CHECK_ADDRESS 0x02 ++#define E4000_CHECK_VALUE 0x40 ++ ++ ++#define MT2063_TUNER_ADDR 0xc0 ++#define MT2063_CHECK_OFFSET 0x00 ++#define MT2063_CHECK_VALUE 0x9e ++#define MT2063_CHECK_VALUE_2 0x9c ++ ++ ++#define MAX3543_TUNER_ADDR 0xc0 ++#define MAX3543_CHECK_OFFSET 0x00 ++#define MAX3543_CHECK_VALUE 0x38 ++#define MAX3543_SHUTDOWN_OFFSET 0x08 ++ ++ ++#define TDA18272_TUNER_ADDR 0xc0 ++#define TDA18272_CHECK_OFFSET 0x00 ++#define TDA18272_CHECK_VALUE1 0xc7 ++#define TDA18272_CHECK_VALUE2 0x60 ++ ++ ++#define FC0013_BASE_ADDRESS 0xc6 ++#define FC0013_CHECK_ADDRESS 0x00 ++#define FC0013_CHECK_VALUE 0xa3 ++#define FC0013_STANDBY_ADDRESS 0x06 ++ ++#define R820T_BASE_ADDRESS 0x34 ++#define R820T_CHECK_ADDRESS 0x00 ++#define R820T_CHECK_VALUE 0x69 ++ ++ ++struct rtl2832_reg_addr{ ++ RegType reg_type; ++ unsigned short reg_addr; ++ int bit_low; ++ int bit_high; ++}; ++ ++ ++ ++typedef enum{ ++ RTD2831_RMAP_INDEX_USB_CTRL_BIT5 =0, ++ RTD2831_RMAP_INDEX_USB_STAT, ++ RTD2831_RMAP_INDEX_USB_EPA_CTL, ++ RTD2831_RMAP_INDEX_USB_SYSCTL, ++ RTD2831_RMAP_INDEX_USB_EPA_CFG, ++ RTD2831_RMAP_INDEX_USB_EPA_MAXPKT, ++ RTD2831_RMAP_INDEX_USB_EPA_FIFO_CFG, ++ ++ RTD2831_RMAP_INDEX_SYS_DEMOD_CTL, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_VAL, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT3, ++ RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT3, ++ RTD2831_RMAP_INDEX_SYS_GPIO_CFG0_BIT67, ++ RTD2831_RMAP_INDEX_SYS_DEMOD_CTL1, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT1, ++ RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT1, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT6, ++ RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT6, ++ RTD2831_RMAP_INDEX_SYS_GPIO_OUTPUT_EN_BIT5, ++ RTD2831_RMAP_INDEX_SYS_GPIO_DIR_BIT5, ++#if 0 ++ RTD2831_RMAP_INDEX_SYS_GPD, ++ RTD2831_RMAP_INDEX_SYS_GPOE, ++ RTD2831_RMAP_INDEX_SYS_GPO, ++ RTD2831_RMAP_INDEX_SYS_SYS_0, ++#endif ++ ++} rtl2832_reg_map_index; ++ ++ ++ ++#define USB_SYSCTL 0x0000 ++#define USB_CTRL 0x0010 ++#define USB_STAT 0x0014 ++#define USB_EPA_CTL 0x0148 ++#define USB_EPA_CFG 0x0144 ++#define USB_EPA_MAXPKT 0x0158 ++#define USB_EPA_FIFO_CFG 0x0160 ++ ++#define DEMOD_CTL 0x0000 ++#define GPIO_OUTPUT_VAL 0x0001 ++#define GPIO_OUTPUT_EN 0x0003 ++#define GPIO_DIR 0x0004 ++#define GPIO_CFG0 0x0007 ++#define GPIO_CFG1 0x0008 ++#define DEMOD_CTL1 0x000b ++ ++ ++ ++ ++ ++ ++#define BIT0 0x00000001 ++#define BIT1 0x00000002 ++#define BIT2 0x00000004 ++#define BIT3 0x00000008 ++#define BIT4 0x00000010 ++#define BIT5 0x00000020 ++#define BIT6 0x00000040 ++#define BIT7 0x00000080 ++#define BIT8 0x00000100 ++#define BIT9 0x00000200 ++#define BIT10 0x00000400 ++#define BIT11 0x00000800 ++#define BIT12 0x00001000 ++#define BIT13 0x00002000 ++#define BIT14 0x00004000 ++#define BIT15 0x00008000 ++#define BIT16 0x00010000 ++#define BIT17 0x00020000 ++#define BIT18 0x00040000 ++#define BIT19 0x00080000 ++#define BIT20 0x00100000 ++#define BIT21 0x00200000 ++#define BIT22 0x00400000 ++#define BIT23 0x00800000 ++#define BIT24 0x01000000 ++#define BIT25 0x02000000 ++#define BIT26 0x04000000 ++#define BIT27 0x08000000 ++#define BIT28 0x10000000 ++#define BIT29 0x20000000 ++#define BIT30 0x40000000 ++#define BIT31 0x80000000 ++ ++ ++/* DTMB related ++ ++typedef enum { ++ PAGE_0 = 0, ++ PAGE_1 = 1, ++ PAGE_2 = 2, ++ PAGE_3 = 3, ++ PAGE_4 = 4, ++ PAGE_5 = 5, ++ PAGE_6 = 6, ++ PAGE_7 = 7, ++ PAGE_8 = 8, ++ PAGE_9 = 9, ++};*/ ++ ++ ++#define SUPPORT_DVBT_MODE 0x01 ++#define SUPPORT_DTMB_MODE 0x02 ++#define SUPPORT_DVBC_MODE 0x04 ++ ++#define INPUT_ADC_LEVEL -8 ++typedef enum { ++ RTL2832 = 0, ++ RTL2836, ++ RTL2840 ++}DEMOD_TYPE; ++ ++ ++ ++static int ++build_nim_module( ++ struct rtl2832_state* p_state); ++ ++ ++int rtl2832_hw_reset(struct rtl2832_state *p_state); ++ ++ ++ ++ ++int rtl2832_read_signal_quality( ++ struct dvb_frontend* fe, ++ u32* quality); ++int ++rtl2832_read_signal_strength( ++ struct dvb_frontend* fe, ++ u16* strength); ++#endif // __RTD2830_PRIV_H__ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/rtl2832u.h b/drivers/drivers/media/dvb/dvb-usb/rtl2832u.h +--- a/drivers/media/dvb/dvb-usb/rtl2832u.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/rtl2832u.h 2016-04-02 19:17:52.116066048 -0300 +@@ -0,0 +1,277 @@ ++ ++#ifndef _RTL2832U_H_ ++#define _RTL2832U_H_ ++ ++ ++ ++#include "dvb-usb.h" ++ ++#ifndef USB_VID_REALTEK ++ #define USB_VID_REALTEK 0x0BDA ++#endif ++#define USB_PID_RTL2832_WARM 0x2832 ++#define USB_PID_RTL2838_WARM 0x2838 ++#define USB_PID_RTL2836_WARM 0x2836 ++#define USB_PID_RTL2839_WARM 0x2839 ++#define USB_PID_RTL2840_WARM 0x2840 ++#define USB_PID_RTL2841_WARM 0x2841 ++#define USB_PID_RTL2834_WARM 0x2834 ++#define USB_PID_RTL2837_WARM 0x2837 ++#define USB_PID_RTL2820_WARM 0x2820 ++#define USB_PID_RTL2821_WARM 0x2821 ++#define USB_PID_RTL2822_WARM 0x2822 ++#define USB_PID_RTL2823_WARM 0x2823 ++#define USB_PID_RTL2810_WARM 0x2810 ++#define USB_PID_RTL2811_WARM 0x2811 ++#define USB_PID_RTL2824_WARM 0x2824 ++#define USB_PID_RTL2825_WARM 0x2825 ++ ++#ifndef USB_VID_DEXATEK ++ #define USB_VID_DEXATEK 0x1D19 ++#endif ++#define USB_PID_DEXATEK_1101 0x1101 ++#define USB_PID_DEXATEK_1102 0x1102 ++#define USB_PID_DEXATEK_1103 0x1103 ++#define USB_PID_DEXATEK_1104 0x1104 ++#define USB_PID_DEXATEK_1105 0x1105 ++#define USB_PID_DEXATEK_1106 0x1106 ++#define USB_PID_DEXATEK_1107 0x1107 ++#define USB_PID_DEXATEK_1108 0x1108 ++#define USB_PID_DEXATEK_2101 0x2101 ++#define USB_PID_DEXATEK_8202 0x8202 ++#define USB_PID_DEXATEK_9201 0x9201 ++#define USB_PID_DEXATEK_3103 0x3103 ++#define USB_PID_DEXATEK_9202 0x9202 ++ ++#ifndef USB_VID_TERRATEC ++ #define USB_VID_TERRATEC 0x0CCD ++#endif ++#define USB_PID_TERRATEC_00A9 0x00A9 ++#define USB_PID_TERRATEC_00B3 0x00B3 ++#define USB_PID_TERRATEC_00D3 0x00D3 ++#define USB_PID_TERRATEC_00D4 0x00D4 ++#define USB_PID_TERRATEC_00E0 0x00E0 ++ ++#ifndef USB_VID_AZUREWAVE_2 ++ #define USB_VID_AZUREWAVE_2 0x13D3 ++#endif ++ #define USB_PID_AZUREWAVE_3234 0x3234 ++ #define USB_PID_AZUREWAVE_3274 0x3274 ++ #define USB_PID_AZUREWAVE_3282 0x3282 ++ ++ ++#ifndef USB_VID_THP ++ #define USB_VID_THP 0x1554 ++#endif ++#define USB_PID_THP_5013 0x5013 ++#define USB_PID_THP_5020 0x5020 ++#define USB_PID_THP_5026 0x5026 ++ ++#ifndef USB_VID_KWORLD_1ST ++ #define USB_VID_KWORLD_1ST 0x1B80 ++#endif ++#define USB_PID_KWORLD_D393 0xD393 ++#define USB_PID_KWORLD_D394 0xD394 ++#define USB_PID_KWORLD_D395 0xD395 ++#define USB_PID_KWORLD_D396 0xD396 ++#define USB_PID_KWORLD_D397 0xD397 ++#define USB_PID_KWORLD_D398 0xD398 ++#define USB_PID_KWORLD_D39A 0xD39A ++#define USB_PID_KWORLD_D39B 0xD39B ++#define USB_PID_KWORLD_D39C 0xD39C ++#define USB_PID_KWORLD_D39E 0xD39E ++#define USB_PID_KWORLD_E77B 0xE77B ++#define USB_PID_KWORLD_D3A1 0xD3A1 ++#define USB_PID_KWORLD_D3A4 0xD3A4 ++#define USB_PID_KWORLD_E41D 0xE41D ++ ++#ifndef USB_VID_GOLDENBRIDGE ++ #define USB_VID_GOLDENBRIDGE 0x1680 ++#endif ++#define USB_PID_GOLDENBRIDGE_WARM 0xA332 ++ ++#ifndef USB_VID_YUAN ++ #define USB_VID_YUAN 0x1164 ++#endif ++#define USB_PID_YUAN_WARM 0x6601 ++#define USB_PID_YUAN_WARM80 0x3280 ++#define USB_PID_YUAN_WARM84 0x3284 ++ ++#ifndef USB_PID_GTEK_WARM_0837 ++ #define USB_PID_GTEK_WARM_0837 0x0837 ++#endif ++#define USB_PID_GTEK_WARM_A803 0xA803 ++#define USB_PID_GTEK_WARM_B803 0xB803 ++#define USB_PID_GTEK_WARM_C803 0xC803 ++#define USB_PID_GTEK_WARM_D803 0xD803 ++#define USB_PID_GTEK_WARM_C280 0xC280 ++#define USB_PID_GTEK_WARM_D286 0xD286 ++#define USB_PID_GTEK_WARM_0139 0x0139 ++#define USB_PID_GTEK_WARM_A683 0xA683 ++ ++#ifndef USB_VID_LEADTEK ++ #define USB_VID_LEADTEK 0x0413 ++#endif ++#define USB_PID_LEADTEK_WARM_1 0x6680 ++#define USB_PID_LEADTEK_WARM_2 0x6F11 ++#define USB_PID_WINFAST_DTV_DONGLE_MINI 0x6a03 ++ ++#ifndef USB_VID_COMPRO ++ #define USB_VID_COMPRO 0x185B ++#endif ++#define USB_PID_COMPRO_WARM_0620 0x0620 ++#define USB_PID_COMPRO_WARM_0630 0x0630 ++#define USB_PID_COMPRO_WARM_0640 0x0640 ++#define USB_PID_COMPRO_WARM_0650 0x0650 ++#define USB_PID_COMPRO_WARM_0680 0x0680 ++#define USB_PID_COMPRO_WARM_9580 0x9580 ++#define USB_PID_COMPRO_WARM_9550 0x9550 ++#define USB_PID_COMPRO_WARM_9540 0x9540 ++#define USB_PID_COMPRO_WARM_9530 0x9530 ++#define USB_PID_COMPRO_WARM_9520 0x9520 ++ ++ ++#define RTD2831_URB_SIZE 4096// 39480 ++#define RTD2831_URB_NUMBER 10 // 4 ++ ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++// remote control ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++ ++//define rtl283u rc register address ++#define IR_RX_BUF 0xFC00 ++#define IR_RX_IE 0xFD00 ++#define IR_RX_IF 0xFD01 ++#define IR_RX_CTRL 0xFD02 ++#define IR_RX_CONFIG 0xFD03 ++#define IR_MAX_DURATION0 0xFD04 ++#define IR_MAX_DURATION1 0xFD05 ++#define IR_IDLE_LEN0 0xFD06 ++#define IR_IDLE_LEN1 0xFD07 ++#define IR_GLITCH_LEN 0xFD08 ++#define IR_RX_BUFFER_CTRL 0xFD09 ++#define IR_RX_BUFFER_DATA 0xFD0A ++#define IR_RX_BC 0xFD0B ++#define IR_RX_CLK 0xFD0C ++#define IR_RX_C_COUNT_L 0xFD0D ++#define IR_RX_C_COUNT_H 0xFD0E ++ ++#define IR_SUSPEND_CTRL 0xFD10 ++#define IR_Err_Tolerance_CTRL 0xFD11 ++#define IR_UNIT_LEN 0xFD12 ++#define IR_Err_Tolerance_LEN 0xFD13 ++#define IR_MAX_H_Tolerance_LEN 0xFD14 ++#define IR_MAX_L_Tolerance_LEN 0xFD15 ++#define IR_MASK_CTRL 0xFD16 ++#define IR_MASK_DATA 0xFD17 ++#define IR_RESUME_MASK_ADDR 0xFD18 ++#define IR_RESUME_MASK_T_LEN 0xFD19 ++ ++#define USB_CTRL 0x0010 ++#define SYS_GPD 0x0004 ++#define SYS_GPOE 0x0003 ++#define SYS_GPO 0x0001 ++#define RC_USE_DEMOD_CTL1 0x000B ++ ++//define use len ++#define LEN_1 0x01 ++#define LEN_2 0x02 ++#define LEN_3 0x03 ++#define LEN_4 0x04 ++ ++ ++ ++//function ++int rtl2832u_remoto_control_initial_setting(struct dvb_usb_device *d); ++#define USB_EPA_CTL 0x0148 ++ ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++//decode control para define ++#define frt0_para1 0x3c ++#define frt0_para2 0x20 ++#define frt0_para3 0x7f ++#define frt0_para4 0x05 ++#define frt0_bits_num 0x80 ++#define frt0_BITS_mask 0x01 ++#define frt0_BITS_mask0 0x00 ++#define frt0_BITS_mask1 0x00 ++#define frt0_BITS_mask2 0x0f ++#define frt0_BITS_mask3 0xff ++ ++#define frt1_para1 0x12 ++#define frt1_para3 0x1a ++#define frt1_para2 0x7f ++#define frt1_para4 0x80 ++#define frt1_para5 0x01 ++#define frt1_para6 0x02 ++#define frt1_bits_num 0x80 ++#define frt1_para_uc_1 0x81 ++#define frt1_para_uc_2 0x82 ++#define frt1_bits_mask0 0x00 ++#define frt1_bits_mask1 0x00 ++#define frt1_bits_mask2 0x7f ++#define frt1_bits_mask3 0xff ++ ++#define frt2_para1 0x0a ++#define frt2_para2 0xFF ++#define frt2_para3 0xb0 ++#define frt2_para4 0xc6 ++#define frt2_para5 0x30 ++#define frt2_para6 0x1b ++#define frt2_para7 0x8f ++#define frt2_para8 0x89 ++#define frt2_para9 0x7f ++#define frt2_para10 0x60 ++#define frt2_para11 0x38 ++#define frt2_para12 0x15 ++#define frt2_bits_num 0x80 ++#define frt2_bits_mask0 0x00 ++#define frt2_bits_mask1 0x00 ++#define frt2_bits_mask2 0xff ++#define frt2_bits_mask3 0xff ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++// remote control ++/////////////////////////////////////////////////////////////////////////////////////////////////////// ++enum protocol_type_for_RT{ ++ RT_RC6=0, ++ RT_RC5, ++ RT_NEC, ++ RT_TEST ++}; ++// op define ++enum OP{ ++ OP_NO =0, ++ OP_AND , ++ OP_OR ++}; ++ ++typedef enum RT_UC_CODE_STATE{ ++ WAITING_6T, ++ WAITING_2T_AFTER_6T, ++ WAITING_NORMAL_BITS ++}RT_UC_CODE_STATE; ++ ++//struct define ++typedef struct RT_rc_set_reg_struct{ ++ u8 type; ++ u16 address; ++ u8 data; ++ u8 op; ++ u8 op_mask; ++}RT_rc_set_reg_struct; ++ ++enum RTL2832U_RC_STATE{ ++ RC_NO_SETTING=0, ++ RC_INSTALL_OK, ++ RC__POLLING_OK, ++ RC_STOP_OK ++}; ++//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++extern struct dvb_frontend * rtl2832u_fe_attach(struct dvb_usb_device *d); ++ ++#endif ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/rtl2832u_io.c b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_io.c +--- a/drivers/media/dvb/dvb-usb/rtl2832u_io.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/rtl2832u_io.c 2016-04-02 19:17:52.124066044 -0300 +@@ -0,0 +1,912 @@ ++ ++ ++#include "rtl2832u_io.h" ++#include ++ ++#define ERROR_TRY_MAX_NUM 4 ++ ++ ++#define DUMMY_PAGE 0x0a ++#define DUMMY_ADDR 0x01 ++ ++ ++ ++void ++platform_wait( ++ unsigned long nMinDelayTime) ++{ ++ // The unit of Sleep() waiting time is millisecond. ++ unsigned long usec; ++ do { ++ usec = (nMinDelayTime > 8000) ? 8000 : nMinDelayTime; ++ msleep(usec); ++ nMinDelayTime -= usec; ++ } while (nMinDelayTime > 0); ++ ++ return; ++ ++} ++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++// remote control ++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++static int ++read_rc_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ offset, /* USB message value */ ++ 0x0201, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info(" error try rc read register %s: offset=0x%x, error code=0x%x !\n", __FUNCTION__, offset, ret); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++ ++ ++static int ++write_rc_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ offset, /* USB message value */ ++ 0x0211, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try rc write register = %d, %s: offset=0x%x, error code=0x%x !\n",try_num ,__FUNCTION__, offset, ret); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++error: ++ return 1; ++ } ++ ++ ++int ++read_rc_char_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned char* buf, ++ unsigned short byte_num) ++{ ++ int ret = 1; ++ ++ if( byte_num != 1 && byte_num !=2 && byte_num !=4 && byte_num != 0x80) ++ { ++ deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num); ++ return 1; ++ } ++ ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) return 1; ++ ++ if (type == RTD2832U_RC ) ++ ret = read_rc_register( dib , byte_addr , buf , byte_num); ++ else ++ { ++ deb_info("error!! %s: erroe register type \n", __FUNCTION__); ++ return 1; ++ } ++ mutex_unlock(&dib->usb_mutex); ++ ++ return ret; ++ ++} ++ ++ ++ ++int ++write_rc_char_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned char* buf, ++ unsigned short byte_num) ++{ ++ int ret = 1; ++ ++ if( byte_num != 1 && byte_num !=2 && byte_num !=4 && byte_num !=0x80) ++ { ++ deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num); ++ return 1; ++ } ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) return 1; ++ ++ if (type == RTD2832U_RC ) ++ ret = write_rc_register( dib , byte_addr , buf , byte_num); ++ else ++ { ++ deb_info("error!! %s: erroe register type \n", __FUNCTION__); ++ ret=1; ++ } ++ mutex_unlock(&dib->usb_mutex); ++ ++ return ret; ++ ++} ++ ++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ++static int ++read_usb_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ (USB_BASE_ADDRESS<<8) + offset, /* USB message value */ ++ 0x0100, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info(" %s: offset=0x%x, error code=0x%x !\n", __FUNCTION__, offset, ret); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++ ++ ++static int ++write_usb_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ (USB_BASE_ADDRESS<<8) + offset, /* USB message value */ ++ 0x0110, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try = %d, %s: offset=0x%x, error code=0x%x !\n",try_num ,__FUNCTION__, offset, ret); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++error: ++ return 1; ++ } ++ ++ ++ ++ ++static int ++read_sys_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ (SYS_BASE_ADDRESS<<8) + offset, /* USB message value */ ++ 0x0200, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info(" %s: offset=0x%x, error code=0x%x !\n", __FUNCTION__, offset, ret); ++ return 1; ++ } ++ ++ return 0; ++ ++ } ++ ++ ++static int ++write_sys_register( ++ struct dvb_usb_device* dib, ++ unsigned short offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ (SYS_BASE_ADDRESS<<8) + offset, /* USB message value */ ++ 0x0210, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ if (ret != bytelength) ++ { ++ deb_info(" error try= %d, %s: offset=0x%x, error code=0x%x !\n",try_num, __FUNCTION__, offset, ret); ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++error: ++ return 1; ++ } ++ ++ ++ ++ ++int ++read_demod_register( ++ struct dvb_usb_device*dib, ++ unsigned char demod_device_addr, ++ unsigned char page, ++ unsigned char offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ int i; ++ unsigned char tmp; ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ demod_device_addr + (offset<<8), /* USB message value */ ++ (0x0000 + page), /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ ++ usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ RTL2832_DEMOD_ADDR + (DUMMY_ADDR<<8), /* USB message value */ ++ (0x0000 + DUMMY_PAGE), /* USB message index value */ ++ &tmp, /* pointer to the receive buffer */ ++ LEN_1_BYTE, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ ++ // deb_info("%s[1345]: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(", __FUNCTION__, ret, demod_device_addr, bytelength,page, offset); ++// for(i = 0; i < bytelength; i++) ++// deb_info("0x%x,", data[i]); ++// deb_info(")\n"); ++ ++ if (ret != bytelength) ++ { ++ deb_info("error!! %s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(", __FUNCTION__, ret, demod_device_addr, bytelength,page, offset); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data[i]); ++ deb_info(")\n"); ++ ++ goto error; ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++ ++int ++write_demod_register( ++ struct dvb_usb_device*dib, ++ unsigned char demod_device_addr, ++ unsigned char page, ++ unsigned char offset, ++ unsigned char *data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char i, try_num; ++ unsigned char tmp; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ demod_device_addr + (offset<<8), /* USB message value */ ++ (0x0010 + page), /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ ++ usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ RTL2832_DEMOD_ADDR + (DUMMY_ADDR<<8), /* USB message value */ ++ (0x0000 + DUMMY_PAGE), /* USB message index value */ ++ &tmp, /* pointer to the receive buffer */ ++ LEN_1_BYTE, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++// deb_info("%s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(", __FUNCTION__, ret, demod_device_addr, bytelength, page,offset); ++// for(i = 0; i < bytelength; i++) ++// deb_info("0x%x,", data[i]); ++// deb_info(")\n"); ++ ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try = %d!! %s: ret=%d, DA=0x%x, len=%d, page=%d, offset=0x%x, data=(",try_num , __FUNCTION__, ret, demod_device_addr, bytelength,page,offset); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data[i]); ++ deb_info(")\n"); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++ } ++ ++ ++ ++ ++ ++ ++int ++read_rtl2832_tuner_register( ++ struct dvb_usb_device *dib, ++ unsigned char device_address, ++ unsigned char offset, ++ unsigned char *data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ int i; ++ unsigned char data_tmp[128]; ++ ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ device_address+(offset<<8), /* USB message value */ ++ 0x0300, /* USB message index value */ ++ data_tmp, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++// deb_info("%s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(", __FUNCTION__, ret, device_address, bytelength,offset); ++// for(i = 0; i < bytelength; i++) ++// deb_info("0x%x,", data_tmp[i]); ++// deb_info(")\n"); ++ ++ if (ret != bytelength) ++ { ++ deb_info("error!! %s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(", __FUNCTION__, ret, device_address, bytelength,offset); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data_tmp[i]); ++ deb_info(")\n"); ++ ++ goto error; ++ } ++ ++ memcpy(data,data_tmp,bytelength); ++ ++ return 0; ++ ++error: ++ return 1; ++ ++ ++} ++ ++int write_rtl2832_tuner_register( ++ struct dvb_usb_device *dib, ++ unsigned char device_address, ++ unsigned char offset, ++ unsigned char *data, ++ unsigned short bytelength) ++{ ++ int ret = -ENOMEM; ++ unsigned char i, try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num++; ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ device_address+(offset<<8), /* USB message value */ ++ 0x0310, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++// deb_info("%s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(", __FUNCTION__, ret, device_address, bytelength, offset); ++// for(i = 0; i < bytelength; i++) ++// deb_info("0x%x,", data[i]); ++// deb_info(")\n"); ++ ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try= %d!! %s: ret=%d, DA=0x%x, len=%d, offset=0x%x, data=(",try_num, __FUNCTION__, ret, device_address, bytelength, offset); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data[i]); ++ deb_info(")\n"); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++ } ++ ++ ++ ++ ++int ++read_rtl2832_stdi2c( ++ struct dvb_usb_device* dib, ++ unsigned short dev_i2c_addr, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int i; ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ unsigned char data_tmp[128]; ++ ++ try_num = 0; ++error_write_again: ++ try_num ++; ++ ++ ++ if(bytelength >= 128) ++ { ++ deb_info("%s error bytelength >=128 \n", __FUNCTION__); ++ goto error; ++ } ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_rcvctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_IN, /* USB message request type value */ ++ dev_i2c_addr, /* USB message value */ ++ 0x0600, /* USB message index value */ ++ data_tmp, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try= %d!! %s: ret=%d, DA=0x%x, len=%d, data=(",try_num, __FUNCTION__, ret, dev_i2c_addr, bytelength); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data_tmp[i]); ++ deb_info(")\n"); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ } ++ ++ memcpy(data,data_tmp,bytelength); ++ ++ return 0; ++error: ++ return 1; ++ ++} ++ ++ ++ ++int ++write_rtl2832_stdi2c( ++ struct dvb_usb_device* dib, ++ unsigned short dev_i2c_addr, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ int i; ++ int ret = -ENOMEM; ++ unsigned char try_num; ++ ++ try_num = 0; ++error_write_again: ++ try_num ++; ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) goto error; ++ ++ ret = usb_control_msg(dib->udev, /* pointer to device */ ++ usb_sndctrlpipe( dib->udev,RTL2832_CTRL_ENDPOINT), /* pipe to control endpoint */ ++ 0, /* USB message request value */ ++ SKEL_VENDOR_OUT, /* USB message request type value */ ++ dev_i2c_addr, /* USB message value */ ++ 0x0610, /* USB message index value */ ++ data, /* pointer to the receive buffer */ ++ bytelength, /* length of the buffer */ ++ DIBUSB_I2C_TIMEOUT); /* time to wait for the message to complete before timing out */ ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ if (ret != bytelength) ++ { ++ deb_info("error try= %d!! %s: ret=%d, DA=0x%x, len=%d, data=(",try_num, __FUNCTION__, ret, dev_i2c_addr, bytelength); ++ for(i = 0; i < bytelength; i++) ++ deb_info("0x%x,", data[i]); ++ deb_info(")\n"); ++ ++ if( try_num > ERROR_TRY_MAX_NUM ) goto error; ++ else goto error_write_again; ++ ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++ ++} ++ ++ ++ ++ ++ ++ ++//3for return PUCHAR value ++ ++int ++read_usb_sys_char_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned char* buf, ++ unsigned short byte_num) ++{ ++ int ret = 1; ++ ++ if( byte_num != 1 && byte_num !=2 && byte_num !=4) ++ { ++ deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num); ++ return 1; ++ } ++ ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) return 1; ++ ++ if( type == RTD2832U_USB ) ++ { ++ ret = read_usb_register( dib , byte_addr , buf , byte_num); ++ } ++ else if ( type == RTD2832U_SYS ) ++ { ++ ret = read_sys_register( dib , byte_addr , buf , byte_num); ++ } ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ return ret; ++ ++} ++ ++ ++ ++int ++write_usb_sys_char_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned char* buf, ++ unsigned short byte_num) ++{ ++ int ret = 1; ++ ++ if( byte_num != 1 && byte_num !=2 && byte_num !=4) ++ { ++ deb_info("error!! %s: length = %d \n", __FUNCTION__, byte_num); ++ return 1; ++ } ++ ++ if( mutex_lock_interruptible(&dib->usb_mutex) ) return 1; ++ ++ if( type == RTD2832U_USB ) ++ { ++ ret = write_usb_register( dib , byte_addr , buf , byte_num); ++ } ++ else if ( type == RTD2832U_SYS ) ++ { ++ ret = write_sys_register( dib , byte_addr , buf , byte_num); ++ } ++ ++ mutex_unlock(&dib->usb_mutex); ++ ++ return ret; ++ ++} ++ ++ ++//3for return INT value ++int ++read_usb_sys_int_bytes( ++ struct dvb_usb_device* dib, ++ RegType type, ++ unsigned short byte_addr, ++ unsigned short n_bytes, ++ int* p_val) ++{ ++ int i; ++ u8 val[LEN_4_BYTE]; ++ int nbit_shift; ++ ++ *p_val= 0; ++ ++ if (read_usb_sys_char_bytes( dib, type, byte_addr, val , n_bytes)) goto error; ++ ++ for (i= 0; i< n_bytes; i++) ++ { ++ nbit_shift = i<<3 ; ++ *p_val = *p_val + (val[i]<= 0; i--) ++ { ++ nbit_shift= i << 3; ++ u8_val[i] = (val>> nbit_shift) & 0xff; ++ } ++ ++ if( write_usb_sys_char_bytes( dib , type , byte_addr, u8_val , n_bytes) ) goto error; ++ ++ return 0; ++error: ++ return 1; ++} ++ ++ ++ ++int ++write_rtl2836_demod_register( ++ struct dvb_usb_device* dib, ++ unsigned char demod_device_addr, ++ unsigned char page, ++ unsigned char offset, ++ unsigned char *data, ++ unsigned short bytelength) ++{ ++ int i; ++ unsigned char datatmp; ++ int try_num; ++ switch(page) ++ { ++ //3 R/W regitser Once R/W "ONE BYTE" ++ case PAGE_0: ++ case PAGE_1: ++ case PAGE_2: ++ case PAGE_3: ++ case PAGE_4: ++ for(i=0; i= 4) ++ goto error; ++ ++ if(read_demod_register(dib, demod_device_addr, page, offset+i, &datatmp, LEN_1_BYTE)) ++ { ++ try_num++; ++ deb_info("%s fail read\n", __FUNCTION__); ++ goto label_read; ++ } ++ ++ if(datatmp != data[i]) ++ { ++ try_num++; ++ deb_info("%s read != write\n", __FUNCTION__); ++ goto label_write; ++ } ++ } ++ break; ++ ++ default: ++ goto error; ++ break; ++ } ++ ++ return 0; ++ ++error: ++ return 1; ++} ++ ++ ++ ++int ++read_rtl2836_demod_register( ++ struct dvb_usb_device*dib, ++ unsigned char demod_device_addr, ++ unsigned char page, ++ unsigned char offset, ++ unsigned char* data, ++ unsigned short bytelength) ++{ ++ ++ int i; ++ unsigned char tmp; ++ ++ switch(page) ++ { ++ //3 R/W regitser Once R/W "ONE BYTE" ++ case PAGE_0: ++ case PAGE_1: ++ case PAGE_2: ++ case PAGE_3: ++ case PAGE_4: ++ for(i=0; iInitialize(pTuner); ++ ++ ++ // Set tuner parameters. (RF frequency) ++ // Note: In the example, RF frequency is 474 MHz. ++ RfFreqHz = 474000000; ++ ++ pTuner->SetIfFreqHz(pTuner, RfFreqHz); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ // Get tuenr type. ++ // Note: One can find tuner type in MODULE_TYPE enumeration. ++ pTuner->GetTunerType(pTuner, &TunerType); ++ ++ // Get tuner I2C device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get tuner parameters. (RF frequency) ++ pTuner->GetRfFreqHz(pTuner, &RfFreqHz); ++ ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "foundation.h" ++ ++ ++ ++ ++ ++/// tuner module pre-definition ++typedef struct TUNER_MODULE_TAG TUNER_MODULE; ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner type getting function pointer ++ ++One can use TUNER_FP_GET_TUNER_TYPE() to get tuner type. ++ ++ ++@param [in] pTuner The tuner module pointer ++@param [out] pTunerType Pointer to an allocated memory for storing tuner type ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_GET_TUNER_TYPE() with the corresponding function. ++ ++ ++@see TUNER_TYPE ++ ++*/ ++typedef void ++(*TUNER_FP_GET_TUNER_TYPE)( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner I2C device address getting function pointer ++ ++One can use TUNER_FP_GET_DEVICE_ADDR() to get tuner I2C device address. ++ ++ ++@param [in] pTuner The tuner module pointer ++@param [out] pDeviceAddr Pointer to an allocated memory for storing tuner I2C device address ++ ++ ++@retval FUNCTION_SUCCESS Get tuner device address successfully. ++@retval FUNCTION_ERROR Get tuner device address unsuccessfully. ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_GET_DEVICE_ADDR() with the corresponding function. ++ ++*/ ++typedef void ++(*TUNER_FP_GET_DEVICE_ADDR)( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner initializing function pointer ++ ++One can use TUNER_FP_INITIALIZE() to initialie tuner. ++ ++ ++@param [in] pTuner The tuner module pointer ++ ++ ++@retval FUNCTION_SUCCESS Initialize tuner successfully. ++@retval FUNCTION_ERROR Initialize tuner unsuccessfully. ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_INITIALIZE() with the corresponding function. ++ ++*/ ++typedef int ++(*TUNER_FP_INITIALIZE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner RF frequency setting function pointer ++ ++One can use TUNER_FP_SET_RF_FREQ_HZ() to set tuner RF frequency in Hz. ++ ++ ++@param [in] pTuner The tuner module pointer ++@param [in] RfFreqHz RF frequency in Hz for setting ++ ++ ++@retval FUNCTION_SUCCESS Set tuner RF frequency successfully. ++@retval FUNCTION_ERROR Set tuner RF frequency unsuccessfully. ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_SET_RF_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*TUNER_FP_SET_RF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++ ++ ++ ++ ++/** ++ ++@brief Tuner RF frequency getting function pointer ++ ++One can use TUNER_FP_GET_RF_FREQ_HZ() to get tuner RF frequency in Hz. ++ ++ ++@param [in] pTuner The tuner module pointer ++@param [in] pRfFreqHz Pointer to an allocated memory for storing demod RF frequency in Hz ++ ++ ++@retval FUNCTION_SUCCESS Get tuner RF frequency successfully. ++@retval FUNCTION_ERROR Get tuner RF frequency unsuccessfully. ++ ++ ++@note ++ -# Tuner building function will set TUNER_FP_GET_RF_FREQ_HZ() with the corresponding function. ++ ++*/ ++typedef int ++(*TUNER_FP_GET_RF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// TDCG-G052D extra module ++typedef struct TDCGG052D_EXTRA_MODULE_TAG TDCGG052D_EXTRA_MODULE; ++struct TDCGG052D_EXTRA_MODULE_TAG ++{ ++ // TDCG-G052D extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control; ++ unsigned char BandSwitch; ++ unsigned char Auxiliary; ++}; ++ ++ ++ ++ ++ ++// TDCH-G001D extra module ++typedef struct TDCHG001D_EXTRA_MODULE_TAG TDCHG001D_EXTRA_MODULE; ++struct TDCHG001D_EXTRA_MODULE_TAG ++{ ++ // TDCH-G001D extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control; ++ unsigned char BandSwitch; ++ unsigned char Auxiliary; ++}; ++ ++ ++ ++ ++ ++// TDQE3-003A extra module ++#define TDQE3003A_CONTROL_BYTE_NUM 3 ++ ++typedef struct TDQE3003A_EXTRA_MODULE_TAG TDQE3003A_EXTRA_MODULE; ++struct TDQE3003A_EXTRA_MODULE_TAG ++{ ++ // TDQE3-003A extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control[TDQE3003A_CONTROL_BYTE_NUM]; ++}; ++ ++ ++ ++ ++ ++// DCT-7045 extra module ++typedef struct DCT7045_EXTRA_MODULE_TAG DCT7045_EXTRA_MODULE; ++struct DCT7045_EXTRA_MODULE_TAG ++{ ++ // DCT-7045 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control; ++}; ++ ++ ++ ++ ++ ++/// MT2062 extra module ++typedef struct MT2062_EXTRA_MODULE_TAG MT2062_EXTRA_MODULE; ++ ++// MT2062 handle openning function pointer ++typedef int ++(*MT2062_FP_OPEN_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2062 handle closing function pointer ++typedef int ++(*MT2062_FP_CLOSE_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2062 handle getting function pointer ++typedef void ++(*MT2062_FP_GET_HANDLE)( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++// MT2062 IF frequency setting function pointer ++typedef int ++(*MT2062_FP_SET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long IfFreqHz ++ ); ++ ++// MT2062 IF frequency getting function pointer ++typedef int ++(*MT2062_FP_GET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++// MT2062 extra module ++struct MT2062_EXTRA_MODULE_TAG ++{ ++ // MT2062 extra variables ++ void *DeviceHandle; ++ int LoopThroughMode; ++ ++ unsigned long IfFreqHz; ++ ++ int IsIfFreqHzSet; ++ ++ // MT2062 extra function pointers ++ MT2062_FP_OPEN_HANDLE OpenHandle; ++ MT2062_FP_CLOSE_HANDLE CloseHandle; ++ MT2062_FP_GET_HANDLE GetHandle; ++ MT2062_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ MT2062_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++}; ++ ++ ++ ++ ++ ++/// MxL5005S extra module ++#define INITCTRL_NUM 40 ++#define CHCTRL_NUM 36 ++#define MXLCTRL_NUM 189 ++#define TUNER_REGS_NUM 104 ++ ++typedef struct MXL5005S_EXTRA_MODULE_TAG MXL5005S_EXTRA_MODULE; ++ ++// MXL5005 Tuner Register Struct ++typedef struct _TunerReg_struct ++{ ++ unsigned short Reg_Num ; // Tuner Register Address ++ unsigned short Reg_Val ; // Current sofware programmed value waiting to be writen ++} TunerReg_struct ; ++ ++// MXL5005 Tuner Control Struct ++typedef struct _TunerControl_struct { ++ unsigned short Ctrl_Num ; // Control Number ++ unsigned short size ; // Number of bits to represent Value ++ unsigned short addr[25] ; // Array of Tuner Register Address for each bit position ++ unsigned short bit[25] ; // Array of bit position in Register Address for each bit position ++ unsigned short val[25] ; // Binary representation of Value ++} TunerControl_struct ; ++ ++// MXL5005 Tuner Struct ++typedef struct _Tuner_struct ++{ ++ unsigned char Mode ; // 0: Analog Mode ; 1: Digital Mode ++ unsigned char IF_Mode ; // for Analog Mode, 0: zero IF; 1: low IF ++ unsigned long Chan_Bandwidth ; // filter channel bandwidth (6, 7, 8) ++ unsigned long IF_OUT ; // Desired IF Out Frequency ++ unsigned short IF_OUT_LOAD ; // IF Out Load Resistor (200/300 Ohms) ++ unsigned long RF_IN ; // RF Input Frequency ++ unsigned long Fxtal ; // XTAL Frequency ++ unsigned char AGC_Mode ; // AGC Mode 0: Dual AGC; 1: Single AGC ++ unsigned short TOP ; // Value: take over point ++ unsigned char CLOCK_OUT ; // 0: turn off clock out; 1: turn on clock out ++ unsigned char DIV_OUT ; // 4MHz or 16MHz ++ unsigned char CAPSELECT ; // 0: disable On-Chip pulling cap; 1: enable ++ unsigned char EN_RSSI ; // 0: disable RSSI; 1: enable RSSI ++ unsigned char Mod_Type ; // Modulation Type; ++ // 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable ++ unsigned char TF_Type ; // Tracking Filter Type ++ // 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H ++ ++ // Calculated Settings ++ unsigned long RF_LO ; // Synth RF LO Frequency ++ unsigned long IF_LO ; // Synth IF LO Frequency ++ unsigned long TG_LO ; // Synth TG_LO Frequency ++ ++ // Pointers to ControlName Arrays ++ unsigned short Init_Ctrl_Num ; // Number of INIT Control Names ++ TunerControl_struct Init_Ctrl[INITCTRL_NUM] ; // INIT Control Names Array Pointer ++ unsigned short CH_Ctrl_Num ; // Number of CH Control Names ++ TunerControl_struct CH_Ctrl[CHCTRL_NUM] ; // CH Control Name Array Pointer ++ unsigned short MXL_Ctrl_Num ; // Number of MXL Control Names ++ TunerControl_struct MXL_Ctrl[MXLCTRL_NUM] ; // MXL Control Name Array Pointer ++ ++ // Pointer to Tuner Register Array ++ unsigned short TunerRegs_Num ; // Number of Tuner Registers ++ TunerReg_struct TunerRegs[TUNER_REGS_NUM] ; // Tuner Register Array Pointer ++} Tuner_struct ; ++ ++// MxL5005S register setting function pointer ++typedef int ++(*MXL5005S_FP_SET_REGS_WITH_TABLE)( ++ TUNER_MODULE *pTuner, ++ unsigned char *pAddrTable, ++ unsigned char *pByteTable, ++ int TableLen ++ ); ++ ++// MxL5005S register mask bits setting function pointer ++typedef int ++(*MXL5005S_FP_SET_REG_MASK_BITS)( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned char WritingValue ++ ); ++ ++// MxL5005S spectrum mode setting function pointer ++typedef int ++(*MXL5005S_FP_SET_SPECTRUM_MODE)( ++ TUNER_MODULE *pTuner, ++ int SpectrumMode ++ ); ++ ++// MxL5005S bandwidth setting function pointer ++typedef int ++(*MXL5005S_FP_SET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++// MxL5005S extra module ++struct MXL5005S_EXTRA_MODULE_TAG ++{ ++ // MxL5005S function pointers ++ MXL5005S_FP_SET_REGS_WITH_TABLE SetRegsWithTable; ++ MXL5005S_FP_SET_REG_MASK_BITS SetRegMaskBits; ++ MXL5005S_FP_SET_SPECTRUM_MODE SetSpectrumMode; ++ MXL5005S_FP_SET_BANDWIDTH_HZ SetBandwidthHz; ++ ++ ++ // MxL5005S extra data ++ unsigned char AgcMasterByte; // Variable name in MaxLinear source code: AGC_MASTER_BYTE ++ ++ // MaxLinear defined struct ++ Tuner_struct MxlDefinedTunerStructure; ++}; ++ ++ ++ ++ ++ ++// TDVM-H715P extra module ++typedef struct TDVMH715P_EXTRA_MODULE_TAG TDVMH751P_EXTRA_MODULE; ++struct TDVMH715P_EXTRA_MODULE_TAG ++{ ++ // TDVM-H715P extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control; ++ unsigned char BandSwitch; ++ unsigned char Auxiliary; ++}; ++ ++ ++ ++ ++ ++// UBA00AL extra module ++typedef struct UBA00AL_EXTRA_MODULE_TAG UBA00AL_EXTRA_MODULE; ++struct UBA00AL_EXTRA_MODULE_TAG ++{ ++ // UBA00AL extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char BandSwitch; ++ unsigned char Control2; ++}; ++ ++ ++ ++ ++ ++/// MT2266 extra module ++typedef struct MT2266_EXTRA_MODULE_TAG MT2266_EXTRA_MODULE; ++ ++// MT2266 handle openning function pointer ++typedef int ++(*MT2266_FP_OPEN_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2266 handle closing function pointer ++typedef int ++(*MT2266_FP_CLOSE_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2266 handle getting function pointer ++typedef void ++(*MT2266_FP_GET_HANDLE)( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++// MT2266 bandwidth setting function pointer ++typedef int ++(*MT2266_FP_SET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++// MT2266 bandwidth getting function pointer ++typedef int ++(*MT2266_FP_GET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++// MT2266 extra module ++struct MT2266_EXTRA_MODULE_TAG ++{ ++ // MT2266 extra variables ++ void *DeviceHandle; ++ unsigned long BandwidthHz; ++ int IsBandwidthHzSet; ++ ++ // MT2266 extra function pointers ++ MT2266_FP_OPEN_HANDLE OpenHandle; ++ MT2266_FP_CLOSE_HANDLE CloseHandle; ++ MT2266_FP_GET_HANDLE GetHandle; ++ MT2266_FP_SET_BANDWIDTH_HZ SetBandwidthHz; ++ MT2266_FP_GET_BANDWIDTH_HZ GetBandwidthHz; ++}; ++ ++ ++ ++ ++ ++// FC2580 extra module ++typedef struct FC2580_EXTRA_MODULE_TAG FC2580_EXTRA_MODULE; ++ ++// FC2580 bandwidth mode setting function pointer ++typedef int ++(*FC2580_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// FC2580 bandwidth mode getting function pointer ++typedef int ++(*FC2580_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// FC2580 extra module ++struct FC2580_EXTRA_MODULE_TAG ++{ ++ // FC2580 extra variables ++ unsigned long CrystalFreqHz; ++ int AgcMode; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // FC2580 extra function pointers ++ FC2580_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ FC2580_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++/// TUA9001 extra module ++typedef struct TUA9001_EXTRA_MODULE_TAG TUA9001_EXTRA_MODULE; ++ ++// Extra manipulaing function ++typedef int ++(*TUA9001_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++typedef int ++(*TUA9001_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++typedef int ++(*TUA9001_FP_GET_REG_BYTES_WITH_REG_ADDR)( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte, ++ unsigned char ByteNum ++ ); ++ ++typedef int ++(*TUA9001_FP_SET_SYS_REG_BYTE)( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char WritingByte ++ ); ++ ++typedef int ++(*TUA9001_FP_GET_SYS_REG_BYTE)( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++// TUA9001 extra module ++struct TUA9001_EXTRA_MODULE_TAG ++{ ++ // TUA9001 extra variables ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // TUA9001 extra function pointers ++ TUA9001_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ TUA9001_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++ TUA9001_FP_GET_REG_BYTES_WITH_REG_ADDR GetRegBytesWithRegAddr; ++ TUA9001_FP_SET_SYS_REG_BYTE SetSysRegByte; ++ TUA9001_FP_GET_SYS_REG_BYTE GetSysRegByte; ++}; ++ ++ ++ ++ ++ ++// DTT-75300 extra module ++typedef struct DTT75300_EXTRA_MODULE_TAG DTT75300_EXTRA_MODULE; ++struct DTT75300_EXTRA_MODULE_TAG ++{ ++ // DTT-75300 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++ unsigned char Control4; ++}; ++ ++ ++ ++ ++ ++// MxL5007T extra module ++typedef struct MXL5007T_EXTRA_MODULE_TAG MXL5007T_EXTRA_MODULE; ++ ++// MxL5007 TunerConfig Struct ++typedef struct _MxL5007_TunerConfigS ++{ ++ int I2C_Addr; ++ int Mode; ++ int IF_Diff_Out_Level; ++ int Xtal_Freq; ++ int IF_Freq; ++ int IF_Spectrum; ++ int ClkOut_Setting; ++ int ClkOut_Amp; ++ int BW_MHz; ++ unsigned int RF_Freq_Hz; ++ ++ // Additional definition ++ TUNER_MODULE *pTuner; ++ ++} MxL5007_TunerConfigS; ++ ++// MxL5007T bandwidth mode setting function pointer ++typedef int ++(*MXL5007T_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// MxL5007T bandwidth mode getting function pointer ++typedef int ++(*MXL5007T_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// MxL5007T extra module ++struct MXL5007T_EXTRA_MODULE_TAG ++{ ++ // MxL5007T extra variables ++ int LoopThroughMode; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // MxL5007T MaxLinear-defined structure ++ MxL5007_TunerConfigS *pTunerConfigS; ++ MxL5007_TunerConfigS TunerConfigSMemory; ++ ++ // MxL5007T extra function pointers ++ MXL5007T_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ MXL5007T_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// VA1T1ED6093 extra module ++typedef struct VA1T1ED6093_EXTRA_MODULE_TAG VA1T1ED6093_EXTRA_MODULE; ++struct VA1T1ED6093_EXTRA_MODULE_TAG ++{ ++ // VA1T1ED6093 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++/// TUA8010 extra module ++typedef struct TUA8010_EXTRA_MODULE_TAG TUA8010_EXTRA_MODULE; ++ ++// Extra manipulaing function ++typedef int ++(*TUA8010_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++typedef int ++(*TUA8010_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++typedef int ++(*TUA8010_FP_GET_REG_BYTES_WITH_REG_ADDR)( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte, ++ unsigned char ByteNum ++ ); ++ ++// TUA8010 extra module ++struct TUA8010_EXTRA_MODULE_TAG ++{ ++ // TUA8010 extra variables ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // TUA8010 extra function pointers ++ TUA8010_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ TUA8010_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++ TUA8010_FP_GET_REG_BYTES_WITH_REG_ADDR GetRegBytesWithRegAddr; ++}; ++ ++ ++ ++ ++ ++// E4000 extra module ++typedef struct E4000_EXTRA_MODULE_TAG E4000_EXTRA_MODULE; ++ ++// E4000 register byte getting function pointer ++typedef int ++(*E4000_FP_GET_REG_BYTE)( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++// E4000 bandwidth Hz setting function pointer ++typedef int ++(*E4000_FP_SET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++// E4000 bandwidth Hz getting function pointer ++typedef int ++(*E4000_FP_GET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++// E4000 extra module ++struct E4000_EXTRA_MODULE_TAG ++{ ++ // E4000 extra variables ++ unsigned long CrystalFreqHz; ++ int BandwidthHz; ++ int IsBandwidthHzSet; ++ ++ // E4000 extra function pointers ++ E4000_FP_GET_REG_BYTE GetRegByte; ++ E4000_FP_SET_BANDWIDTH_HZ SetBandwidthHz; ++ E4000_FP_GET_BANDWIDTH_HZ GetBandwidthHz; ++}; ++ ++ ++ ++ ++ ++// E4005 extra module ++typedef struct E4005_EXTRA_MODULE_TAG E4005_EXTRA_MODULE; ++ ++// E4005 extra module ++struct E4005_EXTRA_MODULE_TAG ++{ ++ // E4005 extra variables ++ unsigned int TunerIfFreq; ++ unsigned int TunerIfMode; ++ unsigned int BandwidthHz; ++ unsigned int CrystalFreqHz; ++ unsigned int IsBandwidthHzSet; ++ unsigned int TunerGainMode; ++ unsigned int TunerCoding; ++}; ++ ++ ++ ++ ++ ++// DCT-70704 extra module ++typedef struct DCT70704_EXTRA_MODULE_TAG DCT70704_EXTRA_MODULE; ++struct DCT70704_EXTRA_MODULE_TAG ++{ ++ // DCT-70704 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char BandSwitch; ++ unsigned char Control2; ++}; ++ ++ ++ ++ ++ ++/// MT2063 extra module ++typedef struct MT2063_EXTRA_MODULE_TAG MT2063_EXTRA_MODULE; ++ ++// MT2063 handle openning function pointer ++typedef int ++(*MT2063_FP_OPEN_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2063 handle closing function pointer ++typedef int ++(*MT2063_FP_CLOSE_HANDLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// MT2063 handle getting function pointer ++typedef void ++(*MT2063_FP_GET_HANDLE)( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++// MT2063 IF frequency setting function pointer ++typedef int ++(*MT2063_FP_SET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long IfFreqHz ++ ); ++ ++// MT2063 IF frequency getting function pointer ++typedef int ++(*MT2063_FP_GET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++// MT2063 bandwidth setting function pointer ++typedef int ++(*MT2063_FP_SET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++// MT2063 bandwidth getting function pointer ++typedef int ++(*MT2063_FP_GET_BANDWIDTH_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++// MT2063 extra module ++struct MT2063_EXTRA_MODULE_TAG ++{ ++ // MT2063 extra variables ++ void *DeviceHandle; ++ int StandardMode; ++ unsigned long VgaGc; ++ ++ unsigned long IfFreqHz; ++ unsigned long BandwidthHz; ++ ++ int IsIfFreqHzSet; ++ int IsBandwidthHzSet; ++ ++ // MT2063 extra function pointers ++ MT2063_FP_OPEN_HANDLE OpenHandle; ++ MT2063_FP_CLOSE_HANDLE CloseHandle; ++ MT2063_FP_GET_HANDLE GetHandle; ++ MT2063_FP_SET_IF_FREQ_HZ SetIfFreqHz; ++ MT2063_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++ MT2063_FP_SET_BANDWIDTH_HZ SetBandwidthHz; ++ MT2063_FP_GET_BANDWIDTH_HZ GetBandwidthHz; ++}; ++ ++ ++ ++ ++ ++// FC0012 extra module ++typedef struct FC0012_EXTRA_MODULE_TAG FC0012_EXTRA_MODULE; ++ ++// FC0012 bandwidth mode setting function pointer ++typedef int ++(*FC0012_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// FC0012 bandwidth mode getting function pointer ++typedef int ++(*FC0012_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// FC0012 extra module ++struct FC0012_EXTRA_MODULE_TAG ++{ ++ // FC0012 extra variables ++ unsigned long CrystalFreqHz; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // FC0012 extra function pointers ++ FC0012_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ FC0012_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// TDAG extra module ++typedef struct TDAG_EXTRA_MODULE_TAG TDAG_EXTRA_MODULE; ++struct TDAG_EXTRA_MODULE_TAG ++{ ++ // TDAG extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// ADMTV804 extra module ++typedef struct ADMTV804_EXTRA_MODULE_TAG ADMTV804_EXTRA_MODULE; ++ ++// ADMTV804 standard bandwidth mode setting function pointer ++typedef int ++(*ADMTV804_FP_SET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// ADMTV804 standard bandwidth mode getting function pointer ++typedef int ++(*ADMTV804_FP_GET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// ADMTV804 RF power level getting function pointer ++typedef int ++(*ADMTV804_FP_GET_RF_POWER_LEVEL)( ++ TUNER_MODULE *pTuner, ++ long *pRfPowerLevel ++ ); ++ ++// ADMTV804 extra module ++struct ADMTV804_EXTRA_MODULE_TAG ++{ ++ // ADMTV804 extra variables (from ADMTV804 source code) ++ unsigned char REV_INFO; ++ unsigned char g_curBand; ++ unsigned char pddiv3; ++ unsigned char REG24; ++ unsigned char REG2B; ++ unsigned char REG2E; ++ unsigned char REG30; ++ unsigned char REG31; ++ unsigned char REG5A; ++ unsigned char REG61; // V1.6 added ++ ++ // ADMTV804 extra variables ++ unsigned long CrystalFreqHz; ++ int StandardBandwidthMode; ++ int IsStandardBandwidthModeSet; ++ long RfPowerLevel; ++ ++ // ADMTV804 extra function pointers ++ ADMTV804_FP_SET_STANDARD_BANDWIDTH_MODE SetStandardBandwidthMode; ++ ADMTV804_FP_GET_STANDARD_BANDWIDTH_MODE GetStandardBandwidthMode; ++ ADMTV804_FP_GET_RF_POWER_LEVEL GetRfPowerLevel; ++}; ++ ++ ++ ++ ++ ++// MAX3543 extra module ++typedef struct MAX3543_EXTRA_MODULE_TAG MAX3543_EXTRA_MODULE; ++ ++// MAX3543 bandwidth mode setting function pointer ++typedef int ++(*MAX3543_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// MAX3543 bandwidth mode getting function pointer ++typedef int ++(*MAX3543_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// MAX3543 extra module ++struct MAX3543_EXTRA_MODULE_TAG ++{ ++ // MAX3543 extra variables (from MAX3543 source code) ++ unsigned short TFRomCoefs[3][4]; ++ unsigned short denominator; ++ unsigned long fracscale ; ++ unsigned short regs[22]; ++ unsigned short IF_Frequency; ++ ++ int broadcast_standard; ++ int XTALSCALE; ++ int XTALREF; ++ int LOSCALE; ++ ++ ++ // MAX3543 extra variables ++ unsigned long CrystalFreqHz; ++ int StandardMode; ++ unsigned long IfFreqHz; ++ int OutputMode; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // MAX3543 extra function pointers ++ MAX3543_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ MAX3543_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// TDA18272 extra module ++typedef struct TDA18272_EXTRA_MODULE_TAG TDA18272_EXTRA_MODULE; ++ ++// TDA18272 standard bandwidth mode setting function pointer ++typedef int ++(*TDA18272_FP_SET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int StandardBandwidthMode ++ ); ++ ++// TDA18272 standard bandwidth mode getting function pointer ++typedef int ++(*TDA18272_FP_GET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pStandardBandwidthMode ++ ); ++ ++// TDA18272 power mode setting function pointer ++typedef int ++(*TDA18272_FP_SET_POWER_MODE)( ++ TUNER_MODULE *pTuner, ++ int PowerMode ++ ); ++ ++// TDA18272 power mode getting function pointer ++typedef int ++(*TDA18272_FP_GET_POWER_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pPowerMode ++ ); ++ ++// TDA18272 IF frequency getting function pointer ++typedef int ++(*TDA18272_FP_GET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++// TDA18272 extra module ++struct TDA18272_EXTRA_MODULE_TAG ++{ ++ // TDA18272 extra variables ++ unsigned long CrystalFreqHz; ++ int UnitNo; ++ int IfOutputVppMode; ++ int StandardBandwidthMode; ++ int IsStandardBandwidthModeSet; ++ int PowerMode; ++ int IsPowerModeSet; ++ ++ // TDA18272 extra function pointers ++ TDA18272_FP_SET_STANDARD_BANDWIDTH_MODE SetStandardBandwidthMode; ++ TDA18272_FP_GET_STANDARD_BANDWIDTH_MODE GetStandardBandwidthMode; ++ TDA18272_FP_SET_POWER_MODE SetPowerMode; ++ TDA18272_FP_GET_POWER_MODE GetPowerMode; ++ TDA18272_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++}; ++ ++ ++ ++ ++ ++// TDA18250 extra module ++typedef struct TDA18250_EXTRA_MODULE_TAG TDA18250_EXTRA_MODULE; ++ ++// TDA18250 standard bandwidth mode setting function pointer ++typedef int ++(*TDA18250_FP_SET_STANDARD_MODE)( ++ TUNER_MODULE *pTuner, ++ int StandardMode ++ ); ++ ++// TDA18250 standard bandwidth mode getting function pointer ++typedef int ++(*TDA18250_FP_GET_STANDARD_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pStandardMode ++ ); ++ ++// TDA18250 power mode setting function pointer ++typedef int ++(*TDA18250_FP_SET_POWER_STATE)( ++ TUNER_MODULE *pTuner, ++ int PowerState ++ ); ++ ++// TDA18250 power mode getting function pointer ++typedef int ++(*TDA18250_FP_GET_POWER_STATE)( ++ TUNER_MODULE *pTuner, ++ int *pPowerState ++ ); ++ ++// TDA18250 IF frequency getting function pointer ++typedef int ++(*TDA18250_FP_GET_IF_FREQ_HZ)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++// TDA18250 PowerLevel getting function pointer ++typedef int ++(*TDA18250_FP_Get_PowerLevel)( ++ TUNER_MODULE *pTuner, ++ unsigned long *pPowerLevel ++ ); ++ ++// TDA18250 PowerLevel getting function pointer ++typedef int ++(*TDA18250_FP_Reset_AGC)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// TDA18250 extra module ++struct TDA18250_EXTRA_MODULE_TAG ++{ ++ // TDA18250 extra variables ++ unsigned long CrystalFreqHz; ++ int UnitNo; ++ int IfOutputVppMode; ++ int StandardMode; ++ int IsStandardModeSet; ++ int PowerState; ++ int IsPowerStateSet; ++ ++ // TDA18250 extra function pointers ++ TDA18250_FP_SET_STANDARD_MODE SetStandardMode; ++ TDA18250_FP_GET_STANDARD_MODE GetStandardMode; ++ TDA18250_FP_SET_POWER_STATE SetPowerState; ++ TDA18250_FP_GET_POWER_STATE GetPowerState; ++ TDA18250_FP_GET_IF_FREQ_HZ GetIfFreqHz; ++ TDA18250_FP_Get_PowerLevel GetPowerLevel; ++ TDA18250_FP_Reset_AGC ResetAGC; ++}; ++ ++ ++ ++ ++ ++// FC0013 extra module ++typedef struct FC0013_EXTRA_MODULE_TAG FC0013_EXTRA_MODULE; ++ ++// FC0013 bandwidth mode setting function pointer ++typedef int ++(*FC0013_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// FC0013 bandwidth mode getting function pointer ++typedef int ++(*FC0013_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// FC0013 reset IQ LPF BW ++typedef int ++(*FC0013_FP_RC_CAL_RESET)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// FC0013 increase IQ LPF BW ++typedef int ++(*FC0013_FP_RC_CAL_ADD)( ++ TUNER_MODULE *pTuner, ++ int RcValue ++ ); ++ ++// FC0013 extra module ++struct FC0013_EXTRA_MODULE_TAG ++{ ++ // FC0013 extra variables ++ unsigned long CrystalFreqHz; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // FC0013 extra function pointers ++ FC0013_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ FC0013_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++ FC0013_FP_RC_CAL_RESET RcCalReset; ++ FC0013_FP_RC_CAL_ADD RcCalAdd; ++}; ++ ++ ++ ++ ++ ++// VA1E1ED2403 extra module ++typedef struct VA1E1ED2403_EXTRA_MODULE_TAG VA1E1ED2403_EXTRA_MODULE; ++struct VA1E1ED2403_EXTRA_MODULE_TAG ++{ ++ // VA1E1ED2403 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// Avalon extra module ++#define AVALON_RF_REG_MAX_ADDR 0x60 ++#define AVALON_BB_REG_MAX_ADDR 0x4f ++ ++typedef struct _AVALON_CONFIG_STRUCT { ++ double RFChannelMHz; ++ double dIfFrequencyMHz; ++ double f_dac_MHz; ++ int TVStandard; ++} AVALON_CONFIG_STRUCT, *PAVALON_CONFIG_STRUCT; ++ ++typedef struct AVALON_EXTRA_MODULE_TAG AVALON_EXTRA_MODULE; ++ ++// AVALON standard bandwidth mode setting function pointer ++typedef int ++(*AVALON_FP_SET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int StandardBandwidthMode ++ ); ++ ++// AVALON standard bandwidth mode getting function pointer ++typedef int ++(*AVALON_FP_GET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pStandardBandwidthMode ++ ); ++ ++// AVALON extra module ++struct AVALON_EXTRA_MODULE_TAG ++{ ++ // AVALON extra variables (from AVALON source code) ++ unsigned char g_avalon_rf_reg_work_table[AVALON_RF_REG_MAX_ADDR+1]; ++ unsigned char g_avalon_bb_reg_work_table[AVALON_BB_REG_MAX_ADDR+1]; ++ ++ int ++ (*g_avalon_i2c_read_handler)( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char *pReadingBuffer, ++ unsigned short *pByteNum ++ ); ++ ++ int ++ (*g_avalon_i2c_write_handler)( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char *pWritingBuffer, ++ unsigned short *pByteNum ++ ); ++ ++ AVALON_CONFIG_STRUCT AvalonConfig; ++ ++ ++ // AVALON extra variables ++ unsigned char AtvDemodDeviceAddr; ++ unsigned long CrystalFreqHz; ++ unsigned long IfFreqHz; ++ int StandardBandwidthMode; ++ int IsStandardBandwidthModeSet; ++ ++ // AVALON extra function pointers ++ AVALON_FP_SET_STANDARD_BANDWIDTH_MODE SetStandardBandwidthMode; ++ AVALON_FP_GET_STANDARD_BANDWIDTH_MODE GetStandardBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// SutRx201 extra module ++typedef struct SUTRE201_EXTRA_MODULE_TAG SUTRE201_EXTRA_MODULE; ++ ++// SUTRE201 standard bandwidth mode setting function pointer ++typedef int ++(*SUTRE201_FP_SET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int StandardBandwidthMode ++ ); ++ ++// SUTRE201 standard bandwidth mode getting function pointer ++typedef int ++(*SUTRE201_FP_GET_STANDARD_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pStandardBandwidthMode ++ ); ++ ++// SUTRE201 tuner enabling function pointer ++typedef int ++(*SUTRE201_FP_ENABLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// SUTRE201 tuner disabling function pointer ++typedef int ++(*SUTRE201_FP_DISABLE)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// SUTRE201 tuner IF port mode setting function pointer ++typedef int ++(*SUTRE201_FP_SET_IF_PORT_MODE)( ++ TUNER_MODULE *pTuner, ++ int IfPortMode ++ ); ++ ++// SUTRE201 extra module ++struct SUTRE201_EXTRA_MODULE_TAG ++{ ++ // SUTRE201 extra variables ++ unsigned long CrystalFreqHz; ++ unsigned long IfFreqHz; ++ int IfPortMode; ++ int CountryMode; ++ int StandardBandwidthMode; ++ int IsStandardBandwidthModeSet; ++ ++ // SUTRE201 extra function pointers ++ SUTRE201_FP_SET_STANDARD_BANDWIDTH_MODE SetStandardBandwidthMode; ++ SUTRE201_FP_GET_STANDARD_BANDWIDTH_MODE GetStandardBandwidthMode; ++ SUTRE201_FP_ENABLE Enable; ++ SUTRE201_FP_DISABLE Disable; ++ SUTRE201_FP_SET_IF_PORT_MODE SetIfPortMode; ++}; ++ ++ ++ ++ ++ ++// MR1300 extra module ++typedef struct MR1300_EXTRA_MODULE_TAG MR1300_EXTRA_MODULE; ++struct MR1300_EXTRA_MODULE_TAG ++{ ++ // MR1300 extra data ++ unsigned long CrystalFreqHz; ++}; ++ ++ ++ ++ ++ ++// TDAC7 extra module ++typedef struct TDAC7_EXTRA_MODULE_TAG TDAC7_EXTRA_MODULE; ++struct TDAC7_EXTRA_MODULE_TAG ++{ ++ // TDAC7 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// VA1T1ER2094 extra module ++typedef struct VA1T1ER2094_EXTRA_MODULE_TAG VA1T1ER2094_EXTRA_MODULE; ++struct VA1T1ER2094_EXTRA_MODULE_TAG ++{ ++ // VA1T1ER2094 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// TDAC3 extra module ++typedef struct TDAC3_EXTRA_MODULE_TAG TDAC3_EXTRA_MODULE; ++struct TDAC3_EXTRA_MODULE_TAG ++{ ++ // TDAC3 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// RT910 extra module ++#define RT910_INITIAL_TABLE_LENGTH 25 ++typedef struct RT910_EXTRA_MODULE_TAG RT910_EXTRA_MODULE; ++ ++// RT910 bandwidth mode setting function pointer ++typedef int ++(*RT910_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// RT910 bandwidth mode getting function pointer ++typedef int ++(*RT910_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// RT910 extra module ++struct RT910_EXTRA_MODULE_TAG ++{ ++ // RT910 extra variables ++ unsigned long CrystalFreqHz; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ unsigned char RT910RegsMap[RT910_INITIAL_TABLE_LENGTH]; ++ unsigned char RT910BW8MCalib[RT910_INITIAL_TABLE_LENGTH]; // 80MHz for C.F. cali. ++ ++ ++ // RT910 extra function pointers ++ RT910_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ RT910_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++// DTM4C20 extra module ++typedef struct DTM4C20_EXTRA_MODULE_TAG DTM4C20_EXTRA_MODULE; ++struct DTM4C20_EXTRA_MODULE_TAG ++{ ++ // DTM4C20 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// GTFD32 extra module ++typedef struct GTFD32_EXTRA_MODULE_TAG GTFD32_EXTRA_MODULE; ++struct GTFD32_EXTRA_MODULE_TAG ++{ ++ // GTFD32 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// GTLP10 extra module ++typedef struct GTLP10_EXTRA_MODULE_TAG GTLP10_EXTRA_MODULE; ++struct GTLP10_EXTRA_MODULE_TAG ++{ ++ // GTLP10 extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// JSS66T extra module ++typedef struct JSS66T_EXTRA_MODULE_TAG JSS66T_EXTRA_MODULE; ++struct JSS66T_EXTRA_MODULE_TAG ++{ ++ // JSS66T extra data ++ unsigned char DividerMsb; ++ unsigned char DividerLsb; ++ unsigned char Control1; ++ unsigned char Control2; ++ unsigned char Control3; ++}; ++ ++ ++ ++ ++ ++// FC0013B extra module ++typedef struct FC0013B_EXTRA_MODULE_TAG FC0013B_EXTRA_MODULE; ++ ++// FC0013B bandwidth mode setting function pointer ++typedef int ++(*FC0013B_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// FC0013B bandwidth mode getting function pointer ++typedef int ++(*FC0013B_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++// FC0013B reset IQ LPF BW ++typedef int ++(*FC0013B_FP_RC_CAL_RESET)( ++ TUNER_MODULE *pTuner ++ ); ++ ++// FC0013B increase IQ LPF BW ++typedef int ++(*FC0013B_FP_RC_CAL_ADD)( ++ TUNER_MODULE *pTuner, ++ int RcValue ++ ); ++ ++// FC0013B extra module ++struct FC0013B_EXTRA_MODULE_TAG ++{ ++ // FC0013B extra variables ++ unsigned long CrystalFreqHz; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // FC0013B extra function pointers ++ FC0013B_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ FC0013B_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++ FC0013B_FP_RC_CAL_RESET RcCalReset; ++ FC0013B_FP_RC_CAL_ADD RcCalAdd; ++}; ++ ++ ++ ++ ++ ++// MR1500 extra module ++typedef struct MR1500_EXTRA_MODULE_TAG MR1500_EXTRA_MODULE; ++ ++// MR1500 bandwidth mode setting function pointer ++typedef int ++(*MR1500_FP_SET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++// MR1500 bandwidth mode getting function pointer ++typedef int ++(*MR1500_FP_GET_BANDWIDTH_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++struct MR1500_EXTRA_MODULE_TAG ++{ ++ // MR1500 extra data ++ unsigned long CrystalFreqHz; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ // MR1500 extra function pointers ++ MR1500_FP_SET_BANDWIDTH_MODE SetBandwidthMode; ++ MR1500_FP_GET_BANDWIDTH_MODE GetBandwidthMode; ++}; ++ ++ ++ ++ ++ ++ ++ ++// R820T extra module ++typedef struct R820T_EXTRA_MODULE_TAG R820T_EXTRA_MODULE; ++ ++ ++// R820T standard mode setting function pointer ++typedef int ++(*R820T_FP_SET_STANDARD_MODE)( ++ TUNER_MODULE *pTuner, ++ int StandardMode ++ ); ++ ++// R820T standard mode getting function pointer ++typedef int ++(*R820T_FP_GET_STANDARD_MODE)( ++ TUNER_MODULE *pTuner, ++ int *pStandardMode ++ ); ++ ++// R820T standby setting function pointer ++typedef int ++(*R820T_FP_SET_STANDBY)( ++ TUNER_MODULE *pTuner, ++ int LoopThroughType ++ ); ++ ++ ++ ++ ++struct R820T_EXTRA_MODULE_TAG ++{ ++ ++ unsigned char Rafael_Chip; ++ ++ // R820T extra variables ++ unsigned long IfFreqHz; ++ int BandwidthMode; ++ int IsBandwidthModeSet; ++ ++ int StandardMode; ++ int IsStandardModeSet; ++ ++ unsigned long CrystalFreqkHz; ++ ++ // R820T extra function pointers ++ R820T_FP_SET_STANDARD_MODE SetStandardMode; ++ R820T_FP_GET_STANDARD_MODE GetStandardMode; ++ ++ R820T_FP_SET_STANDBY SetStandby; ++ ++}; ++ ++ ++ ++ ++/// Tuner module structure ++struct TUNER_MODULE_TAG ++{ ++ // Private variables ++ int TunerType; ///< Tuner type ++ unsigned char DeviceAddr; ///< Tuner I2C device address ++ unsigned long RfFreqHz; ///< Tuner RF frequency in Hz ++ ++ int IsRfFreqHzSet; ///< Tuner RF frequency in Hz (setting status) ++ ++ union ///< Tuner extra module used by driving module ++ { ++ TDCGG052D_EXTRA_MODULE Tdcgg052d; ++ TDCHG001D_EXTRA_MODULE Tdchg001d; ++ TDQE3003A_EXTRA_MODULE Tdqe3003a; ++ DCT7045_EXTRA_MODULE Dct7045; ++ MT2062_EXTRA_MODULE Mt2062; ++ MXL5005S_EXTRA_MODULE Mxl5005s; ++ TDVMH751P_EXTRA_MODULE Tdvmh751p; ++ UBA00AL_EXTRA_MODULE Uba00al; ++ MT2266_EXTRA_MODULE Mt2266; ++ FC2580_EXTRA_MODULE Fc2580; ++ TUA9001_EXTRA_MODULE Tua9001; ++ DTT75300_EXTRA_MODULE Dtt75300; ++ MXL5007T_EXTRA_MODULE Mxl5007t; ++ VA1T1ED6093_EXTRA_MODULE Va1t1ed6093; ++ TUA8010_EXTRA_MODULE Tua8010; ++ E4000_EXTRA_MODULE E4000; ++ E4005_EXTRA_MODULE E4005; ++ DCT70704_EXTRA_MODULE Dct70704; ++ MT2063_EXTRA_MODULE Mt2063; ++ FC0012_EXTRA_MODULE Fc0012; ++ TDAG_EXTRA_MODULE Tdag; ++ ADMTV804_EXTRA_MODULE Admtv804; ++ MAX3543_EXTRA_MODULE Max3543; ++ TDA18272_EXTRA_MODULE Tda18272; ++ TDA18250_EXTRA_MODULE Tda18250; ++ FC0013_EXTRA_MODULE Fc0013; ++ VA1E1ED2403_EXTRA_MODULE Va1e1ed2403; ++ AVALON_EXTRA_MODULE Avalon; ++ SUTRE201_EXTRA_MODULE Sutre201; ++ MR1300_EXTRA_MODULE Mr1300; ++ TDAC7_EXTRA_MODULE Tdac7; ++ VA1T1ER2094_EXTRA_MODULE Va1t1er2094; ++ TDAC3_EXTRA_MODULE Tdac3; ++ RT910_EXTRA_MODULE Rt910; ++ DTM4C20_EXTRA_MODULE Dtm4c20; ++ GTFD32_EXTRA_MODULE Gtfd32; ++ GTLP10_EXTRA_MODULE Gtlp10; ++ JSS66T_EXTRA_MODULE Jss66t; ++ FC0013B_EXTRA_MODULE Fc0013b; ++ MR1500_EXTRA_MODULE Mr1500; ++ R820T_EXTRA_MODULE R820t; ++ } ++ Extra; ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ///< Base interface module ++ I2C_BRIDGE_MODULE *pI2cBridge; ///< I2C bridge module ++ ++ ++ // Tuner manipulating functions ++ TUNER_FP_GET_TUNER_TYPE GetTunerType; ///< Tuner type getting function pointer ++ TUNER_FP_GET_DEVICE_ADDR GetDeviceAddr; ///< Tuner I2C device address getting function pointer ++ ++ TUNER_FP_INITIALIZE Initialize; ///< Tuner initializing function pointer ++ TUNER_FP_SET_RF_FREQ_HZ SetRfFreqHz; ///< Tuner RF frequency setting function pointer ++ TUNER_FP_GET_RF_FREQ_HZ GetRfFreqHz; ///< Tuner RF frequency getting function pointer ++}; ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_e4000.c b/drivers/drivers/media/dvb/dvb-usb/tuner_e4000.c +--- a/drivers/media/dvb/dvb-usb/tuner_e4000.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_e4000.c 2016-04-02 19:17:52.128066043 -0300 +@@ -0,0 +1,2482 @@ ++/** ++ ++@file ++ ++@brief E4000 tuner module definition ++ ++One can manipulate E4000 tuner through E4000 module. ++E4000 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_e4000.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief E4000 tuner module builder ++ ++Use BuildE4000Module() to build E4000 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to E4000 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr E4000 I2C device address ++@param [in] CrystalFreqHz E4000 crystal frequency in Hz ++@param [in] AgcMode E4000 AGC mode ++ ++ ++@note ++ -# One should call BuildE4000Module() to build E4000 module before using it. ++ ++*/ ++void ++BuildE4000Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ E4000_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_E4000; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = e4000_GetTunerType; ++ pTuner->GetDeviceAddr = e4000_GetDeviceAddr; ++ ++ pTuner->Initialize = e4000_Initialize; ++ pTuner->SetRfFreqHz = e4000_SetRfFreqHz; ++ pTuner->GetRfFreqHz = e4000_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->IsBandwidthHzSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->GetRegByte = e4000_GetRegByte; ++ pExtra->SetBandwidthHz = e4000_SetBandwidthHz; ++ pExtra->GetBandwidthHz = e4000_GetBandwidthHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++e4000_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++e4000_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++e4000_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ E4000_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ // Initialize tuner. ++ // Note: Call E4000 source code functions. ++ if(tunerreset(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(Tunerclock(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(Qpeak(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(DCoffloop(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(GainControlinit(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++e4000_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ E4000_EXTRA_MODULE *pExtra; ++ ++ int RfFreqKhz; ++ int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ // Set tuner RF frequency in KHz. ++ // Note: 1. RfFreqKhz = round(RfFreqHz / 1000) ++ // CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ // 2. Call E4000 source code functions. ++ RfFreqKhz = (int)((RfFreqHz + 500) / 1000); ++ CrystalFreqKhz = (int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(Gainmanual(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(E4000_gain_freq(pTuner, RfFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(PLL(pTuner, CrystalFreqKhz, RfFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(LNAfilter(pTuner, RfFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(freqband(pTuner, RfFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(DCoffLUT(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ if(GainControlauto(pTuner) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++e4000_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get E4000 register byte. ++ ++*/ ++int ++e4000_GetRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ) ++{ ++ // Call I2CReadByte() to read tuner register. ++ if(I2CReadByte(pTuner, NO_USE, RegAddr, pReadingByte) != E4000_I2C_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set E4000 tuner bandwidth. ++ ++*/ ++int ++e4000_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ) ++{ ++ E4000_EXTRA_MODULE *pExtra; ++ ++ int BandwidthKhz; ++ int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ // Set tuner bandwidth Hz. ++ // Note: 1. BandwidthKhz = round(BandwidthHz / 1000) ++ // CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ // 2. Call E4000 source code functions. ++ BandwidthKhz = (int)((BandwidthHz + 500) / 1000); ++ CrystalFreqKhz = (int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(IFfilter(pTuner, BandwidthKhz, CrystalFreqKhz) != E4000_1_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner bandwidth Hz parameter. ++ pExtra->BandwidthHz = BandwidthHz; ++ pExtra->IsBandwidthHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get E4000 tuner bandwidth. ++ ++*/ ++int ++e4000_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ) ++{ ++ E4000_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.E4000); ++ ++ ++ // Get tuner bandwidth Hz from tuner module. ++ if(pExtra->IsBandwidthHzSet != YES) ++ goto error_status_get_tuner_bandwidth_hz; ++ ++ *pBandwidthHz = pExtra->BandwidthHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_hz: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Function (implemeted for E4000) ++int ++I2CReadByte( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, pReadingByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ return E4000_I2C_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return E4000_I2C_FAIL; ++} ++ ++ ++ ++ ++ ++int ++I2CWriteByte( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegAddr, ++ unsigned char WritingByte ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBuffer[0] = RegAddr; ++ WritingBuffer[1] = WritingByte; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return E4000_I2C_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return E4000_I2C_FAIL; ++} ++ ++ ++ ++ ++ ++int ++I2CWriteArray( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegStartAddr, ++ unsigned char ByteNum, ++ unsigned char *pWritingBytes ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i; ++ ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of demod register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + stop_bit ++ WritingBuffer[0] = RegStartAddr; ++ ++ for(i = 0; i < ByteNum; i++) ++ WritingBuffer[LEN_1_BYTE + i] = pWritingBytes[i]; ++ ++ ++ /// Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, ByteNum + LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return E4000_I2C_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return E4000_I2C_FAIL; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Elonics. ++ ++ ++ ++ ++ ++// Elonics source code - E4000_API_rev2_04_realtek.cpp ++ ++ ++//****************************************************************************/ ++// ++// Filename E4000_initialisation.c ++// Revision 2.04 ++// ++// Description: ++// Initialisation script for the Elonics E4000 revC tuner ++// ++// Copyright (c) Elonics Ltd ++// ++// Any software supplied free of charge for use with elonics ++// evaluation kits is supplied without warranty and for ++// evaluation purposes only. Incorporation of any of this ++// code into products for open sale is permitted but only at ++// the user's own risk. Elonics accepts no liability for the ++// integrity of this software whatsoever. ++// ++// ++//****************************************************************************/ ++//#include ++//#include ++// ++// User defined variable definitions ++// ++/* ++int Ref_clk = 26000; // Reference clock frequency(kHz). ++int Freq = 590000; // RF Frequency (kHz) ++int bandwidth = 8000; //RF channel bandwith (kHz) ++*/ ++// ++// API defined variable definitions ++//int VCO_freq; ++//unsigned char writearray[5]; ++//unsigned char read1[1]; ++//int status; ++// ++// ++// function definitions ++// ++/* ++int tunerreset (); ++int Tunerclock(); ++int filtercal(); ++int Qpeak(); ++int PLL(int Ref_clk, int Freq); ++int LNAfilter(int Freq); ++int IFfilter(int bandwidth, int Ref_clk); ++int freqband(int Freq); ++int DCoffLUT(); ++int DCoffloop(); ++int commonmode(); ++int GainControlinit(); ++*/ ++// ++//**************************************************************************** ++// --- Public functions ------------------------------------------------------ ++/****************************************************************************\ ++* Function: tunerreset ++* ++* Detailed Description: ++* The function resets the E4000 tuner. (Register 0x00). ++* ++\****************************************************************************/ ++ ++int tunerreset(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0] = 64; ++ // For dummy I2C command, don't check executing status. ++ status=I2CWriteByte (pTuner, 200,2,writearray[0]); ++ status=I2CWriteByte (pTuner, 200,2,writearray[0]); ++ //printf("\nRegister 0=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte (pTuner, 200,9,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte (pTuner, 200,5,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 7; ++ status=I2CWriteByte (pTuner, 200,0,writearray[0]); ++ //printf("\nRegister 0=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: Tunerclock ++* ++* Detailed Description: ++* The function configures the E4000 clock. (Register 0x06, 0x7a). ++* Function disables the clock - values can be modified to enable if required. ++\****************************************************************************/ ++ ++int Tunerclock(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0] = 0; ++ status=I2CWriteByte(pTuner, 200,6,writearray[0]); ++ //printf("\nRegister 6=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 150; ++ status=I2CWriteByte(pTuner, 200,122,writearray[0]); ++ //printf("\nRegister 7a=%d", writearray[0]); ++ //**Modify commands above with value required if output clock is required, ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: filtercal ++* ++* Detailed Description: ++* Instructs RC filter calibration. (Register 0x7b). ++* ++\****************************************************************************/ ++/* ++int filtercal(TUNER_MODULE *pTuner) ++{ ++ //writearray[0] = 1; ++ //I2CWriteByte (pTuner, 200,123,writearray[0]); ++ //printf("\nRegister 7b=%d", writearray[0]); ++ //return; ++ return E4000_1_SUCCESS; ++} ++*/ ++/****************************************************************************\ ++* Function: Qpeak() ++* ++* Detailed Description: ++* The function configures the E4000 gains. ++* Also sigma delta controller. (Register 0x82). ++* ++\****************************************************************************/ ++ ++int Qpeak(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0] = 1; ++ writearray[1] = 254; ++ status=I2CWriteArray(pTuner, 200,126,2,writearray); ++ //printf("\nRegister 7e=%d", writearray[0]); ++ //printf("\nRegister 7f=%d", writearray[1]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CWriteByte (pTuner, 200,130,0); ++ //printf("\nRegister 82=0"); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CWriteByte (pTuner, 200,36,5); ++ //printf("\nRegister 24=5"); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 32; ++ writearray[1] = 1; ++ status=I2CWriteArray(pTuner, 200,135,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ //printf("\nRegister 87=%d", writearray[0]); ++ //printf("\nRegister 88=%d", writearray[1]); ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: E4000_gain_freq() ++* ++* Detailed Description: ++* The function configures the E4000 gains vs. freq ++* 0xa3 to 0xa7. Also 0x24. ++* ++\****************************************************************************/ ++int E4000_gain_freq(TUNER_MODULE *pTuner, int Freq) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ if (Freq<=350000) ++ { ++ writearray[0] = 0x10; ++ writearray[1] = 0x42; ++ writearray[2] = 0x09; ++ writearray[3] = 0x21; ++ writearray[4] = 0x94; ++ } ++ else if(Freq>=1000000) ++ { ++ writearray[0] = 0x10; ++ writearray[1] = 0x42; ++ writearray[2] = 0x09; ++ writearray[3] = 0x21; ++ writearray[4] = 0x94; ++ } ++ else ++ { ++ writearray[0] = 0x10; ++ writearray[1] = 0x42; ++ writearray[2] = 0x09; ++ writearray[3] = 0x21; ++ writearray[4] = 0x94; ++ } ++ status=I2CWriteArray(pTuner, 200,163,5,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if (Freq<=350000) ++ { ++ writearray[0] = 94; ++ writearray[1] = 6; ++ status=I2CWriteArray(pTuner, 200,159,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteArray(pTuner, 200,136,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ else ++ { ++ writearray[0] = 127; ++ writearray[1] = 7; ++ status=I2CWriteArray(pTuner, 200,159,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 1; ++ status=I2CWriteArray(pTuner, 200,136,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ ++ //printf("\nRegister 9f=%d", writearray[0]); ++ //printf("\nRegister a0=%d", writearray[1]); ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: DCoffloop ++* ++* Detailed Description: ++* Populates DC offset LUT. (Registers 0x2d, 0x70, 0x71). ++* Turns on DC offset LUT and time varying DC offset. ++\****************************************************************************/ ++int DCoffloop(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ //writearray[0]=0; ++ //I2CWriteByte(pTuner, 200,115,writearray[0]); ++ //printf("\nRegister 73=%d", writearray[0]); ++ writearray[0] = 31; ++ status=I2CWriteByte(pTuner, 200,45,writearray[0]); ++ //printf("\nRegister 2d=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 1; ++ writearray[1] = 1; ++ status=I2CWriteArray(pTuner, 200,112,2,writearray); ++ //printf("\nRegister 70=%d", writearray[0]); ++ //printf("\nRegister 71=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: commonmode ++* ++* Detailed Description: ++* Configures common mode voltage. (Registers 0x2f). ++* ++\****************************************************************************/ ++/* ++int commonmode(TUNER_MODULE *pTuner) ++{ ++ //writearray[0] = 0; ++ //I2CWriteByte(Device_address,47,writearray[0]); ++ //printf("\nRegister 0x2fh = %d", writearray[0]); ++ // Sets 550mV. Modify if alternative is desired. ++ return E4000_1_SUCCESS; ++} ++*/ ++/****************************************************************************\ ++* Function: GainControlinit ++* ++* Detailed Description: ++* Configures gain control mode. (Registers 0x1d, 0x1e, 0x1f, 0x20, 0x21, ++* 0x1a, 0x74h, 0x75h). ++* User may wish to modify values depending on usage scenario. ++* Routine configures LNA: autonomous gain control ++* IF PWM gain control. ++* PWM thresholds = default ++* Mixer: switches when LNA gain =7.5dB ++* Sensitivity / Linearity mode: manual switch ++* ++\****************************************************************************/ ++int GainControlinit(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ unsigned char read1[1]; ++ int status; ++ ++ unsigned char sum=255; ++ ++ writearray[0] = 23; ++ status=I2CWriteByte(pTuner, 200,26,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ //printf("\nRegister 1a=%d", writearray[0]); ++ ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 16; ++ writearray[1] = 4; ++ writearray[2] = 26; ++ writearray[3] = 15; ++ writearray[4] = 167; ++ status=I2CWriteArray(pTuner, 200,29,5,writearray); ++ //printf("\nRegister 1d=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 81; ++ status=I2CWriteByte(pTuner, 200,134,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ //printf("\nRegister 86=%d", writearray[0]); ++ ++ //For Realtek - gain control logic ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if(read1[0]<=sum) ++ { ++ sum=read1[0]; ++ } ++ ++ status=I2CWriteByte(pTuner, 200,31,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if(read1[0] <= sum) ++ { ++ sum=read1[0]; ++ } ++ ++ status=I2CWriteByte(pTuner, 200,31,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if(read1[0] <= sum) ++ { ++ sum=read1[0]; ++ } ++ ++ status=I2CWriteByte(pTuner, 200,31,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if(read1[0] <= sum) ++ { ++ sum=read1[0]; ++ } ++ ++ status=I2CWriteByte(pTuner, 200,31,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CReadByte(pTuner, 201,27,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if (read1[0]<=sum) ++ { ++ sum=read1[0]; ++ } ++ ++ writearray[0]=sum; ++ status=I2CWriteByte(pTuner, 200,27,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ //printf("\nRegister 1b=%d", writearray[0]); ++ //printf("\nRegister 1e=%d", writearray[1]); ++ //printf("\nRegister 1f=%d", writearray[2]); ++ //printf("\nRegister 20=%d", writearray[3]); ++ //printf("\nRegister 21=%d", writearray[4]); ++ //writearray[0] = 3; ++ //writearray[1] = 252; ++ //writearray[2] = 3; ++ //writearray[3] = 252; ++ //I2CWriteArray(pTuner, 200,116,4,writearray); ++ //printf("\nRegister 74=%d", writearray[0]); ++ //printf("\nRegister 75=%d", writearray[1]); ++ //printf("\nRegister 76=%d", writearray[2]); ++ //printf("\nRegister 77=%d", writearray[3]); ++ ++ return E4000_1_SUCCESS; ++} ++ ++/****************************************************************************\ ++* Main program ++* ++* ++* ++\****************************************************************************/ ++/* ++int main() ++{ ++ tunerreset (); ++ Tunerclock(); ++ //filtercal(); ++ Qpeak(); ++ //PLL(Ref_clk, Freq); ++ //LNAfilter(Freq); ++ //IFfilter(bandwidth, Ref_clk); ++ //freqband(Freq); ++ //DCoffLUT(); ++ DCoffloop(); ++ //commonmode(); ++ GainControlinit(); ++// system("PAUSE"); ++ return(0); ++} ++*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Elonics source code - frequency_change_rev2.04_realtek.c ++ ++ ++//****************************************************************************/ ++// ++// Filename E4000_freqchangerev2.04.c ++// Revision 2.04 ++// ++// Description: ++// Frequency change script for the Elonics E4000 revB tuner ++// ++// Copyright (c) Elonics Ltd ++// ++// Any software supplied free of charge for use with elonics ++// evaluation kits is supplied without warranty and for ++// evaluation purposes only. Incorporation of any of this ++// code into products for open sale is permitted but only at ++// the user's own risk. Elonics accepts no liability for the ++// integrity of this software whatsoever. ++// ++// ++//****************************************************************************/ ++//#include ++//#include ++// ++// User defined variable definitions ++// ++/* ++int Ref_clk = 20000; // Reference clock frequency(kHz). ++int Freq = 590000; // RF Frequency (kHz) ++int bandwidth = 8; //RF channel bandwith (MHz) ++*/ ++// ++// API defined variable definitions ++//int VCO_freq; ++//unsigned char writearray[5]; ++//unsigned char read1[1]; ++//int E4000_1_SUCCESS; ++//int E4000_1_FAIL; ++//int E4000_I2C_SUCCESS; ++//int status; ++// ++// ++// function definitions ++// ++/* ++int Gainmanual(); ++int PLL(int Ref_clk, int Freq); ++int LNAfilter(int Freq); ++int IFfilter(int bandwidth, int Ref_clk); ++int freqband(int Freq); ++int DCoffLUT(); ++int GainControlauto(); ++*/ ++// ++//**************************************************************************** ++// --- Public functions ------------------------------------------------------ ++/****************************************************************************\ ++//****************************************************************************\ ++* Function: Gainmanual ++* ++* Detailed Description: ++* Sets Gain control to serial interface control. ++* ++\****************************************************************************/ ++int Gainmanual(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0]=0; ++ status=I2CWriteByte(pTuner, 200,26,writearray[0]); ++ //printf("\nRegister 1a=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte (pTuner, 200,9,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte (pTuner, 200,5,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++ ++/****************************************************************************\ ++* Function: PLL ++* ++* Detailed Description: ++* Configures E4000 PLL divider & sigma delta. 0x0d,0x09, 0x0a, 0x0b). ++* ++\****************************************************************************/ ++int PLL(TUNER_MODULE *pTuner, int Ref_clk, int Freq) ++{ ++ int VCO_freq; ++ unsigned char writearray[5]; ++ int status; ++ ++ unsigned char divider; ++ int intVCOfreq; ++ int SigDel; ++ int SigDel2; ++ int SigDel3; ++// int harmonic_freq; ++// int offset; ++ ++ if (Freq<=72400) ++ { ++ writearray[4] = 15; ++ VCO_freq=Freq*48; ++ } ++ else if (Freq<=81200) ++ { ++ writearray[4] = 14; ++ VCO_freq=Freq*40; ++ } ++ else if (Freq<=108300) ++ { ++ writearray[4]=13; ++ VCO_freq=Freq*32; ++ } ++ else if (Freq<=162500) ++ { ++ writearray[4]=12; ++ VCO_freq=Freq*24; ++ } ++ else if (Freq<=216600) ++ { ++ writearray[4]=11; ++ VCO_freq=Freq*16; ++ } ++ else if (Freq<=325000) ++ { ++ writearray[4]=10; ++ VCO_freq=Freq*12; ++ } ++ else if (Freq<=350000) ++ { ++ writearray[4]=9; ++ VCO_freq=Freq*8; ++ } ++ else if (Freq<=432000) ++ { ++ writearray[4]=3; ++ VCO_freq=Freq*8; ++ } ++ else if (Freq<=667000) ++ { ++ writearray[4]=2; ++ VCO_freq=Freq*6; ++ } ++ else if (Freq<=1200000) ++ { ++ writearray[4]=1; ++ VCO_freq=Freq*4; ++ } ++ else ++ { ++ writearray[4]=0; ++ VCO_freq=Freq*2; ++ } ++ ++ //printf("\nVCOfreq=%d", VCO_freq); ++// divider = VCO_freq * 1000 / Ref_clk; ++ divider = VCO_freq / Ref_clk; ++ //printf("\ndivider=%d", divider); ++ writearray[0]= divider; ++// intVCOfreq = divider * Ref_clk /1000; ++ intVCOfreq = divider * Ref_clk; ++ //printf("\ninteger VCO freq=%d", intVCOfreq); ++// SigDel=65536 * 1000 * (VCO_freq - intVCOfreq) / Ref_clk; ++ SigDel=65536 * (VCO_freq - intVCOfreq) / Ref_clk; ++ //printf("\nSigma delta=%d", SigDel); ++ if (SigDel<=1024) ++ { ++ SigDel = 1024; ++ } ++ else if (SigDel>=64512) ++ { ++ SigDel=64512; ++ } ++ SigDel2 = SigDel / 256; ++ //printf("\nSigdel2=%d", SigDel2); ++ writearray[2] = (unsigned char)SigDel2; ++ SigDel3 = SigDel - (256 * SigDel2); ++ //printf("\nSig del3=%d", SigDel3); ++ writearray[1]= (unsigned char)SigDel3; ++ writearray[3]=(unsigned char)0; ++ status=I2CWriteArray(pTuner, 200,9,5,writearray); ++ //printf("\nRegister 9=%d", writearray[0]); ++ //printf("\nRegister a=%d", writearray[1]); ++ //printf("\nRegister b=%d", writearray[2]); ++ //printf("\nRegister d=%d", writearray[4]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ if (Freq<=82900) ++ { ++ writearray[0]=0; ++ writearray[2]=1; ++ } ++ else if (Freq<=89900) ++ { ++ writearray[0]=3; ++ writearray[2]=9; ++ } ++ else if (Freq<=111700) ++ { ++ writearray[0]=0; ++ writearray[2]=1; ++ } ++ else if (Freq<=118700) ++ { ++ writearray[0]=3; ++ writearray[2]=1; ++ } ++ else if (Freq<=140500) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=147500) ++ { ++ writearray[0]=3; ++ writearray[2]=11; ++ } ++ else if (Freq<=169300) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=176300) ++ { ++ writearray[0]=3; ++ writearray[2]=11; ++ } ++ else if (Freq<=198100) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=205100) ++ { ++ writearray[0]=3; ++ writearray[2]=19; ++ } ++ else if (Freq<=226900) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=233900) ++ { ++ writearray[0]=3; ++ writearray[2]=3; ++ } ++ else if (Freq<=350000) ++ { ++ writearray[0]=0; ++ writearray[2]=3; ++ } ++ else if (Freq<=485600) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=493600) ++ { ++ writearray[0]=3; ++ writearray[2]=5; ++ } ++ else if (Freq<=514400) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=522400) ++ { ++ writearray[0]=3; ++ writearray[2]=5; ++ } ++ else if (Freq<=543200) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=551200) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=572000) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=580000) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=600800) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=608800) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=629600) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=637600) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=658400) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=666400) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=687200) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=695200) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=716000) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=724000) ++ { ++ writearray[0]=3; ++ writearray[2]=13; ++ } ++ else if (Freq<=744800) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=752800) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else if (Freq<=773600) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=781600) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else if (Freq<=802400) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=810400) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else if (Freq<=831200) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=839200) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else if (Freq<=860000) ++ { ++ writearray[0]=0; ++ writearray[2]=5; ++ } ++ else if (Freq<=868000) ++ { ++ writearray[0]=3; ++ writearray[2]=21; ++ } ++ else ++ { ++ writearray[0]=0; ++ writearray[2]=7; ++ } ++ ++ status=I2CWriteByte (pTuner, 200,7,writearray[2]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ status=I2CWriteByte (pTuner, 200,5,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++ ++/****************************************************************************\ ++* Function: LNAfilter ++* ++* Detailed Description: ++* The function configures the E4000 LNA filter. (Register 0x10). ++* ++\****************************************************************************/ ++ ++int LNAfilter(TUNER_MODULE *pTuner, int Freq) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ if(Freq<=370000) ++ { ++ writearray[0]=0; ++ } ++ else if(Freq<=392500) ++ { ++ writearray[0]=1; ++ } ++ else if(Freq<=415000) ++ { ++ writearray[0] =2; ++ } ++ else if(Freq<=437500) ++ { ++ writearray[0]=3; ++ } ++ else if(Freq<=462500) ++ { ++ writearray[0]=4; ++ } ++ else if(Freq<=490000) ++ { ++ writearray[0]=5; ++ } ++ else if(Freq<=522500) ++ { ++ writearray[0]=6; ++ } ++ else if(Freq<=557500) ++ { ++ writearray[0]=7; ++ } ++ else if(Freq<=595000) ++ { ++ writearray[0]=8; ++ } ++ else if(Freq<=642500) ++ { ++ writearray[0]=9; ++ } ++ else if(Freq<=695000) ++ { ++ writearray[0]=10; ++ } ++ else if(Freq<=740000) ++ { ++ writearray[0]=11; ++ } ++ else if(Freq<=800000) ++ { ++ writearray[0]=12; ++ } ++ else if(Freq<=865000) ++ { ++ writearray[0] =13; ++ } ++ else if(Freq<=930000) ++ { ++ writearray[0]=14; ++ } ++ else if(Freq<=1000000) ++ { ++ writearray[0]=15; ++ } ++ else if(Freq<=1310000) ++ { ++ writearray[0]=0; ++ } ++ else if(Freq<=1340000) ++ { ++ writearray[0]=1; ++ } ++ else if(Freq<=1385000) ++ { ++ writearray[0]=2; ++ } ++ else if(Freq<=1427500) ++ { ++ writearray[0]=3; ++ } ++ else if(Freq<=1452500) ++ { ++ writearray[0]=4; ++ } ++ else if(Freq<=1475000) ++ { ++ writearray[0]=5; ++ } ++ else if(Freq<=1510000) ++ { ++ writearray[0]=6; ++ } ++ else if(Freq<=1545000) ++ { ++ writearray[0]=7; ++ } ++ else if(Freq<=1575000) ++ { ++ writearray[0] =8; ++ } ++ else if(Freq<=1615000) ++ { ++ writearray[0]=9; ++ } ++ else if(Freq<=1650000) ++ { ++ writearray[0] =10; ++ } ++ else if(Freq<=1670000) ++ { ++ writearray[0]=11; ++ } ++ else if(Freq<=1690000) ++ { ++ writearray[0]=12; ++ } ++ else if(Freq<=1710000) ++ { ++ writearray[0]=13; ++ } ++ else if(Freq<=1735000) ++ { ++ writearray[0]=14; ++ } ++ else ++ { ++ writearray[0]=15; ++ } ++ status=I2CWriteByte (pTuner, 200,16,writearray[0]); ++ //printf("\nRegister 10=%d", writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: IFfilter ++* ++* Detailed Description: ++* The function configures the E4000 IF filter. (Register 0x11,0x12). ++* ++\****************************************************************************/ ++int IFfilter(TUNER_MODULE *pTuner, int bandwidth, int Ref_clk) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ int IF_BW; ++ ++ IF_BW = bandwidth / 2; ++ if(IF_BW<=2150) ++ { ++ writearray[0]=253; ++ writearray[1]=31; ++ } ++ else if(IF_BW<=2200) ++ { ++ writearray[0]=253; ++ writearray[1]=30; ++ } ++ else if(IF_BW<=2240) ++ { ++ writearray[0]=252; ++ writearray[1]=29; ++ } ++ else if(IF_BW<=2280) ++ { ++ writearray[0]=252; ++ writearray[1]=28; ++ } ++ else if(IF_BW<=2300) ++ { ++ writearray[0]=252; ++ writearray[1]=27; ++ } ++ else if(IF_BW<=2400) ++ { ++ writearray[0]=252; ++ writearray[1]=26; ++ } ++ else if(IF_BW<=2450) ++ { ++ writearray[0]=252; ++ writearray[1]=25; ++ } ++ else if(IF_BW<=2500) ++ { ++ writearray[0]=252; ++ writearray[1]=24; ++ } ++ else if(IF_BW<=2550) ++ { ++ writearray[0]=252; ++ writearray[1]=23; ++ } ++ else if(IF_BW<=2600) ++ { ++ writearray[0]=252; ++ writearray[1]=22; ++ } ++ else if(IF_BW<=2700) ++ { ++ writearray[0]=252; ++ writearray[1]=21; ++ } ++ else if(IF_BW<=2750) ++ { ++ writearray[0]=252; ++ writearray[1]=20; ++ } ++ else if(IF_BW<=2800) ++ { ++ writearray[0]=252; ++ writearray[1]=19; ++ } ++ else if(IF_BW<=2900) ++ { ++ writearray[0]=251; ++ writearray[1]=18; ++ } ++ else if(IF_BW<=2950) ++ { ++ writearray[0]=251; ++ writearray[1]=17; ++ } ++ else if(IF_BW<=3000) ++ { ++ writearray[0]=251; ++ writearray[1]=16; ++ } ++ else if(IF_BW<=3100) ++ { ++ writearray[0]=251; ++ writearray[1]=15; ++ } ++ else if(IF_BW<=3200) ++ { ++ writearray[0]=250; ++ writearray[1]=14; ++ } ++ else if(IF_BW<=3300) ++ { ++ writearray[0]=250; ++ writearray[1]=13; ++ } ++ else if(IF_BW<=3400) ++ { ++ writearray[0]=249; ++ writearray[1]=12; ++ } ++ else if(IF_BW<=3600) ++ { ++ writearray[0]=249; ++ writearray[1]=11; ++ } ++ else if(IF_BW<=3700) ++ { ++ writearray[0]=249; ++ writearray[1]=10; ++ } ++ else if(IF_BW<=3800) ++ { ++ writearray[0]=248; ++ writearray[1]=9; ++ } ++ else if(IF_BW<=3900) ++ { ++ writearray[0]=248; ++ writearray[1]=8; ++ } ++ else if(IF_BW<=4100) ++ { ++ writearray[0]=248; ++ writearray[1]=7; ++ } ++ else if(IF_BW<=4300) ++ { ++ writearray[0]=247; ++ writearray[1]=6; ++ } ++ else if(IF_BW<=4400) ++ { ++ writearray[0]=247; ++ writearray[1]=5; ++ } ++ else if(IF_BW<=4600) ++ { ++ writearray[0]=247; ++ writearray[1]=4; ++ } ++ else if(IF_BW<=4800) ++ { ++ writearray[0]=246; ++ writearray[1]=3; ++ } ++ else if(IF_BW<=5000) ++ { ++ writearray[0]=246; ++ writearray[1]=2; ++ } ++ else if(IF_BW<=5300) ++ { ++ writearray[0]=245; ++ writearray[1]=1; ++ } ++ else if(IF_BW<=5500) ++ { ++ writearray[0]=245; ++ writearray[1]=0; ++ } ++ else ++ { ++ writearray[0]=0; ++ writearray[1]=32; ++ } ++ status=I2CWriteArray(pTuner, 200,17,2,writearray); ++ //printf("\nRegister 11=%d", writearray[0]); ++ //printf("\nRegister 12=%d", writearray[1]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: freqband ++* ++* Detailed Description: ++* Configures the E4000 frequency band. (Registers 0x07, 0x78). ++* ++\****************************************************************************/ ++int freqband(TUNER_MODULE *pTuner, int Freq) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ if (Freq<=140000) ++ { ++ writearray[0] = 3; ++ status=I2CWriteByte(pTuner, 200,120,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ else if (Freq<=350000) ++ { ++ writearray[0] = 3; ++ status=I2CWriteByte(pTuner, 200,120,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ else if (Freq<=1000000) ++ { ++ writearray[0] = 3; ++ status=I2CWriteByte(pTuner, 200,120,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ else ++ { ++ writearray[0] = 7; ++ status=I2CWriteByte(pTuner, 200,7,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = 0; ++ status=I2CWriteByte(pTuner, 200,120,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: DCoffLUT ++* ++* Detailed Description: ++* Populates DC offset LUT. (Registers 0x50 - 0x53, 0x60 - 0x63). ++* ++\****************************************************************************/ ++int DCoffLUT(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ unsigned char read1[1]; ++ unsigned char IOFF; ++ unsigned char QOFF; ++ unsigned char RANGE1; ++// unsigned char RANGE2; ++ unsigned char QRANGE; ++ unsigned char IRANGE; ++ writearray[0] = 0; ++ writearray[1] = 126; ++ writearray[2] = 36; ++ status=I2CWriteArray(pTuner, 200,21,3,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Sets mixer & IF stage 1 gain = 00 and IF stg 2+ to max gain. ++ writearray[0] = 1; ++ status=I2CWriteByte(pTuner, 200,41,writearray[0]); ++ // Instructs a DC offset calibration. ++ status=I2CReadByte(pTuner, 201,42,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,43,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ QOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,44,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ RANGE1=read1[0]; ++ //reads DC offset values back ++ if(RANGE1>=32) ++ { ++ RANGE1 = RANGE1 -32; ++ } ++ if(RANGE1>=16) ++ { ++ RANGE1 = RANGE1 - 16; ++ } ++ IRANGE=RANGE1; ++ QRANGE = (read1[0] - RANGE1) / 16; ++ ++ writearray[0] = (IRANGE * 64) + IOFF; ++ status=I2CWriteByte(pTuner, 200,96,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = (QRANGE * 64) + QOFF; ++ status=I2CWriteByte(pTuner, 200,80,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Populate DC offset LUT ++ writearray[0] = 0; ++ writearray[1] = 127; ++ status=I2CWriteArray(pTuner, 200,21,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Sets mixer & IF stage 1 gain = 01 leaving IF stg 2+ at max gain. ++ writearray[0]= 1; ++ status=I2CWriteByte(pTuner, 200,41,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Instructs a DC offset calibration. ++ status=I2CReadByte(pTuner, 201,42,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,43,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ QOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,44,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ RANGE1=read1[0]; ++ // Read DC offset values ++ if(RANGE1>=32) ++ { ++ RANGE1 = RANGE1 -32; ++ } ++ if(RANGE1>=16) ++ { ++ RANGE1 = RANGE1 - 16; ++ } ++ IRANGE = RANGE1; ++ QRANGE = (read1[0] - RANGE1) / 16; ++ ++ writearray[0] = (IRANGE * 64) + IOFF; ++ status=I2CWriteByte(pTuner, 200,97,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = (QRANGE * 64) + QOFF; ++ status=I2CWriteByte(pTuner, 200,81,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Populate DC offset LUT ++ writearray[0] = 1; ++ status=I2CWriteByte(pTuner, 200,21,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Sets mixer & IF stage 1 gain = 11 leaving IF stg 2+ at max gain. ++ writearray[0] = 1; ++ status=I2CWriteByte(pTuner, 200,41,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Instructs a DC offset calibration. ++ status=I2CReadByte(pTuner, 201,42,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,43,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ QOFF=read1[0]; ++ status=I2CReadByte(pTuner, 201,44,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ RANGE1 = read1[0]; ++ // Read DC offset values ++ if(RANGE1>=32) ++ { ++ RANGE1 = RANGE1 -32; ++ } ++ if(RANGE1>=16) ++ { ++ RANGE1 = RANGE1 - 16; ++ } ++ IRANGE = RANGE1; ++ QRANGE = (read1[0] - RANGE1) / 16; ++ writearray[0] = (IRANGE * 64) + IOFF; ++ status=I2CWriteByte(pTuner, 200,99,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = (QRANGE * 64) + QOFF; ++ status=I2CWriteByte(pTuner, 200,83,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Populate DC offset LUT ++ writearray[0] = 126; ++ status=I2CWriteByte(pTuner, 200,22,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Sets mixer & IF stage 1 gain = 11 leaving IF stg 2+ at max gain. ++ writearray[0] = 1; ++ status=I2CWriteByte(pTuner, 200,41,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ // Instructs a DC offset calibration. ++ status=I2CReadByte(pTuner, 201,42,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ IOFF=read1[0]; ++ ++ status=I2CReadByte(pTuner, 201,43,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ QOFF=read1[0]; ++ ++ status=I2CReadByte(pTuner, 201,44,read1); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ RANGE1=read1[0]; ++ ++ // Read DC offset values ++ if(RANGE1>=32) ++ { ++ RANGE1 = RANGE1 -32; ++ } ++ if(RANGE1>=16) ++ { ++ RANGE1 = RANGE1 - 16; ++ } ++ IRANGE = RANGE1; ++ QRANGE = (read1[0] - RANGE1) / 16; ++ ++ writearray[0]=(IRANGE * 64) + IOFF; ++ status=I2CWriteByte(pTuner, 200,98,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ writearray[0] = (QRANGE * 64) + QOFF; ++ status=I2CWriteByte(pTuner, 200,82,writearray[0]); ++ // Populate DC offset LUT ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: GainControlinit ++* ++* Detailed Description: ++* Configures gain control mode. (Registers 0x1a) ++* ++\****************************************************************************/ ++int GainControlauto(TUNER_MODULE *pTuner) ++{ ++ unsigned char writearray[5]; ++ int status; ++ ++ writearray[0] = 23; ++ status=I2CWriteByte(pTuner, 200,26,writearray[0]); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Main program ++* ++* ++* ++\****************************************************************************/ ++/* ++int main() ++{ ++ Gainmanual(); ++ PLL(Ref_clk, Freq); ++ LNAfilter(Freq); ++ IFfilter(bandwidth, Ref_clk); ++ freqband(Freq); ++ DCoffLUT(); ++ GainControlauto(); ++ return(0); ++} ++*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Elonics source code - RT2832_SW_optimisation_rev2.c ++ ++ ++ ++/****************************************************************************\ ++* Function: E4000_sensitivity ++* ++* Detailed Description: ++* The function configures the E4000 for sensitivity mode. ++* ++\****************************************************************************/ ++ ++int E4000_sensitivity(TUNER_MODULE *pTuner, int Freq, int bandwidth) ++{ ++ unsigned char writearray[2]; ++ int status; ++ int IF_BW; ++ ++ if(Freq<=700000) ++ { ++ writearray[0] = 0x07; ++ } ++ else ++ { ++ writearray[0] = 0x05; ++ } ++ status = I2CWriteArray(pTuner,200,36,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IF_BW = bandwidth / 2; ++ if(IF_BW<=2500) ++ { ++ writearray[0]=0xfc; ++ writearray[1]=0x17; ++ } ++ else if(IF_BW<=3000) ++ { ++ writearray[0]=0xfb; ++ writearray[1]=0x0f; ++ } ++ else if(IF_BW<=3500) ++ { ++ writearray[0]=0xf9; ++ writearray[1]=0x0b; ++ } ++ else if(IF_BW<=4000) ++ { ++ writearray[0]=0xf8; ++ writearray[1]=0x07; ++ } ++ status = I2CWriteArray(pTuner,200,17,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: E4000_linearity ++* ++* Detailed Description: ++* The function configures the E4000 for linearity mode. ++* ++\****************************************************************************/ ++int E4000_linearity(TUNER_MODULE *pTuner, int Freq, int bandwidth) ++{ ++ ++ unsigned char writearray[2]; ++ int status; ++ int IF_BW; ++ ++ if(Freq<=700000) ++ { ++ writearray[0] = 0x03; ++ } ++ else ++ { ++ writearray[0] = 0x01; ++ } ++ status = I2CWriteArray(pTuner,200,36,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IF_BW = bandwidth / 2; ++ if(IF_BW<=2500) ++ { ++ writearray[0]=0xfe; ++ writearray[1]=0x19; ++ } ++ else if(IF_BW<=3000) ++ { ++ writearray[0]=0xfd; ++ writearray[1]=0x11; ++ } ++ else if(IF_BW<=3500) ++ { ++ writearray[0]=0xfb; ++ writearray[1]=0x0d; ++ } ++ else if(IF_BW<=4000) ++ { ++ writearray[0]=0xfa; ++ writearray[1]=0x0a; ++ } ++ status = I2CWriteArray(pTuner,200,17,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++/****************************************************************************\ ++* Function: E4000_nominal ++* ++* Detailed Description: ++* The function configures the E4000 for nominal ++* ++\****************************************************************************/ ++int E4000_nominal(TUNER_MODULE *pTuner, int Freq, int bandwidth) ++{ ++ unsigned char writearray[2]; ++ int status; ++ int IF_BW; ++ ++ if(Freq<=700000) ++ { ++ writearray[0] = 0x03; ++ } ++ else ++ { ++ writearray[0] = 0x01; ++ } ++ status = I2CWriteArray(pTuner,200,36,1,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ IF_BW = bandwidth / 2; ++ if(IF_BW<=2500) ++ { ++ writearray[0]=0xfc; ++ writearray[1]=0x17; ++ } ++ else if(IF_BW<=3000) ++ { ++ writearray[0]=0xfb; ++ writearray[1]=0x0f; ++ } ++ else if(IF_BW<=3500) ++ { ++ writearray[0]=0xf9; ++ writearray[1]=0x0b; ++ } ++ else if(IF_BW<=4000) ++ { ++ writearray[0]=0xf8; ++ writearray[1]=0x07; ++ } ++ status = I2CWriteArray(pTuner,200,17,2,writearray); ++ if(status != E4000_I2C_SUCCESS) ++ { ++ return E4000_1_FAIL; ++ } ++ ++ return E4000_1_SUCCESS; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_e4000.h b/drivers/drivers/media/dvb/dvb-usb/tuner_e4000.h +--- a/drivers/media/dvb/dvb-usb/tuner_e4000.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_e4000.h 2016-04-02 19:17:52.128066043 -0300 +@@ -0,0 +1,295 @@ ++#ifndef __TUNER_E4000_H ++#define __TUNER_E4000_H ++ ++/** ++ ++@file ++ ++@brief E4000 tuner module declaration ++ ++One can manipulate E4000 tuner through E4000 module. ++E4000 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_e4000.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ E4000_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build E4000 tuner module. ++ BuildE4000Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xac, // I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // Crystal frequency is 16.384 MHz. ++ E4000_AGC_INTERNAL // The E4000 AGC mode is internal AGC mode. ++ ); ++ ++ ++ ++ ++ ++ // Get E4000 tuner extra module. ++ pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set E4000 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, E4000_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get E4000 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is implemented for E4000 source code. ++ ++ ++// Definition (implemeted for E4000) ++#define E4000_1_SUCCESS 1 ++#define E4000_1_FAIL 0 ++#define E4000_I2C_SUCCESS 1 ++#define E4000_I2C_FAIL 0 ++ ++ ++ ++// Function (implemeted for E4000) ++int ++I2CReadByte( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++int ++I2CWriteByte( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegAddr, ++ unsigned char WritingByte ++ ); ++ ++int ++I2CWriteArray( ++ TUNER_MODULE *pTuner, ++ unsigned char NoUse, ++ unsigned char RegStartAddr, ++ unsigned char ByteNum, ++ unsigned char *pWritingBytes ++ ); ++ ++ ++ ++// Functions (from E4000 source code) ++int tunerreset (TUNER_MODULE *pTuner); ++int Tunerclock(TUNER_MODULE *pTuner); ++int Qpeak(TUNER_MODULE *pTuner); ++int DCoffloop(TUNER_MODULE *pTuner); ++int GainControlinit(TUNER_MODULE *pTuner); ++ ++int Gainmanual(TUNER_MODULE *pTuner); ++int E4000_gain_freq(TUNER_MODULE *pTuner, int frequency); ++int PLL(TUNER_MODULE *pTuner, int Ref_clk, int Freq); ++int LNAfilter(TUNER_MODULE *pTuner, int Freq); ++int IFfilter(TUNER_MODULE *pTuner, int bandwidth, int Ref_clk); ++int freqband(TUNER_MODULE *pTuner, int Freq); ++int DCoffLUT(TUNER_MODULE *pTuner); ++int GainControlauto(TUNER_MODULE *pTuner); ++ ++int E4000_sensitivity(TUNER_MODULE *pTuner, int Freq, int bandwidth); ++int E4000_linearity(TUNER_MODULE *pTuner, int Freq, int bandwidth); ++int E4000_high_linearity(TUNER_MODULE *pTuner); ++int E4000_nominal(TUNER_MODULE *pTuner, int Freq, int bandwidth); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is E4000 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Bandwidth in Hz ++enum E4000_BANDWIDTH_HZ ++{ ++ E4000_BANDWIDTH_6000000HZ = 6000000, ++ E4000_BANDWIDTH_7000000HZ = 7000000, ++ E4000_BANDWIDTH_8000000HZ = 8000000, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildE4000Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++e4000_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++e4000_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++e4000_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++e4000_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++e4000_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++e4000_GetRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++int ++e4000_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++int ++e4000_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_fc0012.c b/drivers/drivers/media/dvb/dvb-usb/tuner_fc0012.c +--- a/drivers/media/dvb/dvb-usb/tuner_fc0012.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_fc0012.c 2016-04-02 19:17:52.132066044 -0300 +@@ -0,0 +1,1056 @@ ++/** ++ ++@file ++ ++@brief FC0012 tuner module definition ++ ++One can manipulate FC0012 tuner through FC0012 module. ++FC0012 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_fc0012.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief FC0012 tuner module builder ++ ++Use BuildFc0012Module() to build FC0012 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to FC0012 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr FC0012 I2C device address ++@param [in] CrystalFreqHz FC0012 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildFc0012Module() to build FC0012 module before using it. ++ ++*/ ++void ++BuildFc0012Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ FC0012_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_FC0012; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = fc0012_GetTunerType; ++ pTuner->GetDeviceAddr = fc0012_GetDeviceAddr; ++ ++ pTuner->Initialize = fc0012_Initialize; ++ pTuner->SetRfFreqHz = fc0012_SetRfFreqHz; ++ pTuner->GetRfFreqHz = fc0012_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = fc0012_SetBandwidthMode; ++ pExtra->GetBandwidthMode = fc0012_GetBandwidthMode; ++ ++ ++ // Set tuner RF frequency and tuner bandwidth mode. ++ // Note: Need to give default tuner RF frequency and tuner bandwidth mode, ++ // because FC0012 API use one funnction to set RF frequency and bandwidth mode. ++ pTuner->RfFreqHz = FC0012_RF_FREQ_HZ_DEFAULT; ++ pExtra->BandwidthMode = FC0012_BANDWIDTH_MODE_DEFAULT; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++fc0012_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++fc0012_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++fc0012_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Initialize tuner. ++ if(FC0012_Open(pTuner) != FC0012_FUNCTION_SUCCESS) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++fc0012_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ unsigned long RfFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Set tuner RF frequency in KHz. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ RfFreqKhz = (RfFreqHz + 500) / 1000; ++ ++ if(FC0011_SetFrequency(pTuner, RfFreqKhz, (unsigned short)(pExtra->BandwidthMode)) != FC0012_FUNCTION_SUCCESS) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++fc0012_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set FC0012 tuner bandwidth mode. ++ ++*/ ++int ++fc0012_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ unsigned long RfFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Set tuner bandwidth mode. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ RfFreqKhz = (pTuner->RfFreqHz + 500) / 1000; ++ ++ if(FC0011_SetFrequency(pTuner, RfFreqKhz, (unsigned short)BandwidthMode) != FC0012_FUNCTION_SUCCESS) ++ goto error_status_set_tuner_bandwidth_mode; ++ ++ ++ // Set tuner bandwidth mode parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get FC0012 tuner bandwidth mode. ++ ++*/ ++int ++fc0012_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Get tuner bandwidth mode from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth_mode; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is implemented for FC0012 source code. ++ ++ ++// Read FC0012 register. ++int FC0012_Read(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char *pByte) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, pByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ return FC0012_I2C_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return FC0012_I2C_ERROR; ++} ++ ++ ++ ++ ++ ++// Write FC0012 register. ++int FC0012_Write(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char Byte) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBuffer[0] = RegAddr; ++ WritingBuffer[1] = Byte; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return FC0012_I2C_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return FC0012_I2C_ERROR; ++} ++ ++ ++ ++ ++ ++// Set FC0012 register mask bits. ++int ++fc0012_SetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned char WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingByte; ++ unsigned char WritingByte; ++ ++ unsigned char Mask; ++ unsigned char Shift; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get tuner register byte according to register adddress. ++ if(FC0012_Read(pTuner, RegAddr, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ // Reserve byte unmask bit with mask and inlay writing value into it. ++ WritingByte = ReadingByte & (~Mask); ++ WritingByte |= (WritingValue << Shift) & Mask; ++ ++ ++ // Write tuner register byte with writing byte. ++ if(FC0012_Write(pTuner, RegAddr, WritingByte) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Get FC0012 register mask bits. ++int ++fc0012_GetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned char *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingByte; ++ ++ unsigned char Mask; ++ unsigned char Shift; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get tuner register byte according to register adddress. ++ if(FC0012_Read(pTuner, RegAddr, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ // Get register bits from reading byte with mask and shift ++ *pReadingValue = (ReadingByte & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by fitipower. ++ ++ ++ ++ ++ ++// fitipower source code - FC0012_Tuner_Code.cpp ++ ++ ++//=========================================================== ++// Fitipower Integrated Technology Inc. ++// ++// FC0012 Tuner Code ++// ++// Version 1.2e ++// ++// Date: 2009/09/15 ++// ++// Copyright 2008, All rights reversed. ++// ++// Compile in Visual Studio 2005 C++ Win32 Console ++// ++//--------------------------------------------------------------------- ++// Modify History: ++// 2009-05-11: Change to recieve 28.8 MHz clock ++// 2009-05-14: fix frequency lock problem on 111MHz~148MHz ++// 2009-05-15: remove the limitation of Xin range ++// 2009-07-30: Add VHF filter control ++// Add VHF frequency offset ++// Add reference RSSI function ++// Change register[0x07] to 0x20 ++// 2009-09-15: update VCO re-calibration function ++//--------------------------------------------------------------------- ++//===================================================================== ++ ++// Data Format: ++// BYTE: unsigned char, 1 byte, 8 bits ++// WORD: unsighed short, 2 bytes, 16 bits ++// DWORD: unsigned int, 4 bytes, 32 bits ++ ++// include header, just for testing. ++//#include "stdafx.h" ++//#include "stdlib.h" ++//#include ++ ++//void FC0012_Write(unsigned char address, unsigned char data); ++//unsigned char FC0012_Read(unsigned char address); ++//void FC0012_Open(); ++//void FC0012_Close(); ++//void FC0012_SetFrequency(unsigned int Frequency, unsigned short Bandwidth); ++ ++/* ++// Console main function, just for testing ++int main(int argc, const char* argv[]) ++{ ++ printf("\n"); ++ ++ if ( argc > 1 ) ++ { ++ for( int i = 1; i < argc; i++ ) ++ { ++ FC0012_SetFrequency( atoi(argv[i]), 6); ++ } ++ } ++ ++ return 0; ++} ++ ++// FC0012 I2C Write Function ++void FC0012_Write(unsigned char address, unsigned char data) ++{ ++ // depend on driver function in demodulator vendor. ++} ++ ++// FC0012 I2C Read Function ++unsigned char FC0012_Read(unsigned char address) ++{ ++ // depend on driver function in demodulator vendor. ++ unsigned char value = 0; ++ // value = ........ ++ return value; ++} ++*/ ++ ++// FC0012 Open Function, includes enable/reset pin control and registers initialization. ++int FC0012_Open(TUNER_MODULE *pTuner) ++{ ++ FC0012_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ // Enable FC0012 Power ++// (...) ++ // FC0012 Enable = High ++// (...) ++ // FC0012 Reset = High -> Low ++// (...) ++ ++ //================================ Initial FC0012 Tuner Register ++ if(FC0012_Write(pTuner, 0x01, 0x05) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x02, 0x10) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x03, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x04, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ ++ //===================================== Arios Modify - 2009-10-23 ++ // modify for Realtek CNR test ++ if(FC0012_Write(pTuner, 0x05, 0x0F) != FC0012_I2C_SUCCESS) goto error_status; ++ //===================================== Arios Modify - 2009-10-23 ++ ++ ++ if(FC0012_Write(pTuner, 0x06, 0x00) != FC0012_I2C_SUCCESS) goto error_status; // divider 2, VCO slow. ++ ++ switch(pExtra->CrystalFreqHz) // Gain Shift: 15 // Set bit 5 to 1 for 28.8 MHz clock input (2009/05/12) ++ { ++ default: ++ case CRYSTAL_FREQ_28800000HZ: ++ ++ if(FC0012_Write(pTuner, 0x07, 0x20) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ break; ++ ++ ++ case CRYSTAL_FREQ_27000000HZ: ++ ++ if(FC0012_Write(pTuner, 0x07, 0x20) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ break; ++ ++ ++ case CRYSTAL_FREQ_36000000HZ: ++ ++ if(FC0012_Write(pTuner, 0x07, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ break; ++ } ++ ++ if(FC0012_Write(pTuner, 0x08, 0xFF) != FC0012_I2C_SUCCESS) goto error_status; // AGC Clock divide by 256, AGC gain 1/256, Loop Bw 1/8 ++ if(FC0012_Write(pTuner, 0x09, 0x6E) != FC0012_I2C_SUCCESS) goto error_status; // Disable LoopThrough ++ if(FC0012_Write(pTuner, 0x0A, 0xB8) != FC0012_I2C_SUCCESS) goto error_status; // Disable LO Test Buffer ++ if(FC0012_Write(pTuner, 0x0B, 0x82) != FC0012_I2C_SUCCESS) goto error_status; // Output Clock is same as clock frequency ++ ++ //-------------------------------------------------------------------------- ++ // reg[12] need to be changed if the system is in AGC Up-Down mode ++ //-------------------------------------------------------------------------- ++// if(FC0012_Write(pTuner, 0x0C, 0xF8) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ // Modified for up-dowm AGC by Realtek. ++ if(FC0012_Write(pTuner, 0x0C, 0xFC) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ // 0x0D, val=0x2 for DVBT ++ if(FC0012_Write(pTuner, 0x0D, 0x02) != FC0012_I2C_SUCCESS) goto error_status; // AGC Not Forcing & LNA Forcing ++ ++ // Modified for 2836B DTMB by Realtek. ++// if(FC0012_Write(pTuner, 0x0D, 0x06) != FC0012_I2C_SUCCESS) goto error_status; // AGC Not Forcing & LNA Forcing ++ ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x0F, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x10, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x11, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x12, 0x1F) != FC0012_I2C_SUCCESS) goto error_status; // Set to maximum gain ++ ++ ++ //===================================== Arios Modify - 2009-10-23 ++ // modify for Realtek CNR test ++// if(FC0012_Write(pTuner, 0x13, 0x10) != FC0012_I2C_SUCCESS) goto error_status; // Enable IX2, Set to High Gain ++ if(FC0012_Write(pTuner, 0x13, 0x08) != FC0012_I2C_SUCCESS) goto error_status; // Enable IX2, Set to Middle Gain ++// if(FC0012_Write(pTuner, 0x13, 0x00) != FC0012_I2C_SUCCESS) goto error_status; // Enable IX2, Set to Low Gain ++ //===================================== Arios Modify - 2009-10-23 ++ ++ if(FC0012_Write(pTuner, 0x14, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x15, 0x04) != FC0012_I2C_SUCCESS) goto error_status; // Enable LNA COMPS ++ ++ return FC0012_FUNCTION_SUCCESS; ++ ++error_status: ++ return FC0012_FUNCTION_ERROR; ++} ++ ++ ++/* ++// FC0012 Close Function, control enable/reset and power. ++void FC0012_Close() ++{ ++ // FC0012 Enable = Low ++ // (...) ++ // FC0012 Reset = Low -> High ++ // (...) ++ // Disable FC0012 Power ++ // (...) ++} ++ ++void Delay(unsigned int) ++{ ++ // delay function ++} ++ ++ ++//===================================== RSSI & LNA Control 2009/07/30 ++// better ACI Performance for D-Book & field-test ++void FC0012_RSSI() ++{ ++ unsigned char Input_Power; ++ ++ Delay(200); // Delay 200 ms ++ ++ ++ switch( FC0012_Read(0x13) ) // Read FC0012 LNA gain setting ++ { ++ case 0x10: // High gain 19.7 dB ++ if( Input_Power > -40 ) // if intput power level is bigger than -40 dBm ++ FC0012_Write(0x13, 0x17); // Switch to 17.9 dB ++ break; ++ ++ case 0x17: // High gain 17.9 dB ++ if( Input_Power > -15 ) // if intput power level is bigger than -15 dBm ++ FC0012_Write(0x13, 0x08); // Switch to 7.1 dB ++ else if( Input_Power < -45 ) // if intput power level is smaller than -45 dBm ++ FC0012_Write(0x13, 0x10); // Switch to 19.7 dB ++ break; ++ ++ case 0x08: // Middle gain 7.1 dB ++ if( Input_Power > -5 ) // if intput power level is bigger than -5 dBm ++ FC0012_Write(0x13, 0x02); // Switch to -9.9 dB ++ else if( Input_Power < -20 ) // if intput power level is smaller than -20 dBm ++ FC0012_Write(0x13, 0x17); // Switch to 17.9 dB ++ break; ++ ++ case 0x02: // Low gain -9.9 dB ++ if( Input_Power < -12 ) // if intput power level is smaller than -12 dBm ++ FC0012_Write(0x13, 0x08); // Switch to 7.1 dB ++ break; ++ } ++ ++} ++ ++ ++ ++ ++//===================================== Frequency Control 2009/07/30 ++// Frequency unit: KHz, bandwidth unit: MHz ++void FC0012_Frequency_Control(unsigned int Frequency, unsigned short Bandwidth) ++{ ++ if( Frequency < 260000 && Frequency > 150000 ) ++ { ++ // set GPIO6 = low ++ ++ // 1. Set tuner frequency ++ // 2. if the program quality is not good enough, switch to frequency + 500kHz ++ // 3. if the program quality is still no good, switch to frequency - 500kHz ++ } ++ else ++ { ++ // set GPIO6 = high ++ ++ // set tuner frequency ++ } ++} ++*/ ++ ++ ++ ++// FC0012 frequency/bandwidth setting function. ++// Frequency unit: KHz, bandwidth unit: MHz ++int FC0011_SetFrequency(TUNER_MODULE *pTuner, unsigned long Frequency, unsigned short Bandwidth) ++{ ++// bool VCO1 = false; ++// unsigned int doubleVCO; ++// unsigned short xin, xdiv; ++// unsigned char reg[21], am, pm, multi; ++ int VCO1 = FC0012_FALSE; ++ unsigned long doubleVCO; ++ unsigned short xin, xdiv; ++ unsigned char reg[21], am, pm, multi; ++ unsigned char read_byte; ++ ++ FC0012_EXTRA_MODULE *pExtra; ++ unsigned long CrystalFreqKhz; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0012); ++ ++ // Get tuner crystal frequency in KHz. ++ // Note: CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ CrystalFreqKhz = (pExtra->CrystalFreqHz + 500) / 1000; ++ ++ ++ //===================================== Select frequency divider and the frequency of VCO ++ if (Frequency * 96 < 3560000) ++ { ++ multi = 96; ++ reg[5] = 0x82; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 64 < 3560000) ++ { ++ multi = 64; ++ reg[5] = 0x82; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 48 < 3560000) ++ { ++ multi = 48; ++ reg[5] = 0x42; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 32 < 3560000) ++ { ++ multi = 32; ++ reg[5] = 0x42; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 24 < 3560000) ++ { ++ multi = 24; ++ reg[5] = 0x22; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 16 < 3560000) ++ { ++ multi = 16; ++ reg[5] = 0x22; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 12 < 3560000) ++ { ++ multi = 12; ++ reg[5] = 0x12; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 8 < 3560000) ++ { ++ multi = 8; ++ reg[5] = 0x12; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 6 < 3560000) ++ { ++ multi = 6; ++ reg[5] = 0x0A; ++ reg[6] = 0x00; ++ } ++ else ++ { ++ multi = 4; ++ reg[5] = 0x0A; ++ reg[6] = 0x02; ++ } ++ ++ doubleVCO = Frequency * multi; ++ ++ ++ ++ //===================================== Arios Modify - 2009-10-23 ++ // modify for Realtek CNR test ++ reg[6] = reg[6] | 0x08; ++// VCO1 = true; ++ VCO1 = FC0012_TRUE; ++ /* ++ if (doubleVCO >= 3060000) ++ { ++ reg[6] = reg[6] | 0x08; ++// VCO1 = true; ++ VCO1 = FC0012_TRUE; ++ } ++ */ ++ //===================================== Arios Modify - 2009-10-23 ++ ++ //===================================== From divided value (XDIV) determined the FA and FP value ++// xdiv = (unsigned short)(doubleVCO / 14400); // implement round function, 2009-05-01 by Arios ++// if( (doubleVCO - xdiv * 14400) >= 7200 ) ++ xdiv = (unsigned short)(doubleVCO / (CrystalFreqKhz / 2)); // implement round function, 2009-05-01 by Arios ++ if( (doubleVCO - xdiv * (CrystalFreqKhz / 2)) >= (CrystalFreqKhz / 4) ) ++ xdiv = xdiv + 1; ++ ++ pm = (unsigned char)( xdiv / 8 ); ++ am = (unsigned char)( xdiv - (8 * pm)); ++ ++ if (am < 2) ++ { ++ reg[1] = am + 8; ++ reg[2] = pm - 1; ++ } ++ else ++ { ++ reg[1] = am; ++ reg[2] = pm; ++ } ++ ++ //===================================== From VCO frequency determines the XIN ( fractional part of Delta Sigma PLL) and divided value (XDIV). ++// xin = (unsigned short)(doubleVCO - ((unsigned short)(doubleVCO / 14400)) * 14400); ++// xin = ((xin << 15)/14400); ++ xin = (unsigned short)(doubleVCO - ((unsigned short)(doubleVCO / (CrystalFreqKhz / 2))) * (CrystalFreqKhz / 2)); ++ xin = ((xin << 15)/(unsigned short)(CrystalFreqKhz / 2)); ++ ++// if( xin >= (unsigned short) pow( (double)2, (double)14) ) ++// xin = xin + (unsigned short) pow( (double)2, (double)15); ++ if( xin >= (unsigned short) 16384 ) ++ xin = xin + (unsigned short) 32768; ++ ++ reg[3] = (unsigned char)(xin >> 8); ++ reg[4] = (unsigned char)(xin & 0x00FF); ++ ++ ++ //===================================== Only for testing, 2009-05-01 by Arios ++// printf("Frequency: %d, Fa: %d, Fp: %d, Xin:%d \n", Frequency, am, pm, xin); ++ ++ //===================================== Set Bandwidth ++ switch(Bandwidth) ++ { ++ case 6: ++ reg[6] = 0x80 | reg[6]; ++ break; ++ case 7: ++ reg[6] = ~0x80 & reg[6]; ++ reg[6] = 0x40 | reg[6]; ++ break; ++ case 8: ++ default: ++ reg[6] = ~0xC0 & reg[6]; ++ break; ++ } ++ ++ //===================================== Write registers ++ if(FC0012_Write(pTuner, 0x01, reg[1]) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x02, reg[2]) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x03, reg[3]) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x04, reg[4]) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ //===================================== Arios Modify - 2009-10-23 ++ // modify for Realtek CNR Test ++ reg[5] = reg[5] | 0x07; ++ if(FC0012_Write(pTuner, 0x05, reg[5]) != FC0012_I2C_SUCCESS) goto error_status; ++ //===================================== Arios Modify - 2009-10-23 ++ ++ if(FC0012_Write(pTuner, 0x06, reg[6]) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ //===================================== VCO Calibration ++ if(FC0012_Write(pTuner, 0x0E, 0x80) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ //===================================== VCO Re-Calibration if needed ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++// reg[14] = 0x3F & FC0012_Read(0x0E); ++ if(FC0012_Read(pTuner, 0x0E, &read_byte) != FC0012_I2C_SUCCESS) goto error_status; ++ reg[14] = 0x3F & read_byte; ++ ++ if (VCO1) ++ { ++ if (reg[14] > 0x3C) // modify 2009-09-15 ++ { ++ reg[6] = ~0x08 & reg[6]; ++ ++ if(FC0012_Write(pTuner, 0x06, reg[6]) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ if(FC0012_Write(pTuner, 0x0E, 0x80) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ } ++ } ++ else ++ { ++ if (reg[14] < 0x02) // modify 2009-09-15 ++ { ++ reg[6] = 0x08 | reg[6]; ++ ++ if(FC0012_Write(pTuner, 0x06, reg[6]) != FC0012_I2C_SUCCESS) goto error_status; ++ ++ if(FC0012_Write(pTuner, 0x0E, 0x80) != FC0012_I2C_SUCCESS) goto error_status; ++ if(FC0012_Write(pTuner, 0x0E, 0x00) != FC0012_I2C_SUCCESS) goto error_status; ++ } ++ } ++ ++ return FC0012_FUNCTION_SUCCESS; ++ ++error_status: ++ return FC0012_FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_fc0012.h b/drivers/drivers/media/dvb/dvb-usb/tuner_fc0012.h +--- a/drivers/media/dvb/dvb-usb/tuner_fc0012.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_fc0012.h 2016-04-02 19:17:52.132066044 -0300 +@@ -0,0 +1,292 @@ ++#ifndef __TUNER_FC0012_H ++#define __TUNER_FC0012_H ++ ++/** ++ ++@file ++ ++@brief FC0012 tuner module declaration ++ ++One can manipulate FC0012 tuner through FC0012 module. ++FC0012 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_fc0012.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ FC0012_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build FC0012 tuner module. ++ BuildFc0012Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc6, // I2C device address is 0xc6 in 8-bit format. ++ CRYSTAL_FREQ_36000000HZ // Crystal frequency is 36.0 MHz. ++ ); ++ ++ ++ ++ ++ ++ // Get FC0012 tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0012); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set FC0012 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, FC0012_BANDWIDTH_6000000HZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get FC0012 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is implemented for FC0012 source code. ++ ++ ++// Definitions ++enum FC0012_TRUE_FALSE_STATUS ++{ ++ FC0012_FALSE, ++ FC0012_TRUE, ++}; ++ ++ ++enum FC0012_I2C_STATUS ++{ ++ FC0012_I2C_SUCCESS, ++ FC0012_I2C_ERROR, ++}; ++ ++ ++enum FC0012_FUNCTION_STATUS ++{ ++ FC0012_FUNCTION_SUCCESS, ++ FC0012_FUNCTION_ERROR, ++}; ++ ++ ++ ++// Functions ++int FC0012_Read(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char *pByte); ++int FC0012_Write(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char Byte); ++ ++int ++fc0012_SetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned char WritingValue ++ ); ++ ++int ++fc0012_GetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned char *pReadingValue ++ ); ++ ++int FC0012_Open(TUNER_MODULE *pTuner); ++int FC0011_SetFrequency(TUNER_MODULE *pTuner, unsigned long Frequency, unsigned short Bandwidth); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is FC0012 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Bandwidth mode ++enum FC0012_BANDWIDTH_MODE ++{ ++ FC0012_BANDWIDTH_6000000HZ = 6, ++ FC0012_BANDWIDTH_7000000HZ = 7, ++ FC0012_BANDWIDTH_8000000HZ = 8, ++}; ++ ++ ++// Default for initialing ++#define FC0012_RF_FREQ_HZ_DEFAULT 50000000 ++#define FC0012_BANDWIDTH_MODE_DEFAULT FC0012_BANDWIDTH_6000000HZ ++ ++ ++// Tuner LNA ++enum FC0012_LNA_GAIN_VALUE ++{ ++ FC0012_LNA_GAIN_LOW = 0x0, ++ FC0012_LNA_GAIN_MIDDLE = 0x1, ++ FC0012_LNA_GAIN_HIGH = 0x2, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildFc0012Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++fc0012_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++fc0012_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++fc0012_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++fc0012_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++fc0012_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++fc0012_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++fc0012_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_fc0013.c b/drivers/drivers/media/dvb/dvb-usb/tuner_fc0013.c +--- a/drivers/media/dvb/dvb-usb/tuner_fc0013.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_fc0013.c 2016-04-02 19:17:52.132066044 -0300 +@@ -0,0 +1,1261 @@ ++/** ++ ++@file ++ ++@brief FC0013 tuner module definition ++ ++One can manipulate FC0013 tuner through FC0013 module. ++FC0013 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_fc0013.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief FC0013 tuner module builder ++ ++Use BuildFc0013Module() to build FC0013 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to FC0013 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr FC0013 I2C device address ++@param [in] CrystalFreqHz FC0013 crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildFc0013Module() to build FC0013 module before using it. ++ ++*/ ++void ++BuildFc0013Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ FC0013_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0013); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_FC0013; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = fc0013_GetTunerType; ++ pTuner->GetDeviceAddr = fc0013_GetDeviceAddr; ++ ++ pTuner->Initialize = fc0013_Initialize; ++ pTuner->SetRfFreqHz = fc0013_SetRfFreqHz; ++ pTuner->GetRfFreqHz = fc0013_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = fc0013_SetBandwidthMode; ++ pExtra->GetBandwidthMode = fc0013_GetBandwidthMode; ++ pExtra->RcCalReset = fc0013_RcCalReset; ++ pExtra->RcCalAdd = fc0013_RcCalAdd; ++ ++ ++ // Set tuner RF frequency and tuner bandwidth mode. ++ // Note: Need to give default tuner RF frequency and tuner bandwidth mode, ++ // because FC0013 API use one funnction to set RF frequency and bandwidth mode. ++ pTuner->RfFreqHz = FC0013_RF_FREQ_HZ_DEFAULT; ++ pExtra->BandwidthMode = FC0013_BANDWIDTH_MODE_DEFAULT; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++fc0013_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++fc0013_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++fc0013_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ FC0013_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0013); ++ ++ ++ // Initialize tuner. ++ if(FC0013_Open(pTuner) != FC0013_FUNCTION_SUCCESS) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++fc0013_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ FC0013_EXTRA_MODULE *pExtra; ++ unsigned long RfFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0013); ++ ++ ++ // Set tuner RF frequency in KHz. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ RfFreqKhz = (RfFreqHz + 500) / 1000; ++ ++ if(FC0013_SetFrequency(pTuner, RfFreqKhz, (unsigned short)(pExtra->BandwidthMode)) != FC0013_FUNCTION_SUCCESS) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++fc0013_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set FC0013 tuner bandwidth mode. ++ ++*/ ++int ++fc0013_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ FC0013_EXTRA_MODULE *pExtra; ++ unsigned long RfFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0013); ++ ++ ++ // Set tuner bandwidth mode. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ RfFreqKhz = (pTuner->RfFreqHz + 500) / 1000; ++ ++ if(FC0013_SetFrequency(pTuner, RfFreqKhz, (unsigned short)BandwidthMode) != FC0013_FUNCTION_SUCCESS) ++ goto error_status_set_tuner_bandwidth_mode; ++ ++ ++ // Set tuner bandwidth mode parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get FC0013 tuner bandwidth mode. ++ ++*/ ++int ++fc0013_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ FC0013_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0013); ++ ++ ++ // Get tuner bandwidth mode from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth_mode; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is implemented for FC0013 source code. ++ ++ ++// Read FC0013 register. ++int FC0013_Read(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char *pByte) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, pByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ return FC0013_I2C_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return FC0013_I2C_ERROR; ++} ++ ++ ++ ++ ++ ++// Write FC0013 register. ++int FC0013_Write(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char Byte) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBuffer[0] = RegAddr; ++ WritingBuffer[1] = Byte; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return FC0013_I2C_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return FC0013_I2C_ERROR; ++} ++ ++ ++ ++ ++ ++// Set FC0013 register mask bits. ++int ++fc0013_SetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned char WritingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingByte; ++ unsigned char WritingByte; ++ ++ unsigned char Mask; ++ unsigned char Shift; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get tuner register byte according to register adddress. ++ if(FC0013_Read(pTuner, RegAddr, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ // Reserve byte unmask bit with mask and inlay writing value into it. ++ WritingByte = ReadingByte & (~Mask); ++ WritingByte |= (WritingValue << Shift) & Mask; ++ ++ ++ // Write tuner register byte with writing byte. ++ if(FC0013_Write(pTuner, RegAddr, WritingByte) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Get FC0013 register mask bits. ++int ++fc0013_GetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned char *pReadingValue ++ ) ++{ ++ int i; ++ ++ unsigned char ReadingByte; ++ ++ unsigned char Mask; ++ unsigned char Shift; ++ ++ ++ // Generate mask and shift according to MSB and LSB. ++ Mask = 0; ++ ++ for(i = Lsb; i < (Msb + 1); i++) ++ Mask |= 0x1 << i; ++ ++ Shift = Lsb; ++ ++ ++ // Get tuner register byte according to register adddress. ++ if(FC0013_Read(pTuner, RegAddr, &ReadingByte) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ // Get register bits from reading byte with mask and shift ++ *pReadingValue = (ReadingByte & Mask) >> Shift; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by fitipower. ++ ++ ++ ++ ++ ++// fitipower source code - FC0013_Tuner_Code.cpp ++ ++ ++//===================================================================== ++// Fitipower Integrated Technology Inc. ++// ++// FC0013 Tuner Code ++// ++// Version 0.7 ++// ++// Date: 2010/12/23 ++// ++// Copyright 2010, All rights reversed. ++// ++// Compile in Visual Studio 2005 C++ Win32 Console ++//===================================================================== ++ ++// Data Format: ++// BYTE: unsigned char, 1 byte, 8 bits ++// WORD: unsighed short, 2 bytes, 16 bits ++// DWORD: unsigned int, 4 bytes, 32 bits ++ ++// include header, just for testing. ++//#include "stdafx.h" ++//#include "stdlib.h" ++//#include ++//#include ++//#include ++//#include ++//#include "I2C.h" ++ ++//#define Crystal_Frequency 28800 // FC0013 Crystal Clock (kHz) ++ ++ ++//void FC0013_Write(unsigned char address, unsigned char data); ++//unsigned char FC0013_Read(unsigned char address); ++//void FC0013_Open(); ++//void FC0013_Close(); ++//void FC0013_RSSI(); ++//void FC0013_Band_Selection(bool Band_Selection_DVBT); ++//void FC0013_SetFrequency(unsigned int Frequency, unsigned short Bandwidth); ++ ++//unsigned char FC0013_RSSI_Calibration_Value; ++/* ++// Console main function, just for testing ++int main(int argc, const char* argv[]) ++{ ++ printf("\n"); ++ ++ if ( argc > 1 ) ++ { ++ for( int i = 1; i < argc; i++ ) ++ { ++ FC0013_SetFrequency( atoi(argv[i]), 8 ); ++ } ++ } ++ ++ return 0; ++} ++ ++void Delay(unsigned int) ++{ ++ // delay function ++} ++ ++// FC0013 I2C Write Function ++void FC0013_Write(unsigned char address, unsigned char data) ++{ ++ // depend on driver function in demodulator vendor. ++ I2C_Write(address, data); ++} ++ ++// FC0013 I2C Read Function ++unsigned char FC0013_Read(unsigned char address) ++{ ++ // depend on driver function in demodulator vendor. ++ return return I2C_Read(address); ++} ++*/ ++// FC0013 Open Function, includes enable/reset pin control and registers initialization. ++//void FC0013_Open() ++int FC0013_Open(TUNER_MODULE *pTuner) ++{ ++ // Enable FC0013 Power ++ // (...) ++ // FC0013 Enable = High ++ // (...) ++ // FC0013 Reset = High -> Low ++ // (...) ++ ++ //================================ update base on new FC0013 register bank ++ if(FC0013_Write(pTuner, 0x01, 0x09) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x02, 0x16) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x03, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x04, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x05, 0x17) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x06, 0x02) != FC0013_I2C_SUCCESS) goto error_status; ++// if(FC0013_Write(pTuner, 0x07, 0x27) != FC0013_I2C_SUCCESS) goto error_status; // 28.8MHz, GainShift: 15 ++ if(FC0013_Write(pTuner, 0x07, 0x2A) != FC0013_I2C_SUCCESS) goto error_status; // 28.8MHz, modified by Realtek ++ if(FC0013_Write(pTuner, 0x08, 0xFF) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x09, 0x6F) != FC0013_I2C_SUCCESS) goto error_status; // Enable Loop Through ++ if(FC0013_Write(pTuner, 0x0A, 0xB8) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x0B, 0x82) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ if(FC0013_Write(pTuner, 0x0C, 0xFE) != FC0013_I2C_SUCCESS) goto error_status; // Modified for up-dowm AGC by Realtek(for master, and for 2836BU dongle). ++// if(FC0013_Write(pTuner, 0x0C, 0xFC) != FC0013_I2C_SUCCESS) goto error_status; // Modified for up-dowm AGC by Realtek(for slave, and for 2832 mini dongle). ++ ++// if(FC0013_Write(pTuner, 0x0D, 0x09) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x0D, 0x01) != FC0013_I2C_SUCCESS) goto error_status; // Modified for AGC non-forcing by Realtek. ++ ++ if(FC0013_Write(pTuner, 0x0E, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x0F, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x10, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x11, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x12, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x13, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ if(FC0013_Write(pTuner, 0x14, 0x50) != FC0013_I2C_SUCCESS) goto error_status; // DVB-T, High Gain ++// if(FC0013_Write(pTuner, 0x14, 0x48) != FC0013_I2C_SUCCESS) goto error_status; // DVB-T, Middle Gain ++// if(FC0013_Write(pTuner, 0x14, 0x40) != FC0013_I2C_SUCCESS) goto error_status; // DVB-T, Low Gain ++ ++ if(FC0013_Write(pTuner, 0x15, 0x01) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ ++ return FC0013_FUNCTION_SUCCESS; ++ ++error_status: ++ return FC0013_FUNCTION_ERROR; ++} ++ ++/* ++// FC0013 Close Function, control enable/reset and power. ++void FC0013_Close() ++{ ++ // FC0013 Enable = Low ++ // (...) ++ // FC0013 Reset = Low -> High ++ // (...) ++ // Disable FC0013 Power ++ // (...) ++} ++ ++ ++void FC0013_Band_Selection(bool Band_Selection_DVBT) ++{ ++ if( Band_Selection_DVBT == true ) ++ { ++ FC0013_Write(0x14, (FC0013_Read(0x14) & 0x9F) | 0x40); ++ } ++ else ++ { ++ FC0013_Write(0x14, (FC0013_Read(0x14) & 0x9F) | 0x20); ++ } ++} ++ ++ ++// Get RSSI ADC value ++unsigned char Get_RSSI_Value() ++{ ++ return 0x00; // return RSSI value ++} ++ ++ ++// RSSI Calibration Function ++void FC0013_RSSI_Calibration() ++{ ++ FC0013_Write(0x09, ( FC0013_Read(0x09) | 0x10 ) ); // set the register 9 bit4 EN_CAL_RSSI as 1 ++ FC0013_Write(0x06, ( FC0013_Read(0x06) | 0x01 ) ); // set the register 6 bit 0 LNA_POWER_DOWN as 1 ++ ++ Delay(100); // delay 100ms ++ ++ FC0013_RSSI_Calibration_Value = Get_RSSI_Value(); // read DC value from RSSI pin as rssi_calibration ++ ++ FC0013_Write(0x09, ( FC0013_Read(0x09) & 0xEF ) ); // set the register 9 bit4 EN_CAL_RSSI as 0 ++ FC0013_Write(0x06, ( FC0013_Read(0x06) & 0xFE ) ); // set the register 6 bit 0 LNA_POWER_DOWN as 0 ++} ++ ++ ++// RSSI & LNA Control, call this function if FC0013 is in the External RSSI ADC mode. ++void FC0013_RSSI() ++{ ++ unsigned char Input_Power = 0; // Get Input power information from RSSI ++ // it should be the difference between RSSI ADC value and RSSI calibration value ++ unsigned char LNA_value; ++ unsigned char RSSI_Value, RSSI_Difference; ++ ++ Delay(500); // Delay 500 ms ++ ++ RSSI_Value = Get_RSSI_Value(); // Get RSSI Value from demodulator ADC ++ ++ if( RSSI_Value < FC0013_RSSI_Calibration_Value ) // adjust RSSI Calibration Value ++ FC0013_RSSI_Calibration_Value = RSSI_Value; ++ ++ RSSI_Difference = RSSI_Value - FC0013_RSSI_Calibration_Value; // Calculate voltage difference of RSSI ++ ++ LNA_value = FC0013_Read(0x14); ++ ++ //------------------------------------------------ arios modify 2010-12-24 ++ // " | 0x07" ==> " | 0x27" (make sure reg[0x07] bit5 = 1) ++ // " | 0x0F" ==> " | 0x2F" (make sure reg[0x07] bit5 = 1) ++ // add default in switch case ++ switch( (LNA_value & 0x1F) ) ++ { ++ case 0x10: ++ if( RSSI_Difference > 6 ) ++ { ++ FC0013_Write(0x14, (LNA_value & 0xE0) | 0x17); ++ FC0013_Write(0x07, (FC0013_Read(0x07) & 0xF0) | 0x27); ++ } ++ break; ++ ++ case 0x17: ++ if( RSSI_Difference > 40 ) ++ { ++ FC0013_Write(0x14, (LNA_value & 0xE0) | 0x08); ++ FC0013_Write(0x07, (FC0013_Read(0x07) & 0xF0) | 0x27); ++ } ++ else if( RSSI_Difference < 3 ) ++ { ++ FC0013_Write(0x14, (LNA_value & 0xE0) | 0x10); ++ FC0013_Write(0x07, (FC0013_Read(0x07) & 0xF0) | 0x2F); ++ } ++ break; ++ ++ case 0x08: ++ if( RSSI_Difference > 40 ) ++ { ++ FC0013_Write(0x14, (LNA_value & 0xE0) | 0x02); ++ FC0013_Write(0x07, (FC0013_Read(0x07) & 0xF0) | 0x27); ++ } ++ else if( RSSI_Difference < 7 ) ++ { ++ FC0013_Write(0x14, (LNA_value & 0xE0) | 0x17); ++ FC0013_Write(0x07, (FC0013_Read(0x07) & 0xF0) | 0x27); ++ } ++ break; ++ ++ case 0x02: ++ if( RSSI_Difference < 2 ) ++ { ++ FC0013_Write(0x14, (LNA_value & 0xE0) | 0x08); ++ FC0013_Write(0x07, (FC0013_Read(0x07) & 0xF0) | 0x27); ++ } ++ break; ++ ++ default: ++ FC0013_Write(0x14, (LNA_value & 0xE0) | 0x10); ++ FC0013_Write(0x07, (FC0013_Read(0x07) & 0xF0) | 0x2F); ++ break; ++ } ++} ++*/ ++ ++ ++// Set VHF Track depends on input frequency ++// Frequency Unit: KHz ++int FC0013_SetVhfTrack(TUNER_MODULE *pTuner, unsigned long FrequencyKHz) ++{ ++ unsigned char read_byte; ++ ++ if (FrequencyKHz <= 177500) // VHF Track: 7 ++ { ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x1C) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ } ++ else if (FrequencyKHz <= 184500) // VHF Track: 6 ++ { ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x18) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ } ++ else if (FrequencyKHz <= 191500) // VHF Track: 5 ++ { ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x14) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ } ++ else if (FrequencyKHz <= 198500) // VHF Track: 4 ++ { ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x10) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ } ++ else if (FrequencyKHz <= 205500) // VHF Track: 3 ++ { ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x0C) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ } ++ else if (FrequencyKHz <= 212500) // VHF Track: 2 ++ { ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x08) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ } ++ else if (FrequencyKHz <= 219500) // VHF Track: 2 ++ { ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x08) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ } ++ else if (FrequencyKHz <= 226500) // VHF Track: 1 ++ { ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x04) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ else // VHF Track: 1 ++ { ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x04) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ } ++ ++ //------------------------------------------------ arios modify 2010-12-24 ++ // " | 0x10" ==> " | 0x30" (make sure reg[0x07] bit5 = 1) ++ ++ // Enable VHF filter. ++ if(FC0013_Read(pTuner, 0x07, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x07, read_byte | 0x10) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ // Disable UHF & GPS. ++ if(FC0013_Read(pTuner, 0x14, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x14, read_byte & 0x1F) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ ++ return FC0013_FUNCTION_SUCCESS; ++ ++error_status: ++ return FC0013_FUNCTION_ERROR; ++} ++ ++ ++ ++// FC0013 frequency/bandwidth setting function. ++// Frequency unit: KHz, bandwidth unit: MHz ++//void FC0013_SetFrequency(unsigned int Frequency, unsigned short Bandwidth) ++int FC0013_SetFrequency(TUNER_MODULE *pTuner, unsigned long Frequency, unsigned short Bandwidth) ++{ ++// bool VCO1 = false; ++// unsigned int doubleVCO; ++// unsigned short xin, xdiv; ++// unsigned char reg[21], am, pm, multi; ++ int VCO1 = FC0013_FALSE; ++ unsigned long doubleVCO; ++ unsigned short xin, xdiv; ++ unsigned char reg[21], am, pm, multi; ++ ++ unsigned char read_byte; ++ ++ FC0013_EXTRA_MODULE *pExtra; ++ unsigned long CrystalFreqKhz; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0013); ++ ++ // Get tuner crystal frequency in KHz. ++ // Note: CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ CrystalFreqKhz = (pExtra->CrystalFreqHz + 500) / 1000; ++ ++ // modified 2011-02-09: for D-Book test ++ // set VHF_Track = 7 ++ if(FC0013_Read(pTuner, 0x1D, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ // VHF Track: 7 ++ if(FC0013_Write(pTuner, 0x1D, (read_byte & 0xE3) | 0x1C) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ ++ if( Frequency < 300000 ) ++ { ++ // Set VHF Track. ++ if(FC0013_SetVhfTrack(pTuner, Frequency) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ // Enable VHF filter. ++ if(FC0013_Read(pTuner, 0x07, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x07, read_byte | 0x10) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ // Disable UHF & disable GPS. ++ if(FC0013_Read(pTuner, 0x14, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x14, read_byte & 0x1F) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ else if ( (Frequency >= 300000) && (Frequency <= 862000) ) ++ { ++ // Disable VHF filter. ++ if(FC0013_Read(pTuner, 0x07, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x07, read_byte & 0xEF) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ // enable UHF & disable GPS. ++ if(FC0013_Read(pTuner, 0x14, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x14, (read_byte & 0x1F) | 0x40) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ else if (Frequency > 862000) ++ { ++ // Disable VHF filter ++ if(FC0013_Read(pTuner, 0x07, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x07, read_byte & 0xEF) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ // Disable UHF & enable GPS ++ if(FC0013_Read(pTuner, 0x14, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x14, (read_byte & 0x1F) | 0x20) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ ++ if (Frequency * 96 < 3560000) ++ { ++ multi = 96; ++ reg[5] = 0x82; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 64 < 3560000) ++ { ++ multi = 64; ++ reg[5] = 0x02; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 48 < 3560000) ++ { ++ multi = 48; ++ reg[5] = 0x42; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 32 < 3560000) ++ { ++ multi = 32; ++ reg[5] = 0x82; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 24 < 3560000) ++ { ++ multi = 24; ++ reg[5] = 0x22; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 16 < 3560000) ++ { ++ multi = 16; ++ reg[5] = 0x42; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 12 < 3560000) ++ { ++ multi = 12; ++ reg[5] = 0x12; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 8 < 3560000) ++ { ++ multi = 8; ++ reg[5] = 0x22; ++ reg[6] = 0x02; ++ } ++ else if (Frequency * 6 < 3560000) ++ { ++ multi = 6; ++ reg[5] = 0x0A; ++ reg[6] = 0x00; ++ } ++ else if (Frequency * 4 < 3800000) ++ { ++ multi = 4; ++ reg[5] = 0x12; ++ reg[6] = 0x02; ++ } ++ else ++ { ++ Frequency = Frequency / 2; ++ multi = 4; ++ reg[5] = 0x0A; ++ reg[6] = 0x02; ++ } ++ ++ doubleVCO = Frequency * multi; ++ ++ reg[6] = reg[6] | 0x08; ++// VCO1 = true; ++ VCO1 = FC0013_TRUE; ++ ++ // Calculate VCO parameters: ap & pm & xin. ++// xdiv = (unsigned short)(doubleVCO / (Crystal_Frequency/2)); ++ xdiv = (unsigned short)(doubleVCO / (CrystalFreqKhz/2)); ++// if( (doubleVCO - xdiv * (Crystal_Frequency/2)) >= (Crystal_Frequency/4) ) ++ if( (doubleVCO - xdiv * (CrystalFreqKhz/2)) >= (CrystalFreqKhz/4) ) ++ { ++ xdiv = xdiv + 1; ++ } ++ ++ pm = (unsigned char)( xdiv / 8 ); ++ am = (unsigned char)( xdiv - (8 * pm)); ++ ++ if (am < 2) ++ { ++ reg[1] = am + 8; ++ reg[2] = pm - 1; ++ } ++ else ++ { ++ reg[1] = am; ++ reg[2] = pm; ++ } ++ ++// xin = (unsigned short)(doubleVCO - ((unsigned short)(doubleVCO / (Crystal_Frequency/2))) * (Crystal_Frequency/2)); ++ xin = (unsigned short)(doubleVCO - ((unsigned short)(doubleVCO / (CrystalFreqKhz/2))) * (CrystalFreqKhz/2)); ++// xin = ((xin << 15)/(Crystal_Frequency/2)); ++ xin = (unsigned short)((xin << 15)/(CrystalFreqKhz/2)); ++ ++// if( xin >= (unsigned short) pow( (double)2, (double)14) ) ++// { ++// xin = xin + (unsigned short) pow( (double)2, (double)15); ++// } ++ if( xin >= (unsigned short) 16384 ) ++ xin = xin + (unsigned short) 32768; ++ ++ reg[3] = (unsigned char)(xin >> 8); ++ reg[4] = (unsigned char)(xin & 0x00FF); ++ ++ ++ //===================================== Only for testing ++// printf("Frequency: %d, Fa: %d, Fp: %d, Xin:%d \n", Frequency, am, pm, xin); ++ ++ ++ // Set Low-Pass Filter Bandwidth. ++ switch(Bandwidth) ++ { ++ case 6: ++ reg[6] = 0x80 | reg[6]; ++ break; ++ case 7: ++ reg[6] = ~0x80 & reg[6]; ++ reg[6] = 0x40 | reg[6]; ++ break; ++ case 8: ++ default: ++ reg[6] = ~0xC0 & reg[6]; ++ break; ++ } ++ ++ reg[5] = reg[5] | 0x07; ++ ++ if(FC0013_Write(pTuner, 0x01, reg[1]) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x02, reg[2]) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x03, reg[3]) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x04, reg[4]) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x05, reg[5]) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x06, reg[6]) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ if (multi == 64) ++ { ++// FC0013_Write(0x11, FC0013_Read(0x11) | 0x04); ++ if(FC0013_Read(pTuner, 0x11, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x11, read_byte | 0x04) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ else ++ { ++// FC0013_Write(0x11, FC0013_Read(0x11) & 0xFB); ++ if(FC0013_Read(pTuner, 0x11, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x11, read_byte & 0xFB) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ ++ if(FC0013_Write(pTuner, 0x0E, 0x80) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x0E, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ if(FC0013_Write(pTuner, 0x0E, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++// reg[14] = 0x3F & FC0013_Read(0x0E); ++ if(FC0013_Read(pTuner, 0x0E, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ reg[14] = 0x3F & read_byte; ++ ++ if (VCO1) ++ { ++ if (reg[14] > 0x3C) ++ { ++ reg[6] = ~0x08 & reg[6]; ++ ++ if(FC0013_Write(pTuner, 0x06, reg[6]) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ if(FC0013_Write(pTuner, 0x0E, 0x80) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x0E, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ } ++ else ++ { ++ if (reg[14] < 0x02) ++ { ++ reg[6] = 0x08 | reg[6]; ++ ++ if(FC0013_Write(pTuner, 0x06, reg[6]) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ if(FC0013_Write(pTuner, 0x0E, 0x80) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x0E, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ } ++ ++ ++ return FC0013_FUNCTION_SUCCESS; ++ ++error_status: ++ return FC0013_FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Reset IQ LPF Bandwidth ++int ++fc0013_RcCalReset( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ // not forcing RC_cal and ADC_Ext enable ++ if(FC0013_Write(pTuner, 0x0D, 0x01) != FC0013_I2C_SUCCESS) goto error_status; ++ if(FC0013_Write(pTuner, 0x10, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ ++ return FC0013_FUNCTION_SUCCESS; ++ ++ ++error_status: ++ return FC0013_FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// Increase IQ LPF bandwidth ++int ++fc0013_RcCalAdd( ++ TUNER_MODULE *pTuner, ++ int RcValue ++ ) ++{ ++ unsigned char read_byte; ++ unsigned char rc_cal; ++ int WriteValue; ++ ++ FC0013_EXTRA_MODULE *pExtra; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc0013); ++ ++ ++ // Push RC_cal value Get RC_cal value ++ if(FC0013_Write(pTuner, 0x10, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ //Get RC_cal value ++ if(FC0013_Read(pTuner, 0x10, &read_byte) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ rc_cal = read_byte & 0x0F; ++ ++ WriteValue = (int)rc_cal + RcValue; ++ ++ ++ // Forcing RC_cal ++ if(FC0013_Write(pTuner, 0x0D, 0x11) != FC0013_I2C_SUCCESS) goto error_status; ++ ++ // Modify RC_cal value ++ if( WriteValue > 15 ) ++ { ++ if(FC0013_Write(pTuner, 0x10, 0x0F) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ else if( WriteValue < 0 ) ++ { ++ if(FC0013_Write(pTuner, 0x10, 0x00) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ else ++ { ++ if(FC0013_Write(pTuner, 0x10, (unsigned char)WriteValue) != FC0013_I2C_SUCCESS) goto error_status; ++ } ++ ++ ++ return FC0013_FUNCTION_SUCCESS; ++ ++ ++error_status: ++ return FC0013_FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_fc0013.h b/drivers/drivers/media/dvb/dvb-usb/tuner_fc0013.h +--- a/drivers/media/dvb/dvb-usb/tuner_fc0013.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_fc0013.h 2016-04-02 19:17:52.132066044 -0300 +@@ -0,0 +1,307 @@ ++#ifndef __TUNER_FC0013_H ++#define __TUNER_FC0013_H ++ ++/** ++ ++@file ++ ++@brief FC0013 tuner module declaration ++ ++One can manipulate FC0013 tuner through FC0013 module. ++FC0013 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_fc0013.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ FC0013_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build FC0013 tuner module. ++ BuildFc0013Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc6, // I2C device address is 0xc6 in 8-bit format. ++ CRYSTAL_FREQ_36000000HZ // Crystal frequency is 36.0 MHz. ++ ); ++ ++ ++ ++ ++ ++ // Get FC0013 tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Fc0013); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set FC0013 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, FC0013_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get FC0013 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is implemented for FC0013 source code. ++ ++ ++// Definitions ++enum FC0013_TRUE_FALSE_STATUS ++{ ++ FC0013_FALSE, ++ FC0013_TRUE, ++}; ++ ++ ++enum FC0013_I2C_STATUS ++{ ++ FC0013_I2C_SUCCESS, ++ FC0013_I2C_ERROR, ++}; ++ ++ ++enum FC0013_FUNCTION_STATUS ++{ ++ FC0013_FUNCTION_SUCCESS, ++ FC0013_FUNCTION_ERROR, ++}; ++ ++ ++ ++// Functions ++int FC0013_Read(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char *pByte); ++int FC0013_Write(TUNER_MODULE *pTuner, unsigned char RegAddr, unsigned char Byte); ++ ++int ++fc0013_SetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ const unsigned char WritingValue ++ ); ++ ++int ++fc0013_GetRegMaskBits( ++ TUNER_MODULE *pTuner, ++ unsigned char RegAddr, ++ unsigned char Msb, ++ unsigned char Lsb, ++ unsigned char *pReadingValue ++ ); ++ ++int FC0013_Open(TUNER_MODULE *pTuner); ++int FC0013_SetFrequency(TUNER_MODULE *pTuner, unsigned long Frequency, unsigned short Bandwidth); ++ ++// Set VHF Track depends on input frequency ++int FC0013_SetVhfTrack(TUNER_MODULE *pTuner, unsigned long Frequency); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is FC0013 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Bandwidth mode ++enum FC0013_BANDWIDTH_MODE ++{ ++ FC0013_BANDWIDTH_6000000HZ = 6, ++ FC0013_BANDWIDTH_7000000HZ = 7, ++ FC0013_BANDWIDTH_8000000HZ = 8, ++}; ++ ++ ++// Default for initialing ++#define FC0013_RF_FREQ_HZ_DEFAULT 50000000 ++#define FC0013_BANDWIDTH_MODE_DEFAULT FC0013_BANDWIDTH_8000000HZ ++ ++ ++// Tuner LNA ++enum FC0013_LNA_GAIN_VALUE ++{ ++ FC0013_LNA_GAIN_LOW = 0x00, // -6.3dB ++ FC0013_LNA_GAIN_MIDDLE = 0x08, // 7.1dB ++ FC0013_LNA_GAIN_HIGH_17 = 0x11, // 19.1dB ++ FC0013_LNA_GAIN_HIGH_19 = 0x10, // 19.7dB ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildFc0013Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++fc0013_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++fc0013_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++fc0013_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++fc0013_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++fc0013_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++fc0013_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++fc0013_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++int ++fc0013_RcCalReset( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++fc0013_RcCalAdd( ++ TUNER_MODULE *pTuner, ++ int RcValue ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_fc2580.c b/drivers/drivers/media/dvb/dvb-usb/tuner_fc2580.c +--- a/drivers/media/dvb/dvb-usb/tuner_fc2580.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_fc2580.c 2016-04-02 19:17:52.132066044 -0300 +@@ -0,0 +1,932 @@ ++/** ++ ++@file ++ ++@brief FC2580 tuner module definition ++ ++One can manipulate FC2580 tuner through FC2580 module. ++FC2580 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_fc2580.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief FC2580 tuner module builder ++ ++Use BuildFc2580Module() to build FC2580 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to FC2580 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr FC2580 I2C device address ++@param [in] CrystalFreqHz FC2580 crystal frequency in Hz ++@param [in] AgcMode FC2580 AGC mode ++ ++ ++@note ++ -# One should call BuildFc2580Module() to build FC2580 module before using it. ++ ++*/ ++void ++BuildFc2580Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int AgcMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ FC2580_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_FC2580; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = fc2580_GetTunerType; ++ pTuner->GetDeviceAddr = fc2580_GetDeviceAddr; ++ ++ pTuner->Initialize = fc2580_Initialize; ++ pTuner->SetRfFreqHz = fc2580_SetRfFreqHz; ++ pTuner->GetRfFreqHz = fc2580_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->AgcMode = AgcMode; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = fc2580_SetBandwidthMode; ++ pExtra->GetBandwidthMode = fc2580_GetBandwidthMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++fc2580_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++fc2580_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++fc2580_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ FC2580_EXTRA_MODULE *pExtra; ++ int AgcMode; ++ unsigned int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Get AGC mode. ++ AgcMode = pExtra->AgcMode; ++ ++ // Initialize tuner with AGC mode. ++ // Note: CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ CrystalFreqKhz = (unsigned int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(fc2580_set_init(pTuner, AgcMode, CrystalFreqKhz) != FC2580_FCI_SUCCESS) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++fc2580_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ FC2580_EXTRA_MODULE *pExtra; ++ unsigned int RfFreqKhz; ++ unsigned int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Set tuner RF frequency in KHz. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ // CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ RfFreqKhz = (unsigned int)((RfFreqHz + 500) / 1000); ++ CrystalFreqKhz = (unsigned int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(fc2580_set_freq(pTuner, RfFreqKhz, CrystalFreqKhz) != FC2580_FCI_SUCCESS) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++fc2580_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set FC2580 tuner bandwidth mode. ++ ++*/ ++int ++fc2580_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ FC2580_EXTRA_MODULE *pExtra; ++ unsigned int CrystalFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Set tuner bandwidth mode. ++ // Note: CrystalFreqKhz = round(CrystalFreqHz / 1000) ++ CrystalFreqKhz = (unsigned int)((pExtra->CrystalFreqHz + 500) / 1000); ++ ++ if(fc2580_set_filter(pTuner, (unsigned char)BandwidthMode, CrystalFreqKhz) != FC2580_FCI_SUCCESS) ++ goto error_status_set_tuner_bandwidth_mode; ++ ++ ++ // Set tuner bandwidth mode parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get FC2580 tuner bandwidth mode. ++ ++*/ ++int ++fc2580_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ FC2580_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Fc2580); ++ ++ ++ // Get tuner bandwidth mode from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth_mode; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by FCI. ++ ++ ++ ++ ++ ++// FCI source code - fc2580_driver_v14011_r.c ++ ++ ++/*============================================================================== ++ FILE NAME : FC2580_driver_v1400_r.c ++ ++ VERSION : 1.400_r ++ ++ UPDATE : September 22. 2008 ++ ++==============================================================================*/ ++ ++/*============================================================================== ++ ++ Chip ID of FC2580 is 0x56 or 0xAC(including I2C write bit) ++ ++==============================================================================*/ ++ ++//#include "fc2580_driver_v1400_r.h" ++ ++//fc2580_band_type curr_band = FC2580_NO_BAND; ++//unsigned int freq_xtal = 16384; ++ ++ ++/*============================================================================== ++ milisecond delay function EXTERNAL FUNCTION ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ a ++ length of wanted delay in milisecond unit ++ ++==============================================================================*/ ++void fc2580_wait_msec(TUNER_MODULE *pTuner, int a) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ ++ // Wait time in millisecond. ++ pBaseInterface->WaitMs(pBaseInterface, (unsigned long)a); ++ ++ ++ return; ++} ++ ++/*============================================================================== ++ ++ fc2580 i2c write ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ addr ++ fc2580's memory address\ ++ type : byte ++ ++ data ++ target data ++ type : byte ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_i2c_write( TUNER_MODULE *pTuner, unsigned char addr, unsigned char data ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBytes[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBytes[0] = addr; ++ WritingBytes[1] = data; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBytes, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return FC2580_FCI_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return FC2580_FCI_FAIL; ++}; ++ ++/*============================================================================== ++ ++ fc2580 i2c read ++ ++ This function is a generic function which gets called to read data from ++ fc2580's target memory address. ++ ++ ++ ++ addr ++ fc2580's memory address ++ type : byte ++ ++ ++ ++ data ++ a byte of data read out of target address 'addr' ++ type : byte ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_i2c_read( TUNER_MODULE *pTuner, unsigned char addr, unsigned char *read_data ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &addr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, read_data, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ return FC2580_FCI_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return FC2580_FCI_FAIL; ++}; ++ ++ ++ ++/*============================================================================== ++ fc2580 I2C Test ++ ++ This function is a generic function which tests I2C interface's availability ++ ++ by reading out it's I2C id data from reg. address '0x01'. ++ ++ ++ ++ None ++ ++ ++ int ++ 1 : success - communication is avilable ++ 0 : fail - communication is unavailable ++ ++ ++==============================================================================*/ ++//int fc2580_i2c_test( void ) ++//{ ++// return ( fc2580_i2c_read( 0x01 ) == 0x56 )? 0x01 : 0x00; ++//} ++ ++ ++ ++ ++/*============================================================================== ++ fc2580 initial setting ++ ++ This function is a generic function which gets called to initialize ++ ++ fc2580 in DVB-H mode or L-Band TDMB mode ++ ++ ++ ++ ifagc_mode ++ type : integer ++ 1 : Internal AGC ++ 2 : Voltage Control Mode ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_init( TUNER_MODULE *pTuner, int ifagc_mode, unsigned int freq_xtal ) ++{ ++ fc2580_fci_result_type result = FC2580_FCI_SUCCESS; ++ ++ result &= fc2580_i2c_write(pTuner, 0x00, 0x00); /*** Confidential ***/ ++ result &= fc2580_i2c_write(pTuner, 0x12, 0x86); ++ result &= fc2580_i2c_write(pTuner, 0x14, 0x5C); ++ result &= fc2580_i2c_write(pTuner, 0x16, 0x3C); ++ result &= fc2580_i2c_write(pTuner, 0x1F, 0xD2); ++ result &= fc2580_i2c_write(pTuner, 0x09, 0xD7); ++ result &= fc2580_i2c_write(pTuner, 0x0B, 0xD5); ++ result &= fc2580_i2c_write(pTuner, 0x0C, 0x32); ++ result &= fc2580_i2c_write(pTuner, 0x0E, 0x43); ++ result &= fc2580_i2c_write(pTuner, 0x21, 0x0A); ++ result &= fc2580_i2c_write(pTuner, 0x22, 0x82); ++ if( ifagc_mode == 1 ) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x45, 0x10); //internal AGC ++ result &= fc2580_i2c_write(pTuner, 0x4C, 0x00); //HOLD_AGC polarity ++ } ++ else if( ifagc_mode == 2 ) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x45, 0x20); //Voltage Control Mode ++ result &= fc2580_i2c_write(pTuner, 0x4C, 0x02); //HOLD_AGC polarity ++ } ++ result &= fc2580_i2c_write(pTuner, 0x3F, 0x88); ++ result &= fc2580_i2c_write(pTuner, 0x02, 0x0E); ++ result &= fc2580_i2c_write(pTuner, 0x58, 0x14); ++ result &= fc2580_set_filter(pTuner, 8, freq_xtal); //BW = 7.8MHz ++ ++ return result; ++} ++ ++ ++/*============================================================================== ++ fc2580 frequency setting ++ ++ This function is a generic function which gets called to change LO Frequency ++ ++ of fc2580 in DVB-H mode or L-Band TDMB mode ++ ++ ++ freq_xtal: kHz ++ ++ f_lo ++ Value of target LO Frequency in 'kHz' unit ++ ex) 2.6GHz = 2600000 ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_freq( TUNER_MODULE *pTuner, unsigned int f_lo, unsigned int freq_xtal ) ++{ ++ unsigned int f_diff, f_diff_shifted, n_val, k_val; ++ unsigned int f_vco, r_val, f_comp; ++ unsigned char pre_shift_bits = 4;// number of preshift to prevent overflow in shifting f_diff to f_diff_shifted ++ unsigned char data_0x18; ++ unsigned char data_0x02 = (USE_EXT_CLK<<5)|0x0E; ++ ++ fc2580_band_type band = ( f_lo > 1000000 )? FC2580_L_BAND : ( f_lo > 400000 )? FC2580_UHF_BAND : FC2580_VHF_BAND; ++ ++ fc2580_fci_result_type result = FC2580_FCI_SUCCESS; ++ ++ f_vco = ( band == FC2580_UHF_BAND )? f_lo * 4 : (( band == FC2580_L_BAND )? f_lo * 2 : f_lo * 12); ++ r_val = ( f_vco >= 2*76*freq_xtal )? 1 : ( f_vco >= 76*freq_xtal )? 2 : 4; ++ f_comp = freq_xtal/r_val; ++ n_val = ( f_vco / 2 ) / f_comp; ++ ++ f_diff = f_vco - 2* f_comp * n_val; ++ f_diff_shifted = f_diff << ( 20 - pre_shift_bits ); ++ k_val = f_diff_shifted / ( ( 2* f_comp ) >> pre_shift_bits ); ++ ++ if( f_diff_shifted - k_val * ( ( 2* f_comp ) >> pre_shift_bits ) >= ( f_comp >> pre_shift_bits ) ) ++ k_val = k_val + 1; ++ ++ if( f_vco >= BORDER_FREQ ) //Select VCO Band ++ data_0x02 = data_0x02 | 0x08; //0x02[3] = 1; ++ else ++ data_0x02 = data_0x02 & 0xF7; //0x02[3] = 0; ++ ++// if( band != curr_band ) { ++ switch(band) ++ { ++ case FC2580_UHF_BAND: ++ data_0x02 = (data_0x02 & 0x3F); ++ ++ result &= fc2580_i2c_write(pTuner, 0x25, 0xF0); ++ result &= fc2580_i2c_write(pTuner, 0x27, 0x77); ++ result &= fc2580_i2c_write(pTuner, 0x28, 0x53); ++ result &= fc2580_i2c_write(pTuner, 0x29, 0x60); ++ result &= fc2580_i2c_write(pTuner, 0x30, 0x09); ++ result &= fc2580_i2c_write(pTuner, 0x50, 0x8C); ++ result &= fc2580_i2c_write(pTuner, 0x53, 0x50); ++ ++ if( f_lo < 538000 ) ++ result &= fc2580_i2c_write(pTuner, 0x5F, 0x13); ++ else ++ result &= fc2580_i2c_write(pTuner, 0x5F, 0x15); ++ ++ if( f_lo < 538000 ) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x07); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x06); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x06); ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x08); ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x10); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x12); ++ } ++ else if( f_lo < 794000 ) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x03); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x03); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x03); //ACI improve ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x05); //ACI improve ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x0C); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x0E); ++ } ++ else ++ { ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x07); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x06); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x07); ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x09); ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x10); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x12); ++ } ++ ++ result &= fc2580_i2c_write(pTuner, 0x63, 0x15); ++ ++ result &= fc2580_i2c_write(pTuner, 0x6B, 0x0B); ++ result &= fc2580_i2c_write(pTuner, 0x6C, 0x0C); ++ result &= fc2580_i2c_write(pTuner, 0x6D, 0x78); ++ result &= fc2580_i2c_write(pTuner, 0x6E, 0x32); ++ result &= fc2580_i2c_write(pTuner, 0x6F, 0x14); ++ result &= fc2580_set_filter(pTuner, 8, freq_xtal); //BW = 7.8MHz ++ break; ++ case FC2580_VHF_BAND: ++ data_0x02 = (data_0x02 & 0x3F) | 0x80; ++ result &= fc2580_i2c_write(pTuner, 0x27, 0x77); ++ result &= fc2580_i2c_write(pTuner, 0x28, 0x33); ++ result &= fc2580_i2c_write(pTuner, 0x29, 0x40); ++ result &= fc2580_i2c_write(pTuner, 0x30, 0x09); ++ result &= fc2580_i2c_write(pTuner, 0x50, 0x8C); ++ result &= fc2580_i2c_write(pTuner, 0x53, 0x50); ++ result &= fc2580_i2c_write(pTuner, 0x5F, 0x0F); ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x07); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x63, 0x15); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x03); ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x05); ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x10); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x12); ++ result &= fc2580_i2c_write(pTuner, 0x6B, 0x08); ++ result &= fc2580_i2c_write(pTuner, 0x6C, 0x0A); ++ result &= fc2580_i2c_write(pTuner, 0x6D, 0x78); ++ result &= fc2580_i2c_write(pTuner, 0x6E, 0x32); ++ result &= fc2580_i2c_write(pTuner, 0x6F, 0x54); ++ result &= fc2580_set_filter(pTuner, 7, freq_xtal); //BW = 6.8MHz ++ break; ++ case FC2580_L_BAND: ++ data_0x02 = (data_0x02 & 0x3F) | 0x40; ++ result &= fc2580_i2c_write(pTuner, 0x2B, 0x70); ++ result &= fc2580_i2c_write(pTuner, 0x2C, 0x37); ++ result &= fc2580_i2c_write(pTuner, 0x2D, 0xE7); ++ result &= fc2580_i2c_write(pTuner, 0x30, 0x09); ++ result &= fc2580_i2c_write(pTuner, 0x44, 0x20); ++ result &= fc2580_i2c_write(pTuner, 0x50, 0x8C); ++ result &= fc2580_i2c_write(pTuner, 0x53, 0x50); ++ result &= fc2580_i2c_write(pTuner, 0x5F, 0x0F); ++ result &= fc2580_i2c_write(pTuner, 0x61, 0x0F); ++ result &= fc2580_i2c_write(pTuner, 0x62, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x63, 0x13); ++ result &= fc2580_i2c_write(pTuner, 0x67, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x68, 0x02); ++ result &= fc2580_i2c_write(pTuner, 0x69, 0x0C); ++ result &= fc2580_i2c_write(pTuner, 0x6A, 0x0E); ++ result &= fc2580_i2c_write(pTuner, 0x6B, 0x08); ++ result &= fc2580_i2c_write(pTuner, 0x6C, 0x0A); ++ result &= fc2580_i2c_write(pTuner, 0x6D, 0xA0); ++ result &= fc2580_i2c_write(pTuner, 0x6E, 0x50); ++ result &= fc2580_i2c_write(pTuner, 0x6F, 0x14); ++ result &= fc2580_set_filter(pTuner, 1, freq_xtal); //BW = 1.53MHz ++ break; ++ default: ++ break; ++ } ++// curr_band = band; ++// } ++ ++ //A command about AGC clock's pre-divide ratio ++ if( freq_xtal >= 28000 ) ++ result &= fc2580_i2c_write(pTuner, 0x4B, 0x22 ); ++ ++ //Commands about VCO Band and PLL setting. ++ result &= fc2580_i2c_write(pTuner, 0x02, data_0x02); ++ data_0x18 = ( ( r_val == 1 )? 0x00 : ( ( r_val == 2 )? 0x10 : 0x20 ) ) + (unsigned char)(k_val >> 16); ++ result &= fc2580_i2c_write(pTuner, 0x18, data_0x18); //Load 'R' value and high part of 'K' values ++ result &= fc2580_i2c_write(pTuner, 0x1A, (unsigned char)( k_val >> 8 ) ); //Load middle part of 'K' value ++ result &= fc2580_i2c_write(pTuner, 0x1B, (unsigned char)( k_val ) ); //Load lower part of 'K' value ++ result &= fc2580_i2c_write(pTuner, 0x1C, (unsigned char)( n_val ) ); //Load 'N' value ++ ++ //A command about UHF LNA Load Cap ++ if( band == FC2580_UHF_BAND ) ++ result &= fc2580_i2c_write(pTuner, 0x2D, ( f_lo <= (unsigned int)794000 )? 0x9F : 0x8F ); //LNA_OUT_CAP ++ ++ ++ return result; ++} ++ ++ ++/*============================================================================== ++ fc2580 filter BW setting ++ ++ This function is a generic function which gets called to change Bandwidth ++ ++ frequency of fc2580's channel selection filter ++ ++ ++ freq_xtal: kHz ++ ++ filter_bw ++ 1 : 1.53MHz(TDMB) ++ 6 : 6MHz (Bandwidth 6MHz) ++ 7 : 6.8MHz (Bandwidth 7MHz) ++ 8 : 7.8MHz (Bandwidth 8MHz) ++ ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_filter( TUNER_MODULE *pTuner, unsigned char filter_bw, unsigned int freq_xtal ) ++{ ++ unsigned char cal_mon, i; ++ fc2580_fci_result_type result = FC2580_FCI_SUCCESS; ++ ++ if(filter_bw == 1) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x36, 0x1C); ++ result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(4151*freq_xtal/1000000) ); ++ result &= fc2580_i2c_write(pTuner, 0x39, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ if(filter_bw == 6) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x36, 0x18); ++ result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(4400*freq_xtal/1000000) ); ++ result &= fc2580_i2c_write(pTuner, 0x39, 0x00); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ else if(filter_bw == 7) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x36, 0x18); ++ result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(3910*freq_xtal/1000000) ); ++ result &= fc2580_i2c_write(pTuner, 0x39, 0x80); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ else if(filter_bw == 8) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x36, 0x18); ++ result &= fc2580_i2c_write(pTuner, 0x37, (unsigned char)(3300*freq_xtal/1000000) ); ++ result &= fc2580_i2c_write(pTuner, 0x39, 0x80); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ ++ ++ for(i=0; i<5; i++) ++ { ++ fc2580_wait_msec(pTuner, 5);//wait 5ms ++ result &= fc2580_i2c_read(pTuner, 0x2F, &cal_mon); ++ if( (cal_mon & 0xC0) != 0xC0) ++ { ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x01); ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x09); ++ } ++ else ++ break; ++ } ++ ++ result &= fc2580_i2c_write(pTuner, 0x2E, 0x01); ++ ++ return result; ++} ++ ++/*============================================================================== ++ fc2580 RSSI function ++ ++ This function is a generic function which returns fc2580's ++ ++ current RSSI value. ++ ++ ++ none ++ ++ ++ int ++ rssi : estimated input power. ++ ++==============================================================================*/ ++//int fc2580_get_rssi(void) { ++// ++// unsigned char s_lna, s_rfvga, s_cfs, s_ifvga; ++// int ofs_lna, ofs_rfvga, ofs_csf, ofs_ifvga, rssi; ++// ++// fc2580_i2c_read(0x71, &s_lna ); ++// fc2580_i2c_read(0x72, &s_rfvga ); ++// fc2580_i2c_read(0x73, &s_cfs ); ++// fc2580_i2c_read(0x74, &s_ifvga ); ++// ++// ++// ofs_lna = ++// (curr_band==FC2580_UHF_BAND)? ++// (s_lna==0)? 0 : ++// (s_lna==1)? -6 : ++// (s_lna==2)? -17 : ++// (s_lna==3)? -22 : -30 : ++// (curr_band==FC2580_VHF_BAND)? ++// (s_lna==0)? 0 : ++// (s_lna==1)? -6 : ++// (s_lna==2)? -19 : ++// (s_lna==3)? -24 : -32 : ++// (curr_band==FC2580_L_BAND)? ++// (s_lna==0)? 0 : ++// (s_lna==1)? -6 : ++// (s_lna==2)? -11 : ++// (s_lna==3)? -16 : -34 : ++// 0;//FC2580_NO_BAND ++// ofs_rfvga = -s_rfvga+((s_rfvga>=11)? 1 : 0) + ((s_rfvga>=18)? 1 : 0); ++// ofs_csf = -6*s_cfs; ++// ofs_ifvga = s_ifvga/4; ++// ++// return rssi = ofs_lna+ofs_rfvga+ofs_csf+ofs_ifvga+OFS_RSSI; ++// ++//} ++ ++/*============================================================================== ++ fc2580 Xtal frequency Setting ++ ++ This function is a generic function which sets ++ ++ the frequency of xtal. ++ ++ ++ ++ frequency ++ frequency value of internal(external) Xtal(clock) in kHz unit. ++ ++==============================================================================*/ ++//void fc2580_set_freq_xtal(unsigned int frequency) { ++// ++// freq_xtal = frequency; ++// ++//} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_fc2580.h b/drivers/drivers/media/dvb/dvb-usb/tuner_fc2580.h +--- a/drivers/media/dvb/dvb-usb/tuner_fc2580.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_fc2580.h 2016-04-02 19:17:52.132066044 -0300 +@@ -0,0 +1,461 @@ ++#ifndef __TUNER_FC2580_H ++#define __TUNER_FC2580_H ++ ++/** ++ ++@file ++ ++@brief FC2580 tuner module declaration ++ ++One can manipulate FC2580 tuner through FC2580 module. ++FC2580 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_fc2580.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ FC2580_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build FC2580 tuner module. ++ BuildFc2580Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xac, // I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16384000HZ, // Crystal frequency is 16.384 MHz. ++ FC2580_AGC_INTERNAL // The FC2580 AGC mode is internal AGC mode. ++ ); ++ ++ ++ ++ ++ ++ // Get FC2580 tuner extra module. ++ pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set FC2580 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, FC2580_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get FC2580 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is source code provided by FCI. ++ ++ ++ ++ ++ ++// FCI source code - fc2580_driver_v1400_r.h ++ ++ ++/*============================================================================== ++ FILE NAME : FC2580_driver_v1400_r.h ++ ++ VERSION : 1.400_r ++ ++ UPDATE : September 22. 2008 ++ ++==============================================================================*/ ++ ++/*============================================================================== ++ ++ Chip ID of FC2580 is 0x56 or 0xAC(including I2C write bit) ++ ++==============================================================================*/ ++ ++ ++#define BORDER_FREQ 2600000 //2.6GHz : The border frequency which determines whether Low VCO or High VCO is used ++#define USE_EXT_CLK 0 //0 : Use internal XTAL Oscillator / 1 : Use External Clock input ++#define OFS_RSSI 57 ++ ++typedef enum { ++ FC2580_UHF_BAND, ++ FC2580_L_BAND, ++ FC2580_VHF_BAND, ++ FC2580_NO_BAND ++} fc2580_band_type; ++ ++typedef enum { ++ FC2580_FCI_FAIL, ++ FC2580_FCI_SUCCESS ++} fc2580_fci_result_type; ++ ++/*============================================================================== ++ i2c command write EXTERNAL FUNCTION ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ slave_id ++ i2c id of slave chip ++ type : byte ++ ++ addr ++ memory address of slave chip ++ type : byte ++ ++ data ++ target data ++ type : byte ++ ++==============================================================================*/ ++//extern fc2580_fci_result_type i2c_write( unsigned char slave_id, unsigned char addr, unsigned char *data, unsigned char n ); ++ ++/*============================================================================== ++ i2c command write EXTERNAL FUNCTION ++ ++ This function is a generic function which gets called to read data from ++ slave chip's target memory address. ++ ++ ++ ++ slave_id ++ i2c id of slave chip ++ type : byte ++ ++ addr ++ memory address of slave chip ++ type : byte ++ ++ ++ data ++ a byte of data read out of target address 'addr' of slave chip ++ type : byte ++ ++==============================================================================*/ ++//extern fc2580_fci_result_type i2c_read( unsigned char slave_id, unsigned char addr, unsigned char *read_data, unsigned char n ); ++ ++/*============================================================================== ++ milisecond delay function EXTERNAL FUNCTION ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ a ++ length of wanted delay in milisecond unit ++ ++==============================================================================*/ ++extern void fc2580_wait_msec(TUNER_MODULE *pTuner, int a); ++ ++ ++ ++/*============================================================================== ++ fc2580 i2c command write ++ ++ This function is a generic function which write a byte into fc2580's ++ specific address. ++ ++ ++ ++ addr ++ fc2580's memory address ++ type : byte ++ ++ data ++ target data ++ type : byte ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_i2c_write( TUNER_MODULE *pTuner, unsigned char addr, unsigned char data ); ++ ++/*============================================================================== ++ fc2580 i2c data read ++ ++ This function is a generic function which gets called to read data from ++ fc2580's target memory address. ++ ++ ++ ++ addr ++ fc2580's memory address ++ type : byte ++ ++ ++ ++ data ++ a byte of data read out of target address 'addr' ++ type : byte ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_i2c_read( TUNER_MODULE *pTuner, unsigned char addr, unsigned char *read_data ); ++ ++/*============================================================================== ++ fc2580 initial setting ++ ++ This function is a generic function which gets called to initialize ++ ++ fc2580 in DVB-H mode or L-Band TDMB mode ++ ++ ++ ++ ifagc_mode ++ type : integer ++ 1 : Internal AGC ++ 2 : Voltage Control Mode ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_init( TUNER_MODULE *pTuner, int ifagc_mode, unsigned int freq_xtal ); ++ ++/*============================================================================== ++ fc2580 frequency setting ++ ++ This function is a generic function which gets called to change LO Frequency ++ ++ of fc2580 in DVB-H mode or L-Band TDMB mode ++ ++ ++ ++ f_lo ++ Value of target LO Frequency in 'kHz' unit ++ ex) 2.6GHz = 2600000 ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_freq( TUNER_MODULE *pTuner, unsigned int f_lo, unsigned int freq_xtal ); ++ ++ ++/*============================================================================== ++ fc2580 filter BW setting ++ ++ This function is a generic function which gets called to change Bandwidth ++ ++ frequency of fc2580's channel selection filter ++ ++ ++ ++ filter_bw ++ 1 : 1.53MHz(TDMB) ++ 6 : 6MHz ++ 7 : 7MHz ++ 8 : 7.8MHz ++ ++ ++==============================================================================*/ ++fc2580_fci_result_type fc2580_set_filter( TUNER_MODULE *pTuner, unsigned char filter_bw, unsigned int freq_xtal ); ++ ++/*============================================================================== ++ fc2580 RSSI function ++ ++ This function is a generic function which returns fc2580's ++ ++ current RSSI value. ++ ++ ++ ++ ++==============================================================================*/ ++//int fc2580_get_rssi(void); ++ ++/*============================================================================== ++ fc2580 Xtal frequency Setting ++ ++ This function is a generic function which sets ++ ++ the frequency of xtal. ++ ++ ++ ++ frequency ++ frequency value of internal(external) Xtal(clock) in kHz unit. ++ ++==============================================================================*/ ++//void fc2580_set_freq_xtal(unsigned int frequency); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is FC2580 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// AGC mode ++enum FC2580_AGC_MODE ++{ ++ FC2580_AGC_INTERNAL = 1, ++ FC2580_AGC_EXTERNAL = 2, ++}; ++ ++ ++// Bandwidth mode ++enum FC2580_BANDWIDTH_MODE ++{ ++ FC2580_BANDWIDTH_1530000HZ = 1, ++ FC2580_BANDWIDTH_6000000HZ = 6, ++ FC2580_BANDWIDTH_7000000HZ = 7, ++ FC2580_BANDWIDTH_8000000HZ = 8, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildFc2580Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int AgcMode ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++fc2580_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++fc2580_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++fc2580_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++fc2580_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++fc2580_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++fc2580_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++fc2580_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_max3543.c b/drivers/drivers/media/dvb/dvb-usb/tuner_max3543.c +--- a/drivers/media/dvb/dvb-usb/tuner_max3543.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_max3543.c 2016-04-02 19:17:52.136066045 -0300 +@@ -0,0 +1,1441 @@ ++/** ++ ++@file ++ ++@brief MAX3543 tuner module definition ++ ++One can manipulate MAX3543 tuner through MAX3543 module. ++MAX3543 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_max3543.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief MAX3543 tuner module builder ++ ++Use BuildMax3543Module() to build MAX3543 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to MAX3543 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr MAX3543 I2C device address ++@param [in] CrystalFreqHz MAX3543 crystal frequency in Hz ++@param [in] StandardMode MAX3543 standard mode ++@param [in] IfFreqHz MAX3543 IF frequency in Hz ++@param [in] OutputMode MAX3543 output mode ++ ++ ++@note ++ -# One should call BuildMax3543Module() to build MAX3543 module before using it. ++ ++*/ ++void ++BuildMax3543Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int StandardMode, ++ unsigned long IfFreqHz, ++ int OutputMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_MAX3543; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->RfFreqHz = MAX3543_RF_FREQ_HZ_DEFAULT; ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = max3543_GetTunerType; ++ pTuner->GetDeviceAddr = max3543_GetDeviceAddr; ++ ++ pTuner->Initialize = max3543_Initialize; ++ pTuner->SetRfFreqHz = max3543_SetRfFreqHz; ++ pTuner->GetRfFreqHz = max3543_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->StandardMode = StandardMode; ++ pExtra->IfFreqHz = IfFreqHz; ++ pExtra->OutputMode = OutputMode; ++ pExtra->BandwidthMode = MAX3543_BANDWIDTH_MODE_DEFAULT; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ pExtra->broadcast_standard = StandardMode; ++ ++ switch(CrystalFreqHz) ++ { ++ default: ++ case CRYSTAL_FREQ_16000000HZ: ++ ++ switch(IfFreqHz) ++ { ++ default: ++ case IF_FREQ_36170000HZ: ++ ++ pExtra->XTALSCALE = 8; ++ pExtra->XTALREF = 128; ++ pExtra->LOSCALE = 65; ++ ++ break; ++ } ++ } ++ ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = max3543_SetBandwidthMode; ++ pExtra->GetBandwidthMode = max3543_GetBandwidthMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++max3543_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++max3543_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++max3543_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Initializing tuner. ++ // Note: Call MAX3543 source code function. ++ if(MAX3543_Init(pTuner) != MAX3543_SUCCESS) ++ goto error_status_execute_function; ++ ++ // Set tuner standard mode and output mode. ++ // Note: Call MAX3543 source code function. ++ if(MAX3543_Standard(pTuner, pExtra->StandardMode, pExtra->OutputMode) != MAX3543_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++max3543_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ unsigned long FreqUnit; ++ unsigned short CalculatedValue; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Calculate frequency unit. ++ FreqUnit = MAX3543_CONST_1_MHZ / pExtra->LOSCALE; ++ ++ // Set tuner RF frequency in KHz. ++ // Note: 1. CalculatedValue = round(RfFreqHz / FreqUnit) ++ // 2. Call MAX3543 source code function. ++ CalculatedValue = (unsigned short)((RfFreqHz + (FreqUnit / 2)) / FreqUnit); ++ ++ if(MAX3543_SetFrequency(pTuner, CalculatedValue) != MAX3543_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++max3543_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MAX3543 tuner bandwidth mode. ++ ++*/ ++int ++max3543_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ unsigned short BandwidthModeUshort; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Set tuner bandwidth mode. ++ // Note: Call MAX3543 source code function. ++ BandwidthModeUshort = (unsigned short)BandwidthMode; ++ ++ if(MAX3543_ChannelBW(pTuner, BandwidthModeUshort) != MAX3543_SUCCESS) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner bandwidth Hz parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MAX3543 tuner bandwidth mode. ++ ++*/ ++int ++max3543_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ // Get tuner bandwidth Hz from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth_mode; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Function (implemeted for MAX3543) ++int ++Max3543_Read( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned short *pData ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingByte; ++ unsigned char ReadingByte; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + stop_bit ++ WritingByte = (unsigned char)RegAddr; ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &WritingByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, &ReadingByte, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ *pData = (unsigned short)ReadingByte; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++ ++ ++int ++Max3543_Write( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned short Data ++ ) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBuffer[0] = (unsigned char)RegAddr; ++ WritingBuffer[1] = (unsigned char)Data; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_set_tuner_registers: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by MAXIM. ++ ++ ++ ++ ++ ++// MAXIM source code - Max3543_Driver.c ++ ++ ++/* ++------------------------------------------------------------------------- ++| MAX3543 Tuner Driver ++| Author: Paul Nichol ++| ++| Version: 1.0.3 ++| Date: 12/09/09 ++| ++| ++| Copyright (C) 2009 Maxim Integrated Products. ++| PLEASE READ THE ATTACHED LICENSE CAREFULLY BEFORE USING THIS SOFTWARE. ++| BY USING THE SOFTWARE OF MAXIM INTEGRATED PRODUCTS, INC, YOU ARE AGREEING ++| TO BE BOUND BY THE TERMS OF THE ATTACHED LICENSE, WHICH INCLUDES THE SOFTWARE ++| LICENSE AND SOFTWARE WARRANTY DISCLAIMER, EVEN WITHOUT YOUR SIGNATURE. ++| IF YOU DO NOT AGREE TO THE TERMS OF THIS AGREEMENT, DO NOT USE THIS SOFTWARE. ++| ++| IMPORTANT: This code is operate the Max3543 Multi-Band Terrestrial ++| Hybrid Tuner. Routines include: initializing, tuning, reading the ++| ROM table, reading the lock detect status and tuning the tracking ++| filter. Only integer math is used in this program and no floating point ++| variables are used. Your MCU must be capable of processing unsigned 32 bit integer ++| math to use this routine. (That is: two 16 bit numbers multiplied resulting in a ++| 32 bit result, or a 32 bit number divided by a 16 bit number). ++| ++-------------------------------------------------------------------------- ++*/ ++ ++ ++//#include ++//#include ++///#include ++//#include "mxmdef.h" ++//#include "Max3543_Driver.h" ++ ++/* ++double debugreg[10]; ++UINT_16 TFRomCoefs[3][4]; ++UINT_16 denominator; ++UINT_32 fracscale ; ++UINT_16 regs[22]; ++UINT_16 IF_Frequency; ++*/ ++ ++/* table of fixed coefficients for the tracking filter equations. */ ++ ++const ++static UINT_16 co[6][5]={{ 26, 6, 68, 20, 45 }, /* VHF LO TFS */ ++ { 16, 8, 88, 40, 0 }, /* VHF LO TFP */ ++ { 27, 10, 54, 30,20 }, /* VHF HI TFS */ ++ { 18, 10, 41, 20, 0 }, /* VHF HI TFP */ ++ { 32, 10, 34, 8, 10 }, /* UHF TFS */ ++ { 13, 15, 21, 16, 0 }}; /* UHF TFP */ ++ ++ ++ ++//int MAX3543_Init(TUNER_MODULE *pTuner, UINT_16 RfFreq) ++int MAX3543_Init(TUNER_MODULE *pTuner) ++{ ++ /* ++ Initialize every register. Don't rely on MAX3543 power on reset. ++ Call before using the other routines in this file. ++ */ ++ UINT_16 RegNumber; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ unsigned long FreqUnit; ++ unsigned short CalculatedValue; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ /*Initialize the registers in the MAX3543:*/ ++ ++ ++ ++ pExtra->regs[REG3543_VCO] = 0x4c; ++ pExtra->regs[REG3543_NDIV] = 0x2B; ++ pExtra->regs[REG3543_FRAC2] = 0x8E; ++ pExtra->regs[REG3543_FRAC1] = 0x26; ++ pExtra->regs[REG3543_FRAC0] = 0x66; ++ pExtra->regs[REG3543_MODE] = 0xd8; ++ pExtra->regs[REG3543_TFS] = 0x00; ++ pExtra->regs[REG3543_TFP] = 0x00; ++ pExtra->regs[REG3543_SHDN] = 0x00; ++ pExtra->regs[REG3543_REF] = 0x0a; ++ pExtra->regs[REG3543_VAS] = 0x17; ++ pExtra->regs[REG3543_PD_CFG1] = 0x43; ++ pExtra->regs[REG3543_PD_CFG2] = 0x01; ++ pExtra->regs[REG3543_FILT_CF] = 0x25; ++ pExtra->regs[REG3543_ROM_ADDR] = 0x00; ++ pExtra->regs[REG3543_IRHR] = 0x80; ++ pExtra->regs[REG3543_BIAS_ADJ] = 0x57; ++ pExtra->regs[REG3543_TEST1] = 0x40; ++ pExtra->regs[REG3543_ROM_WRITE] = 0x00; ++ ++ ++ ++ /* Write each register out to the MAX3543: */ ++ for (RegNumber=0;RegNumber<=MAX3543_NUMREGS;RegNumber++) ++ { ++// Max3543_Write(RegNumber, regs[RegNumber]); ++ if(Max3543_Write(pTuner, RegNumber, pExtra->regs[RegNumber]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ } ++ ++ /* First read calibration constants from MAX3543 and store in global ++ variables for use when setting RF tracking filter */ ++// MAX3543_ReadROM(); ++ if(MAX3543_ReadROM(pTuner) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Define the IF frequency used. ++ If using non-floating point math, enter the IF Frequency multiplied ++ by the factor LOSCALE here as an integer. ++ i.e. IF_Frequency = 1445; ++ If using floating point math, use the scalefrq macro: ++ i.e. IF_Frequency = scalefrq(36.125); ++ */ ++// IF_Frequency = scalefrq(36.125); ++ ++ ++ // Calculate frequency unit. ++ FreqUnit = MAX3543_CONST_1_MHZ / pExtra->LOSCALE; ++ ++ // Set tuner RF frequency in KHz. ++ // Note: 1. CalculatedValue = round(RfFreqHz / FreqUnit) ++ // 2. Call MAX3543 source code function. ++ CalculatedValue = (unsigned short)((pExtra->IfFreqHz + (FreqUnit / 2)) / FreqUnit); ++ pExtra->IF_Frequency = CalculatedValue; ++ ++ ++ /* Calculate the denominator just once since it is dependant on the xtal freq only. ++ The denominator is used to calculate the N+FractionalN ratio. ++ */ ++ pExtra->denominator = pExtra->XTALREF * 4 * pExtra->LOSCALE; ++ ++ /* The fracscale is used to calculate the fractional remainder of the N+FractionalN ratio. */ ++ pExtra->fracscale = 2147483648U/pExtra->denominator; ++ ++ ++// Note: Set standard mode, channel bandwith, and RF frequency in other functions. ++ ++// MAX3543_Standard(DVB_T, IFOUT1_DIFF_DTVOUT); ++ ++// MAX3543_ChannelBW(BW8MHZ); ++ // Note: Set bandwidth with 8 MHz for QAM. ++ MAX3543_ChannelBW(pTuner, MAX3543_BANDWIDTH_MODE_DEFAULT); ++ ++// MAX3543_SetFrequency(RfFreq); ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++/* Set the channel bandwidth. Call with arguments: BW7MHZ or BW8MHZ */ ++int MAX3543_ChannelBW(TUNER_MODULE *pTuner, UINT_16 bw) ++{ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ pExtra->regs[REG3543_MODE] = (pExtra->regs[REG3543_MODE] & 0xef) | (bw<<4); ++// Max3543_Write(REG3543_MODE, regs[REG3543_MODE]); ++ if(Max3543_Write(pTuner, REG3543_MODE, pExtra->regs[REG3543_MODE]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++/* ++ Set the broadcast standared and RF signal path. ++ This routine must be called prior to tuning (Set_Frequency() ) ++ such as in MAX3543_Init() or when necessary to change modes. ++ ++ This sub routine has 2 input/function ++ 1. bcstd:it set MAX3543 to optimized power detector/bias setting for each standard (dvb-t,pal?, currently it has 4 choice: ++ 1.1 bcstd=DVBT, optimized for DVB-T ++ 1.2 bcstd=DVBC, optimized for DVB-C ++ 1.3 bcstd=ATV1, optimized for PAL/SECAM - B/G/D/K/I ++ 1.4 bcstd=ATV2, optimized for SECAM-L ++ 2. outputmode: this setting has to match you hardware signal path, it has 3 choice: ++ 2.1 outputmode=IFOUT1_DIFF_IFOUT_DIFF ++ signal path: IFOUT1 (pin6/7) driving a diff input IF filter (ie LC filter or 6966 SAW), ++ then go back to IFVGA input (pin 10/11) and IF output of MAX3543 is pin 15/16. ++ this is common seting for all DTV_only demod and hybrid demod ++ 2.2 outputmode=IFOUT1_SE_IFOUT_DIFF ++ signal path: IFOUT1 (pin6) driving a single-ended input IF filter (ie 7251 SAW) ++ then go back to IFVGA input (pin 10/11) and IF output of MAX3543 is pin 15/16. ++ this is common seting for all DTV_only demod and hybrid demod ++ 2.3 outputmode=IFOUT2 ++ signal path: IFOUT2 (pin14) is MAX3543 IF output, normally it drives a ATV demod. ++ The IFVGA is shutoff ++ this is common setting for separate ATV demod app ++*/ ++ ++int MAX3543_Standard(TUNER_MODULE *pTuner, standard bcstd, outputmode outmd) ++{ ++ char IFSEL; ++ char LNA2G; ++ char SDIVG; ++ char WPDA; ++ char NPDA; ++ char RFIFD; ++ char MIXGM; ++ char LNA2B; ++ char MIXB; ++ ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ pExtra->broadcast_standard = bcstd; /* used later in tuning */ ++ ++ ++ switch ( bcstd ) ++ { ++ case DVB_T: ++ LNA2G = 1; ++ WPDA = 4; ++ NPDA = 3; ++ RFIFD = 1; ++ MIXGM = 1; ++ LNA2B = 1; ++ MIXB = 1; ++ break; ++ case DVB_C: ++ LNA2G = 1; ++ WPDA = 3; ++ NPDA = 3; ++ RFIFD = 1; ++ MIXGM = 1; ++ LNA2B = 1; ++ MIXB = 1; ++ break; ++ case ATV: ++ LNA2G = 0; ++ WPDA = 3; ++ NPDA = 5; ++ RFIFD = 2; ++ MIXGM = 0; ++ LNA2B = 3; ++ MIXB = 3; ++ break; ++ case ATV_SECAM_L: ++ LNA2G = 0; ++ WPDA = 3; ++ NPDA = 3; ++ RFIFD = 2; ++ MIXGM = 0; ++ LNA2B = 3; ++ MIXB = 3; ++ break; ++ default: ++ return MAX3543_ERROR; ++ } ++ ++ /* the outmd must be set after the standard mode bits are set. ++ Please do not change order. */ ++ switch ( outmd ) ++ { ++ case IFOUT1_DIFF_DTVOUT: ++ IFSEL = 0; ++ SDIVG = 0; ++ break; ++ case IFOUT1_SE_DTVOUT: ++ IFSEL = 1; ++ SDIVG = 0; ++ break; ++ case IFOUT2: ++ IFSEL = 2; ++ SDIVG = 1; ++ NPDA = 3; ++ LNA2G = 1; /* overrites value chosen above for this case */ ++ RFIFD = 3; /* overrites value chosen above for this case */ ++ break; ++ default: ++ return MAX3543_ERROR; ++ } ++ ++ ++ /* Mask in each set of bits into the register variables */ ++ pExtra->regs[REG3543_MODE] = (pExtra->regs[REG3543_MODE] & 0x7c) | IFSEL | (LNA2G<<7); ++ pExtra->regs[REG3543_SHDN] = (pExtra->regs[REG3543_SHDN] & 0xf7) | (SDIVG<<3); ++ pExtra->regs[REG3543_PD_CFG1] = (pExtra->regs[REG3543_PD_CFG1] & 0x88) | (WPDA<<4) | NPDA; ++ pExtra->regs[REG3543_PD_CFG2] = (pExtra->regs[REG3543_PD_CFG2] & 0xfc) | RFIFD; ++ pExtra->regs[REG3543_BIAS_ADJ] = (pExtra->regs[REG3543_BIAS_ADJ] & 0x13) | (MIXGM<<6) | (LNA2B<<4) | (MIXB<<2); ++ ++ /* Send each register variable: */ ++// Max3543_Write(REG3543_MODE, regs[REG3543_MODE]); ++ if(Max3543_Write(pTuner, REG3543_MODE, pExtra->regs[REG3543_MODE]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_SHDN, regs[REG3543_SHDN]); ++ if(Max3543_Write(pTuner, REG3543_SHDN, pExtra->regs[REG3543_SHDN]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_PD_CFG1, regs[REG3543_PD_CFG1]); ++ if(Max3543_Write(pTuner, REG3543_PD_CFG1, pExtra->regs[REG3543_PD_CFG1]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_PD_CFG2, regs[REG3543_PD_CFG2]); ++ if(Max3543_Write(pTuner, REG3543_PD_CFG2, pExtra->regs[REG3543_PD_CFG2]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_BIAS_ADJ, regs[REG3543_BIAS_ADJ]); ++ if(Max3543_Write(pTuner, REG3543_BIAS_ADJ, pExtra->regs[REG3543_BIAS_ADJ]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++/*This will set the LO Frequency and all other tuning related register bits. ++ ++ NOTE!!!! The frequency passed to this routine must be scaled by th factor ++ LOSCALE. For example if the frequency was 105.25 MHz you multiply ++ this by LOSCALE which results in a whole number frequency. ++ For example if LOSCALE = 20, then 105.25 * 20 = 2105. ++ You would then call: MAX3543_SetFrequency(2105); ++*/ ++int MAX3543_SetFrequency(TUNER_MODULE *pTuner, UINT_16 RF_Frequency) ++{ ++ UINT_16 RDiv, NewR, NDiv, Vdiv; ++ UINT_32 Num; ++ UINT_16 LO_Frequency; ++ UINT_16 Rem; ++ UINT_32 FracN; ++ ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ LO_Frequency = RF_Frequency + pExtra->IF_Frequency ; ++ ++ /* Determine VCO Divider */ ++ if (LO_Frequency < scalefrq(138)) /* 138MHz scaled UHF band */ ++ { ++ Vdiv = 3; /* divide by 32 */ ++ } ++ else if ( LO_Frequency < scalefrq(275)) /* VHF Band */ ++ { ++ Vdiv = 2; /* divide by 16 */ ++ } ++ else if (LO_Frequency < scalefrq(550)) ++ { ++ Vdiv = 1; /* divide by 8 */ ++ } ++ else ++ { ++ Vdiv = 0; /* divide by 4 */ ++ } ++ ++ ++ /* calculate the r-divider from the RDIV bits: ++ RDIV bits RDIV ++ 00 1 ++ 01 2 ++ 10 4 ++ 11 8 ++ */ ++ RDiv = 1<<((pExtra->regs[REG3543_FRAC2] & 0x30) >> 4); ++ ++ /* Set the R-Divider based on the frequency if in DVB mode. ++ Otherwise set the R-Divider to 2. ++ Only send RDivider if it needs to change from the current state. ++ */ ++ NewR = 0; ++ if ((pExtra->broadcast_standard == DVB_T || pExtra->broadcast_standard == DVB_C) ) ++ { ++ if ((LO_Frequency <= scalefrq(275)) && (RDiv == 1)) ++ NewR = 2; ++ else if ((LO_Frequency > scalefrq(275)) && (RDiv == 2)) ++ NewR = 1; ++ } ++ else if (RDiv == 1) ++ NewR = 2; ++ ++ if (NewR != 0){ ++ RDiv = NewR; ++ pExtra->regs[REG3543_FRAC2] = (pExtra->regs[REG3543_FRAC2] & 0xcf) | ((NewR-1) <<4); ++// Max3543_Write(REG3543_FRAC2, regs[REG3543_FRAC2]); ++ if(Max3543_Write(pTuner, REG3543_FRAC2, pExtra->regs[REG3543_FRAC2]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ } ++ ++ /* Update the VDIV bits in the VCO variable. ++ we will write this variable out to the VCO register during the MAX3543_SeedVCO routine. ++ We can write over all the other bits (D<7:2>) in that register variable because they ++ will be filled in: MAX3543_SeedVCO later. ++ */ ++ pExtra->regs[REG3543_VCO] = Vdiv; ++ ++ /* now convert the Vdiv bits into the multiplier for use in the equation: ++ Vdiv Mult ++ 0 4 ++ 1 8 ++ 2 16 ++ 3 32 ++ */ ++ Vdiv = 1<<(Vdiv+2); ++ ++ ++ //#ifdef HAVE_32BIT_MATH ++ ++ /* Calculate Numerator and Denominator for N+FN calculation */ ++ Num = LO_Frequency * RDiv * Vdiv * pExtra->XTALSCALE; ++ ++ ++ NDiv = (UINT_16) (Num/(UINT_32)pExtra->denominator); /* Note: this is an integer division, returns 16 bit value. */ ++ ++// Max3543_Write(REG3543_NDIV,NDiv); ++ if(Max3543_Write(pTuner, REG3543_NDIV,NDiv) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Calculate whole number remainder from division of Num by denom: ++ Returns 16 bit value. */ ++ Rem = (UINT_16)(Num - (UINT_32) NDiv * (UINT_32) pExtra->denominator); ++ ++ /* FracN = Rem * 2^20/Denom, Scale 2^20/Denom 2048 X larger for more accuracy. */ ++ /* fracscale = 2^31/denom. 2048 = 2^31/2^20 */ ++ FracN =(Rem*pExtra->fracscale)/2048; ++ ++ ++ ++ /* Optional - Seed the VCO to cause it to tune faster. ++ (LO_Frequency/LOSCALE) * Vdiv = the unscaled VCO Frequency. ++ It is unscaled to prevent overflow when it is multiplied by vdiv. ++ */ ++// MAX3543_SeedVCO((LO_Frequency/LOSCALE) * Vdiv); ++ if(MAX3543_SeedVCO(pTuner, (LO_Frequency/pExtra->LOSCALE) * Vdiv) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ ++ pExtra->regs[REG3543_FRAC2] = (pExtra->regs[REG3543_FRAC2] & 0xf0) | ((UINT_16)(FracN >> 16) & 0xf); ++// Max3543_Write(REG3543_FRAC2, regs[REG3543_FRAC2]); ++ if(Max3543_Write(pTuner, REG3543_FRAC2, pExtra->regs[REG3543_FRAC2]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_FRAC1,(UINT_16)(FracN >> 8) & 0xff); ++ if(Max3543_Write(pTuner, REG3543_FRAC1,(UINT_16)(FracN >> 8) & 0xff) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_FRAC0, (UINT_16) FracN & 0xff); ++ if(Max3543_Write(pTuner, REG3543_FRAC0, (UINT_16) FracN & 0xff) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Program tracking filters and other frequency dependent registers */ ++// MAX3543_SetTrackingFilter(RF_Frequency); ++ if(MAX3543_SetTrackingFilter(pTuner, RF_Frequency) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++/*As you tune in frequency, the tracking filter needs ++to be set as a function of frequency. Stored in the ROM on the ++IC are two end points for the VHFL, VHFH, and UHF frequency bands. ++This routine performs the necessary function to calculate the ++needed series and parallel capacitor values from these two end ++points for the current frequency. Once the value is calculated, ++it is loaded into the Tracking Filter Caps register and the ++internal capacitors are switched in tuning the tracking ++filter. ++*/ ++int MAX3543_SetTrackingFilter(TUNER_MODULE *pTuner, UINT_16 RF_Frequency) ++{ ++ /* Calculate the series and parallel capacitor values for the given frequency */ ++ /* band. These values are then written to the registers. This causes the */ ++ /* MAX3543's internal series and parallel capacitors to change thus tuning the */ ++ /* tracking filter to the proper frequency. */ ++ ++ UINT_16 TFB, tfs, tfp, RFin, HRF; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ /* Set the TFB Bits (Tracking Filter Band) for the given frequency. */ ++ if (RF_Frequency < scalefrq(196)) /* VHF Low Band */ ++ { ++ TFB = VHF_L; ++ } ++ else if (RF_Frequency < scalefrq(440)) /* VHF High 196-440 MHz */ ++ { ++ TFB = VHF_H; ++ } ++ else{ /* UHF */ ++ TFB = UHF; ++ } ++ ++ /* Set the RFIN bit. RFIN selects a input low pass filter */ ++ if (RF_Frequency < scalefrq(345)){ /* 345 MHz is the change over point. */ ++ RFin = 0; ++ } ++ else{ ++ RFin = 1; ++ } ++ ++ if (RF_Frequency < scalefrq(110)){ /* 110 MHz is the change over point. */ ++ HRF = 1; ++ } ++ else{ ++ HRF = 0; ++ } ++ ++ /* Write the TFB<1:0> Bits and the RFIN bit into the IFOVLD register */ ++ /* TFB sets the tracking filter band in the chip, RFIN selects the RF input */ ++ pExtra->regs[REG3543_MODE] = (pExtra->regs[REG3543_MODE] & 0x93 ) | (TFB << 2) | (RFin << 6) | (HRF<<5); ++// Max3543_Write(REG3543_MODE,(regs[REG3543_MODE])) ; ++ if(Max3543_Write(pTuner, REG3543_MODE,(pExtra->regs[REG3543_MODE])) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ tfs = tfs_i(pExtra->TFRomCoefs[TFB][SER0], pExtra->TFRomCoefs[TFB][SER1], RF_Frequency/pExtra->LOSCALE, co[TFB*2]); ++ tfp = tfs_i(pExtra->TFRomCoefs[TFB][PAR0], pExtra->TFRomCoefs[TFB][PAR1], RF_Frequency/pExtra->LOSCALE, co[(TFB*2)+1]); ++ ++ /* Write the TFS Bits into the Tracking Filter Series Capacitor register */ ++ if (tfs > 255) /* 255 = 8 bits of TFS */ ++ tfs = 255; ++ if (tfs < 0) ++ tfs = 0; ++ pExtra->regs[REG3543_TFS] = tfs; ++ ++ /* Write the TFP Bits into the Tracking Filter Parallel Capacitor register */ ++ if (tfp > 63) /* 63 = 6 bits of TFP */ ++ tfp = 63; ++ if (tfp < 0) ++ tfp = 0; ++ pExtra->regs[REG3543_TFP] = (pExtra->regs[REG3543_TFP] & 0xc0 ) | tfp; ++ ++ /* Send registers that have been changed */ ++ /* Maxim evkit I2c communication... Replace by microprocessor specific code */ ++// Max3543_Write(REG3543_TFS,(regs[REG3543_TFS])) ; ++ if(Max3543_Write(pTuner, REG3543_TFS,(pExtra->regs[REG3543_TFS])) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++// Max3543_Write(REG3543_TFP,(regs[REG3543_TFP])) ; ++ if(Max3543_Write(pTuner, REG3543_TFP,(pExtra->regs[REG3543_TFP])) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++ ++ ++/* calculate aproximation for Max3540 tracking filter useing integer math only */ ++ ++UINT_16 tfs_i(UINT_16 S0, UINT_16 S1, UINT_16 FreqRF, const UINT_16 c[5]) ++{ UINT_16 i,y,y1,y2,y3,y4,y5,y6,y7,add; ++ UINT_32 res; ++ ++/* y=4*((64*c[0])+c[1]*S0)-((64*c[2]-(S1*c[3]))*(FreqRF))/250; */ ++ y1=64*c[0]; ++ y2=c[1]*S0; ++ y3=4*(y1+y2); ++ y4=S1*c[3]; ++ y5=64*c[2]; ++ y6=y5-y4; ++ y7=(y6*(FreqRF))/250; ++ if (y7((UINT_32)100*c[4])) res=(res+50*1)/100-c[4]; ++ else res=0; ++ ++ if (res<255) return (UINT_16) res; else return 255; ++} ++ ++/* ++ As soon as you program the Frac0 register, a state machine is started to find the ++ correct VCO for the N and Fractional-N values entered. ++ If the VASS bit is set, the search routine will start from the band and ++ sub-band that is currently programmed into the VCO register (VCO and VSUB bits = seed). ++ If you seed the register with bands close to where the auto routine will ++ finally select, the search routine will finish much faster. ++ This routine determines the best seed to use for the VCO and VSUB values. ++ If VASS is cleared, the search will start as the lowest VCO and search up. ++ This takes much longer. Make sure VASS is set before using this routine. ++ For the seed value to be read in the VCO register, it must be there prior to ++ setting the Frac0 register. So call this just before setting the Fractional-N ++ registers. The VASS bit is bit 5 of register 10 (or REG3543_VAS). ++*/ ++int MAX3543_SeedVCO(TUNER_MODULE *pTuner, UINT_16 Fvco){ ++ /* Fvco is the VCO frequency in MHz and is not scaled by LOSCALE */ ++ UINT_16 VCO; ++ UINT_16 VSUB; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ if (Fvco <= 2750) ++ { ++ /* The VCO seed: */ ++ ++ VCO = 0; ++ /* Determine the VCO sub-band (VSUB) seed: */ ++ if (Fvco < 2068) ++ VSUB = 0; ++ else if (Fvco < 2101) ++ VSUB = 1; ++ else if (Fvco < 2137) ++ VSUB = 2; ++ else if (Fvco < 2174) ++ VSUB = 3; ++ else if (Fvco < 2215) ++ VSUB = 4; ++ else if (Fvco < 2256) ++ VSUB = 5; ++ else if (Fvco < 2300) ++ VSUB = 6; ++ else if (Fvco < 2347) ++ VSUB = 7; ++ else if (Fvco < 2400) ++ VSUB = 8; ++ else if (Fvco < 2453) ++ VSUB = 9; ++ else if (Fvco < 2510) ++ VSUB = 10; ++ else if (Fvco < 2571) ++ VSUB = 11; ++ else if (Fvco < 2639) ++ VSUB = 12; ++ else if (Fvco < 2709) ++ VSUB = 13; ++ else if (Fvco < 2787) ++ VSUB = 14; ++ } ++ else if (Fvco <= 3650) ++ { ++ /* The VCO seed: */ ++ VCO = 1; ++ /* Determine the VCO sub-band (VSUB) seed: */ ++ if (Fvco <= 2792) ++ VSUB = 1; ++ else if (Fvco <= 2839) ++ VSUB = 2; ++ else if (Fvco <= 2890) ++ VSUB = 3; ++ else if (Fvco <= 2944) ++ VSUB = 4; ++ else if (Fvco <= 3000) ++ VSUB = 5; ++ else if (Fvco <= 3059) ++ VSUB = 6; ++ else if (Fvco <= 3122) ++ VSUB = 7; ++ else if (Fvco <= 3194) ++ VSUB = 8; ++ else if (Fvco <= 3266) ++ VSUB = 9; ++ else if (Fvco <= 3342) ++ VSUB = 10; ++ else if (Fvco <= 3425) ++ VSUB = 11; ++ else if (Fvco <= 3516) ++ VSUB = 12; ++ else if (Fvco <= 3612) ++ VSUB = 13; ++ else if (Fvco <= 3715) ++ VSUB = 14; ++ } ++ else ++ { ++ /* The VCO seed: */ ++ VCO = 2; ++ /* Determine the VCO sub-band (VSUB) seed: */ ++ if (Fvco <= 3658) ++ VSUB = 0; ++ else if (Fvco <= 3716) ++ VSUB = 2; ++ else if (Fvco <= 3776) ++ VSUB = 2; ++ else if (Fvco <= 3840) ++ VSUB = 3; ++ else if (Fvco <= 3909) ++ VSUB = 4; ++ else if (Fvco <= 3980) ++ VSUB = 5; ++ else if (Fvco <= 4054) ++ VSUB = 6; ++ else if (Fvco <= 4134) ++ VSUB = 7; ++ else if (Fvco <= 4226) ++ VSUB = 8; ++ else if (Fvco <= 4318) ++ VSUB = 9; ++ else if (Fvco <= 4416) ++ VSUB = 10; ++ else if (Fvco <= 4520) ++ VSUB = 11; ++ else if (Fvco <= 4633) ++ VSUB = 12; ++ else if (Fvco <= 4751) ++ VSUB = 13; ++ else if (Fvco <= 4876) ++ VSUB = 14; ++ else ++ VSUB = 15; ++ } ++ /* VCO = D<7:6>, VSUB = D<5:2> */ ++ pExtra->regs[REG3543_VCO] = (pExtra->regs[REG3543_VCO] & 3) | (VSUB<<2) | (VCO<<6); ++ /* Program the VCO register with the seed: */ ++// Max3543_Write(REG3543_VCO, regs[REG3543_VCO]); ++ if(Max3543_Write(pTuner, REG3543_VCO, pExtra->regs[REG3543_VCO]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++/* Returns the lock detect status. This is accomplished by ++ examining the ADC value read from the MAX3543. The ADC ++ value is the tune voltage digitized. If it is too close to ++ ground or Vcc, the part is unlocked. The ADC ranges from 0-7. ++ Values 1 to 6 are considered locked. 0 or 7 is unlocked. ++ Returns True for locked, fase for unlocked. ++*/ ++int MAX3543_LockDetect(TUNER_MODULE *pTuner, int *pAnswer) ++{ ++// BOOL vcoselected; ++ int vcoselected; ++ UINT_16 tries = 65535; ++ char adc; ++ unsigned short Data; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ /* The ADC will not be stable until the VCO is selected. ++ usually the selection process will take 25ms or less but ++ it could theoretically take 100ms. Set tries to some number ++ of your processor clocks corresponding to 100ms. ++ You have to take into account all instructions processed ++ in determining this time. I am picking a value out of the air ++ for now. ++ */ ++ vcoselected = MAX_FALSE; ++ while ((--tries > 0) && (vcoselected == MAX_FALSE)) ++ { ++// if ((Max3543_Read(REG3543_VAS_STATUS) & 1) == 1) ++ if(Max3543_Read(pTuner, REG3543_VAS_STATUS, &Data) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ if ((Data & 1) == 1) ++ vcoselected = MAX_TRUE; ++ } ++ /* open the ADC latch: ADL=0, ADE=1 */ ++ pExtra->regs[REG3543_VAS] = (pExtra->regs[REG3543_VAS] & 0xf3) | 4; ++// Max3543_Write(REG3543_VAS, regs[REG3543_VAS]); ++ if(Max3543_Write(pTuner, REG3543_VAS, pExtra->regs[REG3543_VAS]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* ADC = 3 LSBs of Gen Status Register: */ ++// adc = Max3543_Read(REG3543_GEN_STATUS) & 0x7; ++ if(Max3543_Read(pTuner, REG3543_GEN_STATUS, &Data) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ adc = Data & 0x7; ++ ++ ++ ++ ++ /* locked if ADC within range of 1-6: */ ++ if ((adc<1 ) || (adc>6)) ++ return MAX_FALSE; ++ else ++ return MAX_TRUE; ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++} ++ ++ ++ ++int MAX3543_ReadROM(TUNER_MODULE *pTuner) ++{ ++ unsigned short Data; ++ ++ /* Read the ROM table, extract tracking filter ROM coefficients, ++ IRHR and CFSET constants. ++ This is to be called after the Max3543 powers up. ++ */ ++ UINT_16 rom_data[12]; ++ UINT_16 i; ++ ++ MAX3543_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Max3543); ++ ++ ++ for (i=0; i <= 10; i++) ++ { ++// Max3543_Write(REG3543_ROM_ADDR,i); /*Select ROM Row by setting address register */ ++ if(Max3543_Write(pTuner, REG3543_ROM_ADDR,i) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; /*Select ROM Row by setting address register */ ++ ++// rom_data[i] = Max3543_Read(REG3543_ROM_READ); /* Read from ROMR Register */ ++ if(Max3543_Read(pTuner, REG3543_ROM_READ, &Data) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ rom_data[i] = Data; /* Read from ROMR Register */ ++ } ++ ++ ++ /* The ROM address must be returned to 0 for normal operation or the part will not be biased properly. */ ++// Max3543_Write(REG3543_ROM_ADDR,0); ++ if(Max3543_Write(pTuner, REG3543_ROM_ADDR,0) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Copy all of ROM Row 10 to Filt_CF register. */ ++// Max3543_Write(REG3543_FILT_CF,rom_data[10]); ++ if(Max3543_Write(pTuner, REG3543_FILT_CF,rom_data[10]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ /* Copy the IRHR ROM value to the IRHR register: */ ++// Max3543_Write(REG3543_IRHR, rom_data[0xb]); ++ if(Max3543_Write(pTuner, REG3543_IRHR, rom_data[0xb]) != MAX3543_SUCCESS) ++ goto error_status_access_tuner; ++ ++ ++ /* assemble the broken up word pairs from the ROM table into complete ROM coefficients: */ ++ pExtra->TFRomCoefs[VHF_L][SER0] = (rom_data[1] & 0xFC) >> 2; /*'LS0 )*/ ++ pExtra->TFRomCoefs[VHF_L][SER1] = ((rom_data[1] & 0x3 ) << 4) + ((rom_data[2] & 0xf0) >> 4); /* 'LS1*/ ++ pExtra->TFRomCoefs[VHF_L][PAR0] = ((rom_data[2] & 0xf) << 2) + ((rom_data[3] & 0xc0) >> 6); /*'LP0*/ ++ pExtra->TFRomCoefs[VHF_L][PAR1] = rom_data[3] & 0x3f; /*LP1 */ ++ ++ pExtra->TFRomCoefs[VHF_H][SER0] = ((rom_data[4] & 0xfc) >> 2); /*'HS0 */ ++ pExtra->TFRomCoefs[VHF_H][SER1] = ((rom_data[4] & 0x3) << 4) + ((rom_data[5] & 0xF0) >> 4); /*'HS1 */ ++ pExtra->TFRomCoefs[VHF_H][PAR0] = ((rom_data[5] & 0xf) << 2) + ((rom_data[6] & 0xc0) >> 6); /*'HP0 */ ++ pExtra->TFRomCoefs[VHF_H][PAR1] = rom_data[6] & 0x3F; /*'HP1 */ ++ ++ pExtra->TFRomCoefs[UHF][SER0] = ((rom_data[7] & 0xFC) >> 2); /*'US0 */ ++ pExtra->TFRomCoefs[UHF][SER1] = ((rom_data[7] & 0x3) << 4) + ((rom_data[8] & 0xf0) >> 4 ); /*'US1 */ ++ pExtra->TFRomCoefs[UHF][PAR0] = ((rom_data[8] & 0xF) << 2) + ((rom_data[9] & 0xc0) >> 6); /*'UP0 */ ++ pExtra->TFRomCoefs[UHF][PAR1] = rom_data[9] & 0x3f; /*'UP1 */ ++ ++ ++ return MAX3543_SUCCESS; ++ ++ ++error_status_access_tuner: ++ return MAX3543_ERROR; ++ } ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_max3543.h b/drivers/drivers/media/dvb/dvb-usb/tuner_max3543.h +--- a/drivers/media/dvb/dvb-usb/tuner_max3543.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_max3543.h 2016-04-02 19:17:52.136066045 -0300 +@@ -0,0 +1,572 @@ ++#ifndef __TUNER_MAX3543_H ++#define __TUNER_MAX3543_H ++ ++/** ++ ++@file ++ ++@brief MAX3543 tuner module declaration ++ ++One can manipulate MAX3543 tuner through MAX3543 module. ++MAX3543 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_max3543.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ MAX3543_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build MAX3543 tuner module. ++ BuildMax3543Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0, // I2C device address is 0xac in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // Crystal frequency is 16.0 MHz. ++ MAX3543_STANDARD_DVBT, // The MAX3543 standard mode is DVB-T. ++ IF_FREQ_36170000HZ, // The MAX3543 IF frequency is 36.17 MHz. ++ MAX3543_SAW_INPUT_SE // The MAX3543 SAW input type is single-ended. ++ ); ++ ++ ++ ++ ++ ++ // Get MAX3543 tuner extra module. ++ pTunerExtra = (MAX3543_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set MAX3543 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, MAX3543_BANDWIDTH_7MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get MAX3543 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is implemented for MAX3543 source code. ++ ++ ++// Definition (implemeted for MAX3543) ++ ++// Function return status ++#define MAX3543_SUCCESS 1 ++#define MAX3543_ERROR 0 ++ ++ ++ ++// Function (implemeted for MAX3543) ++int ++Max3543_Read( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned short *pData ++ ); ++ ++int ++Max3543_Write( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned short Data ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Analog Devices. ++ ++ ++ ++ ++ ++// MAXIM source code - mxmdef.h ++ ++ ++ ++//#ifndef MXMDEF_H ++//#define MXMDEF_H ++ ++#define MAX_PATH 260 ++/* ++#ifndef NULL ++#ifdef __cplusplus ++#define NULL 0 ++#else ++#define NULL ((void *)0) ++#endif ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++*/ ++ ++#define MAX_FALSE 0 ++#define MAX_TRUE 1 ++ ++ ++typedef unsigned long DWORD; ++ ++//#endif /* _WINDEF_ */ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MAXIM source code - Max3543_Driver.h ++ ++ ++ ++ /* ++------------------------------------------------------ ++| Max3543_Driver.h, v 1.0.3, 12/9/2009, Paul Nichol ++| Description: Max3543 Driver Includes. ++| ++| Copyright (C) 2009 Maxim Integrated Products ++| ++------------------------------------------------------ ++*/ ++ ++ ++ ++ ++//#ifndef Max3543_Driver_H ++ ++/* integer only mode = 1, floating point mode = 0 */ ++//#define intmode 0 ++ ++ ++//#define Max3543_Driver_H ++ ++ ++#define MAX3543_ADDR 0xc0 ++ ++#define MAX3543_NUMREGS 0x15 ++ ++ ++/* Register Address offsets. Used when sending or indexing registers. */ ++#define REG3543_VCO 0 ++#define REG3543_NDIV 0x1 ++#define REG3543_FRAC2 0x2 ++#define REG3543_FRAC1 0x3 ++#define REG3543_FRAC0 0x4 ++#define REG3543_MODE 0x5 ++#define REG3543_TFS 0x6 ++#define REG3543_TFP 0x7 ++#define REG3543_SHDN 0x8 ++#define REG3543_REF 0x9 ++#define REG3543_VAS 0xa ++#define REG3543_PD_CFG1 0xb ++#define REG3543_PD_CFG2 0xc ++#define REG3543_FILT_CF 0xd ++#define REG3543_ROM_ADDR 0xe ++#define REG3543_IRHR 0xf ++#define REG3543_ROM_READ 0x10 ++#define REG3543_VAS_STATUS 0x11 ++#define REG3543_GEN_STATUS 0x12 ++#define REG3543_BIAS_ADJ 0x13 ++#define REG3543_TEST1 0x14 ++#define REG3543_ROM_WRITE 0x15 ++ ++/* Band constants: */ ++#define VHF_L 0 ++#define VHF_H 1 ++#define UHF 2 ++ ++/* Channel Bandwidth: */ ++#define BW7MHZ 0 ++#define BW8MHZ 1 ++ ++#define SER0 0 ++#define SER1 1 ++#define PAR0 2 ++#define PAR1 3 ++ ++ ++ ++ ++typedef enum {IFOUT1_DIFF_DTVOUT, IFOUT1_SE_DTVOUT,IFOUT2} outputmode; ++ ++typedef enum {DVB_T, DVB_C, ATV, ATV_SECAM_L} standard; ++ ++//standard broadcast_standard; ++ ++ ++ ++/* Note: ++ The SetFrequency() routine must make it's calculations without ++ overflowing 32 bit accumulators. This is a difficult balance of LO, IF and Xtal frequencies. ++ Scaling factors are applied to these frequencies to keep the numbers below the 32 bit result during ++ caltculations. The calculations have been checked for only the following combinations of frequencies ++ and settings: Xtal freqencies of 16.0MHz, 20.25 MHz, 20.48 MHz; IF Frequencies of 30.0 MHz and 30.15MHz; ++ R-Dividers /1 and /2. Any combination of the above numbers may be used. ++ If other combinations or frequencies are needed, the scaling factors: LOSCALE and XTALSCALE must be ++ recalculated. This has been done in a spreadsheet calc.xls. Without checking these ++ scale factors carefully, there could be overflow and tuning errors or amplitude losses due to an ++ incorrect tracking filter setting. ++*/ ++ ++/* Scaling factor for the IF and RF freqencies. ++ Freqencies passed to functions must be multiplied by this factor. ++ (See Note above). ++*/ ++//#define LOSCALE 40 ++ ++/* Scaling factor for Xtal frequency. ++ Use 32 for 16.0MHz, 25 for 20.48 and 4 for 20.25MHz. ++ (See Note above). ++*/ ++//#define XTALSCALE 4 ++ ++//#if intmode ++ /* Macros used for scaling frequency constants. */ ++ /* Use this form if using floating point math. */ ++ ++#define scalefrq(x) ( (UINT_32) ( ( (UINT_16) x) * (UINT_16) pExtra->LOSCALE ) ) ++// #define scalextal(x) ( (UINT_32) ( ( (UINT_16) x ) * (UINT_16) XTALSCALE ) ) ++ ++ ++ /* Note, this is a scaling factor for the Xtal Reference applied to the MAX3543 Xtal Pin. ++ The only valid frequencies are 16.0, 20.25 or 20.48MHz and only with the following conditions: ++ RDiv = /1 or RDiv = /2, IF = 36.0MHz, IF = 36.15 MHz. ++ (See Note above). ++ */ ++// #define XTALREF 81 ++ /* 20.25 * XTALSCALE = 81, where XTALSCALE=4 ++ Use this form if NOT using floating point math. ++ */ ++//#else ++ /* Macros used for scaling frequency constants. */ ++ /* Use this form if NOT using floating point math. */ ++// #define scalefrq(x) ( (unsigned short) ( ( (float) x ) * (float) LOSCALE ) ) ++// #define scalextal(x) ( (unsigned short) ( ( (float) x ) * (float) XTALSCALE ) ) ++ ++ /* Note, this is a scaling factor for the Xtal Reference applied to the MAX3543 Xtal Pin. ++ The only valid frequencies are 16.0, 20.25 or 20.48MHz and only with the following conditions: ++ RDiv = /1 or RDiv = /2, IF = 36.0MHz, IF = 36.15 MHz. ++ (See Note above). ++ */ ++// #define XTALREF scalextal(20.25) ++ /* Use this form if NOT using floating point math. */ ++ /* #define XTALREF 81 */ ++ /* (XTALSCALE * Reference frequency 20.24 * 4 = 81) */ ++//#endif ++ ++ ++ ++ ++#define ATV_SINGLE 2 ++ ++typedef short INT_16; /* compiler type for 16 bit integer */ ++typedef unsigned short UINT_16; /* compiler type for 16 bit unsigned integer */ ++typedef unsigned long UINT_32; /* compiler type for 32 bit unsigned integer */ ++ ++typedef enum {IFOUT_1,IFOUT_2} outmd; ++ ++//int MAX3543_Init(TUNER_MODULE *pTuner, UINT_16 RfFreq); ++int MAX3543_Init(TUNER_MODULE *pTuner); ++int MAX3543_SetFrequency(TUNER_MODULE *pTuner, UINT_16 RF_Frequency); ++//unsigned short MAX3543_Read(UINT_16 reg); ++//void MAX3543_Write(UINT_16 reg, UINT_16 value); ++int MAX3543_LockDetect(TUNER_MODULE *pTuner, int *pAnswer); ++int MAX3543_Standard(TUNER_MODULE *pTuner, standard bcstd, outputmode outmd); ++int MAX3543_ChannelBW(TUNER_MODULE *pTuner, UINT_16 bw); ++int MAX3543_SetTrackingFilter(TUNER_MODULE *pTuner, UINT_16 RF_Frequency); ++int MAX3543_ReadROM(TUNER_MODULE *pTuner); ++UINT_16 tfs_i(UINT_16 S0, UINT_16 S1, UINT_16 FreqRF, const UINT_16 c[5]); ++int MAX3543_SeedVCO(TUNER_MODULE *pTuner, UINT_16 Fvco); ++ ++ ++/******* External functions called by Max3543 code *******/ ++ ++ ++ /* The implementation of these functions is left for the end user. */ ++ /* This is because of the many different microcontrollers and serial */ ++ /* I/O methods that can be used. */ ++ ++// void Max3543_Write(unsigned short RegAddr, unsigned short data); ++ ++ /* This function sends out a byte of data using the following format. */ ++ /* Start, IC_address, ACK, Register Address, Ack, Data, Ack, Stop */ ++ ++ /* IC_address is 0xC0 or 0xC4 depending on JP8 of the Max3543 evkit board. */ ++ /* 0xC0 if the ADDR pin of the Max3543 is low, x0C4 if the pin is high. */ ++ /* The register address is the Index into the register */ ++ /* you wish to fill. */ ++ ++// unsigned short Max3543_Read(unsigned short reg); ++ ++ /* This reads and returns a byte from the Max3543. */ ++ /* The read sequence is: */ ++ /* Start, IC_address, ACK, Register Address, ack, Start, DeviceReadAddress, ack, */ ++ /* Data, NAck, Stop */ ++ /* Note that there is a IC_Address (0xC0 or 0xC4 as above) and a Device Read */ ++ /* Address which is the IC_Address + 1 (0xC1 or 0xC5). */ ++ /* There are also two start conditions in the read back sequence. */ ++ /* The Register Address is an index into the register you */ ++ /* wish to read back. */ ++ ++ ++//#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is MAX3543 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Standard mode ++enum MAX3543_STANDARD_MODE ++{ ++ MAX3543_STANDARD_DVBT = DVB_T, ++ MAX3543_STANDARD_QAM = DVB_C, ++}; ++ ++ ++// Bandwidth mode ++enum MAX3543_BANDWIDTH_MODE ++{ ++ MAX3543_BANDWIDTH_7000000HZ = BW7MHZ, ++ MAX3543_BANDWIDTH_8000000HZ = BW8MHZ, ++}; ++ ++ ++// SAW input type ++enum MAX3543_SAW_INPUT_TYPE ++{ ++ MAX3543_SAW_INPUT_DIFF = IFOUT1_DIFF_DTVOUT, ++ MAX3543_SAW_INPUT_SE = IFOUT1_SE_DTVOUT, ++}; ++ ++ ++ ++// Default for initialing ++#define MAX3543_RF_FREQ_HZ_DEFAULT 474000000 ++#define MAX3543_BANDWIDTH_MODE_DEFAULT MAX3543_BANDWIDTH_8000000HZ ++ ++ ++// Definition for RF frequency setting. ++#define MAX3543_CONST_1_MHZ 1000000 ++ ++ ++ ++ ++ ++// Builder ++void ++BuildMax3543Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int StandardMode, ++ unsigned long IfFreqHz, ++ int OutputMode ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++max3543_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++max3543_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++max3543_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++max3543_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++max3543_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++max3543_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++max3543_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_mt2063.c b/drivers/drivers/media/dvb/dvb-usb/tuner_mt2063.c +--- a/drivers/media/dvb/dvb-usb/tuner_mt2063.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_mt2063.c 2016-04-02 19:17:52.140066046 -0300 +@@ -0,0 +1,5264 @@ ++/** ++ ++@file ++ ++@brief MT2063 tuner module definition ++ ++One can manipulate MT2063 tuner through MT2063 module. ++MT2063 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_mt2063.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief MT2063 tuner module builder ++ ++Use BuildMt2063Module() to build MT2063 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to MT2063 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr MT2063 I2C device address ++@param [in] IfFreqHz MT2063 output IF frequency in Hz ++@param [in] StandardMode Standard mode ++@param [in] IfVgaGainControl IF VGA gain control ++ ++ ++@note ++ -# One should call BuildMt2063Module() to build MT2063 module before using it. ++ ++*/ ++void ++BuildMt2063Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ int StandardMode, ++ unsigned long VgaGc ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_MT2063; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = mt2063_GetTunerType; ++ pTuner->GetDeviceAddr = mt2063_GetDeviceAddr; ++ ++ pTuner->Initialize = mt2063_Initialize; ++ pTuner->SetRfFreqHz = mt2063_SetRfFreqHz; ++ pTuner->GetRfFreqHz = mt2063_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->StandardMode = StandardMode; ++ pExtra->VgaGc = VgaGc; ++ pExtra->IsIfFreqHzSet = NO; ++ pExtra->IsBandwidthHzSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->OpenHandle = mt2063_OpenHandle; ++ pExtra->CloseHandle = mt2063_CloseHandle; ++ pExtra->GetHandle = mt2063_GetHandle; ++ pExtra->SetIfFreqHz = mt2063_SetIfFreqHz; ++ pExtra->GetIfFreqHz = mt2063_GetIfFreqHz; ++ pExtra->SetBandwidthHz = mt2063_SetBandwidthHz; ++ pExtra->GetBandwidthHz = mt2063_GetBandwidthHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++mt2063_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++mt2063_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++mt2063_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Re-initialize tuner. ++ Status = MT2063_ReInit(DeviceHandle); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner output bandwidth. ++// Status = MT2063_SetParam(DeviceHandle, MT2063_OUTPUT_BW, MT2063_BANDWIDTH_6MHZ); ++ ++// if(MT_IS_ERROR(Status)) ++// goto error_status_execute_function; ++ ++ ++ // Set tuner parameters according to standard mode. ++ switch(pExtra->StandardMode) ++ { ++ default: ++ case MT2063_STANDARD_DVBT: ++ ++ Status = MT2063_SetParam(DeviceHandle, MT2063_RCVR_MODE, MT2063_OFFAIR_COFDM); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ break; ++ ++ ++ case MT2063_STANDARD_QAM: ++ ++ Status = MT2063_SetParam(DeviceHandle, MT2063_RCVR_MODE, MT2063_CABLE_QAM); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ break; ++ } ++ ++ ++ // Set tuner VGAGC with IF AGC gain control setting value. ++ Status = MT2063_SetParam(DeviceHandle, MT2063_VGAGC, (UData_t)(pExtra->VgaGc)); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++mt2063_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner RF frequency in Hz. ++ Status = MT2063_Tune(DeviceHandle, RfFreqHz); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++mt2063_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Open MT2063 tuner handle. ++ ++*/ ++int ++mt2063_OpenHandle( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ unsigned char DeviceAddr; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner I2C device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Open MT2063 handle. ++ // Note: 1. Must take tuner extra module DeviceHandle as handle input argument. ++ // 2. Take pTuner as user-defined data input argument. ++ Status = MT2063_Open(DeviceAddr, &pExtra->DeviceHandle, pTuner); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_open_mt2063_handle; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_open_mt2063_handle: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Close MT2063 tuner handle. ++ ++*/ ++int ++mt2063_CloseHandle( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Close MT2063 handle. ++ Status = MT2063_Close(DeviceHandle); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_open_mt2063_handle; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_open_mt2063_handle: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2063 tuner handle. ++ ++*/ ++void ++mt2063_GetHandle( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ *pDeviceHandle = pExtra->DeviceHandle; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MT2063 tuner IF frequency in Hz. ++ ++*/ ++int ++mt2063_SetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long IfFreqHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ unsigned int IfFreqHzUint; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner output IF frequency. ++ IfFreqHzUint = (unsigned int)IfFreqHz; ++ Status = MT2063_SetParam(DeviceHandle, MT2063_OUTPUT_FREQ, IfFreqHzUint); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_execute_function; ++ ++ ++ // Set tuner IF frequnecy parameter in tuner extra module. ++ pExtra->IfFreqHz = IfFreqHz; ++ pExtra->IsIfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_execute_function: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2063 tuner IF frequency in Hz. ++ ++*/ ++int ++mt2063_GetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ ++ // Get tuner IF frequency in Hz from tuner extra module. ++ if(pExtra->IsIfFreqHzSet != YES) ++ goto error_status_get_demod_if_frequency; ++ ++ *pIfFreqHz = pExtra->IfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_demod_if_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MT2063 tuner bandwidth in Hz. ++ ++*/ ++// Note: The function MT2063_SetParam() only sets software bandwidth variables, ++// so execute MT2063_Tune() after this function. ++int ++mt2063_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++// unsigned long BandwidthHzWithShift; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner bandwidth in Hz with shift. ++// BandwidthHzWithShift = BandwidthHz - MT2063_BANDWIDTH_SHIFT_HZ; ++// Status = MT2063_SetParam(DeviceHandle, MT2063_OUTPUT_BW, BandwidthHzWithShift); ++ Status = MT2063_SetParam(DeviceHandle, MT2063_OUTPUT_BW, BandwidthHz); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ // Set tuner bandwidth parameter. ++ pExtra->BandwidthHz = BandwidthHz; ++ pExtra->IsBandwidthHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2063 tuner bandwidth in Hz. ++ ++*/ ++int ++mt2063_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ) ++{ ++ MT2063_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2063); ++ ++ ++ // Get tuner bandwidth in Hz from tuner module. ++ if(pExtra->IsBandwidthHzSet != YES) ++ goto error_status_get_tuner_bandwidth; ++ ++ *pBandwidthHz = pExtra->BandwidthHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Microtune source code - mt_userdef.c ++ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.c ++** ++** Description: User-defined MicroTuner software interface ++** ++** Functions ++** Requiring ++** Implementation: MT_WriteSub ++** MT_ReadSub ++** MT_Sleep ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_userdef.c,v 1.2 2008/11/05 13:46:20 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_userdef.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++//#include "mt_userdef.h" ++ ++ ++/***************************************************************************** ++** ++** Name: MT_WriteSub ++** ++** Description: Write values to device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to write data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2063_WriteSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt) ++{ ++// UData_t status = MT_OK; /* Status to be returned */ ++ /* ++ ** ToDo: Add code here to implement a serial-bus write ++ ** operation to the MTxxxx tuner. If successful, ++ ** return MT_OK. ++ */ ++/* return status; */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i, j; ++ ++ unsigned char RegStartAddr; ++ unsigned char *pWritingBytes; ++ unsigned long ByteNum; ++ ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = subAddress; ++ pWritingBytes = pData; ++ ByteNum = (unsigned long)cnt; ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set tuner register bytes with writing bytes. ++ // Note: Set tuner register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + ++ // stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ReadSub ++** ++** Description: Read values from device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to read data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2063_ReadSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt) ++{ ++// UData_t status = MT_OK; /* Status to be returned */ ++ ++ /* ++ ** ToDo: Add code here to implement a serial-bus read ++ ** operation to the MTxxxx tuner. If successful, ++ ** return MT_OK. ++ */ ++/* return status; */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i; ++ ++ unsigned char RegStartAddr; ++ unsigned char *pReadingBytes; ++ unsigned long ByteNum; ++ ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = subAddress; ++ pReadingBytes = pData; ++ ByteNum = (unsigned long)cnt; ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get tuner register bytes. ++ // Note: Get tuner register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register bytes. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return MT_COMM_ERR; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_Sleep ++** ++** Description: Delay execution for "nMinDelayTime" milliseconds ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** nMinDelayTime - Delay time in milliseconds ++** ++** Returns: None. ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code that ++** blocks execution for the specified period of time. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++void MT2063_Sleep(Handle_t hUserData, ++ UData_t nMinDelayTime) ++{ ++ /* ++ ** ToDo: Add code here to implement a OS blocking ++ ** for a period of "nMinDelayTime" milliseconds. ++ */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get tuner module, base interface. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ ++ // Wait nMinDelayTime milliseconds. ++ pBaseInterface->WaitMs(pBaseInterface, nMinDelayTime); ++ ++ ++ return; ++} ++ ++ ++#if defined(MT2060_CNT) ++#if MT2060_CNT > 0 ++/***************************************************************************** ++** ++** Name: MT_TunerGain (MT2060 only) ++** ++** Description: Measure the relative tuner gain using the demodulator ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** pMeas - Tuner gain (1/100 of dB scale). ++** ie. 1234 = 12.34 (dB) ++** ++** Returns: status: ++** MT_OK - No errors ++** user-defined errors could be set ++** ++** Notes: This is a callback function that is called from the ++** the 1st IF location routine. You MUST provide ++** code that measures the relative tuner gain in a dB ++** (not linear) scale. The return value is an integer ++** value scaled to 1/100 of a dB. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 06-16-2004 DAD Original ++** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name ++** better describes what this function does. ++** ++*****************************************************************************/ ++UData_t MT_TunerGain(Handle_t hUserData, ++ SData_t* pMeas) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ ++ /* ++ ** ToDo: Add code here to return the gain / power level measured ++ ** at the input to the demodulator. ++ */ ++ ++ ++ ++ return (status); ++} ++#endif ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_2063.c ++ ++ ++/***************************************************************************** ++** ++** Name: mt2063.c ++** ++** Copyright 2007-2008 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt2063.c ++** ++** Description: Microtune MT2063 B0, B1 & B3 Tuner software interface ++** Supports tuners with Part/Rev code: 0x9B - 0x9E. ++** ++** Functions ++** Implemented: UData_t MT2063_Open ++** UData_t MT2063_Close ++** UData_t MT2063_ClearPowerMaskBits ++** UData_t MT2063_GetGPIO ++** UData_t MT2063_GetLocked ++** UData_t MT2063_GetParam ++** UData_t MT2063_GetPowerMaskBits ++** UData_t MT2063_GetReg ++** UData_t MT2063_GetTemp ++** UData_t MT2063_GetUserData ++** UData_t MT2063_ReInit ++** UData_t MT2063_SetGPIO ++** UData_t MT2063_SetParam ++** UData_t MT2063_SetPowerMaskBits ++** UData_t MT2063_SetReg ++** UData_t MT2063_Tune ++** ++** References: AN-00189: MT2063 Programming Procedures Application Note ++** MicroTune, Inc. ++** AN-00010: MicroTuner Serial Interface Application Note ++** MicroTune, Inc. ++** ++** Exports: None ++** ++** Dependencies: MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Read byte(s) of data from the two-wire bus. ++** ++** MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Write byte(s) of data to the two-wire bus. ++** ++** MT_Sleep(hUserData, nMinDelayTime); ++** - Delay execution for nMinDelayTime milliseconds ++** ++** CVS ID: $Id: mt2063.c,v 1.6 2009/04/29 09:58:14 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt2063.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** N/A 08-01-2007 PINZ Ver 1.01: Changed Analog &DVB-T settings and added ++** SAW-less receiver mode. ++** 148 09-04-2007 RSK Ver 1.02: Corrected logic of Reg 3B Reference ++** 153 09-07-2007 RSK Ver 1.03: Lock Time improvements ++** 150 09-10-2007 RSK Ver 1.04: Added GetParam/SetParam support for ++** LO1 and LO2 freq for PHY-21 cal. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive ++** modulation ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have ++** the same settings as with MT Launcher ++** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI ++** Add SetParam DNC_OUTPUT_ENABLE ++** Removed VGAGC from receiver mode, ++** default now 3 ++** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode ++** Add SetParam AMPGC, removed from rcvr-mode ++** Corrected names of GCU values ++** reorganized receiver modes, removed, ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** Actualized Receiver-Mode values ++** N/A 11-12-2007 PINZ Ver 1.09: Actualized Receiver-Mode values ++** N/A 11-27-2007 PINZ Improved buffered writing ++** 01-03-2008 PINZ Ver 1.10: Added a trigger of BYPATNUP for ++** correct wakeup of the LNA after shutdown ++** Set AFCsd = 1 as default ++** Changed CAP1sel default ++** 01-14-2008 PINZ Ver 1.11: Updated gain settings, default for VGAGC 3 ++** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW ++** in GetParam. ++** 03-18-2008 PINZ Ver 1.13: Added Support for MT2063 B3 ++** 04-10-2008 PINZ Ver 1.14: Use software-controlled ClearTune ++** cross-over frequency values. ++** Documentation Updates ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 189 S 05-13-2008 PINZ Ver 1.16: Correct location for ExtSRO control. ++** Add control to avoid DECT freqs. ++** Updated Receivermodes for MT2063 B3 ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 07-10-2008 PINZ Ver 1.19: Documentation Updates, Add a GetParam ++** for each SetParam (LNA_RIN, TGTs) ++** 08-05-2008 PINZ Ver 1.20: Disable SDEXT pin while MT2063_ReInit ++** with MT2063B3 ++** 09-18-2008 PINZ Ver 1.22: Updated values for CTFILT_SW ++** 205 M 10-01-2008 JWS Ver 1.23: Use DMAX when LO2 FracN is near 4096 ++** M 10-24-2008 JWS Ver 1.25: Use DMAX when LO1 FracN is 32 ++** 11-05-2008 PINZ Ver 1.26: Minor code fixes ++** 01-07-2009 PINZ Ver 1.27: Changed value of MT2063_ALL_SD in .h ++** 01-20-2009 PINZ Ver 1.28: Fixed a compare to avoid compiler warning ++** 02-16-2009 PINZ Ver 1.29: Several fixes to improve compiler behavior ++** N/A I 02-26-2009 PINZ Ver 1.30: RCVRmode 2: acfifmax 29->0, pd2tgt 33->34 ++** RCVRmode 4: acfifmax 29->0, pd2tgt 30->34 ++** N/A I 03-02-2009 PINZ Ver 1.31: new default Fout 43.75 -> 36.125MHz ++** new default Output-BW 6 -> 8MHz ++** new default Stepsize 50 -> 62.5kHz ++** new default Fin 651 -> 666 MHz ++** Changed order of receiver-mode init ++** N/A I 03-19-2009 PINZ Ver 1.32: Add GetParam VERSION (of API) ++** Add GetParam IC_REV ++** N/A I 04-22-2009 PINZ Ver 1.33: Small fix in GetParam PD1/PD2 ++** N/A I 04-29-2009 PINZ Ver 1.34: Optimized ReInit function ++** ++*****************************************************************************/ ++//#include "mt2063.h" ++//#include "mt_spuravoid.h" ++//#include /* for NULL */ ++#define MT_NULL 0 ++ ++/* Version of this module */ ++#define MT2063_MODULE_VERSION 10304 /* Version 01.34 */ ++ ++ ++/* ++** The expected version of MT_AvoidSpursData_t ++** If the version is different, an updated file is needed from Microtune ++*/ ++/* Expecting version 1.21 of the Spur Avoidance API */ ++#define EXPECTED_MT_AVOID_SPURS_INFO_VERSION 010201 ++ ++#if MT2063_AVOID_SPURS_INFO_VERSION < EXPECTED_MT_AVOID_SPURS_INFO_VERSION ++#error Contact Microtune for a newer version of MT_SpurAvoid.c ++#elif MT2063_AVOID_SPURS_INFO_VERSION > EXPECTED_MT_AVOID_SPURS_INFO_VERSION ++#error Contact Microtune for a newer version of mt2063.c ++#endif ++ ++#ifndef MT2063_CNT ++#error You must define MT2063_CNT in the "mt_userdef.h" file ++#endif ++ ++ ++/* ++** Two-wire serial bus subaddresses of the tuner registers. ++** Also known as the tuner's register addresses. ++*/ ++enum MT2063_Register_Offsets ++{ ++ PART_REV = 0, /* 0x00: Part/Rev Code */ ++ LO1CQ_1, /* 0x01: LO1C Queued Byte 1 */ ++ LO1CQ_2, /* 0x02: LO1C Queued Byte 2 */ ++ LO2CQ_1, /* 0x03: LO2C Queued Byte 1 */ ++ LO2CQ_2, /* 0x04: LO2C Queued Byte 2 */ ++ LO2CQ_3, /* 0x05: LO2C Queued Byte 3 */ ++ RSVD_06, /* 0x06: Reserved */ ++ LO_STATUS, /* 0x07: LO Status */ ++ FIFFC, /* 0x08: FIFF Center */ ++ CLEARTUNE, /* 0x09: ClearTune Filter */ ++ ADC_OUT, /* 0x0A: ADC_OUT */ ++ LO1C_1, /* 0x0B: LO1C Byte 1 */ ++ LO1C_2, /* 0x0C: LO1C Byte 2 */ ++ LO2C_1, /* 0x0D: LO2C Byte 1 */ ++ LO2C_2, /* 0x0E: LO2C Byte 2 */ ++ LO2C_3, /* 0x0F: LO2C Byte 3 */ ++ RSVD_10, /* 0x10: Reserved */ ++ PWR_1, /* 0x11: PWR Byte 1 */ ++ PWR_2, /* 0x12: PWR Byte 2 */ ++ TEMP_STATUS, /* 0x13: Temp Status */ ++ XO_STATUS, /* 0x14: Crystal Status */ ++ RF_STATUS, /* 0x15: RF Attn Status */ ++ FIF_STATUS, /* 0x16: FIF Attn Status */ ++ LNA_OV, /* 0x17: LNA Attn Override */ ++ RF_OV, /* 0x18: RF Attn Override */ ++ FIF_OV, /* 0x19: FIF Attn Override */ ++ LNA_TGT, /* 0x1A: Reserved */ ++ PD1_TGT, /* 0x1B: Pwr Det 1 Target */ ++ PD2_TGT, /* 0x1C: Pwr Det 2 Target */ ++ RSVD_1D, /* 0x1D: Reserved */ ++ RSVD_1E, /* 0x1E: Reserved */ ++ RSVD_1F, /* 0x1F: Reserved */ ++ RSVD_20, /* 0x20: Reserved */ ++ BYP_CTRL, /* 0x21: Bypass Control */ ++ RSVD_22, /* 0x22: Reserved */ ++ RSVD_23, /* 0x23: Reserved */ ++ RSVD_24, /* 0x24: Reserved */ ++ RSVD_25, /* 0x25: Reserved */ ++ RSVD_26, /* 0x26: Reserved */ ++ RSVD_27, /* 0x27: Reserved */ ++ FIFF_CTRL, /* 0x28: FIFF Control */ ++ FIFF_OFFSET, /* 0x29: FIFF Offset */ ++ CTUNE_CTRL, /* 0x2A: Reserved */ ++ CTUNE_OV, /* 0x2B: Reserved */ ++ CTRL_2C, /* 0x2C: Reserved */ ++ FIFF_CTRL2, /* 0x2D: Fiff Control */ ++ RSVD_2E, /* 0x2E: Reserved */ ++ DNC_GAIN, /* 0x2F: DNC Control */ ++ VGA_GAIN, /* 0x30: VGA Gain Ctrl */ ++ RSVD_31, /* 0x31: Reserved */ ++ TEMP_SEL, /* 0x32: Temperature Selection */ ++ RSVD_33, /* 0x33: Reserved */ ++ FN_CTRL, /* 0x34: FracN Control */ ++ RSVD_35, /* 0x35: Reserved */ ++ RSVD_36, /* 0x36: Reserved */ ++ RSVD_37, /* 0x37: Reserved */ ++ RSVD_38, /* 0x38: Reserved */ ++ RSVD_39, /* 0x39: Reserved */ ++ RSVD_3A, /* 0x3A: Reserved */ ++ RSVD_3B, /* 0x3B: Reserved */ ++ RSVD_3C, /* 0x3C: Reserved */ ++ END_REGS ++}; ++ ++ ++/* ++** Constants used by the tuning algorithm ++*/ ++#define REF_FREQ (16000000) /* Reference oscillator Frequency (in Hz) */ ++#define IF1_BW (22000000) /* The IF1 filter bandwidth (in Hz) */ ++#define TUNE_STEP_SIZE (62500) /* Tune in steps of 62.5 kHz */ ++#define SPUR_STEP_HZ (250000) /* Step size (in Hz) to move IF1 when avoiding spurs */ ++#define ZIF_BW (2000000) /* Zero-IF spur-free bandwidth (in Hz) */ ++#define MAX_HARMONICS_1 (15) /* Highest intra-tuner LO Spur Harmonic to be avoided */ ++#define MAX_HARMONICS_2 (5) /* Highest inter-tuner LO Spur Harmonic to be avoided */ ++#define MIN_LO_SEP (1000000) /* Minimum inter-tuner LO frequency separation */ ++#define LO1_FRACN_AVOID (0) /* LO1 FracN numerator avoid region (in Hz) */ ++#define LO2_FRACN_AVOID (199999) /* LO2 FracN numerator avoid region (in Hz) */ ++#define MIN_FIN_FREQ (44000000) /* Minimum input frequency (in Hz) */ ++#define MAX_FIN_FREQ (1100000000) /* Maximum input frequency (in Hz) */ ++#define DEF_FIN_FREQ (666000000) /* Default frequency at initialization (in Hz) */ ++#define MIN_FOUT_FREQ (36000000) /* Minimum output frequency (in Hz) */ ++#define MAX_FOUT_FREQ (57000000) /* Maximum output frequency (in Hz) */ ++#define MIN_DNC_FREQ (1293000000) /* Minimum LO2 frequency (in Hz) */ ++#define MAX_DNC_FREQ (1614000000) /* Maximum LO2 frequency (in Hz) */ ++#define MIN_UPC_FREQ (1396000000) /* Minimum LO1 frequency (in Hz) */ ++#define MAX_UPC_FREQ (2750000000U) /* Maximum LO1 frequency (in Hz) */ ++ ++ ++typedef struct ++{ ++ Handle_t handle; ++ Handle_t hUserData; ++ UData_t address; ++ UData_t version; ++ UData_t tuner_id; ++ MT2063_AvoidSpursData_t AS_Data; ++ UData_t f_IF1_actual; ++ UData_t rcvr_mode; ++ UData_t ctfilt_sw; ++ UData_t CTFiltMax[31]; ++ UData_t num_regs; ++ U8Data reg[END_REGS]; ++} MT2063_Info_t; ++ ++static UData_t nMaxTuners = MT2063_CNT; ++static MT2063_Info_t MT2063_Info[MT2063_CNT]; ++static MT2063_Info_t *Avail[MT2063_CNT]; ++static UData_t nOpenTuners = 0; ++ ++ ++/* ++** Constants for setting receiver modes. ++** (6 modes defined at this time, enumerated by MT2063_RCVR_MODES) ++** (DNC1GC & DNC2GC are the values, which are used, when the specific ++** DNC Output is selected, the other is always off) ++** ++** If PAL-L or L' is received, set: ++** MT2063_SetParam(hMT2063,MT2063_TAGC,1); ++** ++** --------------+---------------------------------------------- ++** Mode 0 : | MT2063_CABLE_QAM ++** Mode 1 : | MT2063_CABLE_ANALOG ++** Mode 2 : | MT2063_OFFAIR_COFDM ++** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS ++** Mode 4 : | MT2063_OFFAIR_ANALOG ++** Mode 5 : | MT2063_OFFAIR_8VSB ++** --------------+----+----+----+----+-----+-----+-------------- ++** Mode | 0 | 1 | 2 | 3 | 4 | 5 | ++** --------------+----+----+----+----+-----+-----+ ++** ++** ++*/ ++static const U8Data RFAGCEN[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data LNARIN[] = { 0, 0, 3, 3, 3, 3 }; ++static const U8Data FIFFQEN[] = { 1, 1, 1, 1, 1, 1 }; ++static const U8Data FIFFQ[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data DNC1GC[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data DNC2GC[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 }; ++static const U8Data LNATGT[] = { 44, 43, 43, 43, 43, 43 }; ++static const U8Data RFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data ACRFMAX[] = { 31, 31, 31, 31, 31, 31 }; ++static const U8Data PD1TGT[] = { 36, 36, 38, 38, 36, 38 }; ++static const U8Data FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; ++static const U8Data ACFIFMAX[] = { 29, 0, 29, 29, 0, 29 }; ++static const U8Data PD2TGT[] = { 40, 34, 38, 42, 34, 38 }; ++ ++ ++static const UData_t df_dosc[] = { ++ 55000, 127000, 167000, 210000, 238000, 267000, 312000, 350000, ++ 372000, 396000, 410000, 421000, 417000, 408000, 387000, 278000, ++ 769000, 816000, 824000, 848000, 903000, 931000, 934000, 961000, ++ 969000, 987000,1005000,1017000, 1006000, 840000, 850000, 0 ++ }; ++ ++ ++/* Forward declaration(s): */ ++static UData_t CalcLO1Mult(UData_t *Div, UData_t *FracN, UData_t f_LO, UData_t f_LO_Step, UData_t f_Ref); ++static UData_t CalcLO2Mult(UData_t *Div, UData_t *FracN, UData_t f_LO, UData_t f_LO_Step, UData_t f_Ref); ++static UData_t fLO_FractionalTerm(UData_t f_ref, UData_t num, UData_t denom); ++static UData_t FindClearTuneFilter(MT2063_Info_t* pInfo, UData_t f_in); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_Open ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: MT2063_Addr - Serial bus address of the tuner. ++** hMT2063 - Tuner handle passed back. ++** hUserData - User-defined data, if needed for the ++** MT_ReadSub() & MT_WriteSub functions. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_NULL - Null pointer argument passed ++** MT_COMM_ERR - Serial bus communications error ++** MT_TUNER_CNT_ERR - Too many tuners open ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_Open(UData_t MT2063_Addr, ++ Handle_t* hMT2063, ++ Handle_t hUserData) ++{ ++ UData_t status = MT_OK; /* Status to be returned. */ ++ SData_t i; ++ MT2063_Info_t* pInfo = MT_NULL; ++ ++ /* Check the argument before using */ ++ if (hMT2063 == MT_NULL) ++ return (UData_t)MT_ARG_NULL; ++ ++ /* Default tuner handle to NULL. If successful, it will be reassigned */ ++ *hMT2063 = MT_NULL; ++ ++ /* ++ ** If this is our first tuner, initialize the address fields and ++ ** the list of available control blocks. ++ */ ++ if (nOpenTuners == 0) ++ { ++ for (i=MT2063_CNT-1; i>=0; i--) ++ { ++ MT2063_Info[i].handle = MT_NULL; ++ MT2063_Info[i].address = (UData_t)MAX_UDATA; ++ MT2063_Info[i].rcvr_mode = MT2063_CABLE_QAM; ++ MT2063_Info[i].hUserData = MT_NULL; ++ Avail[i] = &MT2063_Info[i]; ++ } ++ } ++ ++ /* ++ ** Look for an existing MT2063_State_t entry with this address. ++ */ ++ for (i=MT2063_CNT-1; i>=0; i--) ++ { ++ /* ++ ** If an open'ed handle provided, we'll re-initialize that structure. ++ ** ++ ** We recognize an open tuner because the address and hUserData are ++ ** the same as one that has already been opened ++ */ ++ if ((MT2063_Info[i].address == MT2063_Addr) && ++ (MT2063_Info[i].hUserData == hUserData)) ++ { ++ pInfo = &MT2063_Info[i]; ++ break; ++ } ++ } ++ ++ /* If not found, choose an empty spot. */ ++ if (pInfo == MT_NULL) ++ { ++ /* Check to see that we're not over-allocating */ ++ if (nOpenTuners == MT2063_CNT) ++ return (UData_t)MT_TUNER_CNT_ERR; ++ ++ /* Use the next available block from the list */ ++ pInfo = Avail[nOpenTuners]; ++ nOpenTuners++; ++ } ++ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_RegisterTuner(&pInfo->AS_Data); ++ ++ if (MT_NO_ERROR(status)) ++ { ++ pInfo->handle = (Handle_t) pInfo; ++ pInfo->hUserData = hUserData; ++ pInfo->address = MT2063_Addr; ++ pInfo->rcvr_mode = MT2063_CABLE_QAM; ++// status |= MT2063_ReInit((Handle_t) pInfo); ++ } ++ ++ if (MT_IS_ERROR(status)) ++ /* MT2063_Close handles the un-registration of the tuner */ ++ (void)MT2063_Close((Handle_t) pInfo); ++ else ++ *hMT2063 = pInfo->handle; ++ ++ return (UData_t)(status); ++} ++ ++ ++static UData_t IsValidHandle(MT2063_Info_t* handle) ++{ ++ return (UData_t)(((handle != MT_NULL) && (handle->handle == handle)) ? 1 : 0); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_Close ++** ++** Description: Release the handle to the tuner. ++** ++** Parameters: hMT2063 - Handle to the MT2063 tuner ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_Close(Handle_t hMT2063) ++{ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) hMT2063; ++ ++ if (!IsValidHandle(pInfo)) ++ return (UData_t)MT_INV_HANDLE; ++ ++ /* Unregister tuner with SpurAvoidance routines (if needed) */ ++ MT2063_UnRegisterTuner(&pInfo->AS_Data); ++ ++ /* Now remove the tuner from our own list of tuners */ ++ pInfo->handle = MT_NULL; ++ pInfo->address = (UData_t)MAX_UDATA; ++ pInfo->hUserData = MT_NULL; ++ nOpenTuners--; ++ Avail[nOpenTuners] = pInfo; /* Return control block to available list */ ++ ++ return (UData_t)MT_OK; ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_GetGPIO ++** ++** Description: Get the current MT2063 GPIO value. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** gpio_id - Selects GPIO0, GPIO1 or GPIO2 ++** attr - Selects input readback, I/O direction or ++** output value (MT2063_GPIO_IN, ++** MT2063_GPIO_DIR or MT2063_GPIO_OUT) ++** *value - current setting of GPIO pin ++** ++** Usage: status = MT2063_GetGPIO(hMT2063, MT2063_GPIO0, ++** MT2063_GPIO_OUT, &value); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_GetGPIO(Handle_t h, ++ MT2063_GPIO_ID gpio_id, ++ MT2063_GPIO_Attr attr, ++ UData_t* value) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data regno; ++ SData_t shift; ++ const U8Data GPIOreg[3] = {RF_STATUS, FIF_OV, RF_OV}; ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ if (value == MT_NULL) ++ return (UData_t)MT_ARG_NULL; ++ ++ regno = GPIOreg[attr]; ++ ++ /* We'll read the register just in case the write didn't work last time */ ++ status = MT2063_ReadSub(pInfo->hUserData, pInfo->address, regno, &pInfo->reg[regno], 1); ++ ++ shift = (SData_t)(gpio_id - MT2063_GPIO0 + 5); ++ *value = (pInfo->reg[regno] >> shift) & 1; ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetLocked ++** ++** Description: Checks to see if LO1 and LO2 are locked. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_UPC_UNLOCK - Upconverter PLL unlocked ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetLocked(Handle_t h) ++{ ++ const UData_t nMaxWait = 100; /* wait a maximum of 100 msec */ ++ const UData_t nPollRate = 2; /* poll status bits every 2 ms */ ++ const UData_t nMaxLoops = nMaxWait / nPollRate; ++ const U8Data LO1LK = 0x80; ++ U8Data LO2LK = 0x08; ++ UData_t status = MT_OK; /* Status to be returned */ ++ UData_t nDelays = 0; ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ /* LO2 Lock bit was in a different place for B0 version */ ++ if (pInfo->tuner_id == MT2063_B0) ++ LO2LK = 0x40; ++ ++ do ++ { ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, LO_STATUS, &pInfo->reg[LO_STATUS], 1); ++ ++ if (MT_IS_ERROR(status)) ++ return (UData_t)(status); ++ ++ if ((pInfo->reg[LO_STATUS] & (LO1LK | LO2LK)) == (LO1LK | LO2LK)) ++ return (UData_t)(status); ++ ++ MT2063_Sleep(pInfo->hUserData, nPollRate); /* Wait between retries */ ++ } ++ while (++nDelays < nMaxLoops); ++ ++ if ((pInfo->reg[LO_STATUS] & LO1LK) == 0x00) ++ status |= MT_UPC_UNLOCK; ++ if ((pInfo->reg[LO_STATUS] & LO2LK) == 0x00) ++ status |= MT_DNC_UNLOCK; ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetParam ++** ++** Description: Gets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm - mostly for testing purposes. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2063_Param) ++** pValue - ptr to returned value ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2063_VERSION Version of the API ++** MT2063_IC_ADDR Serial Bus address of this tuner ++** MT2063_IC_REV Tuner revision code ++** MT2063_MAX_OPEN Max # of MT2063's allowed open ++** MT2063_NUM_OPEN # of MT2063's open ++** MT2063_SRO_FREQ crystal frequency ++** MT2063_STEPSIZE minimum tuning step size ++** MT2063_INPUT_FREQ input center frequency ++** MT2063_LO1_FREQ LO1 Frequency ++** MT2063_LO1_STEPSIZE LO1 minimum step size ++** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region ++** MT2063_IF1_ACTUAL Current 1st IF in use ++** MT2063_IF1_REQUEST Requested 1st IF ++** MT2063_IF1_CENTER Center of 1st IF SAW filter ++** MT2063_IF1_BW Bandwidth of 1st IF SAW filter ++** MT2063_ZIF_BW zero-IF bandwidth ++** MT2063_LO2_FREQ LO2 Frequency ++** MT2063_LO2_STEPSIZE LO2 minimum step size ++** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region ++** MT2063_OUTPUT_FREQ output center frequency ++** MT2063_OUTPUT_BW output bandwidth ++** MT2063_LO_SEPARATION min inter-tuner LO separation ++** MT2063_AS_ALG ID of avoid-spurs algorithm in use ++** MT2063_MAX_HARM1 max # of intra-tuner harmonics ++** MT2063_MAX_HARM2 max # of inter-tuner harmonics ++** MT2063_EXCL_ZONES # of 1st IF exclusion zones ++** MT2063_NUM_SPURS # of spurs found/avoided ++** MT2063_SPUR_AVOIDED >0 spurs avoided ++** MT2063_SPUR_PRESENT >0 spurs in output (mathematically) ++** MT2063_RCVR_MODE Predefined modes. ++** MT2063_LNA_RIN Get LNA RIN value ++** MT2063_LNA_TGT Get target power level at LNA ++** MT2063_PD1_TGT Get target power level at PD1 ++** MT2063_PD2_TGT Get target power level at PD2 ++** MT2063_ACLNA LNA attenuator gain code ++** MT2063_ACRF RF attenuator gain code ++** MT2063_ACFIF FIF attenuator gain code ++** MT2063_ACLNA_MAX LNA attenuator limit ++** MT2063_ACRF_MAX RF attenuator limit ++** MT2063_ACFIF_MAX FIF attenuator limit ++** MT2063_PD1 Actual value of PD1 ++** MT2063_PD2 Actual value of PD2 ++** MT2063_DNC_OUTPUT_ENABLE DNC output selection ++** MT2063_VGAGC VGA gain code ++** MT2063_VGAOI VGA output current ++** MT2063_TAGC TAGC setting ++** MT2063_AMPGC AMP gain code ++** MT2063_AVOID_DECT Avoid DECT Frequencies ++** MT2063_CTFILT_SW Cleartune filter selection ++** ++** Usage: status |= MT2063_GetParam(hMT2063, ++** MT2063_IF1_ACTUAL, ++** &f_IF1_Actual); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** See Also: MT2063_SetParam, MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC ++** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW ++** in GetParam. ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 07-10-2008 PINZ Ver 1.19: Documentation Updates, Add a GetParam ++** for each SetParam (LNA_RIN, TGTs) ++** N/A I 03-19-2009 PINZ Ver 1.32: Add GetParam VERSION (of API) ++** Add GetParam IC_REV ++** N/A I 04-22-2009 PINZ Ver 1.33: Small fix in GetParam PD1/PD2 ++****************************************************************************/ ++UData_t MT2063_GetParam(Handle_t h, ++ MT2063_Param param, ++ UData_t* pValue) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ UData_t Div; ++ UData_t Num; ++ UData_t i; ++ U8Data reg; ++ ++ if (pValue == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ *pValue = 0; ++ ++ switch (param) ++ { ++ /* version of the API, e.g. 10302 = 1.32 */ ++ case MT2063_VERSION: ++ *pValue = pInfo->version; ++ break; ++ ++ /* Serial Bus address of this tuner */ ++ case MT2063_IC_ADDR: ++ *pValue = pInfo->address; ++ break; ++ ++ /* tuner revision code (see enum MT2063_REVCODE for values) */ ++ case MT2063_IC_REV: ++ *pValue = pInfo->tuner_id; ++ break; ++ ++ /* Max # of MT2063's allowed to be open */ ++ case MT2063_MAX_OPEN: ++ *pValue = nMaxTuners; ++ break; ++ ++ /* # of MT2063's open */ ++ case MT2063_NUM_OPEN: ++ *pValue = nOpenTuners; ++ break; ++ ++ /* crystal frequency */ ++ case MT2063_SRO_FREQ: ++ *pValue = pInfo->AS_Data.f_ref; ++ break; ++ ++ /* minimum tuning step size */ ++ case MT2063_STEPSIZE: ++ *pValue = pInfo->AS_Data.f_LO2_Step; ++ break; ++ ++ /* input center frequency */ ++ case MT2063_INPUT_FREQ: ++ *pValue = pInfo->AS_Data.f_in; ++ break; ++ ++ /* LO1 Frequency */ ++ case MT2063_LO1_FREQ: ++ { ++ /* read the actual tuner register values for LO1C_1 and LO1C_2 */ ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, LO1C_1, &pInfo->reg[LO1C_1], 2); ++ Div = pInfo->reg[LO1C_1]; ++ Num = pInfo->reg[LO1C_2] & 0x3F; ++ pInfo->AS_Data.f_LO1 = (pInfo->AS_Data.f_ref * Div) + fLO_FractionalTerm(pInfo->AS_Data.f_ref, Num, 64); ++ *pValue = pInfo->AS_Data.f_LO1; ++ } ++ break; ++ ++ /* LO1 minimum step size */ ++ case MT2063_LO1_STEPSIZE: ++ *pValue = pInfo->AS_Data.f_LO1_Step; ++ break; ++ ++ /* LO1 FracN keep-out region */ ++ case MT2063_LO1_FRACN_AVOID: ++ *pValue = pInfo->AS_Data.f_LO1_FracN_Avoid; ++ break; ++ ++ /* Current 1st IF in use */ ++ case MT2063_IF1_ACTUAL: ++ *pValue = pInfo->f_IF1_actual; ++ break; ++ ++ /* Requested 1st IF */ ++ case MT2063_IF1_REQUEST: ++ *pValue = pInfo->AS_Data.f_if1_Request; ++ break; ++ ++ /* Center of 1st IF SAW filter */ ++ case MT2063_IF1_CENTER: ++ *pValue = pInfo->AS_Data.f_if1_Center; ++ break; ++ ++ /* Bandwidth of 1st IF SAW filter */ ++ case MT2063_IF1_BW: ++ *pValue = pInfo->AS_Data.f_if1_bw; ++ break; ++ ++ /* zero-IF bandwidth */ ++ case MT2063_ZIF_BW: ++ *pValue = pInfo->AS_Data.f_zif_bw; ++ break; ++ ++ /* LO2 Frequency */ ++ case MT2063_LO2_FREQ: ++ { ++ /* Read the actual tuner register values for LO2C_1, LO2C_2 and LO2C_3 */ ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, LO2C_1, &pInfo->reg[LO2C_1], 3); ++ Div = (pInfo->reg[LO2C_1] & 0xFE ) >> 1; ++ Num = ((pInfo->reg[LO2C_1] & 0x01 ) << 12) | (pInfo->reg[LO2C_2] << 4) | (pInfo->reg[LO2C_3] & 0x00F); ++ pInfo->AS_Data.f_LO2 = (pInfo->AS_Data.f_ref * Div) + fLO_FractionalTerm(pInfo->AS_Data.f_ref, Num, 8191); ++ *pValue = pInfo->AS_Data.f_LO2; ++ } ++ break; ++ ++ /* LO2 minimum step size */ ++ case MT2063_LO2_STEPSIZE: ++ *pValue = pInfo->AS_Data.f_LO2_Step; ++ break; ++ ++ /* LO2 FracN keep-out region */ ++ case MT2063_LO2_FRACN_AVOID: ++ *pValue = pInfo->AS_Data.f_LO2_FracN_Avoid; ++ break; ++ ++ /* output center frequency */ ++ case MT2063_OUTPUT_FREQ: ++ *pValue = pInfo->AS_Data.f_out; ++ break; ++ ++ /* output bandwidth */ ++ case MT2063_OUTPUT_BW: ++ *pValue = pInfo->AS_Data.f_out_bw - 750000; ++ break; ++ ++ /* min inter-tuner LO separation */ ++ case MT2063_LO_SEPARATION: ++ *pValue = pInfo->AS_Data.f_min_LO_Separation; ++ break; ++ ++ /* ID of avoid-spurs algorithm in use */ ++ case MT2063_AS_ALG: ++ *pValue = pInfo->AS_Data.nAS_Algorithm; ++ break; ++ ++ /* max # of intra-tuner harmonics */ ++ case MT2063_MAX_HARM1: ++ *pValue = pInfo->AS_Data.maxH1; ++ break; ++ ++ /* max # of inter-tuner harmonics */ ++ case MT2063_MAX_HARM2: ++ *pValue = pInfo->AS_Data.maxH2; ++ break; ++ ++ /* # of 1st IF exclusion zones */ ++ case MT2063_EXCL_ZONES: ++ *pValue = pInfo->AS_Data.nZones; ++ break; ++ ++ /* # of spurs found/avoided */ ++ case MT2063_NUM_SPURS: ++ *pValue = pInfo->AS_Data.nSpursFound; ++ break; ++ ++ /* >0 spurs avoided */ ++ case MT2063_SPUR_AVOIDED: ++ *pValue = pInfo->AS_Data.bSpurAvoided; ++ break; ++ ++ /* >0 spurs in output (mathematically) */ ++ case MT2063_SPUR_PRESENT: ++ *pValue = pInfo->AS_Data.bSpurPresent; ++ break; ++ ++ /* Predefined receiver setup combination */ ++ case MT2063_RCVR_MODE: ++ *pValue = pInfo->rcvr_mode; ++ break; ++ ++ case MT2063_PD1: ++ case MT2063_PD2: ++ { ++ reg = pInfo->reg[BYP_CTRL] | ( (param == MT2063_PD1 ? 0x01 : 0x03) & 0x03 ); /* PD1 vs PD2 */ ++ ++ /* Initiate ADC output to reg 0x0A */ ++ if (reg != pInfo->reg[BYP_CTRL]) ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, BYP_CTRL, ®, 1); ++ ++ if (MT_IS_ERROR(status)) ++ return (UData_t)(status); ++ ++ for (i=0; i<8; i++) { ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, ADC_OUT, &pInfo->reg[ADC_OUT], 1); ++ ++ if (MT_NO_ERROR(status)) ++ *pValue += (pInfo->reg[ADC_OUT] >> 2); /* only want 6 MSB's out of 8 */ ++ else ++ break; /* break for-loop */ ++ } ++ *pValue /= (i+1); /* divide by number of reads */ ++ ++ /* Restore value of Register BYP_CTRL */ ++ if (reg != pInfo->reg[BYP_CTRL]) ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, BYP_CTRL, &pInfo->reg[BYP_CTRL], 1); ++ } ++ break; ++ ++ ++ /* Get LNA RIN value */ ++ case MT2063_LNA_RIN: ++ status |= (pInfo->reg[CTRL_2C] & 0x03); ++ break; ++ ++ /* Get LNA target value */ ++ case MT2063_LNA_TGT: ++ status |= (pInfo->reg[LNA_TGT] & 0x3f); ++ break; ++ ++ /* Get PD1 target value */ ++ case MT2063_PD1_TGT: ++ status |= (pInfo->reg[PD1_TGT] & 0x3f); ++ break; ++ ++ /* Get PD2 target value */ ++ case MT2063_PD2_TGT: ++ status |= (pInfo->reg[PD2_TGT] & 0x3f); ++ break; ++ ++ /* Get LNA attenuator code */ ++ case MT2063_ACLNA: ++ { ++ status |= MT2063_GetReg(pInfo, XO_STATUS, ®); ++ *pValue = reg & 0x1f; ++ } ++ break; ++ ++ /* Get RF attenuator code */ ++ case MT2063_ACRF: ++ { ++ status |= MT2063_GetReg(pInfo, RF_STATUS, ®); ++ *pValue = reg & 0x1f; ++ } ++ break; ++ ++ /* Get FIF attenuator code */ ++ case MT2063_ACFIF: ++ { ++ status |= MT2063_GetReg(pInfo, FIF_STATUS, ®); ++ *pValue = reg & 0x1f; ++ } ++ break; ++ ++ /* Get LNA attenuator limit */ ++ case MT2063_ACLNA_MAX: ++ status |= (pInfo->reg[LNA_OV] & 0x1f); ++ break; ++ ++ /* Get RF attenuator limit */ ++ case MT2063_ACRF_MAX: ++ status |= (pInfo->reg[RF_OV] & 0x1f); ++ break; ++ ++ /* Get FIF attenuator limit */ ++ case MT2063_ACFIF_MAX: ++ status |= (pInfo->reg[FIF_OV] & 0x1f); ++ break; ++ ++ /* Get current used DNC output */ ++ case MT2063_DNC_OUTPUT_ENABLE: ++ { ++ if ( (pInfo->reg[DNC_GAIN] & 0x03) == 0x03) /* if DNC1 is off */ ++ { ++ if ( (pInfo->reg[VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */ ++ *pValue = (UData_t)MT2063_DNC_NONE; ++ else ++ *pValue = (UData_t)MT2063_DNC_2; ++ } ++ else /* DNC1 is on */ ++ { ++ if ( (pInfo->reg[VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */ ++ *pValue = (UData_t)MT2063_DNC_1; ++ else ++ *pValue = (UData_t)MT2063_DNC_BOTH; ++ } ++ } ++ break; ++ ++ /* Get VGA Gain Code */ ++ case MT2063_VGAGC: ++ *pValue = ( (pInfo->reg[VGA_GAIN] & 0x0C) >> 2 ); ++ break; ++ ++ /* Get VGA bias current */ ++ case MT2063_VGAOI: ++ *pValue = (pInfo->reg[RSVD_31] & 0x07); ++ break; ++ ++ /* Get TAGC setting */ ++ case MT2063_TAGC: ++ *pValue = (pInfo->reg[RSVD_1E] & 0x03); ++ break; ++ ++ /* Get AMP Gain Code */ ++ case MT2063_AMPGC: ++ *pValue = (pInfo->reg[TEMP_SEL] & 0x03); ++ break; ++ ++ /* Avoid DECT Frequencies */ ++ case MT2063_AVOID_DECT: ++ *pValue = pInfo->AS_Data.avoidDECT; ++ break; ++ ++ /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ ++ case MT2063_CTFILT_SW: ++ *pValue = pInfo->ctfilt_sw; ++ break; ++ ++ case MT2063_EOP: ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ } ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetReg ++** ++** Description: Gets an MT2063 register. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** reg - MT2063 register/subaddress location ++** *val - MT2063 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2063. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetReg(Handle_t h, ++ U8Data reg, ++ U8Data* val) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (val == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, reg, &pInfo->reg[reg], 1); ++ if (MT_NO_ERROR(status)) ++ *val = pInfo->reg[reg]; ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_GetTemp ++** ++** Description: Get the MT2063 Temperature register. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** *value - value read from the register ++** ++** Binary ++** Value Returned Value Approx Temp ++** --------------------------------------------- ++** MT2063_T_0C 0000 0C ++** MT2063_T_10C 0001 10C ++** MT2063_T_20C 0010 20C ++** MT2063_T_30C 0011 30C ++** MT2063_T_40C 0100 40C ++** MT2063_T_50C 0101 50C ++** MT2063_T_60C 0110 60C ++** MT2063_T_70C 0111 70C ++** MT2063_T_80C 1000 80C ++** MT2063_T_90C 1001 90C ++** MT2063_T_100C 1010 100C ++** MT2063_T_110C 1011 110C ++** MT2063_T_120C 1100 120C ++** MT2063_T_130C 1101 130C ++** MT2063_T_140C 1110 140C ++** MT2063_T_150C 1111 150C ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_GetTemp(Handle_t h, MT2063_Temperature* value) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ if (value == MT_NULL) ++ return (UData_t)MT_ARG_NULL; ++ ++ if ((MT_NO_ERROR(status)) && ((pInfo->reg[TEMP_SEL] & 0xE0) != 0x00)) ++ { ++ pInfo->reg[TEMP_SEL] &= (0x1F); ++ status |= MT2063_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ TEMP_SEL, ++ &pInfo->reg[TEMP_SEL], ++ 1); ++ } ++ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, ++ pInfo->address, ++ TEMP_STATUS, ++ &pInfo->reg[TEMP_STATUS], ++ 1); ++ ++ if (MT_NO_ERROR(status)) ++ *value = (MT2063_Temperature) (pInfo->reg[TEMP_STATUS] >> 4); ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetUserData ++** ++** Description: Gets the user-defined data item. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** The hUserData parameter is a user-specific argument ++** that is stored internally with the other tuner- ++** specific information. ++** ++** For example, if additional arguments are needed ++** for the user to identify the device communicating ++** with the tuner, this argument can be used to supply ++** the necessary information. ++** ++** The hUserData parameter is initialized in the tuner's ++** Open function to NULL. ++** ++** See Also: MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetUserData(Handle_t h, ++ Handle_t* hUserData) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (hUserData == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (MT_NO_ERROR(status)) ++ *hUserData = pInfo->hUserData; ++ ++ return (UData_t)(status); ++} ++ ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_SetReceiverMode ++** ++** Description: Set the MT2063 receiver mode ++** ++** --------------+---------------------------------------------- ++** Mode 0 : | MT2063_CABLE_QAM ++** Mode 1 : | MT2063_CABLE_ANALOG ++** Mode 2 : | MT2063_OFFAIR_COFDM ++** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS ++** Mode 4 : | MT2063_OFFAIR_ANALOG ++** Mode 5 : | MT2063_OFFAIR_8VSB ++** --------------+----+----+----+----+-----+-------------------- ++** (DNC1GC & DNC2GC are the values, which are used, when the specific ++** DNC Output is selected, the other is always off) ++** ++** |<---------- Mode -------------->| ++** Reg Field | 0 | 1 | 2 | 3 | 4 | 5 | ++** ------------+-----+-----+-----+-----+-----+-----+ ++** RFAGCen | OFF | OFF | OFF | OFF | OFF | OFF | ++** LNARin | 0 | 0 | 3 | 3 | 3 | 3 | ++** FIFFQen | 1 | 1 | 1 | 1 | 1 | 1 | ++** FIFFq | 0 | 0 | 0 | 0 | 0 | 0 | ++** DNC1gc | 0 | 0 | 0 | 0 | 0 | 0 | ++** DNC2gc | 0 | 0 | 0 | 0 | 0 | 0 | ++** LNA max Atn | 31 | 31 | 31 | 31 | 31 | 31 | ++** LNA Target | 44 | 43 | 43 | 43 | 43 | 43 | ++** ign RF Ovl | 0 | 0 | 0 | 0 | 0 | 0 | ++** RF max Atn | 31 | 31 | 31 | 31 | 31 | 31 | ++** PD1 Target | 36 | 36 | 38 | 38 | 36 | 38 | ++** ign FIF Ovl | 0 | 0 | 0 | 0 | 0 | 0 | ++** FIF max Atn | 29 | 0 | 29 | 29 | 0 | 29 | ++** PD2 Target | 40 | 34 | 38 | 42 | 34 | 38 | ++** ++** ++** Parameters: pInfo - ptr to MT2063_Info_t structure ++** Mode - desired reciever mode ++** ++** Usage: status = MT2063_SetReceiverMode(hMT2063, Mode); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT2063_SetReg - Write a byte of data to a HW register. ++** Assumes that the tuner cache is valid. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** N/A 01-10-2007 PINZ Added additional GCU Settings, FIFF Calib will be triggered ++** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive ++** modulation ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have ++** the same settings as with MT Launcher ++** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI ++** Add SetParam DNC_OUTPUT_ENABLE ++** Removed VGAGC from receiver mode, ++** default now 1 ++** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode ++** Add SetParam AMPGC, removed from rcvr-mode ++** Corrected names of GCU values ++** reorganized receiver modes, removed, ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** Actualized Receiver-Mode values ++** N/A 11-12-2007 PINZ Ver 1.09: Actualized Receiver-Mode values ++** N/A 11-27-2007 PINZ Improved buffered writing ++** 01-03-2008 PINZ Ver 1.10: Added a trigger of BYPATNUP for ++** correct wakeup of the LNA after shutdown ++** Set AFCsd = 1 as default ++** Changed CAP1sel default ++** 01-14-2008 PINZ Ver 1.11: Updated gain settings ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 11-05-2008 PINZ Ver 1.25: Bugfix, update rcvr_mode var earlier. ++** N/A I 02-26-2009 PINZ Ver 1.30: RCVRmode 2: acfifmax 29->0, pd2tgt 33->34 ++** RCVRmode 4: acfifmax 29->0, pd2tgt 30->34 ++** ++******************************************************************************/ ++static UData_t MT2063_SetReceiverMode(MT2063_Info_t* pInfo, MT2063_RCVR_MODES Mode) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data val; ++ UData_t longval; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ if (Mode >= MT2063_NUM_RCVR_MODES) ++ status = MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ pInfo->rcvr_mode = Mode; ++ ++ /* RFAGCen */ ++ if (MT_NO_ERROR(status)) ++ { ++ val = (pInfo->reg[PD1_TGT] & (U8Data)~0x40) | (RFAGCEN[Mode] ? 0x40 : 0x00); ++ if( pInfo->reg[PD1_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, PD1_TGT, val); ++ } ++ } ++ ++ /* LNARin */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_LNA_RIN, LNARIN[Mode]); ++ } ++ ++ /* FIFFQEN and FIFFQ */ ++ if (MT_NO_ERROR(status)) ++ { ++ val = (pInfo->reg[FIFF_CTRL2] & (U8Data)~0xF0) | (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4); ++ if( pInfo->reg[FIFF_CTRL2] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, FIFF_CTRL2, val); ++ /* trigger FIFF calibration, needed after changing FIFFQ */ ++ val = (pInfo->reg[FIFF_CTRL] | (U8Data)0x01); ++ status |= MT2063_SetReg(pInfo, FIFF_CTRL, val); ++ val = (pInfo->reg[FIFF_CTRL] & (U8Data)~0x01); ++ status |= MT2063_SetReg(pInfo, FIFF_CTRL, val); ++ } ++ } ++ ++ /* DNC1GC & DNC2GC */ ++ status |= MT2063_GetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, &longval); ++ status |= MT2063_SetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, longval); ++ ++ /* acLNAmax */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_ACLNA_MAX, ACLNAMAX[Mode]); ++ } ++ ++ /* LNATGT */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_LNA_TGT, LNATGT[Mode]); ++ } ++ ++ /* ACRF */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_ACRF_MAX, ACRFMAX[Mode]); ++ } ++ ++ /* PD1TGT */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_PD1_TGT, PD1TGT[Mode]); ++ } ++ ++ /* FIFATN */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_ACFIF_MAX, ACFIFMAX[Mode]); ++ } ++ ++ /* PD2TGT */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_SetParam(pInfo, MT2063_PD2_TGT, PD2TGT[Mode]); ++ } ++ ++ /* Ignore ATN Overload */ ++ if (MT_NO_ERROR(status)) ++ { ++ val = (pInfo->reg[LNA_TGT] & (U8Data)~0x80) | (RFOVDIS[Mode] ? 0x80 : 0x00); ++ if( pInfo->reg[LNA_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, LNA_TGT, val); ++ } ++ } ++ ++ /* Ignore FIF Overload */ ++ if (MT_NO_ERROR(status)) ++ { ++ val = (pInfo->reg[PD1_TGT] & (U8Data)~0x80) | (FIFOVDIS[Mode] ? 0x80 : 0x00); ++ if( pInfo->reg[PD1_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, PD1_TGT, val); ++ } ++ } ++ ++ ++ return (UData_t)(status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_ReInit ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 148 09-04-2007 RSK Ver 1.02: Corrected logic of Reg 3B Reference ++** 153 09-07-2007 RSK Ver 1.03: Lock Time improvements ++** N/A 10-31-2007 PINZ Ver 1.08: Changed values suitable to rcvr-mode 0 ++** N/A 11-12-2007 PINZ Ver 1.09: Changed values suitable to rcvr-mode 0 ++** N/A 01-03-2007 PINZ Ver 1.10: Added AFCsd = 1 into defaults ++** N/A 01-04-2007 PINZ Ver 1.10: Changed CAP1sel default ++** 01-14-2008 PINZ Ver 1.11: Updated gain settings ++** 03-18-2008 PINZ Ver 1.13: Added Support for B3 ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 08-05-2008 PINZ Ver 1.20: Disable SDEXT pin while MT2063_ReInit ++** with MT2063B3 ++** N/A I 03-02-2009 PINZ Ver 1.31: new default Fout 43.75 -> 36.125MHz ++** new default Output-BW 6 -> 8MHz ++** new default Stepsize 50 -> 62.5kHz ++** new default Fin 651 -> 666 MHz ++** Changed order of receiver-mode init ++** N/A I 04-29-2009 PINZ Ver 1.34: Optimized ReInit function ++** ++******************************************************************************/ ++UData_t MT2063_ReInit(Handle_t h) ++{ ++ U8Data all_resets = 0xF0; /* reset/load bits */ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ UData_t rev=0; ++ ++ U8Data MT2063B0_defaults[] = { /* Reg, Value */ ++ 0x19, 0x05, ++ 0x1B, 0x1D, ++ 0x1C, 0x1F, ++ 0x1D, 0x0F, ++ 0x1E, 0x3F, ++ 0x1F, 0x0F, ++ 0x20, 0x3F, ++ 0x22, 0x21, ++ 0x23, 0x3F, ++ 0x24, 0x20, ++ 0x25, 0x3F, ++ 0x27, 0xEE, ++ 0x2C, 0x27, /* bit at 0x20 is cleared below */ ++ 0x30, 0x03, ++ 0x2C, 0x07, /* bit at 0x20 is cleared here */ ++ 0x2D, 0x87, ++ 0x2E, 0xAA, ++ 0x28, 0xE1, /* Set the FIFCrst bit here */ ++ 0x28, 0xE0, /* Clear the FIFCrst bit here */ ++ 0x00 }; ++ ++ /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */ ++ U8Data MT2063B1_defaults[] = { /* Reg, Value */ ++ 0x05, 0xF0, ++ 0x11, 0x10, /* New Enable AFCsd */ ++ 0x19, 0x05, ++ 0x1A, 0x6C, ++ 0x1B, 0x24, ++ 0x1C, 0x28, ++ 0x1D, 0x8F, ++ 0x1E, 0x14, ++ 0x1F, 0x8F, ++ 0x20, 0x57, ++ 0x22, 0x21, /* New - ver 1.03 */ ++ 0x23, 0x3C, /* New - ver 1.10 */ ++ 0x24, 0x20, /* New - ver 1.03 */ ++ 0x2C, 0x24, /* bit at 0x20 is cleared below */ ++ 0x2D, 0x87, /* FIFFQ=0 */ ++ 0x2F, 0xF3, ++ 0x30, 0x0C, /* New - ver 1.11 */ ++ 0x31, 0x1B, /* New - ver 1.11 */ ++ 0x2C, 0x04, /* bit at 0x20 is cleared here */ ++ 0x28, 0xE1, /* Set the FIFCrst bit here */ ++ 0x28, 0xE0, /* Clear the FIFCrst bit here */ ++ 0x00 }; ++ ++ /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */ ++ U8Data MT2063B3_defaults[] = { /* Reg, Value */ ++ 0x05, 0xF0, ++ 0x11, 0x13, /* disable SDEXT/INTsd for init */ ++ 0x2C, 0x24, /* bit at 0x20 is cleared below */ ++ 0x2C, 0x04, /* bit at 0x20 is cleared here */ ++ 0x28, 0xE1, /* Set the FIFCrst bit here */ ++ 0x28, 0xE0, /* Clear the FIFCrst bit here */ ++ 0x00 }; ++ ++ U8Data *def=MT2063B3_defaults; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ /* Read the Part/Rev code from the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, PART_REV, pInfo->reg, 1); ++ ++ /* Read the Part/Rev codes (2nd byte) from the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, RSVD_3B, &pInfo->reg[RSVD_3B], 2); ++ ++ if (MT_NO_ERROR(status)) { /* Check the part/rev code */ ++ switch (pInfo->reg[PART_REV]) { ++ case 0x9e : { ++ if ( (pInfo->reg[RSVD_3C] & 0x18) == 0x08 ) { ++ rev = MT2063_XX; ++ status |= MT_TUNER_ID_ERR; ++ } ++ else { ++ rev = MT2063_B3; ++ def = MT2063B3_defaults; ++ } ++ break; ++ } ++ case 0x9c : { ++ rev = MT2063_B1; ++ def = MT2063B1_defaults; ++ break; ++ } ++ case 0x9b : { ++ rev = MT2063_B0; ++ def = MT2063B0_defaults; ++ break; ++ } ++ default : { ++ rev = MT2063_XX; ++ status |= MT_TUNER_ID_ERR; ++ break; ++ } ++ } ++ } ++ ++ if (MT_NO_ERROR(status) /* Check the 2nd part/rev code */ ++ && ((pInfo->reg[RSVD_3B] & 0x80) != 0x00)) /* b7 != 0 ==> NOT MT2063 */ ++ status |= MT_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */ ++ ++ /* Reset the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ LO2CQ_3, ++ &all_resets, ++ 1); ++ ++ while (MT_NO_ERROR(status) && *def) ++ { ++ U8Data reg = *def++; ++ U8Data val = *def++; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1); ++ } ++ ++ /* Wait for FIFF location to complete. */ ++ if (MT_NO_ERROR(status)) ++ { ++ UData_t FCRUN = 1; ++ SData_t maxReads = 10; ++ while (MT_NO_ERROR(status) && (FCRUN != 0) && (maxReads-- > 0)) ++ { ++ MT2063_Sleep(pInfo->hUserData, 2); ++ status |= MT2063_ReadSub(pInfo->hUserData, ++ pInfo->address, ++ XO_STATUS, ++ &pInfo->reg[XO_STATUS], ++ 1); ++ FCRUN = (pInfo->reg[XO_STATUS] & 0x40) >> 6; ++ } ++ ++ if (FCRUN != 0) ++ status |= MT_TUNER_INIT_ERR | MT_TUNER_TIMEOUT; ++ ++ if (MT_NO_ERROR(status)) /* Re-read FIFFC value */ ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, FIFFC, &pInfo->reg[FIFFC], 1); ++ } ++ ++ /* Read back all the registers from the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, ++ pInfo->address, ++ PART_REV, ++ pInfo->reg, ++ END_REGS); ++ ++ if (MT_NO_ERROR(status)) ++ { ++ /* Initialize the tuner state. */ ++ pInfo->version = MT2063_MODULE_VERSION; ++ pInfo->tuner_id = rev; ++ pInfo->AS_Data.f_ref = REF_FREQ; ++ pInfo->AS_Data.f_if1_Center = (pInfo->AS_Data.f_ref / 8) * ((UData_t) pInfo->reg[FIFFC] + 640); ++ pInfo->AS_Data.f_if1_bw = IF1_BW; ++ pInfo->AS_Data.f_out = 36125000; ++ pInfo->AS_Data.f_out_bw = 8000000; ++ pInfo->AS_Data.f_zif_bw = ZIF_BW; ++ pInfo->AS_Data.f_LO1_Step = pInfo->AS_Data.f_ref / 64; ++ pInfo->AS_Data.f_LO2_Step = TUNE_STEP_SIZE; ++ pInfo->AS_Data.maxH1 = MAX_HARMONICS_1; ++ pInfo->AS_Data.maxH2 = MAX_HARMONICS_2; ++ pInfo->AS_Data.f_min_LO_Separation = MIN_LO_SEP; ++ pInfo->AS_Data.f_if1_Request = pInfo->AS_Data.f_if1_Center; ++ pInfo->AS_Data.f_LO1 = 2181000000U; ++ pInfo->AS_Data.f_LO2 = 1486249786; ++ pInfo->f_IF1_actual = pInfo->AS_Data.f_if1_Center; ++ pInfo->AS_Data.f_in = pInfo->AS_Data.f_LO1 - pInfo->f_IF1_actual; ++ pInfo->AS_Data.f_LO1_FracN_Avoid = LO1_FRACN_AVOID; ++ pInfo->AS_Data.f_LO2_FracN_Avoid = LO2_FRACN_AVOID; ++ pInfo->num_regs = END_REGS; ++ pInfo->AS_Data.avoidDECT = MT_AVOID_BOTH; ++ pInfo->ctfilt_sw = 1; ++ } ++ ++ if (MT_NO_ERROR(status)) ++ { ++ pInfo->CTFiltMax[ 0] = 69422000; ++ pInfo->CTFiltMax[ 1] = 106211000; ++ pInfo->CTFiltMax[ 2] = 140427000; ++ pInfo->CTFiltMax[ 3] = 177240000; ++ pInfo->CTFiltMax[ 4] = 213091000; ++ pInfo->CTFiltMax[ 5] = 241378000; ++ pInfo->CTFiltMax[ 6] = 274596000; ++ pInfo->CTFiltMax[ 7] = 309696000; ++ pInfo->CTFiltMax[ 8] = 342398000; ++ pInfo->CTFiltMax[ 9] = 378728000; ++ pInfo->CTFiltMax[10] = 416053000; ++ pInfo->CTFiltMax[11] = 456693000; ++ pInfo->CTFiltMax[12] = 496105000; ++ pInfo->CTFiltMax[13] = 534448000; ++ pInfo->CTFiltMax[14] = 572893000; ++ pInfo->CTFiltMax[15] = 603218000; ++ pInfo->CTFiltMax[16] = 632650000; ++ pInfo->CTFiltMax[17] = 668229000; ++ pInfo->CTFiltMax[18] = 710828000; ++ pInfo->CTFiltMax[19] = 735135000; ++ pInfo->CTFiltMax[20] = 765601000; ++ pInfo->CTFiltMax[21] = 809919000; ++ pInfo->CTFiltMax[22] = 842538000; ++ pInfo->CTFiltMax[23] = 863353000; ++ pInfo->CTFiltMax[24] = 911285000; ++ pInfo->CTFiltMax[25] = 942310000; ++ pInfo->CTFiltMax[26] = 977602000; ++ pInfo->CTFiltMax[27] = 1015100000; ++ pInfo->CTFiltMax[28] = 1053415000; ++ pInfo->CTFiltMax[29] = 1098330000; ++ pInfo->CTFiltMax[30] = 1138990000; ++ } ++ ++ /* ++ ** Fetch the FCU osc value and use it and the fRef value to ++ ** scale all of the Band Max values ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ UData_t fcu_osc; ++ UData_t i; ++ ++ pInfo->reg[CTUNE_CTRL] = 0x0A; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, CTUNE_CTRL, &pInfo->reg[CTUNE_CTRL], 1); ++ ++ /* Read the ClearTune filter calibration value */ ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, FIFFC, &pInfo->reg[FIFFC], 1); ++ fcu_osc = pInfo->reg[FIFFC]; ++ ++ pInfo->reg[CTUNE_CTRL] = 0x00; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, CTUNE_CTRL, &pInfo->reg[CTUNE_CTRL], 1); ++ ++ /* Adjust each of the values in the ClearTune filter cross-over table */ ++ for (i = 0; i < 31; i++) ++ { ++ if (fcu_osc>127) pInfo->CTFiltMax[i] += ( fcu_osc - 128 ) * df_dosc[i]; ++ else pInfo->CTFiltMax[i] -= ( 128 - fcu_osc ) * df_dosc[i]; ++ } ++ } ++ ++ /* ++ ** Set the default receiver mode ++ ** ++ */ ++ ++// if (MT_NO_ERROR(status) ) ++// { ++// status |= MT2063_SetParam(h,MT2063_RCVR_MODE,MT2063_CABLE_QAM); ++// } ++ ++ ++ /* ++ ** Tune to the default frequency ++ ** ++ */ ++ ++// if (MT_NO_ERROR(status) ) ++// { ++// status |= MT2063_Tune(h,DEF_FIN_FREQ); ++// } ++ ++ /* ++ ** Enable SDEXT pin again ++ ** ++ */ ++ ++ if ( (MT_NO_ERROR(status)) && (pInfo->tuner_id >= MT2063_B3) ) ++ { ++ status |= MT2063_SetReg(h,PWR_1,0x1b); ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_SetGPIO ++** ++** Description: Modify the MT2063 GPIO value. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** gpio_id - Selects GPIO0, GPIO1 or GPIO2 ++** attr - Selects input readback, I/O direction or ++** output value ++** value - value to set GPIO pin 15, 14 or 19 ++** ++** Usage: status = MT2063_SetGPIO(hMT2063, MT2063_GPIO1, MT2063_GPIO_OUT, 1); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_SetGPIO(Handle_t h, MT2063_GPIO_ID gpio_id, ++ MT2063_GPIO_Attr attr, ++ UData_t value) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data regno; ++ SData_t shift; ++ const U8Data GPIOreg[3] = {0x15, 0x19, 0x18}; ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ regno = GPIOreg[attr]; ++ ++ shift = (SData_t)(gpio_id - MT2063_GPIO0 + 5); ++ ++ if (value & 0x01) ++ pInfo->reg[regno] |= (0x01 << shift); ++ else ++ pInfo->reg[regno] &= ~(0x01 << shift); ++ status = MT2063_WriteSub(pInfo->hUserData, pInfo->address, regno, &pInfo->reg[regno], 1); ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetParam ++** ++** Description: Sets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm. You can override many of the tuning ++** algorithm defaults using this function. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2063_Param) ++** nValue - value to be set ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2063_SRO_FREQ crystal frequency ++** MT2063_STEPSIZE minimum tuning step size ++** MT2063_LO1_FREQ LO1 frequency ++** MT2063_LO1_STEPSIZE LO1 minimum step size ++** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region ++** MT2063_IF1_REQUEST Requested 1st IF ++** MT2063_ZIF_BW zero-IF bandwidth ++** MT2063_LO2_FREQ LO2 frequency ++** MT2063_LO2_STEPSIZE LO2 minimum step size ++** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region ++** MT2063_OUTPUT_FREQ output center frequency ++** MT2063_OUTPUT_BW output bandwidth ++** MT2063_LO_SEPARATION min inter-tuner LO separation ++** MT2063_MAX_HARM1 max # of intra-tuner harmonics ++** MT2063_MAX_HARM2 max # of inter-tuner harmonics ++** MT2063_RCVR_MODE Predefined modes ++** MT2063_LNA_RIN Set LNA Rin (*) ++** MT2063_LNA_TGT Set target power level at LNA (*) ++** MT2063_PD1_TGT Set target power level at PD1 (*) ++** MT2063_PD2_TGT Set target power level at PD2 (*) ++** MT2063_ACLNA_MAX LNA attenuator limit (*) ++** MT2063_ACRF_MAX RF attenuator limit (*) ++** MT2063_ACFIF_MAX FIF attenuator limit (*) ++** MT2063_DNC_OUTPUT_ENABLE DNC output selection ++** MT2063_VGAGC VGA gain code ++** MT2063_VGAOI VGA output current ++** MT2063_TAGC TAGC setting ++** MT2063_AMPGC AMP gain code ++** MT2063_AVOID_DECT Avoid DECT Frequencies ++** MT2063_CTFILT_SW Cleartune filter selection ++** ++** (*) This parameter is set by MT2063_RCVR_MODE, do not call ++** additionally. ++** ++** Usage: status |= MT2063_SetParam(hMT2063, ++** MT2063_STEPSIZE, ++** 50000); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** or set value out of range ++** or non-writable parameter ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** See Also: MT2063_GetParam, MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 06-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 01-20-2009 PINZ Ver 1.28: Fixed a compare to avoid compiler warning ++** ++****************************************************************************/ ++UData_t MT2063_SetParam(Handle_t h, ++ MT2063_Param param, ++ UData_t nValue) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data val=0; ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ switch (param) ++ { ++ /* crystal frequency */ ++ case MT2063_SRO_FREQ: ++ pInfo->AS_Data.f_ref = nValue; ++ pInfo->AS_Data.f_LO1_FracN_Avoid = 0; ++ pInfo->AS_Data.f_LO2_FracN_Avoid = nValue / 80 - 1; ++ pInfo->AS_Data.f_LO1_Step = nValue / 64; ++ pInfo->AS_Data.f_if1_Center = (pInfo->AS_Data.f_ref / 8) * (pInfo->reg[FIFFC] + 640); ++ break; ++ ++ /* minimum tuning step size */ ++ case MT2063_STEPSIZE: ++ pInfo->AS_Data.f_LO2_Step = nValue; ++ break; ++ ++ ++ /* LO1 frequency */ ++ case MT2063_LO1_FREQ: ++ { ++ /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */ ++ /* Capture the Divider and Numerator portions of other LO */ ++ U8Data tempLO2CQ[3]; ++ U8Data tempLO2C[3]; ++ U8Data tmpOneShot; ++ UData_t Div, FracN; ++ U8Data restore = 0; ++ ++ /* Buffer the queue for restoration later and get actual LO2 values. */ ++ status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, LO2CQ_1, &(tempLO2CQ[0]), 3); ++ status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, LO2C_1, &(tempLO2C[0]), 3); ++ ++ /* clear the one-shot bits */ ++ tempLO2CQ[2] = tempLO2CQ[2] & 0x0F; ++ tempLO2C[2] = tempLO2C[2] & 0x0F; ++ ++ /* only write the queue values if they are different from the actual. */ ++ if( ( tempLO2CQ[0] != tempLO2C[0] ) || ++ ( tempLO2CQ[1] != tempLO2C[1] ) || ++ ( tempLO2CQ[2] != tempLO2C[2] ) ) ++ { ++ /* put actual LO2 value into queue (with 0 in one-shot bits) */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_1, &(tempLO2C[0]), 3); ++ ++ if( status == MT_OK ) ++ { ++ /* cache the bytes just written. */ ++ pInfo->reg[LO2CQ_1] = tempLO2C[0]; ++ pInfo->reg[LO2CQ_2] = tempLO2C[1]; ++ pInfo->reg[LO2CQ_3] = tempLO2C[2]; ++ } ++ restore = 1; ++ } ++ ++ /* Calculate the Divider and Numberator components of LO1 */ ++ status = CalcLO1Mult(&Div, &FracN, nValue, pInfo->AS_Data.f_ref/64, pInfo->AS_Data.f_ref); ++ pInfo->reg[LO1CQ_1] = (U8Data)(Div & 0x00FF); ++ pInfo->reg[LO1CQ_2] = (U8Data)(FracN); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &pInfo->reg[LO1CQ_1], 2); ++ ++ /* set the one-shot bit to load the pair of LO values */ ++ tmpOneShot = tempLO2CQ[2] | 0xE0; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_3, &tmpOneShot, 1); ++ ++ /* only restore the queue values if they were different from the actual. */ ++ if( restore ) ++ { ++ /* put actual LO2 value into queue (0 in one-shot bits) */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_1, &(tempLO2CQ[0]), 3); ++ ++ /* cache the bytes just written. */ ++ pInfo->reg[LO2CQ_1] = tempLO2CQ[0]; ++ pInfo->reg[LO2CQ_2] = tempLO2CQ[1]; ++ pInfo->reg[LO2CQ_3] = tempLO2CQ[2]; ++ } ++ ++ status |= MT2063_GetParam( pInfo->hUserData, MT2063_LO1_FREQ, &pInfo->AS_Data.f_LO1 ); ++ } ++ break; ++ ++ /* LO1 minimum step size */ ++ case MT2063_LO1_STEPSIZE: ++ pInfo->AS_Data.f_LO1_Step = nValue; ++ break; ++ ++ /* LO1 FracN keep-out region */ ++ case MT2063_LO1_FRACN_AVOID: ++ pInfo->AS_Data.f_LO1_FracN_Avoid = nValue; ++ break; ++ ++ /* Requested 1st IF */ ++ case MT2063_IF1_REQUEST: ++ pInfo->AS_Data.f_if1_Request = nValue; ++ break; ++ ++ /* zero-IF bandwidth */ ++ case MT2063_ZIF_BW: ++ pInfo->AS_Data.f_zif_bw = nValue; ++ break; ++ ++ /* LO2 frequency */ ++ case MT2063_LO2_FREQ: ++ { ++ /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */ ++ /* Capture the Divider and Numerator portions of other LO */ ++ U8Data tempLO1CQ[2]; ++ U8Data tempLO1C[2]; ++ UData_t Div2; ++ UData_t FracN2; ++ U8Data tmpOneShot; ++ U8Data restore = 0; ++ ++ /* Buffer the queue for restoration later and get actual LO2 values. */ ++ status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, LO1CQ_1, &(tempLO1CQ[0]), 2); ++ status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, LO1C_1, &(tempLO1C[0]), 2); ++ ++ /* only write the queue values if they are different from the actual. */ ++ if( (tempLO1CQ[0] != tempLO1C[0]) || (tempLO1CQ[1] != tempLO1C[1]) ) ++ { ++ /* put actual LO1 value into queue */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &(tempLO1C[0]), 2); ++ ++ /* cache the bytes just written. */ ++ pInfo->reg[LO1CQ_1] = tempLO1C[0]; ++ pInfo->reg[LO1CQ_2] = tempLO1C[1]; ++ restore = 1; ++ } ++ ++ /* Calculate the Divider and Numberator components of LO2 */ ++ status |= CalcLO2Mult(&Div2, &FracN2, nValue, pInfo->AS_Data.f_ref/8191, pInfo->AS_Data.f_ref); ++ pInfo->reg[LO2CQ_1] = (U8Data)((Div2 << 1) | ((FracN2 >> 12) & 0x01) ) & 0xFF; ++ pInfo->reg[LO2CQ_2] = (U8Data)((FracN2 >> 4) & 0xFF); ++ pInfo->reg[LO2CQ_3] = (U8Data)((FracN2 & 0x0F) ); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &pInfo->reg[LO1CQ_1], 3); ++ ++ /* set the one-shot bit to load the LO values */ ++ tmpOneShot = pInfo->reg[LO2CQ_3] | 0xE0; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_3, &tmpOneShot, 1); ++ ++ /* only restore LO1 queue value if they were different from the actual. */ ++ if( restore ) ++ { ++ /* put previous LO1 queue value back into queue */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &(tempLO1CQ[0]), 2); ++ ++ /* cache the bytes just written. */ ++ pInfo->reg[LO1CQ_1] = tempLO1CQ[0]; ++ pInfo->reg[LO1CQ_2] = tempLO1CQ[1]; ++ } ++ ++ status |= MT2063_GetParam( pInfo->hUserData, MT2063_LO2_FREQ, &pInfo->AS_Data.f_LO2 ); ++ } ++ break; ++ ++ /* LO2 minimum step size */ ++ case MT2063_LO2_STEPSIZE: ++ pInfo->AS_Data.f_LO2_Step = nValue; ++ break; ++ ++ /* LO2 FracN keep-out region */ ++ case MT2063_LO2_FRACN_AVOID: ++ pInfo->AS_Data.f_LO2_FracN_Avoid = nValue; ++ break; ++ ++ /* output center frequency */ ++ case MT2063_OUTPUT_FREQ: ++ pInfo->AS_Data.f_out = nValue; ++ break; ++ ++ /* output bandwidth */ ++ case MT2063_OUTPUT_BW: ++ pInfo->AS_Data.f_out_bw = nValue + 750000; ++ break; ++ ++ /* min inter-tuner LO separation */ ++ case MT2063_LO_SEPARATION: ++ pInfo->AS_Data.f_min_LO_Separation = nValue; ++ break; ++ ++ /* max # of intra-tuner harmonics */ ++ case MT2063_MAX_HARM1: ++ pInfo->AS_Data.maxH1 = nValue; ++ break; ++ ++ /* max # of inter-tuner harmonics */ ++ case MT2063_MAX_HARM2: ++ pInfo->AS_Data.maxH2 = nValue; ++ break; ++ ++ case MT2063_RCVR_MODE: ++ status |= MT2063_SetReceiverMode(pInfo, (MT2063_RCVR_MODES)nValue); ++ break; ++ ++ /* Set LNA Rin -- nValue is desired value */ ++ case MT2063_LNA_RIN: ++ val = (U8Data)( ( pInfo->reg[CTRL_2C] & (U8Data)~0x03) | (nValue & 0x03) ); ++ if( pInfo->reg[CTRL_2C] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, CTRL_2C, val); ++ } ++ break; ++ ++ /* Set target power level at LNA -- nValue is desired value */ ++ case MT2063_LNA_TGT: ++ val = (U8Data)( ( pInfo->reg[LNA_TGT] & (U8Data)~0x3F) | (nValue & 0x3F) ); ++ if( pInfo->reg[LNA_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, LNA_TGT, val); ++ } ++ break; ++ ++ /* Set target power level at PD1 -- nValue is desired value */ ++ case MT2063_PD1_TGT: ++ val = (U8Data)( ( pInfo->reg[PD1_TGT] & (U8Data)~0x3F) | (nValue & 0x3F) ); ++ if( pInfo->reg[PD1_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, PD1_TGT, val); ++ } ++ break; ++ ++ /* Set target power level at PD2 -- nValue is desired value */ ++ case MT2063_PD2_TGT: ++ val = (U8Data)( ( pInfo->reg[PD2_TGT] & (U8Data)~0x3F) | (nValue & 0x3F) ); ++ if( pInfo->reg[PD2_TGT] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, PD2_TGT, val); ++ } ++ break; ++ ++ /* Set LNA atten limit -- nValue is desired value */ ++ case MT2063_ACLNA_MAX: ++ val = (U8Data)( ( pInfo->reg[LNA_OV] & (U8Data)~0x1F) | (nValue & 0x1F) ); ++ if( pInfo->reg[LNA_OV] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, LNA_OV, val); ++ } ++ break; ++ ++ /* Set RF atten limit -- nValue is desired value */ ++ case MT2063_ACRF_MAX: ++ val = (U8Data)( ( pInfo->reg[RF_OV] & (U8Data)~0x1F) | (nValue & 0x1F) ); ++ if( pInfo->reg[RF_OV] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, RF_OV, val); ++ } ++ break; ++ ++ /* Set FIF atten limit -- nValue is desired value, max. 5 if no B3 */ ++ case MT2063_ACFIF_MAX: ++ if ( (pInfo->tuner_id == MT2063_B0 || pInfo->tuner_id == MT2063_B1) && nValue > 5) ++ nValue = 5; ++ val = (U8Data)( ( pInfo->reg[FIF_OV] & (U8Data)~0x1F) | (nValue & 0x1F) ); ++ if( pInfo->reg[FIF_OV] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, FIF_OV, val); ++ } ++ break; ++ ++ case MT2063_DNC_OUTPUT_ENABLE: ++ /* selects, which DNC output is used */ ++ switch ((MT2063_DNC_Output_Enable)nValue) ++ { ++ case MT2063_DNC_NONE : ++ { ++ val = (pInfo->reg[DNC_GAIN] & 0xFC ) | 0x03; /* Set DNC1GC=3 */ ++ if (pInfo->reg[DNC_GAIN] != val) ++ status |= MT2063_SetReg(h, DNC_GAIN, val); ++ ++ val = (pInfo->reg[VGA_GAIN] & 0xFC ) | 0x03; /* Set DNC2GC=3 */ ++ if (pInfo->reg[VGA_GAIN] != val) ++ status |= MT2063_SetReg(h, VGA_GAIN, val); ++ ++ val = (pInfo->reg[RSVD_20] & ~0x40); /* Set PD2MUX=0 */ ++ if (pInfo->reg[RSVD_20] != val) ++ status |= MT2063_SetReg(h, RSVD_20, val); ++ ++ break; ++ } ++ case MT2063_DNC_1 : ++ { ++ val = (pInfo->reg[DNC_GAIN] & 0xFC ) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */ ++ if (pInfo->reg[DNC_GAIN] != val) ++ status |= MT2063_SetReg(h, DNC_GAIN, val); ++ ++ val = (pInfo->reg[VGA_GAIN] & 0xFC ) | 0x03; /* Set DNC2GC=3 */ ++ if (pInfo->reg[VGA_GAIN] != val) ++ status |= MT2063_SetReg(h, VGA_GAIN, val); ++ ++ val = (pInfo->reg[RSVD_20] & ~0x40); /* Set PD2MUX=0 */ ++ if (pInfo->reg[RSVD_20] != val) ++ status |= MT2063_SetReg(h, RSVD_20, val); ++ ++ break; ++ } ++ case MT2063_DNC_2 : ++ { ++ val = (pInfo->reg[DNC_GAIN] & 0xFC ) | 0x03; /* Set DNC1GC=3 */ ++ if (pInfo->reg[DNC_GAIN] != val) ++ status |= MT2063_SetReg(h, DNC_GAIN, val); ++ ++ val = (pInfo->reg[VGA_GAIN] & 0xFC ) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */ ++ if (pInfo->reg[VGA_GAIN] != val) ++ status |= MT2063_SetReg(h, VGA_GAIN, val); ++ ++ val = (pInfo->reg[RSVD_20] | 0x40); /* Set PD2MUX=1 */ ++ if (pInfo->reg[RSVD_20] != val) ++ status |= MT2063_SetReg(h, RSVD_20, val); ++ ++ break; ++ } ++ case MT2063_DNC_BOTH : ++ { ++ val = (pInfo->reg[DNC_GAIN] & 0xFC ) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */ ++ if (pInfo->reg[DNC_GAIN] != val) ++ status |= MT2063_SetReg(h, DNC_GAIN, val); ++ ++ val = (pInfo->reg[VGA_GAIN] & 0xFC ) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */ ++ if (pInfo->reg[VGA_GAIN] != val) ++ status |= MT2063_SetReg(h, VGA_GAIN, val); ++ ++ val = (pInfo->reg[RSVD_20] | 0x40); /* Set PD2MUX=1 */ ++ if (pInfo->reg[RSVD_20] != val) ++ status |= MT2063_SetReg(h, RSVD_20, val); ++ ++ break; ++ } ++ default : break; ++ } ++ break; ++ ++ case MT2063_VGAGC: ++ /* Set VGA gain code */ ++ val = (U8Data)( (pInfo->reg[VGA_GAIN] & (U8Data)~0x0C) | ( (nValue & 0x03) << 2) ); ++ if( pInfo->reg[VGA_GAIN] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, VGA_GAIN, val); ++ } ++ break; ++ ++ case MT2063_VGAOI: ++ /* Set VGA bias current */ ++ val = (U8Data)( (pInfo->reg[RSVD_31] & (U8Data)~0x07) | (nValue & 0x07) ); ++ if( pInfo->reg[RSVD_31] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, RSVD_31, val); ++ } ++ break; ++ ++ case MT2063_TAGC: ++ /* Set TAGC */ ++ val = (U8Data)( (pInfo->reg[RSVD_1E] & (U8Data)~0x03) | (nValue & 0x03) ); ++ if( pInfo->reg[RSVD_1E] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, RSVD_1E, val); ++ } ++ break; ++ ++ case MT2063_AMPGC: ++ /* Set Amp gain code */ ++ val = (U8Data)( (pInfo->reg[TEMP_SEL] & (U8Data)~0x03) | (nValue & 0x03) ); ++ if( pInfo->reg[TEMP_SEL] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, TEMP_SEL, val); ++ } ++ break; ++ ++ /* Avoid DECT Frequencies */ ++ case MT2063_AVOID_DECT: ++ { ++ MT_DECT_Avoid_Type newAvoidSetting = (MT_DECT_Avoid_Type) nValue; ++ if (newAvoidSetting <= MT_AVOID_BOTH) ++ { ++ pInfo->AS_Data.avoidDECT = newAvoidSetting; ++ } ++ } ++ break; ++ ++ /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ ++ case MT2063_CTFILT_SW: ++ pInfo->ctfilt_sw = (nValue & 0x01); ++ break; ++ ++ /* These parameters are read-only */ ++ case MT2063_VERSION: ++ case MT2063_IC_ADDR: ++ case MT2063_IC_REV: ++ case MT2063_MAX_OPEN: ++ case MT2063_NUM_OPEN: ++ case MT2063_INPUT_FREQ: ++ case MT2063_IF1_ACTUAL: ++ case MT2063_IF1_CENTER: ++ case MT2063_IF1_BW: ++ case MT2063_AS_ALG: ++ case MT2063_EXCL_ZONES: ++ case MT2063_SPUR_AVOIDED: ++ case MT2063_NUM_SPURS: ++ case MT2063_SPUR_PRESENT: ++ case MT2063_PD1: ++ case MT2063_PD2: ++ case MT2063_ACLNA: ++ case MT2063_ACRF: ++ case MT2063_ACFIF: ++ case MT2063_EOP: ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ } ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetPowerMaskBits ++** ++** Description: Sets the power-down mask bits for various sections of ++** the MT2063 ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to be set. ++** ++** See definition of MT2063_Mask_Bits type for description ++** of each of the power bits. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetPowerMaskBits(Handle_t h, MT2063_Mask_Bits Bits) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ Bits = (MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ ++ if ((Bits & 0xFF00) != 0) ++ { ++ pInfo->reg[PWR_2] |= (U8Data)((Bits & 0xFF00) >> 8); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_2, &pInfo->reg[PWR_2], 1); ++ } ++ if ((Bits & 0xFF) != 0) ++ { ++ pInfo->reg[PWR_1] |= ((U8Data)Bits & 0xFF); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 1); ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_ClearPowerMaskBits ++** ++** Description: Clears the power-down mask bits for various sections of ++** the MT2063 ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to be cleared. ++** ++** See definition of MT2063_Mask_Bits type for description ++** of each of the power bits. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_ClearPowerMaskBits(Handle_t h, MT2063_Mask_Bits Bits) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ Bits = (MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ ++ if ((Bits & 0xFF00) != 0) ++ { ++ pInfo->reg[PWR_2] &= ~(U8Data)(Bits >> 8); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_2, &pInfo->reg[PWR_2], 1); ++ } ++ if ((Bits & 0xFF) != 0) ++ { ++ pInfo->reg[PWR_1] &= ~(U8Data)(Bits & 0xFF); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 1); ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetPowerMaskBits ++** ++** Description: Returns a mask of the enabled power shutdown bits ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to currently set. ++** ++** See definition of MT2063_Mask_Bits type for description ++** of each of the power bits. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Output argument is NULL ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetPowerMaskBits(Handle_t h, MT2063_Mask_Bits *Bits) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ if (Bits == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (MT_NO_ERROR(status)) ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 2); ++ ++ if (MT_NO_ERROR(status)) ++ { ++ *Bits = (MT2063_Mask_Bits)(((SData_t)pInfo->reg[PWR_2] << 8) + pInfo->reg[PWR_1]); ++ *Bits = (MT2063_Mask_Bits)(*Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */ ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_EnableExternalShutdown ++** ++** Description: Enables or disables the operation of the external ++** shutdown pin ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Enabled - 0 = disable the pin, otherwise enable it ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ if (Enabled == 0) ++ pInfo->reg[PWR_1] &= ~0x08; /* Turn off the bit */ ++ else ++ pInfo->reg[PWR_1] |= 0x08; /* Turn the bit on */ ++ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 1); ++ } ++ ++ return (UData_t)(status); ++} ++ ++/**************************************************************************** ++** ++** Name: MT2063_SoftwareShutdown ++** ++** Description: Enables or disables software shutdown function. When ++** Shutdown==1, any section whose power mask is set will be ++** shutdown. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Shutdown - 1 = shutdown the masked sections, otherwise ++** power all sections on ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 01-03-2008 PINZ Ver 1.xx: Added a trigger of BYPATNUP for ++** correct wakeup of the LNA ++** ++****************************************************************************/ ++UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ if (Shutdown == 1) ++ pInfo->reg[PWR_1] |= 0x04; /* Turn the bit on */ ++ else ++ pInfo->reg[PWR_1] &= ~0x04; /* Turn off the bit */ ++ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, PWR_1, &pInfo->reg[PWR_1], 1); ++ ++ if (Shutdown != 1) ++ { ++ pInfo->reg[BYP_CTRL] = (pInfo->reg[BYP_CTRL] & 0x9F) | 0x40; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, BYP_CTRL, &pInfo->reg[BYP_CTRL], 1); ++ pInfo->reg[BYP_CTRL] = (pInfo->reg[BYP_CTRL] & 0x9F); ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, BYP_CTRL, &pInfo->reg[BYP_CTRL], 1); ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetExtSRO ++** ++** Description: Sets the external SRO driver. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Ext_SRO_Setting - external SRO drive setting ++** ++** (default) MT2063_EXT_SRO_OFF - ext driver off ++** MT2063_EXT_SRO_BY_1 - ext driver = SRO frequency ++** MT2063_EXT_SRO_BY_2 - ext driver = SRO/2 frequency ++** MT2063_EXT_SRO_BY_4 - ext driver = SRO/4 frequency ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** The Ext_SRO_Setting settings default to OFF ++** Use this function if you need to override the default ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 189 S 05-13-2008 RSK Ver 1.16: Correct location for ExtSRO control. ++** ++****************************************************************************/ ++UData_t MT2063_SetExtSRO(Handle_t h, ++ MT2063_Ext_SRO Ext_SRO_Setting) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ else ++ { ++ pInfo->reg[CTRL_2C] = (pInfo->reg[CTRL_2C] & 0x3F) | ((U8Data)Ext_SRO_Setting << 6); ++ status = MT2063_WriteSub(pInfo->hUserData, pInfo->address, CTRL_2C, &pInfo->reg[CTRL_2C], 1); ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetReg ++** ++** Description: Sets an MT2063 register. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** reg - MT2063 register/subaddress location ++** val - MT2063 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Use this function if you need to override a default ++** register value ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetReg(Handle_t h, ++ U8Data reg, ++ U8Data val) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1); ++ if (MT_NO_ERROR(status)) ++ pInfo->reg[reg] = val; ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++static UData_t Round_fLO(UData_t f_LO, UData_t f_LO_Step, UData_t f_ref) ++{ ++ return (UData_t)( f_ref * (f_LO / f_ref) ++ + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step) ); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: fLO_FractionalTerm ++** ++** Description: Calculates the portion contributed by FracN / denom. ++** ++** This function preserves maximum precision without ++** risk of overflow. It accurately calculates ++** f_ref * num / denom to within 1 HZ with fixed math. ++** ++** Parameters: num - Fractional portion of the multiplier ++** denom - denominator portion of the ratio ++** This routine successfully handles denom values ++** up to and including 2^18. ++** f_Ref - SRO frequency. This calculation handles ++** f_ref as two separate 14-bit fields. ++** Therefore, a maximum value of 2^28-1 ++** may safely be used for f_ref. This is ++** the genesis of the magic number "14" and the ++** magic mask value of 0x03FFF. ++** ++** Returns: f_ref * num / denom ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++static UData_t fLO_FractionalTerm( UData_t f_ref, ++ UData_t num, ++ UData_t denom ) ++{ ++ UData_t t1 = (f_ref >> 14) * num; ++ UData_t term1 = t1 / denom; ++ UData_t loss = t1 % denom; ++ UData_t term2 = ( ((f_ref & 0x00003FFF) * num + (loss<<14)) + (denom/2) ) / denom; ++ return (UData_t)( ((term1 << 14) + term2) ); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: CalcLO1Mult ++** ++** Description: Calculates Integer divider value and the numerator ++** value for a FracN PLL. ++** ++** This function assumes that the f_LO and f_Ref are ++** evenly divisible by f_LO_Step. ++** ++** Parameters: Div - OUTPUT: Whole number portion of the multiplier ++** FracN - OUTPUT: Fractional portion of the multiplier ++** f_LO - desired LO frequency. ++** f_LO_Step - Minimum step size for the LO (in Hz). ++** f_Ref - SRO frequency. ++** f_Avoid - Range of PLL frequencies to avoid near ++** integer multiples of f_Ref (in Hz). ++** ++** Returns: Recalculated LO frequency. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++static UData_t CalcLO1Mult(UData_t *Div, ++ UData_t *FracN, ++ UData_t f_LO, ++ UData_t f_LO_Step, ++ UData_t f_Ref) ++{ ++ /* Calculate the whole number portion of the divider */ ++ *Div = f_LO / f_Ref; ++ ++ /* Calculate the numerator value (round to nearest f_LO_Step) */ ++ *FracN = (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step); ++ ++ return (UData_t)( (f_Ref * (*Div)) + fLO_FractionalTerm( f_Ref, *FracN, 64 ) ); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: CalcLO2Mult ++** ++** Description: Calculates Integer divider value and the numerator ++** value for a FracN PLL. ++** ++** This function assumes that the f_LO and f_Ref are ++** evenly divisible by f_LO_Step. ++** ++** Parameters: Div - OUTPUT: Whole number portion of the multiplier ++** FracN - OUTPUT: Fractional portion of the multiplier ++** f_LO - desired LO frequency. ++** f_LO_Step - Minimum step size for the LO (in Hz). ++** f_Ref - SRO frequency. ++** f_Avoid - Range of PLL frequencies to avoid near ++** integer multiples of f_Ref (in Hz). ++** ++** Returns: Recalculated LO frequency. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 205 M 10-01-2008 JWS Ver 1.22: Use DMAX when LO2 FracN is near 4096 ++** ++****************************************************************************/ ++static UData_t CalcLO2Mult(UData_t *Div, ++ UData_t *FracN, ++ UData_t f_LO, ++ UData_t f_LO_Step, ++ UData_t f_Ref) ++{ ++ UData_t denom = 8191; ++ ++ /* Calculate the whole number portion of the divider */ ++ *Div = f_LO / f_Ref; ++ ++ /* Calculate the numerator value (round to nearest f_LO_Step) */ ++ *FracN = (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step); ++ ++ /* ++ ** FracN values close to 1/2 (4096) will be forced to 4096. The tuning code must ++ ** then set the DMAX bit for the affected LO(s). ++ */ ++ if ((*FracN >= 4083) && (*FracN <= 4107)) ++ { ++ *FracN = 4096; ++ denom = 8192; ++ } ++ ++ return (UData_t)( (f_Ref * (*Div)) + fLO_FractionalTerm( f_Ref, *FracN, denom ) ); ++} ++ ++/**************************************************************************** ++** ++** Name: FindClearTuneFilter ++** ++** Description: Calculate the corrrect ClearTune filter to be used for ++** a given input frequency. ++** ++** Parameters: pInfo - ptr to tuner data structure ++** f_in - RF input center frequency (in Hz). ++** ++** Returns: ClearTune filter number (0-31) ++** ++** Dependencies: MUST CALL MT2064_Open BEFORE FindClearTuneFilter! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 04-10-2008 PINZ Ver 1.14: Use software-controlled ClearTune ++** cross-over frequency values. ++** ++****************************************************************************/ ++static UData_t FindClearTuneFilter(MT2063_Info_t* pInfo, UData_t f_in) ++{ ++ UData_t RFBand; ++ UData_t idx; /* index loop */ ++ ++ /* ++ ** Find RF Band setting ++ */ ++ RFBand = 31; /* def when f_in > all */ ++ for (idx=0; idx<31; ++idx) ++ { ++ if (pInfo->CTFiltMax[idx] >= f_in) ++ { ++ RFBand = idx; ++ break; ++ } ++ } ++ return (UData_t)(RFBand); ++} ++ ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_Tune ++** ++** Description: Change the tuner's tuned frequency to RFin. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_UPC_UNLOCK - Upconverter PLL unlocked ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_SPUR_CNT_MASK - Count of avoided LO spurs ++** MT_SPUR_PRESENT - LO spur possible in output ++** MT_FIN_RANGE - Input freq out of range ++** MT_FOUT_RANGE - Output freq out of range ++** MT_UPC_RANGE - Upconverter freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2063_Open BEFORE MT2063_Tune! ++** ++** MT_ReadSub - Read data from the two-wire serial bus ++** MT_WriteSub - Write data to the two-wire serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2063_GetLocked - Checks to see if LO1 and LO2 are locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 04-10-2008 PINZ Ver 1.05: Use software-controlled ClearTune ++** cross-over frequency values. ++** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 205 M 10-01-2008 JWS Ver 1.22: Use DMAX when LO2 FracN is near 4096 ++** M 10-24-2008 JWS Ver 1.25: Use DMAX when LO1 FracN is 32 ++** ++****************************************************************************/ ++UData_t MT2063_Tune(Handle_t h, ++ UData_t f_in) /* RF input center frequency */ ++{ ++ MT2063_Info_t* pInfo = (MT2063_Info_t*) h; ++ ++ UData_t status = MT_OK; /* status of operation */ ++ UData_t LO1; /* 1st LO register value */ ++ UData_t Num1; /* Numerator for LO1 reg. value */ ++ UData_t f_IF1; /* 1st IF requested */ ++ UData_t LO2; /* 2nd LO register value */ ++ UData_t Num2; /* Numerator for LO2 reg. value */ ++ UData_t ofLO1, ofLO2; /* last time's LO frequencies */ ++ U8Data fiffc = 0x80; /* FIFF center freq from tuner */ ++ UData_t fiffof; /* Offset from FIFF center freq */ ++ const U8Data LO1LK = 0x80; /* Mask for LO1 Lock bit */ ++ U8Data LO2LK = 0x08; /* Mask for LO2 Lock bit */ ++ U8Data val; ++ UData_t RFBand; ++ U8Data oFN; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ return (UData_t)MT_INV_HANDLE; ++ ++ /* Check the input and output frequency ranges */ ++ if ((f_in < MIN_FIN_FREQ) || (f_in > MAX_FIN_FREQ)) ++ status |= MT_FIN_RANGE; ++ ++ if ((pInfo->AS_Data.f_out < MIN_FOUT_FREQ) || (pInfo->AS_Data.f_out > MAX_FOUT_FREQ)) ++ status |= MT_FOUT_RANGE; ++ ++ /* ++ ** Save original LO1 and LO2 register values ++ */ ++ ofLO1 = pInfo->AS_Data.f_LO1; ++ ofLO2 = pInfo->AS_Data.f_LO2; ++ ++ /* ++ ** Find and set RF Band setting ++ */ ++ if (pInfo->ctfilt_sw == 1) ++ { ++ val = ( pInfo->reg[CTUNE_CTRL] | 0x08 ); ++ if( pInfo->reg[CTUNE_CTRL] != val ) ++ { ++ status |= MT2063_SetReg(pInfo, CTUNE_CTRL, val); ++ } ++ ++ RFBand = FindClearTuneFilter(pInfo, f_in); ++ val = (U8Data)( (pInfo->reg[CTUNE_OV] & ~0x1F) | RFBand ); ++ if (pInfo->reg[CTUNE_OV] != val) ++ { ++ status |= MT2063_SetReg(pInfo, CTUNE_OV, val); ++ } ++ } ++ ++ /* ++ ** Read the FIFF Center Frequency from the tuner ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, FIFFC, &pInfo->reg[FIFFC], 1); ++ fiffc = pInfo->reg[FIFFC]; ++ } ++ ++ /* ++ ** Assign in the requested values ++ */ ++ pInfo->AS_Data.f_in = f_in; ++ /* Request a 1st IF such that LO1 is on a step size */ ++ pInfo->AS_Data.f_if1_Request = Round_fLO(pInfo->AS_Data.f_if1_Request + f_in, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref) - f_in; ++ ++ /* ++ ** Calculate frequency settings. f_IF1_FREQ + f_in is the ++ ** desired LO1 frequency ++ */ ++ MT2063_ResetExclZones(&pInfo->AS_Data); ++ ++ f_IF1 = MT2063_ChooseFirstIF(&pInfo->AS_Data); ++ pInfo->AS_Data.f_LO1 = Round_fLO(f_IF1 + f_in, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref); ++ pInfo->AS_Data.f_LO2 = Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); ++ ++ /* ++ ** Check for any LO spurs in the output bandwidth and adjust ++ ** the LO settings to avoid them if needed ++ */ ++ status |= MT2063_AvoidSpurs(h, &pInfo->AS_Data); ++ ++ /* ++ ** MT_AvoidSpurs spurs may have changed the LO1 & LO2 values. ++ ** Recalculate the LO frequencies and the values to be placed ++ ** in the tuning registers. ++ */ ++ pInfo->AS_Data.f_LO1 = CalcLO1Mult(&LO1, &Num1, pInfo->AS_Data.f_LO1, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref); ++ pInfo->AS_Data.f_LO2 = Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); ++ pInfo->AS_Data.f_LO2 = CalcLO2Mult(&LO2, &Num2, pInfo->AS_Data.f_LO2, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref); ++ ++ /* ++ ** Check the upconverter and downconverter frequency ranges ++ */ ++ if ((pInfo->AS_Data.f_LO1 < MIN_UPC_FREQ) || (pInfo->AS_Data.f_LO1 > MAX_UPC_FREQ)) ++ status |= MT_UPC_RANGE; ++ ++ if ((pInfo->AS_Data.f_LO2 < MIN_DNC_FREQ) || (pInfo->AS_Data.f_LO2 > MAX_DNC_FREQ)) ++ status |= MT_DNC_RANGE; ++ ++ /* LO2 Lock bit was in a different place for B0 version */ ++ if (pInfo->tuner_id == MT2063_B0) ++ LO2LK = 0x40; ++ ++ /* ++ ** If we have the same LO frequencies and we're already locked, ++ ** then skip re-programming the LO registers. ++ */ ++ if ((ofLO1 != pInfo->AS_Data.f_LO1) ++ || (ofLO2 != pInfo->AS_Data.f_LO2) ++ || ((pInfo->reg[LO_STATUS] & (LO1LK | LO2LK)) != (LO1LK | LO2LK))) ++ { ++ /* ++ ** Calculate the FIFFOF register value ++ ** ++ ** IF1_Actual ++ ** FIFFOF = ------------ - 8 * FIFFC - 4992 ++ ** f_ref/64 ++ */ ++ fiffof = (pInfo->AS_Data.f_LO1 - f_in) / (pInfo->AS_Data.f_ref / 64) - 8 * (UData_t)fiffc - 4992; ++ if (fiffof > 0xFF) ++ fiffof = 0xFF; ++ ++ /* ++ ** Place all of the calculated values into the local tuner ++ ** register fields. ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ oFN = pInfo->reg[FN_CTRL]; /* save current FN_CTRL settings */ ++ ++ /* ++ ** If either FracN is 4096 (or was rounded to there) then set its ++ ** DMAX bit, otherwise clear it. ++ */ ++ if (Num1 == 32) ++ pInfo->reg[FN_CTRL] |= 0x20; ++ else ++ pInfo->reg[FN_CTRL] &= ~0x20; ++ if (Num2 == 4096) ++ pInfo->reg[FN_CTRL] |= 0x02; ++ else ++ pInfo->reg[FN_CTRL] &= ~0x02; ++ ++ pInfo->reg[LO1CQ_1] = (U8Data)(LO1 & 0xFF); /* DIV1q */ ++ pInfo->reg[LO1CQ_2] = (U8Data)(Num1 & 0x3F); /* NUM1q */ ++ pInfo->reg[LO2CQ_1] = (U8Data)(((LO2 & 0x7F) << 1) /* DIV2q */ ++ | (Num2 >> 12)); /* NUM2q (hi) */ ++ pInfo->reg[LO2CQ_2] = (U8Data)((Num2 & 0x0FF0) >> 4); /* NUM2q (mid) */ ++ pInfo->reg[LO2CQ_3] = (U8Data)(0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */ ++ ++ /* ++ ** Now write out the computed register values ++ ** IMPORTANT: There is a required order for writing ++ ** (0x05 must follow all the others). ++ */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO1CQ_1, &pInfo->reg[LO1CQ_1], 5); /* 0x01 - 0x05 */ ++ ++ /* The FN_CTRL register is only needed if it changes */ ++ if (oFN != pInfo->reg[FN_CTRL]) ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, FN_CTRL, &pInfo->reg[FN_CTRL], 1); /* 0x34 */ ++ ++ if (pInfo->tuner_id == MT2063_B0) ++ { ++ /* Re-write the one-shot bits to trigger the tune operation */ ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, LO2CQ_3, &pInfo->reg[LO2CQ_3], 1); /* 0x05 */ ++ } ++ ++ /* Write out the FIFF offset only if it's changing */ ++ if (pInfo->reg[FIFF_OFFSET] != (U8Data)fiffof) ++ { ++ pInfo->reg[FIFF_OFFSET] = (U8Data)fiffof; ++ status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, FIFF_OFFSET, &pInfo->reg[FIFF_OFFSET], 1); ++ } ++ } ++ ++ /* ++ ** Check for LO's locking ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2063_GetLocked(h); ++ } ++ ++ /* ++ ** If we locked OK, assign calculated data to MT2063_Info_t structure ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ pInfo->f_IF1_actual = pInfo->AS_Data.f_LO1 - f_in; ++ } ++ } ++ ++ return (UData_t)(status); ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_spuravoid.c ++ ++ ++/***************************************************************************** ++** ++** Name: mt_spuravoid.c ++** ++** Copyright 2006-2008 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt_spuravoid.c ++** ++** Description: Microtune spur avoidance software module. ++** Supports Microtune tuner drivers. ++** ++** CVS ID: $Id: mt_spuravoid.c,v 1.4 2008/11/05 13:46:19 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_spuravoid.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 082 03-25-2005 JWS Original multi-tuner support - requires ++** MTxxxx_CNT declarations ++** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. ++** 094 04-06-2005 JWS Ver 1.11 Added uceil and ufloor to get rid ++** of compiler warnings ++** N/A 04-07-2005 DAD Ver 1.13: Merged single- and multi-tuner spur ++** avoidance into a single module. ++** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range ++** (f_min, f_max) < 0, ignore the entry. ++** 115 03-23-2007 DAD Fix declaration of spur due to truncation ++** errors. ++** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from ++** tuner DLL. ++** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for ++** multi-tuners that have ++** (delta IF1) > (f_out-f_outbw/2). ++** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) ++** Added logic to force f_Center within 1/2 f_Step. ++** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 ++** Type casts added to preserve correct sign. ++** 195 I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT ++** frequencies into MT_ResetExclZones(). ++** N/A I 06-20-2008 RSK Ver 1.21: New VERSION number for ver checking. ++** 199 08-06-2008 JWS Ver 1.22: Added 0x1x1 spur frequency calculations ++** and indicate success of AddExclZone operation. ++** 200 08-07-2008 JWS Ver 1.23: Moved definition of DECT avoid constants ++** so users could access them more easily. ++** ++*****************************************************************************/ ++//#include "mt_spuravoid.h" ++//#include ++//#include /* debug purposes */ ++ ++#if !defined(MT_TUNER_CNT) ++#error MT_TUNER_CNT is not defined (see mt_userdef.h) ++#endif ++ ++#if MT_TUNER_CNT == 0 ++#error MT_TUNER_CNT must be updated in mt_userdef.h ++#endif ++ ++/* Version of this module */ ++#define MT_SPURAVOID_VERSION 10203 /* Version 01.23 */ ++ ++ ++/* Implement ceiling, floor functions. */ ++#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0)) ++#define uceil(n, d) ((n)/(d) + ((n)%(d) != 0)) ++#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d)) ++#define ufloor(n, d) ((n)/(d)) ++ ++/* Macros to check for DECT exclusion options */ ++#define MT_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT_AVOID_US_DECT) != 0) ++#define MT_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT_AVOID_EURO_DECT) != 0) ++ ++ ++struct MT_FIFZone_t ++{ ++ SData_t min_; ++ SData_t max_; ++}; ++ ++#if MT_TUNER_CNT > 1 ++static MT2063_AvoidSpursData_t* TunerList[MT_TUNER_CNT]; ++static UData_t TunerCount = 0; ++#endif ++ ++UData_t MT2063_RegisterTuner(MT2063_AvoidSpursData_t* pAS_Info) ++{ ++#if MT_TUNER_CNT == 1 ++ pAS_Info->nAS_Algorithm = 1; ++ return MT_OK; ++#else ++ UData_t index; ++ ++ pAS_Info->nAS_Algorithm = 2; ++ ++ /* ++ ** Check to see if tuner is already registered ++ */ ++ for (index = 0; index < TunerCount; index++) ++ { ++ if (TunerList[index] == pAS_Info) ++ { ++ return MT_OK; /* Already here - no problem */ ++ } ++ } ++ ++ /* ++ ** Add tuner to list - if there is room. ++ */ ++ if (TunerCount < MT_TUNER_CNT) ++ { ++ TunerList[TunerCount] = pAS_Info; ++ TunerCount++; ++ return MT_OK; ++ } ++ else ++ return MT_TUNER_CNT_ERR; ++#endif ++} ++ ++ ++void MT2063_UnRegisterTuner(MT2063_AvoidSpursData_t* pAS_Info) ++{ ++#if MT_TUNER_CNT == 1 ++ // pAS_Info; ++ // pAS_Info->nAS_Algorithm = 1; ++ // return MT_OK; ++#else ++ ++ UData_t index; ++ ++ for (index = 0; index < TunerCount; index++) ++ { ++ if (TunerList[index] == pAS_Info) ++ { ++ TunerList[index] = TunerList[--TunerCount]; ++ } ++ } ++#endif ++} ++ ++ ++/* ++** Reset all exclusion zones. ++** Add zones to protect the PLL FracN regions near zero ++** ++** 195 I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT ++** frequencies into MT_ResetExclZones(). ++*/ ++void MT2063_ResetExclZones(MT2063_AvoidSpursData_t* pAS_Info) ++{ ++ UData_t center; ++#if MT_TUNER_CNT > 1 ++ UData_t index; ++ MT2063_AvoidSpursData_t* adj; ++#endif ++ ++ pAS_Info->nZones = 0; /* this clears the used list */ ++ pAS_Info->usedZones = MT_NULL; /* reset ptr */ ++ pAS_Info->freeZones = MT_NULL; /* reset ptr */ ++ ++ center = pAS_Info->f_ref * ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw/2 + pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in; ++ while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO1_FracN_Avoid) ++ { ++ /* Exclude LO1 FracN */ ++ MT2063_AddExclZone(pAS_Info, center-pAS_Info->f_LO1_FracN_Avoid, center-1); ++ MT2063_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO1_FracN_Avoid); ++ center += pAS_Info->f_ref; ++ } ++ ++ center = pAS_Info->f_ref * ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw/2 - pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out; ++ while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO2_FracN_Avoid) ++ { ++ /* Exclude LO2 FracN */ ++ MT2063_AddExclZone(pAS_Info, center-pAS_Info->f_LO2_FracN_Avoid, center-1); ++ MT2063_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO2_FracN_Avoid); ++ center += pAS_Info->f_ref; ++ } ++ ++ if( MT_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT) ) ++ { ++ /* Exclude LO1 values that conflict with DECT channels */ ++ MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */ ++ MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */ ++ MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */ ++ MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */ ++ MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */ ++ } ++ ++ if( MT_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT) ) ++ { ++ MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */ ++ MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */ ++ MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */ ++ MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16 */ ++ MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */ ++ MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */ ++ MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */ ++ MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */ ++ MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52 */ ++ MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */ ++ } ++ ++#if MT_TUNER_CNT > 1 ++ /* ++ ** Iterate through all adjacent tuners and exclude frequencies related to them ++ */ ++ for (index = 0; index < TunerCount; ++index) ++ { ++ adj = TunerList[index]; ++ if (pAS_Info == adj) /* skip over our own data, don't process it */ ++ continue; ++ ++ /* ++ ** Add 1st IF exclusion zone covering adjacent tuner's LO2 ++ ** at "adjfLO2 + f_out" +/- m_MinLOSpacing ++ */ ++ if (adj->f_LO2 != 0) ++ MT2063_AddExclZone(pAS_Info, ++ (adj->f_LO2 + pAS_Info->f_out) - pAS_Info->f_min_LO_Separation, ++ (adj->f_LO2 + pAS_Info->f_out) + pAS_Info->f_min_LO_Separation ); ++ ++ /* ++ ** Add 1st IF exclusion zone covering adjacent tuner's LO1 ++ ** at "adjfLO1 - f_in" +/- m_MinLOSpacing ++ */ ++ if (adj->f_LO1 != 0) ++ MT2063_AddExclZone(pAS_Info, ++ (adj->f_LO1 - pAS_Info->f_in) - pAS_Info->f_min_LO_Separation, ++ (adj->f_LO1 - pAS_Info->f_in) + pAS_Info->f_min_LO_Separation ); ++ } ++#endif ++} ++ ++ ++static struct MT2063_ExclZone_t* InsertNode(MT2063_AvoidSpursData_t* pAS_Info, ++ struct MT2063_ExclZone_t* pPrevNode) ++{ ++ struct MT2063_ExclZone_t* pNode; ++ /* Check for a node in the free list */ ++ if (pAS_Info->freeZones != MT_NULL) ++ { ++ /* Use one from the free list */ ++ pNode = pAS_Info->freeZones; ++ pAS_Info->freeZones = pNode->next_; ++ } ++ else ++ { ++ /* Grab a node from the array */ ++ pNode = &pAS_Info->MT_ExclZones[pAS_Info->nZones]; ++ } ++ ++ if (pPrevNode != MT_NULL) ++ { ++ pNode->next_ = pPrevNode->next_; ++ pPrevNode->next_ = pNode; ++ } ++ else /* insert at the beginning of the list */ ++ { ++ pNode->next_ = pAS_Info->usedZones; ++ pAS_Info->usedZones = pNode; ++ } ++ ++ pAS_Info->nZones++; ++ return pNode; ++} ++ ++ ++static struct MT2063_ExclZone_t* RemoveNode(MT2063_AvoidSpursData_t* pAS_Info, ++ struct MT2063_ExclZone_t* pPrevNode, ++ struct MT2063_ExclZone_t* pNodeToRemove) ++{ ++ struct MT2063_ExclZone_t* pNext = pNodeToRemove->next_; ++ ++ /* Make previous node point to the subsequent node */ ++ if (pPrevNode != MT_NULL) ++ pPrevNode->next_ = pNext; ++ ++ /* Add pNodeToRemove to the beginning of the freeZones */ ++ pNodeToRemove->next_ = pAS_Info->freeZones; ++ pAS_Info->freeZones = pNodeToRemove; ++ ++ /* Decrement node count */ ++ pAS_Info->nZones--; ++ ++ return pNext; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_AddExclZone ++** ++** Description: Add (and merge) an exclusion zone into the list. ++** If the range (f_min, f_max) is totally outside the ++** 1st IF BW, ignore the entry. ++** If the range (f_min, f_max) is negative, ignore the entry. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range ++** (f_min, f_max) < 0, ignore the entry. ++** 199 08-06-2008 JWS Ver 1.22: Indicate success of addition operation. ++** ++*****************************************************************************/ ++UData_t MT2063_AddExclZone(MT2063_AvoidSpursData_t* pAS_Info, ++ UData_t f_min, ++ UData_t f_max) ++{ ++ UData_t status = 1; /* Assume addition is possible */ ++ ++ /* Check to see if this overlaps the 1st IF filter */ ++ if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2))) ++ && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2))) ++ && (f_min < f_max)) ++ { ++ /* ++ ** 1 2 3 4 5 6 ++ ** ++ ** New entry: |---| |--| |--| |-| |---| |--| ++ ** or or or or or ++ ** Existing: |--| |--| |--| |---| |-| |--| ++ */ ++ struct MT2063_ExclZone_t* pNode = pAS_Info->usedZones; ++ struct MT2063_ExclZone_t* pPrev = MT_NULL; ++ struct MT2063_ExclZone_t* pNext = MT_NULL; ++ ++ /* Check for our place in the list */ ++ while ((pNode != MT_NULL) && (pNode->max_ < f_min)) ++ { ++ pPrev = pNode; ++ pNode = pNode->next_; ++ } ++ ++ if ((pNode != MT_NULL) && (pNode->min_ < f_max)) ++ { ++ /* Combine me with pNode */ ++ if (f_min < pNode->min_) ++ pNode->min_ = f_min; ++ if (f_max > pNode->max_) ++ pNode->max_ = f_max; ++ } ++ else ++ { ++ pNode = InsertNode(pAS_Info, pPrev); ++ pNode->min_ = f_min; ++ pNode->max_ = f_max; ++ } ++ ++ /* Look for merging possibilities */ ++ pNext = pNode->next_; ++ while ((pNext != MT_NULL) && (pNext->min_ < pNode->max_)) ++ { ++ if (pNext->max_ > pNode->max_) ++ pNode->max_ = pNext->max_; ++ pNext = RemoveNode(pAS_Info, pNode, pNext); /* Remove pNext, return ptr to pNext->next */ ++ } ++ } ++ else ++ status = 0; /* Did not add the zone - caller determines whether this is a problem */ ++ ++ return status; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ChooseFirstIF ++** ++** Description: Choose the best available 1st IF ++** If f_Desired is not excluded, choose that first. ++** Otherwise, return the value closest to f_Center that is ++** not excluded ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from ++** tuner DLL. ++** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) ++** Added logic to force f_Center within 1/2 f_Step. ++** ++*****************************************************************************/ ++UData_t MT2063_ChooseFirstIF(MT2063_AvoidSpursData_t* pAS_Info) ++{ ++ /* ++ ** Update "f_Desired" to be the nearest "combinational-multiple" of "f_LO1_Step". ++ ** The resulting number, F_LO1 must be a multiple of f_LO1_Step. And F_LO1 is the arithmetic sum ++ ** of f_in + f_Center. Neither f_in, nor f_Center must be a multiple of f_LO1_Step. ++ ** However, the sum must be. ++ */ ++ const UData_t f_Desired = pAS_Info->f_LO1_Step * ((pAS_Info->f_if1_Request + pAS_Info->f_in + pAS_Info->f_LO1_Step/2) / pAS_Info->f_LO1_Step) - pAS_Info->f_in; ++ const UData_t f_Step = (pAS_Info->f_LO1_Step > pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->f_LO2_Step; ++ UData_t f_Center; ++ ++ SData_t i; ++ SData_t j = 0; ++ UData_t bDesiredExcluded = 0; ++ UData_t bZeroExcluded = 0; ++ SData_t tmpMin, tmpMax; ++ SData_t bestDiff; ++ struct MT2063_ExclZone_t* pNode = pAS_Info->usedZones; ++ struct MT_FIFZone_t zones[MT2063_MAX_ZONES]; ++ ++ if (pAS_Info->nZones == 0) ++ return f_Desired; ++ ++ /* f_Center needs to be an integer multiple of f_Step away from f_Desired */ ++ if (pAS_Info->f_if1_Center > f_Desired) ++ f_Center = f_Desired + f_Step * ((pAS_Info->f_if1_Center - f_Desired + f_Step/2) / f_Step); ++ else ++ f_Center = f_Desired - f_Step * ((f_Desired - pAS_Info->f_if1_Center + f_Step/2) / f_Step); ++ ++// assert(abs((SData_t) f_Center - (SData_t) pAS_Info->f_if1_Center) <= (SData_t) (f_Step/2)); ++ ++ /* Take MT_ExclZones, center around f_Center and change the resolution to f_Step */ ++ while (pNode != MT_NULL) ++ { ++ /* floor function */ ++ tmpMin = floor((SData_t) (pNode->min_ - f_Center), (SData_t) f_Step); ++ ++ /* ceil function */ ++ tmpMax = ceil((SData_t) (pNode->max_ - f_Center), (SData_t) f_Step); ++ ++ if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired)) ++ bDesiredExcluded = 1; ++ ++ if ((tmpMin < 0) && (tmpMax > 0)) ++ bZeroExcluded = 1; ++ ++ /* See if this zone overlaps the previous */ ++ if ((j>0) && (tmpMin < zones[j-1].max_)) ++ zones[j-1].max_ = tmpMax; ++ else ++ { ++ /* Add new zone */ ++// assert(jnext_; ++ } ++ ++ /* ++ ** If the desired is okay, return with it ++ */ ++ if (bDesiredExcluded == 0) ++ return f_Desired; ++ ++ /* ++ ** If the desired is excluded and the center is okay, return with it ++ */ ++ if (bZeroExcluded == 0) ++ return f_Center; ++ ++ /* Find the value closest to 0 (f_Center) */ ++ bestDiff = zones[0].min_; ++ for (i=0; i= b) ? a : b; ++} ++ ++#if MT_TUNER_CNT > 1 ++static SData_t RoundAwayFromZero(SData_t n, SData_t d) ++{ ++ return (n<0) ? floor(n, d) : ceil(n, d); ++} ++ ++/**************************************************************************** ++** ++** Name: IsSpurInAdjTunerBand ++** ++** Description: Checks to see if a spur will be present within the IF's ++** bandwidth or near the zero IF. ++** (fIFOut +/- fIFBW/2, -fIFOut +/- fIFBW/2) ++** and ++** (0 +/- fZIFBW/2) ++** ++** ma mb me mf mc md ++** <--+-+-+-----------------+-+-+-----------------+-+-+--> ++** | ^ 0 ^ | ++** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ ++** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 ++** ++** Note that some equations are doubled to prevent round-off ++** problems when calculating fIFBW/2 ++** ++** The spur frequencies are computed as: ++** ++** fSpur = n * f1 - m * f2 - fOffset ++** ++** Parameters: f1 - The 1st local oscillator (LO) frequency ++** of the tuner whose output we are examining ++** f2 - The 1st local oscillator (LO) frequency ++** of the adjacent tuner ++** fOffset - The 2nd local oscillator of the tuner whose ++** output we are examining ++** fIFOut - Output IF center frequency ++** fIFBW - Output IF Bandwidth ++** nMaxH - max # of LO harmonics to search ++** fp - If spur, positive distance to spur-free band edge (returned) ++** fm - If spur, negative distance to spur-free band edge (returned) ++** ++** Returns: 1 if an LO spur would be present, otherwise 0. ++** ++** Dependencies: None. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 01-21-2005 JWS Original, adapted from MT_DoubleConversion. ++** 115 03-23-2007 DAD Fix declaration of spur due to truncation ++** errors. ++** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for ++** multi-tuners that have ++** (delta IF1) > (f_out-f_outbw/2). ++** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 ++** Type casts added to preserve correct sign. ++** 199 08-06-2008 JWS Ver 1.22: Added 0x1x1 spur frequency calculations. ++** ++****************************************************************************/ ++static UData_t IsSpurInAdjTunerBand(UData_t bIsMyOutput, ++ UData_t f1, ++ UData_t f2, ++ UData_t fOffset, ++ UData_t fIFOut, ++ UData_t fIFBW, ++ UData_t fZIFBW, ++ UData_t nMaxH, ++ UData_t *fp, ++ UData_t *fm) ++{ ++ UData_t bSpurFound = 0; ++ ++ const UData_t fHalf_IFBW = fIFBW / 2; ++ const UData_t fHalf_ZIFBW = fZIFBW / 2; ++ ++ /* Calculate a scale factor for all frequencies, so that our ++ calculations all stay within 31 bits */ ++ const UData_t f_Scale = ((f1 + (fOffset + fIFOut + fHalf_IFBW) / nMaxH) / (MAX_UDATA/2 / nMaxH)) + 1; ++ ++ /* ++ ** After this scaling, _f1, _f2, and _f3 are guaranteed to fit into ++ ** signed data types (smaller than MAX_UDATA/2) ++ */ ++ const SData_t _f1 = (SData_t) ( f1 / f_Scale); ++ const SData_t _f2 = (SData_t) ( f2 / f_Scale); ++ const SData_t _f3 = (SData_t) (fOffset / f_Scale); ++ ++ const SData_t c = (SData_t) (fIFOut - fHalf_IFBW) / (SData_t) f_Scale; ++ const SData_t d = (SData_t) ((fIFOut + fHalf_IFBW) / f_Scale); ++ const SData_t f = (SData_t) (fHalf_ZIFBW / f_Scale); ++ ++ SData_t ma, mb, mc, md, me, mf; ++ ++ SData_t fp_ = 0; ++ SData_t fm_ = 0; ++ SData_t n; ++ ++ ++ /* ++ ** If the other tuner does not have an LO frequency defined, ++ ** assume that we cannot interfere with it ++ */ ++ if (f2 == 0) ++ return 0; ++ ++ ++ /* Check out all multiples of f1 from -nMaxH to +nMaxH */ ++ for (n = -(SData_t)nMaxH; n <= (SData_t)nMaxH; ++n) ++ { ++ const SData_t nf1 = n*_f1; ++ md = floor(_f3 + d - nf1, _f2); ++ ++ /* If # f2 harmonics > nMaxH, then no spurs present */ ++ if (md <= -(SData_t) nMaxH ) ++ break; ++ ++ ma = floor(_f3 - d - nf1, _f2); ++ if ((ma == md) || (ma >= (SData_t) (nMaxH))) ++ continue; ++ ++ mc = floor(_f3 + c - nf1, _f2); ++ if (mc != md) ++ { ++ const SData_t m = md; ++ const SData_t fspur = (nf1 + m*_f2 - _f3); ++ const SData_t den = (bIsMyOutput ? n - 1 : n); ++ if (den == 0) ++ { ++ fp_ = (d - fspur)* f_Scale; ++ fm_ = (fspur - c)* f_Scale; ++ } ++ else ++ { ++ fp_ = (SData_t) RoundAwayFromZero((d - fspur)* f_Scale, den); ++ fm_ = (SData_t) RoundAwayFromZero((fspur - c)* f_Scale, den); ++ } ++ if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) ++ { ++ bSpurFound = 1; ++ break; ++ } ++ } ++ ++ /* Location of Zero-IF-spur to be checked */ ++ mf = floor(_f3 + f - nf1, _f2); ++ me = floor(_f3 - f - nf1, _f2); ++ if (me != mf) ++ { ++ const SData_t m = mf; ++ const SData_t fspur = (nf1 + m*_f2 - _f3); ++ const SData_t den = (bIsMyOutput ? n - 1 : n); ++ if (den == 0) ++ { ++ fp_ = (d - fspur)* f_Scale; ++ fm_ = (fspur - c)* f_Scale; ++ } ++ else ++ { ++ fp_ = (SData_t) RoundAwayFromZero((f - fspur)* f_Scale, den); ++ fm_ = (SData_t) RoundAwayFromZero((fspur + f)* f_Scale, den); ++ } ++ if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) ++ { ++ bSpurFound = 1; ++ break; ++ } ++ } ++ ++ mb = floor(_f3 - c - nf1, _f2); ++ if (ma != mb) ++ { ++ const SData_t m = mb; ++ const SData_t fspur = (nf1 + m*_f2 - _f3); ++ const SData_t den = (bIsMyOutput ? n - 1 : n); ++ if (den == 0) ++ { ++ fp_ = (d - fspur)* f_Scale; ++ fm_ = (fspur - c)* f_Scale; ++ } ++ else ++ { ++ fp_ = (SData_t) RoundAwayFromZero((-c - fspur)* f_Scale, den); ++ fm_ = (SData_t) RoundAwayFromZero((fspur +d)* f_Scale, den); ++ } ++ if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) ++ { ++ bSpurFound = 1; ++ break; ++ } ++ } ++ } ++ ++ /* ++ ** Verify that fm & fp are both positive ++ ** Add one to ensure next 1st IF choice is not right on the edge ++ */ ++ if (fp_ < 0) ++ { ++ *fp = -fm_ + 1; ++ *fm = -fp_ + 1; ++ } ++ else if (fp_ > 0) ++ { ++ *fp = fp_ + 1; ++ *fm = fm_ + 1; ++ } ++ else ++ { ++ *fp = 1; ++ *fm = abs(fm_) + 1; ++ } ++ ++ return bSpurFound; ++} ++#endif ++ ++/**************************************************************************** ++** ++** Name: IsSpurInBand ++** ++** Description: Checks to see if a spur will be present within the IF's ++** bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW) ++** ++** ma mb mc md ++** <--+-+-+-------------------+-------------------+-+-+--> ++** | ^ 0 ^ | ++** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ ++** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 ++** ++** Note that some equations are doubled to prevent round-off ++** problems when calculating fIFBW/2 ++** ++** Parameters: pAS_Info - Avoid Spurs information block ++** fm - If spur, amount f_IF1 has to move negative ++** fp - If spur, amount f_IF1 has to move positive ++** ++** Global: None ++** ++** Returns: 1 if an LO spur would be present, otherwise 0. ++** ++** Dependencies: None. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 11-28-2002 DAD Implemented algorithm from applied patent ++** ++****************************************************************************/ ++static UData_t IsSpurInBand(MT2063_AvoidSpursData_t* pAS_Info, ++ UData_t* fm, ++ UData_t* fp) ++{ ++ /* ++ ** Calculate LO frequency settings. ++ */ ++ UData_t n, n0; ++ const UData_t f_LO1 = pAS_Info->f_LO1; ++ const UData_t f_LO2 = pAS_Info->f_LO2; ++ const UData_t d = pAS_Info->f_out + pAS_Info->f_out_bw/2; ++ const UData_t c = d - pAS_Info->f_out_bw; ++ const UData_t f = pAS_Info->f_zif_bw/2; ++ const UData_t f_Scale = (f_LO1 / (MAX_UDATA/2 / pAS_Info->maxH1)) + 1; ++ SData_t f_nsLO1, f_nsLO2; ++ SData_t f_Spur; ++ UData_t ma, mb, mc, md, me, mf; ++ UData_t lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs; ++#if MT_TUNER_CNT > 1 ++ UData_t index; ++ ++ MT2063_AvoidSpursData_t *adj; ++#endif ++ *fm = 0; ++ ++ /* ++ ** For each edge (d, c & f), calculate a scale, based on the gcd ++ ** of f_LO1, f_LO2 and the edge value. Use the larger of this ++ ** gcd-based scale factor or f_Scale. ++ */ ++ lo_gcd = gcd(f_LO1, f_LO2); ++ gd_Scale = umax((UData_t) gcd(lo_gcd, d), f_Scale); ++ hgds = gd_Scale/2; ++ gc_Scale = umax((UData_t) gcd(lo_gcd, c), f_Scale); ++ hgcs = gc_Scale/2; ++ gf_Scale = umax((UData_t) gcd(lo_gcd, f), f_Scale); ++ hgfs = gf_Scale/2; ++ ++ n0 = uceil(f_LO2 - d, f_LO1 - f_LO2); ++ ++ /* Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic */ ++ for (n=n0; n<=pAS_Info->maxH1; ++n) ++ { ++ md = (n*((f_LO1+hgds)/gd_Scale) - ((d+hgds)/gd_Scale)) / ((f_LO2+hgds)/gd_Scale); ++ ++ /* If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present */ ++ if (md >= pAS_Info->maxH1) ++ break; ++ ++ ma = (n*((f_LO1+hgds)/gd_Scale) + ((d+hgds)/gd_Scale)) / ((f_LO2+hgds)/gd_Scale); ++ ++ /* If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic */ ++ if (md == ma) ++ continue; ++ ++ mc = (n*((f_LO1+hgcs)/gc_Scale) - ((c+hgcs)/gc_Scale)) / ((f_LO2+hgcs)/gc_Scale); ++ if (mc != md) ++ { ++ f_nsLO1 = (SData_t) (n*(f_LO1/gc_Scale)); ++ f_nsLO2 = (SData_t) (mc*(f_LO2/gc_Scale)); ++ f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - mc*(f_LO2 % gc_Scale); ++ ++ *fp = ((f_Spur - (SData_t) c) / (mc - n)) + 1; ++ *fm = (((SData_t) d - f_Spur) / (mc - n)) + 1; ++ return 1; ++ } ++ ++ /* Location of Zero-IF-spur to be checked */ ++ me = (n*((f_LO1+hgfs)/gf_Scale) + ((f+hgfs)/gf_Scale)) / ((f_LO2+hgfs)/gf_Scale); ++ mf = (n*((f_LO1+hgfs)/gf_Scale) - ((f+hgfs)/gf_Scale)) / ((f_LO2+hgfs)/gf_Scale); ++ if (me != mf) ++ { ++ f_nsLO1 = n*(f_LO1/gf_Scale); ++ f_nsLO2 = me*(f_LO2/gf_Scale); ++ f_Spur = (gf_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gf_Scale) - me*(f_LO2 % gf_Scale); ++ ++ *fp = ((f_Spur + (SData_t) f) / (me - n)) + 1; ++ *fm = (((SData_t) f - f_Spur) / (me - n)) + 1; ++ return 1; ++ } ++ ++ mb = (n*((f_LO1+hgcs)/gc_Scale) + ((c+hgcs)/gc_Scale)) / ((f_LO2+hgcs)/gc_Scale); ++ if (ma != mb) ++ { ++ f_nsLO1 = n*(f_LO1/gc_Scale); ++ f_nsLO2 = ma*(f_LO2/gc_Scale); ++ f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - ma*(f_LO2 % gc_Scale); ++ ++ *fp = (((SData_t) d + f_Spur) / (ma - n)) + 1; ++ *fm = (-(f_Spur + (SData_t) c) / (ma - n)) + 1; ++ return 1; ++ } ++ } ++ ++#if MT_TUNER_CNT > 1 ++ /* If no spur found, see if there are more tuners on the same board */ ++ for (index = 0; index < TunerCount; ++index) ++ { ++ adj = TunerList[index]; ++ if (pAS_Info == adj) /* skip over our own data, don't process it */ ++ continue; ++ ++ /* Look for LO-related spurs from the adjacent tuner generated into my IF output */ ++ if (IsSpurInAdjTunerBand(1, /* check my IF output */ ++ pAS_Info->f_LO1, /* my fLO1 */ ++ adj->f_LO1, /* the other tuner's fLO1 */ ++ pAS_Info->f_LO2, /* my fLO2 */ ++ pAS_Info->f_out, /* my fOut */ ++ pAS_Info->f_out_bw, /* my output IF bandwidth */ ++ pAS_Info->f_zif_bw, /* my Zero-IF bandwidth */ ++ pAS_Info->maxH2, ++ fp, /* minimum amount to move LO's positive */ ++ fm)) /* miminum amount to move LO's negative */ ++ return 1; ++ /* Look for LO-related spurs from my tuner generated into the adjacent tuner's IF output */ ++ if (IsSpurInAdjTunerBand(0, /* check his IF output */ ++ pAS_Info->f_LO1, /* my fLO1 */ ++ adj->f_LO1, /* the other tuner's fLO1 */ ++ adj->f_LO2, /* the other tuner's fLO2 */ ++ adj->f_out, /* the other tuner's fOut */ ++ adj->f_out_bw, /* the other tuner's output IF bandwidth */ ++ pAS_Info->f_zif_bw, /* the other tuner's Zero-IF bandwidth */ ++ adj->maxH2, ++ fp, /* minimum amount to move LO's positive */ ++ fm)) /* miminum amount to move LO's negative */ ++ return 1; ++ } ++#endif ++ /* No spurs found */ ++ return 0; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_AvoidSpurs ++** ++** Description: Main entry point to avoid spurs. ++** Checks for existing spurs in present LO1, LO2 freqs ++** and if present, chooses spur-free LO1, LO2 combination ++** that tunes the same input/output frequencies. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. ++** ++*****************************************************************************/ ++UData_t MT2063_AvoidSpurs(Handle_t h, ++ MT2063_AvoidSpursData_t* pAS_Info) ++{ ++ UData_t status = MT_OK; ++ UData_t fm, fp; /* restricted range on LO's */ ++ pAS_Info->bSpurAvoided = 0; ++ pAS_Info->nSpursFound = 0; ++ //h; /* warning expected: code has no effect */ ++ ++ if (pAS_Info->maxH1 == 0) ++ return MT_OK; ++ ++ /* ++ ** Avoid LO Generated Spurs ++ ** ++ ** Make sure that have no LO-related spurs within the IF output ++ ** bandwidth. ++ ** ++ ** If there is an LO spur in this band, start at the current IF1 frequency ++ ** and work out until we find a spur-free frequency or run up against the ++ ** 1st IF SAW band edge. Use temporary copies of fLO1 and fLO2 so that they ++ ** will be unchanged if a spur-free setting is not found. ++ */ ++ pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp); ++ if (pAS_Info->bSpurPresent) ++ { ++ UData_t zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in; /* current attempt at a 1st IF */ ++ UData_t zfLO1 = pAS_Info->f_LO1; /* current attempt at an LO1 freq */ ++ UData_t zfLO2 = pAS_Info->f_LO2; /* current attempt at an LO2 freq */ ++ UData_t delta_IF1; ++ UData_t new_IF1; ++ UData_t added; /* success of Excl Zone addition */ ++ ++ /* ++ ** Spur was found, attempt to find a spur-free 1st IF ++ */ ++ do ++ { ++ pAS_Info->nSpursFound++; ++ ++ /* Raise f_IF1_upper, if needed */ ++ added = MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp); ++ ++ /* ++ ** If Exclusion Zone could NOT be added, then we'll just keep picking ++ ** the same bad point, so exit this loop and report that there is a ++ ** spur present in the output ++ */ ++ if (!added) ++ break; ++ ++ /* Choose next IF1 that is closest to f_IF1_CENTER */ ++ new_IF1 = MT2063_ChooseFirstIF(pAS_Info); ++ ++ if (new_IF1 > zfIF1) ++ { ++ pAS_Info->f_LO1 += (new_IF1 - zfIF1); ++ pAS_Info->f_LO2 += (new_IF1 - zfIF1); ++ } ++ else ++ { ++ pAS_Info->f_LO1 -= (zfIF1 - new_IF1); ++ pAS_Info->f_LO2 -= (zfIF1 - new_IF1); ++ } ++ zfIF1 = new_IF1; ++ ++ if (zfIF1 > pAS_Info->f_if1_Center) ++ delta_IF1 = zfIF1 - pAS_Info->f_if1_Center; ++ else ++ delta_IF1 = pAS_Info->f_if1_Center - zfIF1; ++ } ++ /* ++ ** Continue while the new 1st IF is still within the 1st IF bandwidth ++ ** and there is a spur in the band (again) ++ */ ++ while ((2*delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && ++ (pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp))); ++ ++ /* ++ ** Use the LO-spur free values found. If the search went all the way to ++ ** the 1st IF band edge and always found spurs, just leave the original ++ ** choice. It's as "good" as any other. ++ */ ++ if (pAS_Info->bSpurPresent == 1) ++ { ++ status |= MT_SPUR_PRESENT; ++ pAS_Info->f_LO1 = zfLO1; ++ pAS_Info->f_LO2 = zfLO2; ++ } ++ else ++ pAS_Info->bSpurAvoided = 1; ++ } ++ ++ status |= ((pAS_Info->nSpursFound << MT_SPUR_SHIFT) & MT_SPUR_CNT_MASK); ++ ++ return (status); ++} ++ ++ ++UData_t MT2063_AvoidSpursVersion(void) ++{ ++ return (MT_SPURAVOID_VERSION); ++} ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_mt2063.h b/drivers/drivers/media/dvb/dvb-usb/tuner_mt2063.h +--- a/drivers/media/dvb/dvb-usb/tuner_mt2063.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_mt2063.h 2016-04-02 19:17:52.140066046 -0300 +@@ -0,0 +1,2206 @@ ++#ifndef __TUNER_MT2063_H ++#define __TUNER_MT2063_H ++ ++/** ++ ++@file ++ ++@brief MT2063 tuner module declaration ++ ++One can manipulate MT2063 tuner through MT2063 module. ++MT2063 module is derived from tunerd module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_mt2063.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ MT2063_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long IfFreqHz; ++ ++ ++ ... ++ ++ ++ ++ // Build MT2063 tuner module. ++ BuildMt2063Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0 // I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2063 tuner extra module. ++ pTunerExtra = &(pTuner->pExtra.Mt2063); ++ ++ // Open MT2063 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set MT2063 IF frequency. ++ pTunerExtra->SetIfFreqHz(pTuner, IF_FREQ_36125000HZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get MT2063 IF frequency. ++ pTunerExtra->SetIfFreqHz(pTuner, &IfFreqHz); ++ ++ ++ ++ ++ ++ // Close MT2063 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Microtune source code - mt_errordef.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_errordef.h ++** ++** Copyright 2004-2007 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt_errordef.h ++** ++** Description: Definition of bits in status/error word used by various ++** MicroTuner control programs. ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_errordef.h,v 1.2 2008/11/05 13:46:19 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_errordef.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 09-09-2004 JWS Original ++** 088 01-26-2005 DAD Added MT_TUNER_INIT_ERR. ++** N/A 12-09-2005 DAD Added MT_TUNER_TIMEOUT (info). ++** N/A 10-17-2006 JWS Updated copyright notice. ++** N/A L 02-25-2008 RSK Correcting Comment Block to match constants. ++** ++*****************************************************************************/ ++ ++/* ++** Note to users: DO NOT EDIT THIS FILE ++** ++** If you wish to rename any of the "user defined" bits, ++** it should be done in the user file that includes this ++** source file (e.g. mt_userdef.h) ++** ++*/ ++ ++ ++ ++/* ++** 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 ++** 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ++** M U <- Info Codes --> <# Spurs> < User> <----- Err Codes -----> ++** ++** 31 = MT_ERROR - Master Error Flag. If set, check Err Codes for reason. ++** 30 = MT_USER_ERROR - User-declared error flag. ++** 29 = Unused ++** 28 = Unused ++** ++** 27 = MT_DNC_RANGE ++** 26 = MT_UPC_RANGE ++** 25 = MT_FOUT_RANGE ++** 24 = MT_FIN_OUT_OF_RANGE ++** ++** 23 = MT_SPUR_PRESENT - Unavoidable spur in output ++** 22 = MT_TUNER_TIMEOUT ++** 21 = Unused ++** 20 = MT_SPUR_CNT_MASK (MSB) - Count of avoided spurs ++** ++** 19 = MT_SPUR_CNT_MASK ++** 18 = MT_SPUR_CNT_MASK ++** 17 = MT_SPUR_CNT_MASK ++** 16 = MT_SPUR_CNT_MASK (LSB) ++** ++** 15 = MT_USER_DEFINED4 - User-definable bit (see MT_Userdef.h) ++** 14 = MT_USER_DEFINED3 - User-definable bit (see MT_Userdef.h) ++** 13 = MT_USER_DEFINED2 - User-definable bit (see MT_Userdef.h) ++** 12 = MT_USER_DEFINED1 - User-definable bit (see MT_Userdef.h) ++** ++** 11 = Unused ++** 10 = Unused ++** 9 = MT_TUNER_INIT_ERR - Tuner initialization error ++** 8 = MT_TUNER_ID_ERR - Tuner Part Code / Rev Code mismatches expected value ++** ++** 7 = MT_TUNER_CNT_ERR - Attempt to open more than MT_TUNER_CNT tuners ++** 6 = MT_ARG_NULL - Null pointer passed as argument ++** 5 = MT_ARG_RANGE - Argument value out of range ++** 4 = MT_INV_HANDLE - Tuner handle is invalid ++** ++** 3 = MT_COMM_ERR - Serial bus communications error ++** 2 = MT_DNC_UNLOCK - Downconverter PLL is unlocked ++** 1 = MT_UPC_UNLOCK - Upconverter PLL is unlocked ++** 0 = MT_UNKNOWN - Unknown error ++*/ ++#define MT_ERROR (1 << 31) ++#define MT_USER_ERROR (1 << 30) ++ ++/* Macro to be used to check for errors */ ++#define MT_IS_ERROR(s) (((s) >> 30) != 0) ++#define MT_NO_ERROR(s) (((s) >> 30) == 0) ++ ++ ++#define MT_OK (0x00000000) ++ ++/* Unknown error */ ++#define MT_UNKNOWN (0x80000001) ++ ++/* Error: Upconverter PLL is not locked */ ++#define MT_UPC_UNLOCK (0x80000002) ++ ++/* Error: Downconverter PLL is not locked */ ++#define MT_DNC_UNLOCK (0x80000004) ++ ++/* Error: Two-wire serial bus communications error */ ++#define MT_COMM_ERR (0x80000008) ++ ++/* Error: Tuner handle passed to function was invalid */ ++#define MT_INV_HANDLE (0x80000010) ++ ++/* Error: Function argument is invalid (out of range) */ ++#define MT_ARG_RANGE (0x80000020) ++ ++/* Error: Function argument (ptr to return value) was NULL */ ++#define MT_ARG_NULL (0x80000040) ++ ++/* Error: Attempt to open more than MT_TUNER_CNT tuners */ ++#define MT_TUNER_CNT_ERR (0x80000080) ++ ++/* Error: Tuner Part Code / Rev Code mismatches expected value */ ++#define MT_TUNER_ID_ERR (0x80000100) ++ ++/* Error: Tuner Initialization failure */ ++#define MT_TUNER_INIT_ERR (0x80000200) ++ ++/* User-definable fields (see mt_userdef.h) */ ++#define MT_USER_DEFINED1 (0x00001000) ++#define MT_USER_DEFINED2 (0x00002000) ++#define MT_USER_DEFINED3 (0x00004000) ++#define MT_USER_DEFINED4 (0x00008000) ++#define MT_USER_MASK (0x4000f000) ++#define MT_USER_SHIFT (12) ++ ++/* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */ ++#define MT_SPUR_CNT_MASK (0x001f0000) ++#define MT_SPUR_SHIFT (16) ++ ++/* Info: Tuner timeout waiting for condition */ ++#define MT_TUNER_TIMEOUT (0x00400000) ++ ++/* Info: Unavoidable LO-related spur may be present in the output */ ++#define MT_SPUR_PRESENT (0x00800000) ++ ++/* Info: Tuner input frequency is out of range */ ++#define MT_FIN_RANGE (0x01000000) ++ ++/* Info: Tuner output frequency is out of range */ ++#define MT_FOUT_RANGE (0x02000000) ++ ++/* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */ ++#define MT_UPC_RANGE (0x04000000) ++ ++/* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */ ++#define MT_DNC_RANGE (0x08000000) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_userdef.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.h ++** ++** Copyright 2006-2008 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable and the terms of the end-user software ++** license agreement (EULA). ++** ++** Protected by US Patent 7,035,614 and additional patents pending or filed. ++** ++** BY INSTALLING, COPYING, OR USING THE MICROTUNE SOFTWARE, YOU AGREE TO BE ++** BOUND BY ALL OF THE TERMS AND CONDITIONS OF THE MICROTUNE, INC. END-USER ++** SOFTWARE LICENSE AGREEMENT (EULA), INCLUDING BUT NOT LIMITED TO, THE ++** CONFIDENTIALITY OBLIGATIONS DESCRIBED THEREIN. IF YOU DO NOT AGREE, DO NOT ++** INSTALL, COPY, OR USE THE MICROTUNE SOFTWARE AND IMMEDIATELY RETURN OR ++** DESTROY ANY COPIES OF MICROTUNE SOFTWARE OR CONFIDENTIAL INFORMATION THAT ++** YOU HAVE IN YOUR POSSESSION. ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.h ++** ++** Description: User-defined data types needed by MicroTuner source code. ++** ++** Customers must provide the code for these functions ++** in the file "mt_userdef.c". ++** ++** Customers must verify that the typedef's in the ++** "Data Types" section are correct for their platform. ++** ++** Functions ++** Requiring ++** Implementation: MT_WriteSub ++** MT_ReadSub ++** MT_Sleep ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_userdef.h,v 1.2 2008/11/05 13:46:20 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_userdef.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** 082 12-06-2004 JWS Multi-tuner support - requires MTxxxx_CNT ++** declarations ++** N/A 04-13-2007 JWS Added Signed 8-bit type - S8Data ++** 200 08-07-2008 JWS Included definition of DECT avoid constants. ++** ++*****************************************************************************/ ++#if !defined( __MT_USERDEF_H ) ++#define __MT_USERDEF_H ++ ++//#include "mt_errordef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++#if !defined( __MT_DATA_DEF_H ) ++#define __MT_DATA_DEF_H ++/* ++** Data Types ++*/ ++typedef unsigned char U8Data; /* type corresponds to 8 bits */ ++typedef signed char S8Data; /* type corresponds to 8 bits */ ++typedef unsigned int UData_t; /* type must be at least 32 bits */ ++typedef int SData_t; /* type must be at least 32 bits */ ++typedef void * Handle_t; /* memory pointer type */ ++typedef double FData_t; /* floating point data type */ ++#endif ++#define MAX_UDATA (4294967295U) /* max value storable in UData_t */ ++ ++/* ++** Define an MTxxxx_CNT macro for each type of tuner that will be built ++** into your application (e.g., MT2121, MT2060). MT_TUNER_CNT ++** must be set to the SUM of all of the MTxxxx_CNT macros. ++** ++** #define MT2050_CNT (1) ++** #define MT2060_CNT (1) ++** #define MT2111_CNT (1) ++** #define MT2121_CNT (3) ++*/ ++ ++ ++#if !defined( MT_TUNER_CNT ) ++#define MT_TUNER_CNT (1) /* total num of MicroTuner tuners */ ++#endif ++ ++#ifndef _MT_DECT_Avoid_Type_DEFINE_ ++#define _MT_DECT_Avoid_Type_DEFINE_ ++// ++// DECT Frequency Avoidance: ++// These constants are used to avoid interference from DECT frequencies. ++// ++typedef enum ++{ ++ MT_NO_DECT_AVOIDANCE = 0, /* Do not create DECT exclusion zones. */ ++ MT_AVOID_US_DECT = 0x00000001, /* Avoid US DECT frequencies. */ ++ MT_AVOID_EURO_DECT = 0x00000002, /* Avoid European DECT frequencies. */ ++ MT_AVOID_BOTH /* Avoid both regions. Not typically used. */ ++} MT_DECT_Avoid_Type; ++#endif ++/* ++** Optional user-defined Error/Info Codes (examples below) ++** ++** This is the area where you can define user-specific error/info return ++** codes to be returned by any of the functions you are responsible for ++** writing such as MT_WriteSub() and MT_ReadSub. There are four bits ++** available in the status field for your use. When set, these ++** bits will be returned in the status word returned by any tuner driver ++** call. If you OR in the MT_ERROR bit as well, the tuner driver code ++** will treat the code as an error. ++** ++** The following are a few examples of errors you can provide. ++** ++** Example 1: ++** You might check to see the hUserData handle is correct and issue ++** MY_USERDATA_INVALID which would be defined like this: ++** ++** #define MY_USERDATA_INVALID (MT_USER_ERROR | MT_USER_DEFINED1) ++** ++** ++** Example 2: ++** You might be able to provide more descriptive two-wire bus errors: ++** ++** #define NO_ACK (MT_USER_ERROR | MT_USER_DEFINED1) ++** #define NO_NACK (MT_USER_ERROR | MT_USER_DEFINED2) ++** #define BUS_BUSY (MT_USER_ERROR | MT_USER_DEFINED3) ++** ++** ++** Example 3: ++** You can also provide information (non-error) feedback: ++** ++** #define MY_INFO_1 (MT_USER_DEFINED1) ++** ++** ++** Example 4: ++** You can combine the fields together to make a multi-bit field. ++** This one can provide the tuner number based off of the addr ++** passed to MT_WriteSub or MT_ReadSub. It assumes that ++** MT_USER_DEFINED4 through MT_USER_DEFINED1 are contiguously. If ++** TUNER_NUM were OR'ed into the status word on an error, you could ++** use this to identify which tuner had the problem (and whether it ++** was during a read or write operation). ++** ++** #define TUNER_NUM ((addr & 0x07) >> 1) << MT_USER_SHIFT ++** ++*/ ++ ++/***************************************************************************** ++** ++** Name: MT_WriteSub ++** ++** Description: Write values to device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to write data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2063_WriteSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt); ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ReadSub ++** ++** Description: Read values from device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to read data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2063_ReadSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt); ++ ++ ++/***************************************************************************** ++** ++** Name: MT_Sleep ++** ++** Description: Delay execution for "nMinDelayTime" milliseconds ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** nMinDelayTime - Delay time in milliseconds ++** ++** Returns: None. ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code that ++** blocks execution for the specified period of time. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++void MT2063_Sleep(Handle_t hUserData, ++ UData_t nMinDelayTime); ++ ++ ++#if defined(MT2060_CNT) ++#if MT2060_CNT > 0 ++/***************************************************************************** ++** ++** Name: MT_TunerGain (for MT2060 only) ++** ++** Description: Measure the relative tuner gain using the demodulator ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** pMeas - Tuner gain (1/100 of dB scale). ++** ie. 1234 = 12.34 (dB) ++** ++** Returns: status: ++** MT_OK - No errors ++** user-defined errors could be set ++** ++** Notes: This is a callback function that is called from the ++** the 1st IF location routine. You MUST provide ++** code that measures the relative tuner gain in a dB ++** (not linear) scale. The return value is an integer ++** value scaled to 1/100 of a dB. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 06-16-2004 DAD Original ++** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name ++** better describes what this function does. ++** ++*****************************************************************************/ ++UData_t MT_TunerGain(Handle_t hUserData, ++ SData_t* pMeas); ++#endif ++#endif ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt2063.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt2063.h ++** ++** Copyright 2007 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt2063.h ++** ++** Description: Microtune MT2063 B0/B1 Tuner software interface ++** Supports tuners with Part/Rev codes: 0x9B, 0x9C. ++** ++** Functions ++** Implemented: UData_t MT2063_Open ++** UData_t MT2063_Close ++** UData_t MT2063_GetGPIO ++** UData_t MT2063_GetLocked ++** UData_t MT2063_GetParam ++** UData_t MT2063_GetPowerMaskBits ++** UData_t MT2063_GetReg ++** UData_t MT2063_GetTemp ++** UData_t MT2063_GetUserData ++** UData_t MT2063_ReInit ++** UData_t MT2063_SetGPIO ++** UData_t MT2063_SetParam ++** UData_t MT2063_SetPowerMaskBits ++** UData_t MT2063_ClearPowerMaskBits ++** UData_t MT2063_SetReg ++** UData_t MT2063_Tune ++** ++** References: AN-xxxxx: MT2063 Programming Procedures Application Note ++** MicroTune, Inc. ++** AN-00010: MicroTuner Serial Interface Application Note ++** MicroTune, Inc. ++** ++** Enumerations ++** Defined: MT2063_Ext_SRO ++** MT2063_Param ++** MT2063_Mask_Bits ++** MT2063_GPIO_Attr; ++** MT2063_Temperature ++** ++** Exports: None ++** ++** Dependencies: MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Read byte(s) of data from the two-wire bus. ++** ++** MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Write byte(s) of data to the two-wire bus. ++** ++** MT_Sleep(hUserData, nMinDelayTime); ++** - Delay execution for nMinDelayTime milliseconds ++** ++** CVS ID: $Id: mt2063.h,v 1.5 2009/04/29 09:58:14 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt2063.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** N/A 08-01-2007 PINZ Changed Analog & DVB-T settings and added ++** SAW-less receiver mode. ++** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive ++** modulation ++** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE) ++** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have ++** the same settings as with MT Launcher ++** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI ++** Add SetParam DNC_OUTPUT_ENABLE ++** Removed VGAGC from receiver mode, ++** default now 1 ++** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode ++** Add SetParam AMPGC, removed from rcvr-mode ++** Corrected names of GCU values ++** Actualized Receiver-Mode values ++** N/A 04-18-2008 PINZ Ver 1.09: Add SetParam LNA_TGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 06-06-2008 PINZ Ver 1.10: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 175 I 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 07-10-2008 PINZ Ver 1.19: Documentation Updates, Add a GetParam ++** for each SetParam (LNA_RIN, TGTs) ++** 01-07-2009 PINZ Ver 1.27: Changed value of MT2063_ALL_SD in .h ++** 02-16-2009 PINZ Ver 1.29: Several fixes to improve compiler behavior ++** N/A I 03-19-2009 PINZ Ver 1.32: Add GetParam VERSION (of API) ++** Add GetParam IC_REV ++*****************************************************************************/ ++#if !defined( __MT2063_H ) ++#define __MT2063_H ++ ++//#include "mt_userdef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++ ++/* ++** Chip revision ++** ++*/ ++typedef enum ++{ ++ MT2063_XX = 0, ++ MT2063_B0 = 206310, ++ MT2063_B1 = 206311, ++ MT2063_B3 = 206313 ++} MT2063_REVCODE; ++ ++ ++/* ++** Values returned by the MT2063's on-chip temperature sensor ++** to be read/written. ++*/ ++typedef enum ++{ ++ MT2063_T_0C = 0, /* Temperature approx 0C */ ++ MT2063_T_10C, /* Temperature approx 10C */ ++ MT2063_T_20C, /* Temperature approx 20C */ ++ MT2063_T_30C, /* Temperature approx 30C */ ++ MT2063_T_40C, /* Temperature approx 40C */ ++ MT2063_T_50C, /* Temperature approx 50C */ ++ MT2063_T_60C, /* Temperature approx 60C */ ++ MT2063_T_70C, /* Temperature approx 70C */ ++ MT2063_T_80C, /* Temperature approx 80C */ ++ MT2063_T_90C, /* Temperature approx 90C */ ++ MT2063_T_100C, /* Temperature approx 100C */ ++ MT2063_T_110C, /* Temperature approx 110C */ ++ MT2063_T_120C, /* Temperature approx 120C */ ++ MT2063_T_130C, /* Temperature approx 130C */ ++ MT2063_T_140C, /* Temperature approx 140C */ ++ MT2063_T_150C /* Temperature approx 150C */ ++} MT2063_Temperature; ++ ++ ++/* ++** Parameters for selecting GPIO bits ++*/ ++typedef enum ++{ ++ MT2063_GPIO_IN, ++ MT2063_GPIO_DIR, ++ MT2063_GPIO_OUT ++} MT2063_GPIO_Attr; ++ ++typedef enum ++{ ++ MT2063_GPIO0, ++ MT2063_GPIO1, ++ MT2063_GPIO2 ++} MT2063_GPIO_ID; ++ ++ ++/* ++** Parameter for function MT2063_SetExtSRO that specifies the external ++** SRO drive frequency. ++** ++** MT2063_EXT_SRO_OFF is the power-up default value. ++*/ ++typedef enum ++{ ++ MT2063_EXT_SRO_OFF, /* External SRO drive off */ ++ MT2063_EXT_SRO_BY_4, /* External SRO drive divide by 4 */ ++ MT2063_EXT_SRO_BY_2, /* External SRO drive divide by 2 */ ++ MT2063_EXT_SRO_BY_1 /* External SRO drive divide by 1 */ ++} MT2063_Ext_SRO; ++ ++ ++/* ++** Parameter for function MT2063_SetPowerMask that specifies the power down ++** of various sections of the MT2063. ++*/ ++typedef enum ++{ ++ MT2063_REG_SD = 0x0040, /* Shutdown regulator */ ++ MT2063_SRO_SD = 0x0020, /* Shutdown SRO */ ++ MT2063_AFC_SD = 0x0010, /* Shutdown AFC A/D */ ++ MT2063_PD_SD = 0x0002, /* Enable power detector shutdown */ ++ MT2063_PDADC_SD = 0x0001, /* Enable power detector A/D shutdown */ ++ MT2063_VCO_SD = 0x8000, /* Enable VCO shutdown */ ++ MT2063_LTX_SD = 0x4000, /* Enable LTX shutdown */ ++ MT2063_LT1_SD = 0x2000, /* Enable LT1 shutdown */ ++ MT2063_LNA_SD = 0x1000, /* Enable LNA shutdown */ ++ MT2063_UPC_SD = 0x0800, /* Enable upconverter shutdown */ ++ MT2063_DNC_SD = 0x0400, /* Enable downconverter shutdown */ ++ MT2063_VGA_SD = 0x0200, /* Enable VGA shutdown */ ++ MT2063_AMP_SD = 0x0100, /* Enable AMP shutdown */ ++ MT2063_ALL_SD = 0xFF13, /* All shutdown bits for this tuner */ ++ MT2063_NONE_SD = 0x0000 /* No shutdown bits */ ++} MT2063_Mask_Bits; ++ ++ ++/* ++** Parameter for function MT2063_GetParam & MT2063_SetParam that ++** specifies the tuning algorithm parameter to be read/written. ++*/ ++typedef enum ++{ ++ /* version of the API, e.g. 10302 = 1.32 */ ++ MT2063_VERSION, ++ ++ /* tuner address set by MT2063_Open() */ ++ MT2063_IC_ADDR, ++ ++ /* tuner revision code (see enum MT2063_REVCODE for values) */ ++ MT2063_IC_REV, ++ ++ /* max number of MT2063 tuners set by MT_TUNER_CNT in mt_userdef.h */ ++ MT2063_MAX_OPEN, ++ ++ /* current number of open MT2063 tuners set by MT2063_Open() */ ++ MT2063_NUM_OPEN, ++ ++ /* crystal frequency (default: 16000000 Hz) */ ++ MT2063_SRO_FREQ, ++ ++ /* min tuning step size (default: 50000 Hz) */ ++ MT2063_STEPSIZE, ++ ++ /* input center frequency set by MT2063_Tune() */ ++ MT2063_INPUT_FREQ, ++ ++ /* LO1 Frequency set by MT2063_Tune() */ ++ MT2063_LO1_FREQ, ++ ++ /* LO1 minimum step size (default: 250000 Hz) */ ++ MT2063_LO1_STEPSIZE, ++ ++ /* LO1 FracN keep-out region (default: 999999 Hz) */ ++ MT2063_LO1_FRACN_AVOID, ++ ++ /* Current 1st IF in use set by MT2063_Tune() */ ++ MT2063_IF1_ACTUAL, ++ ++ /* Requested 1st IF set by MT2063_Tune() */ ++ MT2063_IF1_REQUEST, ++ ++ /* Center of 1st IF SAW filter (default: 1218000000 Hz) */ ++ MT2063_IF1_CENTER, ++ ++ /* Bandwidth of 1st IF SAW filter (default: 20000000 Hz) */ ++ MT2063_IF1_BW, ++ ++ /* zero-IF bandwidth (default: 2000000 Hz) */ ++ MT2063_ZIF_BW, ++ ++ /* LO2 Frequency set by MT2063_Tune() */ ++ MT2063_LO2_FREQ, ++ ++ /* LO2 minimum step size (default: 50000 Hz) */ ++ MT2063_LO2_STEPSIZE, ++ ++ /* LO2 FracN keep-out region (default: 374999 Hz) */ ++ MT2063_LO2_FRACN_AVOID, ++ ++ /* output center frequency set by MT2063_Tune() */ ++ MT2063_OUTPUT_FREQ, ++ ++ /* output bandwidth set by MT2063_Tune() */ ++ MT2063_OUTPUT_BW, ++ ++ /* min inter-tuner LO separation (default: 1000000 Hz) */ ++ MT2063_LO_SEPARATION, ++ ++ /* ID of avoid-spurs algorithm in use compile-time constant */ ++ MT2063_AS_ALG, ++ ++ /* max # of intra-tuner harmonics (default: 15) */ ++ MT2063_MAX_HARM1, ++ ++ /* max # of inter-tuner harmonics (default: 7) */ ++ MT2063_MAX_HARM2, ++ ++ /* # of 1st IF exclusion zones used set by MT2063_Tune() */ ++ MT2063_EXCL_ZONES, ++ ++ /* # of spurs found/avoided set by MT2063_Tune() */ ++ MT2063_NUM_SPURS, ++ ++ /* >0 spurs avoided set by MT2063_Tune() */ ++ MT2063_SPUR_AVOIDED, ++ ++ /* >0 spurs in output (mathematically) set by MT2063_Tune() */ ++ MT2063_SPUR_PRESENT, ++ ++ /* Receiver Mode for some parameters. 1 is DVB-T */ ++ MT2063_RCVR_MODE, ++ ++ /* directly set LNA attenuation, parameter is value to set */ ++ MT2063_ACLNA, ++ ++ /* maximum LNA attenuation, parameter is value to set */ ++ MT2063_ACLNA_MAX, ++ ++ /* directly set ATN attenuation. Paremeter is value to set. */ ++ MT2063_ACRF, ++ ++ /* maxium ATN attenuation. Paremeter is value to set. */ ++ MT2063_ACRF_MAX, ++ ++ /* directly set FIF attenuation. Paremeter is value to set. */ ++ MT2063_ACFIF, ++ ++ /* maxium FIF attenuation. Paremeter is value to set. */ ++ MT2063_ACFIF_MAX, ++ ++ /* LNA Rin */ ++ MT2063_LNA_RIN, ++ ++ /* Power Detector LNA level target */ ++ MT2063_LNA_TGT, ++ ++ /* Power Detector 1 level */ ++ MT2063_PD1, ++ ++ /* Power Detector 1 level target */ ++ MT2063_PD1_TGT, ++ ++ /* Power Detector 2 level */ ++ MT2063_PD2, ++ ++ /* Power Detector 2 level target */ ++ MT2063_PD2_TGT, ++ ++ /* Selects, which DNC is activ */ ++ MT2063_DNC_OUTPUT_ENABLE, ++ ++ /* VGA gain code */ ++ MT2063_VGAGC, ++ ++ /* VGA bias current */ ++ MT2063_VGAOI, ++ ++ /* TAGC, determins the speed of the AGC */ ++ MT2063_TAGC, ++ ++ /* AMP gain code */ ++ MT2063_AMPGC, ++ ++ /* Control setting to avoid DECT freqs (default: MT_AVOID_BOTH) */ ++ MT2063_AVOID_DECT, ++ ++ /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ ++ MT2063_CTFILT_SW, ++ ++ MT2063_EOP /* last entry in enumerated list */ ++ ++} MT2063_Param; ++ ++ ++/* ++** Parameter for selecting tuner mode ++*/ ++typedef enum ++{ ++ MT2063_CABLE_QAM = 0, /* Digital cable */ ++ MT2063_CABLE_ANALOG, /* Analog cable */ ++ MT2063_OFFAIR_COFDM, /* Digital offair */ ++ MT2063_OFFAIR_COFDM_SAWLESS, /* Digital offair without SAW */ ++ MT2063_OFFAIR_ANALOG, /* Analog offair */ ++ MT2063_OFFAIR_8VSB, /* Analog offair */ ++ MT2063_NUM_RCVR_MODES ++} MT2063_RCVR_MODES; ++ ++ ++/* ++** Possible values for MT2063_DNC_OUTPUT ++*/ ++typedef enum { ++ MT2063_DNC_NONE = 0, ++ MT2063_DNC_1, ++ MT2063_DNC_2, ++ MT2063_DNC_BOTH ++} MT2063_DNC_Output_Enable; ++ ++ ++/* ====== Functions which are declared in MT2063.c File ======= */ ++ ++/****************************************************************************** ++** ++** Name: MT2063_Open ++** ++** Description: Initialize the tuner's register values. ++** ++** Usage: status = MT2063_Open(0xC0, &hMT2063, NULL); ++** if (MT_IS_ERROR(status)) ++** // Check error codes for reason ++** ++** Parameters: MT2063_Addr - Serial bus address of the tuner. ++** hMT2063 - Tuner handle passed back. ++** hUserData - User-defined data, if needed for the ++** MT_ReadSub() & MT_WriteSub functions. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_COMM_ERR - Serial bus communications error ++** MT_ARG_NULL - Null pointer argument passed ++** MT_TUNER_CNT_ERR - Too many tuners open ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_Open(UData_t MT2063_Addr, ++ Handle_t* hMT2063, ++ Handle_t hUserData); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_Close ++** ++** Description: Release the handle to the tuner. ++** ++** Parameters: hMT2063 - Handle to the MT2063 tuner ++** ++** Usage: status = MT2063_Close(hMT2063); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_Close(Handle_t hMT2063); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_Tune ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** f_in - RF input center frequency (in Hz). ++** ++** Usage: status = MT2063_Tune(hMT2063, ++** f_in) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_UPC_UNLOCK - Upconverter PLL unlocked ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_SPUR_CNT_MASK - Count of avoided LO spurs ++** MT_SPUR_PRESENT - LO spur possible in output ++** MT_FIN_RANGE - Input freq out of range ++** MT_FOUT_RANGE - Output freq out of range ++** MT_UPC_RANGE - Upconverter freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2063_Open BEFORE MT2063_Tune! ++** ++** MT_ReadSub - Read data from the two-wire serial bus ++** MT_WriteSub - Write data to the two-wire serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_Tune(Handle_t h, ++ UData_t f_in); /* RF input center frequency */ ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_GetGPIO ++** ++** Description: Get the current MT2063 GPIO value. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** attr - Selects input readback, I/O direction or ++** output value ++** bit - Selects GPIO0, GPIO1, or GPIO2 ++** *value - current setting of GPIO pin ++** ++** Usage: status = MT2063_GetGPIO(hMT2063, MT2063_GPIO2, &value); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_GetGPIO(Handle_t h, MT2063_GPIO_ID gpio_id, MT2063_GPIO_Attr attr, UData_t* value); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetLocked ++** ++** Description: Checks to see if LO1 and LO2 are locked. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** ++** Usage: status = MT2063_GetLocked(hMT2063); ++** if (status & (MT_UPC_UNLOCK | MT_DNC_UNLOCK)) ++** // error!, one or more PLL's unlocked ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_UPC_UNLOCK - Upconverter PLL unlocked ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetLocked(Handle_t h); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetParam ++** ++** Description: Gets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm - mostly for testing purposes. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2063_Param) ++** pValue - ptr to returned value ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2063_IC_ADDR Serial Bus address of this tuner ++** MT2063_MAX_OPEN Max # of MT2063's allowed open ++** MT2063_NUM_OPEN # of MT2063's open ++** MT2063_SRO_FREQ crystal frequency ++** MT2063_STEPSIZE minimum tuning step size ++** MT2063_INPUT_FREQ input center frequency ++** MT2063_LO1_FREQ LO1 Frequency ++** MT2063_LO1_STEPSIZE LO1 minimum step size ++** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region ++** MT2063_IF1_ACTUAL Current 1st IF in use ++** MT2063_IF1_REQUEST Requested 1st IF ++** MT2063_IF1_CENTER Center of 1st IF SAW filter ++** MT2063_IF1_BW Bandwidth of 1st IF SAW filter ++** MT2063_ZIF_BW zero-IF bandwidth ++** MT2063_LO2_FREQ LO2 Frequency ++** MT2063_LO2_STEPSIZE LO2 minimum step size ++** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region ++** MT2063_OUTPUT_FREQ output center frequency ++** MT2063_OUTPUT_BW output bandwidth ++** MT2063_LO_SEPARATION min inter-tuner LO separation ++** MT2063_AS_ALG ID of avoid-spurs algorithm in use ++** MT2063_MAX_HARM1 max # of intra-tuner harmonics ++** MT2063_MAX_HARM2 max # of inter-tuner harmonics ++** MT2063_EXCL_ZONES # of 1st IF exclusion zones ++** MT2063_NUM_SPURS # of spurs found/avoided ++** MT2063_SPUR_AVOIDED >0 spurs avoided ++** MT2063_SPUR_PRESENT >0 spurs in output (mathematically) ++** MT2063_RCVR_MODE Predefined modes. ++** MT2063_LNA_RIN Get LNA RIN value ++** MT2063_LNA_TGT Get target power level at LNA ++** MT2063_PD1_TGT Get target power level at PD1 ++** MT2063_PD2_TGT Get target power level at PD2 ++** MT2063_ACLNA LNA attenuator gain code ++** MT2063_ACRF RF attenuator gain code ++** MT2063_ACFIF FIF attenuator gain code ++** MT2063_ACLNA_MAX LNA attenuator limit ++** MT2063_ACRF_MAX RF attenuator limit ++** MT2063_ACFIF_MAX FIF attenuator limit ++** MT2063_PD1 Actual value of PD1 ++** MT2063_PD2 Actual value of PD2 ++** MT2063_DNC_OUTPUT_ENABLE DNC output selection ++** MT2063_VGAGC VGA gain code ++** MT2063_VGAOI VGA output current ++** MT2063_TAGC TAGC setting ++** MT2063_AMPGC AMP gain code ++** MT2063_AVOID_DECT Avoid DECT Frequencies ++** MT2063_CTFILT_SW Cleartune filter selection ++** ++** Usage: status |= MT2063_GetParam(hMT2063, ++** MT2063_IF1_ACTUAL, ++** &f_IF1_Actual); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** See Also: MT2063_SetParam, MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC ++** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW ++** in GetParam. ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** 07-10-2008 PINZ Ver 1.19: Documentation Updates, Add a GetParam ++** for each SetParam (LNA_RIN, TGTs) ++** ++****************************************************************************/ ++UData_t MT2063_GetParam(Handle_t h, ++ MT2063_Param param, ++ UData_t* pValue); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetReg ++** ++** Description: Gets an MT2063 register. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** reg - MT2063 register/subaddress location ++** *val - MT2063 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2063. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetReg(Handle_t h, ++ U8Data reg, ++ U8Data* val); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_GetTemp ++** ++** Description: Get the MT2063 Temperature register. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** *value - value read from the register ++** ++** Binary ++** Value Returned Value Approx Temp ++** --------------------------------------------- ++** MT2063_T_0C 0000 0C ++** MT2063_T_10C 0001 10C ++** MT2063_T_20C 0010 20C ++** MT2063_T_30C 0011 30C ++** MT2063_T_40C 0100 40C ++** MT2063_T_50C 0101 50C ++** MT2063_T_60C 0110 60C ++** MT2063_T_70C 0111 70C ++** MT2063_T_80C 1000 80C ++** MT2063_T_90C 1001 90C ++** MT2063_T_100C 1010 100C ++** MT2063_T_110C 1011 110C ++** MT2063_T_120C 1100 120C ++** MT2063_T_130C 1101 130C ++** MT2063_T_140C 1110 140C ++** MT2063_T_150C 1111 150C ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_GetTemp(Handle_t h, MT2063_Temperature* value); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetUserData ++** ++** Description: Gets the user-defined data item. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** ++** Usage: status = MT2063_GetUserData(hMT2063, &hUserData); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** The hUserData parameter is a user-specific argument ++** that is stored internally with the other tuner- ++** specific information. ++** ++** For example, if additional arguments are needed ++** for the user to identify the device communicating ++** with the tuner, this argument can be used to supply ++** the necessary information. ++** ++** The hUserData parameter is initialized in the tuner's ++** Open function to NULL. ++** ++** See Also: MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetUserData(Handle_t h, ++ Handle_t* hUserData); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_ReInit ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_ReInit(Handle_t h); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2063_SetGPIO ++** ++** Description: Modify the MT2063 GPIO value. ++** ++** Parameters: h - Open handle to the tuner (from MT2063_Open). ++** gpio_id - Selects GPIO0, GPIO1, or GPIO2 ++** attr - Selects input readback, I/O direction or ++** output value ++** value - value to set GPIO pin ++** ++** Usage: status = MT2063_SetGPIO(hMT2063, MT2063_GPIO1, MT2063_GPIO_OUT, 1); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++******************************************************************************/ ++UData_t MT2063_SetGPIO(Handle_t h, MT2063_GPIO_ID gpio_id, MT2063_GPIO_Attr attr, UData_t value); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetParam ++** ++** Description: Sets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm. You can override many of the tuning ++** algorithm defaults using this function. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2063_Param) ++** nValue - value to be set ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2063_SRO_FREQ crystal frequency ++** MT2063_STEPSIZE minimum tuning step size ++** MT2063_LO1_FREQ LO1 frequency ++** MT2063_LO1_STEPSIZE LO1 minimum step size ++** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region ++** MT2063_IF1_REQUEST Requested 1st IF ++** MT2063_ZIF_BW zero-IF bandwidth ++** MT2063_LO2_FREQ LO2 frequency ++** MT2063_LO2_STEPSIZE LO2 minimum step size ++** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region ++** MT2063_OUTPUT_FREQ output center frequency ++** MT2063_OUTPUT_BW output bandwidth ++** MT2063_LO_SEPARATION min inter-tuner LO separation ++** MT2063_MAX_HARM1 max # of intra-tuner harmonics ++** MT2063_MAX_HARM2 max # of inter-tuner harmonics ++** MT2063_RCVR_MODE Predefined modes ++** MT2063_LNA_RIN Set LNA Rin (*) ++** MT2063_LNA_TGT Set target power level at LNA (*) ++** MT2063_PD1_TGT Set target power level at PD1 (*) ++** MT2063_PD2_TGT Set target power level at PD2 (*) ++** MT2063_ACLNA_MAX LNA attenuator limit (*) ++** MT2063_ACRF_MAX RF attenuator limit (*) ++** MT2063_ACFIF_MAX FIF attenuator limit (*) ++** MT2063_DNC_OUTPUT_ENABLE DNC output selection ++** MT2063_VGAGC VGA gain code ++** MT2063_VGAOI VGA output current ++** MT2063_TAGC TAGC setting ++** MT2063_AMPGC AMP gain code ++** MT2063_AVOID_DECT Avoid DECT Frequencies ++** MT2063_CTFILT_SW Cleartune filter selection ++** ++** (*) This parameter is set by MT2063_RCVR_MODE, do not call ++** additionally. ++** ++** Usage: status |= MT2063_SetParam(hMT2063, ++** MT2063_STEPSIZE, ++** 50000); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** or set value out of range ++** or non-writable parameter ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** See Also: MT2063_GetParam, MT2063_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ ++** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC ++** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT ++** Split SetParam up to ACLNA / ACLNA_MAX ++** removed ACLNA_INRC/DECR (+RF & FIF) ++** removed GCUAUTO / BYPATNDN/UP ++** 175 I 06-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs. ++** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid. ++** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW ++** ++****************************************************************************/ ++UData_t MT2063_SetParam(Handle_t h, ++ MT2063_Param param, ++ UData_t nValue); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetPowerMaskBits ++** ++** Description: Sets the power-down mask bits for various sections of ++** the MT2063 ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to be set. ++** ++** MT2063_ALL_SD All shutdown bits for this tuner ++** ++** MT2063_REG_SD Shutdown regulator ++** MT2063_SRO_SD Shutdown SRO ++** MT2063_AFC_SD Shutdown AFC A/D ++** MT2063_PD_SD Enable power detector shutdown ++** MT2063_PDADC_SD Enable power detector A/D shutdown ++** MT2063_VCO_SD Enable VCO shutdown VCO ++** MT2063_UPC_SD Enable upconverter shutdown ++** MT2063_DNC_SD Enable downconverter shutdown ++** MT2063_VGA_SD Enable VGA shutdown ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetPowerMaskBits(Handle_t h, MT2063_Mask_Bits Bits); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_ClearPowerMaskBits ++** ++** Description: Clears the power-down mask bits for various sections of ++** the MT2063 ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to be cleared. ++** ++** MT2063_ALL_SD All shutdown bits for this tuner ++** ++** MT2063_REG_SD Shutdown regulator ++** MT2063_SRO_SD Shutdown SRO ++** MT2063_AFC_SD Shutdown AFC A/D ++** MT2063_PD_SD Enable power detector shutdown ++** MT2063_PDADC_SD Enable power detector A/D shutdown ++** MT2063_VCO_SD Enable VCO shutdown VCO ++** MT2063_UPC_SD Enable upconverter shutdown ++** MT2063_DNC_SD Enable downconverter shutdown ++** MT2063_VGA_SD Enable VGA shutdown ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_ClearPowerMaskBits(Handle_t h, MT2063_Mask_Bits Bits); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_GetPowerMaskBits ++** ++** Description: Returns a mask of the enabled power shutdown bits ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Bits - Mask bits to currently set. ++** ++** MT2063_REG_SD Shutdown regulator ++** MT2063_SRO_SD Shutdown SRO ++** MT2063_AFC_SD Shutdown AFC A/D ++** MT2063_PD_SD Enable power detector shutdown ++** MT2063_PDADC_SD Enable power detector A/D shutdown ++** MT2063_VCO_SD Enable VCO shutdown VCO ++** MT2063_UPC_SD Enable upconverter shutdown ++** MT2063_DNC_SD Enable downconverter shutdown ++** MT2063_VGA_SD Enable VGA shutdown ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Output argument is NULL ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_GetPowerMaskBits(Handle_t h, MT2063_Mask_Bits *Bits); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_EnableExternalShutdown ++** ++** Description: Enables or disables the operation of the external ++** shutdown pin ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Enabled - 0 = disable the pin, otherwise enable it ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SoftwareShutdown ++** ++** Description: Enables or disables software shutdown function. When ++** Shutdown==1, any section whose power mask is set will be ++** shutdown. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Shutdown - 1 = shutdown the masked sections, otherwise ++** power all sections on ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetExtSRO ++** ++** Description: Sets the external SRO driver. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** Ext_SRO_Setting - external SRO drive setting ++** ++** (default) MT2063_EXT_SRO_OFF - ext driver off ++** MT2063_EXT_SRO_BY_1 - ext driver = SRO frequency ++** MT2063_EXT_SRO_BY_2 - ext driver = SRO/2 frequency ++** MT2063_EXT_SRO_BY_4 - ext driver = SRO/4 frequency ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** The Ext_SRO_Setting settings default to OFF ++** Use this function if you need to override the default ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetExtSRO(Handle_t h, MT2063_Ext_SRO Ext_SRO_Setting); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2063_SetReg ++** ++** Description: Sets an MT2063 register. ++** ++** Parameters: h - Tuner handle (returned by MT2063_Open) ++** reg - MT2063 register/subaddress location ++** val - MT2063 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2063_Open() FIRST! ++** ++** Use this function if you need to override a default ++** register value ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. ++** ++****************************************************************************/ ++UData_t MT2063_SetReg(Handle_t h, ++ U8Data reg, ++ U8Data val); ++ ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_spuravoid.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_spuravoid.h ++** ++** Copyright 2006-2008 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt_spuravoid.h ++** ++** Description: Implements spur avoidance for MicroTuners ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_spuravoid.h,v 1.4 2008/11/05 13:46:20 software Exp $ ++** CVS Source: $Source: /export/vol0/cvsroot/software/tuners/MT2063/mt_spuravoid.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** 083 02-08-2005 JWS Added separate version number for expected ++** version of MT_SpurAvoid.h ++** 083 02-08-2005 JWS Added function to return the version of the ++** MT_AvoidSpurs source file. ++** 098 04-12-2005 DAD Increased MAX_ZONES from 32 to 48. 32 is ++** sufficient for the default avoidance params. ++** 103 01-31-2005 DAD In MT_AddExclZone(), if the range ++** (f_min, f_max) < 0, ignore the entry. ++** 195 M 06-20-2008 RSK Ver 1.21: Refactoring to place DECT frequency ++** avoidance (US and Euro) in 'SpurAvoidance'. ++** 199 08-06-2008 JWS Ver 1.22: Added 0x1x1 spur frequency calculations ++** and indicate success of AddExclZone operation. ++** 200 08-07-2008 JWS Ver 1.23: Moved definition of DECT avoid constants ++** so users could access them more easily. ++** ++*****************************************************************************/ ++#if !defined(__MT2063_SPURAVOID_H) ++#define __MT2063_SPURAVOID_H ++ ++//#include "mt_userdef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++/* ++** Constant defining the version of the following structure ++** and therefore the API for this code. ++** ++** When compiling the tuner driver, the preprocessor will ++** check against this version number to make sure that ++** it matches the version that the tuner driver knows about. ++*/ ++/* Version 010201 => 1.21 */ ++#define MT2063_AVOID_SPURS_INFO_VERSION 010201 ++ ++ ++#define MT2063_MAX_ZONES 48 ++ ++struct MT2063_ExclZone_t; ++ ++struct MT2063_ExclZone_t ++{ ++ UData_t min_; ++ UData_t max_; ++ struct MT2063_ExclZone_t* next_; ++}; ++#ifndef _MT_DECT_Avoid_Type_DEFINE_ ++#define _MT_DECT_Avoid_Type_DEFINE_ ++// ++// DECT Frequency Avoidance: ++// These constants are used to avoid interference from DECT frequencies. ++// ++typedef enum ++{ ++ MT_NO_DECT_AVOIDANCE = 0x00000000, // Do not create DECT exclusion zones. ++ MT_AVOID_US_DECT = 0x00000001, // Avoid US DECT frequencies. ++ MT_AVOID_EURO_DECT = 0x00000002, // Avoid European DECT frequencies. ++ MT_AVOID_BOTH // Avoid both regions. Not typically used. ++} MT_DECT_Avoid_Type; ++#endif ++ ++/* ++** Structure of data needed for Spur Avoidance ++*/ ++typedef struct ++{ ++ UData_t nAS_Algorithm; ++ UData_t f_ref; ++ UData_t f_in; ++ UData_t f_LO1; ++ UData_t f_if1_Center; ++ UData_t f_if1_Request; ++ UData_t f_if1_bw; ++ UData_t f_LO2; ++ UData_t f_out; ++ UData_t f_out_bw; ++ UData_t f_LO1_Step; ++ UData_t f_LO2_Step; ++ UData_t f_LO1_FracN_Avoid; ++ UData_t f_LO2_FracN_Avoid; ++ UData_t f_zif_bw; ++ UData_t f_min_LO_Separation; ++ UData_t maxH1; ++ UData_t maxH2; ++ MT_DECT_Avoid_Type avoidDECT; ++ UData_t bSpurPresent; ++ UData_t bSpurAvoided; ++ UData_t nSpursFound; ++ UData_t nZones; ++ struct MT2063_ExclZone_t* freeZones; ++ struct MT2063_ExclZone_t* usedZones; ++ struct MT2063_ExclZone_t MT_ExclZones[MT2063_MAX_ZONES]; ++} MT2063_AvoidSpursData_t; ++ ++UData_t MT2063_RegisterTuner(MT2063_AvoidSpursData_t* pAS_Info); ++ ++void MT2063_UnRegisterTuner(MT2063_AvoidSpursData_t* pAS_Info); ++ ++void MT2063_ResetExclZones(MT2063_AvoidSpursData_t* pAS_Info); ++ ++UData_t MT2063_AddExclZone(MT2063_AvoidSpursData_t* pAS_Info, ++ UData_t f_min, ++ UData_t f_max); ++ ++UData_t MT2063_ChooseFirstIF(MT2063_AvoidSpursData_t* pAS_Info); ++ ++UData_t MT2063_AvoidSpurs(Handle_t h, ++ MT2063_AvoidSpursData_t* pAS_Info); ++ ++UData_t MT2063_AvoidSpursVersion(void); ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is MT2063 tuner API source code ++ ++ ++ ++ ++ ++/** ++ ++@file ++ ++@brief MT2063 tuner module declaration ++ ++One can manipulate MT2063 tuner through MT2063 module. ++MT2063 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// MT2063 API option ++#define MT2063_CNT 4 ++ ++// MT2063 macro ++//#define abs(x) ((x) < 0 ? -(x) : (x)) ++ ++// MT2063 bandwidth shift ++#define MT2063_BANDWIDTH_SHIFT_HZ 1000000 ++ ++ ++ ++// Bandwidth modes ++enum MT2063_BANDWIDTH_MODE ++{ ++ MT2063_BANDWIDTH_6MHZ = 6000000, ++ MT2063_BANDWIDTH_7MHZ = 7000000, ++ MT2063_BANDWIDTH_8MHZ = 8000000, ++}; ++ ++ ++// Standard modes ++enum MT2063_STANDARD_MODE ++{ ++ MT2063_STANDARD_DVBT, ++ MT2063_STANDARD_QAM, ++}; ++ ++ ++// VGAGC settings ++enum MT2063_VGAGC_SETTINGS ++{ ++ MT2063_VGAGC_0X0 = 0x0, ++ MT2063_VGAGC_0X1 = 0x1, ++ MT2063_VGAGC_0X3 = 0x3, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildMt2063Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ int StandardMode, ++ unsigned long IfVgaGainControl ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++mt2063_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++mt2063_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++mt2063_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mt2063_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++mt2063_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++mt2063_OpenHandle( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mt2063_CloseHandle( ++ TUNER_MODULE *pTuner ++ ); ++ ++void ++mt2063_GetHandle( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++int ++mt2063_SetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long IfFreqHz ++ ); ++ ++int ++mt2063_GetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++int ++mt2063_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++int ++mt2063_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_mt2266.c b/drivers/drivers/media/dvb/dvb-usb/tuner_mt2266.c +--- a/drivers/media/dvb/dvb-usb/tuner_mt2266.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_mt2266.c 2016-04-02 19:17:52.144066046 -0300 +@@ -0,0 +1,3278 @@ ++/** ++ ++@file ++ ++@brief MT2266 tuner module definition ++ ++One can manipulate MT2266 tuner through MT2266 module. ++MT2266 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_mt2266.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief MT2266 tuner module builder ++ ++Use BuildMt2266Module() to build MT2266 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to MT2266 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr MT2266 I2C device address ++ ++ ++@note ++ -# One should call BuildMt2266Module() to build MT2266 module before using it. ++ ++*/ ++void ++BuildMt2266Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_MT2266; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = mt2266_GetTunerType; ++ pTuner->GetDeviceAddr = mt2266_GetDeviceAddr; ++ ++ pTuner->Initialize = mt2266_Initialize; ++ pTuner->SetRfFreqHz = mt2266_SetRfFreqHz; ++ pTuner->GetRfFreqHz = mt2266_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->IsBandwidthHzSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->OpenHandle = mt2266_OpenHandle; ++ pExtra->CloseHandle = mt2266_CloseHandle; ++ pExtra->GetHandle = mt2266_GetHandle; ++ pExtra->SetBandwidthHz = mt2266_SetBandwidthHz; ++ pExtra->GetBandwidthHz = mt2266_GetBandwidthHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++mt2266_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++mt2266_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++mt2266_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Re-initialize tuner. ++ Status = MT2266_ReInit(DeviceHandle); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++mt2266_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner RF frequency in Hz. ++ Status = MT2266_ChangeFreq(DeviceHandle, RfFreqHz); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++mt2266_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Open MT2266 tuner handle. ++ ++*/ ++int ++mt2266_OpenHandle( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ unsigned char DeviceAddr; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner I2C device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Open MT2266 handle. ++ // Note: 1. Must take tuner extra module DeviceHandle as handle input argument. ++ // 2. Take pTuner as user-defined data input argument. ++ Status = MT2266_Open(DeviceAddr, &pExtra->DeviceHandle, pTuner); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_open_mt2266_handle; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_open_mt2266_handle: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Close MT2266 tuner handle. ++ ++*/ ++int ++mt2266_CloseHandle( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Close MT2266 handle. ++ Status = MT2266_Close(DeviceHandle); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_open_mt2266_handle; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_open_mt2266_handle: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2266 tuner handle. ++ ++*/ ++void ++mt2266_GetHandle( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ *pDeviceHandle = pExtra->DeviceHandle; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MT2266 tuner bandwidth in Hz. ++ ++*/ ++int ++mt2266_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ Handle_t DeviceHandle; ++ UData_t Status; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ // Get tuner handle. ++ DeviceHandle = pExtra->DeviceHandle; ++ ++ ++ // Set tuner bandwidth in Hz. ++ Status = MT2266_SetParam(DeviceHandle, MT2266_OUTPUT_BW, BandwidthHz); ++ ++ if(MT_IS_ERROR(Status)) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ // Set tuner bandwidth parameter. ++ pExtra->BandwidthHz = BandwidthHz; ++ pExtra->IsBandwidthHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MT2266 tuner bandwidth in Hz. ++ ++*/ ++int ++mt2266_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ) ++{ ++ MT2266_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mt2266); ++ ++ ++ // Get tuner bandwidth in Hz from tuner module. ++ if(pExtra->IsBandwidthHzSet != YES) ++ goto error_status_get_tuner_bandwidth; ++ ++ *pBandwidthHz = pExtra->BandwidthHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Microtune source code - mt_userdef.c ++ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.c ++** ++** Description: User-defined MicroTuner software interface ++** ++** Functions ++** Requiring ++** Implementation: MT_WriteSub ++** MT_ReadSub ++** MT_Sleep ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_userdef.c,v 1.2 2006/10/26 16:39:18 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt_userdef.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++//#include "mt_userdef.h" ++ ++ ++/***************************************************************************** ++** ++** Name: MT_WriteSub ++** ++** Description: Write values to device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to write data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2266_WriteSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt) ++{ ++// UData_t status = MT_OK; /* Status to be returned */ ++ /* ++ ** ToDo: Add code here to implement a serial-bus write ++ ** operation to the MTxxxx tuner. If successful, ++ ** return MT_OK. ++ */ ++/* return status; */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i, j; ++ ++ unsigned char RegStartAddr; ++ unsigned char *pWritingBytes; ++ unsigned long ByteNum; ++ ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = subAddress; ++ pWritingBytes = pData; ++ ByteNum = (unsigned long)cnt; ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set tuner register bytes with writing bytes. ++ // Note: Set tuner register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + ++ // stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_set_tuner_registers: ++ return MT_COMM_ERR; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ReadSub ++** ++** Description: Read values from device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to read data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2266_ReadSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt) ++{ ++ // UData_t status = MT_OK; /* Status to be returned */ ++ ++ /* ++ ** ToDo: Add code here to implement a serial-bus read ++ ** operation to the MTxxxx tuner. If successful, ++ ** return MT_OK. ++ */ ++/* return status; */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i; ++ ++ unsigned char RegStartAddr; ++ unsigned char *pReadingBytes; ++ unsigned long ByteNum; ++ ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = subAddress; ++ pReadingBytes = pData; ++ ByteNum = (unsigned long)cnt; ++ ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ // Get tuner register bytes. ++ // Note: Get tuner register bytes considering maximum reading byte number. ++ for(i = 0; i < ByteNum; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = RegStartAddr + i; ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ByteNum - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegReadingAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register bytes. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, &pReadingBytes[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ } ++ ++ ++ return MT_OK; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return MT_COMM_ERR; ++} ++ ++ ++/***************************************************************************** ++** ++** Name: MT_Sleep ++** ++** Description: Delay execution for "nMinDelayTime" milliseconds ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** nMinDelayTime - Delay time in milliseconds ++** ++** Returns: None. ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code that ++** blocks execution for the specified period of time. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++void MT2266_Sleep(Handle_t hUserData, ++ UData_t nMinDelayTime) ++{ ++ /* ++ ** ToDo: Add code here to implement a OS blocking ++ ** for a period of "nMinDelayTime" milliseconds. ++ */ ++ ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get tuner module, base interface. ++ pTuner = (TUNER_MODULE *)hUserData; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ ++ // Wait nMinDelayTime milliseconds. ++ pBaseInterface->WaitMs(pBaseInterface, nMinDelayTime); ++ ++ ++ return; ++} ++ ++ ++#if defined(MT2060_CNT) ++#if MT2060_CNT > 0 ++/***************************************************************************** ++** ++** Name: MT_TunerGain (MT2060 only) ++** ++** Description: Measure the relative tuner gain using the demodulator ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** pMeas - Tuner gain (1/100 of dB scale). ++** ie. 1234 = 12.34 (dB) ++** ++** Returns: status: ++** MT_OK - No errors ++** user-defined errors could be set ++** ++** Notes: This is a callback function that is called from the ++** the 1st IF location routine. You MUST provide ++** code that measures the relative tuner gain in a dB ++** (not linear) scale. The return value is an integer ++** value scaled to 1/100 of a dB. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 06-16-2004 DAD Original ++** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name ++** better describes what this function does. ++** ++*****************************************************************************/ ++UData_t MT_TunerGain(Handle_t hUserData, ++ SData_t* pMeas) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ ++ /* ++ ** ToDo: Add code here to return the gain / power level measured ++ ** at the input to the demodulator. ++ */ ++ ++ ++ ++ return (status); ++} ++#endif ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt2266.c ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt2266.c ++** ++** Copyright 2007 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt2266.c ++** ++** Description: Microtune MT2266 Tuner software interface. ++** Supports tuners with Part/Rev code: 0x85. ++** ++** Functions ++** Implemented: UData_t MT2266_Open ++** UData_t MT2266_Close ++** UData_t MT2266_ChangeFreq ++** UData_t MT2266_GetLocked ++** UData_t MT2266_GetParam ++** UData_t MT2266_GetReg ++** UData_t MT2266_GetUHFXFreqs ++** UData_t MT2266_GetUserData ++** UData_t MT2266_ReInit ++** UData_t MT2266_SetParam ++** UData_t MT2266_SetPowerModes ++** UData_t MT2266_SetReg ++** UData_t MT2266_SetUHFXFreqs ++** ++** References: AN-00010: MicroTuner Serial Interface Application Note ++** MicroTune, Inc. ++** ++** Exports: None ++** ++** Dependencies: MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Read byte(s) of data from the two-wire bus. ++** ++** MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Write byte(s) of data to the two-wire bus. ++** ++** MT_Sleep(hUserData, nMinDelayTime); ++** - Delay execution for x milliseconds ++** ++** CVS ID: $Id: mt2266.c,v 1.5 2007/10/02 18:43:17 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt2266.c,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 06-08-2006 JWS Ver 1.01: Corrected problem with tuner ID check ++** N/A 11-01-2006 RSK Ver 1.02: Adding multiple-filter support ++** as well as Get/Set functions. ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification for gcc ++** N/A 12-20-2006 RSK Ver 1.04: Adding fLO_FractionalTerm() usage. ++** 118 05-09-2007 RSK Ver 1.05: Adding Standard MTxxxx_Tune() API. ++** ++*****************************************************************************/ ++//#include "mt2266.h" ++//#include /* for NULL */ ++#define MT_NULL 0 ++ ++/* Version of this module */ ++#define VERSION 10005 /* Version 01.05 */ ++ ++ ++#ifndef MT2266_CNT ++#error You must define MT2266_CNT in the "mt_userdef.h" file ++#endif ++ ++/* ++** Normally, the "reg" array in the tuner structure is used as a cache ++** containing the current value of the tuner registers. If the user's ++** application MUST change tuner registers without using the MT2266_SetReg ++** routine provided, he may compile this code with the __NO_CACHE__ ++** variable defined. ++** The PREFETCH macro will insert code code to re-read tuner registers if ++** __NO_CACHE__ is defined. If it is not defined (normal) then PREFETCH ++** does nothing. ++*/ ++ ++#if defined(__NO_CACHE__) ++#define PREFETCH(var, cnt) \ ++ if (MT_NO_ERROR(status)) \ ++ status |= MT2266_ReadSub(pInfo->hUserData, pInfo->address, (var), &pInfo->reg[(var)], (cnt)); ++#else ++#define PREFETCH(var, cnt) ++#endif ++ ++ ++ ++/* ++** Two-wire serial bus subaddresses of the tuner registers. ++** Also known as the tuner's register addresses. ++*/ ++enum MT2266_Register_Offsets ++{ ++ MT2266_PART_REV = 0, /* 0x00 */ ++ MT2266_LO_CTRL_1, /* 0x01 */ ++ MT2266_LO_CTRL_2, /* 0x02 */ ++ MT2266_LO_CTRL_3, /* 0x03 */ ++ MT2266_SMART_ANT, /* 0x04 */ ++ MT2266_BAND_CTRL, /* 0x05 */ ++ MT2266_CLEARTUNE, /* 0x06 */ ++ MT2266_IGAIN, /* 0x07 */ ++ MT2266_BBFILT_1, /* 0x08 */ ++ MT2266_BBFILT_2, /* 0x09 */ ++ MT2266_BBFILT_3, /* 0x0A */ ++ MT2266_BBFILT_4, /* 0x0B */ ++ MT2266_BBFILT_5, /* 0x0C */ ++ MT2266_BBFILT_6, /* 0x0D */ ++ MT2266_BBFILT_7, /* 0x0E */ ++ MT2266_BBFILT_8, /* 0x0F */ ++ MT2266_RCC_CTRL, /* 0x10 */ ++ MT2266_RSVD_11, /* 0x11 */ ++ MT2266_STATUS_1, /* 0x12 */ ++ MT2266_STATUS_2, /* 0x13 */ ++ MT2266_STATUS_3, /* 0x14 */ ++ MT2266_STATUS_4, /* 0x15 */ ++ MT2266_STATUS_5, /* 0x16 */ ++ MT2266_SRO_CTRL, /* 0x17 */ ++ MT2266_RSVD_18, /* 0x18 */ ++ MT2266_RSVD_19, /* 0x19 */ ++ MT2266_RSVD_1A, /* 0x1A */ ++ MT2266_RSVD_1B, /* 0x1B */ ++ MT2266_ENABLES, /* 0x1C */ ++ MT2266_RSVD_1D, /* 0x1D */ ++ MT2266_RSVD_1E, /* 0x1E */ ++ MT2266_RSVD_1F, /* 0x1F */ ++ MT2266_GPO, /* 0x20 */ ++ MT2266_RSVD_21, /* 0x21 */ ++ MT2266_RSVD_22, /* 0x22 */ ++ MT2266_RSVD_23, /* 0x23 */ ++ MT2266_RSVD_24, /* 0x24 */ ++ MT2266_RSVD_25, /* 0x25 */ ++ MT2266_RSVD_26, /* 0x26 */ ++ MT2266_RSVD_27, /* 0x27 */ ++ MT2266_RSVD_28, /* 0x28 */ ++ MT2266_RSVD_29, /* 0x29 */ ++ MT2266_RSVD_2A, /* 0x2A */ ++ MT2266_RSVD_2B, /* 0x2B */ ++ MT2266_RSVD_2C, /* 0x2C */ ++ MT2266_RSVD_2D, /* 0x2D */ ++ MT2266_RSVD_2E, /* 0x2E */ ++ MT2266_RSVD_2F, /* 0x2F */ ++ MT2266_RSVD_30, /* 0x30 */ ++ MT2266_RSVD_31, /* 0x31 */ ++ MT2266_RSVD_32, /* 0x32 */ ++ MT2266_RSVD_33, /* 0x33 */ ++ MT2266_RSVD_34, /* 0x34 */ ++ MT2266_RSVD_35, /* 0x35 */ ++ MT2266_RSVD_36, /* 0x36 */ ++ MT2266_RSVD_37, /* 0x37 */ ++ MT2266_RSVD_38, /* 0x38 */ ++ MT2266_RSVD_39, /* 0x39 */ ++ MT2266_RSVD_3A, /* 0x3A */ ++ MT2266_RSVD_3B, /* 0x3B */ ++ MT2266_RSVD_3C, /* 0x3C */ ++ END_REGS ++}; ++ ++/* ++** DefaultsEntry points to an array of U8Data used to initialize ++** various registers (the first byte is the starting subaddress) ++** and a count of the bytes (including subaddress) in the array. ++** ++** DefaultsList is an array of DefaultsEntry elements terminated ++** by an entry with a NULL pointer for the data array. ++*/ ++typedef struct MT2266_DefaultsEntryTag ++{ ++ U8Data *data; ++ UData_t cnt; ++} MT2266_DefaultsEntry; ++ ++typedef MT2266_DefaultsEntry MT2266_DefaultsList[]; ++ ++#define DEF_LIST_ENTRY(a) {a, sizeof(a)/sizeof(U8Data) - 1} ++#define END_DEF_LIST {0,0} ++ ++/* ++** Constants used by the tuning algorithm ++*/ ++ /* REF_FREQ is now the actual crystal frequency */ ++#define REF_FREQ (30000000UL) /* Reference oscillator Frequency (in Hz) */ ++#define TUNE_STEP_SIZE (50UL) /* Tune in steps of 50 kHz */ ++#define MIN_UHF_FREQ (350000000UL) /* Minimum UHF frequency (in Hz) */ ++#define MAX_UHF_FREQ (900000000UL) /* Maximum UHF frequency (in Hz) */ ++#define MIN_VHF_FREQ (174000000UL) /* Minimum VHF frequency (in Hz) */ ++#define MAX_VHF_FREQ (230000000UL) /* Maximum VHF frequency (in Hz) */ ++#define OUTPUT_BW (8000000UL) /* Output channel bandwidth (in Hz) */ ++#define UHF_DEFAULT_FREQ (600000000UL) /* Default UHF input frequency (in Hz) */ ++ ++ ++/* ++** The number of Tuner Registers ++*/ ++static const UData_t Num_Registers = END_REGS; ++ ++/* ++** Crossover Frequency sets for 2 filters, without and with attenuation. ++*/ ++typedef struct ++{ ++ MT2266_XFreq_Set xfreq[ MT2266_NUMBER_OF_XFREQ_SETS ]; ++ ++} MT2266_XFreqs_t; ++ ++ ++MT2266_XFreqs_t MT2266_default_XFreqs = ++{ ++ /* xfreq */ ++ { ++ /* uhf0 */ ++ { /* < 0 MHz: 15+1 */ ++ 0UL, /* 0 .. 0 MHz: 15 */ ++ 0UL, /* 0 .. 443 MHz: 14 */ ++ 443000 / TUNE_STEP_SIZE, /* 443 .. 470 MHz: 13 */ ++ 470000 / TUNE_STEP_SIZE, /* 470 .. 496 MHz: 12 */ ++ 496000 / TUNE_STEP_SIZE, /* 496 .. 525 MHz: 11 */ ++ 525000 / TUNE_STEP_SIZE, /* 525 .. 552 MHz: 10 */ ++ 552000 / TUNE_STEP_SIZE, /* 552 .. 580 MHz: 9 */ ++ 580000 / TUNE_STEP_SIZE, /* 580 .. 657 MHz: 8 */ ++ 657000 / TUNE_STEP_SIZE, /* 657 .. 682 MHz: 7 */ ++ 682000 / TUNE_STEP_SIZE, /* 682 .. 710 MHz: 6 */ ++ 710000 / TUNE_STEP_SIZE, /* 710 .. 735 MHz: 5 */ ++ 735000 / TUNE_STEP_SIZE, /* 735 .. 763 MHz: 4 */ ++ 763000 / TUNE_STEP_SIZE, /* 763 .. 802 MHz: 3 */ ++ 802000 / TUNE_STEP_SIZE, /* 802 .. 840 MHz: 2 */ ++ 840000 / TUNE_STEP_SIZE, /* 840 .. 877 MHz: 1 */ ++ 877000 / TUNE_STEP_SIZE /* 877+ MHz: 0 */ ++ }, ++ ++ /* uhf1 */ ++ { /* < 443 MHz: 15+1 */ ++ 443000 / TUNE_STEP_SIZE, /* 443 .. 470 MHz: 15 */ ++ 470000 / TUNE_STEP_SIZE, /* 470 .. 496 MHz: 14 */ ++ 496000 / TUNE_STEP_SIZE, /* 496 .. 525 MHz: 13 */ ++ 525000 / TUNE_STEP_SIZE, /* 525 .. 552 MHz: 12 */ ++ 552000 / TUNE_STEP_SIZE, /* 552 .. 580 MHz: 11 */ ++ 580000 / TUNE_STEP_SIZE, /* 580 .. 605 MHz: 10 */ ++ 605000 / TUNE_STEP_SIZE, /* 605 .. 632 MHz: 9 */ ++ 632000 / TUNE_STEP_SIZE, /* 632 .. 657 MHz: 8 */ ++ 657000 / TUNE_STEP_SIZE, /* 657 .. 682 MHz: 7 */ ++ 682000 / TUNE_STEP_SIZE, /* 682 .. 710 MHz: 6 */ ++ 710000 / TUNE_STEP_SIZE, /* 710 .. 735 MHz: 5 */ ++ 735000 / TUNE_STEP_SIZE, /* 735 .. 763 MHz: 4 */ ++ 763000 / TUNE_STEP_SIZE, /* 763 .. 802 MHz: 3 */ ++ 802000 / TUNE_STEP_SIZE, /* 802 .. 840 MHz: 2 */ ++ 840000 / TUNE_STEP_SIZE, /* 840 .. 877 MHz: 1 */ ++ 877000 / TUNE_STEP_SIZE /* 877+ MHz: 0 */ ++ }, ++ ++ /* uhf0_a */ ++ { /* < 0 MHz: 15+1 */ ++ 0UL, /* 0 .. 0 MHz: 15 */ ++ 0UL, /* 0 .. 442 MHz: 14 */ ++ 442000 / TUNE_STEP_SIZE, /* 442 .. 472 MHz: 13 */ ++ 472000 / TUNE_STEP_SIZE, /* 472 .. 505 MHz: 12 */ ++ 505000 / TUNE_STEP_SIZE, /* 505 .. 535 MHz: 11 */ ++ 535000 / TUNE_STEP_SIZE, /* 535 .. 560 MHz: 10 */ ++ 560000 / TUNE_STEP_SIZE, /* 560 .. 593 MHz: 9 */ ++ 593000 / TUNE_STEP_SIZE, /* 593 .. 673 MHz: 8 */ ++ 673000 / TUNE_STEP_SIZE, /* 673 .. 700 MHz: 7 */ ++ 700000 / TUNE_STEP_SIZE, /* 700 .. 727 MHz: 6 */ ++ 727000 / TUNE_STEP_SIZE, /* 727 .. 752 MHz: 5 */ ++ 752000 / TUNE_STEP_SIZE, /* 752 .. 783 MHz: 4 */ ++ 783000 / TUNE_STEP_SIZE, /* 783 .. 825 MHz: 3 */ ++ 825000 / TUNE_STEP_SIZE, /* 825 .. 865 MHz: 2 */ ++ 865000 / TUNE_STEP_SIZE, /* 865 .. 905 MHz: 1 */ ++ 905000 / TUNE_STEP_SIZE /* 905+ MHz: 0 */ ++ }, ++ ++ /* uhf1_a */ ++ { /* < 442 MHz: 15+1 */ ++ 442000 / TUNE_STEP_SIZE, /* 442 .. 472 MHz: 15 */ ++ 472000 / TUNE_STEP_SIZE, /* 472 .. 505 MHz: 14 */ ++ 505000 / TUNE_STEP_SIZE, /* 505 .. 535 MHz: 13 */ ++ 535000 / TUNE_STEP_SIZE, /* 535 .. 560 MHz: 12 */ ++ 560000 / TUNE_STEP_SIZE, /* 560 .. 593 MHz: 11 */ ++ 593000 / TUNE_STEP_SIZE, /* 593 .. 620 MHz: 10 */ ++ 620000 / TUNE_STEP_SIZE, /* 620 .. 647 MHz: 9 */ ++ 647000 / TUNE_STEP_SIZE, /* 647 .. 673 MHz: 8 */ ++ 673000 / TUNE_STEP_SIZE, /* 673 .. 700 MHz: 7 */ ++ 700000 / TUNE_STEP_SIZE, /* 700 .. 727 MHz: 6 */ ++ 727000 / TUNE_STEP_SIZE, /* 727 .. 752 MHz: 5 */ ++ 752000 / TUNE_STEP_SIZE, /* 752 .. 783 MHz: 4 */ ++ 783000 / TUNE_STEP_SIZE, /* 783 .. 825 MHz: 3 */ ++ 825000 / TUNE_STEP_SIZE, /* 825 .. 865 MHz: 2 */ ++ 865000 / TUNE_STEP_SIZE, /* 865 .. 905 MHz: 1 */ ++ 905000 / TUNE_STEP_SIZE /* 905+ MHz: 0 */ ++ } ++ } ++}; ++ ++typedef struct ++{ ++ Handle_t handle; ++ Handle_t hUserData; ++ UData_t address; ++ UData_t version; ++ UData_t tuner_id; ++ UData_t f_Ref; ++ UData_t f_Step; ++ UData_t f_in; ++ UData_t f_LO; ++ UData_t f_bw; ++ UData_t band; ++ UData_t num_regs; ++ U8Data RC2_Value; ++ U8Data RC2_Nominal; ++ U8Data reg[END_REGS]; ++ ++ MT2266_XFreqs_t xfreqs; ++ ++} MT2266_Info_t; ++ ++static UData_t nMaxTuners = MT2266_CNT; ++static MT2266_Info_t MT2266_Info[MT2266_CNT]; ++static MT2266_Info_t *Avail[MT2266_CNT]; ++static UData_t nOpenTuners = 0; ++ ++/* ++** Constants used to write a minimal set of registers when changing bands. ++** If the user wants a total reset, they should call MT2266_Open() again. ++** Skip 01, 02, 03, 04 (get overwritten anyways) ++** Write 05 ++** Skip 06 - 18 ++** Write 19 (diff for L-Band) ++** Skip 1A 1B 1C ++** Write 1D - 2B ++** Skip 2C - 3C ++*/ ++ ++static U8Data MT2266_VHF_defaults1[] = ++{ ++ 0x05, /* address 0xC0, reg 0x05 */ ++ 0x04, /* Reg 0x05 LBANDen = 1 (that's right)*/ ++}; ++static U8Data MT2266_VHF_defaults2[] = ++{ ++ 0x19, /* address 0xC0, reg 0x19 */ ++ 0x61, /* Reg 0x19 CAPto = 3*/ ++}; ++static U8Data MT2266_VHF_defaults3[] = ++{ ++ 0x1D, /* address 0xC0, reg 0x1D */ ++ 0xFE, /* reg 0x1D */ ++ 0x00, /* reg 0x1E */ ++ 0x00, /* reg 0x1F */ ++ 0xB4, /* Reg 0x20 GPO = 1*/ ++ 0x03, /* Reg 0x21 LBIASen = 1, UBIASen = 1*/ ++ 0xA5, /* Reg 0x22 */ ++ 0xA5, /* Reg 0x23 */ ++ 0xA5, /* Reg 0x24 */ ++ 0xA5, /* Reg 0x25 */ ++ 0x82, /* Reg 0x26 CASCM = b0001 (bits reversed)*/ ++ 0xAA, /* Reg 0x27 */ ++ 0xF1, /* Reg 0x28 */ ++ 0x17, /* Reg 0x29 */ ++ 0x80, /* Reg 0x2A MIXbiasen = 1*/ ++ 0x1F, /* Reg 0x2B */ ++}; ++ ++static MT2266_DefaultsList MT2266_VHF_defaults = { ++ DEF_LIST_ENTRY(MT2266_VHF_defaults1), ++ DEF_LIST_ENTRY(MT2266_VHF_defaults2), ++ DEF_LIST_ENTRY(MT2266_VHF_defaults3), ++ END_DEF_LIST ++}; ++ ++static U8Data MT2266_UHF_defaults1[] = ++{ ++ 0x05, /* address 0xC0, reg 0x05 */ ++ 0x52, /* Reg 0x05 */ ++}; ++static U8Data MT2266_UHF_defaults2[] = ++{ ++ 0x19, /* address 0xC0, reg 0x19 */ ++ 0x61, /* Reg 0x19 CAPto = 3*/ ++}; ++static U8Data MT2266_UHF_defaults3[] = ++{ ++ 0x1D, /* address 0xC0, reg 0x1D */ ++ 0xDC, /* Reg 0x1D */ ++ 0x00, /* Reg 0x1E */ ++ 0x0A, /* Reg 0x1F */ ++ 0xD4, /* Reg 0x20 GPO = 1*/ ++ 0x03, /* Reg 0x21 LBIASen = 1, UBIASen = 1*/ ++ 0x64, /* Reg 0x22 */ ++ 0x64, /* Reg 0x23 */ ++ 0x64, /* Reg 0x24 */ ++ 0x64, /* Reg 0x25 */ ++ 0x22, /* Reg 0x26 CASCM = b0100 (bits reversed)*/ ++ 0xAA, /* Reg 0x27 */ ++ 0xF2, /* Reg 0x28 */ ++ 0x1E, /* Reg 0x29 */ ++ 0x80, /* Reg 0x2A MIXbiasen = 1*/ ++ 0x14, /* Reg 0x2B */ ++}; ++ ++static MT2266_DefaultsList MT2266_UHF_defaults = { ++ DEF_LIST_ENTRY(MT2266_UHF_defaults1), ++ DEF_LIST_ENTRY(MT2266_UHF_defaults2), ++ DEF_LIST_ENTRY(MT2266_UHF_defaults3), ++ END_DEF_LIST ++}; ++ ++ ++static UData_t UncheckedSet(MT2266_Info_t* pInfo, ++ U8Data reg, ++ U8Data val); ++ ++static UData_t UncheckedGet(MT2266_Info_t* pInfo, ++ U8Data reg, ++ U8Data* val); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_Open ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: MT2266_Addr - Serial bus address of the tuner. ++** hMT2266 - Tuner handle passed back. ++** hUserData - User-defined data, if needed for the ++** MT_ReadSub() & MT_WriteSub functions. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_COMM_ERR - Serial bus communications error ++** MT_ARG_NULL - Null pointer argument passed ++** MT_TUNER_CNT_ERR - Too many tuners open ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-01-2006 RSK Ver 1.02: Initialize Crossover Tables to Default ++** ++******************************************************************************/ ++UData_t MT2266_Open(UData_t MT2266_Addr, ++ Handle_t* hMT2266, ++ Handle_t hUserData) ++{ ++ UData_t status = MT_OK; /* Status to be returned. */ ++ SData_t i, j; ++ MT2266_Info_t* pInfo = MT_NULL; ++ ++ ++ /* Check the argument before using */ ++ if (hMT2266 == MT_NULL) ++ return MT_ARG_NULL; ++ *hMT2266 = MT_NULL; ++ ++ /* ++ ** If this is our first tuner, initialize the address fields and ++ ** the list of available control blocks. ++ */ ++ if (nOpenTuners == 0) ++ { ++ for (i=MT2266_CNT-1; i>=0; i--) ++ { ++ MT2266_Info[i].handle = MT_NULL; ++ MT2266_Info[i].address =MAX_UDATA; ++ MT2266_Info[i].hUserData = MT_NULL; ++ ++ /* Reset the UHF Crossover Frequency tables on open/init. */ ++ for (j=0; j< MT2266_NUM_XFREQS; j++ ) ++ { ++ MT2266_Info[i].xfreqs.xfreq[MT2266_UHF0][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0][j]; ++ MT2266_Info[i].xfreqs.xfreq[MT2266_UHF1][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1][j]; ++ MT2266_Info[i].xfreqs.xfreq[MT2266_UHF0_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0_ATTEN][j]; ++ MT2266_Info[i].xfreqs.xfreq[MT2266_UHF1_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1_ATTEN][j]; ++ } ++ ++ Avail[i] = &MT2266_Info[i]; ++ } ++ } ++ ++ /* ++ ** Look for an existing MT2266_State_t entry with this address. ++ */ ++ for (i=MT2266_CNT-1; i>=0; i--) ++ { ++ /* ++ ** If an open'ed handle provided, we'll re-initialize that structure. ++ ** ++ ** We recognize an open tuner because the address and hUserData are ++ ** the same as one that has already been opened ++ */ ++ if ((MT2266_Info[i].address == MT2266_Addr) && ++ (MT2266_Info[i].hUserData == hUserData)) ++ { ++ pInfo = &MT2266_Info[i]; ++ break; ++ } ++ } ++ ++ /* If not found, choose an empty spot. */ ++ if (pInfo == MT_NULL) ++ { ++ /* Check to see that we're not over-allocating. */ ++ if (nOpenTuners == MT2266_CNT) ++ return MT_TUNER_CNT_ERR; ++ ++ /* Use the next available block from the list */ ++ pInfo = Avail[nOpenTuners]; ++ nOpenTuners++; ++ } ++ ++ pInfo->handle = (Handle_t) pInfo; ++ pInfo->hUserData = hUserData; ++ pInfo->address = MT2266_Addr; ++ ++// status |= MT2266_ReInit((Handle_t) pInfo); ++ ++ if (MT_IS_ERROR(status)) ++ MT2266_Close((Handle_t) pInfo); ++ else ++ *hMT2266 = pInfo->handle; ++ ++ return (status); ++} ++ ++ ++static UData_t IsValidHandle(MT2266_Info_t* handle) ++{ ++ return ((handle != MT_NULL) && (handle->handle == handle)) ? 1 : 0; ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_Close ++** ++** Description: Release the handle to the tuner. ++** ++** Parameters: hMT2266 - Handle to the MT2266 tuner ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++******************************************************************************/ ++UData_t MT2266_Close(Handle_t hMT2266) ++{ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) hMT2266; ++ ++ if (!IsValidHandle(pInfo)) ++ return MT_INV_HANDLE; ++ ++ /* Remove the tuner from our list of tuners */ ++ pInfo->handle = MT_NULL; ++ pInfo->address = MAX_UDATA; ++ pInfo->hUserData = MT_NULL; ++ nOpenTuners--; ++ Avail[nOpenTuners] = pInfo; /* Return control block to available list */ ++ ++ return MT_OK; ++} ++ ++ ++/****************************************************************************** ++** ++** Name: Run_BB_RC_Cal2 ++** ++** Description: Run Base Band RC Calibration (Method 2) ++** MT2266 B0 only, others return MT_OK ++** ++** Parameters: hMT2266 - Handle to the MT2266 tuner ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++******************************************************************************/ ++static UData_t Run_BB_RC_Cal2(Handle_t h) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data tmp_rcc; ++ U8Data dumy; ++ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ /* ++ ** Set the crystal frequency in the calibration register ++ ** and enable RC calibration #2 ++ */ ++ PREFETCH(MT2266_RCC_CTRL, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ tmp_rcc = pInfo->reg[MT2266_RCC_CTRL]; ++ if (pInfo->f_Ref < (36000000 /*/ TUNE_STEP_SIZE*/)) ++ tmp_rcc = (tmp_rcc & 0xDF) | 0x10; ++ else ++ tmp_rcc |= 0x30; ++ status |= UncheckedSet(pInfo, MT2266_RCC_CTRL, tmp_rcc); ++ ++ /* Read RC Calibration value */ ++ status |= UncheckedGet(pInfo, MT2266_STATUS_4, &dumy); ++ ++ /* Disable RC Cal 2 */ ++ status |= UncheckedSet(pInfo, MT2266_RCC_CTRL, pInfo->reg[MT2266_RCC_CTRL] & 0xEF); ++ ++ /* Store RC Cal 2 value */ ++ pInfo->RC2_Value = pInfo->reg[MT2266_STATUS_4]; ++ ++ if (pInfo->f_Ref < (36000000 /*/ TUNE_STEP_SIZE*/)) ++ pInfo->RC2_Nominal = (U8Data) ((pInfo->f_Ref + 77570) / 155139); ++ else ++ pInfo->RC2_Nominal = (U8Data) ((pInfo->f_Ref + 93077) / 186154); ++ ++ return (status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: Set_BBFilt ++** ++** Description: Set Base Band Filter bandwidth ++** Based on SRO frequency & BB RC Calibration ++** User stores channel bw as 5-8 MHz. This routine ++** calculates a 3 dB corner bw based on 1/2 the bandwidth ++** and a bandwidth related constant. ++** ++** Parameters: hMT2266 - Handle to the MT2266 tuner ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++******************************************************************************/ ++static UData_t Set_BBFilt(Handle_t h) ++{ ++ UData_t f_3dB_bw; ++ U8Data BBFilt = 0; ++ U8Data Sel = 0; ++ SData_t TmpFilt; ++ SData_t i; ++ UData_t status = MT_OK; /* Status to be returned */ ++ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ /* Check RC2_Value value */ ++ if(pInfo->RC2_Value == 0) ++ return MT_UNKNOWN; ++ ++ /* ++ ** Convert the channel bandwidth into a 3 dB bw by dividing it by 2 ++ ** and subtracting 300, 250, 200, or 0 kHz based on 8, 7, 6, 5 MHz ++ ** channel bandwidth. ++ */ ++ f_3dB_bw = (pInfo->f_bw / 2); /* bw -> bw/2 */ ++ if (pInfo->f_bw > 7500000) ++ { ++ /* >3.75 MHz corner */ ++ f_3dB_bw -= 300000; ++ Sel = 0x00; ++ TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 81; ++ } ++ else if (pInfo->f_bw > 6500000) ++ { ++ /* >3.25 MHz .. 3.75 MHz corner */ ++ f_3dB_bw -= 250000; ++ Sel = 0x00; ++ TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 81; ++ } ++ else if (pInfo->f_bw > 5500000) ++ { ++ /* >2.75 MHz .. 3.25 MHz corner */ ++ f_3dB_bw -= 200000; ++ Sel = 0x80; ++ TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 113; ++ } ++ else ++ { ++ /* <= 2.75 MHz corner */ ++ Sel = 0xC0; ++ TmpFilt = ((429916107 / pInfo->RC2_Value) * pInfo->RC2_Nominal) / f_3dB_bw - 129; ++ } ++ ++ if (TmpFilt > 63) ++ TmpFilt = 63; ++ else if (TmpFilt < 0) ++ TmpFilt = 0; ++ BBFilt = ((U8Data) TmpFilt) | Sel; ++ ++ for ( i = MT2266_BBFILT_1; i <= MT2266_BBFILT_8; i++ ) ++ pInfo->reg[i] = BBFilt; ++ ++ if (MT_NO_ERROR(status)) ++ status |= MT2266_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ MT2266_BBFILT_1, ++ &pInfo->reg[MT2266_BBFILT_1], ++ 8); ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetLocked ++** ++** Description: Checks to see if the PLL is locked. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_GetLocked(Handle_t h) ++{ ++ const UData_t nMaxWait = 200; /* wait a maximum of 200 msec */ ++ const UData_t nPollRate = 2; /* poll status bits every 2 ms */ ++ const UData_t nMaxLoops = nMaxWait / nPollRate; ++ UData_t status = MT_OK; /* Status to be returned */ ++ UData_t nDelays = 0; ++ U8Data statreg; ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ if (IsValidHandle(pInfo) == 0) ++ return MT_INV_HANDLE; ++ ++ do ++ { ++ status |= UncheckedGet(pInfo, MT2266_STATUS_1, &statreg); ++ ++ if ((MT_IS_ERROR(status)) || ((statreg & 0x40) == 0x40)) ++ return (status); ++ ++ MT2266_Sleep(pInfo->hUserData, nPollRate); /* Wait between retries */ ++ } ++ while (++nDelays < nMaxLoops); ++ ++ if ((statreg & 0x40) != 0x40) ++ status |= MT_DNC_UNLOCK; ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetParam ++** ++** Description: Gets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm - mostly for testing purposes. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2266_Param) ++** pValue - ptr to returned value ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2266_IC_ADDR Serial Bus address of this tuner ++** MT2266_MAX_OPEN Max number of MT2266's that can be open ++** MT2266_NUM_OPEN Number of MT2266's currently open ++** MT2266_NUM_REGS Number of tuner registers ++** MT2266_SRO_FREQ crystal frequency ++** MT2266_STEPSIZE minimum tuning step size ++** MT2266_INPUT_FREQ input center frequency ++** MT2266_LO_FREQ LO Frequency ++** MT2266_OUTPUT_BW Output channel bandwidth ++** MT2266_RC2_VALUE Base band filter cal RC code (method 2) ++** MT2266_RC2_NOMINAL Base band filter nominal cal RC code ++** MT2266_RF_ADC RF attenuator A/D readback ++** MT2266_RF_ATTN RF attenuation (0-255) ++** MT2266_RF_EXT External control of RF atten ++** MT2266_LNA_GAIN LNA gain setting (0-15) ++** MT2266_BB_ADC BB attenuator A/D readback ++** MT2266_BB_ATTN Baseband attenuation (0-255) ++** MT2266_BB_EXT External control of BB atten ++** ++** Usage: status |= MT2266_GetParam(hMT2266, ++** MT2266_OUTPUT_BW, ++** &f_bw); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetParam, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_GetParam(Handle_t h, ++ MT2266_Param param, ++ UData_t* pValue) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data tmp; ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ if (pValue == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ switch (param) ++ { ++ /* Serial Bus address of this tuner */ ++ case MT2266_IC_ADDR: ++ *pValue = pInfo->address; ++ break; ++ ++ /* Max # of MT2266's allowed to be open */ ++ case MT2266_MAX_OPEN: ++ *pValue = nMaxTuners; ++ break; ++ ++ /* # of MT2266's open */ ++ case MT2266_NUM_OPEN: ++ *pValue = nOpenTuners; ++ break; ++ ++ /* Number of tuner registers */ ++ case MT2266_NUM_REGS: ++ *pValue = Num_Registers; ++ break; ++ ++ /* crystal frequency */ ++ case MT2266_SRO_FREQ: ++ *pValue = pInfo->f_Ref; ++ break; ++ ++ /* minimum tuning step size */ ++ case MT2266_STEPSIZE: ++ *pValue = pInfo->f_Step; ++ break; ++ ++ /* input center frequency */ ++ case MT2266_INPUT_FREQ: ++ *pValue = pInfo->f_in; ++ break; ++ ++ /* LO Frequency */ ++ case MT2266_LO_FREQ: ++ *pValue = pInfo->f_LO; ++ break; ++ ++ /* Output Channel Bandwidth */ ++ case MT2266_OUTPUT_BW: ++ *pValue = pInfo->f_bw; ++ break; ++ ++ /* Base band filter cal RC code */ ++ case MT2266_RC2_VALUE: ++ *pValue = (UData_t) pInfo->RC2_Value; ++ break; ++ ++ /* Base band filter nominal cal RC code */ ++ case MT2266_RC2_NOMINAL: ++ *pValue = (UData_t) pInfo->RC2_Nominal; ++ break; ++ ++ /* RF attenuator A/D readback */ ++ case MT2266_RF_ADC: ++ status |= UncheckedGet(pInfo, MT2266_STATUS_2, &tmp); ++ if (MT_NO_ERROR(status)) ++ *pValue = (UData_t) tmp; ++ break; ++ ++ /* BB attenuator A/D readback */ ++ case MT2266_BB_ADC: ++ status |= UncheckedGet(pInfo, MT2266_STATUS_3, &tmp); ++ if (MT_NO_ERROR(status)) ++ *pValue = (UData_t) tmp; ++ break; ++ ++ /* RF attenuator setting */ ++ case MT2266_RF_ATTN: ++ PREFETCH(MT2266_RSVD_1F, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ if (MT_NO_ERROR(status)) ++ *pValue = pInfo->reg[MT2266_RSVD_1F]; ++ break; ++ ++ /* BB attenuator setting */ ++ case MT2266_BB_ATTN: ++ PREFETCH(MT2266_RSVD_2C, 3); /* Fetch register(s) if __NO_CACHE__ defined */ ++ *pValue = pInfo->reg[MT2266_RSVD_2C] ++ + pInfo->reg[MT2266_RSVD_2D] ++ + pInfo->reg[MT2266_RSVD_2E] - 3; ++ break; ++ ++ /* RF external / internal atten control */ ++ case MT2266_RF_EXT: ++ PREFETCH(MT2266_GPO, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ *pValue = ((pInfo->reg[MT2266_GPO] & 0x40) != 0x00); ++ break; ++ ++ /* BB external / internal atten control */ ++ case MT2266_BB_EXT: ++ PREFETCH(MT2266_RSVD_33, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ *pValue = ((pInfo->reg[MT2266_RSVD_33] & 0x10) != 0x00); ++ break; ++ ++ /* LNA gain setting (0-15) */ ++ case MT2266_LNA_GAIN: ++ PREFETCH(MT2266_IGAIN, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ *pValue = ((pInfo->reg[MT2266_IGAIN] & 0x3C) >> 2); ++ break; ++ ++ case MT2266_EOP: ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ } ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION - DO NOT USE OUTSIDE OF mt2266.c ++** ++** Name: UncheckedGet ++** ++** Description: Gets an MT2266 register with minimal checking ++** ++** NOTE: This is a local function that performs the same ++** steps as the MT2266_GetReg function that is available ++** in the external API. It does not do any of the standard ++** error checking that the API function provides and should ++** not be called from outside this file. ++** ++** Parameters: *pInfo - Tuner control structure ++** reg - MT2266 register/subaddress location ++** *val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2266. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++static UData_t UncheckedGet(MT2266_Info_t* pInfo, ++ U8Data reg, ++ U8Data* val) ++{ ++ UData_t status; /* Status to be returned */ ++ ++#if defined(_DEBUG) ++ status = MT_OK; ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (val == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_IS_ERROR(status)) ++ return(status); ++#endif ++ ++ status = MT2266_ReadSub(pInfo->hUserData, pInfo->address, reg, &pInfo->reg[reg], 1); ++ ++ if (MT_NO_ERROR(status)) ++ *val = pInfo->reg[reg]; ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetReg ++** ++** Description: Gets an MT2266 register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** reg - MT2266 register/subaddress location ++** *val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2266. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_GetReg(Handle_t h, ++ U8Data reg, ++ U8Data* val) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (val == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedGet(pInfo, reg, val); ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetUHFXFreqs ++** ++** Description: Retrieves the specified set of UHF Crossover Frequencies ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: MT2266_Freq_Set tmpFreqs; ++** status = MT2266_GetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** if (status & MT_ARG_RANGE) ++** // error, Invalid UHF Crossover Frequency Set requested. ++** else ++** for( int i = 0; i < MT2266_NUM_XFREQS; i++ ) ++** . . . ++** ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_RANGE - freq_type is out of range. ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: freqs_buffer *must* be defined of type MT2266_Freq_Set ++** to assure sufficient space allocation! ++** ++** USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetUHFXFreqs ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 10-26-2006 RSK Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetUHFXFreqs(Handle_t h, ++ MT2266_UHFXFreq_Type freq_type, ++ MT2266_XFreq_Set freqs_buffer) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ ++ if (freq_type >= MT2266_NUMBER_OF_XFREQ_SETS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ int i; ++ ++ for( i = 0; i < MT2266_NUM_XFREQS; i++ ) ++ { ++ freqs_buffer[i] = pInfo->xfreqs.xfreq[ freq_type ][i] * TUNE_STEP_SIZE / 1000; ++ } ++ } ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetUserData ++** ++** Description: Gets the user-defined data item. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** The hUserData parameter is a user-specific argument ++** that is stored internally with the other tuner- ++** specific information. ++** ++** For example, if additional arguments are needed ++** for the user to identify the device communicating ++** with the tuner, this argument can be used to supply ++** the necessary information. ++** ++** The hUserData parameter is initialized in the tuner's ++** Open function to NULL. ++** ++** See Also: MT2266_SetUserData, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_GetUserData(Handle_t h, ++ Handle_t* hUserData) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ ++ if (hUserData == MT_NULL) ++ status |= MT_ARG_NULL; ++ ++ if (MT_NO_ERROR(status)) ++ *hUserData = pInfo->hUserData; ++ ++ return (status); ++} ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_ReInit ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 06-08-2006 JWS Ver 1.01: Corrected problem with tuner ID check ++** N/A 11-01-2006 RSK Ver 1.02: Initialize XFreq Tables to Default ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification ++** ++******************************************************************************/ ++UData_t MT2266_ReInit(Handle_t h) ++{ ++ int j; ++ ++ U8Data MT2266_Init_Defaults1[] = ++ { ++ 0x01, /* Start w/register 0x01 */ ++ 0x00, /* Reg 0x01 */ ++ 0x00, /* Reg 0x02 */ ++ 0x28, /* Reg 0x03 */ ++ 0x00, /* Reg 0x04 */ ++ 0x52, /* Reg 0x05 */ ++ 0x99, /* Reg 0x06 */ ++ 0x3F, /* Reg 0x07 */ ++ }; ++ ++ U8Data MT2266_Init_Defaults2[] = ++ { ++ 0x17, /* Start w/register 0x17 */ ++ 0x6D, /* Reg 0x17 */ ++ 0x71, /* Reg 0x18 */ ++ 0x61, /* Reg 0x19 */ ++ 0xC0, /* Reg 0x1A */ ++ 0xBF, /* Reg 0x1B */ ++ 0xFF, /* Reg 0x1C */ ++ 0xDC, /* Reg 0x1D */ ++ 0x00, /* Reg 0x1E */ ++ 0x0A, /* Reg 0x1F */ ++ 0xD4, /* Reg 0x20 */ ++ 0x03, /* Reg 0x21 */ ++ 0x64, /* Reg 0x22 */ ++ 0x64, /* Reg 0x23 */ ++ 0x64, /* Reg 0x24 */ ++ 0x64, /* Reg 0x25 */ ++ 0x22, /* Reg 0x26 */ ++ 0xAA, /* Reg 0x27 */ ++ 0xF2, /* Reg 0x28 */ ++ 0x1E, /* Reg 0x29 */ ++ 0x80, /* Reg 0x2A */ ++ 0x14, /* Reg 0x2B */ ++ 0x01, /* Reg 0x2C */ ++ 0x01, /* Reg 0x2D */ ++ 0x01, /* Reg 0x2E */ ++ 0x01, /* Reg 0x2F */ ++ 0x01, /* Reg 0x30 */ ++ 0x01, /* Reg 0x31 */ ++ 0x7F, /* Reg 0x32 */ ++ 0x5E, /* Reg 0x33 */ ++ 0x3F, /* Reg 0x34 */ ++ 0xFF, /* Reg 0x35 */ ++ 0xFF, /* Reg 0x36 */ ++ 0xFF, /* Reg 0x37 */ ++ 0x00, /* Reg 0x38 */ ++ 0x77, /* Reg 0x39 */ ++ 0x0F, /* Reg 0x3A */ ++ 0x2D, /* Reg 0x3B */ ++ }; ++ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ U8Data BBVref; ++ U8Data tmpreg = 0; ++ U8Data statusreg = 0; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ /* Read the Part/Rev code from the tuner */ ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedGet(pInfo, MT2266_PART_REV, &tmpreg); ++ if (MT_NO_ERROR(status) && (tmpreg != 0x85)) // MT226? B0 ++ status |= MT_TUNER_ID_ERR; ++ else ++ { ++ /* ++ ** Read the status register 5 ++ */ ++ tmpreg = pInfo->reg[MT2266_RSVD_11] |= 0x03; ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedSet(pInfo, MT2266_RSVD_11, tmpreg); ++ tmpreg &= ~(0x02); ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedSet(pInfo, MT2266_RSVD_11, tmpreg); ++ ++ /* Get and store the status 5 register value */ ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedGet(pInfo, MT2266_STATUS_5, &statusreg); ++ ++ /* MT2266 */ ++ if (MT_IS_ERROR(status) || ((statusreg & 0x30) != 0x30)) ++ status |= MT_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */ ++ } ++ ++ if (MT_NO_ERROR(status)) ++ { ++ /* Initialize the tuner state. Hold off on f_in and f_LO */ ++ pInfo->version = VERSION; ++ pInfo->tuner_id = pInfo->reg[MT2266_PART_REV]; ++ pInfo->f_Ref = REF_FREQ; ++ pInfo->f_Step = TUNE_STEP_SIZE * 1000; /* kHz -> Hz */ ++ pInfo->f_in = UHF_DEFAULT_FREQ; ++ pInfo->f_LO = UHF_DEFAULT_FREQ; ++ pInfo->f_bw = OUTPUT_BW; ++ pInfo->band = MT2266_UHF_BAND; ++ pInfo->num_regs = END_REGS; ++ ++ /* Reset the UHF Crossover Frequency tables on open/init. */ ++ for (j=0; j< MT2266_NUM_XFREQS; j++ ) ++ { ++ pInfo->xfreqs.xfreq[MT2266_UHF0][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0][j]; ++ pInfo->xfreqs.xfreq[MT2266_UHF1][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1][j]; ++ pInfo->xfreqs.xfreq[MT2266_UHF0_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF0_ATTEN][j]; ++ pInfo->xfreqs.xfreq[MT2266_UHF1_ATTEN][j] = MT2266_default_XFreqs.xfreq[MT2266_UHF1_ATTEN][j]; ++ } ++ ++ /* Write the default values to the tuner registers. Default mode is UHF */ ++ status |= MT2266_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ MT2266_Init_Defaults1[0], ++ &MT2266_Init_Defaults1[1], ++ sizeof(MT2266_Init_Defaults1)/sizeof(U8Data)-1); ++ status |= MT2266_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ MT2266_Init_Defaults2[0], ++ &MT2266_Init_Defaults2[1], ++ sizeof(MT2266_Init_Defaults2)/sizeof(U8Data)-1); ++ } ++ ++ /* Read back all the registers from the tuner */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2266_ReadSub(pInfo->hUserData, pInfo->address, 0, &pInfo->reg[0], END_REGS); ++ } ++ ++ /* ++ ** Set reg[0x33] based on statusreg ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ BBVref = (((statusreg >> 6) + 2) & 0x03); ++ tmpreg = (pInfo->reg[MT2266_RSVD_33] & ~(0x60)) | (BBVref << 5); ++ status |= UncheckedSet(pInfo, MT2266_RSVD_33, tmpreg); ++ } ++ ++ /* Run the baseband filter calibration */ ++ if (MT_NO_ERROR(status)) ++ status |= Run_BB_RC_Cal2(h); ++ ++ /* Set the baseband filter bandwidth to the default */ ++ if (MT_NO_ERROR(status)) ++ status |= Set_BBFilt(h); ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetParam ++** ++** Description: Sets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm. You can override many of the tuning ++** algorithm defaults using this function. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2266_Param) ++** nValue - value to be set ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2266_SRO_FREQ crystal frequency ++** MT2266_STEPSIZE minimum tuning step size ++** MT2266_INPUT_FREQ Center of input channel ++** MT2266_OUTPUT_BW Output channel bandwidth ++** MT2266_RF_ATTN RF attenuation (0-255) ++** MT2266_RF_EXT External control of RF atten ++** MT2266_LNA_GAIN LNA gain setting (0-15) ++** MT2266_LNA_GAIN_DECR Decrement LNA Gain (arg=min) ++** MT2266_LNA_GAIN_INCR Increment LNA Gain (arg=max) ++** MT2266_BB_ATTN Baseband attenuation (0-255) ++** MT2266_BB_EXT External control of BB atten ++** MT2266_UHF_MAXSENS Set for UHF max sensitivity mode ++** MT2266_UHF_NORMAL Set for UHF normal mode ++** ++** Usage: status |= MT2266_SetParam(hMT2266, ++** MT2266_STEPSIZE, ++** 50000); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Invalid parameter requested ++** or set value out of range ++** or non-writable parameter ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_GetParam, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification for gcc ++** ++****************************************************************************/ ++UData_t MT2266_SetParam(Handle_t h, ++ MT2266_Param param, ++ UData_t nValue) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ U8Data tmpreg; ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ switch (param) ++ { ++ /* crystal frequency */ ++ case MT2266_SRO_FREQ: ++ pInfo->f_Ref = nValue; ++ if (pInfo->f_Ref < 22000000) ++ { ++ /* Turn off f_SRO divide by 2 */ ++ status |= UncheckedSet(pInfo, ++ MT2266_SRO_CTRL, ++ (U8Data) (pInfo->reg[MT2266_SRO_CTRL] &= 0xFE)); ++ } ++ else ++ { ++ /* Turn on f_SRO divide by 2 */ ++ status |= UncheckedSet(pInfo, ++ MT2266_SRO_CTRL, ++ (U8Data) (pInfo->reg[MT2266_SRO_CTRL] |= 0x01)); ++ } ++ status |= Run_BB_RC_Cal2(h); ++ if (MT_NO_ERROR(status)) ++ status |= Set_BBFilt(h); ++ break; ++ ++ /* minimum tuning step size */ ++ case MT2266_STEPSIZE: ++ pInfo->f_Step = nValue; ++ break; ++ ++ /* Width of output channel */ ++ case MT2266_OUTPUT_BW: ++ pInfo->f_bw = nValue; ++ status |= Set_BBFilt(h); ++ break; ++ ++ /* BB attenuation (0-255) */ ++ case MT2266_BB_ATTN: ++ if (nValue > 255) ++ status |= MT_ARG_RANGE; ++ else ++ { ++ UData_t BBA_Stage1; ++ UData_t BBA_Stage2; ++ UData_t BBA_Stage3; ++ ++ BBA_Stage3 = (nValue > 102) ? 103 : nValue + 1; ++ BBA_Stage2 = (nValue > 175) ? 75 : nValue + 2 - BBA_Stage3; ++ BBA_Stage1 = (nValue > 176) ? nValue - 175 : 1; ++ pInfo->reg[MT2266_RSVD_2C] = (U8Data) BBA_Stage1; ++ pInfo->reg[MT2266_RSVD_2D] = (U8Data) BBA_Stage2; ++ pInfo->reg[MT2266_RSVD_2E] = (U8Data) BBA_Stage3; ++ pInfo->reg[MT2266_RSVD_2F] = (U8Data) BBA_Stage1; ++ pInfo->reg[MT2266_RSVD_30] = (U8Data) BBA_Stage2; ++ pInfo->reg[MT2266_RSVD_31] = (U8Data) BBA_Stage3; ++ status |= MT2266_WriteSub(pInfo->hUserData, ++ pInfo->address, ++ MT2266_RSVD_2C, ++ &pInfo->reg[MT2266_RSVD_2C], ++ 6); ++ } ++ break; ++ ++ /* RF attenuation (0-255) */ ++ case MT2266_RF_ATTN: ++ if (nValue > 255) ++ status |= MT_ARG_RANGE; ++ else ++ status |= UncheckedSet(pInfo, MT2266_RSVD_1F, (U8Data) nValue); ++ break; ++ ++ /* RF external / internal atten control */ ++ case MT2266_RF_EXT: ++ if (nValue == 0) ++ tmpreg = pInfo->reg[MT2266_GPO] &= ~0x40; ++ else ++ tmpreg = pInfo->reg[MT2266_GPO] |= 0x40; ++ status |= UncheckedSet(pInfo, MT2266_GPO, tmpreg); ++ break; ++ ++ /* LNA gain setting (0-15) */ ++ case MT2266_LNA_GAIN: ++ if (nValue > 15) ++ status |= MT_ARG_RANGE; ++ else ++ { ++ tmpreg = (pInfo->reg[MT2266_IGAIN] & 0xC3) | ((U8Data)nValue << 2); ++ status |= UncheckedSet(pInfo, MT2266_IGAIN, tmpreg); ++ } ++ break; ++ ++ /* Decrement LNA Gain setting, argument is min LNA Gain setting */ ++ case MT2266_LNA_GAIN_DECR: ++ if (nValue > 15) ++ status |= MT_ARG_RANGE; ++ else ++ { ++ PREFETCH(MT2266_IGAIN, 1); ++ if (MT_NO_ERROR(status) && ((U8Data) ((pInfo->reg[MT2266_IGAIN] & 0x3C) >> 2) > (U8Data) nValue)) ++ status |= UncheckedSet(pInfo, MT2266_IGAIN, pInfo->reg[MT2266_IGAIN] - 0x04); ++ } ++ break; ++ ++ /* Increment LNA Gain setting, argument is max LNA Gain setting */ ++ case MT2266_LNA_GAIN_INCR: ++ if (nValue > 15) ++ status |= MT_ARG_RANGE; ++ else ++ { ++ PREFETCH(MT2266_IGAIN, 1); ++ if (MT_NO_ERROR(status) && ((U8Data) ((pInfo->reg[MT2266_IGAIN] & 0x3C) >> 2) < (U8Data) nValue)) ++ status |= UncheckedSet(pInfo, MT2266_IGAIN, pInfo->reg[MT2266_IGAIN] + 0x04); ++ } ++ break; ++ ++ /* BB external / internal atten control */ ++ case MT2266_BB_EXT: ++ if (nValue == 0) ++ tmpreg = pInfo->reg[MT2266_RSVD_33] &= ~0x08; ++ else ++ tmpreg = pInfo->reg[MT2266_RSVD_33] |= 0x08; ++ status |= UncheckedSet(pInfo, MT2266_RSVD_33, tmpreg); ++ break; ++ ++ /* Set for UHF max sensitivity mode */ ++ case MT2266_UHF_MAXSENS: ++ PREFETCH(MT2266_BAND_CTRL, 1); ++ if (MT_NO_ERROR(status) && ((pInfo->reg[MT2266_BAND_CTRL] & 0x30) == 0x10)) ++ status |= UncheckedSet(pInfo, MT2266_BAND_CTRL, pInfo->reg[MT2266_BAND_CTRL] ^ 0x30); ++ break; ++ ++ /* Set for UHF normal mode */ ++ case MT2266_UHF_NORMAL: ++ if (MT_NO_ERROR(status) && ((pInfo->reg[MT2266_BAND_CTRL] & 0x30) == 0x20)) ++ status |= UncheckedSet(pInfo, MT2266_BAND_CTRL, pInfo->reg[MT2266_BAND_CTRL] ^ 0x30); ++ break; ++ ++ /* These parameters are read-only */ ++ case MT2266_IC_ADDR: ++ case MT2266_MAX_OPEN: ++ case MT2266_NUM_OPEN: ++ case MT2266_NUM_REGS: ++ case MT2266_INPUT_FREQ: ++ case MT2266_LO_FREQ: ++ case MT2266_RC2_VALUE: ++ case MT2266_RF_ADC: ++ case MT2266_BB_ADC: ++ case MT2266_EOP: ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ } ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetPowerModes ++** ++** Description: Sets the bits in the MT2266_ENABLES register and the ++** SROsd bit in the MT2266_SROADC_CTRL register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** flags - Bit mask of flags to indicate enabled ++** bits. ++** ++** Usage: status = MT2266_SetPowerModes(hMT2266, flags); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** The bits in the MT2266_ENABLES register and the ++** SROsd bit are set according to the supplied flags. ++** ++** The pre-defined flags are as follows: ++** MT2266_SROen ++** MT2266_LOen ++** MT2266_ADCen ++** MT2266_PDen ++** MT2266_DCOCen ++** MT2266_BBen ++** MT2266_MIXen ++** MT2266_LNAen ++** MT2266_ALL_ENABLES ++** MT2266_NO_ENABLES ++** MT2266_SROsd ++** MT2266_SRO_NOT_sd ++** ++** ONLY the enable bits (or SROsd bit) specified in the ++** flags parameter will be set. Any flag which is not ++** included, will cause that bit to be disabled. ++** ++** The ALL_ENABLES, NO_ENABLES, and SRO_NOT_sd constants ++** are for convenience. The NO_ENABLES and SRO_NOT_sd ++** do not actually have to be included, but are provided ++** for clarity. ++** ++** See Also: MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_SetPowerModes(Handle_t h, ++ UData_t flags) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ U8Data tmpreg; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ PREFETCH(MT2266_SRO_CTRL, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ if (MT_NO_ERROR(status)) ++ { ++ if (flags & MT2266_SROsd) ++ tmpreg = pInfo->reg[MT2266_SRO_CTRL] |= 0x10; /* set the SROsd bit */ ++ else ++ tmpreg = pInfo->reg[MT2266_SRO_CTRL] &= 0xEF; /* clear the SROsd bit */ ++ status |= UncheckedSet(pInfo, MT2266_SRO_CTRL, tmpreg); ++ } ++ ++ PREFETCH(MT2266_ENABLES, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= UncheckedSet(pInfo, MT2266_ENABLES, (U8Data)(flags & 0xff)); ++ } ++ ++ return status; ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION - DO NOT USE OUTSIDE OF mt2266.c ++** ++** Name: UncheckedSet ++** ++** Description: Sets an MT2266 register. ++** ++** NOTE: This is a local function that performs the same ++** steps as the MT2266_SetReg function that is available ++** in the external API. It does not do any of the standard ++** error checking that the API function provides and should ++** not be called from outside this file. ++** ++** Parameters: *pInfo - Tuner control structure ++** reg - MT2266 register/subaddress location ++** val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Sets a register value without any preliminary checking for ++** valid handles or register numbers. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++static UData_t UncheckedSet(MT2266_Info_t* pInfo, ++ U8Data reg, ++ U8Data val) ++{ ++ UData_t status; /* Status to be returned */ ++ ++#if defined(_DEBUG) ++ status = MT_OK; ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_IS_ERROR(status)) ++ return (status); ++#endif ++ ++ status = MT2266_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1); ++ ++ if (MT_NO_ERROR(status)) ++ pInfo->reg[reg] = val; ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetReg ++** ++** Description: Sets an MT2266 register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** reg - MT2266 register/subaddress location ++** val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to override a default ++** register value ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++UData_t MT2266_SetReg(Handle_t h, ++ U8Data reg, ++ U8Data val) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status |= MT_INV_HANDLE; ++ ++ if (reg >= END_REGS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ status |= UncheckedSet(pInfo, reg, val); ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetUHFXFreqs ++** ++** Description: Assigns the specified set of UHF Crossover Frequencies ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: MT2266_Freq_Set tmpFreqs; ++** status = MT2266_GetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** ... ++** tmpFreqs[i] = ++** ... ++** status = MT2266_SetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** ++** if (status & MT_ARG_RANGE) ++** // error, Invalid UHF Crossover Frequency Set requested. ++** else ++** for( int i = 0; i < MT2266_NUM_XFREQS; i++ ) ++** . . . ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_RANGE - freq_type is out of range. ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: freqs_buffer *must* be defined of type MT2266_Freq_Set ++** to assure sufficient space allocation! ++** ++** USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetUHFXFreqs ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 10-26-2006 RSK Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetUHFXFreqs(Handle_t h, ++ MT2266_UHFXFreq_Type freq_type, ++ MT2266_XFreq_Set freqs_buffer) ++{ ++ UData_t status = MT_OK; /* Status to be returned */ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ status = MT_INV_HANDLE; ++ ++ if (freq_type >= MT2266_NUMBER_OF_XFREQ_SETS) ++ status |= MT_ARG_RANGE; ++ ++ if (MT_NO_ERROR(status)) ++ { ++ int i; ++ ++ for( i = 0; i < MT2266_NUM_XFREQS; i++ ) ++ { ++ pInfo->xfreqs.xfreq[ freq_type ][i] = freqs_buffer[i] * 1000 / TUNE_STEP_SIZE; ++ } ++ } ++ ++ return (status); ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION ++** ++** Name: RoundToStep ++** ++** Description: Rounds the given frequency to the closes f_Step value ++** given the tuner ref frequency.. ++** ++** ++** Parameters: freq - Frequency to be rounded (in Hz). ++** f_Step - Step size for the frequency (in Hz). ++** f_Ref - SRO frequency (in Hz). ++** ++** Returns: Rounded frequency. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** ++****************************************************************************/ ++static UData_t RoundToStep(UData_t freq, UData_t f_Step, UData_t f_ref) ++{ ++ return f_ref * (freq / f_ref) ++ + f_Step * (((freq % f_ref) + (f_Step / 2)) / f_Step); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: fLO_FractionalTerm ++** ++** Description: Calculates the portion contributed by FracN / denom. ++** ++** This function preserves maximum precision without ++** risk of overflow. It accurately calculates ++** f_ref * num / denom to within 1 HZ with fixed math. ++** ++** Parameters: num - Fractional portion of the multiplier ++** denom - denominator portion of the ratio ++** This routine successfully handles denom values ++** up to and including 2^18. ++** f_Ref - SRO frequency. This calculation handles ++** f_ref as two separate 14-bit fields. ++** Therefore, a maximum value of 2^28-1 ++** may safely be used for f_ref. This is ++** the genesis of the magic number "14" and the ++** magic mask value of 0x03FFF. ++** ++** Returns: f_ref * num / denom ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 12-20-2006 RSK Ver 1.04: Adding fLO_FractionalTerm() usage. ++** ++****************************************************************************/ ++static UData_t fLO_FractionalTerm( UData_t f_ref, ++ UData_t num, ++ UData_t denom ) ++{ ++ UData_t t1 = (f_ref >> 14) * num; ++ UData_t term1 = t1 / denom; ++ UData_t loss = t1 % denom; ++ UData_t term2 = ( ((f_ref & 0x00003FFF) * num + (loss<<14)) + (denom/2) ) / denom; ++ return ((term1 << 14) + term2); ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION ++** ++** Name: CalcLOMult ++** ++** Description: Calculates Integer divider value and the numerator ++** value for LO's FracN PLL. ++** ++** This function assumes that the f_LO and f_Ref are ++** evenly divisible by f_LO_Step. ++** ++** Parameters: Div - OUTPUT: Whole number portion of the multiplier ++** FracN - OUTPUT: Fractional portion of the multiplier ++** f_LO - desired LO frequency. ++** denom - LO FracN denominator value ++** f_Ref - SRO frequency. ++** ++** Returns: Recalculated LO frequency. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 12-20-2006 RSK Ver 1.04: Adding fLO_FractionalTerm() usage. ++** ++****************************************************************************/ ++static UData_t CalcLOMult(UData_t *Div, ++ UData_t *FracN, ++ UData_t f_LO, ++ UData_t denom, ++ UData_t f_Ref) ++{ ++ UData_t a, b, i; ++ const SData_t TwoNShift = 13; // bits to shift to obtain 2^n qty ++ const SData_t RoundShift = 18; // bits to shift before rounding ++ ++ /* Calculate the whole number portion of the divider */ ++ *Div = f_LO / f_Ref; ++ ++ /* ++ ** Calculate the FracN numerator 1 bit at a time. This keeps the ++ ** integer values from overflowing when large values are multiplied. ++ ** This loop calculates the fractional portion of F/20MHz accurate ++ ** to 32 bits. The 2^n factor is represented by the placement of ++ ** the value in the 32-bit word. Since we want as much accuracy ++ ** as possible, we'll leave it at the top of the word. ++ */ ++ *FracN = 0; ++ a = f_LO; ++ for (i=32; i>0; --i) ++ { ++ b = 2*(a % f_Ref); ++ *FracN = (*FracN * 2) + (b >= f_Ref); ++ a = b; ++ } ++ ++ /* ++ ** If the denominator is a 2^n - 1 value (the usual case) then the ++ ** value we really need is (F/20) * 2^n - (F/20). Shifting the ++ ** calculated (F/20) value to the right and subtracting produces ++ ** the desired result -- still accurate to 32 bits. ++ */ ++ if ((denom & 0x01) != 0) ++ *FracN -= (*FracN >> TwoNShift); ++ ++ /* ++ ** Now shift the result so that it is 1 bit bigger than we need, ++ ** use the low-order bit to round the remaining bits, and shift ++ ** to make the answer the desired size. ++ */ ++ *FracN >>= RoundShift; ++ *FracN = (*FracN & 0x01) + (*FracN >> 1); ++ ++ /* Check for rollover (cannot happen with 50 kHz step size) */ ++ if (*FracN == (denom | 1)) ++ { ++ *FracN = 0; ++ ++Div; ++ } ++ ++ ++ return (f_Ref * (*Div)) + fLO_FractionalTerm( f_Ref, *FracN, denom ); ++} ++ ++ ++/**************************************************************************** ++** LOCAL FUNCTION ++** ++** Name: GetCrossover ++** ++** Description: Determines the appropriate value in the set of ++** crossover frequencies. ++** ++** This function assumes that the crossover frequency table ++** ias been properly initialized in descending order. ++** ++** Parameters: f_in - The input frequency to use. ++** freqs - The array of crossover frequency entries. ++** ++** Returns: Index of crossover frequency band to use. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 10-27-2006 RSK Original ++** ++****************************************************************************/ ++static U8Data GetCrossover( UData_t f_in, UData_t* freqs ) ++{ ++ U8Data idx; ++ U8Data retVal = 0; ++ ++ for (idx=0; idx< (U8Data)MT2266_NUM_XFREQS; idx++) ++ { ++ if ( freqs[idx] >= f_in) ++ { ++ retVal = (U8Data)MT2266_NUM_XFREQS - idx; ++ break; ++ } ++ } ++ ++ return retVal; ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_ChangeFreq ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_FIN_RANGE - Input freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2266_Open BEFORE MT2266_ChangeFreq! ++** ++** MT_ReadSub - Read byte(s) of data from the two-wire-bus ++** MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2266_GetLocked - Checks to see if the PLL is locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-01-2006 RSK Ver 1.02: Added usage of UFILT0 and UFILT1. ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification ++** 118 05-09-2007 RSK Ver 1.05: Refactored to call _Tune() API. ++** ++****************************************************************************/ ++UData_t MT2266_ChangeFreq(Handle_t h, ++ UData_t f_in) /* RF input center frequency */ ++{ ++ return (MT2266_Tune(h, f_in)); ++} ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_Tune ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_FIN_RANGE - Input freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2266_Open BEFORE MT2266_Tune! ++** ++** MT_ReadSub - Read byte(s) of data from the two-wire-bus ++** MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2266_GetLocked - Checks to see if the PLL is locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-01-2006 RSK Ver 1.02: Added usage of UFILT0 and UFILT1. ++** N/A 11-29-2006 DAD Ver 1.03: Parenthesis clarification ++** 118 05-09-2007 RSK Ver 1.05: Adding Standard MTxxxx_Tune() API. ++** ++****************************************************************************/ ++UData_t MT2266_Tune(Handle_t h, ++ UData_t f_in) /* RF input center frequency */ ++{ ++ MT2266_Info_t* pInfo = (MT2266_Info_t*) h; ++ ++ UData_t status = MT_OK; /* status of operation */ ++ UData_t LO; /* LO register value */ ++ UData_t Num; /* Numerator for LO reg. value */ ++ UData_t ofLO; /* last time's LO frequency */ ++ UData_t ofin; /* last time's input frequency */ ++ U8Data LO_Band; /* LO Mode bits */ ++ UData_t s_fRef; /* Ref Freq scaled for LO Band */ ++ UData_t this_band; /* Band for the requested freq */ ++ UData_t SROx2; /* SRO times 2 */ ++ ++ /* Verify that the handle passed points to a valid tuner */ ++ if (IsValidHandle(pInfo) == 0) ++ return MT_INV_HANDLE; ++ ++ /* ++ ** Save original input and LO value ++ */ ++ ofLO = pInfo->f_LO; ++ ofin = pInfo->f_in; ++ ++ /* ++ ** Assign in the requested input value ++ */ ++ pInfo->f_in = f_in; ++ ++ /* ++ ** Get the SRO multiplier value ++ */ ++ SROx2 = (2 - (pInfo->reg[MT2266_SRO_CTRL] & 0x01)); ++ ++ /* Check f_Step value */ ++ if(pInfo->f_Step == 0) ++ return MT_UNKNOWN; ++ ++ /* Request an LO that is on a step size boundary */ ++ pInfo->f_LO = RoundToStep(f_in, pInfo->f_Step, pInfo->f_Ref); ++ ++ if (pInfo->f_LO < MIN_VHF_FREQ) ++ { ++ status |= MT_FIN_RANGE | MT_ARG_RANGE | MT_DNC_RANGE; ++ return status; /* Does not support frequencies below MIN_VHF_FREQ */ ++ } ++ else if (pInfo->f_LO <= MAX_VHF_FREQ) ++ { ++ /* VHF Band */ ++ s_fRef = pInfo->f_Ref * SROx2 / 4; ++ LO_Band = 0; ++ this_band = MT2266_VHF_BAND; ++ } ++ else if (pInfo->f_LO < MIN_UHF_FREQ) ++ { ++ status |= MT_FIN_RANGE | MT_ARG_RANGE | MT_DNC_RANGE; ++ return status; /* Does not support frequencies between MAX_VHF_FREQ & MIN_UHF_FREQ */ ++ } ++ else if (pInfo->f_LO <= MAX_UHF_FREQ) ++ { ++ /* UHF Band */ ++ s_fRef = pInfo->f_Ref * SROx2 / 2; ++ LO_Band = 1; ++ this_band = MT2266_UHF_BAND; ++ } ++ else ++ { ++ status |= MT_FIN_RANGE | MT_ARG_RANGE | MT_DNC_RANGE; ++ return status; /* Does not support frequencies above MAX_UHF_FREQ */ ++ } ++ ++ /* ++ ** Calculate the LO frequencies and the values to be placed ++ ** in the tuning registers. ++ */ ++ pInfo->f_LO = CalcLOMult(&LO, &Num, pInfo->f_LO, 8191, s_fRef); ++ ++ /* ++ ** If we have the same LO frequencies and we're already locked, ++ ** then just return without writing any registers. ++ */ ++ if ((ofLO == pInfo->f_LO) ++ && ((pInfo->reg[MT2266_STATUS_1] & 0x40) == 0x40)) ++ { ++ return (status); ++ } ++ ++ /* ++ ** Reset defaults here if we're tuning into a new band ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ if (this_band != pInfo->band) ++ { ++ MT2266_DefaultsEntry *defaults = MT_NULL; ++ switch (this_band) ++ { ++ case MT2266_VHF_BAND: ++ defaults = &MT2266_VHF_defaults[0]; ++ break; ++ case MT2266_UHF_BAND: ++ defaults = &MT2266_UHF_defaults[0]; ++ break; ++ default: ++ status |= MT_ARG_RANGE; ++ } ++ if ( MT_NO_ERROR(status)) ++ { ++ while (defaults->data && MT_NO_ERROR(status)) ++ { ++ status |= MT2266_WriteSub(pInfo->hUserData, pInfo->address, defaults->data[0], &defaults->data[1], defaults->cnt); ++ defaults++; ++ } ++ /* re-read the new registers into the cached values */ ++ status |= MT2266_ReadSub(pInfo->hUserData, pInfo->address, 0, &pInfo->reg[0], END_REGS); ++ pInfo->band = this_band; ++ } ++ } ++ } ++ ++ /* ++ ** Place all of the calculated values into the local tuner ++ ** register fields. ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ pInfo->reg[MT2266_LO_CTRL_1] = (U8Data)(Num >> 8); ++ pInfo->reg[MT2266_LO_CTRL_2] = (U8Data)(Num & 0xFF); ++ pInfo->reg[MT2266_LO_CTRL_3] = (U8Data)(LO & 0xFF); ++ ++ /* ++ ** Now write out the computed register values ++ */ ++ status |= MT2266_WriteSub(pInfo->hUserData, pInfo->address, MT2266_LO_CTRL_1, &pInfo->reg[MT2266_LO_CTRL_1], 3); ++ ++ if (pInfo->band == MT2266_UHF_BAND) ++ { ++ U8Data UFilt0 = 0; /* def when f_in > all */ ++ U8Data UFilt1 = 0; /* def when f_in > all */ ++ UData_t* XFreq0; ++ UData_t* XFreq1; ++ SData_t ClearTune_Fuse; ++ SData_t f_offset; ++ UData_t f_in_; ++ ++ PREFETCH(MT2266_BAND_CTRL, 2); /* Fetch register(s) if __NO_CACHE__ defined */ ++ PREFETCH(MT2266_STATUS_5, 1); /* Fetch register(s) if __NO_CACHE__ defined */ ++ ++ XFreq0 = (pInfo->reg[MT2266_BAND_CTRL] & 0x10) ? pInfo->xfreqs.xfreq[ MT2266_UHF0_ATTEN ] : pInfo->xfreqs.xfreq[ MT2266_UHF0 ]; ++ XFreq1 = (pInfo->reg[MT2266_BAND_CTRL] & 0x10) ? pInfo->xfreqs.xfreq[ MT2266_UHF1_ATTEN ] : pInfo->xfreqs.xfreq[ MT2266_UHF1 ]; ++ ++ ClearTune_Fuse = pInfo->reg[MT2266_STATUS_5] & 0x07; ++ f_offset = (10000000) * ((ClearTune_Fuse > 3) ? (ClearTune_Fuse - 8) : ClearTune_Fuse); ++ f_in_ = (f_in - f_offset) / 1000 / TUNE_STEP_SIZE; ++ ++ UFilt0 = GetCrossover( f_in_, XFreq0 ); ++ UFilt1 = GetCrossover( f_in_, XFreq1 ); ++ ++ /* If UFilt == 16, set UBANDen and set UFilt = 15 */ ++ if ( (UFilt0 == 16) || (UFilt1 == 16) ) ++ { ++ pInfo->reg[MT2266_BAND_CTRL] |= 0x01; ++ if( UFilt0 > 0 ) UFilt0--; ++ if( UFilt1 > 0 ) UFilt1--; ++ } ++ else ++ pInfo->reg[MT2266_BAND_CTRL] &= ~(0x01); ++ ++ pInfo->reg[MT2266_BAND_CTRL] = ++ (pInfo->reg[MT2266_BAND_CTRL] & 0x3F) | (LO_Band << 6); ++ ++ pInfo->reg[MT2266_CLEARTUNE] = (UFilt1 << 4) | UFilt0; ++ /* Write UBANDsel [05] & ClearTune [06] */ ++ status |= MT2266_WriteSub(pInfo->hUserData, pInfo->address, MT2266_BAND_CTRL, &pInfo->reg[MT2266_BAND_CTRL], 2); ++ } ++ } ++ ++ /* ++ ** Check for LO lock ++ */ ++ if (MT_NO_ERROR(status)) ++ { ++ status |= MT2266_GetLocked(h); ++ } ++ ++ return (status); ++} ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_mt2266.h b/drivers/drivers/media/dvb/dvb-usb/tuner_mt2266.h +--- a/drivers/media/dvb/dvb-usb/tuner_mt2266.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_mt2266.h 2016-04-02 19:17:52.148066045 -0300 +@@ -0,0 +1,1534 @@ ++#ifndef __TUNER_MT2266_H ++#define __TUNER_MT2266_H ++ ++/** ++ ++@file ++ ++@brief MT2266 tuner module declaration ++ ++One can manipulate MT2266 tuner through MT2266 module. ++MT2266 module is derived from tunerd module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_mt2266.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ MT2266_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthHz; ++ ++ ++ ... ++ ++ ++ ++ // Build MT2266 tuner module. ++ BuildMt2266Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0 // I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get MT2266 tuner extra module. ++ pTunerExtra = &(pTuner->Extra.Mt2266); ++ ++ // Open MT2266 handle. ++ pTunerExtra->OpenHandle(pTuner); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set MT2266 bandwidth. ++ pTunerExtra->SetBandwidthHz(pTuner, MT2266_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get MT2266 bandwidth. ++ pTunerExtra->GetBandwidthHz(pTuner, &BandwidthHz); ++ ++ ++ ++ ++ ++ // Close MT2266 handle. ++ pTunerExtra->CloseHandle(pTuner); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++// The following context is source code provided by Microtune. ++ ++ ++ ++ ++ ++// Microtune source code - mt_errordef.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_errordef.h ++** ++** Description: Definition of bits in status/error word used by various ++** MicroTuner control programs. ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_errordef.h,v 1.1 2006/06/22 20:18:12 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt_errordef.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 09-09-2004 JWS Original ++** 088 01-26-2005 DAD Added MT_TUNER_INIT_ERR. ++** N/A 12-09-2005 DAD Added MT_TUNER_TIMEOUT (info). ++** ++*****************************************************************************/ ++ ++/* ++** Note to users: DO NOT EDIT THIS FILE ++** ++** If you wish to rename any of the "user defined" bits, ++** it should be done in the user file that includes this ++** source file (e.g. mt_userdef.h) ++** ++*/ ++ ++ ++ ++/* ++** 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 ++** 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ++** M U <- Info Codes --> <# Spurs> < User> <----- Err Codes -----> ++** ++** 31 = MT_ERROR - Master Error Flag. If set, check Err Codes for reason. ++** 30 = MT_USER_ERROR - User-declared error flag. ++** 29 = Unused ++** 28 = Unused ++** 27 = MT_DNC_RANGE ++** 26 = MT_UPC_RANGE ++** 25 = MT_FOUT_RANGE ++** 24 = MT_FIN_OUT_OF_RANGE ++** 23 = MT_SPUR_PRESENT - Unavoidable spur in output ++** 22 = MT_TUNER_TIMEOUT ++** 21 = Unused ++** 20 = Unused ++** 19 = MT_SPUR_CNT_MASK (MSB) - Count of avoided spurs ++** 18 = MT_SPUR_CNT_MASK ++** 17 = MT_SPUR_CNT_MASK ++** 16 = MT_SPUR_CNT_MASK ++** 15 = MT_SPUR_CNT_MASK (LSB) ++** 14 = MT_USER_DEFINED4 - User-definable bit (see MT_Userdef.h) ++** 13 = MT_USER_DEFINED3 - User-definable bit (see MT_Userdef.h) ++** 12 = MT_USER_DEFINED2 - User-definable bit (see MT_Userdef.h) ++** 11 = MT_USER_DEFINED1 - User-definable bit (see MT_Userdef.h) ++** 10 = Unused ++** 9 = MT_TUNER_INIT_ERR - Tuner initialization error ++** 8 = MT_TUNER_ID_ERR - Tuner Part Code / Rev Code mismatches expected value ++** 7 = MT_TUNER_CNT_ERR - Attempt to open more than MT_TUNER_CNT tuners ++** 6 = MT_ARG_NULL - Null pointer passed as argument ++** 5 = MT_ARG_RANGE - Argument value out of range ++** 4 = MT_INV_HANDLE - Tuner handle is invalid ++** 3 = MT_COMM_ERR - Serial bus communications error ++** 2 = MT_DNC_UNLOCK - Downconverter PLL is unlocked ++** 1 = MT_UPC_UNLOCK - Upconverter PLL is unlocked ++** 0 = MT_UNKNOWN - Unknown error ++*/ ++#define MT_ERROR (1 << 31) ++#define MT_USER_ERROR (1 << 30) ++ ++/* Macro to be used to check for errors */ ++#define MT_IS_ERROR(s) (((s) >> 30) != 0) ++#define MT_NO_ERROR(s) (((s) >> 30) == 0) ++ ++ ++#define MT_OK (0x00000000) ++ ++/* Unknown error */ ++#define MT_UNKNOWN (0x80000001) ++ ++/* Error: Upconverter PLL is not locked */ ++#define MT_UPC_UNLOCK (0x80000002) ++ ++/* Error: Downconverter PLL is not locked */ ++#define MT_DNC_UNLOCK (0x80000004) ++ ++/* Error: Two-wire serial bus communications error */ ++#define MT_COMM_ERR (0x80000008) ++ ++/* Error: Tuner handle passed to function was invalid */ ++#define MT_INV_HANDLE (0x80000010) ++ ++/* Error: Function argument is invalid (out of range) */ ++#define MT_ARG_RANGE (0x80000020) ++ ++/* Error: Function argument (ptr to return value) was NULL */ ++#define MT_ARG_NULL (0x80000040) ++ ++/* Error: Attempt to open more than MT_TUNER_CNT tuners */ ++#define MT_TUNER_CNT_ERR (0x80000080) ++ ++/* Error: Tuner Part Code / Rev Code mismatches expected value */ ++#define MT_TUNER_ID_ERR (0x80000100) ++ ++/* Error: Tuner Initialization failure */ ++#define MT_TUNER_INIT_ERR (0x80000200) ++ ++/* User-definable fields (see mt_userdef.h) */ ++#define MT_USER_DEFINED1 (0x00001000) ++#define MT_USER_DEFINED2 (0x00002000) ++#define MT_USER_DEFINED3 (0x00004000) ++#define MT_USER_DEFINED4 (0x00008000) ++#define MT_USER_MASK (0x4000f000) ++#define MT_USER_SHIFT (12) ++ ++/* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */ ++#define MT_SPUR_CNT_MASK (0x001f0000) ++#define MT_SPUR_SHIFT (16) ++ ++/* Info: Tuner timeout waiting for condition */ ++#define MT_TUNER_TIMEOUT (0x00400000) ++ ++/* Info: Unavoidable LO-related spur may be present in the output */ ++#define MT_SPUR_PRESENT (0x00800000) ++ ++/* Info: Tuner input frequency is out of range */ ++#define MT_FIN_RANGE (0x01000000) ++ ++/* Info: Tuner output frequency is out of range */ ++#define MT_FOUT_RANGE (0x02000000) ++ ++/* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */ ++#define MT_UPC_RANGE (0x04000000) ++ ++/* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */ ++#define MT_DNC_RANGE (0x08000000) ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt_userdef.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt_userdef.h ++** ++** Description: User-defined data types needed by MicroTuner source code. ++** ++** Customers must provide the code for these functions ++** in the file "mt_userdef.c". ++** ++** Customers must verify that the typedef's in the ++** "Data Types" section are correct for their platform. ++** ++** Functions ++** Requiring ++** Implementation: MT_WriteSub ++** MT_ReadSub ++** MT_Sleep ++** ++** References: None ++** ++** Exports: None ++** ++** CVS ID: $Id: mt_userdef.h,v 1.1 2006/06/22 20:18:12 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt_userdef.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** 082 12-06-2004 JWS Multi-tuner support - requires MTxxxx_CNT ++** declarations ++** ++*****************************************************************************/ ++#if !defined( __MT_USERDEF_H ) ++#define __MT_USERDEF_H ++ ++//#include "mt_errordef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++/* ++** Data Types ++*/ ++typedef unsigned char U8Data; /* type corresponds to 8 bits */ ++typedef unsigned int UData_t; /* type must be at least 32 bits */ ++typedef int SData_t; /* type must be at least 32 bits */ ++typedef void * Handle_t; /* memory pointer type */ ++typedef double FData_t; /* floating point data type */ ++ ++#define MAX_UDATA (4294967295U) /* max value storable in UData_t */ ++ ++ ++/* ++** Define an MTxxxx_CNT macro for each type of tuner that will be built ++** into your application (e.g., MT2121, MT2060). MT_TUNER_CNT ++** must be set to the SUM of all of the MTxxxx_CNT macros. ++** ++** #define MT2050_CNT (1) ++** #define MT2060_CNT (1) ++** #define MT2111_CNT (1) ++** #define MT2121_CNT (3) ++*/ ++ ++ ++#if !defined( MT_TUNER_CNT ) ++#define MT_TUNER_CNT (1) /* total num of MicroTuner tuners */ ++#endif ++ ++/* ++** Optional user-defined Error/Info Codes (examples below) ++** ++** This is the area where you can define user-specific error/info return ++** codes to be returned by any of the functions you are responsible for ++** writing such as MT_WriteSub() and MT_ReadSub. There are four bits ++** available in the status field for your use. When set, these ++** bits will be returned in the status word returned by any tuner driver ++** call. If you OR in the MT_ERROR bit as well, the tuner driver code ++** will treat the code as an error. ++** ++** The following are a few examples of errors you can provide. ++** ++** Example 1: ++** You might check to see the hUserData handle is correct and issue ++** MY_USERDATA_INVALID which would be defined like this: ++** ++** #define MY_USERDATA_INVALID (MT_USER_ERROR | MT_USER_DEFINED1) ++** ++** ++** Example 2: ++** You might be able to provide more descriptive two-wire bus errors: ++** ++** #define NO_ACK (MT_USER_ERROR | MT_USER_DEFINED1) ++** #define NO_NACK (MT_USER_ERROR | MT_USER_DEFINED2) ++** #define BUS_BUSY (MT_USER_ERROR | MT_USER_DEFINED3) ++** ++** ++** Example 3: ++** You can also provide information (non-error) feedback: ++** ++** #define MY_INFO_1 (MT_USER_DEFINED1) ++** ++** ++** Example 4: ++** You can combine the fields together to make a multi-bit field. ++** This one can provide the tuner number based off of the addr ++** passed to MT_WriteSub or MT_ReadSub. It assumes that ++** MT_USER_DEFINED4 through MT_USER_DEFINED1 are contiguously. If ++** TUNER_NUM were OR'ed into the status word on an error, you could ++** use this to identify which tuner had the problem (and whether it ++** was during a read or write operation). ++** ++** #define TUNER_NUM ((addr & 0x07) >> 1) << MT_USER_SHIFT ++** ++*/ ++ ++/***************************************************************************** ++** ++** Name: MT_WriteSub ++** ++** Description: Write values to device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to write data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2266_WriteSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt); ++ ++ ++/***************************************************************************** ++** ++** Name: MT_ReadSub ++** ++** Description: Read values from device using a two-wire serial bus. ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** addr - device serial bus address (value passed ++** as parameter to MTxxxx_Open) ++** subAddress - serial bus sub-address (Register Address) ++** pData - pointer to the Data to be written to the ++** device ++** cnt - number of bytes/registers to be written ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** user-defined ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code for this ++** function to read data using the tuner's 2-wire serial ++** bus. ++** ++** The hUserData parameter is a user-specific argument. ++** If additional arguments are needed for the user's ++** serial bus read/write functions, this argument can be ++** used to supply the necessary information. ++** The hUserData parameter is initialized in the tuner's Open ++** function. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++UData_t MT2266_ReadSub(Handle_t hUserData, ++ UData_t addr, ++ U8Data subAddress, ++ U8Data *pData, ++ UData_t cnt); ++ ++ ++/***************************************************************************** ++** ++** Name: MT_Sleep ++** ++** Description: Delay execution for "nMinDelayTime" milliseconds ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** nMinDelayTime - Delay time in milliseconds ++** ++** Returns: None. ++** ++** Notes: This is a callback function that is called from the ++** the tuning algorithm. You MUST provide code that ++** blocks execution for the specified period of time. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 03-25-2004 DAD Original ++** ++*****************************************************************************/ ++void MT2266_Sleep(Handle_t hUserData, ++ UData_t nMinDelayTime); ++ ++ ++#if defined(MT2060_CNT) ++#if MT2060_CNT > 0 ++/***************************************************************************** ++** ++** Name: MT_TunerGain (for MT2060 only) ++** ++** Description: Measure the relative tuner gain using the demodulator ++** ++** Parameters: hUserData - User-specific I/O parameter that was ++** passed to tuner's Open function. ++** pMeas - Tuner gain (1/100 of dB scale). ++** ie. 1234 = 12.34 (dB) ++** ++** Returns: status: ++** MT_OK - No errors ++** user-defined errors could be set ++** ++** Notes: This is a callback function that is called from the ++** the 1st IF location routine. You MUST provide ++** code that measures the relative tuner gain in a dB ++** (not linear) scale. The return value is an integer ++** value scaled to 1/100 of a dB. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 06-16-2004 DAD Original ++** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name ++** better describes what this function does. ++** ++*****************************************************************************/ ++UData_t MT_TunerGain(Handle_t hUserData, ++ SData_t* pMeas); ++#endif ++#endif ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Microtune source code - mt2266.h ++ ++ ++ ++/***************************************************************************** ++** ++** Name: mt2266.h ++** ++** Copyright 2007 Microtune, Inc. All Rights Reserved ++** ++** This source code file contains confidential information and/or trade ++** secrets of Microtune, Inc. or its affiliates and is subject to the ++** terms of your confidentiality agreement with Microtune, Inc. or one of ++** its affiliates, as applicable. ++** ++*****************************************************************************/ ++ ++/***************************************************************************** ++** ++** Name: mt2266.h ++** ++** Description: Microtune MT2266 Tuner software interface. ++** Supports tuners with Part/Rev code: 0x85. ++** ++** Functions ++** Implemented: UData_t MT2266_Open ++** UData_t MT2266_Close ++** UData_t MT2266_ChangeFreq ++** UData_t MT2266_GetLocked ++** UData_t MT2266_GetParam ++** UData_t MT2266_GetReg ++** UData_t MT2266_GetUHFXFreqs ++** UData_t MT2266_GetUserData ++** UData_t MT2266_ReInit ++** UData_t MT2266_SetParam ++** UData_t MT2266_SetPowerModes ++** UData_t MT2266_SetReg ++** UData_t MT2266_SetUHFXFreqs ++** UData_t MT2266_Tune ++** ++** References: AN-00010: MicroTuner Serial Interface Application Note ++** MicroTune, Inc. ++** ++** Exports: None ++** ++** Dependencies: MT_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Read byte(s) of data from the two-wire bus. ++** ++** MT_WriteSub(hUserData, IC_Addr, subAddress, *pData, cnt); ++** - Write byte(s) of data to the two-wire bus. ++** ++** MT_Sleep(hUserData, nMinDelayTime); ++** - Delay execution for x milliseconds ++** ++** CVS ID: $Id: mt2266.h,v 1.3 2007/10/02 18:43:17 software Exp $ ++** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2266/mt2266.h,v $ ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 05-30-2006 DAD Ver 1.0: Modified version of mt2260.c (Ver 1.01). ++** N/A 11-01-2006 RSK Ver 1.02: Adding Get/Set UHFXFreq access functions. ++** 118 05-09-2007 RSK Ver 1.05: Adding Standard MTxxxx_Tune() API. ++** ++*****************************************************************************/ ++#if !defined( __MT2266_H ) ++#define __MT2266_H ++ ++//#include "mt_userdef.h" ++ ++#if defined( __cplusplus ) ++extern "C" /* Use "C" external linkage */ ++{ ++#endif ++ ++/* ++** Parameter for function MT2266_GetParam & MT2266_SetParam that ++** specifies the tuning algorithm parameter to be read/written. ++*/ ++typedef enum ++{ ++ /* tuner address set by MT2266_Open() */ ++ MT2266_IC_ADDR, ++ ++ /* max number of MT2266 tuners set by MT2266_CNT in mt_userdef.h */ ++ MT2266_MAX_OPEN, ++ ++ /* current number of open MT2266 tuners set by MT2266_Open() */ ++ MT2266_NUM_OPEN, ++ ++ /* Number of tuner registers */ ++ MT2266_NUM_REGS, ++ ++ /* crystal frequency (default: 18000000 Hz) */ ++ MT2266_SRO_FREQ, ++ ++ /* min tuning step size (default: 50000 Hz) */ ++ MT2266_STEPSIZE, ++ ++ /* input center frequency set by MT2266_ChangeFreq() */ ++ MT2266_INPUT_FREQ, ++ ++ /* LO Frequency set by MT2266_ChangeFreq() */ ++ MT2266_LO_FREQ, ++ ++ /* output channel bandwidth (default: 8000000 Hz) */ ++ MT2266_OUTPUT_BW, ++ ++ /* Base band filter calibration RC code (default: N/A) */ ++ MT2266_RC2_VALUE, ++ ++ /* Base band filter nominal cal RC code (default: N/A) */ ++ MT2266_RC2_NOMINAL, ++ ++ /* RF attenuator A/D readback (read-only) */ ++ MT2266_RF_ADC, ++ ++ /* BB attenuator A/D readback (read-only) */ ++ MT2266_BB_ADC, ++ ++ /* RF attenuator setting (default: varies) */ ++ MT2266_RF_ATTN, ++ ++ /* BB attenuator setting (default: varies) */ ++ MT2266_BB_ATTN, ++ ++ /* RF external / internal atten control (default: varies) */ ++ MT2266_RF_EXT, ++ ++ /* BB external / internal atten control (default: 1) */ ++ MT2266_BB_EXT, ++ ++ /* LNA gain setting (0-15) (default: varies) */ ++ MT2266_LNA_GAIN, ++ ++ /* Decrement LNA Gain (where arg=min LNA Gain value) */ ++ MT2266_LNA_GAIN_DECR, ++ ++ /* Increment LNA Gain (where arg=max LNA Gain value) */ ++ MT2266_LNA_GAIN_INCR, ++ ++ /* Set for UHF max sensitivity mode */ ++ MT2266_UHF_MAXSENS, ++ ++ /* Set for UHF normal mode */ ++ MT2266_UHF_NORMAL, ++ ++ MT2266_EOP /* last entry in enumerated list */ ++} MT2266_Param; ++ ++ ++/* ++** Parameter for function MT2266_GetUHFXFreqs & MT2266_SetUHFXFreqs that ++** specifies the particular frequency crossover table to be read/written. ++*/ ++typedef enum ++{ ++ /* Reference the UHF 0 filter, without any attenuation */ ++ MT2266_UHF0, ++ ++ /* Reference the UHF 1 filter, without any attenuation */ ++ MT2266_UHF1, ++ ++ /* Reference the UHF 0 filter, with attenuation */ ++ MT2266_UHF0_ATTEN, ++ ++ /* Reference the UHF 1 filter, with attenuation */ ++ MT2266_UHF1_ATTEN, ++ ++ MT2266_NUMBER_OF_XFREQ_SETS /* last entry in enumerated list */ ++ ++} MT2266_UHFXFreq_Type; ++ ++ ++#define MT2266_NUM_XFREQS (16) ++ ++typedef UData_t MT2266_XFreq_Set[ MT2266_NUM_XFREQS ]; ++ ++/* ++** Constants for Specifying Operating Band of the Tuner ++*/ ++#define MT2266_VHF_BAND (0) ++#define MT2266_UHF_BAND (1) ++#define MT2266_L_BAND (2) ++ ++/* ++** Constants for specifying power modes these values ++** are bit-mapped and can be added/OR'ed to indicate ++** multiple settings. Examples: ++** MT2266_SetPowerModes(h, MT2266_NO_ENABLES + MT22266_SROsd); ++** MT2266_SetPowerModes(h, MT2266_ALL_ENABLES | MT22266_SRO_NOT_sd); ++** MT2266_SetPowerModes(h, MT2266_NO_ENABLES + MT22266_SROsd); ++** MT2266_SetPowerModes(h, MT2266_SROen + MT22266_LOen + MT2266_ADCen); ++*/ ++#define MT2266_SROen (0x01) ++#define MT2266_LOen (0x02) ++#define MT2266_ADCen (0x04) ++#define MT2266_PDen (0x08) ++#define MT2266_DCOCen (0x10) ++#define MT2266_BBen (0x20) ++#define MT2266_MIXen (0x40) ++#define MT2266_LNAen (0x80) ++#define MT2266_ALL_ENABLES (0xFF) ++#define MT2266_NO_ENABLES (0x00) ++#define MT2266_SROsd (0x100) ++#define MT2266_SRO_NOT_sd (0x000) ++ ++/* ====== Functions which are declared in mt2266.c File ======= */ ++ ++/****************************************************************************** ++** ++** Name: MT2266_Open ++** ++** Description: Initialize the tuner's register values. ++** ++** Usage: status = MT2266_Open(0xC0, &hMT2266, NULL); ++** if (MT_IS_ERROR(status)) ++** // Check error codes for reason ++** ++** Parameters: MT2266_Addr - Serial bus address of the tuner. ++** hMT2266 - Tuner handle passed back. ++** hUserData - User-defined data, if needed for the ++** MT_ReadSub() & MT_WriteSub functions. ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_COMM_ERR - Serial bus communications error ++** MT_ARG_NULL - Null pointer argument passed ++** MT_TUNER_CNT_ERR - Too many tuners open ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++******************************************************************************/ ++UData_t MT2266_Open(UData_t MT2266_Addr, ++ Handle_t* hMT2266, ++ Handle_t hUserData); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_Close ++** ++** Description: Release the handle to the tuner. ++** ++** Parameters: hMT2266 - Handle to the MT2266 tuner ++** ++** Usage: status = MT2266_Close(hMT2266); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: mt_errordef.h - definition of error codes ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++******************************************************************************/ ++UData_t MT2266_Close(Handle_t hMT2266); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_ChangeFreq ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Usage: status = MT2266_ChangeFreq(hMT2266, f_in); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_FIN_RANGE - Input freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2266_Open BEFORE MT2266_ChangeFreq! ++** ++** MT_ReadSub - Read byte(s) of data from the two-wire-bus ++** MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2266_GetLocked - Checks to see if the PLL is locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++******************************************************************************/ ++UData_t MT2266_ChangeFreq(Handle_t h, ++ UData_t f_in); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetLocked ++** ++** Description: Checks to see if the PLL is locked. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: status = MT2266_GetLocked(hMT2266); ++** if (status & MT_DNC_UNLOCK) ++** // error!, PLL is unlocked ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus ++** MT_Sleep - Delay execution for x milliseconds ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetLocked(Handle_t h); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetParam ++** ++** Description: Gets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm - mostly for testing purposes. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2266_Param) ++** pValue - ptr to returned value ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2266_IC_ADDR Serial Bus address of this tuner ++** MT2266_MAX_OPEN Max number of MT2266's that can be open ++** MT2266_NUM_OPEN Number of MT2266's currently open ++** MT2266_NUM_REGS Number of tuner registers ++** MT2266_SRO_FREQ crystal frequency ++** MT2266_STEPSIZE minimum tuning step size ++** MT2266_INPUT_FREQ input center frequency ++** MT2266_LO_FREQ LO Frequency ++** MT2266_OUTPUT_BW Output channel bandwidth ++** MT2266_RC2_VALUE Base band filter cal RC code (method 2) ++** MT2266_RF_ADC RF attenuator A/D readback ++** MT2266_RF_ATTN RF attenuation (0-255) ++** MT2266_RF_EXT External control of RF atten ++** MT2266_LNA_GAIN LNA gain setting (0-15) ++** MT2266_BB_ADC BB attenuator A/D readback ++** MT2266_BB_ATTN Baseband attenuation (0-255) ++** MT2266_BB_EXT External control of BB atten ++** ++** Usage: status |= MT2266_GetParam(hMT2266, ++** MT2266_OUTPUT_BW, ++** &f_bw); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetParam, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetParam(Handle_t h, ++ MT2266_Param param, ++ UData_t* pValue); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetReg ++** ++** Description: Gets an MT2266 register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** reg - MT2266 register/subaddress location ++** *val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to read a register from ++** the MT2266. ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetReg(Handle_t h, ++ U8Data reg, ++ U8Data* val); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetUHFXFreqs ++** ++** Description: Retrieves the specified set of UHF Crossover Frequencies ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: MT2266_Freq_Set tmpFreqs; ++** status = MT2266_GetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** if (status & MT_ARG_RANGE) ++** // error, Invalid UHF Crossover Frequency Set requested. ++** else ++** for( int i = 0; i < MT2266_NUM_XFREQS; i++ ) ++** . . . ++** ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_RANGE - freq_type is out of range. ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: freqs_buffer *must* be defined of type MT2266_Freq_Set ++** to assure sufficient space allocation! ++** ++** USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetUHFXFreqs ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 11-01-2006 RSK Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetUHFXFreqs(Handle_t h, ++ MT2266_UHFXFreq_Type freq_type, ++ MT2266_XFreq_Set freqs_buffer); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_GetUserData ++** ++** Description: Gets the user-defined data item. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** ++** Usage: status = MT2266_GetUserData(hMT2266, &hUserData); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** The hUserData parameter is a user-specific argument ++** that is stored internally with the other tuner- ++** specific information. ++** ++** For example, if additional arguments are needed ++** for the user to identify the device communicating ++** with the tuner, this argument can be used to supply ++** the necessary information. ++** ++** The hUserData parameter is initialized in the tuner's ++** Open function to NULL. ++** ++** See Also: MT2266_SetUserData, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_GetUserData(Handle_t h, ++ Handle_t* hUserData); ++ ++ ++/****************************************************************************** ++** ++** Name: MT2266_ReInit ++** ++** Description: Initialize the tuner's register values. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch ++** MT_TUNER_INIT_ERR - Tuner initialization failed ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_COMM_ERR - Serial bus communications error ++** ++** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus ++** MT_WriteSub - Write byte(s) of data to the two-wire bus ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++******************************************************************************/ ++UData_t MT2266_ReInit(Handle_t h); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetParam ++** ++** Description: Sets a tuning algorithm parameter. ++** ++** This function provides access to the internals of the ++** tuning algorithm. You can override many of the tuning ++** algorithm defaults using this function. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** param - Tuning algorithm parameter ++** (see enum MT2266_Param) ++** nValue - value to be set ++** ++** param Description ++** ---------------------- -------------------------------- ++** MT2266_SRO_FREQ crystal frequency ++** MT2266_STEPSIZE minimum tuning step size ++** MT2266_INPUT_FREQ Center of input channel ++** MT2266_OUTPUT_BW Output channel bandwidth ++** MT2266_RF_ATTN RF attenuation (0-255) ++** MT2266_RF_EXT External control of RF atten ++** MT2266_LNA_GAIN LNA gain setting (0-15) ++** MT2266_LNA_GAIN_DECR Decrement LNA Gain (arg=min) ++** MT2266_LNA_GAIN_INCR Increment LNA Gain (arg=max) ++** MT2266_BB_ATTN Baseband attenuation (0-255) ++** MT2266_BB_EXT External control of BB atten ++** MT2266_UHF_MAXSENS Set for UHF max sensitivity mode ++** MT2266_UHF_NORMAL Set for UHF normal mode ++** ++** Usage: status |= MT2266_SetParam(hMT2266, ++** MT2266_STEPSIZE, ++** 50000); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_NULL - Null pointer argument passed ++** MT_ARG_RANGE - Invalid parameter requested ++** or set value out of range ++** or non-writable parameter ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_GetParam, MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetParam(Handle_t h, ++ MT2266_Param param, ++ UData_t nValue); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetPowerModes ++** ++** Description: Sets the bits in the MT2266_ENABLES register and the ++** SROsd bit in the MT2266_SROADC_CTRL register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** flags - Bit mask of flags to indicate enabled ++** bits. ++** ++** Usage: status = MT2266_SetPowerModes(hMT2266, flags); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** The bits in the MT2266_ENABLES register and the ++** SROsd bit are set according to the supplied flags. ++** ++** The pre-defined flags are as follows: ++** MT2266_SROen ++** MT2266_LOen ++** MT2266_ADCen ++** MT2266_PDen ++** MT2266_DCOCen ++** MT2266_BBen ++** MT2266_MIXen ++** MT2266_LNAen ++** MT2266_ALL_ENABLES ++** MT2266_NO_ENABLES ++** MT2266_SROsd ++** MT2266_SRO_NOT_sd ++** ++** ONLY the enable bits (or SROsd bit) specified in the ++** flags parameter will be set. Any flag which is not ++** included, will cause that bit to be disabled. ++** ++** The ALL_ENABLES, NO_ENABLES, and SRO_NOT_sd constants ++** are for convenience. The NO_ENABLES and SRO_NOT_sd ++** do not actually have to be included, but are provided ++** for clarity. ++** ++** See Also: MT2266_Open ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetPowerModes(Handle_t h, ++ UData_t flags); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetReg ++** ++** Description: Sets an MT2266 register. ++** ++** Parameters: h - Tuner handle (returned by MT2266_Open) ++** reg - MT2266 register/subaddress location ++** val - MT2266 register/subaddress value ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_COMM_ERR - Serial bus communications error ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_ARG_RANGE - Argument out of range ++** ++** Dependencies: USERS MUST CALL MT2266_Open() FIRST! ++** ++** Use this function if you need to override a default ++** register value ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 02-03-2006 DAD/JWS Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetReg(Handle_t h, ++ U8Data reg, ++ U8Data val); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_SetUHFXFreqs ++** ++** Description: Retrieves the specified set of UHF Crossover Frequencies ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** ++** Usage: MT2266_Freq_Set tmpFreqs; ++** status = MT2266_SetUHFXFreqs(hMT2266, ++** MT2266_UHF1_WITH_ATTENUATION, ++** tmpFreqs ); ++** if (status & MT_ARG_RANGE) ++** // error, Invalid UHF Crossover Frequency Set requested. ++** else ++** for( int i = 0; i < MT2266_NUM_XFREQS; i++ ) ++** . . . ++** ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_ARG_RANGE - freq_type is out of range. ++** MT_INV_HANDLE - Invalid tuner handle ++** ++** Dependencies: freqs_buffer *must* be defined of type MT2266_Freq_Set ++** to assure sufficient space allocation! ++** ++** USERS MUST CALL MT2266_Open() FIRST! ++** ++** See Also: MT2266_SetUHFXFreqs ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 11_01-2006 RSK Original. ++** ++****************************************************************************/ ++UData_t MT2266_SetUHFXFreqs(Handle_t h, ++ MT2266_UHFXFreq_Type freq_type, ++ MT2266_XFreq_Set freqs_buffer); ++ ++ ++/**************************************************************************** ++** ++** Name: MT2266_Tune ++** ++** Description: Change the tuner's tuned frequency to f_in. ++** ++** Parameters: h - Open handle to the tuner (from MT2266_Open). ++** f_in - RF input center frequency (in Hz). ++** ++** Usage: status = MT2266_Tune(hMT2266, f_in); ++** ++** Returns: status: ++** MT_OK - No errors ++** MT_INV_HANDLE - Invalid tuner handle ++** MT_DNC_UNLOCK - Downconverter PLL unlocked ++** MT_COMM_ERR - Serial bus communications error ++** MT_FIN_RANGE - Input freq out of range ++** MT_DNC_RANGE - Downconverter freq out of range ++** ++** Dependencies: MUST CALL MT2266_Open BEFORE MT2266_Tune! ++** ++** MT_ReadSub - Read byte(s) of data from the two-wire-bus ++** MT_WriteSub - Write byte(s) of data to the two-wire-bus ++** MT_Sleep - Delay execution for x milliseconds ++** MT2266_GetLocked - Checks to see if the PLL is locked ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** 118 05-09-2007 RSK Original API Introduction (was ChangeFreq). ++** ++******************************************************************************/ ++UData_t MT2266_Tune(Handle_t h, ++ UData_t f_in); ++ ++ ++#if defined( __cplusplus ) ++} ++#endif ++ ++#endif ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is MT2266 tuner API source code ++ ++ ++ ++ ++ ++/** ++ ++@file ++ ++@brief MT2266 tuner module declaration ++ ++One can manipulate MT2266 tuner through MT2266 module. ++MT2266 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// Definitions ++ ++// MT2266 API option ++#define __NO_CACHE__ ++#define MT2266_CNT 4 ++ ++ ++// Bandwidth modes ++enum MT2266_BANDWIDTH_HZ ++{ ++ MT2266_BANDWIDTH_5MHZ = 5000000, ++ MT2266_BANDWIDTH_6MHZ = 6000000, ++ MT2266_BANDWIDTH_7MHZ = 7000000, ++ MT2266_BANDWIDTH_8MHZ = 8000000, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildMt2266Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++mt2266_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++mt2266_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++mt2266_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mt2266_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++mt2266_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++mt2266_OpenHandle( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mt2266_CloseHandle( ++ TUNER_MODULE *pTuner ++ ); ++ ++void ++mt2266_GetHandle( ++ TUNER_MODULE *pTuner, ++ void **pDeviceHandle ++ ); ++ ++int ++mt2266_SetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long BandwidthHz ++ ); ++ ++int ++mt2266_GetBandwidthHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pBandwidthHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c b/drivers/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c +--- a/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_mxl5007t.c 2016-04-02 19:17:52.148066045 -0300 +@@ -0,0 +1,1267 @@ ++/** ++ ++@file ++ ++@brief MxL5007T tuner module definition ++ ++One can manipulate MxL5007T tuner through MxL5007T module. ++MxL5007T module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_mxl5007t.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief MxL5007T tuner module builder ++ ++Use BuildMxl5007tModule() to build MxL5007T module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to MxL5007T tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr MxL5007T I2C device address ++@param [in] CrystalFreqHz MxL5007T crystal frequency in Hz ++@param [in] StandardMode MxL5007T standard mode ++@param [in] IfFreqHz MxL5007T IF frequency in Hz ++@param [in] LoopThroughMode MxL5007T loop-through mode ++@param [in] ClkOutMode MxL5007T clock output mode ++@param [in] ClkOutAmpMode MxL5007T clock output amplitude mode ++@param [in] QamIfDiffOutLevel MxL5007T QAM IF differential output level for QAM standard only ++ ++ ++@note ++ -# One should call BuildMxl5007tModule() to build MxL5007T module before using it. ++ ++*/ ++void ++BuildMxl5007tModule( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int StandardMode, ++ unsigned long IfFreqHz, ++ int SpectrumMode, ++ int LoopThroughMode, ++ int ClkOutMode, ++ int ClkOutAmpMode, ++ long QamIfDiffOutLevel ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ MXL5007T_EXTRA_MODULE *pExtra; ++ MxL5007_TunerConfigS *pTunerConfigS; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ // Set and get MaxLinear-defined MxL5007T structure pointer. ++ pExtra->pTunerConfigS = &(pExtra->TunerConfigSMemory); ++ pTunerConfigS = pExtra->pTunerConfigS; ++ ++ // Set additional definition tuner module pointer. ++ pTunerConfigS->pTuner = pTuner; ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_MXL5007T; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = mxl5007t_GetTunerType; ++ pTuner->GetDeviceAddr = mxl5007t_GetDeviceAddr; ++ ++ pTuner->Initialize = mxl5007t_Initialize; ++ pTuner->SetRfFreqHz = mxl5007t_SetRfFreqHz; ++ pTuner->GetRfFreqHz = mxl5007t_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->LoopThroughMode = LoopThroughMode; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ ++ // Initialize MaxLinear-defined MxL5007T structure variables. ++ // Note: The API doesn't use I2C device address of MaxLinear-defined MxL5007T structure. ++ switch(StandardMode) ++ { ++ default: ++ case MXL5007T_STANDARD_DVBT: pTunerConfigS->Mode = MxL_MODE_DVBT; break; ++ case MXL5007T_STANDARD_ATSC: pTunerConfigS->Mode = MxL_MODE_ATSC; break; ++ case MXL5007T_STANDARD_QAM: pTunerConfigS->Mode = MxL_MODE_CABLE; break; ++ case MXL5007T_STANDARD_ISDBT: pTunerConfigS->Mode = MxL_MODE_ISDBT; break; ++ } ++ ++ pTunerConfigS->IF_Diff_Out_Level = (SINT32)QamIfDiffOutLevel; ++ ++ switch(CrystalFreqHz) ++ { ++ default: ++ case CRYSTAL_FREQ_16000000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_16_MHZ; break; ++ case CRYSTAL_FREQ_24000000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_24_MHZ; break; ++ case CRYSTAL_FREQ_25000000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_25_MHZ; break; ++ case CRYSTAL_FREQ_27000000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_27_MHZ; break; ++ case CRYSTAL_FREQ_28800000HZ: pTunerConfigS->Xtal_Freq = MxL_XTAL_28_8_MHZ; break; ++ } ++ ++ switch(IfFreqHz) ++ { ++ default: ++ case IF_FREQ_4570000HZ: pTunerConfigS->IF_Freq = MxL_IF_4_57_MHZ; break; ++ case IF_FREQ_36150000HZ: pTunerConfigS->IF_Freq = MxL_IF_36_15_MHZ; break; ++ case IF_FREQ_44000000HZ: pTunerConfigS->IF_Freq = MxL_IF_44_MHZ; break; ++ } ++ ++ switch(SpectrumMode) ++ { ++ default: ++ case SPECTRUM_NORMAL: pTunerConfigS->IF_Spectrum = MxL_NORMAL_IF; break; ++ case SPECTRUM_INVERSE: pTunerConfigS->IF_Spectrum = MxL_INVERT_IF; break; ++ } ++ ++ switch(ClkOutMode) ++ { ++ default: ++ case MXL5007T_CLK_OUT_DISABLE: pTunerConfigS->ClkOut_Setting = MxL_CLKOUT_DISABLE; break; ++ case MXL5007T_CLK_OUT_ENABLE: pTunerConfigS->ClkOut_Setting = MxL_CLKOUT_ENABLE; break; ++ } ++ ++ switch(ClkOutAmpMode) ++ { ++ default: ++ case MXL5007T_CLK_OUT_AMP_0: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_0; break; ++ case MXL5007T_CLK_OUT_AMP_1: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_1; break; ++ case MXL5007T_CLK_OUT_AMP_2: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_2; break; ++ case MXL5007T_CLK_OUT_AMP_3: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_3; break; ++ case MXL5007T_CLK_OUT_AMP_4: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_4; break; ++ case MXL5007T_CLK_OUT_AMP_5: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_5; break; ++ case MXL5007T_CLK_OUT_AMP_6: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_6; break; ++ case MXL5007T_CLK_OUT_AMP_7: pTunerConfigS->ClkOut_Amp = MxL_CLKOUT_AMP_7; break; ++ } ++ ++ pTunerConfigS->BW_MHz = MXL5007T_BANDWIDTH_MODE_DEFAULT; ++ pTunerConfigS->RF_Freq_Hz = MXL5007T_RF_FREQ_HZ_DEFAULT; ++ ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = mxl5007t_SetBandwidthMode; ++ pExtra->GetBandwidthMode = mxl5007t_GetBandwidthMode; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++mxl5007t_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++mxl5007t_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++mxl5007t_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ MXL5007T_EXTRA_MODULE *pExtra; ++ MxL5007_TunerConfigS *pTunerConfigS; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ // Get MaxLinear-defined MxL5007T structure. ++ pTunerConfigS = pExtra->pTunerConfigS; ++ ++ ++ // Initialize tuner. ++ if(MxL_Tuner_Init(pTunerConfigS) != MxL_OK) ++ goto error_status_initialize_tuner; ++ ++ // Set tuner loop-through mode. ++ if(MxL_Loop_Through_On(pTunerConfigS, pExtra->LoopThroughMode) != MxL_OK) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++mxl5007t_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ MXL5007T_EXTRA_MODULE *pExtra; ++ MxL5007_TunerConfigS *pTunerConfigS; ++ ++ UINT32 Mxl5007tRfFreqHz; ++ MxL5007_BW_MHz Mxl5007tBandwidthMhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ // Get MaxLinear-defined MxL5007T structure. ++ pTunerConfigS = pExtra->pTunerConfigS; ++ ++ ++ // Get bandwidth. ++ Mxl5007tBandwidthMhz = pTunerConfigS->BW_MHz; ++ ++ // Set RF frequency. ++ Mxl5007tRfFreqHz = (UINT32)RfFreqHz; ++ ++ // Set MxL5007T RF frequency and bandwidth. ++ if(MxL_Tuner_RFTune(pTunerConfigS, Mxl5007tRfFreqHz, Mxl5007tBandwidthMhz) != MxL_OK) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++mxl5007t_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set MxL5007T tuner bandwidth mode. ++ ++*/ ++int ++mxl5007t_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ MXL5007T_EXTRA_MODULE *pExtra; ++ MxL5007_TunerConfigS *pTunerConfigS; ++ ++ UINT32 Mxl5007tRfFreqHz; ++ MxL5007_BW_MHz Mxl5007tBandwidthMhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ // Get MaxLinear-defined MxL5007T structure. ++ pTunerConfigS = pExtra->pTunerConfigS; ++ ++ ++ // Get RF frequency. ++ Mxl5007tRfFreqHz = pTunerConfigS->RF_Freq_Hz; ++ ++ // Set bandwidth. ++ switch(BandwidthMode) ++ { ++ case MXL5007T_BANDWIDTH_6000000HZ: Mxl5007tBandwidthMhz = MxL_BW_6MHz; break; ++ case MXL5007T_BANDWIDTH_7000000HZ: Mxl5007tBandwidthMhz = MxL_BW_7MHz; break; ++ case MXL5007T_BANDWIDTH_8000000HZ: Mxl5007tBandwidthMhz = MxL_BW_8MHz; break; ++ ++ default: goto error_status_get_undefined_value; ++ } ++ ++ // Set MxL5007T RF frequency and bandwidth. ++ if(MxL_Tuner_RFTune(pTunerConfigS, Mxl5007tRfFreqHz, Mxl5007tBandwidthMhz) != MxL_OK) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ // Set tuner bandwidth parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth: ++error_status_get_undefined_value: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get MxL5007T tuner bandwidth mode. ++ ++*/ ++int ++mxl5007t_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ MXL5007T_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Mxl5007t); ++ ++ ++ // Get tuner bandwidth mode from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth_mode; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by MaxLinear. ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL_User_Define.c ++ ++ ++/* ++ ++ Driver APIs for MxL5007 Tuner ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL_User_Define.c ++ ++ */ ++ ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++// // ++// I2C Functions (implement by customer) // ++// // ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++ ++/****************************************************************************** ++** ++** Name: MxL_I2C_Write ++** ++** Description: I2C write operations ++** ++** Parameters: ++** DeviceAddr - MxL5007 Device address ++** pArray - Write data array pointer ++** count - total number of array ++** ++** Returns: 0 if success ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 12-16-2007 khuang initial release. ++** ++******************************************************************************/ ++//UINT32 MxL_I2C_Write(UINT8 DeviceAddr, UINT8* pArray, UINT32 count) ++UINT32 MxL_I2C_Write(MxL5007_TunerConfigS* myTuner, UINT8* pArray, UINT32 count) ++{ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned long WritingByteNumMax; ++ ++ unsigned long i; ++ unsigned char Buffer[I2C_BUFFER_LEN]; ++ unsigned long WritingIndex; ++ ++ unsigned char *pData; ++ unsigned long DataLen; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pTuner = myTuner->pTuner; ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ // Get writing byte and byte number. ++ pData = (unsigned char *)pArray; ++ DataLen = (unsigned long)count; ++ ++ // Calculate MxL5007T maximum writing byte number. ++ // Note: MxL5007T maximum writing byte number must be a multiple of 2. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax; ++ WritingByteNumMax = ((WritingByteNumMax % 2) == 0) ? WritingByteNumMax : (WritingByteNumMax - 1); ++ ++ ++ // Set register bytes. ++ // Note: The 2 kind of I2C formats of MxL5007T is described as follows: ++ // 1. start_bit + (device_addr | writing_bit) + (register_addr + writing_byte) * n + stop_bit ++ // ... ++ // start_bit + (device_addr | writing_bit) + (register_addr + writing_byte) * m + stop_bit ++ // 2. start_bit + (device_addr | writing_bit) + 0xff + stop_bit ++ for(i = 0, WritingIndex = 0; i < DataLen; i++, WritingIndex++) ++ { ++ // Put data into buffer. ++ Buffer[WritingIndex] = pData[i]; ++ ++ // If writing buffer is full or put data into buffer completely, send the I2C writing command with buffer. ++ if( (WritingIndex == (WritingByteNumMax - 1)) || (i == (DataLen - 1)) ) ++ { ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, Buffer, (WritingIndex + LEN_1_BYTE)) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ WritingIndex = -1; ++ } ++ } ++ ++ ++ return MxL_OK; ++ ++ ++error_status_set_tuner_registers: ++ return MxL_ERR_OTHERS; ++} ++ ++/****************************************************************************** ++** ++** Name: MxL_I2C_Read ++** ++** Description: I2C read operations ++** ++** Parameters: ++** DeviceAddr - MxL5007 Device address ++** Addr - register address for read ++** *Data - data return ++** ++** Returns: 0 if success ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 12-16-2007 khuang initial release. ++** ++******************************************************************************/ ++//UINT32 MxL_I2C_Read(UINT8 DeviceAddr, UINT8 Addr, UINT8* mData) ++UINT32 MxL_I2C_Read(MxL5007_TunerConfigS* myTuner, UINT8 Addr, UINT8* mData) ++{ ++ TUNER_MODULE *pTuner; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned char Buffer[LEN_2_BYTE]; ++ ++ ++ ++ // Get tuner module and I2C bridge. ++ pTuner = myTuner->pTuner; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + 0xfb + RegReadingAddr + stop_bit ++ Buffer[0] = (unsigned char)MXL5007T_I2C_READING_CONST; ++ Buffer[1] = (unsigned char)Addr; ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, Buffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register bytes. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_byte + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, Buffer, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ *mData = (UINT8)Buffer[0]; ++ ++ ++ return MxL_OK; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ return MxL_ERR_OTHERS; ++} ++ ++/****************************************************************************** ++** ++** Name: MxL_Delay ++** ++** Description: Delay function in milli-second ++** ++** Parameters: ++** mSec - milli-second to delay ++** ++** Returns: 0 ++** ++** Revision History: ++** ++** SCR Date Author Description ++** ------------------------------------------------------------------------- ++** N/A 12-16-2007 khuang initial release. ++** ++******************************************************************************/ ++//void MxL_Delay(UINT32 mSec) ++void MxL_Delay(MxL5007_TunerConfigS* myTuner, UINT32 mSec) ++{ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ ++ // Get tuner module and base interface. ++ pTuner = myTuner->pTuner; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ // Wait in ms. ++ pBaseInterface->WaitMs(pBaseInterface, mSec); ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007.c ++ ++ ++/* ++ MxL5007 Source Code : V4.1.3 ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL5007.c ++ ++ Description: The source code is for MxL5007 user to quickly integrate MxL5007 into their software. ++ There are two functions the user can call to generate a array of I2C command that's require to ++ program the MxL5007 tuner. The user should pass an array pointer and an integer pointer in to the ++ function. The funciton will fill up the array with format like follow: ++ ++ addr1 ++ data1 ++ addr2 ++ data2 ++ ... ++ ++ The user can then pass this array to their I2C function to perform progromming the tuner. ++*/ ++//#include "StdAfx.h" ++//#include "MxL5007_Common.h" ++//#include "MxL5007.h" ++ ++ ++ ++UINT32 MxL5007_Init(UINT8* pArray, // a array pointer that store the addr and data pairs for I2C write ++ UINT32* Array_Size, // a integer pointer that store the number of element in above array ++ UINT8 Mode, ++ SINT32 IF_Diff_Out_Level, ++ UINT32 Xtal_Freq_Hz, ++ UINT32 IF_Freq_Hz, ++ UINT8 Invert_IF, ++ UINT8 Clk_Out_Enable, ++ UINT8 Clk_Out_Amp ++ ) ++{ ++ ++ UINT32 Reg_Index=0; ++ UINT32 Array_Index=0; ++ ++ IRVType IRV_Init[]= ++ { ++ //{ Addr, Data} ++ { 0x02, 0x06}, ++ { 0x03, 0x48}, ++ { 0x05, 0x04}, ++ { 0x06, 0x10}, ++ { 0x2E, 0x15}, //Override ++ { 0x30, 0x10}, //Override ++ { 0x45, 0x58}, //Override ++ { 0x48, 0x19}, //Override ++ { 0x52, 0x03}, //Override ++ { 0x53, 0x44}, //Override ++ { 0x6A, 0x4B}, //Override ++ { 0x76, 0x00}, //Override ++ { 0x78, 0x18}, //Override ++ { 0x7A, 0x17}, //Override ++ { 0x85, 0x06}, //Override ++ { 0x01, 0x01}, //TOP_MASTER_ENABLE=1 ++ { 0, 0} ++ }; ++ ++ ++ IRVType IRV_Init_Cable[]= ++ { ++ //{ Addr, Data} ++ { 0x02, 0x06}, ++ { 0x03, 0x48}, ++ { 0x05, 0x04}, ++ { 0x06, 0x10}, ++ { 0x09, 0x3F}, ++ { 0x0A, 0x3F}, ++ { 0x0B, 0x3F}, ++ { 0x2E, 0x15}, //Override ++ { 0x30, 0x10}, //Override ++ { 0x45, 0x58}, //Override ++ { 0x48, 0x19}, //Override ++ { 0x52, 0x03}, //Override ++ { 0x53, 0x44}, //Override ++ { 0x6A, 0x4B}, //Override ++ { 0x76, 0x00}, //Override ++ { 0x78, 0x18}, //Override ++ { 0x7A, 0x17}, //Override ++ { 0x85, 0x06}, //Override ++ { 0x01, 0x01}, //TOP_MASTER_ENABLE=1 ++ { 0, 0} ++ }; ++ //edit Init setting here ++ ++ PIRVType myIRV=IRV_Init; ++ ++ switch(Mode) ++ { ++ case MxL_MODE_ISDBT: //ISDB-T Mode ++ myIRV = IRV_Init; ++ SetIRVBit(myIRV, 0x06, 0x1F, 0x10); ++ break; ++ case MxL_MODE_DVBT: //DVBT Mode ++ myIRV = IRV_Init; ++ SetIRVBit(myIRV, 0x06, 0x1F, 0x11); ++ break; ++ case MxL_MODE_ATSC: //ATSC Mode ++ myIRV = IRV_Init; ++ SetIRVBit(myIRV, 0x06, 0x1F, 0x12); ++ break; ++ case MxL_MODE_CABLE: ++ myIRV = IRV_Init_Cable; ++ SetIRVBit(myIRV, 0x09, 0xFF, 0xC1); ++ SetIRVBit(myIRV, 0x0A, 0xFF, 8-IF_Diff_Out_Level); ++ SetIRVBit(myIRV, 0x0B, 0xFF, 0x17); ++ break; ++ ++ ++ } ++ ++ switch(IF_Freq_Hz) ++ { ++ case MxL_IF_4_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x00); ++ break; ++ case MxL_IF_4_5_MHZ: //4.5MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x02); ++ break; ++ case MxL_IF_4_57_MHZ: //4.57MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x03); ++ break; ++ case MxL_IF_5_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x04); ++ break; ++ case MxL_IF_5_38_MHZ: //5.38MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x05); ++ break; ++ case MxL_IF_6_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x06); ++ break; ++ case MxL_IF_6_28_MHZ: //6.28MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x07); ++ break; ++ case MxL_IF_9_1915_MHZ: //9.1915MHz ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x08); ++ break; ++ case MxL_IF_35_25_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x09); ++ break; ++ case MxL_IF_36_15_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x0a); ++ break; ++ case MxL_IF_44_MHZ: ++ SetIRVBit(myIRV, 0x02, 0x0F, 0x0B); ++ break; ++ } ++ ++ if(Invert_IF) ++ SetIRVBit(myIRV, 0x02, 0x10, 0x10); //Invert IF ++ else ++ SetIRVBit(myIRV, 0x02, 0x10, 0x00); //Normal IF ++ ++ ++ switch(Xtal_Freq_Hz) ++ { ++ case MxL_XTAL_16_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x00); //select xtal freq & Ref Freq ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x00); ++ break; ++ case MxL_XTAL_20_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x10); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x01); ++ break; ++ case MxL_XTAL_20_25_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x20); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x02); ++ break; ++ case MxL_XTAL_20_48_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x30); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x03); ++ break; ++ case MxL_XTAL_24_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x40); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x04); ++ break; ++ case MxL_XTAL_25_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x50); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x05); ++ break; ++ case MxL_XTAL_25_14_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x60); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x06); ++ break; ++ case MxL_XTAL_27_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x70); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x07); ++ break; ++ case MxL_XTAL_28_8_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x80); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x08); ++ break; ++ case MxL_XTAL_32_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0x90); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x09); ++ break; ++ case MxL_XTAL_40_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0xA0); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x0A); ++ break; ++ case MxL_XTAL_44_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0xB0); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x0B); ++ break; ++ case MxL_XTAL_48_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0xC0); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x0C); ++ break; ++ case MxL_XTAL_49_3811_MHZ: ++ SetIRVBit(myIRV, 0x03, 0xF0, 0xD0); ++ SetIRVBit(myIRV, 0x05, 0x0F, 0x0D); ++ break; ++ } ++ ++ if(!Clk_Out_Enable) //default is enable ++ SetIRVBit(myIRV, 0x03, 0x08, 0x00); ++ ++ //Clk_Out_Amp ++ SetIRVBit(myIRV, 0x03, 0x07, Clk_Out_Amp); ++ ++ //Generate one Array that Contain Data, Address ++ while (myIRV[Reg_Index].Num || myIRV[Reg_Index].Val) ++ { ++ pArray[Array_Index++] = myIRV[Reg_Index].Num; ++ pArray[Array_Index++] = myIRV[Reg_Index].Val; ++ Reg_Index++; ++ } ++ ++ *Array_Size=Array_Index; ++ return 0; ++} ++ ++ ++UINT32 MxL5007_RFTune(UINT8* pArray, UINT32* Array_Size, UINT32 RF_Freq, UINT8 BWMHz) ++{ ++ IRVType IRV_RFTune[]= ++ { ++ //{ Addr, Data} ++ { 0x0F, 0x00}, //abort tune ++ { 0x0C, 0x15}, ++ { 0x0D, 0x40}, ++ { 0x0E, 0x0E}, ++ { 0x1F, 0x87}, //Override ++ { 0x20, 0x1F}, //Override ++ { 0x21, 0x87}, //Override ++ { 0x22, 0x1F}, //Override ++ { 0x80, 0x01}, //Freq Dependent Setting ++ { 0x0F, 0x01}, //start tune ++ { 0, 0} ++ }; ++ ++ UINT32 dig_rf_freq=0; ++ UINT32 temp; ++ UINT32 Reg_Index=0; ++ UINT32 Array_Index=0; ++ UINT32 i; ++ UINT32 frac_divider = 1000000; ++ ++ switch(BWMHz) ++ { ++ case MxL_BW_6MHz: //6MHz ++ SetIRVBit(IRV_RFTune, 0x0C, 0x3F, 0x15); //set DIG_MODEINDEX, DIG_MODEINDEX_A, and DIG_MODEINDEX_CSF ++ break; ++ case MxL_BW_7MHz: //7MHz ++ SetIRVBit(IRV_RFTune, 0x0C, 0x3F, 0x2A); ++ break; ++ case MxL_BW_8MHz: //8MHz ++ SetIRVBit(IRV_RFTune, 0x0C, 0x3F, 0x3F); ++ break; ++ } ++ ++ ++ //Convert RF frequency into 16 bits => 10 bit integer (MHz) + 6 bit fraction ++ dig_rf_freq = RF_Freq / MHz; ++ temp = RF_Freq % MHz; ++ for(i=0; i<6; i++) ++ { ++ dig_rf_freq <<= 1; ++ frac_divider /=2; ++ if(temp > frac_divider) ++ { ++ temp -= frac_divider; ++ dig_rf_freq++; ++ } ++ } ++ ++ //add to have shift center point by 7.8124 kHz ++ if(temp > 7812) ++ dig_rf_freq ++; ++ ++ SetIRVBit(IRV_RFTune, 0x0D, 0xFF, (UINT8)dig_rf_freq); ++ SetIRVBit(IRV_RFTune, 0x0E, 0xFF, (UINT8)(dig_rf_freq>>8)); ++ ++ if (RF_Freq >=333*MHz) ++ SetIRVBit(IRV_RFTune, 0x80, 0x40, 0x40); ++ ++ //Generate one Array that Contain Data, Address ++ while (IRV_RFTune[Reg_Index].Num || IRV_RFTune[Reg_Index].Val) ++ { ++ pArray[Array_Index++] = IRV_RFTune[Reg_Index].Num; ++ pArray[Array_Index++] = IRV_RFTune[Reg_Index].Val; ++ Reg_Index++; ++ } ++ ++ *Array_Size=Array_Index; ++ ++ return 0; ++} ++ ++//local functions called by Init and RFTune ++UINT32 SetIRVBit(PIRVType pIRV, UINT8 Num, UINT8 Mask, UINT8 Val) ++{ ++ while (pIRV->Num || pIRV->Val) ++ { ++ if (pIRV->Num==Num) ++ { ++ pIRV->Val&=~Mask; ++ pIRV->Val|=Val; ++ } ++ pIRV++; ++ ++ } ++ return 0; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007_API.h ++ ++ ++/* ++ ++ Driver APIs for MxL5007 Tuner ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL5007_API.c ++ ++ Version: 4.1.3 ++*/ ++ ++ ++//#include "StdAfx.h" ++//#include "MxL5007_API.h" ++//#include "MxL_User_Define.c" ++//#include "MxL5007.c" ++ ++ ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++// // ++// Tuner Functions // ++// // ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++MxL_ERR_MSG MxL_Set_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 RegData) ++{ ++ UINT32 Status=0; ++ UINT8 pArray[2]; ++ pArray[0] = RegAddr; ++ pArray[1] = RegData; ++// Status = MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2); ++ Status = MxL_I2C_Write(myTuner, pArray, 2); ++ if(Status) return MxL_ERR_SET_REG; ++ ++ return MxL_OK; ++ ++} ++ ++MxL_ERR_MSG MxL_Get_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 *RegData) ++{ ++// if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, RegAddr, RegData)) ++ if(MxL_I2C_Read(myTuner, RegAddr, RegData)) ++ return MxL_ERR_GET_REG; ++ return MxL_OK; ++ ++} ++ ++MxL_ERR_MSG MxL_Soft_Reset(MxL5007_TunerConfigS* myTuner) ++{ ++/* UINT32 Status=0; */ ++ UINT8 reg_reset=0; ++ reg_reset = 0xFF; ++/* if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, ®_reset, 1))*/ ++ if(MxL_I2C_Write(myTuner, ®_reset, 1)) ++ return MxL_ERR_OTHERS; ++ ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_Loop_Through_On(MxL5007_TunerConfigS* myTuner, MxL5007_LoopThru isOn) ++{ ++ UINT8 pArray[2]; // a array pointer that store the addr and data pairs for I2C write ++ ++ pArray[0]=0x04; ++ if(isOn) ++ pArray[1]= 0x01; ++ else ++ pArray[1]= 0x0; ++ ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2)) ++ if(MxL_I2C_Write(myTuner, pArray, 2)) ++ return MxL_ERR_OTHERS; ++ ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_Stand_By(MxL5007_TunerConfigS* myTuner) ++{ ++ UINT8 pArray[4]; // a array pointer that store the addr and data pairs for I2C write ++ ++ pArray[0] = 0x01; ++ pArray[1] = 0x0; ++ pArray[2] = 0x0F; ++ pArray[3] = 0x0; ++ ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 4)) ++ if(MxL_I2C_Write(myTuner, pArray, 4)) ++ return MxL_ERR_OTHERS; ++ ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_Wake_Up(MxL5007_TunerConfigS* myTuner) ++{ ++ UINT8 pArray[2]; // a array pointer that store the addr and data pairs for I2C write ++ ++ pArray[0] = 0x01; ++ pArray[1] = 0x01; ++ ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, 2)) ++ if(MxL_I2C_Write(myTuner, pArray, 2)) ++ return MxL_ERR_OTHERS; ++ ++ if(MxL_Tuner_RFTune(myTuner, myTuner->RF_Freq_Hz, myTuner->BW_MHz)) ++ return MxL_ERR_RFTUNE; ++ ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_Tuner_Init(MxL5007_TunerConfigS* myTuner) ++{ ++ UINT8 pArray[MAX_ARRAY_SIZE]; // a array pointer that store the addr and data pairs for I2C write ++ UINT32 Array_Size; // a integer pointer that store the number of element in above array ++ ++ //Soft reset tuner ++ if(MxL_Soft_Reset(myTuner)) ++ return MxL_ERR_INIT; ++ ++ //perform initialization calculation ++ MxL5007_Init(pArray, &Array_Size, (UINT8)myTuner->Mode, myTuner->IF_Diff_Out_Level, (UINT32)myTuner->Xtal_Freq, ++ (UINT32)myTuner->IF_Freq, (UINT8)myTuner->IF_Spectrum, (UINT8)myTuner->ClkOut_Setting, (UINT8)myTuner->ClkOut_Amp); ++ ++ //perform I2C write here ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, Array_Size)) ++ if(MxL_I2C_Write(myTuner, pArray, Array_Size)) ++ return MxL_ERR_INIT; ++ ++ return MxL_OK; ++} ++ ++ ++MxL_ERR_MSG MxL_Tuner_RFTune(MxL5007_TunerConfigS* myTuner, UINT32 RF_Freq_Hz, MxL5007_BW_MHz BWMHz) ++{ ++ //UINT32 Status=0; ++ UINT8 pArray[MAX_ARRAY_SIZE]; // a array pointer that store the addr and data pairs for I2C write ++ UINT32 Array_Size; // a integer pointer that store the number of element in above array ++ ++ //Store information into struc ++ myTuner->RF_Freq_Hz = RF_Freq_Hz; ++ myTuner->BW_MHz = BWMHz; ++ ++ //perform Channel Change calculation ++ MxL5007_RFTune(pArray,&Array_Size,RF_Freq_Hz,BWMHz); ++ ++ //perform I2C write here ++// if(MxL_I2C_Write((UINT8)myTuner->I2C_Addr, pArray, Array_Size)) ++ if(MxL_I2C_Write(myTuner, pArray, Array_Size)) ++ return MxL_ERR_RFTUNE; ++ ++ //wait for 3ms ++// MxL_Delay(3); ++ MxL_Delay(myTuner, 3); ++ ++ return MxL_OK; ++} ++ ++MxL5007_ChipVersion MxL_Check_ChipVersion(MxL5007_TunerConfigS* myTuner) ++{ ++ UINT8 Data; ++// if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD9, &Data)) ++ if(MxL_I2C_Read(myTuner, 0xD9, &Data)) ++ return MxL_GET_ID_FAIL; ++ ++ switch(Data) ++ { ++ case 0x14: return MxL_5007T_V4; break; ++ default: return MxL_UNKNOWN_ID; ++ } ++} ++ ++MxL_ERR_MSG MxL_RFSynth_Lock_Status(MxL5007_TunerConfigS* myTuner, BOOL* isLock) ++{ ++ UINT8 Data; ++ *isLock = MxL_FALSE; ++// if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD8, &Data)) ++ if(MxL_I2C_Read(myTuner, 0xD8, &Data)) ++ return MxL_ERR_OTHERS; ++ Data &= 0x0C; ++ if (Data == 0x0C) ++ *isLock = MxL_TRUE; //RF Synthesizer is Lock ++ return MxL_OK; ++} ++ ++MxL_ERR_MSG MxL_REFSynth_Lock_Status(MxL5007_TunerConfigS* myTuner, BOOL* isLock) ++{ ++ UINT8 Data; ++ *isLock = MxL_FALSE; ++// if(MxL_I2C_Read((UINT8)myTuner->I2C_Addr, 0xD8, &Data)) ++ if(MxL_I2C_Read(myTuner, 0xD8, &Data)) ++ return MxL_ERR_OTHERS; ++ Data &= 0x03; ++ if (Data == 0x03) ++ *isLock = MxL_TRUE; //REF Synthesizer is Lock ++ return MxL_OK; ++} ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h b/drivers/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h +--- a/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_mxl5007t.h 2016-04-02 19:17:52.148066045 -0300 +@@ -0,0 +1,788 @@ ++#ifndef __TUNER_MXL5007T_H ++#define __TUNER_MXL5007T_H ++ ++/** ++ ++@file ++ ++@brief MxL5007T tuner module declaration ++ ++One can manipulate MxL5007T tuner through MxL5007T module. ++MxL5007T module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_mxl5007t.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ MXL5007T_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ unsigned long BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build MxL5007T tuner module. ++ BuildMxl5007tModule( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0, // I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // Crystal frequency is 16.0 MHz. ++ MXL5007T_STANDARD_DVBT, // The MxL5007T standard mode is DVB-T. ++ IF_FREQ_4570000HZ, // The MxL5007T IF frequency is 4.57 MHz. ++ SPECTRUM_NORMAL, // The MxL5007T spectrum mode is normal. ++ MXL5007T_LOOP_THROUGH_DISABLE, // The MxL5007T loop-through mode is disabled. ++ MXL5007T_CLK_OUT_DISABLE, // The MxL5007T clock output mode is disabled. ++ MXL5007T_CLK_OUT_AMP_0, // The MxL5007T clock output amplitude is 0. ++ 0 // The MxL5007T QAM IF differential output level is 0 for cable only. ++ ); ++ ++ ++ ++ ++ ++ // Get MxL5007T tuner extra module. ++ pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set MxL5007T bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, MXL5007T_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get MxL5007T bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// The following context is source code provided by MaxLinear. ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007_Common.h ++ ++ ++/******************************************************************************* ++ * ++ * FILE NAME : MxL_Common.h ++ * ++ * AUTHOR : Kyle Huang ++ * DATE CREATED : May 05, 2008 ++ * ++ * DESCRIPTION : ++ * ++ ******************************************************************************* ++ * Copyright (c) 2006, MaxLinear, Inc. ++ ******************************************************************************/ ++ ++//#ifndef __MXL5007_COMMON_H ++//#define __MXL5007_COMMON_H ++ ++ ++ ++/****************************************************************************** ++* User-Defined Types (Typedefs) ++******************************************************************************/ ++ ++ ++/**************************************************************************** ++* Imports and definitions for WIN32 ++****************************************************************************/ ++//#include ++ ++#ifndef _UINT_X_ ++#define _UINT_X_ 1 ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++#endif ++typedef char SINT8; ++typedef short SINT16; ++typedef int SINT32; ++//typedef float REAL32; ++ ++// Additional definition ++#define BOOL int ++#define MxL_FALSE 0 ++#define MxL_TRUE 1 ++ ++/****************************************************************************\ ++* Imports and definitions for non WIN32 platforms * ++\****************************************************************************/ ++/* ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++typedef char SINT8; ++typedef short SINT16; ++typedef int SINT32; ++typedef float REAL32; ++ ++// create a boolean ++#ifndef __boolean__ ++#define __boolean__ ++typedef enum {FALSE=0,TRUE} BOOL; ++#endif //boolean ++*/ ++ ++ ++/****************************************************************************\ ++* Definitions for all platforms * ++\****************************************************************************/ ++#ifndef NULL ++#define NULL (void*)0 ++#endif ++ ++ ++ ++/******************************/ ++/* MxL5007 Err message */ ++/******************************/ ++typedef enum{ ++ MxL_OK = 0, ++ MxL_ERR_INIT = 1, ++ MxL_ERR_RFTUNE = 2, ++ MxL_ERR_SET_REG = 3, ++ MxL_ERR_GET_REG = 4, ++ MxL_ERR_OTHERS = 10 ++}MxL_ERR_MSG; ++ ++/******************************/ ++/* MxL5007 Chip verstion */ ++/******************************/ ++typedef enum{ ++ MxL_UNKNOWN_ID = 0x00, ++ MxL_5007T_V4 = 0x14, ++ MxL_GET_ID_FAIL = 0xFF ++}MxL5007_ChipVersion; ++ ++ ++/****************************************************************************** ++ CONSTANTS ++******************************************************************************/ ++ ++#ifndef MHz ++ #define MHz 1000000 ++#endif ++ ++#define MAX_ARRAY_SIZE 100 ++ ++ ++// Enumeration of Mode ++// Enumeration of Mode ++typedef enum ++{ ++ MxL_MODE_ISDBT = 0, ++ MxL_MODE_DVBT = 1, ++ MxL_MODE_ATSC = 2, ++ MxL_MODE_CABLE = 0x10 ++} MxL5007_Mode ; ++ ++typedef enum ++{ ++ MxL_IF_4_MHZ = 4000000, ++ MxL_IF_4_5_MHZ = 4500000, ++ MxL_IF_4_57_MHZ = 4570000, ++ MxL_IF_5_MHZ = 5000000, ++ MxL_IF_5_38_MHZ = 5380000, ++ MxL_IF_6_MHZ = 6000000, ++ MxL_IF_6_28_MHZ = 6280000, ++ MxL_IF_9_1915_MHZ = 9191500, ++ MxL_IF_35_25_MHZ = 35250000, ++ MxL_IF_36_15_MHZ = 36150000, ++ MxL_IF_44_MHZ = 44000000 ++} MxL5007_IF_Freq ; ++ ++typedef enum ++{ ++ MxL_XTAL_16_MHZ = 16000000, ++ MxL_XTAL_20_MHZ = 20000000, ++ MxL_XTAL_20_25_MHZ = 20250000, ++ MxL_XTAL_20_48_MHZ = 20480000, ++ MxL_XTAL_24_MHZ = 24000000, ++ MxL_XTAL_25_MHZ = 25000000, ++ MxL_XTAL_25_14_MHZ = 25140000, ++ MxL_XTAL_27_MHZ = 27000000, ++ MxL_XTAL_28_8_MHZ = 28800000, ++ MxL_XTAL_32_MHZ = 32000000, ++ MxL_XTAL_40_MHZ = 40000000, ++ MxL_XTAL_44_MHZ = 44000000, ++ MxL_XTAL_48_MHZ = 48000000, ++ MxL_XTAL_49_3811_MHZ = 49381100 ++} MxL5007_Xtal_Freq ; ++ ++typedef enum ++{ ++ MxL_BW_6MHz = 6, ++ MxL_BW_7MHz = 7, ++ MxL_BW_8MHz = 8 ++} MxL5007_BW_MHz; ++ ++typedef enum ++{ ++ MxL_NORMAL_IF = 0 , ++ MxL_INVERT_IF ++ ++} MxL5007_IF_Spectrum ; ++ ++typedef enum ++{ ++ MxL_LT_DISABLE = 0 , ++ MxL_LT_ENABLE ++ ++} MxL5007_LoopThru ; ++ ++typedef enum ++{ ++ MxL_CLKOUT_DISABLE = 0 , ++ MxL_CLKOUT_ENABLE ++ ++} MxL5007_ClkOut; ++ ++typedef enum ++{ ++ MxL_CLKOUT_AMP_0 = 0 , ++ MxL_CLKOUT_AMP_1, ++ MxL_CLKOUT_AMP_2, ++ MxL_CLKOUT_AMP_3, ++ MxL_CLKOUT_AMP_4, ++ MxL_CLKOUT_AMP_5, ++ MxL_CLKOUT_AMP_6, ++ MxL_CLKOUT_AMP_7 ++} MxL5007_ClkOut_Amp; ++ ++typedef enum ++{ ++ MxL_I2C_ADDR_96 = 96 , ++ MxL_I2C_ADDR_97 = 97 , ++ MxL_I2C_ADDR_98 = 98 , ++ MxL_I2C_ADDR_99 = 99 ++} MxL5007_I2CAddr ; ++/* ++// ++// MxL5007 TunerConfig Struct ++// ++typedef struct _MxL5007_TunerConfigS ++{ ++ MxL5007_I2CAddr I2C_Addr; ++ MxL5007_Mode Mode; ++ SINT32 IF_Diff_Out_Level; ++ MxL5007_Xtal_Freq Xtal_Freq; ++ MxL5007_IF_Freq IF_Freq; ++ MxL5007_IF_Spectrum IF_Spectrum; ++ MxL5007_ClkOut ClkOut_Setting; ++ MxL5007_ClkOut_Amp ClkOut_Amp; ++ MxL5007_BW_MHz BW_MHz; ++ UINT32 RF_Freq_Hz; ++ ++ // Additional definition ++ TUNER_MODULE *pTuner; ++ ++} MxL5007_TunerConfigS; ++*/ ++ ++ ++ ++//#endif /* __MXL5007_COMMON_H__*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007.h ++ ++ ++ ++/* ++ ++ Driver APIs for MxL5007 Tuner ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL5007.h ++ ++ */ ++ ++ ++//#include "MxL5007_Common.h" ++ ++ ++typedef struct ++{ ++ UINT8 Num; //Register number ++ UINT8 Val; //Register value ++} IRVType, *PIRVType; ++ ++ ++UINT32 MxL5007_Init(UINT8* pArray, // a array pointer that store the addr and data pairs for I2C write ++ UINT32* Array_Size, // a integer pointer that store the number of element in above array ++ UINT8 Mode, ++ SINT32 IF_Diff_Out_Level, ++ UINT32 Xtal_Freq_Hz, ++ UINT32 IF_Freq_Hz, ++ UINT8 Invert_IF, ++ UINT8 Clk_Out_Enable, ++ UINT8 Clk_Out_Amp ++ ); ++UINT32 MxL5007_RFTune(UINT8* pArray, UINT32* Array_Size, ++ UINT32 RF_Freq, // RF Frequency in Hz ++ UINT8 BWMHz // Bandwidth in MHz ++ ); ++UINT32 SetIRVBit(PIRVType pIRV, UINT8 Num, UINT8 Mask, UINT8 Val); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// MaxLinear source code - MxL5007.h ++ ++ ++ ++/* ++ ++ Driver APIs for MxL5007 Tuner ++ ++ Copyright, Maxlinear, Inc. ++ All Rights Reserved ++ ++ File Name: MxL5007_API.h ++ ++ */ ++//#ifndef __MxL5007_API_H ++//#define __MxL5007_API_H ++ ++//#include "MxL5007_Common.h" ++ ++/****************************************************************************** ++** ++** Name: MxL_Set_Register ++** ++** Description: Write one register to MxL5007 ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** RegAddr - Register address to be written ++** RegData - Data to be written ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_SET_REG if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Set_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 RegData); ++ ++/****************************************************************************** ++** ++** Name: MxL_Get_Register ++** ++** Description: Read one register from MxL5007 ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** RegAddr - Register address to be read ++** RegData - Pointer to register read ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_GET_REG if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Get_Register(MxL5007_TunerConfigS* myTuner, UINT8 RegAddr, UINT8 *RegData); ++ ++/****************************************************************************** ++** ++** Name: MxL_Tuner_Init ++** ++** Description: MxL5007 Initialization ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_INIT if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Tuner_Init(MxL5007_TunerConfigS* ); ++ ++/****************************************************************************** ++** ++** Name: MxL_Tuner_RFTune ++** ++** Description: Frequency tunning for channel ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** RF_Freq_Hz - RF Frequency in Hz ++** BWMHz - Bandwidth 6, 7 or 8 MHz ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_RFTUNE if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Tuner_RFTune(MxL5007_TunerConfigS*, UINT32 RF_Freq_Hz, MxL5007_BW_MHz BWMHz); ++ ++/****************************************************************************** ++** ++** Name: MxL_Soft_Reset ++** ++** Description: Software Reset the MxL5007 Tuner ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Soft_Reset(MxL5007_TunerConfigS*); ++ ++/****************************************************************************** ++** ++** Name: MxL_Loop_Through_On ++** ++** Description: Turn On/Off on-chip Loop-through ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** isOn - True to turn On Loop Through ++** - False to turn off Loop Through ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Loop_Through_On(MxL5007_TunerConfigS*, MxL5007_LoopThru); ++ ++/****************************************************************************** ++** ++** Name: MxL_Standby ++** ++** Description: Enter Standby Mode ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Stand_By(MxL5007_TunerConfigS*); ++ ++/****************************************************************************** ++** ++** Name: MxL_Wakeup ++** ++** Description: Wakeup from Standby Mode (Note: after wake up, please call RF_Tune again) ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_Wake_Up(MxL5007_TunerConfigS*); ++ ++/****************************************************************************** ++** ++** Name: MxL_Check_ChipVersion ++** ++** Description: Return the MxL5007 Chip ID ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** ++** Returns: MxL_ChipVersion ++** ++******************************************************************************/ ++MxL5007_ChipVersion MxL_Check_ChipVersion(MxL5007_TunerConfigS*); ++ ++/****************************************************************************** ++** ++** Name: MxL_RFSynth_Lock_Status ++** ++** Description: RF synthesizer lock status of MxL5007 ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** isLock - Pointer to Lock Status ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_RFSynth_Lock_Status(MxL5007_TunerConfigS* , BOOL* isLock); ++ ++/****************************************************************************** ++** ++** Name: MxL_REFSynth_Lock_Status ++** ++** Description: REF synthesizer lock status of MxL5007 ++** ++** Parameters: myTuner - Pointer to MxL5007_TunerConfigS ++** isLock - Pointer to Lock Status ++** ++** Returns: MxL_ERR_MSG - MxL_OK if success ++** - MxL_ERR_OTHERS if fail ++** ++******************************************************************************/ ++MxL_ERR_MSG MxL_REFSynth_Lock_Status(MxL5007_TunerConfigS* , BOOL* isLock); ++ ++//#endif //__MxL5007_API_H ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is MxL5007T tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Standard mode ++enum MXL5007T_STANDARD_MODE ++{ ++ MXL5007T_STANDARD_DVBT, ++ MXL5007T_STANDARD_ATSC, ++ MXL5007T_STANDARD_QAM, ++ MXL5007T_STANDARD_ISDBT, ++}; ++ ++ ++// Loop-through mode ++enum MXL5007T_LOOP_THROUGH_MODE ++{ ++ MXL5007T_LOOP_THROUGH_DISABLE = MxL_LT_DISABLE, ++ MXL5007T_LOOP_THROUGH_ENABLE = MxL_LT_ENABLE, ++}; ++ ++ ++// Clock output mode ++enum MXL5007T_CLK_OUT_MODE ++{ ++ MXL5007T_CLK_OUT_DISABLE, ++ MXL5007T_CLK_OUT_ENABLE, ++}; ++ ++ ++// Clock output amplitude mode ++enum MXL5007T_CLK_OUT_AMP_MODE ++{ ++ MXL5007T_CLK_OUT_AMP_0, ++ MXL5007T_CLK_OUT_AMP_1, ++ MXL5007T_CLK_OUT_AMP_2, ++ MXL5007T_CLK_OUT_AMP_3, ++ MXL5007T_CLK_OUT_AMP_4, ++ MXL5007T_CLK_OUT_AMP_5, ++ MXL5007T_CLK_OUT_AMP_6, ++ MXL5007T_CLK_OUT_AMP_7, ++}; ++ ++ ++// Bandwidth mode ++enum MXL5007T_BANDWIDTH_MODE ++{ ++ MXL5007T_BANDWIDTH_6000000HZ, ++ MXL5007T_BANDWIDTH_7000000HZ, ++ MXL5007T_BANDWIDTH_8000000HZ, ++}; ++ ++ ++ ++// Constant ++#define MXL5007T_I2C_READING_CONST 0xfb ++ ++// Default value ++#define MXL5007T_RF_FREQ_HZ_DEFAULT 44000000; ++#define MXL5007T_BANDWIDTH_MODE_DEFAULT MxL_BW_6MHz; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildMxl5007tModule( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int StandardMode, ++ unsigned long IfFreqHz, ++ int SpectrumMode, ++ int LoopThroughMode, ++ int ClkOutMode, ++ int ClkOutAmpMode, ++ long QamIfDiffOutLevel ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++mxl5007t_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++mxl5007t_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++mxl5007t_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++mxl5007t_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++mxl5007t_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++mxl5007t_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++mxl5007t_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_r820t.c b/drivers/drivers/media/dvb/dvb-usb/tuner_r820t.c +--- a/drivers/media/dvb/dvb-usb/tuner_r820t.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_r820t.c 2016-04-02 19:17:52.152066045 -0300 +@@ -0,0 +1,3453 @@ ++/** ++ ++@file ++ ++@brief R820T tuner module definition ++ ++One can manipulate R820T tuner through R820T module. ++R820T module is derived from tuner module. ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_r820t.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief R820T tuner module builder ++ ++Use BuildR820tModule() to build R820T module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to R820T tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr R820T I2C device address ++@param [in] CrystalFreqHz R820T crystal frequency in Hz ++ ++ ++@note ++ -# One should call BuildR820tModule() to build R820T module before using it. ++ ++*/ ++void ++BuildR820tModule( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned char RafaelChipID ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ R820T_EXTRA_MODULE *pExtra; ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.R820t); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_R820T; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = r820t_GetTunerType; ++ pTuner->GetDeviceAddr = r820t_GetDeviceAddr; ++ ++ pTuner->Initialize = r820t_Initialize; ++ pTuner->SetRfFreqHz = r820t_SetRfFreqHz; ++ pTuner->GetRfFreqHz = r820t_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->IsStandardModeSet = NO; ++ pExtra->Rafael_Chip = RafaelChipID; ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetStandardMode = r820t_SetStandardMode; ++ pExtra->GetStandardMode = r820t_GetStandardMode; ++ pExtra->SetStandby = r820t_SetStandby; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++r820t_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++r820t_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++r820t_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ // Initialize tuner. ++ if(R828_Init(pTuner) != RT_Success) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++r820t_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ R820T_EXTRA_MODULE *pExtra; ++ ++ R828_Set_Info R828Info; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.R820t); ++ ++ if(pExtra->IsStandardModeSet==NO) ++ goto error_status_set_tuner_rf_frequency; ++ ++ R828Info.R828_Standard = (R828_Standard_Type)pExtra->StandardMode; ++ R828Info.RF_KHz = (UINT32)(RfFreqHz /1000); ++ ++ if(R828_SetFrequency(pTuner, R828Info, NORMAL_MODE) != RT_Success) ++ goto error_status_set_tuner_rf_frequency; ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++r820t_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++/** ++ ++@brief Set R820T tuner standard mode. ++ ++*/ ++int ++r820t_SetStandardMode( ++ TUNER_MODULE *pTuner, ++ int StandardMode ++ ) ++{ ++ R820T_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.R820t); ++ ++ ++ if(R828_SetStandard(pTuner, (R828_Standard_Type)StandardMode) != RT_Success) ++ goto error_status_set_tuner_standard_mode; ++ ++ ++ // Set tuner standard mode parameter. ++ pExtra->StandardMode = StandardMode; ++ pExtra->IsStandardModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_standard_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++/** ++ ++@brief Get R820T tuner standard mode. ++ ++*/ ++int ++r820t_GetStandardMode( ++ TUNER_MODULE *pTuner, ++ int *pStandardMode ++ ) ++{ ++ R820T_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.R820t); ++ ++ ++ // Get tuner bandwidth mode from tuner module. ++ if(pExtra->IsStandardModeSet != YES) ++ goto error_status_get_tuner_standard_mode; ++ ++ *pStandardMode = pExtra->StandardMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_standard_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++/** ++ ++@brief Set R820T tuner standby ++ ++*/ ++int ++r820t_SetStandby( ++ TUNER_MODULE *pTuner, ++ int LoopThroughType ++ ) ++{ ++ ++ if(R828_Standby(pTuner, (R828_LoopThrough_Type)LoopThroughType) != RT_Success) ++ goto error_status_set_tuner_standby; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_standby: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is implemented for R820T source code. ++ ++int ++r820t_Convert(int InvertNum) ++{ ++ int ReturnNum; ++ int AddNum; ++ int BitNum; ++ int CuntNum; ++ ++ ReturnNum = 0; ++ AddNum = 0x80; ++ BitNum = 0x01; ++ ++ for(CuntNum = 0;CuntNum < 8;CuntNum ++) ++ { ++ if(BitNum & InvertNum) ++ ReturnNum += AddNum; ++ ++ AddNum /= 2; ++ BitNum *= 2; ++ } ++ ++ return ReturnNum; ++} ++ ++ ++ ++R828_ErrCode ++I2C_Write_Len(TUNER_MODULE *pTuner, R828_I2C_LEN_TYPE *I2C_Info) ++{ ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i, j; ++ ++ unsigned char RegStartAddr; ++ unsigned char *pWritingBytes; ++ unsigned long ByteNum; ++ ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ unsigned long WritingByteNum, WritingByteNumMax, WritingByteNumRem; ++ unsigned char RegWritingAddr; ++ ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = I2C_Info->RegAddr; ++ pWritingBytes = I2C_Info->Data; ++ ByteNum = (unsigned long)I2C_Info->Len; ++ ++ ++ // Calculate maximum writing byte number. ++ WritingByteNumMax = pBaseInterface->I2cWritingByteNumMax - LEN_1_BYTE; ++ ++ ++ // Set tuner register bytes with writing bytes. ++ // Note: Set tuner register bytes considering maximum writing byte number. ++ for(i = 0; i < ByteNum; i += WritingByteNumMax) ++ { ++ // Set register writing address. ++ RegWritingAddr = RegStartAddr + i; ++ ++ // Calculate remainder writing byte number. ++ WritingByteNumRem = ByteNum - i; ++ ++ // Determine writing byte number. ++ WritingByteNum = (WritingByteNumRem > WritingByteNumMax) ? WritingByteNumMax : WritingByteNumRem; ++ ++ ++ // Set writing buffer. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegWritingAddr + writing_bytes (WritingByteNum bytes) + ++ // stop_bit ++ WritingBuffer[0] = RegWritingAddr; ++ ++ for(j = 0; j < WritingByteNum; j++) ++ WritingBuffer[LEN_1_BYTE + j] = pWritingBytes[i + j]; ++ ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, WritingByteNum + LEN_1_BYTE) != ++ FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ } ++ ++ ++ return RT_Success; ++ ++ ++error_status_set_tuner_registers: ++ ++ return RT_Fail; ++ ++ ++} ++ ++ ++ ++R828_ErrCode ++I2C_Read_Len(TUNER_MODULE *pTuner, R828_I2C_LEN_TYPE *I2C_Info) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ unsigned int i; ++ ++ unsigned char RegStartAddr; ++ unsigned char ReadingBytes[I2C_BUFFER_LEN]; ++ unsigned long ByteNum; ++ ++ ++ // Get tuner module, base interface, and I2C bridge. ++ pBaseInterface = pTuner->pBaseInterface; ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Get regiser start address, writing bytes, and byte number. ++ RegStartAddr = 0x00; ++ ByteNum = (unsigned long)I2C_Info->Len; ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + RegReadingAddr + stop_bit ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegStartAddr, LEN_1_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register bytes. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + reading_bytes (ReadingByteNum bytes) + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, ReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ for(i = 0; iData[i] = (UINT8)r820t_Convert(ReadingBytes[i]); ++ } ++ ++ ++ return RT_Success; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++ ++ return RT_Fail; ++ ++ ++ ++} ++ ++ ++ ++R828_ErrCode ++I2C_Write(TUNER_MODULE *pTuner, R828_I2C_TYPE *I2C_Info) ++{ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[LEN_2_BYTE]; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr + data + stop_bit ++ WritingBuffer[0] = I2C_Info->RegAddr; ++ WritingBuffer[1] = I2C_Info->Data; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, LEN_2_BYTE) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return RT_Success; ++ ++error_status_set_tuner_registers: ++ ++ ++ return RT_Fail; ++ ++ ++} ++ ++ ++ ++ ++void ++R828_Delay_MS( ++ TUNER_MODULE *pTuner, ++ unsigned long WaitTimeMs ++ ) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ // Wait in ms. ++ pBaseInterface->WaitMs(pBaseInterface, WaitTimeMs); ++ ++ ++ return; ++} ++ ++ ++//----------------------------------------------------- ++// ++// Filename: R820T.c ++// ++// This file is R820T tuner driver ++// Copyright 2011 by Rafaelmicro., Inc. ++// ++//----------------------------------------------------- ++ ++ ++//#include "stdafx.h" ++//#include "R828.h" ++//#include "..\I2C_Sys.h" ++ ++ ++#if(TUNER_CLK_OUT==TRUE) //enable tuner clk output for share Xtal application ++UINT8 R828_iniArry[27] = {0x83, 0x32, 0x75, 0xC0, 0x40, 0xD6, 0x6C, 0xF5, 0x63, ++ /* 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D */ ++ ++ 0x75, 0x68, 0x6C, 0x83, 0x80, 0x00, 0x0F, 0x00, 0xC0,//xtal_check ++ /* 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 */ ++ ++ 0x30, 0x48, 0xCC, 0x60, 0x00, 0x54, 0xAE, 0x4A, 0xC0}; ++ /* 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F */ ++#else ++UINT8 R828_iniArry[27] = {0x83, 0x32, 0x75, 0xC0, 0x40, 0xD6, 0x6C, 0xF5, 0x63, ++ /* 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D */ ++ ++ 0x75, 0x78, 0x6C, 0x83, 0x80, 0x00, 0x0F, 0x00, 0xC0,//xtal_check ++ /* 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 */ ++ ++ 0x30, 0x48, 0xCC, 0x60, 0x00, 0x54, 0xAE, 0x4A, 0xC0}; ++ /* 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F */ ++#endif ++ ++UINT8 R828_ADDRESS=0x34; ++UINT8 Rafael_Chip = R820T; ++//----------------------------------------------------------// ++// Internal Structs // ++//----------------------------------------------------------// ++typedef struct _R828_SectType ++{ ++ UINT8 Phase_Y; ++ UINT8 Gain_X; ++ UINT16 Value; ++}R828_SectType; ++ ++typedef enum _BW_Type ++{ ++ BW_6M = 0, ++ BW_7M, ++ BW_8M, ++ BW_1_7M, ++ BW_10M, ++ BW_200K ++}BW_Type; ++ ++typedef struct _Sys_Info_Type ++{ ++ UINT16 IF_KHz; ++ BW_Type BW; ++ UINT32 FILT_CAL_LO; ++ UINT8 FILT_GAIN; ++ UINT8 IMG_R; ++ UINT8 FILT_Q; ++ UINT8 HP_COR; ++ UINT8 EXT_ENABLE; ++ UINT8 LOOP_THROUGH; ++ UINT8 LT_ATT; ++ UINT8 FLT_EXT_WIDEST; ++ UINT8 POLYFIL_CUR; ++}Sys_Info_Type; ++ ++typedef struct _Freq_Info_Type ++{ ++ UINT8 OPEN_D; ++ UINT8 RF_MUX_PLOY; ++ UINT8 TF_C; ++ UINT8 XTAL_CAP20P; ++ UINT8 XTAL_CAP10P; ++ UINT8 XTAL_CAP0P; ++ UINT8 IMR_MEM; ++}Freq_Info_Type; ++ ++ ++typedef struct _SysFreq_Info_Type ++{ ++ UINT8 LNA_TOP; ++ UINT8 LNA_VTH_L; ++ UINT8 MIXER_TOP; ++ UINT8 MIXER_VTH_L; ++ UINT8 AIR_CABLE1_IN; ++ UINT8 CABLE2_IN; ++ UINT8 PRE_DECT; ++ UINT8 LNA_DISCHARGE; ++ UINT8 CP_CUR; ++ UINT8 DIV_BUF_CUR; ++ UINT8 FILTER_CUR; ++}SysFreq_Info_Type; ++ ++//----------------------------------------------------------// ++// Internal Parameters // ++//----------------------------------------------------------// ++enum XTAL_CAP_VALUE ++{ ++ XTAL_LOW_CAP_30P = 0, ++ XTAL_LOW_CAP_20P, ++ XTAL_LOW_CAP_10P, ++ XTAL_LOW_CAP_0P, ++ XTAL_HIGH_CAP_0P ++}; ++UINT8 R828_Arry[27]; ++R828_SectType IMR_Data[5] = { ++ {0, 0, 0}, ++ {0, 0, 0}, ++ {0, 0, 0}, ++ {0, 0, 0}, ++ {0, 0, 0} ++ };//Please keep this array data for standby mode. ++R828_I2C_TYPE R828_I2C; ++R828_I2C_LEN_TYPE R828_I2C_Len; ++ ++UINT32 R828_IF_khz; ++UINT32 R828_CAL_LO_khz; ++UINT8 R828_IMR_point_num; ++UINT8 R828_IMR_done_flag = FALSE; ++UINT8 R828_Fil_Cal_flag[STD_SIZE]; ++static UINT8 R828_Fil_Cal_code[STD_SIZE]; ++ ++static UINT8 Xtal_cap_sel = XTAL_LOW_CAP_0P; ++static UINT8 Xtal_cap_sel_tmp = XTAL_LOW_CAP_0P; ++//----------------------------------------------------------// ++// Internal static struct // ++//----------------------------------------------------------// ++static SysFreq_Info_Type SysFreq_Info1; ++static Sys_Info_Type Sys_Info1; ++//static Freq_Info_Type R828_Freq_Info; ++static Freq_Info_Type Freq_Info1; ++//----------------------------------------------------------// ++// Internal Functions // ++//----------------------------------------------------------// ++R828_ErrCode R828_Xtal_Check(TUNER_MODULE *pTuner); ++R828_ErrCode R828_InitReg(TUNER_MODULE *pTuner); ++R828_ErrCode R828_IMR_Prepare(TUNER_MODULE *pTuner); ++R828_ErrCode R828_IMR(TUNER_MODULE *pTuner, UINT8 IMR_MEM, BOOL IM_Flag); ++R828_ErrCode R828_PLL(TUNER_MODULE *pTuner, UINT32 LO_Freq, R828_Standard_Type R828_Standard); ++R828_ErrCode R828_MUX(TUNER_MODULE *pTuner, UINT32 RF_KHz); ++R828_ErrCode R828_IQ(TUNER_MODULE *pTuner, R828_SectType* IQ_Pont); ++R828_ErrCode R828_IQ_Tree(TUNER_MODULE *pTuner, UINT8 FixPot, UINT8 FlucPot, UINT8 PotReg, R828_SectType* CompareTree); ++R828_ErrCode R828_CompreCor(R828_SectType* CorArry); ++R828_ErrCode R828_CompreStep(TUNER_MODULE *pTuner, R828_SectType* StepArry, UINT8 Pace); ++R828_ErrCode R828_Muti_Read(TUNER_MODULE *pTuner, UINT8 IMR_Reg, UINT16* IMR_Result_Data); ++R828_ErrCode R828_Section(TUNER_MODULE *pTuner, R828_SectType* SectionArry); ++R828_ErrCode R828_F_IMR(TUNER_MODULE *pTuner, R828_SectType* IQ_Pont); ++R828_ErrCode R828_IMR_Cross(TUNER_MODULE *pTuner, R828_SectType* IQ_Pont, UINT8* X_Direct); ++ ++Sys_Info_Type R828_Sys_Sel(R828_Standard_Type R828_Standard); ++Freq_Info_Type R828_Freq_Sel(UINT32 RF_freq); ++SysFreq_Info_Type R828_SysFreq_Sel(R828_Standard_Type R828_Standard,UINT32 RF_freq); ++ ++R828_ErrCode R828_Filt_Cal(TUNER_MODULE *pTuner, UINT32 Cal_Freq,BW_Type R828_BW); ++//R828_ErrCode R828_SetFrequency(TUNER_MODULE *pTuner, R828_Set_Info R828_INFO, R828_SetFreq_Type R828_SetFreqMode); ++ ++ ++ ++Sys_Info_Type R828_Sys_Sel(R828_Standard_Type R828_Standard) ++{ ++ Sys_Info_Type R828_Sys_Info; ++ ++ switch (R828_Standard) ++ { ++ ++ case DVB_T_6M: ++ case DVB_T2_6M: ++ R828_Sys_Info.IF_KHz=3570; ++ R828_Sys_Info.BW=BW_6M; ++ R828_Sys_Info.FILT_CAL_LO=56000; //52000->56000 ++ R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on ++ R828_Sys_Info.IMG_R=0x00; //image negative ++ R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1) ++ R828_Sys_Info.HP_COR=0x6B; // 1.7M disable, +2cap, 1.0MHz ++ R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1 ++ R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON ++ R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable ++ R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF ++ R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min ++ break; ++ ++ case DVB_T_7M: ++ case DVB_T2_7M: ++ R828_Sys_Info.IF_KHz=4070; ++ R828_Sys_Info.BW=BW_7M; ++ R828_Sys_Info.FILT_CAL_LO=60000; ++ R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on ++ R828_Sys_Info.IMG_R=0x00; //image negative ++ R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1) ++ R828_Sys_Info.HP_COR=0x2B; // 1.7M disable, +1cap, 1.0MHz ++ R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1 ++ R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON ++ R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable ++ R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF ++ R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min ++ break; ++ ++ case DVB_T_7M_2: ++ case DVB_T2_7M_2: ++ R828_Sys_Info.IF_KHz=4570; ++ R828_Sys_Info.BW=BW_7M; ++ R828_Sys_Info.FILT_CAL_LO=63000; ++ R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on ++ R828_Sys_Info.IMG_R=0x00; //image negative ++ R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1) ++ R828_Sys_Info.HP_COR=0x2A; // 1.7M disable, +1cap, 1.25MHz ++ R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1 ++ R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON ++ R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable ++ R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF ++ R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min ++ break; ++ ++ case DVB_T_8M: ++ case DVB_T2_8M: ++ R828_Sys_Info.IF_KHz=4570; ++ R828_Sys_Info.BW=BW_8M; ++ R828_Sys_Info.FILT_CAL_LO=68500; ++ R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on ++ R828_Sys_Info.IMG_R=0x00; //image negative ++ R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1) ++ R828_Sys_Info.HP_COR=0x0B; // 1.7M disable, +0cap, 1.0MHz ++ R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1 ++ R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON ++ R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable ++ R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF ++ R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min ++ break; ++ ++ case ISDB_T: ++ R828_Sys_Info.IF_KHz=4063; ++ R828_Sys_Info.BW=BW_6M; ++ R828_Sys_Info.FILT_CAL_LO=59000; ++ R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on ++ R828_Sys_Info.IMG_R=0x00; //image negative ++ R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1) ++ R828_Sys_Info.HP_COR=0x6A; // 1.7M disable, +2cap, 1.25MHz ++ R828_Sys_Info.EXT_ENABLE=0x40; //R30[6], ext enable; R30[5]:0 ext at LNA max ++ R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON ++ R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable ++ R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF ++ R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min ++ break; ++ ++ default: //DVB_T_8M ++ R828_Sys_Info.IF_KHz=4570; ++ R828_Sys_Info.BW=BW_8M; ++ R828_Sys_Info.FILT_CAL_LO=68500; ++ R828_Sys_Info.FILT_GAIN=0x10; //+3dB, 6MHz on ++ R828_Sys_Info.IMG_R=0x00; //image negative ++ R828_Sys_Info.FILT_Q=0x10; //R10[4]:low Q(1'b1) ++ R828_Sys_Info.HP_COR=0x0D; // 1.7M disable, +0cap, 0.7MHz ++ R828_Sys_Info.EXT_ENABLE=0x60; //R30[6]=1 ext enable; R30[5]:1 ext at LNA max-1 ++ R828_Sys_Info.LOOP_THROUGH=0x00; //R5[7], LT ON ++ R828_Sys_Info.LT_ATT=0x00; //R31[7], LT ATT enable ++ R828_Sys_Info.FLT_EXT_WIDEST=0x00;//R15[7]: FLT_EXT_WIDE OFF ++ R828_Sys_Info.POLYFIL_CUR=0x60; //R25[6:5]:Min ++ break; ++ ++ } ++ ++ return R828_Sys_Info; ++} ++ ++ ++ ++Freq_Info_Type R828_Freq_Sel(UINT32 LO_freq) ++{ ++ Freq_Info_Type R828_Freq_Info; ++ ++ if(LO_freq<50000) ++ { ++ R828_Freq_Info.OPEN_D=0x08; // low ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0xDF; //R27[7:0] band2,band0 ++ R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ ++ else if(LO_freq>=50000 && LO_freq<55000) ++ { ++ R828_Freq_Info.OPEN_D=0x08; // low ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0xBE; //R27[7:0] band4,band1 ++ R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ else if( LO_freq>=55000 && LO_freq<60000) ++ { ++ R828_Freq_Info.OPEN_D=0x08; // low ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x8B; //R27[7:0] band7,band4 ++ R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ else if( LO_freq>=60000 && LO_freq<65000) ++ { ++ R828_Freq_Info.OPEN_D=0x08; // low ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x7B; //R27[7:0] band8,band4 ++ R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ else if( LO_freq>=65000 && LO_freq<70000) ++ { ++ R828_Freq_Info.OPEN_D=0x08; // low ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x69; //R27[7:0] band9,band6 ++ R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ else if( LO_freq>=70000 && LO_freq<75000) ++ { ++ R828_Freq_Info.OPEN_D=0x08; // low ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x58; //R27[7:0] band10,band7 ++ R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ else if( LO_freq>=75000 && LO_freq<80000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x44; //R27[7:0] band11,band11 ++ R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ else if( LO_freq>=80000 && LO_freq<90000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x44; //R27[7:0] band11,band11 ++ R828_Freq_Info.XTAL_CAP20P=0x02; //R16[1:0] 20pF (10) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ else if( LO_freq>=90000 && LO_freq<100000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x34; //R27[7:0] band12,band11 ++ R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ else if( LO_freq>=100000 && LO_freq<110000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x34; //R27[7:0] band12,band11 ++ R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 0; ++ } ++ else if( LO_freq>=110000 && LO_freq<120000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x24; //R27[7:0] band13,band11 ++ R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 1; ++ } ++ else if( LO_freq>=120000 && LO_freq<140000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x24; //R27[7:0] band13,band11 ++ R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 1; ++ } ++ else if( LO_freq>=140000 && LO_freq<180000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x14; //R27[7:0] band14,band11 ++ R828_Freq_Info.XTAL_CAP20P=0x01; //R16[1:0] 10pF (01) ++ R828_Freq_Info.XTAL_CAP10P=0x01; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 1; ++ } ++ else if( LO_freq>=180000 && LO_freq<220000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x13; //R27[7:0] band14,band12 ++ R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00) ++ R828_Freq_Info.XTAL_CAP10P=0x00; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 1; ++ } ++ else if( LO_freq>=220000 && LO_freq<250000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x13; //R27[7:0] band14,band12 ++ R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00) ++ R828_Freq_Info.XTAL_CAP10P=0x00; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 2; ++ } ++ else if( LO_freq>=250000 && LO_freq<280000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x11; //R27[7:0] highest,highest ++ R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00) ++ R828_Freq_Info.XTAL_CAP10P=0x00; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 2; ++ } ++ else if( LO_freq>=280000 && LO_freq<310000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x02; //R26[7:6]=0 (LPF) R26[1:0]=2 (low) ++ R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest ++ R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00) ++ R828_Freq_Info.XTAL_CAP10P=0x00; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 2; ++ } ++ else if( LO_freq>=310000 && LO_freq<450000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x41; //R26[7:6]=1 (bypass) R26[1:0]=1 (middle) ++ R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest ++ R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00) ++ R828_Freq_Info.XTAL_CAP10P=0x00; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 2; ++ } ++ else if( LO_freq>=450000 && LO_freq<588000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x41; //R26[7:6]=1 (bypass) R26[1:0]=1 (middle) ++ R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest ++ R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00) ++ R828_Freq_Info.XTAL_CAP10P=0x00; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 3; ++ } ++ else if( LO_freq>=588000 && LO_freq<650000) ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x40; //R26[7:6]=1 (bypass) R26[1:0]=0 (highest) ++ R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest ++ R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00) ++ R828_Freq_Info.XTAL_CAP10P=0x00; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 3; ++ } ++ else ++ { ++ R828_Freq_Info.OPEN_D=0x00; // high ++ R828_Freq_Info.RF_MUX_PLOY = 0x40; //R26[7:6]=1 (bypass) R26[1:0]=0 (highest) ++ R828_Freq_Info.TF_C=0x00; //R27[7:0] highest,highest ++ R828_Freq_Info.XTAL_CAP20P=0x00; //R16[1:0] 0pF (00) ++ R828_Freq_Info.XTAL_CAP10P=0x00; ++ R828_Freq_Info.XTAL_CAP0P=0x00; ++ R828_Freq_Info.IMR_MEM = 4; ++ } ++ ++ return R828_Freq_Info; ++} ++ ++ ++ ++SysFreq_Info_Type R828_SysFreq_Sel(R828_Standard_Type R828_Standard,UINT32 RF_freq) ++{ ++ SysFreq_Info_Type R828_SysFreq_Info; ++ ++ switch(R828_Standard) ++ { ++ ++ case DVB_T_6M: ++ case DVB_T_7M: ++ case DVB_T_7M_2: ++ case DVB_T_8M: ++ if( (RF_freq==506000) || (RF_freq==666000) || (RF_freq==818000) ) ++ { ++ R828_SysFreq_Info.MIXER_TOP=0x14; // MIXER TOP:14 , TOP-1, low-discharge ++ R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2 ++ R828_SysFreq_Info.CP_CUR=0x28; //101, 0.2 ++ R828_SysFreq_Info.DIV_BUF_CUR=0x20; // 10, 200u ++ } ++ else ++ { ++ R828_SysFreq_Info.MIXER_TOP=0x24; // MIXER TOP:13 , TOP-1, low-discharge ++ R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2 ++ R828_SysFreq_Info.CP_CUR=0x38; // 111, auto ++ R828_SysFreq_Info.DIV_BUF_CUR=0x30; // 11, 150u ++ } ++ R828_SysFreq_Info.LNA_VTH_L=0x53; // LNA VTH 0.84 , VTL 0.64 ++ R828_SysFreq_Info.MIXER_VTH_L=0x75; // MIXER VTH 1.04, VTL 0.84 ++ R828_SysFreq_Info.AIR_CABLE1_IN=0x00; ++ R828_SysFreq_Info.CABLE2_IN=0x00; ++ R828_SysFreq_Info.PRE_DECT=0x40; ++ R828_SysFreq_Info.LNA_DISCHARGE=14; ++ R828_SysFreq_Info.FILTER_CUR=0x40; // 10, low ++ break; ++ ++ ++ case DVB_T2_6M: ++ case DVB_T2_7M: ++ case DVB_T2_7M_2: ++ case DVB_T2_8M: ++ R828_SysFreq_Info.MIXER_TOP=0x24; // MIXER TOP:13 , TOP-1, low-discharge ++ R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2 ++ R828_SysFreq_Info.LNA_VTH_L=0x53; // LNA VTH 0.84 , VTL 0.64 ++ R828_SysFreq_Info.MIXER_VTH_L=0x75; // MIXER VTH 1.04, VTL 0.84 ++ R828_SysFreq_Info.AIR_CABLE1_IN=0x00; ++ R828_SysFreq_Info.CABLE2_IN=0x00; ++ R828_SysFreq_Info.PRE_DECT=0x40; ++ R828_SysFreq_Info.LNA_DISCHARGE=14; ++ R828_SysFreq_Info.CP_CUR=0x38; // 111, auto ++ R828_SysFreq_Info.DIV_BUF_CUR=0x30; // 11, 150u ++ R828_SysFreq_Info.FILTER_CUR=0x40; // 10, low ++ break; ++ ++ case ISDB_T: ++ R828_SysFreq_Info.MIXER_TOP=0x24; // MIXER TOP:13 , TOP-1, low-discharge ++ R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2 ++ R828_SysFreq_Info.LNA_VTH_L=0x75; // LNA VTH 1.04 , VTL 0.84 ++ R828_SysFreq_Info.MIXER_VTH_L=0x75; // MIXER VTH 1.04, VTL 0.84 ++ R828_SysFreq_Info.AIR_CABLE1_IN=0x00; ++ R828_SysFreq_Info.CABLE2_IN=0x00; ++ R828_SysFreq_Info.PRE_DECT=0x40; ++ R828_SysFreq_Info.LNA_DISCHARGE=14; ++ R828_SysFreq_Info.CP_CUR=0x38; // 111, auto ++ R828_SysFreq_Info.DIV_BUF_CUR=0x30; // 11, 150u ++ R828_SysFreq_Info.FILTER_CUR=0x40; // 10, low ++ break; ++ ++ default: //DVB-T 8M ++ R828_SysFreq_Info.MIXER_TOP=0x24; // MIXER TOP:13 , TOP-1, low-discharge ++ R828_SysFreq_Info.LNA_TOP=0xE5; // Detect BW 3, LNA TOP:4, PreDet Top:2 ++ R828_SysFreq_Info.LNA_VTH_L=0x53; // LNA VTH 0.84 , VTL 0.64 ++ R828_SysFreq_Info.MIXER_VTH_L=0x75; // MIXER VTH 1.04, VTL 0.84 ++ R828_SysFreq_Info.AIR_CABLE1_IN=0x00; ++ R828_SysFreq_Info.CABLE2_IN=0x00; ++ R828_SysFreq_Info.PRE_DECT=0x40; ++ R828_SysFreq_Info.LNA_DISCHARGE=14; ++ R828_SysFreq_Info.CP_CUR=0x38; // 111, auto ++ R828_SysFreq_Info.DIV_BUF_CUR=0x30; // 11, 150u ++ R828_SysFreq_Info.FILTER_CUR=0x40; // 10, low ++ break; ++ ++ } //end switch ++ ++ ++//DTV use Diplexer ++#if(USE_DIPLEXER==TRUE) ++if ((Rafael_Chip==R820C) || (Rafael_Chip==R820T) || (Rafael_Chip==R828S)) ++{ ++ // Air-in (>=DIP_FREQ) & cable-1(= DIP_FREQ) ++ { ++ R828_SysFreq_Info.AIR_CABLE1_IN = 0x00; //air in, cable-1 off ++ R828_SysFreq_Info.CABLE2_IN = 0x00; //cable-2 off ++ } ++ else ++ { ++ R828_SysFreq_Info.AIR_CABLE1_IN = 0x60; //cable-1 in, air off ++ R828_SysFreq_Info.CABLE2_IN = 0x00; //cable-2 off ++ } ++} ++#endif ++ return R828_SysFreq_Info; ++ ++ } ++ ++ ++ ++ ++R828_ErrCode R828_Xtal_Check(TUNER_MODULE *pTuner) ++{ ++ ++ UINT8 ArrayNum; ++ ++ ArrayNum = 27; ++ for(ArrayNum=0;ArrayNum<27;ArrayNum++) ++ { ++ R828_Arry[ArrayNum] = R828_iniArry[ArrayNum]; ++ } ++ ++ //cap 30pF & Drive Low ++ R828_I2C.RegAddr = 0x10; ++ R828_Arry[11] = (R828_Arry[11] & 0xF4) | 0x0B ; ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //set pll autotune = 128kHz ++ R828_I2C.RegAddr = 0x1A; ++ R828_Arry[21] = R828_Arry[21] & 0xF3; ++ R828_I2C.Data = R828_Arry[21]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //set manual initial reg = 111111; ++ R828_I2C.RegAddr = 0x13; ++ R828_Arry[14] = (R828_Arry[14] & 0x80) | 0x7F; ++ R828_I2C.Data = R828_Arry[14]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //set auto ++ R828_I2C.RegAddr = 0x13; ++ R828_Arry[14] = (R828_Arry[14] & 0xBF); ++ R828_I2C.Data = R828_Arry[14]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Delay_MS(pTuner, 5); ++ ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 3; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ // if 30pF unlock, set to cap 20pF ++#if (USE_16M_XTAL==TRUE) ++ //VCO=2360MHz for 16M Xtal. VCO band 26 ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23)) ++#else ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F)) ++#endif ++ { ++ //cap 20pF ++ R828_I2C.RegAddr = 0x10; ++ R828_Arry[11] = (R828_Arry[11] & 0xFC) | 0x02; ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Delay_MS(pTuner, 5); ++ ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 3; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ // if 20pF unlock, set to cap 10pF ++#if (USE_16M_XTAL==TRUE) ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23)) ++#else ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F)) ++#endif ++ { ++ //cap 10pF ++ R828_I2C.RegAddr = 0x10; ++ R828_Arry[11] = (R828_Arry[11] & 0xFC) | 0x01; ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Delay_MS(pTuner, 5); ++ ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 3; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ // if 10pF unlock, set to cap 0pF ++#if (USE_16M_XTAL==TRUE) ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23)) ++#else ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F)) ++#endif ++ { ++ //cap 0pF ++ R828_I2C.RegAddr = 0x10; ++ R828_Arry[11] = (R828_Arry[11] & 0xFC) | 0x00; ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Delay_MS(pTuner, 5); ++ ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 3; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ // if unlock, set to high drive ++#if (USE_16M_XTAL==TRUE) ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23)) ++#else ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F)) ++#endif ++ { ++ //X'tal drive high ++ R828_I2C.RegAddr = 0x10; ++ R828_Arry[11] = (R828_Arry[11] & 0xF7) ; ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //R828_Delay_MS(15); ++ R828_Delay_MS(pTuner, 20); ++ ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 3; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++#if (USE_16M_XTAL==TRUE) ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) > 29) || ((R828_I2C_Len.Data[2] & 0x3F) < 23)) ++#else ++ if(((R828_I2C_Len.Data[2] & 0x40) == 0x00) || ((R828_I2C_Len.Data[2] & 0x3F) == 0x3F)) ++#endif ++ { ++ return RT_Fail; ++ } ++ else //0p+high drive lock ++ { ++ Xtal_cap_sel_tmp = XTAL_HIGH_CAP_0P; ++ } ++ } ++ else //0p lock ++ { ++ Xtal_cap_sel_tmp = XTAL_LOW_CAP_0P; ++ } ++ } ++ else //10p lock ++ { ++ Xtal_cap_sel_tmp = XTAL_LOW_CAP_10P; ++ } ++ } ++ else //20p lock ++ { ++ Xtal_cap_sel_tmp = XTAL_LOW_CAP_20P; ++ } ++ } ++ else // 30p lock ++ { ++ Xtal_cap_sel_tmp = XTAL_LOW_CAP_30P; ++ } ++ ++ return RT_Success; ++} ++R828_ErrCode R828_Init(TUNER_MODULE *pTuner) ++{ ++ R820T_EXTRA_MODULE *pExtra; ++ UINT8 i; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.R820t); ++ ++ //write initial reg ++ //if(R828_InitReg(pTuner) != RT_Success) ++ // return RT_Fail; ++ ++ if(R828_IMR_done_flag==FALSE) ++ { ++ ++ //write initial reg ++ if(R828_InitReg(pTuner) != RT_Success) ++ return RT_Fail; ++ ++ //Do Xtal check ++ if((Rafael_Chip==R820T) || (Rafael_Chip==R828S) || (Rafael_Chip==R820C)) ++ { ++ Xtal_cap_sel = XTAL_HIGH_CAP_0P; ++ } ++ else ++ { ++ if(R828_Xtal_Check(pTuner) != RT_Success) //1st ++ return RT_Fail; ++ ++ Xtal_cap_sel = Xtal_cap_sel_tmp; ++ ++ if(R828_Xtal_Check(pTuner) != RT_Success) //2nd ++ return RT_Fail; ++ ++ if(Xtal_cap_sel_tmp > Xtal_cap_sel) ++ { ++ Xtal_cap_sel = Xtal_cap_sel_tmp; ++ } ++ ++ if(R828_Xtal_Check(pTuner) != RT_Success) //3rd ++ return RT_Fail; ++ ++ if(Xtal_cap_sel_tmp > Xtal_cap_sel) ++ { ++ Xtal_cap_sel = Xtal_cap_sel_tmp; ++ } ++ ++ } ++ ++ //reset filter cal. ++ for (i=0; i24000) ++ RingRef = R828_Xtal /2; ++ else ++ RingRef = R828_Xtal; ++ ++ for(n=0;n<16;n++) ++ { ++ if((16+n)* 8 * RingRef >= 3100000) ++ { ++ n_ring=n; ++ break; ++ } ++ ++ if(n==15) //n_ring not found ++ { ++ //return RT_Fail; ++ n_ring=n; ++ } ++ ++ } ++ ++ R828_Arry[19] &= 0xF0; //set ring[3:0] ++ R828_Arry[19] |= n_ring; ++ RingVCO = (16+n_ring)* 8 * RingRef; ++ R828_Arry[19]&=0xDF; //clear ring_se23 ++ R828_Arry[20]&=0xFC; //clear ring_seldiv ++ R828_Arry[26]&=0xFC; //clear ring_att ++ ++ switch(IMR_MEM) ++ { ++ case 0: ++ RingFreq = RingVCO/48; ++ R828_Arry[19]|=0x20; // ring_se23 = 1 ++ R828_Arry[20]|=0x03; // ring_seldiv = 3 ++ R828_Arry[26]|=0x02; // ring_att 10 ++ break; ++ case 1: ++ RingFreq = RingVCO/16; ++ R828_Arry[19]|=0x00; // ring_se23 = 0 ++ R828_Arry[20]|=0x02; // ring_seldiv = 2 ++ R828_Arry[26]|=0x00; // pw_ring 00 ++ break; ++ case 2: ++ RingFreq = RingVCO/8; ++ R828_Arry[19]|=0x00; // ring_se23 = 0 ++ R828_Arry[20]|=0x01; // ring_seldiv = 1 ++ R828_Arry[26]|=0x03; // pw_ring 11 ++ break; ++ case 3: ++ RingFreq = RingVCO/6; ++ R828_Arry[19]|=0x20; // ring_se23 = 1 ++ R828_Arry[20]|=0x00; // ring_seldiv = 0 ++ R828_Arry[26]|=0x03; // pw_ring 11 ++ break; ++ case 4: ++ RingFreq = RingVCO/4; ++ R828_Arry[19]|=0x00; // ring_se23 = 0 ++ R828_Arry[20]|=0x00; // ring_seldiv = 0 ++ R828_Arry[26]|=0x01; // pw_ring 01 ++ break; ++ default: ++ RingFreq = RingVCO/4; ++ R828_Arry[19]|=0x00; // ring_se23 = 0 ++ R828_Arry[20]|=0x00; // ring_seldiv = 0 ++ R828_Arry[26]|=0x01; // pw_ring 01 ++ break; ++ } ++ ++ ++ //write pw_ring,n_ring,ringdiv2 to I2C ++ ++ //------------n_ring,ring_se23----------// ++ R828_I2C.RegAddr = 0x18; ++ R828_I2C.Data = R828_Arry[19]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ //------------ring_sediv----------------// ++ R828_I2C.RegAddr = 0x19; ++ R828_I2C.Data = R828_Arry[20]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ //------------pw_ring-------------------// ++ R828_I2C.RegAddr = 0x1f; ++ R828_I2C.Data = R828_Arry[26]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //Must do before PLL() ++ if(R828_MUX(pTuner, RingFreq - 5300) != RT_Success) //MUX input freq ~ RF_in Freq ++ return RT_Fail; ++ ++ if(R828_PLL(pTuner, (RingFreq - 5300), STD_SIZE) != RT_Success) //set pll freq = ring freq - 6M ++ return RT_Fail; ++ ++ if(IM_Flag == TRUE) ++ { ++ if(R828_IQ(pTuner, &IMR_POINT) != RT_Success) ++ return RT_Fail; ++ } ++ else ++ { ++ IMR_POINT.Gain_X = IMR_Data[3].Gain_X; ++ IMR_POINT.Phase_Y = IMR_Data[3].Phase_Y; ++ IMR_POINT.Value = IMR_Data[3].Value; ++ if(R828_F_IMR(pTuner, &IMR_POINT) != RT_Success) ++ return RT_Fail; ++ } ++ ++ //Save IMR Value ++ switch(IMR_MEM) ++ { ++ case 0: ++ IMR_Data[0].Gain_X = IMR_POINT.Gain_X; ++ IMR_Data[0].Phase_Y = IMR_POINT.Phase_Y; ++ IMR_Data[0].Value = IMR_POINT.Value; ++ break; ++ case 1: ++ IMR_Data[1].Gain_X = IMR_POINT.Gain_X; ++ IMR_Data[1].Phase_Y = IMR_POINT.Phase_Y; ++ IMR_Data[1].Value = IMR_POINT.Value; ++ break; ++ case 2: ++ IMR_Data[2].Gain_X = IMR_POINT.Gain_X; ++ IMR_Data[2].Phase_Y = IMR_POINT.Phase_Y; ++ IMR_Data[2].Value = IMR_POINT.Value; ++ break; ++ case 3: ++ IMR_Data[3].Gain_X = IMR_POINT.Gain_X; ++ IMR_Data[3].Phase_Y = IMR_POINT.Phase_Y; ++ IMR_Data[3].Value = IMR_POINT.Value; ++ break; ++ case 4: ++ IMR_Data[4].Gain_X = IMR_POINT.Gain_X; ++ IMR_Data[4].Phase_Y = IMR_POINT.Phase_Y; ++ IMR_Data[4].Value = IMR_POINT.Value; ++ break; ++ default: ++ IMR_Data[4].Gain_X = IMR_POINT.Gain_X; ++ IMR_Data[4].Phase_Y = IMR_POINT.Phase_Y; ++ IMR_Data[4].Value = IMR_POINT.Value; ++ break; ++ } ++ return RT_Success; ++} ++ ++ ++ ++ ++ ++ ++R828_ErrCode R828_PLL(TUNER_MODULE *pTuner, UINT32 LO_Freq, R828_Standard_Type R828_Standard) ++{ ++ ++ R820T_EXTRA_MODULE *pExtra; ++ ++ UINT8 MixDiv; ++ UINT8 DivBuf; ++ UINT8 Ni; ++ UINT8 Si; ++ UINT8 DivNum; ++ UINT8 Nint; ++ UINT32 VCO_Min; ++ UINT32 VCO_Max; ++ UINT32 VCO_Freq; ++ UINT32 PLL_Ref; //Max 24000 (kHz) ++ UINT32 VCO_Fra; //VCO contribution by SDM (kHz) ++ UINT16 Nsdm; ++ UINT16 SDM; ++ UINT16 SDM16to9; ++ UINT16 SDM8to1; ++ //UINT8 Judge = 0; ++ UINT8 VCO_fine_tune; ++ ++ ++ MixDiv = 2; ++ DivBuf = 0; ++ Ni = 0; ++ Si = 0; ++ DivNum = 0; ++ Nint = 0; ++ VCO_Min = 1770000; ++ VCO_Max = VCO_Min*2; ++ VCO_Freq = 0; ++ PLL_Ref = 0; //Max 24000 (kHz) ++ VCO_Fra = 0; //VCO contribution by SDM (kHz) ++ Nsdm = 2; ++ SDM = 0; ++ SDM16to9 = 0; ++ SDM8to1 = 0; ++ //UINT8 Judge = 0; ++ VCO_fine_tune = 0; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.R820t); ++ ++ ++if ((pExtra->Rafael_Chip==R620D) || (pExtra->Rafael_Chip==R828D) || (pExtra->Rafael_Chip==R828)) //X'tal can't not exceed 20MHz for ATV ++{ ++ if(R828_Standard <= SECAM_L1) //ref set refdiv2, reffreq = Xtal/2 on ATV application ++ { ++ R828_Arry[11] |= 0x10; //b4=1 ++ PLL_Ref = R828_Xtal /2; ++ } ++ else //DTV, FilCal, IMR ++ { ++ R828_Arry[11] &= 0xEF; ++ PLL_Ref = R828_Xtal; ++ } ++} ++else ++{ ++ if(R828_Xtal > 24000) ++ { ++ R828_Arry[11] |= 0x10; //b4=1 ++ PLL_Ref = R828_Xtal /2; ++ } ++ else ++ { ++ R828_Arry[11] &= 0xEF; ++ PLL_Ref = R828_Xtal; ++ } ++} ++ ++ R828_I2C.RegAddr = 0x10; ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //set pll autotune = 128kHz ++ R828_I2C.RegAddr = 0x1A; ++ R828_Arry[21] = R828_Arry[21] & 0xF3; ++ R828_I2C.Data = R828_Arry[21]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //Set VCO current = 100 ++ R828_I2C.RegAddr = 0x12; ++ R828_Arry[13] = (R828_Arry[13] & 0x1F) | 0x80; ++ R828_I2C.Data = R828_Arry[13]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //Divider ++ while(MixDiv <= 64) ++ { ++ if(((LO_Freq * MixDiv) >= VCO_Min) && ((LO_Freq * MixDiv) < VCO_Max)) ++ { ++ DivBuf = MixDiv; ++ while(DivBuf > 2) ++ { ++ DivBuf = DivBuf >> 1; ++ DivNum ++; ++ } ++ break; ++ } ++ MixDiv = MixDiv << 1; ++ } ++ ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 5; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ VCO_fine_tune = (R828_I2C_Len.Data[4] & 0x30)>>4; ++ ++ if(VCO_fine_tune > VCO_pwr_ref) ++ DivNum = DivNum - 1; ++ else if(VCO_fine_tune < VCO_pwr_ref) ++ DivNum = DivNum + 1; ++ ++ R828_I2C.RegAddr = 0x10; ++ R828_Arry[11] &= 0x1F; ++ R828_Arry[11] |= (DivNum << 5); ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ VCO_Freq = LO_Freq * MixDiv; ++ Nint = (UINT8) (VCO_Freq / 2 / PLL_Ref); ++ VCO_Fra = (UINT16) (VCO_Freq - 2 * PLL_Ref * Nint); ++ ++ //boundary spur prevention ++ if (VCO_Fra < PLL_Ref/64) //2*PLL_Ref/128 ++ VCO_Fra = 0; ++ else if (VCO_Fra > PLL_Ref*127/64) //2*PLL_Ref*127/128 ++ { ++ VCO_Fra = 0; ++ Nint ++; ++ } ++ else if((VCO_Fra > PLL_Ref*127/128) && (VCO_Fra < PLL_Ref)) //> 2*PLL_Ref*127/256, < 2*PLL_Ref*128/256 ++ VCO_Fra = PLL_Ref*127/128; // VCO_Fra = 2*PLL_Ref*127/256 ++ else if((VCO_Fra > PLL_Ref) && (VCO_Fra < PLL_Ref*129/128)) //> 2*PLL_Ref*128/256, < 2*PLL_Ref*129/256 ++ VCO_Fra = PLL_Ref*129/128; // VCO_Fra = 2*PLL_Ref*129/256 ++ else ++ VCO_Fra = VCO_Fra; ++ ++ //N & S ++ Ni = (Nint - 13) / 4; ++ Si = Nint - 4 *Ni - 13; ++ R828_I2C.RegAddr = 0x14; ++ R828_Arry[15] = 0x00; ++ R828_Arry[15] |= (Ni + (Si << 6)); ++ R828_I2C.Data = R828_Arry[15]; ++ ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //pw_sdm ++ R828_I2C.RegAddr = 0x12; ++ R828_Arry[13] &= 0xF7; ++ if(VCO_Fra == 0) ++ R828_Arry[13] |= 0x08; ++ R828_I2C.Data = R828_Arry[13]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //SDM calculator ++ while(VCO_Fra > 1) ++ { ++ if (VCO_Fra > (2*PLL_Ref / Nsdm)) ++ { ++ SDM = SDM + 32768 / (Nsdm/2); ++ VCO_Fra = VCO_Fra - 2*PLL_Ref / Nsdm; ++ if (Nsdm >= 0x8000) ++ break; ++ } ++ Nsdm = Nsdm << 1; ++ } ++ ++ SDM16to9 = SDM >> 8; ++ SDM8to1 = SDM - (SDM16to9 << 8); ++ ++ R828_I2C.RegAddr = 0x16; ++ R828_Arry[17] = (UINT8) SDM16to9; ++ R828_I2C.Data = R828_Arry[17]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ R828_I2C.RegAddr = 0x15; ++ R828_Arry[16] = (UINT8) SDM8to1; ++ R828_I2C.Data = R828_Arry[16]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++// R828_Delay_MS(10); ++ ++if ((pExtra->Rafael_Chip==R620D) || (pExtra->Rafael_Chip==R828D) || (pExtra->Rafael_Chip==R828)) ++{ ++ if(R828_Standard <= SECAM_L1) ++ R828_Delay_MS(pTuner, 20); ++ else ++ R828_Delay_MS(pTuner, 10); ++} ++else ++ R828_Delay_MS(pTuner, 10); ++ ++ ++ //check PLL lock status ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 3; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ if( (R828_I2C_Len.Data[2] & 0x40) == 0x00 ) ++ { ++ R828_I2C.RegAddr = 0x12; ++ R828_Arry[13] = (R828_Arry[13] & 0x1F) | 0x60; //increase VCO current ++ R828_I2C.Data = R828_Arry[13]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ } ++ ++ //set pll autotune = 8kHz ++ R828_I2C.RegAddr = 0x1A; ++ R828_Arry[21] = R828_Arry[21] | 0x08; ++ R828_I2C.Data = R828_Arry[21]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ return RT_Success; ++ ++} ++ ++ ++ ++ ++ ++R828_ErrCode R828_MUX(TUNER_MODULE *pTuner, UINT32 RF_KHz) ++{ ++ UINT8 RT_Reg08; ++ UINT8 RT_Reg09; ++ ++ RT_Reg08 = 0; ++ RT_Reg09 = 0; ++ ++ //Freq_Info_Type Freq_Info1; ++ Freq_Info1 = R828_Freq_Sel(RF_KHz); ++ ++ ++ // Open Drain ++ R828_I2C.RegAddr = 0x17; ++ R828_Arry[18] = (R828_Arry[18] & 0xF7) | Freq_Info1.OPEN_D; ++ R828_I2C.Data = R828_Arry[18]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ // RF_MUX,Polymux ++ R828_I2C.RegAddr = 0x1A; ++ R828_Arry[21] = (R828_Arry[21] & 0x3C) | Freq_Info1.RF_MUX_PLOY; ++ R828_I2C.Data = R828_Arry[21]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // TF BAND ++ R828_I2C.RegAddr = 0x1B; ++ R828_Arry[22] &= 0x00; ++ R828_Arry[22] |= Freq_Info1.TF_C; ++ R828_I2C.Data = R828_Arry[22]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ // XTAL CAP & Drive ++ R828_I2C.RegAddr = 0x10; ++ R828_Arry[11] &= 0xF4; ++ switch(Xtal_cap_sel) ++ { ++ case XTAL_LOW_CAP_30P: ++ case XTAL_LOW_CAP_20P: ++ R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP20P | 0x08; ++ break; ++ ++ case XTAL_LOW_CAP_10P: ++ R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP10P | 0x08; ++ break; ++ ++ case XTAL_LOW_CAP_0P: ++ R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP0P | 0x08; ++ break; ++ ++ case XTAL_HIGH_CAP_0P: ++ R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP0P | 0x00; ++ break; ++ ++ default: ++ R828_Arry[11] = R828_Arry[11] | Freq_Info1.XTAL_CAP0P | 0x08; ++ break; ++ } ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ //Set_IMR ++ if(R828_IMR_done_flag == TRUE) ++ { ++ RT_Reg08 = IMR_Data[Freq_Info1.IMR_MEM].Gain_X & 0x3F; ++ RT_Reg09 = IMR_Data[Freq_Info1.IMR_MEM].Phase_Y & 0x3F; ++ } ++ else ++ { ++ RT_Reg08 = 0; ++ RT_Reg09 = 0; ++ } ++ ++ R828_I2C.RegAddr = 0x08; ++ R828_Arry[3] = R828_iniArry[3] & 0xC0; ++ R828_Arry[3] = R828_Arry[3] | RT_Reg08; ++ R828_I2C.Data = R828_Arry[3]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x09; ++ R828_Arry[4] = R828_iniArry[4] & 0xC0; ++ R828_Arry[4] = R828_Arry[4] | RT_Reg09; ++ R828_I2C.Data =R828_Arry[4] ; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ return RT_Success; ++} ++ ++ ++ ++ ++R828_ErrCode R828_IQ(TUNER_MODULE *pTuner, R828_SectType* IQ_Pont) ++{ ++ R828_SectType Compare_IQ[3]; ++// R828_SectType CompareTemp; ++// UINT8 IQ_Cunt = 0; ++ UINT8 VGA_Cunt; ++ UINT16 VGA_Read; ++ UINT8 X_Direction; // 1:X, 0:Y ++ ++ VGA_Cunt = 0; ++ VGA_Read = 0; ++ ++ // increase VGA power to let image significant ++ for(VGA_Cunt = 12;VGA_Cunt < 16;VGA_Cunt ++) ++ { ++ R828_I2C.RegAddr = 0x0C; ++ R828_I2C.Data = (R828_Arry[7] & 0xF0) + VGA_Cunt; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Delay_MS(pTuner, 10); // ++ ++ if(R828_Muti_Read(pTuner, 0x01, &VGA_Read) != RT_Success) ++ return RT_Fail; ++ ++ if(VGA_Read > 40*4) ++ break; ++ } ++ ++ //initial 0x08, 0x09 ++ //Compare_IQ[0].Gain_X = 0x40; //should be 0xC0 in R828, Jason ++ //Compare_IQ[0].Phase_Y = 0x40; //should be 0x40 in R828 ++ Compare_IQ[0].Gain_X = R828_iniArry[3] & 0xC0; // Jason modified, clear b[5], b[4:0] ++ Compare_IQ[0].Phase_Y = R828_iniArry[4] & 0xC0; // ++ ++ //while(IQ_Cunt < 3) ++ //{ ++ // Determine X or Y ++ if(R828_IMR_Cross(pTuner, &Compare_IQ[0], &X_Direction) != RT_Success) ++ return RT_Fail; ++ ++ //if(X_Direction==1) ++ //{ ++ // if(R828_IQ_Tree(Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) //X ++ // return RT_Fail; ++ //} ++ //else ++ //{ ++ // if(R828_IQ_Tree(Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) //Y ++ // return RT_Fail; ++ //} ++ ++ /* ++ //--- X direction ---// ++ //X: 3 points ++ if(R828_IQ_Tree(Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) // ++ return RT_Fail; ++ ++ //compare and find min of 3 points. determine I/Q direction ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ //increase step to find min value of this direction ++ if(R828_CompreStep(&Compare_IQ[0], 0x08) != RT_Success) ++ return RT_Fail; ++ */ ++ ++ if(X_Direction==1) ++ { ++ //compare and find min of 3 points. determine I/Q direction ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ //increase step to find min value of this direction ++ if(R828_CompreStep(pTuner, &Compare_IQ[0], 0x08) != RT_Success) //X ++ return RT_Fail; ++ } ++ else ++ { ++ //compare and find min of 3 points. determine I/Q direction ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ //increase step to find min value of this direction ++ if(R828_CompreStep(pTuner, &Compare_IQ[0], 0x09) != RT_Success) //Y ++ return RT_Fail; ++ } ++ /* ++ //--- Y direction ---// ++ //Y: 3 points ++ if(R828_IQ_Tree(Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) // ++ return RT_Fail; ++ ++ //compare and find min of 3 points. determine I/Q direction ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ //increase step to find min value of this direction ++ if(R828_CompreStep(&Compare_IQ[0], 0x09) != RT_Success) ++ return RT_Fail; ++ */ ++ ++ //Another direction ++ if(X_Direction==1) ++ { ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) //Y ++ return RT_Fail; ++ ++ //compare and find min of 3 points. determine I/Q direction ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ //increase step to find min value of this direction ++ if(R828_CompreStep(pTuner, &Compare_IQ[0], 0x09) != RT_Success) //Y ++ return RT_Fail; ++ } ++ else ++ { ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) //X ++ return RT_Fail; ++ ++ //compare and find min of 3 points. determine I/Q direction ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ //increase step to find min value of this direction ++ if(R828_CompreStep(pTuner, &Compare_IQ[0], 0x08) != RT_Success) //X ++ return RT_Fail; ++ } ++ //CompareTemp = Compare_IQ[0]; ++ ++ //--- Check 3 points again---// ++ if(X_Direction==1) ++ { ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) //X ++ return RT_Fail; ++ } ++ else ++ { ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) //Y ++ return RT_Fail; ++ } ++ ++ //if(R828_IQ_Tree(Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, 0x09, &Compare_IQ[0]) != RT_Success) // ++ // return RT_Fail; ++ ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ //if((CompareTemp.Gain_X == Compare_IQ[0].Gain_X) && (CompareTemp.Phase_Y == Compare_IQ[0].Phase_Y))//Ben Check ++ // break; ++ ++ //IQ_Cunt ++; ++ //} ++ //if(IQ_Cunt == 3) ++ // return RT_Fail; ++ ++ //Section-4 Check ++ /* ++ CompareTemp = Compare_IQ[0]; ++ for(IQ_Cunt = 0;IQ_Cunt < 5;IQ_Cunt ++) ++ { ++ if(R828_Section(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ if((CompareTemp.Gain_X == Compare_IQ[0].Gain_X) && (CompareTemp.Phase_Y == Compare_IQ[0].Phase_Y)) ++ break; ++ } ++ */ ++ ++ //Section-9 check ++ //if(R828_F_IMR(&Compare_IQ[0]) != RT_Success) ++ if(R828_Section(pTuner, &Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ *IQ_Pont = Compare_IQ[0]; ++ ++ //reset gain/phase control setting ++ R828_I2C.RegAddr = 0x08; ++ R828_I2C.Data = R828_iniArry[3] & 0xC0; //Jason ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x09; ++ R828_I2C.Data = R828_iniArry[4] & 0xC0; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ return RT_Success; ++} ++ ++ ++ ++//-------------------------------------------------------------------------------------------- ++// Purpose: record IMC results by input gain/phase location ++// then adjust gain or phase positive 1 step and negtive 1 step, both record results ++// input: FixPot: phase or gain ++// FlucPot phase or gain ++// PotReg: 0x08 or 0x09 ++// CompareTree: 3 IMR trace and results ++// output: TREU or FALSE ++//-------------------------------------------------------------------------------------------- ++R828_ErrCode R828_IQ_Tree(TUNER_MODULE *pTuner, UINT8 FixPot, UINT8 FlucPot, UINT8 PotReg, R828_SectType* CompareTree) ++{ ++ UINT8 TreeCunt; ++ UINT8 TreeTimes; ++ UINT8 TempPot; ++ UINT8 PntReg; ++ ++ TreeCunt = 0; ++ TreeTimes = 3; ++ TempPot = 0; ++ PntReg = 0; ++ ++ if(PotReg == 0x08) ++ PntReg = 0x09; //phase control ++ else ++ PntReg = 0x08; //gain control ++ ++ for(TreeCunt = 0;TreeCunt < TreeTimes;TreeCunt ++) ++ { ++ R828_I2C.RegAddr = PotReg; ++ R828_I2C.Data = FixPot; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = PntReg; ++ R828_I2C.Data = FlucPot; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ if(R828_Muti_Read(pTuner, 0x01, &CompareTree[TreeCunt].Value) != RT_Success) ++ return RT_Fail; ++ ++ if(PotReg == 0x08) ++ { ++ CompareTree[TreeCunt].Gain_X = FixPot; ++ CompareTree[TreeCunt].Phase_Y = FlucPot; ++ } ++ else ++ { ++ CompareTree[TreeCunt].Phase_Y = FixPot; ++ CompareTree[TreeCunt].Gain_X = FlucPot; ++ } ++ ++ if(TreeCunt == 0) //try right-side point ++ FlucPot ++; ++ else if(TreeCunt == 1) //try left-side point ++ { ++ if((FlucPot & 0x1F) < 0x02) //if absolute location is 1, change I/Q direction ++ { ++ TempPot = 2 - (FlucPot & 0x1F); ++ if(FlucPot & 0x20) //b[5]:I/Q selection. 0:Q-path, 1:I-path ++ { ++ FlucPot &= 0xC0; ++ FlucPot |= TempPot; ++ } ++ else ++ { ++ FlucPot |= (0x20 | TempPot); ++ } ++ } ++ else ++ FlucPot -= 2; ++ } ++ } ++ ++ return RT_Success; ++} ++ ++ ++ ++ ++//-----------------------------------------------------------------------------------/ ++// Purpose: compare IMC result aray [0][1][2], find min value and store to CorArry[0] ++// input: CorArry: three IMR data array ++// output: TRUE or FALSE ++//-----------------------------------------------------------------------------------/ ++R828_ErrCode R828_CompreCor(R828_SectType* CorArry) ++{ ++ UINT8 CompCunt; ++ R828_SectType CorTemp; ++ ++ CompCunt = 0; ++ ++ for(CompCunt = 3;CompCunt > 0;CompCunt --) ++ { ++ if(CorArry[0].Value > CorArry[CompCunt - 1].Value) //compare IMC result [0][1][2], find min value ++ { ++ CorTemp = CorArry[0]; ++ CorArry[0] = CorArry[CompCunt - 1]; ++ CorArry[CompCunt - 1] = CorTemp; ++ } ++ } ++ ++ return RT_Success; ++} ++ ++ ++//-------------------------------------------------------------------------------------// ++// Purpose: if (Gain<9 or Phase<9), Gain+1 or Phase+1 and compare with min value ++// new < min => update to min and continue ++// new > min => Exit ++// input: StepArry: three IMR data array ++// Pace: gain or phase register ++// output: TRUE or FALSE ++//-------------------------------------------------------------------------------------// ++R828_ErrCode R828_CompreStep(TUNER_MODULE *pTuner, R828_SectType* StepArry, UINT8 Pace) ++{ ++ //UINT8 StepCunt = 0; ++ R828_SectType StepTemp; ++ ++ //min value already saved in StepArry[0] ++ StepTemp.Phase_Y = StepArry[0].Phase_Y; ++ StepTemp.Gain_X = StepArry[0].Gain_X; ++ ++ while(((StepTemp.Gain_X & 0x1F) < IMR_TRIAL) && ((StepTemp.Phase_Y & 0x1F) < IMR_TRIAL)) //5->10 ++ { ++ if(Pace == 0x08) ++ StepTemp.Gain_X ++; ++ else ++ StepTemp.Phase_Y ++; ++ ++ R828_I2C.RegAddr = 0x08; ++ R828_I2C.Data = StepTemp.Gain_X ; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x09; ++ R828_I2C.Data = StepTemp.Phase_Y; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ if(R828_Muti_Read(pTuner, 0x01, &StepTemp.Value) != RT_Success) ++ return RT_Fail; ++ ++ if(StepTemp.Value <= StepArry[0].Value) ++ { ++ StepArry[0].Gain_X = StepTemp.Gain_X; ++ StepArry[0].Phase_Y = StepTemp.Phase_Y; ++ StepArry[0].Value = StepTemp.Value; ++ } ++ else ++ { ++ break; ++ } ++ ++ } //end of while() ++ ++ return RT_Success; ++} ++ ++ ++//-----------------------------------------------------------------------------------/ ++// Purpose: read multiple IMC results for stability ++// input: IMR_Reg: IMC result address ++// IMR_Result_Data: result ++// output: TRUE or FALSE ++//-----------------------------------------------------------------------------------/ ++R828_ErrCode R828_Muti_Read(TUNER_MODULE *pTuner, UINT8 IMR_Reg, UINT16* IMR_Result_Data) //jason modified ++{ ++ UINT8 ReadCunt; ++ UINT16 ReadAmount; ++ UINT8 ReadMax; ++ UINT8 ReadMin; ++ UINT8 ReadData; ++ ++ ReadCunt = 0; ++ ReadAmount = 0; ++ ReadMax = 0; ++ ReadMin = 255; ++ ReadData = 0; ++ ++ R828_Delay_MS(pTuner, 5); ++ ++ for(ReadCunt = 0;ReadCunt < 6;ReadCunt ++) ++ { ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = IMR_Reg + 1; //IMR_Reg = 0x01 ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ ReadData = R828_I2C_Len.Data[1]; ++ ++ ReadAmount = ReadAmount + (UINT16)ReadData; ++ ++ if(ReadData < ReadMin) ++ ReadMin = ReadData; ++ ++ if(ReadData > ReadMax) ++ ReadMax = ReadData; ++ } ++ *IMR_Result_Data = ReadAmount - (UINT16)ReadMax - (UINT16)ReadMin; ++ ++ return RT_Success; ++} ++ ++ ++R828_ErrCode R828_Section(TUNER_MODULE *pTuner, R828_SectType* IQ_Pont) ++{ ++ R828_SectType Compare_IQ[3]; ++ R828_SectType Compare_Bet[3]; ++ ++ //Try X-1 column and save min result to Compare_Bet[0] ++ if((IQ_Pont->Gain_X & 0x1F) == 0x00) ++ { ++ /* ++ if((IQ_Pont->Gain_X & 0xE0) == 0x40) //bug => only compare b[5], ++ Compare_IQ[0].Gain_X = 0x61; // Gain=1, I-path //Jason ++ else ++ Compare_IQ[0].Gain_X = 0x41; // Gain=1, Q-path ++ */ ++ Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) & 0xDF) + 1; //Q-path, Gain=1 ++ } ++ else ++ Compare_IQ[0].Gain_X = IQ_Pont->Gain_X - 1; //left point ++ Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; ++ ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) // y-direction ++ return RT_Fail; ++ ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ Compare_Bet[0].Gain_X = Compare_IQ[0].Gain_X; ++ Compare_Bet[0].Phase_Y = Compare_IQ[0].Phase_Y; ++ Compare_Bet[0].Value = Compare_IQ[0].Value; ++ ++ //Try X column and save min result to Compare_Bet[1] ++ Compare_IQ[0].Gain_X = IQ_Pont->Gain_X; ++ Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; ++ ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ Compare_Bet[1].Gain_X = Compare_IQ[0].Gain_X; ++ Compare_Bet[1].Phase_Y = Compare_IQ[0].Phase_Y; ++ Compare_Bet[1].Value = Compare_IQ[0].Value; ++ ++ //Try X+1 column and save min result to Compare_Bet[2] ++ if((IQ_Pont->Gain_X & 0x1F) == 0x00) ++ Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) | 0x20) + 1; //I-path, Gain=1 ++ else ++ Compare_IQ[0].Gain_X = IQ_Pont->Gain_X + 1; ++ Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; ++ ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ Compare_Bet[2].Gain_X = Compare_IQ[0].Gain_X; ++ Compare_Bet[2].Phase_Y = Compare_IQ[0].Phase_Y; ++ Compare_Bet[2].Value = Compare_IQ[0].Value; ++ ++ if(R828_CompreCor(&Compare_Bet[0]) != RT_Success) ++ return RT_Fail; ++ ++ *IQ_Pont = Compare_Bet[0]; ++ ++ return RT_Success; ++} ++ ++ ++R828_ErrCode R828_IMR_Cross(TUNER_MODULE *pTuner, R828_SectType* IQ_Pont, UINT8* X_Direct) ++{ ++ ++ R828_SectType Compare_Cross[5]; //(0,0)(0,Q-1)(0,I-1)(Q-1,0)(I-1,0) ++ R828_SectType Compare_Temp; ++ UINT8 CrossCount; ++ UINT8 Reg08; ++ UINT8 Reg09; ++ ++ CrossCount = 0; ++ Reg08 = R828_iniArry[3] & 0xC0; ++ Reg09 = R828_iniArry[4] & 0xC0; ++ ++ //memset(&Compare_Temp,0, sizeof(R828_SectType)); ++ Compare_Temp.Gain_X = 0; ++ Compare_Temp.Phase_Y = 0; ++ Compare_Temp.Value = 0; ++ ++ Compare_Temp.Value = 255; ++ ++ for(CrossCount=0; CrossCount<5; CrossCount++) ++ { ++ ++ if(CrossCount==0) ++ { ++ Compare_Cross[CrossCount].Gain_X = Reg08; ++ Compare_Cross[CrossCount].Phase_Y = Reg09; ++ } ++ else if(CrossCount==1) ++ { ++ Compare_Cross[CrossCount].Gain_X = Reg08; //0 ++ Compare_Cross[CrossCount].Phase_Y = Reg09 + 1; //Q-1 ++ } ++ else if(CrossCount==2) ++ { ++ Compare_Cross[CrossCount].Gain_X = Reg08; //0 ++ Compare_Cross[CrossCount].Phase_Y = (Reg09 | 0x20) + 1; //I-1 ++ } ++ else if(CrossCount==3) ++ { ++ Compare_Cross[CrossCount].Gain_X = Reg08 + 1; //Q-1 ++ Compare_Cross[CrossCount].Phase_Y = Reg09; ++ } ++ else ++ { ++ Compare_Cross[CrossCount].Gain_X = (Reg08 | 0x20) + 1; //I-1 ++ Compare_Cross[CrossCount].Phase_Y = Reg09; ++ } ++ ++ R828_I2C.RegAddr = 0x08; ++ R828_I2C.Data = Compare_Cross[CrossCount].Gain_X; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x09; ++ R828_I2C.Data = Compare_Cross[CrossCount].Phase_Y; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ if(R828_Muti_Read(pTuner, 0x01, &Compare_Cross[CrossCount].Value) != RT_Success) ++ return RT_Fail; ++ ++ if( Compare_Cross[CrossCount].Value < Compare_Temp.Value) ++ { ++ Compare_Temp.Value = Compare_Cross[CrossCount].Value; ++ Compare_Temp.Gain_X = Compare_Cross[CrossCount].Gain_X; ++ Compare_Temp.Phase_Y = Compare_Cross[CrossCount].Phase_Y; ++ } ++ } //end for loop ++ ++ ++ if((Compare_Temp.Phase_Y & 0x1F)==1) //y-direction ++ { ++ *X_Direct = (UINT8) 0; ++ IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; ++ IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; ++ IQ_Pont[0].Value = Compare_Cross[0].Value; ++ ++ IQ_Pont[1].Gain_X = Compare_Cross[1].Gain_X; ++ IQ_Pont[1].Phase_Y = Compare_Cross[1].Phase_Y; ++ IQ_Pont[1].Value = Compare_Cross[1].Value; ++ ++ IQ_Pont[2].Gain_X = Compare_Cross[2].Gain_X; ++ IQ_Pont[2].Phase_Y = Compare_Cross[2].Phase_Y; ++ IQ_Pont[2].Value = Compare_Cross[2].Value; ++ } ++ else //(0,0) or x-direction ++ { ++ *X_Direct = (UINT8) 1; ++ IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; ++ IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; ++ IQ_Pont[0].Value = Compare_Cross[0].Value; ++ ++ IQ_Pont[1].Gain_X = Compare_Cross[3].Gain_X; ++ IQ_Pont[1].Phase_Y = Compare_Cross[3].Phase_Y; ++ IQ_Pont[1].Value = Compare_Cross[3].Value; ++ ++ IQ_Pont[2].Gain_X = Compare_Cross[4].Gain_X; ++ IQ_Pont[2].Phase_Y = Compare_Cross[4].Phase_Y; ++ IQ_Pont[2].Value = Compare_Cross[4].Value; ++ } ++ return RT_Success; ++} ++ ++ ++//----------------------------------------------------------------------------------------// ++// purpose: search surrounding points from previous point ++// try (x-1), (x), (x+1) columns, and find min IMR result point ++// input: IQ_Pont: previous point data(IMR Gain, Phase, ADC Result, RefRreq) ++// will be updated to final best point ++// output: TRUE or FALSE ++//----------------------------------------------------------------------------------------// ++R828_ErrCode R828_F_IMR(TUNER_MODULE *pTuner, R828_SectType* IQ_Pont) ++{ ++ R828_SectType Compare_IQ[3]; ++ R828_SectType Compare_Bet[3]; ++ UINT8 VGA_Cunt; ++ UINT16 VGA_Read; ++ ++ VGA_Cunt = 0; ++ VGA_Read = 0; ++ ++ //VGA ++ for(VGA_Cunt = 12;VGA_Cunt < 16;VGA_Cunt ++) ++ { ++ R828_I2C.RegAddr = 0x0C; ++ R828_I2C.Data = (R828_Arry[7] & 0xF0) + VGA_Cunt; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Delay_MS(pTuner, 10); ++ ++ if(R828_Muti_Read(pTuner, 0x01, &VGA_Read) != RT_Success) ++ return RT_Fail; ++ ++ if(VGA_Read > 40*4) ++ break; ++ } ++ ++ //Try X-1 column and save min result to Compare_Bet[0] ++ if((IQ_Pont->Gain_X & 0x1F) == 0x00) ++ { ++ Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) & 0xDF) + 1; //Q-path, Gain=1 ++ } ++ else ++ Compare_IQ[0].Gain_X = IQ_Pont->Gain_X - 1; //left point ++ Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; ++ ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) // y-direction ++ return RT_Fail; ++ ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ Compare_Bet[0].Gain_X = Compare_IQ[0].Gain_X; ++ Compare_Bet[0].Phase_Y = Compare_IQ[0].Phase_Y; ++ Compare_Bet[0].Value = Compare_IQ[0].Value; ++ ++ //Try X column and save min result to Compare_Bet[1] ++ Compare_IQ[0].Gain_X = IQ_Pont->Gain_X; ++ Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; ++ ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ Compare_Bet[1].Gain_X = Compare_IQ[0].Gain_X; ++ Compare_Bet[1].Phase_Y = Compare_IQ[0].Phase_Y; ++ Compare_Bet[1].Value = Compare_IQ[0].Value; ++ ++ //Try X+1 column and save min result to Compare_Bet[2] ++ if((IQ_Pont->Gain_X & 0x1F) == 0x00) ++ Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) | 0x20) + 1; //I-path, Gain=1 ++ else ++ Compare_IQ[0].Gain_X = IQ_Pont->Gain_X + 1; ++ Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; ++ ++ if(R828_IQ_Tree(pTuner, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, 0x08, &Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ if(R828_CompreCor(&Compare_IQ[0]) != RT_Success) ++ return RT_Fail; ++ ++ Compare_Bet[2].Gain_X = Compare_IQ[0].Gain_X; ++ Compare_Bet[2].Phase_Y = Compare_IQ[0].Phase_Y; ++ Compare_Bet[2].Value = Compare_IQ[0].Value; ++ ++ if(R828_CompreCor(&Compare_Bet[0]) != RT_Success) ++ return RT_Fail; ++ ++ *IQ_Pont = Compare_Bet[0]; ++ ++ return RT_Success; ++} ++ ++ ++ ++R828_ErrCode R828_GPIO(TUNER_MODULE *pTuner, R828_GPIO_Type R828_GPIO_Conrl) ++{ ++ if(R828_GPIO_Conrl == HI_SIG) ++ R828_Arry[10] |= 0x01; ++ else ++ R828_Arry[10] &= 0xFE; ++ ++ R828_I2C.RegAddr = 0x0F; ++ R828_I2C.Data = R828_Arry[10]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ return RT_Success; ++} ++ ++ ++ ++ ++ ++R828_ErrCode R828_SetStandard(TUNER_MODULE *pTuner, R828_Standard_Type RT_Standard) ++{ ++ ++ // Used Normal Arry to Modify ++ UINT8 ArrayNum; ++ ++ ArrayNum = 27; ++ for(ArrayNum=0;ArrayNum<27;ArrayNum++) ++ { ++ R828_Arry[ArrayNum] = R828_iniArry[ArrayNum]; ++ } ++ ++ ++ // Record Init Flag & Xtal_check Result ++ if(R828_IMR_done_flag == TRUE) ++ R828_Arry[7] = (R828_Arry[7] & 0xF0) | 0x01 | (Xtal_cap_sel<<1); ++ else ++ R828_Arry[7] = (R828_Arry[7] & 0xF0) | 0x00; ++ ++ R828_I2C.RegAddr = 0x0C; ++ R828_I2C.Data = R828_Arry[7]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // Record version ++ R828_I2C.RegAddr = 0x13; ++ R828_Arry[14] = (R828_Arry[14] & 0xC0) | VER_NUM; ++ R828_I2C.Data = R828_Arry[14]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ //for LT Gain test ++ if(RT_Standard > SECAM_L1) ++ { ++ R828_I2C.RegAddr = 0x1D; //[5:3] LNA TOP ++ R828_I2C.Data = (R828_Arry[24] & 0xC7) | 0x00; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //R828_Delay_MS(1); ++ } ++ ++ // Look Up System Dependent Table ++ Sys_Info1 = R828_Sys_Sel(RT_Standard); ++ R828_IF_khz = Sys_Info1.IF_KHz; ++ R828_CAL_LO_khz = Sys_Info1.FILT_CAL_LO; ++ ++ // Filter Calibration ++ if(R828_Fil_Cal_flag[RT_Standard] == FALSE) ++ { ++ // do filter calibration ++ if(R828_Filt_Cal(pTuner, Sys_Info1.FILT_CAL_LO,Sys_Info1.BW) != RT_Success) ++ return RT_Fail; ++ ++ ++ // read and set filter code ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 5; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ R828_Fil_Cal_code[RT_Standard] = R828_I2C_Len.Data[4] & 0x0F; ++ ++ //Filter Cali. Protection ++ if(R828_Fil_Cal_code[RT_Standard]==0 || R828_Fil_Cal_code[RT_Standard]==15) ++ { ++ if(R828_Filt_Cal(pTuner, Sys_Info1.FILT_CAL_LO,Sys_Info1.BW) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 5; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ R828_Fil_Cal_code[RT_Standard] = R828_I2C_Len.Data[4] & 0x0F; ++ ++ if(R828_Fil_Cal_code[RT_Standard]==15) //narrowest ++ R828_Fil_Cal_code[RT_Standard] = 0; ++ ++ } ++ R828_Fil_Cal_flag[RT_Standard] = TRUE; ++ } ++ ++ // Set Filter Q ++ R828_Arry[5] = (R828_Arry[5] & 0xE0) | Sys_Info1.FILT_Q | R828_Fil_Cal_code[RT_Standard]; ++ R828_I2C.RegAddr = 0x0A; ++ R828_I2C.Data = R828_Arry[5]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // Set BW, Filter_gain, & HP corner ++ R828_Arry[6]= (R828_Arry[6] & 0x10) | Sys_Info1.HP_COR; ++ R828_I2C.RegAddr = 0x0B; ++ R828_I2C.Data = R828_Arry[6]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // Set Img_R ++ R828_Arry[2] = (R828_Arry[2] & 0x7F) | Sys_Info1.IMG_R; ++ R828_I2C.RegAddr = 0x07; ++ R828_I2C.Data = R828_Arry[2]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ // Set filt_3dB, V6MHz ++ R828_Arry[1] = (R828_Arry[1] & 0xCF) | Sys_Info1.FILT_GAIN; ++ R828_I2C.RegAddr = 0x06; ++ R828_I2C.Data = R828_Arry[1]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //channel filter extension ++ R828_Arry[25] = (R828_Arry[25] & 0x9F) | Sys_Info1.EXT_ENABLE; ++ R828_I2C.RegAddr = 0x1E; ++ R828_I2C.Data = R828_Arry[25]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ //Loop through ++ R828_Arry[0] = (R828_Arry[0] & 0x7F) | Sys_Info1.LOOP_THROUGH; ++ R828_I2C.RegAddr = 0x05; ++ R828_I2C.Data = R828_Arry[0]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //Loop through attenuation ++ R828_Arry[26] = (R828_Arry[26] & 0x7F) | Sys_Info1.LT_ATT; ++ R828_I2C.RegAddr = 0x1F; ++ R828_I2C.Data = R828_Arry[26]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //filter extention widest ++ R828_Arry[10] = (R828_Arry[10] & 0x7F) | Sys_Info1.FLT_EXT_WIDEST; ++ R828_I2C.RegAddr = 0x0F; ++ R828_I2C.Data = R828_Arry[10]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //RF poly filter current ++ R828_Arry[20] = (R828_Arry[20] & 0x9F) | Sys_Info1.POLYFIL_CUR; ++ R828_I2C.RegAddr = 0x19; ++ R828_I2C.Data = R828_Arry[20]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ return RT_Success; ++} ++ ++ ++ ++R828_ErrCode R828_Filt_Cal(TUNER_MODULE *pTuner, UINT32 Cal_Freq,BW_Type R828_BW) ++{ ++ //set in Sys_sel() ++ /* ++ if(R828_BW == BW_8M) ++ { ++ //set filt_cap = no cap ++ R828_I2C.RegAddr = 0x0B; //reg11 ++ R828_Arry[6] &= 0x9F; //filt_cap = no cap ++ R828_I2C.Data = R828_Arry[6]; ++ } ++ else if(R828_BW == BW_7M) ++ { ++ //set filt_cap = +1 cap ++ R828_I2C.RegAddr = 0x0B; //reg11 ++ R828_Arry[6] &= 0x9F; //filt_cap = no cap ++ R828_Arry[6] |= 0x20; //filt_cap = +1 cap ++ R828_I2C.Data = R828_Arry[6]; ++ } ++ else if(R828_BW == BW_6M) ++ { ++ //set filt_cap = +2 cap ++ R828_I2C.RegAddr = 0x0B; //reg11 ++ R828_Arry[6] &= 0x9F; //filt_cap = no cap ++ R828_Arry[6] |= 0x60; //filt_cap = +2 cap ++ R828_I2C.Data = R828_Arry[6]; ++ } ++ ++ ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++*/ ++ ++ // Set filt_cap ++ R828_I2C.RegAddr = 0x0B; ++ R828_Arry[6]= (R828_Arry[6] & 0x9F) | (Sys_Info1.HP_COR & 0x60); ++ R828_I2C.Data = R828_Arry[6]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ //set cali clk =on ++ R828_I2C.RegAddr = 0x0F; //reg15 ++ R828_Arry[10] |= 0x04; //calibration clk=on ++ R828_I2C.Data = R828_Arry[10]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //X'tal cap 0pF for PLL ++ R828_I2C.RegAddr = 0x10; ++ R828_Arry[11] = (R828_Arry[11] & 0xFC) | 0x00; ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //Set PLL Freq = Filter Cali Freq ++ if(R828_PLL(pTuner, Cal_Freq, STD_SIZE) != RT_Success) ++ return RT_Fail; ++ ++ //Start Trigger ++ R828_I2C.RegAddr = 0x0B; //reg11 ++ R828_Arry[6] |= 0x10; //vstart=1 ++ R828_I2C.Data = R828_Arry[6]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //delay 0.5ms ++ R828_Delay_MS(pTuner, 1); ++ ++ //Stop Trigger ++ R828_I2C.RegAddr = 0x0B; ++ R828_Arry[6] &= 0xEF; //vstart=0 ++ R828_I2C.Data = R828_Arry[6]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ //set cali clk =off ++ R828_I2C.RegAddr = 0x0F; //reg15 ++ R828_Arry[10] &= 0xFB; //calibration clk=off ++ R828_I2C.Data = R828_Arry[10]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ return RT_Success; ++ ++} ++ ++ ++ ++ ++R828_ErrCode R828_SetFrequency(TUNER_MODULE *pTuner, R828_Set_Info R828_INFO, R828_SetFreq_Type R828_SetFreqMode) ++{ ++ ++ UINT32 LO_KHz; ++ ++ // Check Input Frequency Range ++ if((R828_INFO.RF_KHz<40000) || (R828_INFO.RF_KHz>900000)) ++ { ++ return RT_Fail; ++ } ++ ++ if(R828_INFO.R828_Standard==SECAM_L1) ++ LO_KHz = R828_INFO.RF_KHz - Sys_Info1.IF_KHz; ++ else ++ LO_KHz = R828_INFO.RF_KHz + Sys_Info1.IF_KHz; ++ ++ //Set MUX dependent var. Must do before PLL( ) ++ if(R828_MUX(pTuner, LO_KHz) != RT_Success) ++ return RT_Fail; ++ ++ ++ ++ //Set PLL ++ if(R828_PLL(pTuner, LO_KHz, R828_INFO.R828_Standard) != RT_Success) ++ return RT_Fail; ++ ++ R828_IMR_point_num = Freq_Info1.IMR_MEM; ++ ++ ++ //Set TOP,VTH,VTL ++ SysFreq_Info1 = R828_SysFreq_Sel(R828_INFO.R828_Standard, R828_INFO.RF_KHz); ++ ++ ++ // write DectBW, pre_dect_TOP ++ R828_Arry[24] = (R828_Arry[24] & 0x38) | (SysFreq_Info1.LNA_TOP & 0xC7); ++ R828_I2C.RegAddr = 0x1D; ++ R828_I2C.Data = R828_Arry[24]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // write MIXER TOP, TOP+-1 ++ R828_Arry[23] = (R828_Arry[23] & 0x07) | (SysFreq_Info1.MIXER_TOP & 0xF8); ++ R828_I2C.RegAddr = 0x1C; ++ R828_I2C.Data = R828_Arry[23]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ // write LNA VTHL ++ R828_Arry[8] = (R828_Arry[8] & 0x00) | SysFreq_Info1.LNA_VTH_L; ++ R828_I2C.RegAddr = 0x0D; ++ R828_I2C.Data = R828_Arry[8]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // write MIXER VTHL ++ R828_Arry[9] = (R828_Arry[9] & 0x00) | SysFreq_Info1.MIXER_VTH_L; ++ R828_I2C.RegAddr = 0x0E; ++ R828_I2C.Data = R828_Arry[9]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // Cable-1/Air in ++ R828_I2C.RegAddr = 0x05; ++ R828_Arry[0] &= 0x9F; ++ R828_Arry[0] |= SysFreq_Info1.AIR_CABLE1_IN; ++ R828_I2C.Data = R828_Arry[0]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // Cable-2 in ++ R828_I2C.RegAddr = 0x06; ++ R828_Arry[1] &= 0xF7; ++ R828_Arry[1] |= SysFreq_Info1.CABLE2_IN; ++ R828_I2C.Data = R828_Arry[1]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //CP current ++ R828_I2C.RegAddr = 0x11; ++ R828_Arry[12] &= 0xC7; ++ R828_Arry[12] |= SysFreq_Info1.CP_CUR; ++ R828_I2C.Data = R828_Arry[12]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //div buffer current ++ R828_I2C.RegAddr = 0x17; ++ R828_Arry[18] &= 0xCF; ++ R828_Arry[18] |= SysFreq_Info1.DIV_BUF_CUR; ++ R828_I2C.Data = R828_Arry[18]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // Set channel filter current ++ R828_I2C.RegAddr = 0x0A; ++ R828_Arry[5] = (R828_Arry[5] & 0x9F) | SysFreq_Info1.FILTER_CUR; ++ R828_I2C.Data = R828_Arry[5]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //Air-In only for Astrometa ++ R828_Arry[0] = (R828_Arry[0] & 0x9F) | 0x00; ++ R828_Arry[1] = (R828_Arry[1] & 0xF7) | 0x00; ++ ++ R828_I2C.RegAddr = 0x05; ++ R828_I2C.Data = R828_Arry[0]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x06; ++ R828_I2C.Data = R828_Arry[1]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ //Set LNA ++ if(R828_INFO.R828_Standard > SECAM_L1) ++ { ++ ++ if(R828_SetFreqMode==FAST_MODE) //FAST mode ++ { ++ //R828_Arry[24] = (R828_Arry[24] & 0xC7) | 0x20; //LNA TOP:4 ++ R828_Arry[24] = (R828_Arry[24] & 0xC7) | 0x00; //LNA TOP:lowest ++ R828_I2C.RegAddr = 0x1D; ++ R828_I2C.Data = R828_Arry[24]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Arry[23] = (R828_Arry[23] & 0xFB); // 0: normal mode ++ R828_I2C.RegAddr = 0x1C; ++ R828_I2C.Data = R828_Arry[23]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Arry[1] = (R828_Arry[1] & 0xBF); //0: PRE_DECT off ++ R828_I2C.RegAddr = 0x06; ++ R828_I2C.Data = R828_Arry[1]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //agc clk 250hz ++ R828_Arry[21] = (R828_Arry[21] & 0xCF) | 0x30; ++ R828_I2C.RegAddr = 0x1A; ++ R828_I2C.Data = R828_Arry[21]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ } ++ else //NORMAL mode ++ { ++ ++ R828_Arry[24] = (R828_Arry[24] & 0xC7) | 0x00; //LNA TOP:lowest ++ R828_I2C.RegAddr = 0x1D; ++ R828_I2C.Data = R828_Arry[24]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Arry[23] = (R828_Arry[23] & 0xFB); // 0: normal mode ++ R828_I2C.RegAddr = 0x1C; ++ R828_I2C.Data = R828_Arry[23]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Arry[1] = (R828_Arry[1] & 0xBF); //0: PRE_DECT off ++ R828_I2C.RegAddr = 0x06; ++ R828_I2C.Data = R828_Arry[1]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //agc clk 250hz ++ R828_Arry[21] = (R828_Arry[21] & 0xCF) | 0x30; //250hz ++ R828_I2C.RegAddr = 0x1A; ++ R828_I2C.Data = R828_Arry[21]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Delay_MS(pTuner, 250); ++ ++ // PRE_DECT on ++ /* ++ R828_Arry[1] = (R828_Arry[1] & 0xBF) | SysFreq_Info1.PRE_DECT; ++ R828_I2C.RegAddr = 0x06; ++ R828_I2C.Data = R828_Arry[1]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ */ ++ // write LNA TOP = 3 ++ //R828_Arry[24] = (R828_Arry[24] & 0xC7) | (SysFreq_Info1.LNA_TOP & 0x38); ++ R828_Arry[24] = (R828_Arry[24] & 0xC7) | 0x18; //TOP=3 ++ R828_I2C.RegAddr = 0x1D; ++ R828_I2C.Data = R828_Arry[24]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // write discharge mode ++ R828_Arry[23] = (R828_Arry[23] & 0xFB) | (SysFreq_Info1.MIXER_TOP & 0x04); ++ R828_I2C.RegAddr = 0x1C; ++ R828_I2C.Data = R828_Arry[23]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // LNA discharge current ++ R828_Arry[25] = (R828_Arry[25] & 0xE0) | SysFreq_Info1.LNA_DISCHARGE; ++ R828_I2C.RegAddr = 0x1E; ++ R828_I2C.Data = R828_Arry[25]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //agc clk 60hz ++ R828_Arry[21] = (R828_Arry[21] & 0xCF) | 0x20; ++ R828_I2C.RegAddr = 0x1A; ++ R828_I2C.Data = R828_Arry[21]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ } ++ } ++ else ++ { ++ if(R828_SetFreqMode==NORMAL_MODE || R828_SetFreqMode==FAST_MODE) ++ { ++ /* ++ // PRE_DECT on ++ R828_Arry[1] = (R828_Arry[1] & 0xBF) | SysFreq_Info1.PRE_DECT; ++ R828_I2C.RegAddr = 0x06; ++ R828_I2C.Data = R828_Arry[1]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ */ ++ // PRE_DECT off ++ R828_Arry[1] = (R828_Arry[1] & 0xBF); //0: PRE_DECT off ++ R828_I2C.RegAddr = 0x06; ++ R828_I2C.Data = R828_Arry[1]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // write LNA TOP ++ R828_Arry[24] = (R828_Arry[24] & 0xC7) | (SysFreq_Info1.LNA_TOP & 0x38); ++ R828_I2C.RegAddr = 0x1D; ++ R828_I2C.Data = R828_Arry[24]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // write discharge mode ++ R828_Arry[23] = (R828_Arry[23] & 0xFB) | (SysFreq_Info1.MIXER_TOP & 0x04); ++ R828_I2C.RegAddr = 0x1C; ++ R828_I2C.Data = R828_Arry[23]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // LNA discharge current ++ R828_Arry[25] = (R828_Arry[25] & 0xE0) | SysFreq_Info1.LNA_DISCHARGE; ++ R828_I2C.RegAddr = 0x1E; ++ R828_I2C.Data = R828_Arry[25]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ // agc clk 1Khz, external det1 cap 1u ++ R828_Arry[21] = (R828_Arry[21] & 0xCF) | 0x00; ++ R828_I2C.RegAddr = 0x1A; ++ R828_I2C.Data = R828_Arry[21]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_Arry[11] = (R828_Arry[11] & 0xFB) | 0x00; ++ R828_I2C.RegAddr = 0x10; ++ R828_I2C.Data = R828_Arry[11]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ } ++ } ++ ++ return RT_Success; ++ ++} ++ ++ ++ ++ ++R828_ErrCode R828_Standby(TUNER_MODULE *pTuner, R828_LoopThrough_Type R828_LoopSwitch) ++{ ++ if(R828_LoopSwitch == LOOP_THROUGH) ++ { ++ R828_I2C.RegAddr = 0x06; ++ R828_I2C.Data = 0xB1; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ R828_I2C.RegAddr = 0x05; ++ R828_I2C.Data = 0x03; ++ ++ ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ } ++ else ++ { ++ R828_I2C.RegAddr = 0x05; ++ R828_I2C.Data = 0xA3; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x06; ++ R828_I2C.Data = 0xB1; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ } ++ ++ R828_I2C.RegAddr = 0x07; ++ R828_I2C.Data = 0x3A; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x08; ++ R828_I2C.Data = 0x40; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x09; ++ R828_I2C.Data = 0xC0; //polyfilter off ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x0A; ++ R828_I2C.Data = 0x36; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x0C; ++ R828_I2C.Data = 0x35; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x0F; ++ R828_I2C.Data = 0x78; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x11; ++ R828_I2C.Data = 0x03; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x17; ++ R828_I2C.Data = 0xF4; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C.RegAddr = 0x19; ++ R828_I2C.Data = 0x0C; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ ++ return RT_Success; ++} ++ ++ ++ ++R828_ErrCode R828_GetRfGain(TUNER_MODULE *pTuner, R828_RF_Gain_Info *pR828_rf_gain) ++{ ++ ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 4; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ pR828_rf_gain->RF_gain1 = (R828_I2C_Len.Data[3] & 0x0F); ++ pR828_rf_gain->RF_gain2 = ((R828_I2C_Len.Data[3] & 0xF0) >> 4); ++ pR828_rf_gain->RF_gain_comb = pR828_rf_gain->RF_gain1*2 + pR828_rf_gain->RF_gain2; ++ ++ return RT_Success; ++} ++ ++ ++R828_ErrCode R828_RfGainMode(TUNER_MODULE *pTuner, R828_RF_Gain_TYPE R828_RfGainType) ++{ ++ UINT8 MixerGain; ++ UINT8 LnaGain; ++ ++ MixerGain = 0; ++ LnaGain = 0; ++ ++ if(R828_RfGainType==RF_MANUAL) ++ { ++ //LNA auto off ++ R828_I2C.RegAddr = 0x05; ++ R828_Arry[0] = R828_Arry[0] | 0x10; ++ R828_I2C.Data = R828_Arry[0]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //Mixer auto off ++ R828_I2C.RegAddr = 0x07; ++ R828_Arry[2] = R828_Arry[2] & 0xEF; ++ R828_I2C.Data = R828_Arry[2]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ R828_I2C_Len.RegAddr = 0x00; ++ R828_I2C_Len.Len = 4; ++ if(I2C_Read_Len(pTuner, &R828_I2C_Len) != RT_Success) ++ return RT_Fail; ++ ++ MixerGain = (R828_I2C_Len.Data[3] & 0xF0) >> 4; ++ LnaGain = R828_I2C_Len.Data[3] & 0x0F; ++ ++ //set LNA gain ++ R828_I2C.RegAddr = 0x05; ++ R828_Arry[0] = (R828_Arry[0] & 0xF0) | LnaGain; ++ R828_I2C.Data = R828_Arry[0]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //set Mixer gain ++ R828_I2C.RegAddr = 0x07; ++ R828_Arry[2] = (R828_Arry[2] & 0xF0) | MixerGain; ++ R828_I2C.Data = R828_Arry[2]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ } ++ else ++ { ++ //LNA ++ R828_I2C.RegAddr = 0x05; ++ R828_Arry[0] = R828_Arry[0] & 0xEF; ++ R828_I2C.Data = R828_Arry[0]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ ++ //Mixer ++ R828_I2C.RegAddr = 0x07; ++ R828_Arry[2] = R828_Arry[2] | 0x10; ++ R828_I2C.Data = R828_Arry[2]; ++ if(I2C_Write(pTuner, &R828_I2C) != RT_Success) ++ return RT_Fail; ++ } ++ ++ return RT_Success; ++} ++ ++ ++ ++//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++// Smart GUI // ++//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++#if 0 ++UINT8 R828_IMR_XT[6]; ++UINT8 R828_IMR_YT[6]; ++R828_ErrCode R828_ReadIMR(void) ++{ ++ UINT8 IMR_C = 0; ++// UINT8 IMR_X[6] = {0, 0, 0, 0, 0, 0}; ++// UINT8 IMR_Y[6] = {0, 0, 0, 0, 0, 0}; ++ ++ ++ for(IMR_C = 0;IMR_C < 6;IMR_C ++) ++ { ++ R828_IMR_XT[IMR_C] = IMR_Data[IMR_C].Gain_X; ++ R828_IMR_YT[IMR_C] = IMR_Data[IMR_C].Phase_Y; ++ } ++ ++ return RT_Success; ++} ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_r820t.h b/drivers/drivers/media/dvb/dvb-usb/tuner_r820t.h +--- a/drivers/media/dvb/dvb-usb/tuner_r820t.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_r820t.h 2016-04-02 19:17:52.152066045 -0300 +@@ -0,0 +1,263 @@ ++ ++#ifndef __TUNER_R820T_H ++#define __TUNER_R820T_H ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++//*************************************************************** ++//* INCLUDES.H ++//*************************************************************** ++#define VERSION "R820T_v1.49_ASTRO" ++#define VER_NUM 49 ++ ++#define USE_16M_XTAL FALSE ++#define R828_Xtal 28800 ++ ++#define USE_DIPLEXER FALSE ++#define TUNER_CLK_OUT TRUE ++ ++ ++#define BOOL int ++ ++//----------------------------------------------------------// ++// Type Define // ++//----------------------------------------------------------// ++ ++//#define UINT8 unsigned char ++//#define UINT16 unsigned short ++//#define UINT32 unsigned long ++ ++#ifndef _UINT_X_ ++#define _UINT_X_ 1 ++typedef unsigned char UINT8; ++typedef unsigned short UINT16; ++typedef unsigned int UINT32; ++#endif ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++ ++typedef enum _R828_ErrCode ++{ ++ RT_Success, ++ RT_Fail ++}R828_ErrCode; ++ ++typedef enum _Rafael_Chip_Type //Don't modify chip list ++{ ++ R828 = 0, ++ R828D, ++ R828S, ++ R820T, ++ R820C, ++ R620D, ++ R620S ++}Rafael_Chip_Type; ++//----------------------------------------------------------// ++// R828 Parameter // ++//----------------------------------------------------------// ++ ++extern UINT8 R828_ADDRESS; ++ ++#define DIP_FREQ 320000 ++#define IMR_TRIAL 9 ++#define VCO_pwr_ref 0x02 ++ ++extern UINT32 R828_IF_khz; ++extern UINT32 R828_CAL_LO_khz; ++extern UINT8 R828_IMR_point_num; ++extern UINT8 R828_IMR_done_flag; ++extern UINT8 Rafael_Chip; ++ ++typedef enum _R828_Standard_Type //Don't remove standand list!! ++{ ++ ++ NTSC_MN = 0, ++ PAL_I, ++ PAL_DK, ++ PAL_B_7M, //no use ++ PAL_BGH_8M, //for PAL B/G, PAL G/H ++ SECAM_L, ++ SECAM_L1_INV, //for SECAM L' ++ SECAM_L1, //no use ++ ATV_SIZE, ++ DVB_T_6M = ATV_SIZE, ++ DVB_T_7M, ++ DVB_T_7M_2, ++ DVB_T_8M, ++ DVB_T2_6M, ++ DVB_T2_7M, ++ DVB_T2_7M_2, ++ DVB_T2_8M, ++ DVB_T2_1_7M, ++ DVB_T2_10M, ++ DVB_C_8M, ++ DVB_C_6M, ++ ISDB_T, ++ DTMB, ++ R828_ATSC, ++ FM, ++ STD_SIZE ++}R828_Standard_Type; ++ ++extern UINT8 R828_Fil_Cal_flag[STD_SIZE]; ++ ++typedef enum _R828_SetFreq_Type ++{ ++ FAST_MODE = TRUE, ++ NORMAL_MODE = FALSE ++}R828_SetFreq_Type; ++ ++typedef enum _R828_LoopThrough_Type ++{ ++ LOOP_THROUGH = TRUE, ++ SIGLE_IN = FALSE ++}R828_LoopThrough_Type; ++ ++ ++typedef enum _R828_InputMode_Type ++{ ++ AIR_IN = 0, ++ CABLE_IN_1, ++ CABLE_IN_2 ++}R828_InputMode_Type; ++ ++typedef enum _R828_IfAgc_Type ++{ ++ IF_AGC1 = 0, ++ IF_AGC2 ++}R828_IfAgc_Type; ++ ++typedef enum _R828_GPIO_Type ++{ ++ HI_SIG = TRUE, ++ LO_SIG = FALSE ++}R828_GPIO_Type; ++ ++typedef struct _R828_Set_Info ++{ ++ UINT32 RF_KHz; ++ R828_Standard_Type R828_Standard; ++ R828_LoopThrough_Type RT_Input; ++ R828_InputMode_Type RT_InputMode; ++ R828_IfAgc_Type R828_IfAgc_Select; ++}R828_Set_Info; ++ ++typedef struct _R828_RF_Gain_Info ++{ ++ UINT8 RF_gain1; ++ UINT8 RF_gain2; ++ UINT8 RF_gain_comb; ++}R828_RF_Gain_Info; ++ ++typedef enum _R828_RF_Gain_TYPE ++{ ++ RF_AUTO = 0, ++ RF_MANUAL ++}R828_RF_Gain_TYPE; ++ ++ ++ ++typedef struct _R828_I2C_LEN_TYPE ++{ ++ UINT8 RegAddr; ++ UINT8 Data[50]; ++ UINT8 Len; ++}R828_I2C_LEN_TYPE; ++ ++typedef struct _R828_I2C_TYPE ++{ ++ UINT8 RegAddr; ++ UINT8 Data; ++}R828_I2C_TYPE; ++//----------------------------------------------------------// ++// R828 Function // ++//----------------------------------------------------------// ++R828_ErrCode R828_Init(TUNER_MODULE *pTuner); ++R828_ErrCode R828_Standby(TUNER_MODULE *pTuner, R828_LoopThrough_Type R828_LoopSwitch); ++R828_ErrCode R828_GPIO(TUNER_MODULE *pTuner, R828_GPIO_Type R828_GPIO_Conrl); ++R828_ErrCode R828_SetStandard(TUNER_MODULE *pTuner, R828_Standard_Type RT_Standard); ++R828_ErrCode R828_SetFrequency(TUNER_MODULE *pTuner, R828_Set_Info R828_INFO, R828_SetFreq_Type R828_SetFreqMode); ++R828_ErrCode R828_GetRfGain(TUNER_MODULE *pTuner, R828_RF_Gain_Info *pR828_rf_gain); ++R828_ErrCode R828_RfGainMode(TUNER_MODULE *pTuner, R828_RF_Gain_TYPE R828_RfGainType); ++ ++ ++//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++// Smart GUI // ++//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// ++//extern UINT8 R828_IMR_XT[6]; ++//extern UINT8 R828_IMR_YT[6]; ++//R828_ErrCode SmartGUIFunction(void); ++ ++ ++ ++ ++ ++ ++void ++BuildR820tModule( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned char RafaelChipID ++ ); ++ ++ ++void ++r820t_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++r820t_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++r820t_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++r820t_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++r820t_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++int ++r820t_SetStandardMode( ++ TUNER_MODULE *pTuner, ++ int StandardMode ++ ); ++ ++int ++r820t_GetStandardMode( ++ TUNER_MODULE *pTuner, ++ int *pStandardMode ++ ); ++ ++ ++int ++r820t_SetStandby( ++ TUNER_MODULE *pTuner, ++ int LoopThroughType ++ ); ++ ++ ++ ++#endif ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_tda18272.c b/drivers/drivers/media/dvb/dvb-usb/tuner_tda18272.c +--- a/drivers/media/dvb/dvb-usb/tuner_tda18272.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_tda18272.c 2016-04-02 19:17:52.168066046 -0300 +@@ -0,0 +1,21631 @@ ++/** ++ ++@file ++ ++@brief TDA18272 tuner module definition ++ ++One can manipulate TDA18272 tuner through TDA18272 module. ++TDA18272 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_tda18272.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief TDA18272 tuner module builder ++ ++Use BuildTda18272Module() to build TDA18272 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to TDA18272 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr TDA18272 I2C device address ++@param [in] CrystalFreqHz TDA18272 crystal frequency in Hz ++@param [in] UnitNo TDA18272 unit number ++@param [in] IfOutputVppMode TDA18272 IF output Vp-p mode ++ ++ ++@note ++ -# One should call BuildTda18272Module() to build TDA18272 module before using it. ++ ++*/ ++void ++BuildTda18272Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int UnitNo, ++ int IfOutputVppMode ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ TDA18272_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tda18272); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_TDA18272; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = tda18272_GetTunerType; ++ pTuner->GetDeviceAddr = tda18272_GetDeviceAddr; ++ ++ pTuner->Initialize = tda18272_Initialize; ++ pTuner->SetRfFreqHz = tda18272_SetRfFreqHz; ++ pTuner->GetRfFreqHz = tda18272_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ pExtra->CrystalFreqHz = CrystalFreqHz; ++ pExtra->UnitNo = UnitNo; ++ pExtra->IfOutputVppMode = IfOutputVppMode; ++ pExtra->IsStandardBandwidthModeSet = NO; ++ pExtra->IsPowerModeSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetStandardBandwidthMode = tda18272_SetStandardBandwidthMode; ++ pExtra->GetStandardBandwidthMode = tda18272_GetStandardBandwidthMode; ++ pExtra->SetPowerMode = tda18272_SetPowerMode; ++ pExtra->GetPowerMode = tda18272_GetPowerMode; ++ pExtra->GetIfFreqHz = tda18272_GetIfFreqHz; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++tda18272_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++tda18272_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++tda18272_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ TDA18272_EXTRA_MODULE *pExtra; ++ ++ int UnitNo; ++ tmbslFrontEndDependency_t sSrvTunerFunc; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tda18272); ++ ++ // Get unit number. ++ UnitNo = pExtra->UnitNo; ++ ++ ++ // Set user-defined function to tuner structure. ++ sSrvTunerFunc.sIo.Write = tda18272_Write; ++ sSrvTunerFunc.sIo.Read = tda18272_Read; ++ sSrvTunerFunc.sTime.Get = Null; ++ sSrvTunerFunc.sTime.Wait = tda18272_Wait; ++ sSrvTunerFunc.sDebug.Print = Null; ++ sSrvTunerFunc.sMutex.Init = Null; ++ sSrvTunerFunc.sMutex.DeInit = Null; ++ sSrvTunerFunc.sMutex.Acquire = Null; ++ sSrvTunerFunc.sMutex.Release = Null; ++ sSrvTunerFunc.dwAdditionalDataSize = 0; ++ sSrvTunerFunc.pAdditionalData = Null; ++ ++ // De-initialize tuner. ++ // Note: 1. tmbslTDA182I2DeInit() doesn't access hardware. ++ // 2. Doesn't need to check tmbslTDA182I2DeInit() return, because we will get error return when the module is ++ // un-initialized. ++ tmbslTDA182I2DeInit(UnitNo); ++ ++ // Initialize tuner. ++ // Note: tmbslTDA182I2Init() doesn't access hardware. ++ if(tmbslTDA182I2Init(UnitNo, &sSrvTunerFunc, pTuner) != TM_OK) ++ goto error_status_initialize_tuner; ++ ++ // Reset tuner. ++ if(tmbslTDA182I2Reset(UnitNo) != TM_OK) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++tda18272_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ TDA18272_EXTRA_MODULE *pExtra; ++ tmUnitSelect_t UnitNo; ++ tmTDA182I2IF_AGC_Gain_t IfOutputVppMode; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tda18272); ++ ++ // Get unit number. ++ UnitNo = (tmUnitSelect_t)pExtra->UnitNo; ++ ++ // Get IF output Vp-p mode. ++ IfOutputVppMode = (tmTDA182I2IF_AGC_Gain_t)pExtra->IfOutputVppMode; ++ ++ ++ // Set tuner RF frequency. ++ if(tmbslTDA182I2SetRf(UnitNo, RfFreqHz, IfOutputVppMode) != TM_OK) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = RfFreqHz; ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++tda18272_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set TDA18272 tuner standard and bandwidth mode. ++ ++*/ ++int ++tda18272_SetStandardBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int StandardBandwidthMode ++ ) ++{ ++ TDA18272_EXTRA_MODULE *pExtra; ++ int UnitNo; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tda18272); ++ ++ // Get unit number. ++ UnitNo = pExtra->UnitNo; ++ ++ ++ // Set tuner standard and bandwidth mode. ++ if(tmbslTDA182I2SetStandardMode(UnitNo, StandardBandwidthMode) != TM_OK) ++ goto error_status_set_tuner_standard_bandwidth_mode; ++ ++ ++ // Set tuner bandwidth mode parameter. ++ pExtra->StandardBandwidthMode = StandardBandwidthMode; ++ pExtra->IsStandardBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_standard_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get TDA18272 tuner standard and bandwidth mode. ++ ++*/ ++int ++tda18272_GetStandardBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pStandardBandwidthMode ++ ) ++{ ++ TDA18272_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tda18272); ++ ++ ++ // Get tuner bandwidth mode from tuner module. ++ if(pExtra->IsStandardBandwidthModeSet != YES) ++ goto error_status_get_tuner_standard_bandwidth_mode; ++ ++ *pStandardBandwidthMode = pExtra->StandardBandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_standard_bandwidth_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set TDA18272 tuner power mode. ++ ++*/ ++int ++tda18272_SetPowerMode( ++ TUNER_MODULE *pTuner, ++ int PowerMode ++ ) ++{ ++ TDA18272_EXTRA_MODULE *pExtra; ++ int UnitNo; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tda18272); ++ ++ // Get unit number. ++ UnitNo = pExtra->UnitNo; ++ ++ ++ // Set tuner power mode. ++ if(tmbslTDA182I2SetPowerState(UnitNo, PowerMode) != TM_OK) ++ goto error_status_set_tuner_power_mode; ++ ++ ++ // Set tuner power mode parameter. ++ pExtra->PowerMode = PowerMode; ++ pExtra->IsPowerModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_power_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get TDA18272 tuner power mode. ++ ++*/ ++int ++tda18272_GetPowerMode( ++ TUNER_MODULE *pTuner, ++ int *pPowerMode ++ ) ++{ ++ TDA18272_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tda18272); ++ ++ ++ // Get tuner power mode from tuner module. ++ if(pExtra->IsPowerModeSet != YES) ++ goto error_status_get_tuner_power_mode; ++ ++ *pPowerMode = pExtra->PowerMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_power_mode: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get TDA18272 tuner IF frequency in Hz. ++ ++*/ ++int ++tda18272_GetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ) ++{ ++ TDA18272_EXTRA_MODULE *pExtra; ++ int UnitNo; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tda18272); ++ ++ // Get unit number. ++ UnitNo = pExtra->UnitNo; ++ ++ ++ // Get tuner IF frequency in Hz. ++ if(tmbslTDA182I2GetIF(UnitNo, pIfFreqHz) != TM_OK) ++ goto error_status_get_tuner_if_frequency; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_if_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is implemented for TDA18272 source code. ++ ++ ++// Read TDA18272 registers. ++tmErrorCode_t ++tda18272_Read( ++ tmUnitSelect_t tUnit, ++ UInt32 AddrSize, ++ UInt8* pAddr, ++ UInt32 ReadLen, ++ UInt8* pData ++ ) ++{ ++ ptmTDA182I2Object_t pObj; ++ ++ TUNER_MODULE *pTuner; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ unsigned long i; ++ unsigned long ReadingByteNum, ReadingByteNumMax, ReadingByteNumRem; ++ unsigned char RegReadingAddr; ++ ++ ++ // Get NXP object. ++ pObj = Null; ++ if(TDA182I2GetInstance(tUnit, &pObj) != TM_OK) ++ goto error_status_get_nxp_object; ++ ++ ++ // Get tuner. ++ pTuner = pObj->pTuner; ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ // Calculate maximum reading byte number. ++ ReadingByteNumMax = pBaseInterface->I2cReadingByteNumMax; ++ ++ ++ ++ // Get tuner register bytes. ++ // Note: Get tuner register bytes considering maximum reading byte number. ++ for(i = 0; i < ReadLen; i += ReadingByteNumMax) ++ { ++ // Set register reading address. ++ RegReadingAddr = (unsigned char)(*pAddr + i); ++ ++ // Calculate remainder reading byte number. ++ ReadingByteNumRem = ReadLen - i; ++ ++ // Determine reading byte number. ++ ReadingByteNum = (ReadingByteNumRem > ReadingByteNumMax) ? ReadingByteNumMax : ReadingByteNumRem; ++ ++ ++ // Set tuner register reading address. ++ // Note: The I2C format of tuner register reading address setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr * N + stop_bit ++ ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, &RegReadingAddr, (unsigned long)AddrSize) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_register_reading_address; ++ ++ // Get tuner register byte. ++ // Note: The I2C format of tuner register byte getting is as follows: ++ // start_bit + (DeviceAddr | reading_bit) + read_data * N + stop_bit ++ if(pI2cBridge->ForwardI2cReadingCmd(pI2cBridge, DeviceAddr, &pData[i], ReadingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ } ++ ++ ++ return TM_OK; ++ ++ ++error_status_get_tuner_registers: ++error_status_set_tuner_register_reading_address: ++error_status_get_nxp_object: ++ return TM_ERR_READ; ++} ++ ++ ++ ++ ++ ++// Write TDA18272 registers. ++tmErrorCode_t ++tda18272_Write( ++ tmUnitSelect_t tUnit, ++ UInt32 AddrSize, ++ UInt8* pAddr, ++ UInt32 WriteLen, ++ UInt8* pData ++ ) ++{ ++ ptmTDA182I2Object_t pObj; ++ ++ TUNER_MODULE *pTuner; ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ unsigned char DeviceAddr; ++ unsigned char WritingBuffer[I2C_BUFFER_LEN]; ++ ++ unsigned long i; ++ unsigned long WritingByteNum; ++ ++ ++ // Get NXP object. ++ pObj = Null; ++ if(TDA182I2GetInstance(tUnit, &pObj) != TM_OK) ++ goto error_status_get_nxp_object; ++ ++ ++ // Get tuner. ++ pTuner = pObj->pTuner; ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ // Calculate writing byte number. ++ WritingByteNum = (unsigned char)(AddrSize + WriteLen); ++ ++ ++ // Set writing bytes. ++ // Note: The I2C format of tuner register byte setting is as follows: ++ // start_bit + (DeviceAddr | writing_bit) + addr * N + data * N + stop_bit ++ for(i = 0; i < AddrSize; i++) ++ WritingBuffer[i] = pAddr[i]; ++ ++ for(i = 0; i < WriteLen; i++) ++ WritingBuffer[AddrSize + i] = pData[i]; ++ ++ // Set tuner register bytes with writing buffer. ++ if(pI2cBridge->ForwardI2cWritingCmd(pI2cBridge, DeviceAddr, WritingBuffer, WritingByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return TM_OK; ++ ++ ++error_status_set_tuner_registers: ++error_status_get_nxp_object: ++ return TM_ERR_WRITE; ++} ++ ++ ++ ++ ++ ++// Wait a time. ++tmErrorCode_t ++tda18272_Wait( ++ tmUnitSelect_t tUnit, ++ UInt32 tms ++ ) ++{ ++ ptmTDA182I2Object_t pObj; ++ ++ TUNER_MODULE *pTuner; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ ++ // Get NXP object. ++ pObj = Null; ++ if(TDA182I2GetInstance(tUnit, &pObj) != TM_OK) ++ goto error_status_get_nxp_object; ++ ++ ++ // Get tuner. ++ pTuner = pObj->pTuner; ++ ++ // Get I2C bridge. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ // Wait a time. ++ pBaseInterface->WaitMs(pBaseInterface, tms); ++ ++ ++ return TM_OK; ++ ++ ++error_status_get_nxp_object: ++ return TM_ERR_BAD_UNIT_NUMBER; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by NXP. ++ ++ ++ ++ ++ ++// NXP source code - .\tmbslTDA182I2\src\tmbslTDA182I2.c ++ ++ ++//----------------------------------------------------------------------------- ++// $Header: ++// (C) Copyright 2001 NXP Semiconductors, All rights reserved ++// ++// This source code and any compilation or derivative thereof is the sole ++// property of NXP Corporation and is provided pursuant to a Software ++// License Agreement. This code is the proprietary information of NXP ++// Corporation and is confidential in nature. Its use and dissemination by ++// any party other than NXP Corporation is strictly limited by the ++// confidential information provisions of the Agreement referenced above. ++//----------------------------------------------------------------------------- ++// FILE NAME: tmbslTDA182I2.c ++// ++// %version: 33 % ++// ++// DESCRIPTION: Function for the Hybrid silicon tuner TDA182I2 ++// ++// DOCUMENT REF: ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++ ++//----------------------------------------------------------------------------- ++// Standard include files: ++//----------------------------------------------------------------------------- ++// ++ ++//#include "tmNxTypes.h" ++//#include "tmCompId.h" ++//#include "tmFrontEnd.h" ++//#include "tmbslFrontEndTypes.h" ++ ++//#include "tmddTDA182I2.h" ++ ++//#ifdef TMBSL_TDA18272 ++// #include "tmbslTDA18272.h" ++//#else /* TMBSL_TDA18272 */ ++// #include "tmbslTDA18212.h" ++//#endif /* TMBSL_TDA18272 */ ++ ++//----------------------------------------------------------------------------- ++// Project include files: ++//----------------------------------------------------------------------------- ++// ++//#include "tmbslTDA182I2local.h" ++//#include "tmbslTDA182I2Instance.h" ++ ++//----------------------------------------------------------------------------- ++// Types and defines: ++//----------------------------------------------------------------------------- ++// ++ ++//----------------------------------------------------------------------------- ++// Global data: ++//----------------------------------------------------------------------------- ++// ++ ++//----------------------------------------------------------------------------- ++// Exported functions: ++//----------------------------------------------------------------------------- ++// ++ ++//----------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA18211Init: ++// ++// DESCRIPTION: create an instance of a TDA182I2 Tuner ++// ++// RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER ++// TM_OK ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmbslTDA182I2Init ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmbslFrontEndDependency_t* psSrvFunc, /* I: setup parameters */ ++ TUNER_MODULE *pTuner // Added by Realtek ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if (psSrvFunc == Null) ++ { ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ } ++ ++ if(err == TM_OK) ++ { ++ //---------------------- ++ // initialize the Object ++ //---------------------- ++ // pObj initialization ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ } ++ ++ /* check driver state */ ++ if (err == TM_OK || err == TDA182I2_ERR_NOT_INITIALIZED) ++ { ++ if (pObj != Null && pObj->init == True) ++ { ++ err = TDA182I2_ERR_NOT_INITIALIZED; ++ } ++ else ++ { ++ /* initialize the Object */ ++ if (pObj == Null) ++ { ++ err = TDA182I2AllocInstance(tUnit, &pObj); ++ if (err != TM_OK || pObj == Null) ++ { ++ err = TDA182I2_ERR_NOT_INITIALIZED; ++ } ++ } ++ ++ if (err == TM_OK) ++ { ++ // initialize the Object by default values ++ pObj->sRWFunc = psSrvFunc->sIo; ++ pObj->sTime = psSrvFunc->sTime; ++ pObj->sDebug = psSrvFunc->sDebug; ++ ++ if( psSrvFunc->sMutex.Init != Null ++ && psSrvFunc->sMutex.DeInit != Null ++ && psSrvFunc->sMutex.Acquire != Null ++ && psSrvFunc->sMutex.Release != Null) ++ { ++ pObj->sMutex = psSrvFunc->sMutex; ++ ++ err = pObj->sMutex.Init(&pObj->pMutex); ++ } ++ ++ pObj->init = True; ++ err = TM_OK; ++ ++ err = tmddTDA182I2Init(tUnit, psSrvFunc); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Init(0x%08X) failed.", pObj->tUnit)); ++ } ++ } ++ } ++ ++ // Added by Realtek ++ pObj->pTuner = pTuner; ++ ++ return err; ++} ++ ++//----------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA182I2DeInit: ++// ++// DESCRIPTION: destroy an instance of a TDA182I2 Tuner ++// ++// RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER ++// TDA182I2_ERR_NOT_INITIALIZED ++// TM_OK ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmbslTDA182I2DeInit ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* check input parameters */ ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2DeInit(tUnit); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2DeInit(0x%08X) failed.", pObj->tUnit)); ++ ++ (void)TDA182I2MutexRelease(pObj); ++ ++ if(pObj->sMutex.DeInit != Null) ++ { ++ if(pObj->pMutex != Null) ++ { ++ err = pObj->sMutex.DeInit(pObj->pMutex); ++ } ++ ++ pObj->sMutex.Init = Null; ++ pObj->sMutex.DeInit = Null; ++ pObj->sMutex.Acquire = Null; ++ pObj->sMutex.Release = Null; ++ ++ pObj->pMutex = Null; ++ } ++ } ++ ++ err = TDA182I2DeAllocInstance(tUnit); ++ ++ return err; ++} ++ ++//----------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA182I2GetSWVersion: ++// ++// DESCRIPTION: Return the version of this device ++// ++// RETURN: TM_OK ++// ++// NOTES: Values defined in the tmTDA182I2local.h file ++//----------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmbslTDA182I2GetSWVersion ++( ++ ptmSWVersion_t pSWVersion /* I: Receives SW Version */ ++) ++{ ++ tmErrorCode_t err = TDA182I2_ERR_NOT_INITIALIZED; ++ ++ err = tmddTDA182I2GetSWVersion(pSWVersion); ++ ++ return err; ++} ++ ++//----------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA182I2CheckHWVersion: ++// ++// DESCRIPTION: Check HW version ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: Values defined in the tmTDA182I2local.h file ++//----------------------------------------------------------------------------- ++tmErrorCode_t ++tmbslTDA182I2CheckHWVersion ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TDA182I2_ERR_NOT_INITIALIZED; ++ UInt16 uIdentity = 0; ++ UInt8 majorRevision = 0; ++ ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2GetIdentity(tUnit, &uIdentity); ++ ++ if(err == TM_OK) ++ { ++ if(uIdentity == 18272 || uIdentity == 18212) ++ { ++ /* TDA18272/12 found. Check Major Revision*/ ++ err = tmddTDA182I2GetMajorRevision(tUnit, &majorRevision); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetMajorRevision(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK && majorRevision != 1) ++ { ++ /* Only TDA18272/12 ES2 are supported */ ++ err = TDA182I2_ERR_BAD_VERSION; ++ } ++ } ++ else ++ { ++ err = TDA182I2_ERR_BAD_VERSION; ++ } ++ } ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA182I2SetPowerState: ++// ++// DESCRIPTION: Set the power state of this device. ++// ++// RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER ++// TDA182I2_ERR_NOT_INITIALIZED ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmbslTDA182I2SetPowerState ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmTDA182I2PowerState_t powerState /* I: Power state of this device */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // pObj initialization ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ if(powerState > pObj->minPowerState) ++ { ++ powerState = pObj->minPowerState; ++ } ++ ++ // Call tmddTDA182I2SetPowerState ++ err = tmddTDA182I2SetPowerState(tUnit, powerState); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetPowerState(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // set power state ++ pObj->curPowerState = powerState; ++ } ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA182I2GetPowerState: ++// ++// DESCRIPTION: Get the power state of this device. ++// ++// RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER ++// TDA182I2_ERR_NOT_INITIALIZED ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmbslTDA182I2GetPowerState ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmTDA182I2PowerState_t *pPowerState /* O: Power state of this device */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(pPowerState == Null) ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ // pObj initialization ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // get power state ++ *pPowerState = pObj->curPowerState; ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA182I2SetStandardMode: ++// ++// DESCRIPTION: Set the standard mode of this device. ++// ++// RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER ++// TDA182I2_ERR_NOT_INITIALIZED ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmbslTDA182I2SetStandardMode ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmTDA182I2StandardMode_t StandardMode /* I: Standard mode of this device */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // pObj initialization ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // store standard mode ++ pObj->StandardMode = StandardMode; ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA182I2GetStandardMode: ++// ++// DESCRIPTION: Get the standard mode of this device. ++// ++// RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER ++// TDA182I2_ERR_NOT_INITIALIZED ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmbslTDA182I2GetStandardMode ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmTDA182I2StandardMode_t *pStandardMode /* O: Standard mode of this device */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(pStandardMode == Null) ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ // pObj initialization ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Get standard mode */ ++ *pStandardMode = pObj->StandardMode; ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA182I2SetRf: ++// ++// DESCRIPTION: Calculate i2c I2CMap & write in TDA182I2 ++// ++// RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER ++// TDA182I2_ERR_NOT_INITIALIZED ++// TDA182I2_ERR_BAD_PARAMETER ++// TMBSL_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmbslTDA182I2SetRf ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uRF, /* I: RF frequency in hertz */ ++ tmTDA182I2IF_AGC_Gain_t IF_Gain // Added by realtek ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ Bool bIRQWait = True; ++ UInt8 ratioL, ratioH; ++ UInt32 DeltaL, DeltaH; ++ UInt8 uAGC1_loop_off; ++ UInt8 uRF_Filter_Gv = 0; ++ ++ //------------------------------ ++ // test input parameters ++ //------------------------------ ++ // pObj initialization ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2GetIRQWait(tUnit, &bIRQWait); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetIRQWait(0x%08X) failed.", tUnit)); ++ ++ pObj->uRF = uRF; ++ ++ if(err == TM_OK) ++ { ++ /* Set LPF */ ++ err = tmddTDA182I2SetLP_FC(tUnit, pObj->Std_Array[pObj->StandardMode].LPF); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetLP_FC(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set LPF Offset */ ++ err = tmddTDA182I2SetLP_FC_Offset(tUnit, pObj->Std_Array[pObj->StandardMode].LPF_Offset); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetLP_FC_Offset(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set IF Gain */ ++// err = tmddTDA182I2SetIF_Level(tUnit, pObj->Std_Array[pObj->StandardMode].IF_Gain); ++ err = tmddTDA182I2SetIF_Level(tUnit, IF_Gain); // Modified by Realtek ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIF_Level(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set IF Notch */ ++ err = tmddTDA182I2SetIF_ATSC_Notch(tUnit, pObj->Std_Array[pObj->StandardMode].IF_Notch); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIF_ATSC_Notch(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Enable/disable HPF */ ++ if ( pObj->Std_Array[pObj->StandardMode].IF_HPF == tmTDA182I2_IF_HPF_Disabled ) ++ { ++ err = tmddTDA182I2SetHi_Pass(tUnit, 0); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetHi_Pass(0x%08X, 0) failed.", tUnit)); ++ } ++ else ++ { ++ err = tmddTDA182I2SetHi_Pass(tUnit, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetHi_Pass(0x%08X, 1) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Set IF HPF */ ++ err = tmddTDA182I2SetIF_HP_Fc(tUnit, (UInt8)(pObj->Std_Array[pObj->StandardMode].IF_HPF - 1)); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIF_HP_Fc(0x%08X) failed.", tUnit)); ++ } ++ } ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set DC Notch */ ++ err = tmddTDA182I2SetIF_Notch(tUnit, pObj->Std_Array[pObj->StandardMode].DC_Notch); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIF_Notch(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGC1 LNA Top */ ++ err = tmddTDA182I2SetAGC1_TOP(tUnit, pObj->Std_Array[pObj->StandardMode].AGC1_LNA_TOP); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC1_TOP(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGC2 RF Top */ ++ err = tmddTDA182I2SetAGC2_TOP(tUnit, pObj->Std_Array[pObj->StandardMode].AGC2_RF_Attenuator_TOP); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC2_TOP(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGC3 RF AGC Top */ ++ if (pObj->uRF < tmTDA182I2_AGC3_RF_AGC_TOP_FREQ_LIM) ++ { ++ err = tmddTDA182I2SetRFAGC_Top(tUnit, pObj->Std_Array[pObj->StandardMode].AGC3_RF_AGC_TOP_Low_band); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetRFAGC_Top(0x%08X) failed.", tUnit)); ++ } ++ else ++ { ++ err = tmddTDA182I2SetRFAGC_Top(tUnit, pObj->Std_Array[pObj->StandardMode].AGC3_RF_AGC_TOP_High_band); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetRFAGC_Top(0x%08X) failed.", tUnit)); ++ } ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGC4 IR Mixer Top */ ++ err = tmddTDA182I2SetIR_Mixer_Top(tUnit, pObj->Std_Array[pObj->StandardMode].AGC4_IR_Mixer_TOP); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIR_Mixer_Top(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGC5 IF AGC Top */ ++ err = tmddTDA182I2SetAGC5_TOP(tUnit, pObj->Std_Array[pObj->StandardMode].AGC5_IF_AGC_TOP); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC5_TOP(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGC3 Adapt */ ++ err = tmddTDA182I2SetPD_RFAGC_Adapt(tUnit, pObj->Std_Array[pObj->StandardMode].AGC3_Adapt); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetPD_RFAGC_Adapt(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGC3 Adapt TOP */ ++ err = tmddTDA182I2SetRFAGC_Adapt_TOP(tUnit, pObj->Std_Array[pObj->StandardMode].AGC3_Adapt_TOP); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetRFAGC_Adapt_TOP(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGC5 Atten 3dB */ ++ err = tmddTDA182I2SetRF_Atten_3dB(tUnit, pObj->Std_Array[pObj->StandardMode].AGC5_Atten_3dB); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetRF_Atten_3dB(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGC5 Detector HPF */ ++ err = tmddTDA182I2SetAGC5_Ana(tUnit, pObj->Std_Array[pObj->StandardMode].AGC5_Detector_HPF); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC5_Ana(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set AGCK Mode */ ++ err = tmddTDA182I2SetAGCK_Mode(tUnit, pObj->Std_Array[pObj->StandardMode].GSK&0x03); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGCK_Mode(0x%08X) failed.", tUnit)); ++ ++ err = tmddTDA182I2SetAGCK_Step(tUnit, (pObj->Std_Array[pObj->StandardMode].GSK&0x0C)>>2); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGCK_Step(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set H3H5 VHF Filter 6 */ ++ err = tmddTDA182I2SetPSM_StoB(tUnit, pObj->Std_Array[pObj->StandardMode].H3H5_VHF_Filter6); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetPSM_StoB(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set IF */ ++ err = tmddTDA182I2SetIF_Freq(tUnit, pObj->Std_Array[pObj->StandardMode].IF - pObj->Std_Array[pObj->StandardMode].CF_Offset); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIF_Freq(0x%08X) failed.", tUnit)); ++ } ++ if (pObj->Std_Array[pObj->StandardMode].LTO_STO_immune && pObj->Master ) ++ { ++ /* save RF_Filter_Gv current value */ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2GetAGC2_Gain_Read (tUnit, &uRF_Filter_Gv); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetRF_Filter_Gv(0x%08X) failed.", tUnit)); ++ } ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetRF_Filter_Gv(tUnit, uRF_Filter_Gv ); ++ } ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetForce_AGC2_gain(tUnit, 0x1); ++ } ++ /* smooth RF_Filter_Gv to min value */ ++ if((err == TM_OK)&&(uRF_Filter_Gv != 0)) ++ { ++ do ++ { ++ err = tmddTDA182I2SetRF_Filter_Gv(tUnit, uRF_Filter_Gv -1 ); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetRF_Filter_Gv(0x%08X) failed.", tUnit)); ++ if(err == TM_OK) ++ { ++ err = TDA182I2Wait(pObj, 10); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetRF_Filter_Cap(0x%08X) failed.", tUnit)); ++ } ++ uRF_Filter_Gv = uRF_Filter_Gv -1 ; ++ } ++ while ( uRF_Filter_Gv > 0); ++ } ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetRF_Atten_3dB (tUnit, 0x01); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetRF_Filter_Gv(0x%08X) failed.", tUnit)); ++ } ++ } ++ if(err == TM_OK) ++ { ++ /* Set RF */ ++ err = tmddTDA182I2SetRF_Freq(tUnit, uRF + pObj->Std_Array[pObj->StandardMode].CF_Offset); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetRF_Freq(0x%08X) failed.", tUnit)); ++ ++ } ++ ++ if (pObj->Std_Array[pObj->StandardMode].LTO_STO_immune && pObj->Master ) ++ { ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetRF_Atten_3dB (tUnit, 0x00); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetRF_Filter_Gv(0x%08X) failed.", tUnit)); ++ } ++ err = TDA182I2Wait(pObj, 50); ++ if(err == TM_OK) ++ { ++ tmddTDA182I2SetForce_AGC2_gain(tUnit, 0x0); ++ } ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Spurious reduction begin */ ++ ratioL = (UInt8)(uRF / 16000000); ++ ratioH = (UInt8)(uRF / 16000000) + 1; ++ DeltaL = (uRF - (ratioL * 16000000)); ++ DeltaH = ((ratioH * 16000000) - uRF); ++ ++ if (uRF < 72000000 ) ++ { ++ /* Set sigma delta clock*/ ++ err = tmddTDA182I2SetDigital_Clock_Mode(tUnit, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetDigital_Clock_Mode(0x%08X, sigma delta clock) failed.", tUnit)); ++ } ++ else if (uRF < 104000000 ) ++ { ++ /* Set 16 Mhz Xtal clock */ ++ err = tmddTDA182I2SetDigital_Clock_Mode(tUnit, 0); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetDigital_Clock_Mode(0x%08X, 16 Mhz xtal clock) failed.", tUnit)); ++ } ++ else if (uRF <= 120000000 ) ++ { ++ /* Set sigma delta clock*/ ++ err = tmddTDA182I2SetDigital_Clock_Mode(tUnit, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetDigital_Clock_Mode(0x%08X, sigma delta clock) failed.", tUnit)); ++ } ++ else /* RF above 120 MHz */ ++ { ++ if (DeltaL <= DeltaH ) ++ { ++ if (ratioL & 0x000001 ) /* ratioL odd */ ++ { ++ /* Set 16 Mhz Xtal clock */ ++ err = tmddTDA182I2SetDigital_Clock_Mode(tUnit, 0); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetDigital_Clock_Mode(0x%08X, 16 Mhz xtal clock) failed.", tUnit)); ++ } ++ else /* ratioL even */ ++ { ++ /* Set sigma delta clock*/ ++ err = tmddTDA182I2SetDigital_Clock_Mode(tUnit, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetDigital_Clock_Mode(0x%08X, sigma delta clock) failed.", tUnit)); ++ } ++ ++ } ++ else /* (DeltaL > DeltaH ) */ ++ { ++ if (ratioL & 0x000001 ) /*(ratioL odd)*/ ++ { ++ /* Set sigma delta clock*/ ++ err = tmddTDA182I2SetDigital_Clock_Mode(tUnit, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetDigital_Clock_Mode(0x%08X, sigma delta clock) failed.", tUnit)); ++ } ++ else ++ { ++ /* Set 16 Mhz Xtal clock */ ++ err = tmddTDA182I2SetDigital_Clock_Mode(tUnit, 0); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetDigital_Clock_Mode(0x%08X, 16 Mhz xtal clock) failed.", tUnit)); ++ } ++ } ++ } ++ } ++ /* Spurious reduction end */ ++ ++ if(err == TM_OK) ++ { ++ if ( pObj->Std_Array[pObj->StandardMode].AGC1_Freeze == True ) ++ { ++ err = tmddTDA182I2GetAGC1_loop_off(tUnit, &uAGC1_loop_off) ; ++ ++ if (uAGC1_loop_off == 0) // first AGC1 freeze ++ { ++ err = tmddTDA182I2SetAGC1_loop_off(tUnit, 0x1 ) ; ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetForce_AGC1_gain(tUnit, 0x1); ++ } ++ } ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2AGC1_Adapt (tUnit); /* Adapt AGC1gain from Last SetRF */ ++ } ++ } ++ else ++ { ++ err = tmddTDA182I2SetForce_AGC1_gain(tUnit, 0x0); ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetAGC1_loop_off(tUnit, 0x0 ) ; ++ } ++ } ++ } ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmbslTDA182I2GetRf: ++// ++// DESCRIPTION: Get the frequency programmed in the tuner ++// ++// RETURN: TMBSL_ERR_TUNER_BAD_UNIT_NUMBER ++// TDA182I2_ERR_NOT_INITIALIZED ++// TM_OK ++// ++// NOTES: The value returned is the one stored in the Object ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmbslTDA182I2GetRf ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* puRF /* O: RF frequency in hertz */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(puRF == Null) ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ ++ //------------------------------ ++ // test input parameters ++ //------------------------------ ++ // pObj initialization ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Get RF */ ++ *puRF = pObj->uRF/* - pObj->Std_Array[pObj->StandardMode].CF_Offset*/; ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2Reset */ ++/*============================================================================*/ ++tmErrorCode_t ++tmbslTDA182I2Reset ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ Bool bIRQWait = True; ++ ++ //------------------------------ ++ // test input parameters ++ //------------------------------ ++ // pObj initialization ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2GetIRQWait(tUnit, &bIRQWait); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetIRQWait(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2Init(tUnit); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2Init(0x%08X) failed.", tUnit)); ++ } ++ if(err == TM_OK) ++ { ++ // Wait for XtalCal End ( Master only ) ++ if (pObj->Master) ++ { ++ err = TDA182I2WaitXtalCal_End ( pObj, 100, 5); ++ } ++ else ++ { ++ /* Initialize Fmax_LO and N_CP_Current */ ++ err = tmddTDA182I2SetFmax_Lo(tUnit, 0x00); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetFmax_Lo(0x%08X, 0x0A) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetN_CP_Current(tUnit, 0x68); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetN_CP_Current(0x%08X, 0x68) failed.", tUnit)); ++ } ++ } ++ } ++ if(err == TM_OK) ++ { ++ // initialize tuner ++ err = tmddTDA182I2Reset(tUnit); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Reset(0x%08X) failed.", tUnit)); ++ } ++ if (err == TM_OK) ++ { ++ /* Initialize Fmax_LO and N_CP_Current */ ++ err = tmddTDA182I2SetFmax_Lo(tUnit, 0x0A); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetFmax_Lo(0x%08X, 0x0A) failed.", tUnit)); ++ } ++ if (err == TM_OK) ++ { ++ err = tmddTDA182I2SetLT_Enable(tUnit, pObj->LT_Enable ); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetLT_Enable(0x%08X, 0) failed.", tUnit)); ++ } ++ if (err == TM_OK) ++ { ++ err = tmddTDA182I2SetPSM_AGC1(tUnit, pObj->PSM_AGC1 ); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetPSM_AGC1(0x%08X, 1) failed.", tUnit)); ++ } ++ if (err == TM_OK) ++ { ++ err = tmddTDA182I2SetAGC1_6_15dB(tUnit, pObj->AGC1_6_15dB ); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC1_6_15dB(0x%08X, 0) failed.", tUnit)); ++ } ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2GetIF */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2GetIF ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* puIF /* O: IF Frequency in hertz */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(puIF == Null) ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ *puIF = pObj->Std_Array[pObj->StandardMode].IF - pObj->Std_Array[pObj->StandardMode].CF_Offset; ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2GetCF_Offset */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2GetCF_Offset( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* puOffset /* O: Center frequency offset in hertz */ ++ ) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(puOffset == Null) ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ *puOffset = pObj->Std_Array[pObj->StandardMode].CF_Offset; ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2GetLockStatus */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2GetLockStatus ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmbslFrontEndState_t* pLockStatus /* O: PLL Lock status */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ UInt8 uValue, uValueLO; ++ ++ if( pLockStatus == Null ) ++ { ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2GetLO_Lock(tUnit, &uValueLO); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetLO_Lock(0x%08X) failed.", tUnit)); ++ } ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2GetIRQ_status(tUnit, &uValue); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetIRQ_status(0x%08X) failed.", tUnit)); ++ ++ uValue = uValue & uValueLO; ++ } ++ if(err == TM_OK) ++ { ++ *pLockStatus = (uValue)? tmbslFrontEndStateLocked : tmbslFrontEndStateNotLocked; ++ } ++ else ++ { ++ *pLockStatus = tmbslFrontEndStateUnknown; ++ } ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2GetPowerLevel */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2GetPowerLevel ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* pPowerLevel /* O: Power Level in dBuV */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(pPowerLevel == Null) ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ *pPowerLevel = 0; ++ ++ err = tmddTDA182I2GetPower_Level(tUnit, (UInt8 *)pPowerLevel); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetPower_Level(0x%08X) failed.", tUnit)); ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2SetIRQWait */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2SetIRQWait ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ Bool bWait /* I: Determine if we need to wait IRQ in driver functions */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetIRQWait(tUnit, bWait); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIRQWait(0x%08X) failed.", tUnit)); ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2GetIRQWait */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2GetIRQWait ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ Bool* pbWait /* O: Determine if we need to wait IRQ in driver functions */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(pbWait == Null) ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2GetIRQWait(tUnit, pbWait); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetIRQWait(0x%08X) failed.", tUnit)); ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2GetIRQ */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2GetIRQ ++( ++ tmUnitSelect_t tUnit /* I: Unit number */, ++ Bool* pbIRQ /* O: IRQ triggered */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(pbIRQ == Null) ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ *pbIRQ = 0; ++ ++ err = tmddTDA182I2GetIRQ_status(tUnit, (UInt8 *)pbIRQ); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetIRQ_status(0x%08X) failed.", tUnit)); ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2WaitIRQ */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2WaitIRQ ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 timeOut, /* I: timeOut for IRQ wait */ ++ UInt32 waitStep, /* I: wait step */ ++ UInt8 irqStatus /* I: IRQs to wait */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2WaitIRQ(tUnit, timeOut, waitStep, irqStatus); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2WaitIRQ(0x%08X) failed.", tUnit)); ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2GetXtalCal_End */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2GetXtalCal_End ++( ++ tmUnitSelect_t tUnit /* I: Unit number */, ++ Bool* pbXtalCal_End /* O: XtalCal_End triggered */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(pbXtalCal_End == Null) ++ err = TDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ *pbXtalCal_End = 0; ++ ++ err = tmddTDA182I2GetMSM_XtalCal_End(tUnit, (UInt8 *)pbXtalCal_End); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetMSM_XtalCal_End(0x%08X) failed.", tUnit)); ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* tmbslTDA182I2WaitXtalCal_End */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2WaitXtalCal_End ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 timeOut, /* I: timeOut for IRQ wait */ ++ UInt32 waitStep /* I: wait step */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2WaitXtalCal_End(tUnit, timeOut, waitStep); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2WaitXtalCal_End(0x%08X) failed.", tUnit)); ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++/*============================================================================*/ ++/* tmbslTDA182I2CheckRFFilterRobustness */ ++/*============================================================================*/ ++/* ++tmErrorCode_t ++tmbslTDA182I2CheckRFFilterRobustness ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ ptmTDA182I2RFFilterRating rating // O: RF Filter rating ++ ) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ UInt8 rfcal_log_0 = 0; ++ UInt8 rfcal_log_2 = 0; ++ UInt8 rfcal_log_3 = 0; ++ UInt8 rfcal_log_5 = 0; ++ UInt8 rfcal_log_6 = 0; ++ UInt8 rfcal_log_8 = 0; ++ UInt8 rfcal_log_9 = 0; ++ UInt8 rfcal_log_11 = 0; ++ ++ double VHFLow_0 = 0.0; ++ double VHFLow_1 = 0.0; ++ double VHFHigh_0 = 0.0; ++ double VHFHigh_1 = 0.0; ++ double UHFLow_0 = 0.0; ++ double UHFLow_1 = 0.0; ++ double UHFHigh_0 = 0.0; ++ double UHFHigh_1 = 0.0; ++ ++ err = tmddTDA182I2Getrfcal_log_0(tUnit, &rfcal_log_0); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Getrfcal_log_0(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2Getrfcal_log_2(tUnit, &rfcal_log_2); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Getrfcal_log_2(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2Getrfcal_log_3(tUnit, &rfcal_log_3); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Getrfcal_log_3(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2Getrfcal_log_5(tUnit, &rfcal_log_5); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Getrfcal_log_5(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2Getrfcal_log_6(tUnit, &rfcal_log_6); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Getrfcal_log_6(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2Getrfcal_log_8(tUnit, &rfcal_log_8); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Getrfcal_log_8(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2Getrfcal_log_9(tUnit, &rfcal_log_9); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Getrfcal_log_9(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2Getrfcal_log_11(tUnit, &rfcal_log_11); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Getrfcal_log_11(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ if (rfcal_log_0 & 0x80) ++ { ++ rating->VHFLow_0_Margin = 0; ++ rating->VHFLow_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Error; ++ } ++ else ++ { ++ // VHFLow_0 ++ VHFLow_0 = 100 * (45 - 39.8225 * (1 + (0.31 * (rfcal_log_0 < 64 ? rfcal_log_0 : rfcal_log_0 - 128)) / 1.0 / 100.0)) / 45.0; ++ rating->VHFLow_0_Margin = 0.0024 * VHFLow_0 * VHFLow_0 * VHFLow_0 - 0.101 * VHFLow_0 * VHFLow_0 + 1.629 * VHFLow_0 + 1.8266; ++ if (rating->VHFLow_0_Margin >= 0) ++ { ++ rating->VHFLow_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_High; ++ } ++ else ++ { ++ rating->VHFLow_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Low; ++ } ++ } ++ ++ if (rfcal_log_2 & 0x80) ++ { ++ rating->VHFLow_1_Margin = 0; ++ rating->VHFLow_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Error; ++ } ++ else ++ { ++ // VHFLow_1 ++ VHFLow_1 = 100 * (152.1828 * (1 + (1.53 * (rfcal_log_2 < 64 ? rfcal_log_2 : rfcal_log_2 - 128)) / 1.0 / 100.0) - (144.896 - 6)) / (144.896 - 6); ++ rating->VHFLow_1_Margin = 0.0024 * VHFLow_1 * VHFLow_1 * VHFLow_1 - 0.101 * VHFLow_1 * VHFLow_1 + 1.629 * VHFLow_1 + 1.8266; ++ if (rating->VHFLow_1_Margin >= 0) ++ { ++ rating->VHFLow_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_High; ++ } ++ else ++ { ++ rating->VHFLow_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Low; ++ } ++ } ++ ++ if (rfcal_log_3 & 0x80) ++ { ++ rating->VHFHigh_0_Margin = 0; ++ rating->VHFHigh_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Error; ++ } ++ else ++ { ++ // VHFHigh_0 ++ VHFHigh_0 = 100 * ((144.896 + 6) - 135.4063 * (1 + (0.27 * (rfcal_log_3 < 64 ? rfcal_log_3 : rfcal_log_3 - 128)) / 1.0 / 100.0)) / (144.896 + 6); ++ rating->VHFHigh_0_Margin = 0.0024 * VHFHigh_0 * VHFHigh_0 * VHFHigh_0 - 0.101 * VHFHigh_0 * VHFHigh_0 + 1.629 * VHFHigh_0 + 1.8266; ++ if (rating->VHFHigh_0_Margin >= 0) ++ { ++ rating->VHFHigh_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_High; ++ } ++ else ++ { ++ rating->VHFHigh_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Low; ++ } ++ } ++ ++ if (rfcal_log_5 & 0x80) ++ { ++ rating->VHFHigh_1_Margin = 0; ++ rating->VHFHigh_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Error; ++ } ++ else ++ { ++ // VHFHigh_1 ++ VHFHigh_1 = 100 * (383.1455 * (1 + (0.91 * (rfcal_log_5 < 64 ? rfcal_log_5 : rfcal_log_5 - 128)) / 1.0 / 100.0) - (367.104 - 8)) / (367.104 - 8); ++ rating->VHFHigh_1_Margin = 0.0024 * VHFHigh_1 * VHFHigh_1 * VHFHigh_1 - 0.101 * VHFHigh_1 * VHFHigh_1 + 1.629 * VHFHigh_1 + 1.8266; ++ if (rating->VHFHigh_1_Margin >= 0) ++ { ++ rating->VHFHigh_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_High; ++ } ++ else ++ { ++ rating->VHFHigh_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Low; ++ } ++ } ++ ++ if (rfcal_log_6 & 0x80) ++ { ++ rating->UHFLow_0_Margin = 0; ++ rating->UHFLow_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Error; ++ } ++ else ++ { ++ // UHFLow_0 ++ UHFLow_0 = 100 * ((367.104 + 8) - 342.6224 * (1 + (0.21 * (rfcal_log_6 < 64 ? rfcal_log_6 : rfcal_log_6 - 128)) / 1.0 / 100.0)) / (367.104 + 8); ++ rating->UHFLow_0_Margin = 0.0024 * UHFLow_0 * UHFLow_0 * UHFLow_0 - 0.101 * UHFLow_0 * UHFLow_0 + 1.629 * UHFLow_0 + 1.8266; ++ if (rating->UHFLow_0_Margin >= 0) ++ { ++ rating->UHFLow_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_High; ++ } ++ else ++ { ++ rating->UHFLow_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Low; ++ } ++ } ++ ++ if (rfcal_log_8 & 0x80) ++ { ++ rating->UHFLow_1_Margin = 0; ++ rating->UHFLow_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Error; ++ } ++ else ++ { ++ // UHFLow_1 ++ UHFLow_1 = 100 * (662.5595 * (1 + (0.33 * (rfcal_log_8 < 64 ? rfcal_log_8 : rfcal_log_8 - 128)) / 1.0 / 100.0) - (624.128 - 2)) / (624.128 - 2); ++ rating->UHFLow_1_Margin = 0.0024 * UHFLow_1 * UHFLow_1 * UHFLow_1 - 0.101 * UHFLow_1 * UHFLow_1 + 1.629 * UHFLow_1 + 1.8266; ++ if (rating->UHFLow_1_Margin >= 0) ++ { ++ rating->UHFLow_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_High; ++ } ++ else ++ { ++ rating->UHFLow_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Low; ++ } ++ } ++ ++ if (rfcal_log_9 & 0x80) ++ { ++ rating->UHFHigh_0_Margin = 0; ++ rating->UHFHigh_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Error; ++ } ++ else ++ { ++ // UHFHigh_0 ++ UHFHigh_0 = 100 * ((624.128 + 2) - 508.2747 * (1 + (0.23 * (rfcal_log_9 < 64 ? rfcal_log_9 : rfcal_log_9 - 128)) / 1.0 / 100.0)) / (624.128 + 2); ++ rating->UHFHigh_0_Margin = 0.0024 * UHFHigh_0 * UHFHigh_0 * UHFHigh_0 - 0.101 * UHFHigh_0 * UHFHigh_0 + 1.629 * UHFHigh_0 + 1.8266; ++ if (rating->UHFHigh_0_Margin >= 0) ++ { ++ rating->UHFHigh_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_High; ++ } ++ else ++ { ++ rating->UHFHigh_0_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Low; ++ } ++ } ++ ++ if (rfcal_log_11 & 0x80) ++ { ++ rating->UHFHigh_1_Margin = 0; ++ rating->UHFHigh_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Error; ++ } ++ else ++ { ++ // UHFHigh_1 ++ UHFHigh_1 = 100 * (947.8913 * (1 + (0.3 * (rfcal_log_11 < 64 ? rfcal_log_11 : rfcal_log_11 - 128)) / 1.0 / 100.0) - (866 - 14)) / (866 - 14); ++ rating->UHFHigh_1_Margin = 0.0024 * UHFHigh_1 * UHFHigh_1 * UHFHigh_1 - 0.101 * UHFHigh_1 * UHFHigh_1 + 1.629 * UHFHigh_1 + 1.8266; ++ if (rating->UHFHigh_1_Margin >= 0) ++ { ++ rating->UHFHigh_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_High; ++ } ++ else ++ { ++ rating->UHFHigh_1_RFFilterRobustness = tmTDA182I2RFFilterRobustness_Low; ++ } ++ } ++ } ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++*/ ++ ++/*============================================================================*/ ++/* tmbslTDA182I2Write */ ++/*============================================================================*/ ++ ++tmErrorCode_t ++tmbslTDA182I2Write ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uIndex, /* I: Start index to write */ ++ UInt32 WriteLen, /* I: Number of bytes to write */ ++ UInt8* pData /* I: Data to write */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // pObj initialization ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = TDA182I2MutexAcquire(pObj, TDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // Call tmddTDA182I2Write ++ ++ (void)TDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++//----------------------------------------------------------------------------- ++// Internal functions: ++//----------------------------------------------------------------------------- ++// ++ ++//----------------------------------------------------------------------------- ++// FUNCTION: TDA182I2Init: ++// ++// DESCRIPTION: initialization of the Tuner ++// ++// RETURN: always True ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++static tmErrorCode_t ++TDA182I2Init ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++) ++{ ++ ptmTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ //------------------------------ ++ // test input parameters ++ //------------------------------ ++ // pObj initialization ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "TDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ //err = tmddTDA182I2SetIRQWait(tUnit, True); ++ ++ //if(pObj->bIRQWait) ++ //{ ++ // err = TDA182I2WaitIRQ(pObj); ++ //} ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: TDA182I2Wait ++// ++// DESCRIPTION: This function waits for requested time ++// ++// RETURN: True or False ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++static tmErrorCode_t ++TDA182I2Wait ++( ++ ptmTDA182I2Object_t pObj, /* I: Driver object */ ++ UInt32 Time /* I: Time to wait for */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ ++ // wait Time ms ++ err = POBJ_SRVFUNC_STIME.Wait(pObj->tUnit, Time); ++ ++ // Return value ++ return err; ++} ++ ++/*============================================================================*/ ++/* TDA182I2MutexAcquire */ ++/*============================================================================*/ ++extern tmErrorCode_t ++TDA182I2MutexAcquire ++( ++ ptmTDA182I2Object_t pObj, ++ UInt32 timeOut ++ ) ++{ ++ tmErrorCode_t err = TM_OK; ++ ++ if(pObj->sMutex.Acquire != Null && pObj->pMutex != Null) ++ { ++ err = pObj->sMutex.Acquire(pObj->pMutex, timeOut); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* TDA182I2MutexRelease */ ++/*============================================================================*/ ++extern tmErrorCode_t ++TDA182I2MutexRelease ++( ++ ptmTDA182I2Object_t pObj ++ ) ++{ ++ tmErrorCode_t err = TM_OK; ++ ++ if(pObj->sMutex.Release != Null && pObj->pMutex != Null) ++ { ++ err = pObj->sMutex.Release(pObj->pMutex); ++ } ++ ++ return err; ++} ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2WaitXtalCal_End */ ++/* */ ++/* DESCRIPTION: Wait for MSM_XtalCal_End to trigger */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++static tmErrorCode_t ++TDA182I2WaitXtalCal_End ++( ++ ptmTDA182I2Object_t pObj, /* I: Instance object */ ++ UInt32 timeOut, /* I: timeout */ ++ UInt32 waitStep /* I: wait step */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ UInt32 counter = timeOut/waitStep; /* Wait max timeOut/waitStepms */ ++ UInt8 uMSM_XtalCal_End = 0; ++ ++ while(err == TM_OK && (--counter)>0) ++ { ++ err = tmddTDA182I2GetMSM_XtalCal_End(pObj->tUnit, &uMSM_XtalCal_End); ++ ++ if(uMSM_XtalCal_End == 1) ++ { ++ /* MSM_XtalCal_End triggered => Exit */ ++ break; ++ } ++ ++ TDA182I2Wait(pObj, waitStep); ++ } ++ ++ if(counter == 0) ++ { ++ err = ddTDA182I2_ERR_NOT_READY; ++ } ++ ++ return err; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmbslTDA182I2\src\tmbslTDA182I2Instance.c ++ ++ ++//----------------------------------------------------------------------------- ++// $Header: ++// (C) Copyright 2001 NXP Semiconductors, All rights reserved ++// ++// This source code and any compilation or derivative thereof is the sole ++// property of NXP Corporation and is provided pursuant to a Software ++// License Agreement. This code is the proprietary information of NXP ++// Corporation and is confidential in nature. Its use and dissemination by ++// any party other than NXP Corporation is strictly limited by the ++// confidential information provisions of the Agreement referenced above. ++//----------------------------------------------------------------------------- ++// FILE NAME: tmbslTDA182I2Instance.c ++// ++// DESCRIPTION: define the static Objects ++// ++// DOCUMENT REF: DVP Software Coding Guidelines v1.14 ++// DVP Board Support Library Architecture Specification v0.5 ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++ ++//#include "tmNxTypes.h" ++//#include "tmCompId.h" ++//#include "tmFrontEnd.h" ++//#include "tmUnitParams.h" ++//#include "tmbslFrontEndTypes.h" ++ ++//#ifdef TMBSL_TDA18272 ++// #include "tmbslTDA18272.h" ++//#else /* TMBSL_TDA18272 */ ++// #include "tmbslTDA18212.h" ++//#endif /* TMBSL_TDA18272 */ ++ ++//#include "tmbslTDA182I2local.h" ++//#include "tmbslTDA182I2Instance.h" ++//#include ++ ++//----------------------------------------------------------------------------- ++// Global data: ++//----------------------------------------------------------------------------- ++// ++// ++// default instance ++tmTDA182I2Object_t gTDA182I2Instance[] = ++{ ++ { ++ (tmUnitSelect_t)(-1), /* tUnit */ ++ (tmUnitSelect_t)(-1), /* tUnit temporary */ ++ Null, /* pMutex */ ++ False, /* init (instance initialization default) */ ++ { /* sRWFunc */ ++ Null, ++ Null ++ }, ++ { /* sTime */ ++ Null, ++ Null ++ }, ++ { /* sDebug */ ++ Null ++ }, ++ { /* sMutex */ ++ Null, ++ Null, ++ Null, ++ Null ++ }, ++#ifdef TMBSL_TDA18272 ++TMBSL_TDA182I2_INSTANCE_CUSTOM_MODE_PATH0 ++ { ++TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL_SELECTION_PATH0 ++TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_ANALOG_SELECTION_PATH0 ++ } ++#else ++TMBSL_TDA182I2_INSTANCE_CUSTOM_MODE_PATH0 ++ { ++TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL_SELECTION_PATH0 ++ } ++#endif ++ }, ++ { ++ (tmUnitSelect_t)(-1), /* tUnit */ ++ (tmUnitSelect_t)(-1), /* tUnit temporary */ ++ Null, /* pMutex */ ++ False, /* init (instance initialization default) */ ++ { /* sRWFunc */ ++ Null, ++ Null ++ }, ++ { /* sTime */ ++ Null, ++ Null ++ }, ++ { /* sDebug */ ++ Null ++ }, ++ { /* sMutex */ ++ Null, ++ Null, ++ Null, ++ Null ++ }, ++#ifdef TMBSL_TDA18272 ++TMBSL_TDA182I2_INSTANCE_CUSTOM_MODE_PATH1 ++ { ++TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL_SELECTION_PATH1 ++TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_ANALOG_SELECTION_PATH1 ++ } ++#else ++TMBSL_TDA182I2_INSTANCE_CUSTOM_MODE_PATH1 ++ { ++TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL_SELECTION_PATH1 ++ } ++#endif ++ } ++}; ++ ++ ++//----------------------------------------------------------------------------- ++// FUNCTION: TDA182I2AllocInstance: ++// ++// DESCRIPTION: allocate new instance ++// ++// RETURN: ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++tmErrorCode_t ++TDA182I2AllocInstance ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ pptmTDA182I2Object_t ppDrvObject /* I: Device Object */ ++) ++{ ++ tmErrorCode_t err = TDA182I2_ERR_BAD_UNIT_NUMBER; ++ ptmTDA182I2Object_t pObj = Null; ++ UInt32 uLoopCounter = 0; ++ ++ /* Find a free instance */ ++ for(uLoopCounter = 0; uLoopCounterinit == False) ++ { ++ pObj->tUnit = tUnit; ++ pObj->tUnitW = tUnit; ++ ++ // Added by Realtek. ++ // Set master bit manually according to tUnit. ++ pObj->Master = (tUnit == 0) ? True : False; ++ ++ *ppDrvObject = pObj; ++ err = TM_OK; ++ break; ++ } ++ } ++ ++ /* return value */ ++ return err; ++} ++ ++//----------------------------------------------------------------------------- ++// FUNCTION: TDA182I2DeAllocInstance: ++// ++// DESCRIPTION: deallocate instance ++// ++// RETURN: always TM_OK ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++tmErrorCode_t ++TDA182I2DeAllocInstance ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++) ++{ ++ tmErrorCode_t err = TDA182I2_ERR_BAD_UNIT_NUMBER; ++ ptmTDA182I2Object_t pObj = Null; ++ ++ /* check input parameters */ ++ err = TDA182I2GetInstance(tUnit, &pObj); ++ ++ /* check driver state */ ++ if (err == TM_OK) ++ { ++ if (pObj == Null || pObj->init == False) ++ { ++ err = TDA182I2_ERR_NOT_INITIALIZED; ++ } ++ } ++ ++ if ((err == TM_OK) && (pObj != Null)) ++ { ++ pObj->init = False; ++ } ++ ++ /* return value */ ++ return err; ++} ++ ++//----------------------------------------------------------------------------- ++// FUNCTION: TDA182I2GetInstance: ++// ++// DESCRIPTION: get the instance ++// ++// RETURN: always True ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++tmErrorCode_t ++TDA182I2GetInstance ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ pptmTDA182I2Object_t ppDrvObject /* I: Device Object */ ++) ++{ ++ tmErrorCode_t err = TDA182I2_ERR_NOT_INITIALIZED; ++ ptmTDA182I2Object_t pObj = Null; ++ UInt32 uLoopCounter = 0; ++ ++ /* get instance */ ++ for(uLoopCounter = 0; uLoopCounterinit == True && pObj->tUnit == GET_INDEX_TYPE_TUNIT(tUnit)) ++ { ++ pObj->tUnitW = tUnit; ++ ++ *ppDrvObject = pObj; ++ err = TM_OK; ++ break; ++ } ++ } ++ ++ /* return value */ ++ return err; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmddTDA182I2\src\tmddTDA182I2.c ++ ++ ++/* ++ Copyright (C) 2006-2009 NXP B.V., All Rights Reserved. ++ This source code and any compilation or derivative thereof is the proprietary ++ information of NXP B.V. and is confidential in nature. Under no circumstances ++ is this software to be exposed to or placed under an Open Source License of ++ any type without the expressed written permission of NXP B.V. ++ * ++ * \file tmddTDA182I2.c ++ * ++ * 3 ++ * ++ * \date %modify_time% ++ * ++ * \brief Describe briefly the purpose of this file. ++ * ++ * REFERENCE DOCUMENTS : ++ * TDA18254_Driver_User_Guide.pdf ++ * ++ * Detailed description may be added here. ++ * ++ * \section info Change Information ++ * ++*/ ++ ++/*============================================================================*/ ++/* Standard include files: */ ++/*============================================================================*/ ++//#include "tmNxTypes.h" ++//#include "tmCompId.h" ++//#include "tmFrontEnd.h" ++//#include "tmbslFrontEndTypes.h" ++//#include "tmUnitParams.h" ++ ++/*============================================================================*/ ++/* Project include files: */ ++/*============================================================================*/ ++//#include "tmddTDA182I2.h" ++//#include ++ ++//#include "tmddTDA182I2Instance.h" ++ ++/*============================================================================*/ ++/* Types and defines: */ ++/*============================================================================*/ ++ ++/*============================================================================*/ ++/* Global data: */ ++/*============================================================================*/ ++ ++/*============================================================================*/ ++/* Internal Prototypes: */ ++/*============================================================================*/ ++ ++/*============================================================================*/ ++/* Exported functions: */ ++/*============================================================================*/ ++ ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2Init */ ++/* */ ++/* DESCRIPTION: Create an instance of a TDA182I2 Tuner */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2Init ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmbslFrontEndDependency_t* psSrvFunc /* I: setup parameters */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if (psSrvFunc == Null) ++ { ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ } ++ ++ /* Get Instance Object */ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ } ++ ++ /* Check driver state */ ++ if (err == TM_OK || err == ddTDA182I2_ERR_NOT_INITIALIZED) ++ { ++ if (pObj != Null && pObj->init == True) ++ { ++ err = ddTDA182I2_ERR_NOT_INITIALIZED; ++ } ++ else ++ { ++ /* Allocate the Instance Object */ ++ if (pObj == Null) ++ { ++ err = ddTDA182I2AllocInstance(tUnit, &pObj); ++ if (err != TM_OK || pObj == Null) ++ { ++ err = ddTDA182I2_ERR_NOT_INITIALIZED; ++ } ++ } ++ ++ if(err == TM_OK) ++ { ++ /* initialize the Instance Object */ ++ pObj->sRWFunc = psSrvFunc->sIo; ++ pObj->sTime = psSrvFunc->sTime; ++ pObj->sDebug = psSrvFunc->sDebug; ++ ++ if( psSrvFunc->sMutex.Init != Null ++ && psSrvFunc->sMutex.DeInit != Null ++ && psSrvFunc->sMutex.Acquire != Null ++ && psSrvFunc->sMutex.Release != Null) ++ { ++ pObj->sMutex = psSrvFunc->sMutex; ++ ++ err = pObj->sMutex.Init(&pObj->pMutex); ++ } ++ ++ pObj->init = True; ++ err = TM_OK; ++ } ++ } ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2DeInit */ ++/* */ ++/* DESCRIPTION: Destroy an instance of a TDA182I2 Tuner */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2DeInit ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ ptmddTDA182I2Object_t pObj = Null; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ ++// tmDBGPRINTEx(DEBUGLVL_VERBOSE, "tmddTDA182I2DeInit(0x%08X)", tUnit); ++ ++ if(err == TM_OK) ++ { ++ if(pObj->sMutex.DeInit != Null) ++ { ++ if(pObj->pMutex != Null) ++ { ++ err = pObj->sMutex.DeInit(pObj->pMutex); ++ } ++ ++ pObj->sMutex.Init = Null; ++ pObj->sMutex.DeInit = Null; ++ pObj->sMutex.Acquire = Null; ++ pObj->sMutex.Release = Null; ++ ++ pObj->pMutex = Null; ++ } ++ } ++ ++ err = ddTDA182I2DeAllocInstance(tUnit); ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetSWVersion */ ++/* */ ++/* DESCRIPTION: Return the version of this device */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: Values defined in the tmddTDA182I2local.h file */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetSWVersion ++( ++ ptmSWVersion_t pSWVersion /* I: Receives SW Version */ ++) ++{ ++ pSWVersion->compatibilityNr = TDA182I2_DD_COMP_NUM; ++ pSWVersion->majorVersionNr = TDA182I2_DD_MAJOR_VER; ++ pSWVersion->minorVersionNr = TDA182I2_DD_MINOR_VER; ++ ++ return TM_OK; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2Reset */ ++/* */ ++/* DESCRIPTION: Initialize TDA182I2 Hardware */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2Reset ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /****** I2C map initialization : begin *********/ ++ if(err == TM_OK) ++ { ++ /* read all bytes */ ++ err = ddTDA182I2Read(pObj, 0x00, TDA182I2_I2C_MAP_NB_BYTES); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ } ++ if(err == TM_OK) ++ { ++ /* RSSI_Ck_Speed 31,25 kHz 0 */ ++ err = tmddTDA182I2SetRSSI_Ck_Speed(tUnit, 0); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetRSSI_Ck_Speed(0x%08X, 0) failed.", tUnit)); ++ } ++ if(err == TM_OK) ++ { ++ /* AGC1_Do_step 8,176 ms 2 */ ++ err = tmddTDA182I2SetAGC1_Do_step(tUnit, 2); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC1_Do_step(0x%08X, 2) failed.", tUnit)); ++ } ++ if(err == TM_OK) ++ { ++ /* AGC2_Do_step 8,176 ms 1 */ ++ err = tmddTDA182I2SetAGC2_Do_step(tUnit, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC2_Do_step(0x%08X, 1) failed.", tUnit)); ++ } ++ if(err == TM_OK) ++ { ++ /* AGCs_Up_Step_assym UP 12 Asym / 4 Asym / 5 Asym 3 */ ++ err = tmddTDA182I2SetAGCs_Up_Step_assym(tUnit, 3); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGCs_Up_Step_assym(0x%08X, 3) failed.", tUnit)); ++ } ++ if(err == TM_OK) ++ { ++ /* AGCs_Do_Step_assym DO 12 Asym / 45 Sym 2 */ ++ err = tmddTDA182I2SetAGCs_Do_Step_assym(tUnit, 2); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGCs_Do_Step_assym(0x%08X, 2) failed.", tUnit)); ++ } ++ /****** I2C map initialization : end *********/ ++ ++ /*****************************************/ ++ /* Launch tuner calibration */ ++ /* State reached after 1.5 s max */ ++ if(err == TM_OK) ++ { ++ /* set IRQ_clear */ ++ err = tmddTDA182I2SetIRQ_Clear(tUnit, 0x1F); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIRQ_clear(0x%08X, 0x1F) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* set power state on */ ++ err = tmddTDA182I2SetPowerState(tUnit, tmddTDA182I2_PowerNormalMode); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetPowerState(0x%08X, PowerNormalMode) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* set & trigger MSM */ ++ pObj->I2CMap.uBx19.MSM_byte_1 = 0x3B; ++ pObj->I2CMap.uBx1A.MSM_byte_2 = 0x01; ++ ++ /* write bytes 0x19 to 0x1A */ ++ err = ddTDA182I2Write(pObj, 0x19, 2); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ pObj->I2CMap.uBx1A.MSM_byte_2 = 0x00; ++ ++ } ++ ++ if(pObj->bIRQWait) ++ { ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2WaitIRQ(pObj, 1500, 50, 0x1F); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2WaitIRQ(0x%08X) failed.", tUnit)); ++ } ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetLPF_Gain_Mode */ ++/* */ ++/* DESCRIPTION: Free/Freeze LPF Gain */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetLPF_Gain_Mode ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uMode /* I: Unknown/Free/Frozen */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ switch(uMode) ++ { ++ case tmddTDA182I2_LPF_Gain_Unknown: ++ default: ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetLPF_Gain_Free(0x%08X, tmddTDA182I2_LPF_Gain_Unknown).", tUnit)); ++ break; ++ ++ case tmddTDA182I2_LPF_Gain_Free: ++ err = tmddTDA182I2SetAGC5_loop_off(tUnit, False); /* Disable AGC5 loop off */ ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC5_loop_off(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetForce_AGC5_gain(tUnit, False); /* Do not force AGC5 gain */ ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetForce_AGC5_gain(0x%08X) failed.", tUnit)); ++ } ++ break; ++ ++ case tmddTDA182I2_LPF_Gain_Frozen: ++ err = tmddTDA182I2SetAGC5_loop_off(tUnit, True); /* Enable AGC5 loop off */ ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC5_loop_off(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetForce_AGC5_gain(tUnit, True); /* Force AGC5 gain */ ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetForce_AGC5_gain(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2SetAGC5_Gain(tUnit, 0); /* Force gain to 0dB */ ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetAGC5_Gain(0x%08X) failed.", tUnit)); ++ } ++ break; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetLPF_Gain_Mode */ ++/* */ ++/* DESCRIPTION: Free/Freeze LPF Gain */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetLPF_Gain_Mode ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 *puMode /* I/O: Unknown/Free/Frozen */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ UInt8 AGC5_loop_off = 0; ++ UInt8 Force_AGC5_gain = 0; ++ UInt8 AGC5_Gain = 0; ++ ++ /* Test the parameter */ ++ if (puMode == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ *puMode = tmddTDA182I2_LPF_Gain_Unknown; ++ ++ err = tmddTDA182I2GetAGC5_loop_off(tUnit, &AGC5_loop_off); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetAGC5_loop_off(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2GetForce_AGC5_gain(tUnit, &Force_AGC5_gain); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetForce_AGC5_gain(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = tmddTDA182I2GetAGC5_Gain(tUnit, &AGC5_Gain); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2GetAGC5_Gain(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ if(AGC5_loop_off==False && Force_AGC5_gain==False) ++ { ++ *puMode = tmddTDA182I2_LPF_Gain_Free; ++ } ++ else if(AGC5_loop_off==True && Force_AGC5_gain==True && AGC5_Gain==0) ++ { ++ *puMode = tmddTDA182I2_LPF_Gain_Frozen; ++ } ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2Write */ ++/* */ ++/* DESCRIPTION: Write in TDA182I2 hardware */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2Write ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uIndex, /* I: Start index to write */ ++ UInt32 uNbBytes, /* I: Number of bytes to write */ ++ UInt8* puBytes /* I: Pointer on an array of bytes */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ UInt32 uCounter; ++ UInt8* pI2CMap = Null; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* pI2CMap initialization */ ++ pI2CMap = &(pObj->I2CMap.uBx00.ID_byte_1) + uIndex; ++ ++ /* Save the values written in the Tuner */ ++ for (uCounter = 0; uCounter < uNbBytes; uCounter++) ++ { ++ *pI2CMap = puBytes[uCounter]; ++ pI2CMap ++; ++ } ++ ++ /* Write in the Tuner */ ++ err = ddTDA182I2Write(pObj,(UInt8)(uIndex),(UInt8)(uNbBytes)); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2Read */ ++/* */ ++/* DESCRIPTION: Read in TDA182I2 hardware */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2Read ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uIndex, /* I: Start index to read */ ++ UInt32 uNbBytes, /* I: Number of bytes to read */ ++ UInt8* puBytes /* I: Pointer on an array of bytes */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ UInt32 uCounter = 0; ++ UInt8* pI2CMap = Null; ++ ++ /* Test the parameters */ ++ if (uNbBytes > TDA182I2_I2C_MAP_NB_BYTES) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* pI2CMap initialization */ ++ pI2CMap = &(pObj->I2CMap.uBx00.ID_byte_1) + uIndex; ++ ++ /* Read from the Tuner */ ++ err = ddTDA182I2Read(pObj,(UInt8)(uIndex),(UInt8)(uNbBytes)); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Copy read values to puBytes */ ++ for (uCounter = 0; uCounter < uNbBytes; uCounter++) ++ { ++ *puBytes = (*pI2CMap); ++ pI2CMap ++; ++ puBytes ++; ++ } ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetMS */ ++/* */ ++/* DESCRIPTION: Get the MS bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetMS ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x00 */ ++ err = ddTDA182I2Read(pObj, 0x00, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx00.bF.MS ; ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIdentity */ ++/* */ ++/* DESCRIPTION: Get the Identity bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIdentity ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt16* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x00-0x01 */ ++ err = ddTDA182I2Read(pObj, 0x00, 2); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx00.bF.Ident_1 << 8 | pObj->I2CMap.uBx01.bF.Ident_2; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetMinorRevision */ ++/* */ ++/* DESCRIPTION: Get the Revision bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetMinorRevision ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x02 */ ++ err = ddTDA182I2Read(pObj, 0x02, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx02.bF.Minor_rev; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetMajorRevision */ ++/* */ ++/* DESCRIPTION: Get the Revision bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetMajorRevision ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x02 */ ++ err = ddTDA182I2Read(pObj, 0x02, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx02.bF.Major_rev; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetLO_Lock */ ++/* */ ++/* DESCRIPTION: Get the LO_Lock bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetLO_Lock ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x05 */ ++ err = ddTDA182I2Read(pObj, 0x05, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx05.bF.LO_Lock ; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetPowerState */ ++/* */ ++/* DESCRIPTION: Set the power state of the TDA182I2 */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetPowerState ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmddTDA182I2PowerState_t powerState /* I: Power state of this device */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read bytes 0x06-0x14 */ ++ err = ddTDA182I2Read(pObj, 0x06, 15); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ /* Set digital clock mode*/ ++ if(err == TM_OK) ++ { ++ switch (powerState) ++ { ++ case tmddTDA182I2_PowerStandbyWithLNAOnAndWithXtalOnAndWithSyntheOn: ++ case tmddTDA182I2_PowerStandbyWithLNAOnAndWithXtalOn: ++ case tmddTDA182I2_PowerStandbyWithXtalOn: ++ case tmddTDA182I2_PowerStandby: ++ /* Set 16 Mhz Xtal clock */ ++ err = tmddTDA182I2SetDigital_Clock_Mode(tUnit, 0); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetDigital_Clock_Mode(0x%08X, 16 Mhz xtal clock) failed.", tUnit)); ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ /* Set power state */ ++ if(err == TM_OK) ++ { ++ switch (powerState) ++ { ++ case tmddTDA182I2_PowerNormalMode: ++ pObj->I2CMap.uBx06.bF.SM = 0x00; ++ pObj->I2CMap.uBx06.bF.SM_Synthe = 0x00; ++ pObj->I2CMap.uBx06.bF.SM_LT = 0x00; ++ pObj->I2CMap.uBx06.bF.SM_XT = 0x00; ++ break; ++ ++ case tmddTDA182I2_PowerStandbyWithLNAOnAndWithXtalOnAndWithSyntheOn: ++ pObj->I2CMap.uBx06.bF.SM = 0x01; ++ pObj->I2CMap.uBx06.bF.SM_Synthe = 0x00; ++ pObj->I2CMap.uBx06.bF.SM_LT = 0x00; ++ pObj->I2CMap.uBx06.bF.SM_XT = 0x00; ++ break; ++ ++ case tmddTDA182I2_PowerStandbyWithLNAOnAndWithXtalOn: ++ pObj->I2CMap.uBx06.bF.SM = 0x01; ++ pObj->I2CMap.uBx06.bF.SM_Synthe = 0x01; ++ pObj->I2CMap.uBx06.bF.SM_LT = 0x00; ++ pObj->I2CMap.uBx06.bF.SM_XT = 0x00; ++ break; ++ ++ case tmddTDA182I2_PowerStandbyWithXtalOn: ++ pObj->I2CMap.uBx06.bF.SM = 0x01; ++ pObj->I2CMap.uBx06.bF.SM_Synthe = 0x01; ++ pObj->I2CMap.uBx06.bF.SM_LT = 0x01; ++ pObj->I2CMap.uBx06.bF.SM_XT = 0x00; ++ break; ++ ++ case tmddTDA182I2_PowerStandby: ++ pObj->I2CMap.uBx06.bF.SM = 0x01; ++ pObj->I2CMap.uBx06.bF.SM_Synthe = 0x01; ++ pObj->I2CMap.uBx06.bF.SM_LT = 0x01; ++ pObj->I2CMap.uBx06.bF.SM_XT = 0x01; ++ break; ++ ++ default: ++ /* Power state not supported*/ ++ return ddTDA182I2_ERR_NOT_SUPPORTED; ++ } ++ ++ /* Write byte 0x06 */ ++ err = ddTDA182I2Write(pObj, 0x06, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ } ++ ++ /* Set digital clock mode*/ ++ if(err == TM_OK) ++ { ++ switch (powerState) ++ { ++ case tmddTDA182I2_PowerNormalMode: ++ /* Set sigma delta clock*/ ++ err = tmddTDA182I2SetDigital_Clock_Mode(tUnit, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetDigital_Clock_Mode(0x%08X, sigma delta clock) failed.", tUnit)); ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Store powerstate */ ++ pObj->curPowerState = powerState; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetPowerState */ ++/* */ ++/* DESCRIPTION: Get the power state of the TDA182I2 */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetPowerState ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ ptmddTDA182I2PowerState_t pPowerState /* O: Power state of this device */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Get power state */ ++ if ((pObj->I2CMap.uBx06.bF.SM == 0x00) && (pObj->I2CMap.uBx06.bF.SM_Synthe == 0x00) && (pObj->I2CMap.uBx06.bF.SM_LT == 0x00) && (pObj->I2CMap.uBx06.bF.SM_XT == 0x00)) ++ { ++ *pPowerState = tmddTDA182I2_PowerNormalMode; ++ } ++ else if ((pObj->I2CMap.uBx06.bF.SM == 0x01) && (pObj->I2CMap.uBx06.bF.SM_Synthe == 0x00) && (pObj->I2CMap.uBx06.bF.SM_LT == 0x00) && (pObj->I2CMap.uBx06.bF.SM_XT == 0x00)) ++ { ++ *pPowerState = tmddTDA182I2_PowerStandbyWithLNAOnAndWithXtalOnAndWithSyntheOn; ++ } ++ else if ((pObj->I2CMap.uBx06.bF.SM == 0x01) && (pObj->I2CMap.uBx06.bF.SM_Synthe == 0x01) && (pObj->I2CMap.uBx06.bF.SM_LT == 0x00) && (pObj->I2CMap.uBx06.bF.SM_XT == 0x00)) ++ { ++ *pPowerState = tmddTDA182I2_PowerStandbyWithLNAOnAndWithXtalOn; ++ } ++ else if ((pObj->I2CMap.uBx06.bF.SM == 0x01) && (pObj->I2CMap.uBx06.bF.SM_Synthe == 0x01) && (pObj->I2CMap.uBx06.bF.SM_LT == 0x01) && (pObj->I2CMap.uBx06.bF.SM_XT == 0x00)) ++ { ++ *pPowerState = tmddTDA182I2_PowerStandbyWithXtalOn; ++ } ++ else if ((pObj->I2CMap.uBx06.bF.SM == 0x01) && (pObj->I2CMap.uBx06.bF.SM_Synthe == 0x01) && (pObj->I2CMap.uBx06.bF.SM_LT == 0x01) && (pObj->I2CMap.uBx06.bF.SM_XT == 0x01)) ++ { ++ *pPowerState = tmddTDA182I2_PowerStandby; ++ } ++ else ++ { ++ *pPowerState = tmddTDA182I2_PowerMax; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetPower_Level */ ++/* */ ++/* DESCRIPTION: Get the Power_Level bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetPower_Level ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ UInt8 uValue = 0; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ if(err == TM_OK) ++ { ++ /* Set IRQ_clear*/ ++ err = tmddTDA182I2SetIRQ_Clear(tUnit, 0x10); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIRQ_clear(0x%08X, 0x10) failed.", tUnit)); ++ } ++ if(err == TM_OK) ++ { ++ /* Trigger RSSI_Meas */ ++ pObj->I2CMap.uBx19.MSM_byte_1 = 0x80; ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /*Trigger MSM_Launch */ ++ pObj->I2CMap.uBx1A.bF.MSM_Launch = 1; ++ ++ /* Write byte 0x1A */ ++ err = ddTDA182I2Write(pObj, 0x1A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ pObj->I2CMap.uBx1A.bF.MSM_Launch = 0; ++ if(pObj->bIRQWait) ++ { ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2WaitIRQ(pObj, 700, 1, 0x10); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2WaitIRQ(0x%08X) failed.", tUnit)); ++ } ++ } ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x07 */ ++ err = ddTDA182I2Read(pObj, 0x07, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Get value (limit range) */ ++ uValue = pObj->I2CMap.uBx07.bF.Power_Level; ++ if (uValue < TDA182I2_POWER_LEVEL_MIN) ++ { ++ *puValue = 0x00; ++ } ++ else if (uValue > TDA182I2_POWER_LEVEL_MAX) ++ { ++ *puValue = 0xFF; ++ } ++ else ++ { ++ *puValue = uValue; ++ } ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIRQ_status */ ++/* */ ++/* DESCRIPTION: Get the IRQ_status bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIRQ_status ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x08 */ ++ err = ddTDA182I2GetIRQ_status(pObj, puValue); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetIRQ_status(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetMSM_XtalCal_End */ ++/* */ ++/* DESCRIPTION: Get the MSM_XtalCal_End bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetMSM_XtalCal_End ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x08 */ ++ err = ddTDA182I2GetMSM_XtalCal_End(pObj, puValue); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIRQ_Clear */ ++/* */ ++/* DESCRIPTION: Set the IRQ_Clear bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIRQ_Clear ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 irqStatus /* I: IRQs to clear */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set IRQ_Clear */ ++ /*pObj->I2CMap.uBx0A.bF.IRQ_Clear = 1; */ ++ pObj->I2CMap.uBx0A.IRQ_clear |= (0x80|(irqStatus&0x1F)); ++ ++ /* Write byte 0x0A */ ++ err = ddTDA182I2Write(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ /* Reset IRQ_Clear (buffer only, no write) */ ++ /*pObj->I2CMap.uBx0A.bF.IRQ_Clear = 0;*/ ++ pObj->I2CMap.uBx0A.IRQ_clear &= (~(0x80|(irqStatus&0x1F))); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGC1_TOP */ ++/* */ ++/* DESCRIPTION: Set the AGC1_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGC1_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx0C.bF.AGC1_TOP = uValue; ++ ++ /* write byte 0x0C */ ++ err = ddTDA182I2Write(pObj, 0x0C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGC1_TOP */ ++/* */ ++/* DESCRIPTION: Get the AGC1_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGC1_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if ( puValue == Null ) ++ { ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ } ++ ++ /* Get Instance Object */ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x0C */ ++ err = ddTDA182I2Read(pObj, 0x0C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx0C.bF.AGC1_TOP; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGC2_TOP */ ++/* */ ++/* DESCRIPTION: Set the AGC2_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGC2_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* set value */ ++ pObj->I2CMap.uBx0D.bF.AGC2_TOP = uValue; ++ ++ /* Write byte 0x0D */ ++ err = ddTDA182I2Write(pObj, 0x0D, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGC2_TOP */ ++/* */ ++/* DESCRIPTION: Get the AGC2_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGC2_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x0D */ ++ err = ddTDA182I2Read(pObj, 0x0D, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx0D.bF.AGC2_TOP; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGCs_Up_Step */ ++/* */ ++/* DESCRIPTION: Set the AGCs_Up_Step bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGCs_Up_Step ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx0E.bF.AGCs_Up_Step = uValue; ++ ++ /* Write byte 0x0E */ ++ err = ddTDA182I2Write(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGCs_Up_Step */ ++/* */ ++/* DESCRIPTION: Get the AGCs_Up_Step bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGCs_Up_Step ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x0E */ ++ err = ddTDA182I2Read(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx0E.bF.AGCs_Up_Step; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGCK_Step */ ++/* */ ++/* DESCRIPTION: Set the AGCK_Step bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGCK_Step ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx0E.bF.AGCK_Step = uValue; ++ ++ /* Write byte 0x0E */ ++ err = ddTDA182I2Write(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGCK_Step */ ++/* */ ++/* DESCRIPTION: Get the AGCK_Step bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGCK_Step ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x0E */ ++ err = ddTDA182I2Read(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx0E.bF.AGCK_Step; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGCK_Mode */ ++/* */ ++/* DESCRIPTION: Set the AGCK_Mode bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGCK_Mode ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx0E.bF.AGCK_Mode = uValue; ++ ++ /* Write byte 0x0E */ ++ err = ddTDA182I2Write(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGCK_Mode */ ++/* */ ++/* DESCRIPTION: Get the AGCK_Mode bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGCK_Mode ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x0E */ ++ err = ddTDA182I2Read(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx0E.bF.AGCK_Mode; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetPD_RFAGC_Adapt */ ++/* */ ++/* DESCRIPTION: Set the PD_RFAGC_Adapt bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetPD_RFAGC_Adapt ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx0F.bF.PD_RFAGC_Adapt = uValue; ++ ++ /* Write byte 0x0F */ ++ err = ddTDA182I2Write(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetPD_RFAGC_Adapt */ ++/* */ ++/* DESCRIPTION: Get the PD_RFAGC_Adapt bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetPD_RFAGC_Adapt ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x0F */ ++ err = ddTDA182I2Read(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx0F.bF.PD_RFAGC_Adapt; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetRFAGC_Adapt_TOP */ ++/* */ ++/* DESCRIPTION: Set the RFAGC_Adapt_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetRFAGC_Adapt_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx0F.bF.RFAGC_Adapt_TOP = uValue; ++ ++ /* Write byte 0x0F */ ++ err = ddTDA182I2Write(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetRFAGC_Adapt_TOP */ ++/* */ ++/* DESCRIPTION: Get the RFAGC_Adapt_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetRFAGC_Adapt_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x0F */ ++ err = ddTDA182I2Read(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx0F.bF.RFAGC_Adapt_TOP; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetRF_Atten_3dB */ ++/* */ ++/* DESCRIPTION: Set the RF_Atten_3dB bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetRF_Atten_3dB ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx0F.bF.RF_Atten_3dB = uValue; ++ ++ /* Write byte 0x0F */ ++ err = ddTDA182I2Write(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetRF_Atten_3dB */ ++/* */ ++/* DESCRIPTION: Get the RF_Atten_3dB bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetRF_Atten_3dB ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x0F */ ++ err = ddTDA182I2Read(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx0F.bF.RF_Atten_3dB; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetRFAGC_Top */ ++/* */ ++/* DESCRIPTION: Set the RFAGC_Top bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetRFAGC_Top ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx0F.bF.RFAGC_Top = uValue; ++ ++ /* Write byte 0x0F */ ++ err = ddTDA182I2Write(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetRFAGC_Top */ ++/* */ ++/* DESCRIPTION: Get the RFAGC_Top bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetRFAGC_Top ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x0F */ ++ err = ddTDA182I2Read(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx0F.bF.RFAGC_Top; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIR_Mixer_Top */ ++/* */ ++/* DESCRIPTION: Set the IR_Mixer_Top bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIR_Mixer_Top ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx10.bF.IR_Mixer_Top = uValue; ++ ++ /* Write byte 0x10 */ ++ err = ddTDA182I2Write(pObj, 0x10, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIR_Mixer_Top */ ++/* */ ++/* DESCRIPTION: Get the IR_Mixer_Top bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIR_Mixer_Top ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x10 */ ++ err = ddTDA182I2Read(pObj, 0x10, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx10.bF.IR_Mixer_Top; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGC5_Ana */ ++/* */ ++/* DESCRIPTION: Set the AGC5_Ana bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGC5_Ana ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx11.bF.AGC5_Ana = uValue; ++ ++ /* Write byte 0x11 */ ++ err = ddTDA182I2Write(pObj, 0x11, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGC5_Ana */ ++/* */ ++/* DESCRIPTION: Get the AGC5_Ana bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGC5_Ana ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x11 */ ++ err = ddTDA182I2Read(pObj, 0x11, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx11.bF.AGC5_Ana; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGC5_TOP */ ++/* */ ++/* DESCRIPTION: Set the AGC5_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGC5_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx11.bF.AGC5_TOP = uValue; ++ ++ /* Write byte 0x11 */ ++ err = ddTDA182I2Write(pObj, 0x11, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGC5_TOP */ ++/* */ ++/* DESCRIPTION: Get the AGC5_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGC5_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x11 */ ++ err = ddTDA182I2Read(pObj, 0x11, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx11.bF.AGC5_TOP; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIF_Level */ ++/* */ ++/* DESCRIPTION: Set the IF_level bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIF_Level ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx12.bF.IF_level = uValue; ++ ++ /* Write byte 0x12 */ ++ err = ddTDA182I2Write(pObj, 0x12, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIF_Level */ ++/* */ ++/* DESCRIPTION: Get the IF_level bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIF_Level ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x12 */ ++ err = ddTDA182I2Read(pObj, 0x12, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx12.bF.IF_level; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIF_HP_Fc */ ++/* */ ++/* DESCRIPTION: Set the IF_HP_Fc bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIF_HP_Fc ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx13.bF.IF_HP_Fc = uValue; ++ ++ /* Write byte 0x13 */ ++ err = ddTDA182I2Write(pObj, 0x13, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIF_HP_Fc */ ++/* */ ++/* DESCRIPTION: Get the IF_HP_Fc bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIF_HP_Fc ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x13 */ ++ err = ddTDA182I2Read(pObj, 0x13, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx13.bF.IF_HP_Fc; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIF_ATSC_Notch */ ++/* */ ++/* DESCRIPTION: Set the IF_ATSC_Notch bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIF_ATSC_Notch ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx13.bF.IF_ATSC_Notch = uValue; ++ ++ /* Write byte 0x13 */ ++ err = ddTDA182I2Write(pObj, 0x13, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIF_ATSC_Notch */ ++/* */ ++/* DESCRIPTION: Get the IF_ATSC_Notch bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIF_ATSC_Notch ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x13 */ ++ err = ddTDA182I2Read(pObj, 0x13, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx13.bF.IF_ATSC_Notch; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetLP_FC_Offset */ ++/* */ ++/* DESCRIPTION: Set the LP_FC_Offset bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetLP_FC_Offset ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx13.bF.LP_FC_Offset = uValue; ++ ++ /* Write byte 0x13 */ ++ err = ddTDA182I2Write(pObj, 0x13, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetLP_FC_Offset */ ++/* */ ++/* DESCRIPTION: Get the LP_FC_Offset bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetLP_FC_Offset ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x13 */ ++ err = ddTDA182I2Read(pObj, 0x13, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx13.bF.LP_FC_Offset; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetLP_FC */ ++/* */ ++/* DESCRIPTION: Set the LP_Fc bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetLP_FC ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx13.bF.LP_Fc = uValue; ++ ++ /* Write byte 0x13 */ ++ err = ddTDA182I2Write(pObj, 0x13, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetLP_FC */ ++/* */ ++/* DESCRIPTION: Get the LP_Fc bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetLP_FC ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x13 */ ++ err = ddTDA182I2Read(pObj, 0x13, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx13.bF.LP_Fc; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetDigital_Clock_Mode */ ++/* */ ++/* DESCRIPTION: Set the Digital_Clock_Mode bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetDigital_Clock_Mode ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx14.bF.Digital_Clock_Mode = uValue; ++ ++ /* Write byte 0x14 */ ++ err = ddTDA182I2Write(pObj, 0x14, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetDigital_Clock_Mode */ ++/* */ ++/* DESCRIPTION: Get the Digital_Clock_Mode bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetDigital_Clock_Mode ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x14 */ ++ err = ddTDA182I2Read(pObj, 0x14, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx14.bF.Digital_Clock_Mode; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIF_Freq */ ++/* */ ++/* DESCRIPTION: Set the IF_Freq bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIF_Freq ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx15.bF.IF_Freq = (UInt8)(uValue / 50000); ++ ++ /* Write byte 0x15 */ ++ err = ddTDA182I2Write(pObj, 0x15, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIF_Freq */ ++/* */ ++/* DESCRIPTION: Get the IF_Freq bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIF_Freq ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x15 */ ++ err = ddTDA182I2Read(pObj, 0x15, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx15.bF.IF_Freq * 50000; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetRF_Freq */ ++/* */ ++/* DESCRIPTION: Set the RF_Freq bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetRF_Freq ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ UInt32 uRF = 0; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /*****************************************/ ++ /* Tune the settings that depend on the RF input frequency, expressed in kHz.*/ ++ /* RF filters tuning, PLL locking*/ ++ /* State reached after 5ms*/ ++ ++ if(err == TM_OK) ++ { ++ /* Set IRQ_clear */ ++ err = tmddTDA182I2SetIRQ_Clear(tUnit, 0x0C); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetIRQ_clear(0x%08X, 0x0C) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set power state ON */ ++ err = tmddTDA182I2SetPowerState(tUnit, tmddTDA182I2_PowerNormalMode); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "tmddTDA182I2SetPowerState(0x%08X, PowerNormalMode) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set RF frequency expressed in kHz */ ++ uRF = uValue / 1000; ++ pObj->I2CMap.uBx16.bF.RF_Freq_1 = (UInt8)((uRF & 0x00FF0000) >> 16); ++ pObj->I2CMap.uBx17.bF.RF_Freq_2 = (UInt8)((uRF & 0x0000FF00) >> 8); ++ pObj->I2CMap.uBx18.bF.RF_Freq_3 = (UInt8)(uRF & 0x000000FF); ++ ++ /* write bytes 0x16 to 0x18*/ ++ err = ddTDA182I2Write(pObj, 0x16, 3); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set & trigger MSM */ ++ pObj->I2CMap.uBx19.MSM_byte_1 = 0x41; ++ pObj->I2CMap.uBx1A.MSM_byte_2 = 0x01; ++ ++ /* Write bytes 0x19 to 0x1A */ ++ err = ddTDA182I2Write(pObj, 0x19, 2); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ pObj->I2CMap.uBx1A.MSM_byte_2 = 0x00; ++ } ++ if(pObj->bIRQWait) ++ { ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2WaitIRQ(pObj, 50, 5, 0x0C); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2WaitIRQ(0x%08X) failed.", tUnit)); ++ } ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetRF_Freq */ ++/* */ ++/* DESCRIPTION: Get the RF_Freq bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetRF_Freq ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read bytes 0x16 to 0x18 */ ++ err = ddTDA182I2Read(pObj, 0x16, 3); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = (pObj->I2CMap.uBx16.bF.RF_Freq_1 << 16) | (pObj->I2CMap.uBx17.bF.RF_Freq_2 << 8) | pObj->I2CMap.uBx18.bF.RF_Freq_3; ++ *puValue = *puValue * 1000; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetMSM_Launch */ ++/* */ ++/* DESCRIPTION: Set the MSM_Launch bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetMSM_Launch ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx1A.bF.MSM_Launch = 1; ++ ++ /* Write byte 0x1A */ ++ err = ddTDA182I2Write(pObj, 0x1A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ /* reset MSM_Launch (buffer only, no write) */ ++ pObj->I2CMap.uBx1A.bF.MSM_Launch = 0x00; ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetMSM_Launch */ ++/* */ ++/* DESCRIPTION: Get the MSM_Launch bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetMSM_Launch ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x1A */ ++ err = ddTDA182I2Read(pObj, 0x1A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx1A.bF.MSM_Launch; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetPSM_StoB */ ++/* */ ++/* DESCRIPTION: Set the PSM_StoB bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetPSM_StoB ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx1B.bF.PSM_StoB = uValue; ++ ++ /* Read byte 0x1B */ ++ err = ddTDA182I2Write(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetPSM_StoB */ ++/* */ ++/* DESCRIPTION: Get the PSM_StoB bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetPSM_StoB ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x1B */ ++ err = ddTDA182I2Read(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx1B.bF.PSM_StoB; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetFmax_Lo */ ++/* */ ++/* DESCRIPTION: Set the Fmax_Lo bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetFmax_Lo ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1D.bF.Fmax_Lo = uValue; ++ ++ // read byte 0x1D ++ err = ddTDA182I2Write(pObj, 0x1D, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetFmax_Lo */ ++/* */ ++/* DESCRIPTION: Get the Fmax_Lo bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetFmax_Lo ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1D ++ err = ddTDA182I2Read(pObj, 0x1D, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1D.bF.Fmax_Lo; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++ ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIR_Loop */ ++/* */ ++/* DESCRIPTION: Set the IR_Loop bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIR_Loop ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx1E.bF.IR_Loop = uValue - 4; ++ ++ /* Read byte 0x1E */ ++ err = ddTDA182I2Write(pObj, 0x1E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIR_Loop */ ++/* */ ++/* DESCRIPTION: Get the IR_Loop bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIR_Loop ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x1E */ ++ err = ddTDA182I2Read(pObj, 0x1E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx1E.bF.IR_Loop + 4; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIR_Target */ ++/* */ ++/* DESCRIPTION: Set the IR_Target bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIR_Target ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx1E.bF.IR_Target = uValue; ++ ++ /* Read byte 0x1E */ ++ err = ddTDA182I2Write(pObj, 0x1E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIR_Target */ ++/* */ ++/* DESCRIPTION: Get the IR_Target bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIR_Target ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x1E */ ++ err = ddTDA182I2Read(pObj, 0x1E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx1E.bF.IR_Target; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIR_Corr_Boost */ ++/* */ ++/* DESCRIPTION: Set the IR_Corr_Boost bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIR_Corr_Boost ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx1F.bF.IR_Corr_Boost = uValue; ++ ++ /* Read byte 0x1F */ ++ err = ddTDA182I2Write(pObj, 0x1F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIR_Corr_Boost */ ++/* */ ++/* DESCRIPTION: Get the IR_Corr_Boost bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIR_Corr_Boost ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x1F */ ++ err = ddTDA182I2Read(pObj, 0x1F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx1F.bF.IR_Corr_Boost; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIR_mode_ram_store */ ++/* */ ++/* DESCRIPTION: Set the IR_mode_ram_store bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIR_mode_ram_store ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx1F.bF.IR_mode_ram_store = uValue; ++ ++ /* Write byte 0x1F */ ++ err = ddTDA182I2Write(pObj, 0x1F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIR_mode_ram_store */ ++/* */ ++/* DESCRIPTION: Get the IR_mode_ram_store bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIR_mode_ram_store ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x1F */ ++ err = ddTDA182I2Read(pObj, 0x1F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx1F.bF.IR_mode_ram_store; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetPD_Udld */ ++/* */ ++/* DESCRIPTION: Set the PD_Udld bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetPD_Udld ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx22.bF.PD_Udld = uValue; ++ ++ /* Write byte 0x22 */ ++ err = ddTDA182I2Write(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetPD_Udld */ ++/* */ ++/* DESCRIPTION: Get the PD_Udld bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetPD_Udld ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x22 */ ++ err = ddTDA182I2Read(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx22.bF.PD_Udld; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGC_Ovld_TOP */ ++/* */ ++/* DESCRIPTION: Set the AGC_Ovld_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGC_Ovld_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx22.bF.AGC_Ovld_TOP = uValue; ++ ++ /* Write byte 0x22 */ ++ err = ddTDA182I2Write(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGC_Ovld_TOP */ ++/* */ ++/* DESCRIPTION: Get the AGC_Ovld_TOP bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGC_Ovld_TOP ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x22 */ ++ err = ddTDA182I2Read(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx22.bF.AGC_Ovld_TOP; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetHi_Pass */ ++/* */ ++/* DESCRIPTION: Set the Hi_Pass bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetHi_Pass ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx23.bF.Hi_Pass = uValue; ++ ++ /* Read byte 0x23 */ ++ err = ddTDA182I2Write(pObj, 0x23, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetHi_Pass */ ++/* */ ++/* DESCRIPTION: Get the Hi_Pass bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetHi_Pass ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x23 */ ++ err = ddTDA182I2Read(pObj, 0x23, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx23.bF.Hi_Pass; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIF_Notch */ ++/* */ ++/* DESCRIPTION: Set the IF_Notch bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIF_Notch ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx23.bF.IF_Notch = uValue; ++ ++ /* Read byte 0x23 */ ++ err = ddTDA182I2Write(pObj, 0x23, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIF_Notch */ ++/* */ ++/* DESCRIPTION: Get the IF_Notch bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIF_Notch ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x23 */ ++ err = ddTDA182I2Read(pObj, 0x23, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx23.bF.IF_Notch; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGC5_loop_off */ ++/* */ ++/* DESCRIPTION: Set the AGC5_loop_off bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGC5_loop_off ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx25.bF.AGC5_loop_off = uValue; ++ ++ /* Read byte 0x25 */ ++ err = ddTDA182I2Write(pObj, 0x25, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGC5_loop_off */ ++/* */ ++/* DESCRIPTION: Get the AGC5_loop_off bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGC5_loop_off ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x25 */ ++ err = ddTDA182I2Read(pObj, 0x25, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx25.bF.AGC5_loop_off; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGC5_Do_step */ ++/* */ ++/* DESCRIPTION: Set the AGC5_Do_step bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGC5_Do_step ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx25.bF.AGC5_Do_step = uValue; ++ ++ /* Read byte 0x25 */ ++ err = ddTDA182I2Write(pObj, 0x25, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGC5_Do_step */ ++/* */ ++/* DESCRIPTION: Get the AGC5_Do_step bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGC5_Do_step ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x25 */ ++ err = ddTDA182I2Read(pObj, 0x25, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx25.bF.AGC5_Do_step; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetForce_AGC5_gain */ ++/* */ ++/* DESCRIPTION: Set the Force_AGC5_gain bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetForce_AGC5_gain ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx25.bF.Force_AGC5_gain = uValue; ++ ++ /* Read byte 0x25 */ ++ err = ddTDA182I2Write(pObj, 0x25, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetForce_AGC5_gain */ ++/* */ ++/* DESCRIPTION: Get the Force_AGC5_gain bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetForce_AGC5_gain ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x25 */ ++ err = ddTDA182I2Read(pObj, 0x25, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx25.bF.Force_AGC5_gain; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetAGC5_Gain */ ++/* */ ++/* DESCRIPTION: Set the AGC5_Gain bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetAGC5_Gain ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx25.bF.AGC5_Gain = uValue; ++ ++ /* Read byte 0x25 */ ++ err = ddTDA182I2Write(pObj, 0x25, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetAGC5_Gain */ ++/* */ ++/* DESCRIPTION: Get the AGC5_Gain bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetAGC5_Gain ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x25 */ ++ err = ddTDA182I2Read(pObj, 0x25, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx25.bF.AGC5_Gain; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetRF_Filter_Bypass */ ++/* */ ++/* DESCRIPTION: Set the RF_Filter_Bypass bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetRF_Filter_Bypass ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx2C.bF.RF_Filter_Bypass = uValue; ++ ++ /* Read byte 0x2C */ ++ err = ddTDA182I2Write(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetRF_Filter_Bypass */ ++/* */ ++/* DESCRIPTION: Get the RF_Filter_Bypass bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetRF_Filter_Bypass ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x2C */ ++ err = ddTDA182I2Read(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx2C.bF.RF_Filter_Bypass; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetRF_Filter_Band */ ++/* */ ++/* DESCRIPTION: Set the RF_Filter_Band bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetRF_Filter_Band ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx2C.bF.RF_Filter_Band = uValue; ++ ++ /* Read byte 0x2C */ ++ err = ddTDA182I2Write(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetRF_Filter_Band */ ++/* */ ++/* DESCRIPTION: Get the RF_Filter_Band bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetRF_Filter_Band ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x2C */ ++ err = ddTDA182I2Read(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx2C.bF.RF_Filter_Band; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetRF_Filter_Cap */ ++/* */ ++/* DESCRIPTION: Set the RF_Filter_Cap bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetRF_Filter_Cap ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx2D.bF.RF_Filter_Cap = uValue; ++ ++ /* Read byte 0x2D */ ++ err = ddTDA182I2Write(pObj, 0x2D, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetRF_Filter_Cap */ ++/* */ ++/* DESCRIPTION: Get the RF_Filter_Cap bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetRF_Filter_Cap ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x2D */ ++ err = ddTDA182I2Read(pObj, 0x2D, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx2D.bF.RF_Filter_Cap; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetGain_Taper */ ++/* */ ++/* DESCRIPTION: Set the Gain_Taper bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetGain_Taper ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx2E.bF.Gain_Taper = uValue; ++ ++ /* Read byte 0x2E */ ++ err = ddTDA182I2Write(pObj, 0x2E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetGain_Taper */ ++/* */ ++/* DESCRIPTION: Get the Gain_Taper bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetGain_Taper ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if( puValue == Null ) ++ { ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ } ++ ++ /* Get Instance Object */ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x2E */ ++ err = ddTDA182I2Read(pObj, 0x2E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx2E.bF.Gain_Taper; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetN_CP_Current */ ++/* */ ++/* DESCRIPTION: Set the N_CP_Current bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetN_CP_Current ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx30.bF.N_CP_Current = uValue; ++ ++ /* Read byte 0x30 */ ++ err = ddTDA182I2Write(pObj, 0x30, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetN_CP_Current */ ++/* */ ++/* DESCRIPTION: Get the N_CP_Current bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetN_CP_Current ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x30 */ ++ err = ddTDA182I2Read(pObj, 0x30, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx30.bF.N_CP_Current; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetRSSI_Ck_Speed */ ++/* */ ++/* DESCRIPTION: Set the RSSI_Ck_Speed bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetRSSI_Ck_Speed ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx36.bF.RSSI_Ck_Speed = uValue; ++ ++ /* Write byte 0x36 */ ++ err = ddTDA182I2Write(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetRSSI_Ck_Speed */ ++/* */ ++/* DESCRIPTION: Get the RSSI_Ck_Speed bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetRSSI_Ck_Speed ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x36 */ ++ err = ddTDA182I2Read(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx36.bF.RSSI_Ck_Speed; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetRFCAL_Phi2 */ ++/* */ ++/* DESCRIPTION: Set the RFCAL_Phi2 bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Phi2 ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Set value */ ++ pObj->I2CMap.uBx37.bF.RFCAL_Phi2 = uValue; ++ ++ /* Write byte 0x37 */ ++ err = ddTDA182I2Write(pObj, 0x37, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetRFCAL_Phi2 */ ++/* */ ++/* DESCRIPTION: Get the RFCAL_Phi2 bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Phi2 ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x37 */ ++ err = ddTDA182I2Read(pObj, 0x37, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx37.bF.RFCAL_Phi2; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2WaitIRQ */ ++/* */ ++/* DESCRIPTION: Wait the IRQ to trigger */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2WaitIRQ ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 timeOut, /* I: timeout */ ++ UInt32 waitStep, /* I: wait step */ ++ UInt8 irqStatus /* I: IRQs to wait */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2WaitIRQ(pObj, timeOut, waitStep, irqStatus); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2WaitIRQ(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2WaitXtalCal_End */ ++/* */ ++/* DESCRIPTION: Wait the MSM_XtalCal_End to trigger */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2WaitXtalCal_End ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 timeOut, /* I: timeout */ ++ UInt32 waitStep /* I: wait step */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2WaitXtalCal_End(pObj, timeOut, waitStep); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2WaitXtalCal_End(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2SetIRQWait */ ++/* */ ++/* DESCRIPTION: Set whether wait IRQ in driver or not */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2SetIRQWait ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ Bool bWait /* I: Determine if we need to wait IRQ in driver functions */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ pObj->bIRQWait = bWait; ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: tmddTDA182I2GetIRQWait */ ++/* */ ++/* DESCRIPTION: Get whether wait IRQ in driver or not */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2GetIRQWait ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ Bool* pbWait /* O: Determine if we need to wait IRQ in driver functions */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (pbWait == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ *pbWait = pObj->bIRQWait; ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2GetIRQ_status */ ++/* */ ++/* DESCRIPTION: Get IRQ status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++ddTDA182I2GetIRQ_status ++( ++ ptmddTDA182I2Object_t pObj, /* I: Instance object */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ ++ /* Read byte 0x08 */ ++ err = ddTDA182I2Read(pObj, 0x08, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", pObj->tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx08.bF.IRQ_status; ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2GetMSM_XtalCal_End */ ++/* */ ++/* DESCRIPTION: Get MSM_XtalCal_End bit(s) status */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++ddTDA182I2GetMSM_XtalCal_End ++( ++ ptmddTDA182I2Object_t pObj, /* I: Instance object */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ ++ /* Test the parameters */ ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Read byte 0x08 */ ++ err = ddTDA182I2Read(pObj, 0x08, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", pObj->tUnit)); ++ ++ if(err == TM_OK) ++ { ++ /* Get value */ ++ *puValue = pObj->I2CMap.uBx08.bF.MSM_XtalCal_End; ++ } ++ } ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2WaitIRQ */ ++/* */ ++/* DESCRIPTION: Wait for IRQ to trigger */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++ddTDA182I2WaitIRQ ++( ++ ptmddTDA182I2Object_t pObj, /* I: Instance object */ ++ UInt32 timeOut, /* I: timeout */ ++ UInt32 waitStep, /* I: wait step */ ++ UInt8 irqStatus /* I: IRQs to wait */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ UInt32 counter = timeOut/waitStep; /* Wait max timeOut/waitStep ms */ ++ UInt8 uIRQ = 0; ++ UInt8 uIRQStatus = 0; ++ Bool bIRQTriggered = False; ++ ++ while(err == TM_OK && (--counter)>0) ++ { ++ err = ddTDA182I2GetIRQ_status(pObj, &uIRQ); ++ ++ if(err == TM_OK && uIRQ == 1) ++ { ++ bIRQTriggered = True; ++ } ++ ++ if(bIRQTriggered) ++ { ++ /* IRQ triggered => Exit */ ++ break; ++ } ++ ++ if(err == TM_OK && irqStatus != 0x00) ++ { ++ uIRQStatus = ((pObj->I2CMap.uBx08.IRQ_status)&0x1F); ++ ++ if(irqStatus == uIRQStatus) ++ { ++ bIRQTriggered = True; ++ } ++ } ++ ++ err = ddTDA182I2Wait(pObj, waitStep); ++ } ++ ++ if(counter == 0) ++ { ++ err = ddTDA182I2_ERR_NOT_READY; ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2WaitXtalCal_End */ ++/* */ ++/* DESCRIPTION: Wait for MSM_XtalCal_End to trigger */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++ddTDA182I2WaitXtalCal_End ++( ++ ptmddTDA182I2Object_t pObj, /* I: Instance object */ ++ UInt32 timeOut, /* I: timeout */ ++ UInt32 waitStep /* I: wait step */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ UInt32 counter = timeOut/waitStep; /* Wait max timeOut/waitStepms */ ++ UInt8 uMSM_XtalCal_End = 0; ++ ++ while(err == TM_OK && (--counter)>0) ++ { ++ err = ddTDA182I2GetMSM_XtalCal_End(pObj, &uMSM_XtalCal_End); ++ ++ if(uMSM_XtalCal_End == 1) ++ { ++ /* MSM_XtalCal_End triggered => Exit */ ++ break; ++ } ++ ++ ddTDA182I2Wait(pObj, waitStep); ++ } ++ ++ if(counter == 0) ++ { ++ err = ddTDA182I2_ERR_NOT_READY; ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2Write */ ++/* */ ++/* DESCRIPTION: Write in TDA182I2 hardware */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++ddTDA182I2Write ++( ++ ptmddTDA182I2Object_t pObj, /* I: Driver object */ ++ UInt8 uSubAddress, /* I: sub address */ ++ UInt8 uNbData /* I: nb of data */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ UInt8* pI2CMap = Null; ++ ++ /* pI2CMap initialization */ ++ pI2CMap = &(pObj->I2CMap.uBx00.ID_byte_1); ++ ++ err = POBJ_SRVFUNC_SIO.Write (pObj->tUnitW, 1, &uSubAddress, uNbData, &(pI2CMap[uSubAddress])); ++ ++ /* return value */ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2Read */ ++/* */ ++/* DESCRIPTION: Read in TDA182I2 hardware */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++ddTDA182I2Read ++( ++ ptmddTDA182I2Object_t pObj, /* I: Driver object */ ++ UInt8 uSubAddress, /* I: sub address */ ++ UInt8 uNbData /* I: nb of data */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ UInt8* pI2CMap = Null; ++ ++ /* pRegister initialization */ ++ pI2CMap = &(pObj->I2CMap.uBx00.ID_byte_1) + uSubAddress; ++ ++ /* Read data from the Tuner */ ++ err = POBJ_SRVFUNC_SIO.Read(pObj->tUnitW, 1, &uSubAddress, uNbData, pI2CMap); ++ ++ /* return value */ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2Wait */ ++/* */ ++/* DESCRIPTION: Wait for the requested time */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++ddTDA182I2Wait ++( ++ ptmddTDA182I2Object_t pObj, /* I: Driver object */ ++ UInt32 Time /* I: time to wait for */ ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ ++ /* wait Time ms */ ++ err = POBJ_SRVFUNC_STIME.Wait (pObj->tUnit, Time); ++ ++ /* Return value */ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2MutexAcquire */ ++/* */ ++/* DESCRIPTION: Acquire driver mutex */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++ddTDA182I2MutexAcquire ++( ++ ptmddTDA182I2Object_t pObj, ++ UInt32 timeOut ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ ++ if(pObj->sMutex.Acquire != Null && pObj->pMutex != Null) ++ { ++ err = pObj->sMutex.Acquire(pObj->pMutex, timeOut); ++ } ++ ++ return err; ++} ++ ++/*============================================================================*/ ++/* FUNCTION: ddTDA182I2MutexRelease */ ++/* */ ++/* DESCRIPTION: Release driver mutex */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++ddTDA182I2MutexRelease ++( ++ ptmddTDA182I2Object_t pObj ++) ++{ ++ tmErrorCode_t err = TM_OK; ++ ++ if(pObj->sMutex.Release != Null && pObj->pMutex != Null) ++ { ++ err = pObj->sMutex.Release(pObj->pMutex); ++ } ++ ++ return err; ++} ++/*============================================================================*/ ++/* FUNCTION: tmTDA182I2AGC1_change */ ++/* */ ++/* DESCRIPTION: adapt AGC1_gain from latest call ( simulate AGC1 gain free ) */ ++/* */ ++/* RETURN: TM_OK if no error */ ++/* */ ++/* NOTES: */ ++/* */ ++/*============================================================================*/ ++tmErrorCode_t ++tmddTDA182I2AGC1_Adapt ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ UInt8 counter, vAGC1min, vAGC1_max_step; ++ Int16 TotUp , TotDo ; ++ UInt8 NbStepsDone = 0; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if (pObj->I2CMap.uBx0C.bF.AGC1_6_15dB == 0) ++ { ++ vAGC1min = 0; // -12 dB ++ vAGC1_max_step = 10; // -12 +15 dB ++ } ++ else ++ { ++ vAGC1min = 6; // 6 dB ++ vAGC1_max_step = 4; // 6 -> 15 dB ++ } ++ ++ while(err == TM_OK && NbStepsDone < vAGC1_max_step) // limit to min - max steps 10 ++ { ++ counter = 0; TotUp = 0; TotDo = 0; NbStepsDone = NbStepsDone + 1; ++ while(err == TM_OK && (counter++)<40) ++ { ++ err = ddTDA182I2Read(pObj, 0x31, 1); /* read UP , DO AGC1 */ ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ TotDo = TotDo + ( pObj->I2CMap.uBx31.bF.Do_AGC1 ? 14 : -1 ); ++ TotUp = TotUp + ( pObj->I2CMap.uBx31.bF.Up_AGC1 ? 1 : -4 ); ++ err = ddTDA182I2Wait(pObj, 1); ++ } ++ if ( TotUp >= 15 && pObj->I2CMap.uBx24.bF.AGC1_Gain != 9 ) ++ { ++ pObj->I2CMap.uBx24.bF.AGC1_Gain = pObj->I2CMap.uBx24.bF.AGC1_Gain + 1; ++ err = ddTDA182I2Write(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ } ++ else if ( TotDo >= 10 && pObj->I2CMap.uBx24.bF.AGC1_Gain != vAGC1min ) ++ { ++ pObj->I2CMap.uBx24.bF.AGC1_Gain = pObj->I2CMap.uBx24.bF.AGC1_Gain - 1; ++ err = ddTDA182I2Write(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ } ++ else ++ { ++ NbStepsDone = vAGC1_max_step; ++ } ++ } ++ return err; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmddTDA182I2\src\tmddTDA182I2Instance.c ++ ++ ++/*----------------------------------------------------------------------------- ++// $Header: ++// (C) Copyright 2008 NXP Semiconductors, All rights reserved ++// ++// This source code and any compilation or derivative thereof is the sole ++// property of NXP Corporation and is provided pursuant to a Software ++// License Agreement. This code is the proprietary information of NXP ++// Corporation and is confidential in nature. Its use and dissemination by ++// any party other than NXP Corporation is strictly limited by the ++// confidential information provisions of the Agreement referenced above. ++//----------------------------------------------------------------------------- ++// FILE NAME: tmddTDA182I2Instance.c ++// ++// DESCRIPTION: define the static Objects ++// ++// DOCUMENT REF: DVP Software Coding Guidelines v1.14 ++// DVP Board Support Library Architecture Specification v0.5 ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++*/ ++ ++//#include "tmNxTypes.h" ++//#include "tmCompId.h" ++//#include "tmFrontEnd.h" ++//#include "tmUnitParams.h" ++//#include "tmbslFrontEndTypes.h" ++ ++//#include "tmddTDA182I2.h" ++//#include "tmddTDA182I2local.h" ++ ++//#include "tmddTDA182I2Instance.h" ++ ++/*----------------------------------------------------------------------------- ++// Global data: ++//----------------------------------------------------------------------------- ++// ++*/ ++ ++ ++/* default instance */ ++tmddTDA182I2Object_t gddTDA182I2Instance[] = ++{ ++ { ++ (tmUnitSelect_t)(-1), /* Unit not set */ ++ (tmUnitSelect_t)(-1), /* UnitW not set */ ++ Null, /* pMutex */ ++ False, /* init (instance initialization default) */ ++ { /* sRWFunc */ ++ Null, ++ Null ++ }, ++ { /* sTime */ ++ Null, ++ Null ++ }, ++ { /* sDebug */ ++ Null ++ }, ++ { /* sMutex */ ++ Null, ++ Null, ++ Null, ++ Null ++ }, ++ tmddTDA182I2_PowerStandbyWithXtalOn, /* curPowerState */ ++ True, /* bIRQWait */ ++ { ++ {0} // I2CMap; ++ } ++ }, ++ { ++ (tmUnitSelect_t)(-1), /* Unit not set */ ++ (tmUnitSelect_t)(-1), /* UnitW not set */ ++ Null, /* pMutex */ ++ False, /* init (instance initialization default) */ ++ { /* sRWFunc */ ++ Null, ++ Null ++ }, ++ { /* sTime */ ++ Null, ++ Null ++ }, ++ { /* sDebug */ ++ Null ++ }, ++ { /* sMutex */ ++ Null, ++ Null, ++ Null, ++ Null ++ }, ++ tmddTDA182I2_PowerStandbyWithXtalOn, /* curPowerState */ ++ True, /* bIRQWait */ ++ { ++ {0} // I2CMap; ++ } ++ } ++}; ++ ++/*----------------------------------------------------------------------------- ++// FUNCTION: ddTDA182I2AllocInstance: ++// ++// DESCRIPTION: allocate new instance ++// ++// RETURN: ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++*/ ++tmErrorCode_t ++ddTDA182I2AllocInstance ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ pptmddTDA182I2Object_t ppDrvObject /* I: Device Object */ ++ ) ++{ ++ tmErrorCode_t err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ptmddTDA182I2Object_t pObj = Null; ++ UInt32 uLoopCounter = 0; ++ ++ /* Find a free instance */ ++ for(uLoopCounter = 0; uLoopCounterinit == False) ++ { ++ pObj->tUnit = tUnit; ++ pObj->tUnitW = tUnit; ++ ++ *ppDrvObject = pObj; ++ err = TM_OK; ++ break; ++ } ++ } ++ ++ /* return value */ ++ return err; ++} ++ ++/*----------------------------------------------------------------------------- ++// FUNCTION: ddTDA182I2DeAllocInstance: ++// ++// DESCRIPTION: deallocate instance ++// ++// RETURN: always TM_OK ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++*/ ++tmErrorCode_t ++ddTDA182I2DeAllocInstance ++( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++ ) ++{ ++ tmErrorCode_t err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ptmddTDA182I2Object_t pObj = Null; ++ ++ /* check input parameters */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ ++ /* check driver state */ ++ if (err == TM_OK) ++ { ++ if (pObj == Null || pObj->init == False) ++ { ++ err = ddTDA182I2_ERR_NOT_INITIALIZED; ++ } ++ } ++ ++ if ((err == TM_OK) && (pObj != Null)) ++ { ++ pObj->init = False; ++ } ++ ++ /* return value */ ++ return err; ++} ++ ++/*----------------------------------------------------------------------------- ++// FUNCTION: ddTDA182I2GetInstance: ++// ++// DESCRIPTION: get the instance ++// ++// RETURN: always True ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++*/ ++tmErrorCode_t ++ddTDA182I2GetInstance ++( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ pptmddTDA182I2Object_t ppDrvObject /* I: Device Object */ ++ ) ++{ ++ tmErrorCode_t err = ddTDA182I2_ERR_NOT_INITIALIZED; ++ ptmddTDA182I2Object_t pObj = Null; ++ UInt32 uLoopCounter = 0; ++ ++ /* get instance */ ++ for(uLoopCounter = 0; uLoopCounterinit == True && pObj->tUnit == GET_INDEX_TYPE_TUNIT(tUnit)) ++ { ++ pObj->tUnitW = tUnit; ++ ++ *ppDrvObject = pObj; ++ err = TM_OK; ++ break; ++ } ++ } ++ ++ /* return value */ ++ return err; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmddTDA182I2\src\tmddTDA182I2_Advanced.c ++ ++ ++/*----------------------------------------------------------------------------- ++// $Header: ++// (C) Copyright 2008 NXP Semiconductors, All rights reserved ++// ++// This source code and any compilation or derivative thereof is the sole ++// property of Philips Corporation and is provided pursuant to a Software ++// License Agreement. This code is the proprietary information of Philips ++// Corporation and is confidential in nature. Its use and dissemination by ++// any party other than Philips Corporation is strictly limited by the ++// confidential information provisions of the Agreement referenced above. ++//----------------------------------------------------------------------------- ++// FILE NAME: tmddTDA182I2_Alt.c ++// ++// DESCRIPTION: TDA182I2 standard APIs ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++*/ ++ ++//#include "tmNxTypes.h" ++//#include "tmCompId.h" ++//#include "tmFrontEnd.h" ++//#include "tmbslFrontEndTypes.h" ++ ++//#include "tmddTDA182I2.h" ++//#include "tmddTDA182I2local.h" ++ ++//#include "tmddTDA182I2Instance.h" ++ ++/*----------------------------------------------------------------------------- ++// Project include files: ++//----------------------------------------------------------------------------- ++*/ ++ ++/*----------------------------------------------------------------------------- ++// Types and defines: ++//----------------------------------------------------------------------------- ++*/ ++ ++/*----------------------------------------------------------------------------- ++// Global data: ++//----------------------------------------------------------------------------- ++*/ ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetTM_D: ++// ++// DESCRIPTION: Get the TM_D bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetTM_D ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // switch thermometer on ++ pObj->I2CMap.uBx04.bF.TM_ON = 1; ++ ++ // write byte 0x04 ++ err = ddTDA182I2Write(pObj, 0x04, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x03 ++ err = ddTDA182I2Read(pObj, 0x03, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx03.bF.TM_D; ++ ++ // switch thermometer off ++ pObj->I2CMap.uBx04.bF.TM_ON = 0; ++ ++ // write byte 0x04 ++ err = ddTDA182I2Write(pObj, 0x04, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetTM_ON: ++// ++// DESCRIPTION: Set the TM_ON bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetTM_ON ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx04.bF.TM_ON = uValue; ++ ++ // write byte 0x04 ++ err = ddTDA182I2Write(pObj, 0x04, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetTM_ON: ++// ++// DESCRIPTION: Get the TM_ON bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetTM_ON ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x04 ++ err = ddTDA182I2Read(pObj, 0x04, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx04.bF.TM_ON; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetPOR: ++// ++// DESCRIPTION: Get the POR bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetPOR ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x05 ++ err = ddTDA182I2Read(pObj, 0x05, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx05.bF.POR ; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RSSI_End: ++// ++// DESCRIPTION: Get the MSM_RSSI_End bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RSSI_End ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x08 ++ err = ddTDA182I2Read(pObj, 0x08, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx08.bF.MSM_RSSI_End; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_LOCalc_End: ++// ++// DESCRIPTION: Get the MSM_LOCalc_End bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_LOCalc_End ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x08 ++ err = ddTDA182I2Read(pObj, 0x08, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx08.bF.MSM_LOCalc_End; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RFCal_End: ++// ++// DESCRIPTION: Get the MSM_RFCal_End bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RFCal_End ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x08 ++ err = ddTDA182I2Read(pObj, 0x08, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx08.bF.MSM_RFCal_End; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_IRCAL_End: ++// ++// DESCRIPTION: Get the MSM_IRCAL_End bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_IRCAL_End ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x08 ++ err = ddTDA182I2Read(pObj, 0x08, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx08.bF.MSM_IRCAL_End; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RCCal_End: ++// ++// DESCRIPTION: Get the MSM_RCCal_End bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RCCal_End ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x08 ++ err = ddTDA182I2Read(pObj, 0x08, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx08.bF.MSM_RCCal_End; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIRQ_Enable: ++// ++// DESCRIPTION: Set the IRQ_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIRQ_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx09.bF.IRQ_Enable = uValue; ++ ++ // write byte 0x09 ++ err = ddTDA182I2Write(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIRQ_Enable: ++// ++// DESCRIPTION: Get the IRQ_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIRQ_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x09 ++ err = ddTDA182I2Read(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx09.bF.IRQ_Enable; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetXtalCal_Enable: ++// ++// DESCRIPTION: Set the XtalCal_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetXtalCal_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx09.bF.XtalCal_Enable = uValue; ++ ++ // write byte 0x09 ++ err = ddTDA182I2Write(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetXtalCal_Enable: ++// ++// DESCRIPTION: Get the XtalCal_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetXtalCal_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x09 ++ err = ddTDA182I2Read(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx09.bF.XtalCal_Enable; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_RSSI_Enable: ++// ++// DESCRIPTION: Set the MSM_RSSI_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_RSSI_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx09.bF.MSM_RSSI_Enable = uValue; ++ ++ // write byte 0x09 ++ err = ddTDA182I2Write(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RSSI_Enable: ++// ++// DESCRIPTION: Get the MSM_RSSI_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RSSI_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x09 ++ err = ddTDA182I2Read(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx09.bF.MSM_RSSI_Enable; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_LOCalc_Enable: ++// ++// DESCRIPTION: Set the MSM_LOCalc_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_LOCalc_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx09.bF.MSM_LOCalc_Enable = uValue; ++ ++ // write byte 0x09 ++ err = ddTDA182I2Write(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_LOCalc_Enable: ++// ++// DESCRIPTION: Get the MSM_LOCalc_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_LOCalc_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x09 ++ err = ddTDA182I2Read(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx09.bF.MSM_LOCalc_Enable; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_RFCAL_Enable: ++// ++// DESCRIPTION: Set the MSM_RFCAL_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_RFCAL_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx09.bF.MSM_RFCAL_Enable = uValue; ++ ++ // write byte 0x09 ++ err = ddTDA182I2Write(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RFCAL_Enable: ++// ++// DESCRIPTION: Get the MSM_RFCAL_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RFCAL_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x09 ++ err = ddTDA182I2Read(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx09.bF.MSM_RFCAL_Enable; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_IRCAL_Enable: ++// ++// DESCRIPTION: Set the MSM_IRCAL_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_IRCAL_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx09.bF.MSM_IRCAL_Enable = uValue; ++ ++ // write byte 0x09 ++ err = ddTDA182I2Write(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_IRCAL_Enable: ++// ++// DESCRIPTION: Get the MSM_IRCAL_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_IRCAL_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x09 ++ err = ddTDA182I2Read(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx09.bF.MSM_IRCAL_Enable; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_RCCal_Enable: ++// ++// DESCRIPTION: Set the MSM_RCCal_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_RCCal_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx09.bF.MSM_RCCal_Enable = uValue; ++ ++ // write byte 0x09 ++ err = ddTDA182I2Write(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RCCal_Enable: ++// ++// DESCRIPTION: Get the MSM_RCCal_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RCCal_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x09 ++ err = ddTDA182I2Read(pObj, 0x09, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx09.bF.MSM_RCCal_Enable; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetXtalCal_Clear: ++// ++// DESCRIPTION: Set the XtalCal_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetXtalCal_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0A.bF.XtalCal_Clear = uValue; ++ ++ // write byte 0x0A ++ err = ddTDA182I2Write(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetXtalCal_Clear: ++// ++// DESCRIPTION: Get the XtalCal_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetXtalCal_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0A ++ err = ddTDA182I2Read(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0A.bF.XtalCal_Clear; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_RSSI_Clear: ++// ++// DESCRIPTION: Set the MSM_RSSI_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_RSSI_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0A.bF.MSM_RSSI_Clear = uValue; ++ ++ // write byte 0x0A ++ err = ddTDA182I2Write(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RSSI_Clear: ++// ++// DESCRIPTION: Get the MSM_RSSI_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RSSI_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0A ++ err = ddTDA182I2Read(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0A.bF.MSM_RSSI_Clear; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_LOCalc_Clear: ++// ++// DESCRIPTION: Set the MSM_LOCalc_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_LOCalc_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0A.bF.MSM_LOCalc_Clear = uValue; ++ ++ // write byte 0x0A ++ err = ddTDA182I2Write(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_LOCalc_Clear: ++// ++// DESCRIPTION: Get the MSM_LOCalc_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_LOCalc_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0A ++ err = ddTDA182I2Read(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0A.bF.MSM_LOCalc_Clear; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_RFCal_Clear: ++// ++// DESCRIPTION: Set the MSM_RFCal_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_RFCal_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0A.bF.MSM_RFCal_Clear = uValue; ++ ++ // write byte 0x0A ++ err = ddTDA182I2Write(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RFCal_Clear: ++// ++// DESCRIPTION: Get the MSM_RFCal_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RFCal_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0A ++ err = ddTDA182I2Read(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0A.bF.MSM_RFCal_Clear; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_IRCAL_Clear: ++// ++// DESCRIPTION: Set the MSM_IRCAL_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_IRCAL_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0A.bF.MSM_IRCAL_Clear = uValue; ++ ++ // write byte 0x0A ++ err = ddTDA182I2Write(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_IRCAL_Clear: ++// ++// DESCRIPTION: Get the MSM_IRCAL_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_IRCAL_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0A ++ err = ddTDA182I2Read(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0A.bF.MSM_IRCAL_Clear; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_RCCal_Clear: ++// ++// DESCRIPTION: Set the MSM_RCCal_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_RCCal_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0A.bF.MSM_RCCal_Clear = uValue; ++ ++ // write byte 0x0A ++ err = ddTDA182I2Write(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RCCal_Clear: ++// ++// DESCRIPTION: Get the MSM_RCCal_Clear bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RCCal_Clear ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0A ++ err = ddTDA182I2Read(pObj, 0x0A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0A.bF.MSM_RCCal_Clear; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIRQ_Set: ++// ++// DESCRIPTION: Set the IRQ_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIRQ_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0B.bF.IRQ_Set = uValue; ++ ++ // write byte 0x0B ++ err = ddTDA182I2Write(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIRQ_Set: ++// ++// DESCRIPTION: Get the IRQ_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIRQ_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0B ++ err = ddTDA182I2Read(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0B.bF.IRQ_Set; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetXtalCal_Set: ++// ++// DESCRIPTION: Set the XtalCal_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetXtalCal_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0B.bF.XtalCal_Set = uValue; ++ ++ // write byte 0x0B ++ err = ddTDA182I2Write(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetXtalCal_Set: ++// ++// DESCRIPTION: Get the XtalCal_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetXtalCal_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0B ++ err = ddTDA182I2Read(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0B.bF.XtalCal_Set; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_RSSI_Set: ++// ++// DESCRIPTION: Set the MSM_RSSI_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_RSSI_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0B.bF.MSM_RSSI_Set = uValue; ++ ++ // write byte 0x0B ++ err = ddTDA182I2Write(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RSSI_Set: ++// ++// DESCRIPTION: Get the MSM_RSSI_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RSSI_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0B ++ err = ddTDA182I2Read(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0B.bF.MSM_RSSI_Set; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_LOCalc_Set: ++// ++// DESCRIPTION: Set the MSM_LOCalc_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_LOCalc_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0B.bF.MSM_LOCalc_Set = uValue; ++ ++ // write byte 0x0B ++ err = ddTDA182I2Write(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_LOCalc_Set: ++// ++// DESCRIPTION: Get the MSM_LOCalc_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_LOCalc_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0B ++ err = ddTDA182I2Read(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ // get value ++ *puValue = pObj->I2CMap.uBx0B.bF.MSM_LOCalc_Set; ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_RFCal_Set: ++// ++// DESCRIPTION: Set the MSM_RFCal_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_RFCal_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0B.bF.MSM_RFCal_Set = uValue; ++ ++ // write byte 0x0B ++ err = ddTDA182I2Write(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RFCal_Set: ++// ++// DESCRIPTION: Get the MSM_RFCal_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RFCal_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0B ++ err = ddTDA182I2Read(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0B.bF.MSM_RFCal_Set; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_IRCAL_Set: ++// ++// DESCRIPTION: Set the MSM_IRCAL_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_IRCAL_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0B.bF.MSM_IRCAL_Set = uValue; ++ ++ // write byte 0x0B ++ err = ddTDA182I2Write(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_IRCAL_Set: ++// ++// DESCRIPTION: Get the MSM_IRCAL_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_IRCAL_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0B ++ err = ddTDA182I2Read(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0B.bF.MSM_IRCAL_Set; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetMSM_RCCal_Set: ++// ++// DESCRIPTION: Set the MSM_RCCal_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetMSM_RCCal_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0B.bF.MSM_RCCal_Set = uValue; ++ ++ // write byte 0x0B ++ err = ddTDA182I2Write(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetMSM_RCCal_Set: ++// ++// DESCRIPTION: Get the MSM_RCCal_Set bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetMSM_RCCal_Set ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0B ++ err = ddTDA182I2Read(pObj, 0x0B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0B.bF.MSM_RCCal_Set; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetLT_Enable: ++// ++// DESCRIPTION: Set the LT_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetLT_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0C.bF.LT_Enable = uValue; ++ ++ // write byte 0x0C ++ err = ddTDA182I2Write(pObj, 0x0C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetLT_Enable: ++// ++// DESCRIPTION: Get the LT_Enable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetLT_Enable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0C ++ err = ddTDA182I2Read(pObj, 0x0C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0C.bF.LT_Enable; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetAGC1_6_15dB: ++// ++// DESCRIPTION: Set the AGC1_6_15dB bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetAGC1_6_15dB ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0C.bF.AGC1_6_15dB = uValue; ++ ++ // write byte 0x0C ++ err = ddTDA182I2Write(pObj, 0x0C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC1_6_15dB: ++// ++// DESCRIPTION: Get the AGC1_6_15dB bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC1_6_15dB ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0C ++ err = ddTDA182I2Read(pObj, 0x0C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0C.bF.AGC1_6_15dB; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetAGCs_Up_Step_assym: ++// ++// DESCRIPTION: Set the AGCs_Up_Step_assym bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetAGCs_Up_Step_assym ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0E.bF.AGCs_Up_Step_assym = uValue; ++ ++ // write byte 0x0E ++ err = ddTDA182I2Write(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGCs_Up_Step_assym: ++// ++// DESCRIPTION: Get the AGCs_Up_Step_assym bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGCs_Up_Step_assym ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0E ++ err = ddTDA182I2Read(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0E.bF.AGCs_Up_Step_assym; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetPulse_Shaper_Disable: ++// ++// DESCRIPTION: Set the Pulse_Shaper_Disable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetPulse_Shaper_Disable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0E.bF.Pulse_Shaper_Disable = uValue; ++ ++ // write byte 0x0E ++ err = ddTDA182I2Write(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetPulse_Shaper_Disable: ++// ++// DESCRIPTION: Get the Pulse_Shaper_Disable bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetPulse_Shaper_Disable ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0E ++ err = ddTDA182I2Read(pObj, 0x0E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0E.bF.Pulse_Shaper_Disable; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFAGC_Low_BW: ++// ++// DESCRIPTION: Set the RFAGC_Low_BW bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFAGC_Low_BW ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx0F.bF.RFAGC_Low_BW = uValue; ++ ++ // write byte 0x0F ++ err = ddTDA182I2Write(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFAGC_Low_BW: ++// ++// DESCRIPTION: Get the RFAGC_Low_BW bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFAGC_Low_BW ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x0F ++ err = ddTDA182I2Read(pObj, 0x0F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx0F.bF.RFAGC_Low_BW; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetAGCs_Do_Step_assym: ++// ++// DESCRIPTION: Set the AGCs_Do_Step_assym bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetAGCs_Do_Step_assym ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx11.bF.AGCs_Do_Step_assym = uValue; ++ ++ // write byte 0x11 ++ err = ddTDA182I2Write(pObj, 0x11, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGCs_Do_Step_assym: ++// ++// DESCRIPTION: Get the AGCs_Do_Step_assym bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGCs_Do_Step_assym ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x11 ++ err = ddTDA182I2Read(pObj, 0x11, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx11.bF.AGCs_Do_Step_assym; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetI2C_Clock_Mode: ++// ++// DESCRIPTION: Set the I2C_Clock_Mode bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetI2C_Clock_Mode ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx14.bF.I2C_Clock_Mode = uValue; ++ ++ // write byte 0x14 ++ err = ddTDA182I2Write(pObj, 0x14, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetI2C_Clock_Mode: ++// ++// DESCRIPTION: Get the I2C_Clock_Mode bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetI2C_Clock_Mode ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x14 ++ err = ddTDA182I2Read(pObj, 0x14, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx14.bF.I2C_Clock_Mode; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetXtalOsc_AnaReg_En: ++// ++// DESCRIPTION: Set the XtalOsc_AnaReg_En bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetXtalOsc_AnaReg_En ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx14.bF.XtalOsc_AnaReg_En = uValue; ++ ++ // write byte 0x14 ++ err = ddTDA182I2Write(pObj, 0x14, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetXtalOsc_AnaReg_En: ++// ++// DESCRIPTION: Get the XtalOsc_AnaReg_En bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetXtalOsc_AnaReg_En ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x14 ++ err = ddTDA182I2Read(pObj, 0x14, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx14.bF.XtalOsc_AnaReg_En; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetXTout: ++// ++// DESCRIPTION: Set the XTout bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetXTout ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx14.bF.XTout = uValue; ++ ++ // write byte 0x14 ++ err = ddTDA182I2Write(pObj, 0x14, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetXTout: ++// ++// DESCRIPTION: Get the XTout bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetXTout ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x14 ++ err = ddTDA182I2Read(pObj, 0x14, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx14.bF.XTout; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRSSI_Meas: ++// ++// DESCRIPTION: Set the RSSI_Meas bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRSSI_Meas ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx19.bF.RSSI_Meas = uValue; ++ ++ // read byte 0x19 ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRSSI_Meas: ++// ++// DESCRIPTION: Get the RSSI_Meas bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRSSI_Meas ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x19 ++ err = ddTDA182I2Read(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx19.bF.RSSI_Meas; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRF_CAL_AV: ++// ++// DESCRIPTION: Set the RF_CAL_AV bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRF_CAL_AV ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx19.bF.RF_CAL_AV = uValue; ++ ++ // read byte 0x19 ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRF_CAL_AV: ++// ++// DESCRIPTION: Get the RF_CAL_AV bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRF_CAL_AV ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x19 ++ err = ddTDA182I2Read(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx19.bF.RF_CAL_AV; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRF_CAL: ++// ++// DESCRIPTION: Set the RF_CAL bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRF_CAL ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx19.bF.RF_CAL = uValue; ++ ++ // read byte 0x19 ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRF_CAL: ++// ++// DESCRIPTION: Get the RF_CAL bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRF_CAL ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x19 ++ err = ddTDA182I2Read(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx19.bF.RF_CAL; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_CAL_Loop: ++// ++// DESCRIPTION: Set the IR_CAL_Loop bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_CAL_Loop ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx19.bF.IR_CAL_Loop = uValue; ++ ++ // read byte 0x19 ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_CAL_Loop: ++// ++// DESCRIPTION: Get the IR_CAL_Loop bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_CAL_Loop ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x19 ++ err = ddTDA182I2Read(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx19.bF.IR_CAL_Loop; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_Cal_Image: ++// ++// DESCRIPTION: Set the IR_Cal_Image bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_Cal_Image ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx19.bF.IR_Cal_Image = uValue; ++ ++ // read byte 0x19 ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_Cal_Image: ++// ++// DESCRIPTION: Get the IR_Cal_Image bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_Cal_Image ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x19 ++ err = ddTDA182I2Read(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx19.bF.IR_Cal_Image; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_CAL_Wanted: ++// ++// DESCRIPTION: Set the IR_CAL_Wanted bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_CAL_Wanted ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx19.bF.IR_CAL_Wanted = uValue; ++ ++ // read byte 0x19 ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_CAL_Wanted: ++// ++// DESCRIPTION: Get the IR_CAL_Wanted bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_CAL_Wanted ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x19 ++ err = ddTDA182I2Read(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx19.bF.IR_CAL_Wanted; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRC_Cal: ++// ++// DESCRIPTION: Set the RC_Cal bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRC_Cal ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx19.bF.RC_Cal = uValue; ++ ++ // read byte 0x19 ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRC_Cal: ++// ++// DESCRIPTION: Get the RC_Cal bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRC_Cal ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x19 ++ err = ddTDA182I2Read(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx19.bF.RC_Cal; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetCalc_PLL: ++// ++// DESCRIPTION: Set the Calc_PLL bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetCalc_PLL ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx19.bF.Calc_PLL = uValue; ++ ++ // read byte 0x19 ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetCalc_PLL: ++// ++// DESCRIPTION: Get the Calc_PLL bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetCalc_PLL ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x19 ++ err = ddTDA182I2Read(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx19.bF.Calc_PLL; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetXtalCal_Launch: ++// ++// DESCRIPTION: Set the XtalCal_Launch bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetXtalCal_Launch ++( ++ tmUnitSelect_t tUnit // I: Unit number ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1A.bF.XtalCal_Launch = 1; ++ ++ // write byte 0x1A ++ err = ddTDA182I2Write(pObj, 0x1A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ // reset XtalCal_Launch (buffer only, no write) ++ pObj->I2CMap.uBx1A.bF.XtalCal_Launch = 0; ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetXtalCal_Launch: ++// ++// DESCRIPTION: Get the XtalCal_Launch bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetXtalCal_Launch ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1A ++ err = ddTDA182I2Read(pObj, 0x1A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1A.bF.XtalCal_Launch; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetPSM_AGC1: ++// ++// DESCRIPTION: Set the PSM_AGC1 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetPSM_AGC1 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1B.bF.PSM_AGC1 = uValue; ++ ++ // read byte 0x1B ++ err = ddTDA182I2Write(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetPSM_AGC1: ++// ++// DESCRIPTION: Get the PSM_AGC1 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetPSM_AGC1 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1B ++ err = ddTDA182I2Read(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1B.bF.PSM_AGC1; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetPSMRFpoly: ++// ++// DESCRIPTION: Set the PSMRFpoly bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetPSMRFpoly ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1B.bF.PSMRFpoly = uValue; ++ ++ // read byte 0x1B ++ err = ddTDA182I2Write(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetPSMRFpoly: ++// ++// DESCRIPTION: Get the PSMRFpoly bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetPSMRFpoly ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1B ++ err = ddTDA182I2Read(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ // get value ++ *puValue = pObj->I2CMap.uBx1B.bF.PSMRFpoly; ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetPSM_Mixer: ++// ++// DESCRIPTION: Set the PSM_Mixer bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetPSM_Mixer ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1B.bF.PSM_Mixer = uValue; ++ ++ // read byte 0x1B ++ err = ddTDA182I2Write(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetPSM_Mixer: ++// ++// DESCRIPTION: Get the PSM_Mixer bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetPSM_Mixer ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1B ++ err = ddTDA182I2Read(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1B.bF.PSM_Mixer; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetPSM_Ifpoly: ++// ++// DESCRIPTION: Set the PSM_Ifpoly bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetPSM_Ifpoly ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1B.bF.PSM_Ifpoly = uValue; ++ ++ // read byte 0x1B ++ err = ddTDA182I2Write(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetPSM_Ifpoly: ++// ++// DESCRIPTION: Get the PSM_Ifpoly bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetPSM_Ifpoly ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1B ++ err = ddTDA182I2Read(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1B.bF.PSM_Ifpoly; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetPSM_Lodriver: ++// ++// DESCRIPTION: Set the PSM_Lodriver bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetPSM_Lodriver ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1B.bF.PSM_Lodriver = uValue; ++ ++ // read byte 0x1B ++ err = ddTDA182I2Write(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetPSM_Lodriver: ++// ++// DESCRIPTION: Get the PSM_Lodriver bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetPSM_Lodriver ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1B ++ err = ddTDA182I2Read(pObj, 0x1B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1B.bF.PSM_Lodriver; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetDCC_Bypass: ++// ++// DESCRIPTION: Set the DCC_Bypass bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetDCC_Bypass ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1C.bF.DCC_Bypass = uValue; ++ ++ // read byte 0x1C ++ err = ddTDA182I2Write(pObj, 0x1C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetDCC_Bypass: ++// ++// DESCRIPTION: Get the DCC_Bypass bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetDCC_Bypass ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1C ++ err = ddTDA182I2Read(pObj, 0x1C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1C.bF.DCC_Bypass; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetDCC_Slow: ++// ++// DESCRIPTION: Set the DCC_Slow bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetDCC_Slow ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1C.bF.DCC_Slow = uValue; ++ ++ // read byte 0x1C ++ err = ddTDA182I2Write(pObj, 0x1C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetDCC_Slow: ++// ++// DESCRIPTION: Get the DCC_Slow bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetDCC_Slow ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1C ++ err = ddTDA182I2Read(pObj, 0x1C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1C.bF.DCC_Slow; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetDCC_psm: ++// ++// DESCRIPTION: Set the DCC_psm bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetDCC_psm ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1C.bF.DCC_psm = uValue; ++ ++ // read byte 0x1C ++ err = ddTDA182I2Write(pObj, 0x1C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetDCC_psm: ++// ++// DESCRIPTION: Get the DCC_psm bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetDCC_psm ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1C ++ err = ddTDA182I2Read(pObj, 0x1C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1C.bF.DCC_psm; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_GStep: ++// ++// DESCRIPTION: Set the IR_GStep bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_GStep ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1E.bF.IR_GStep = uValue - 40; ++ ++ // read byte 0x1E ++ err = ddTDA182I2Write(pObj, 0x1E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_GStep: ++// ++// DESCRIPTION: Get the IR_GStep bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_GStep ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1E ++ err = ddTDA182I2Read(pObj, 0x1E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1E.bF.IR_GStep + 40; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_FreqLow_Sel: ++// ++// DESCRIPTION: Set the IR_FreqLow_Sel bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_FreqLow_Sel ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1F.bF.IR_FreqLow_Sel = uValue; ++ ++ // read byte 0x1F ++ err = ddTDA182I2Write(pObj, 0x1F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_FreqLow_Sel: ++// ++// DESCRIPTION: Get the IR_FreqLow_Sel bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_FreqLow_Sel ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1F ++ err = ddTDA182I2Read(pObj, 0x1F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1F.bF.IR_FreqLow_Sel; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_FreqLow: ++// ++// DESCRIPTION: Set the IR_FreqLow bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_FreqLow ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx1F.bF.IR_FreqLow = uValue; ++ ++ // read byte 0x1F ++ err = ddTDA182I2Write(pObj, 0x1F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_FreqLow: ++// ++// DESCRIPTION: Get the IR_FreqLow bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_FreqLow ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x1F ++ err = ddTDA182I2Read(pObj, 0x1F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx1F.bF.IR_FreqLow; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_FreqMid: ++// ++// DESCRIPTION: Set the IR_FreqMid bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_FreqMid ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx20.bF.IR_FreqMid = uValue; ++ ++ // read byte 0x20 ++ err = ddTDA182I2Write(pObj, 0x20, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_FreqMid: ++// ++// DESCRIPTION: Get the IR_FreqMid bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_FreqMid ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x20 ++ err = ddTDA182I2Read(pObj, 0x20, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx20.bF.IR_FreqMid; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetCoarse_IR_FreqHigh: ++// ++// DESCRIPTION: Set the Coarse_IR_FreqHigh bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetCoarse_IR_FreqHigh ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx21.bF.Coarse_IR_FreqHigh = uValue; ++ ++ // write byte 0x21 ++ err = ddTDA182I2Write(pObj, 0x21, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetCoarse_IR_FreqHigh: ++// ++// DESCRIPTION: Get the Coarse_IR_FreqHigh bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetCoarse_IR_FreqHigh ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x21 ++ err = ddTDA182I2Read(pObj, 0x21, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx21.bF.Coarse_IR_FreqHigh; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_FreqHigh: ++// ++// DESCRIPTION: Set the IR_FreqHigh bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_FreqHigh ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx21.bF.IR_FreqHigh = uValue; ++ ++ // read byte 0x21 ++ err = ddTDA182I2Write(pObj, 0x21, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_FreqHigh: ++// ++// DESCRIPTION: Get the IR_FreqHigh bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_FreqHigh ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x21 ++ err = ddTDA182I2Read(pObj, 0x21, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx21.bF.IR_FreqHigh; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetPD_Vsync_Mgt: ++// ++// DESCRIPTION: Set the PD_Vsync_Mgt bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetPD_Vsync_Mgt ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx22.bF.PD_Vsync_Mgt = uValue; ++ ++ // write byte 0x22 ++ err = ddTDA182I2Write(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetPD_Vsync_Mgt: ++// ++// DESCRIPTION: Get the PD_Vsync_Mgt bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetPD_Vsync_Mgt ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x22 ++ err = ddTDA182I2Read(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx22.bF.PD_Vsync_Mgt; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetPD_Ovld: ++// ++// DESCRIPTION: Set the PD_Ovld bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetPD_Ovld ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx22.bF.PD_Ovld = uValue; ++ ++ // write byte 0x22 ++ err = ddTDA182I2Write(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetPD_Ovld: ++// ++// DESCRIPTION: Get the PD_Ovld bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetPD_Ovld ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x22 ++ err = ddTDA182I2Read(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx22.bF.PD_Ovld; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetAGC_Ovld_Timer: ++// ++// DESCRIPTION: Set the AGC_Ovld_Timer bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetAGC_Ovld_Timer ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx22.bF.AGC_Ovld_Timer = uValue; ++ ++ // write byte 0x22 ++ err = ddTDA182I2Write(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC_Ovld_Timer: ++// ++// DESCRIPTION: Get the AGC_Ovld_Timer bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC_Ovld_Timer ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x22 ++ err = ddTDA182I2Read(pObj, 0x22, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx22.bF.AGC_Ovld_Timer; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_Mixer_loop_off: ++// ++// DESCRIPTION: Set the IR_Mixer_loop_off bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_Mixer_loop_off ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx23.bF.IR_Mixer_loop_off = uValue; ++ ++ // read byte 0x23 ++ err = ddTDA182I2Write(pObj, 0x23, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_Mixer_loop_off: ++// ++// DESCRIPTION: Get the IR_Mixer_loop_off bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_Mixer_loop_off ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x23 ++ err = ddTDA182I2Read(pObj, 0x23, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx23.bF.IR_Mixer_loop_off; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIR_Mixer_Do_step: ++// ++// DESCRIPTION: Set the IR_Mixer_Do_step bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIR_Mixer_Do_step ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx23.bF.IR_Mixer_Do_step = uValue; ++ ++ // read byte 0x23 ++ err = ddTDA182I2Write(pObj, 0x23, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIR_Mixer_Do_step: ++// ++// DESCRIPTION: Get the IR_Mixer_Do_step bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIR_Mixer_Do_step ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x23 ++ err = ddTDA182I2Read(pObj, 0x23, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx23.bF.IR_Mixer_Do_step; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetAGC1_loop_off: ++// ++// DESCRIPTION: Set the AGC1_loop_off bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetAGC1_loop_off ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx24.bF.AGC1_loop_off = uValue; ++ ++ // read byte 0x24 ++ err = ddTDA182I2Write(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC1_loop_off: ++// ++// DESCRIPTION: Get the AGC1_loop_off bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC1_loop_off ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x24 ++ err = ddTDA182I2Read(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx24.bF.AGC1_loop_off; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetAGC1_Do_step: ++// ++// DESCRIPTION: Set the AGC1_Do_step bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetAGC1_Do_step ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx24.bF.AGC1_Do_step = uValue; ++ ++ // read byte 0x24 ++ err = ddTDA182I2Write(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC1_Do_step: ++// ++// DESCRIPTION: Get the AGC1_Do_step bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC1_Do_step ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x24 ++ err = ddTDA182I2Read(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx24.bF.AGC1_Do_step; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetForce_AGC1_gain: ++// ++// DESCRIPTION: Set the Force_AGC1_gain bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetForce_AGC1_gain ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx24.bF.Force_AGC1_gain = uValue; ++ ++ // read byte 0x24 ++ err = ddTDA182I2Write(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetForce_AGC1_gain: ++// ++// DESCRIPTION: Get the Force_AGC1_gain bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetForce_AGC1_gain ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x24 ++ err = ddTDA182I2Read(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx24.bF.Force_AGC1_gain; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetAGC1_Gain: ++// ++// DESCRIPTION: Set the AGC1_Gain bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetAGC1_Gain ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx24.bF.AGC1_Gain = uValue; ++ ++ // read byte 0x24 ++ err = ddTDA182I2Write(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC1_Gain: ++// ++// DESCRIPTION: Get the AGC1_Gain bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC1_Gain ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x24 ++ err = ddTDA182I2Read(pObj, 0x24, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx24.bF.AGC1_Gain; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq0: ++// ++// DESCRIPTION: Set the RFCAL_Freq0 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq0 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx26.bF.RFCAL_Freq0 = uValue; ++ ++ // read byte 0x26 ++ err = ddTDA182I2Write(pObj, 0x26, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq0: ++// ++// DESCRIPTION: Get the RFCAL_Freq0 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq0 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x26 ++ err = ddTDA182I2Read(pObj, 0x26, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx26.bF.RFCAL_Freq0; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq1: ++// ++// DESCRIPTION: Set the RFCAL_Freq1 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq1 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx26.bF.RFCAL_Freq1 = uValue; ++ ++ // read byte 0x26 ++ err = ddTDA182I2Write(pObj, 0x26, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq1: ++// ++// DESCRIPTION: Get the RFCAL_Freq1 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq1 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x26 ++ err = ddTDA182I2Read(pObj, 0x26, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx26.bF.RFCAL_Freq1; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq2: ++// ++// DESCRIPTION: Set the RFCAL_Freq2 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq2 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx27.bF.RFCAL_Freq2 = uValue; ++ ++ // read byte 0x27 ++ err = ddTDA182I2Write(pObj, 0x27, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq2: ++// ++// DESCRIPTION: Get the RFCAL_Freq2 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq2 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x27 ++ err = ddTDA182I2Read(pObj, 0x27, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx27.bF.RFCAL_Freq2; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq3: ++// ++// DESCRIPTION: Set the RFCAL_Freq3 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq3 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx27.bF.RFCAL_Freq3 = uValue; ++ ++ // read byte 0x27 ++ err = ddTDA182I2Write(pObj, 0x27, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq3: ++// ++// DESCRIPTION: Get the RFCAL_Freq3 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq3 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x27 ++ err = ddTDA182I2Read(pObj, 0x27, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx27.bF.RFCAL_Freq3; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq4: ++// ++// DESCRIPTION: Set the RFCAL_Freq4 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq4 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx28.bF.RFCAL_Freq4 = uValue; ++ ++ // read byte 0x28 ++ err = ddTDA182I2Write(pObj, 0x28, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq4: ++// ++// DESCRIPTION: Get the RFCAL_Freq4 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq4 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x28 ++ err = ddTDA182I2Read(pObj, 0x28, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx28.bF.RFCAL_Freq4; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq5: ++// ++// DESCRIPTION: Set the RFCAL_Freq5 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq5 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx28.bF.RFCAL_Freq5 = uValue; ++ ++ // read byte 0x28 ++ err = ddTDA182I2Write(pObj, 0x28, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq5: ++// ++// DESCRIPTION: Get the RFCAL_Freq5 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq5 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x28 ++ err = ddTDA182I2Read(pObj, 0x28, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx28.bF.RFCAL_Freq5; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq6: ++// ++// DESCRIPTION: Set the RFCAL_Freq6 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq6 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx29.bF.RFCAL_Freq6 = uValue; ++ ++ // read byte 0x29 ++ err = ddTDA182I2Write(pObj, 0x29, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq6: ++// ++// DESCRIPTION: Get the RFCAL_Freq6 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq6 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x29 ++ err = ddTDA182I2Read(pObj, 0x29, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx29.bF.RFCAL_Freq6; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq7: ++// ++// DESCRIPTION: Set the RFCAL_Freq7 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq7 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx29.bF.RFCAL_Freq7 = uValue; ++ ++ // read byte 0x29 ++ err = ddTDA182I2Write(pObj, 0x29, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq7: ++// ++// DESCRIPTION: Get the RFCAL_Freq7 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq7 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x29 ++ err = ddTDA182I2Read(pObj, 0x29, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx29.bF.RFCAL_Freq7; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq8: ++// ++// DESCRIPTION: Set the RFCAL_Freq8 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq8 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2A.bF.RFCAL_Freq8 = uValue; ++ ++ // read byte 0x2A ++ err = ddTDA182I2Write(pObj, 0x2A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq8: ++// ++// DESCRIPTION: Get the RFCAL_Freq8 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq8 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2A ++ err = ddTDA182I2Read(pObj, 0x2A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2A.bF.RFCAL_Freq8; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq9: ++// ++// DESCRIPTION: Set the RFCAL_Freq9 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq9 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2A.bF.RFCAL_Freq9 = uValue; ++ ++ // read byte 0x2A ++ err = ddTDA182I2Write(pObj, 0x2A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq9: ++// ++// DESCRIPTION: Get the RFCAL_Freq9 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq9 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2A ++ err = ddTDA182I2Read(pObj, 0x2A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2A.bF.RFCAL_Freq9; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq10: ++// ++// DESCRIPTION: Set the RFCAL_Freq10 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq10 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2B.bF.RFCAL_Freq10 = uValue; ++ ++ // read byte 0x2B ++ err = ddTDA182I2Write(pObj, 0x2B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq10: ++// ++// DESCRIPTION: Get the ? bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq10 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2B ++ err = ddTDA182I2Read(pObj, 0x2B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2B.bF.RFCAL_Freq10; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Freq11: ++// ++// DESCRIPTION: Set the RFCAL_Freq11 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Freq11 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2B.bF.RFCAL_Freq11 = uValue; ++ ++ // read byte 0x2B ++ err = ddTDA182I2Write(pObj, 0x2B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Freq11: ++// ++// DESCRIPTION: Get the RFCAL_Freq11 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Freq11 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2B ++ err = ddTDA182I2Read(pObj, 0x2B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2B.bF.RFCAL_Freq11; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset0: ++// ++// DESCRIPTION: Set the RFCAL_Offset0 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset0 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx26.bF.RFCAL_Offset_Cprog0 = uValue; ++ ++ // read byte 0x26 ++ err = ddTDA182I2Write(pObj, 0x26, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset0: ++// ++// DESCRIPTION: Get the RFCAL_Offset0 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset0 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x26 ++ err = ddTDA182I2Read(pObj, 0x26, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx26.bF.RFCAL_Offset_Cprog0; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset1: ++// ++// DESCRIPTION: Set the RFCAL_Offset1 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset1 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx26.bF.RFCAL_Offset_Cprog1 = uValue; ++ ++ // read byte 0x26 ++ err = ddTDA182I2Write(pObj, 0x26, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset1: ++// ++// DESCRIPTION: Get the RFCAL_Offset1 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset1 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ ++ // read byte 0x26 ++ err = ddTDA182I2Read(pObj, 0x26, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx26.bF.RFCAL_Offset_Cprog1; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset2: ++// ++// DESCRIPTION: Set the RFCAL_Offset2 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset2 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx27.bF.RFCAL_Offset_Cprog2 = uValue; ++ ++ // read byte 0x27 ++ err = ddTDA182I2Write(pObj, 0x27, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset2: ++// ++// DESCRIPTION: Get the RFCAL_Offset2 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset2 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x27 ++ err = ddTDA182I2Read(pObj, 0x27, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx27.bF.RFCAL_Offset_Cprog2; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset3: ++// ++// DESCRIPTION: Set the RFCAL_Offset3 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset3 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx27.bF.RFCAL_Offset_Cprog3 = uValue; ++ ++ // read byte 0x27 ++ err = ddTDA182I2Write(pObj, 0x27, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset3: ++// ++// DESCRIPTION: Get the RFCAL_Offset3 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset3 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x27 ++ err = ddTDA182I2Read(pObj, 0x27, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx27.bF.RFCAL_Offset_Cprog3; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset4: ++// ++// DESCRIPTION: Set the RFCAL_Offset4 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset4 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx28.bF.RFCAL_Offset_Cprog4 = uValue; ++ ++ // read byte 0x28 ++ err = ddTDA182I2Write(pObj, 0x28, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset4: ++// ++// DESCRIPTION: Get the RFCAL_Offset4 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset4 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x28 ++ err = ddTDA182I2Read(pObj, 0x28, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx28.bF.RFCAL_Offset_Cprog4; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset5: ++// ++// DESCRIPTION: Set the RFCAL_Offset5 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset5 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx28.bF.RFCAL_Offset_Cprog5 = uValue; ++ ++ // read byte 0x28 ++ err = ddTDA182I2Write(pObj, 0x28, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset5: ++// ++// DESCRIPTION: Get the RFCAL_Offset5 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset5 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x28 ++ err = ddTDA182I2Read(pObj, 0x28, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx28.bF.RFCAL_Offset_Cprog5; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset6: ++// ++// DESCRIPTION: Set the RFCAL_Offset6 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset6 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx29.bF.RFCAL_Offset_Cprog6 = uValue; ++ ++ // read byte 0x29 ++ err = ddTDA182I2Write(pObj, 0x29, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset6: ++// ++// DESCRIPTION: Get the RFCAL_Offset6 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset6 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x29 ++ err = ddTDA182I2Read(pObj, 0x29, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx29.bF.RFCAL_Offset_Cprog6; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset7: ++// ++// DESCRIPTION: Set the RFCAL_Offset7 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset7 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx29.bF.RFCAL_Offset_Cprog7 = uValue; ++ ++ // read byte 0x29 ++ err = ddTDA182I2Write(pObj, 0x29, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset7: ++// ++// DESCRIPTION: Get the RFCAL_Offset7 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset7 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x29 ++ err = ddTDA182I2Read(pObj, 0x29, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx29.bF.RFCAL_Offset_Cprog7; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset8: ++// ++// DESCRIPTION: Set the RFCAL_Offset8 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset8 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2A.bF.RFCAL_Offset_Cprog8 = uValue; ++ ++ // read byte 0x2A ++ err = ddTDA182I2Write(pObj, 0x2A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset8: ++// ++// DESCRIPTION: Get the RFCAL_Offset8 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset8 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2A ++ err = ddTDA182I2Read(pObj, 0x2A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2A.bF.RFCAL_Offset_Cprog8; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset9: ++// ++// DESCRIPTION: Set the RFCAL_Offset9 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset9 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2A.bF.RFCAL_Offset_Cprog9 = uValue; ++ ++ // read byte 0x2A ++ err = ddTDA182I2Write(pObj, 0x2A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset9: ++// ++// DESCRIPTION: Get the RFCAL_Offset9 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset9 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2A ++ err = ddTDA182I2Read(pObj, 0x2A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2A.bF.RFCAL_Offset_Cprog9; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset10: ++// ++// DESCRIPTION: Set the RFCAL_Offset10 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset10 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2B.bF.RFCAL_Offset_Cprog10 = uValue; ++ ++ // read byte 0x2B ++ err = ddTDA182I2Write(pObj, 0x2B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset10: ++// ++// DESCRIPTION: Get the ? bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset10 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2B ++ err = ddTDA182I2Read(pObj, 0x2B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2B.bF.RFCAL_Offset_Cprog10; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_Offset11: ++// ++// DESCRIPTION: Set the RFCAL_Offset11 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_Offset11 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2B.bF.RFCAL_Offset_Cprog11 = uValue; ++ ++ // read byte 0x2B ++ err = ddTDA182I2Write(pObj, 0x2B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_Offset11: ++// ++// DESCRIPTION: Get the RFCAL_Offset11 bit(s) status ++// ++// RETURN: TM_OK if no error ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_Offset11 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2B ++ err = ddTDA182I2Read(pObj, 0x2B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2B.bF.RFCAL_Offset_Cprog11; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetAGC2_loop_off: ++// ++// DESCRIPTION: Set the AGC2_loop_off bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetAGC2_loop_off ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2C.bF.AGC2_loop_off = uValue; ++ ++ // read byte 0x2C ++ err = ddTDA182I2Write(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC2_loop_off: ++// ++// DESCRIPTION: Get the AGC2_loop_off bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC2_loop_off ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2C ++ err = ddTDA182I2Read(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2C.bF.AGC2_loop_off; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetForce_AGC2_gain: ++// ++// DESCRIPTION: Set the Force_AGC2_gain bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetForce_AGC2_gain ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2C.bF.Force_AGC2_gain = uValue; ++ ++ // write byte 0x2C ++ err = ddTDA182I2Write(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetForce_AGC2_gain: ++// ++// DESCRIPTION: Get the Force_AGC2_gain bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetForce_AGC2_gain ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2C ++ err = ddTDA182I2Read(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2C.bF.Force_AGC2_gain; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRF_Filter_Gv: ++// ++// DESCRIPTION: Set the RF_Filter_Gv bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRF_Filter_Gv ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2C.bF.RF_Filter_Gv = uValue; ++ ++ // read byte 0x2C ++ err = ddTDA182I2Write(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRF_Filter_Gv: ++// ++// DESCRIPTION: Get the RF_Filter_Gv bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRF_Filter_Gv ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2C ++ err = ddTDA182I2Read(pObj, 0x2C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2C.bF.RF_Filter_Gv; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetAGC2_Do_step: ++// ++// DESCRIPTION: Set the AGC2_Do_step bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetAGC2_Do_step ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2E.bF.AGC2_Do_step = uValue; ++ ++ // read byte 0x2E ++ err = ddTDA182I2Write(pObj, 0x2E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC2_Do_step: ++// ++// DESCRIPTION: Get the AGC2_Do_step bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC2_Do_step ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2E ++ err = ddTDA182I2Read(pObj, 0x2E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2E.bF.AGC2_Do_step; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRF_BPF_Bypass: ++// ++// DESCRIPTION: Set the RF_BPF_Bypass bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRF_BPF_Bypass ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2F.bF.RF_BPF_Bypass = uValue; ++ ++ // read byte 0x2F ++ err = ddTDA182I2Write(pObj, 0x2F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRF_BPF_Bypass: ++// ++// DESCRIPTION: Get the RF_BPF_Bypass bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRF_BPF_Bypass ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2F ++ err = ddTDA182I2Read(pObj, 0x2F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2F.bF.RF_BPF_Bypass; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRF_BPF: ++// ++// DESCRIPTION: Set the RF_BPF bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRF_BPF ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx2F.bF.RF_BPF = uValue; ++ ++ // read byte 0x2F ++ err = ddTDA182I2Write(pObj, 0x2F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRF_BPF: ++// ++// DESCRIPTION: Get the RF_BPF bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRF_BPF ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x2F ++ err = ddTDA182I2Read(pObj, 0x2F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx2F.bF.RF_BPF; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetUp_AGC5: ++// ++// DESCRIPTION: Get the Up_AGC5 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetUp_AGC5 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x31 ++ err = ddTDA182I2Read(pObj, 0x31, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx31.bF.Up_AGC5; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetDo_AGC5: ++// ++// DESCRIPTION: Get the Do_AGC5 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetDo_AGC5 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x31 ++ err = ddTDA182I2Read(pObj, 0x31, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx31.bF.Do_AGC5; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetUp_AGC4: ++// ++// DESCRIPTION: Get the Up_AGC4 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetUp_AGC4 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x31 ++ err = ddTDA182I2Read(pObj, 0x31, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx31.bF.Up_AGC4; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetDo_AGC4: ++// ++// DESCRIPTION: Get the Do_AGC4 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetDo_AGC4 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x31 ++ err = ddTDA182I2Read(pObj, 0x31, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx31.bF.Do_AGC4; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetUp_AGC2: ++// ++// DESCRIPTION: Get the Up_AGC2 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetUp_AGC2 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x31 ++ err = ddTDA182I2Read(pObj, 0x31, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx31.bF.Up_AGC2; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetDo_AGC2: ++// ++// DESCRIPTION: Get the Do_AGC2 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetDo_AGC2 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x31 ++ err = ddTDA182I2Read(pObj, 0x31, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx31.bF.Do_AGC2; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetUp_AGC1: ++// ++// DESCRIPTION: Get the Up_AGC1 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetUp_AGC1 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x31 ++ err = ddTDA182I2Read(pObj, 0x31, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx31.bF.Up_AGC1; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetDo_AGC1: ++// ++// DESCRIPTION: Get the Do_AGC1 bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetDo_AGC1 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x31 ++ err = ddTDA182I2Read(pObj, 0x31, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx31.bF.Do_AGC1; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC2_Gain_Read: ++// ++// DESCRIPTION: Get the AGC2_Gain_Read bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC2_Gain_Read ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x32 ++ err = ddTDA182I2Read(pObj, 0x32, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx32.bF.AGC2_Gain_Read; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC1_Gain_Read: ++// ++// DESCRIPTION: Get the AGC1_Gain_Read bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC1_Gain_Read ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x32 ++ err = ddTDA182I2Read(pObj, 0x32, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx32.bF.AGC1_Gain_Read; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetTOP_AGC3_Read: ++// ++// DESCRIPTION: Get the TOP_AGC3_Read bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetTOP_AGC3_Read ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x33 ++ err = ddTDA182I2Read(pObj, 0x33, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx33.bF.TOP_AGC3_Read; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC5_Gain_Read: ++// ++// DESCRIPTION: Get the AGC5_Gain_Read bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC5_Gain_Read ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x34 ++ err = ddTDA182I2Read(pObj, 0x34, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx34.bF.AGC5_Gain_Read; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetAGC4_Gain_Read: ++// ++// DESCRIPTION: Get the AGC4_Gain_Read bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetAGC4_Gain_Read ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x34 ++ err = ddTDA182I2Read(pObj, 0x34, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx34.bF.AGC4_Gain_Read; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRSSI: ++// ++// DESCRIPTION: Set the RSSI bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRSSI ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx35.RSSI = uValue; ++ ++ // write byte 0x35 ++ err = ddTDA182I2Write(pObj, 0x35, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRSSI: ++// ++// DESCRIPTION: Get the RSSI bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRSSI ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ // tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x35 ++ err = ddTDA182I2Read(pObj, 0x35, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx35.RSSI; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRSSI_AV: ++// ++// DESCRIPTION: Set the RSSI_AV bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRSSI_AV ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx36.bF.RSSI_AV = uValue; ++ ++ // write byte 0x36 ++ err = ddTDA182I2Write(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRSSI_AV: ++// ++// DESCRIPTION: Get the RSSI_AV bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRSSI_AV ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x36 ++ err = ddTDA182I2Read(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx36.bF.RSSI_AV; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRSSI_Cap_Reset_En: ++// ++// DESCRIPTION: Set the RSSI_Cap_Reset_En bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRSSI_Cap_Reset_En ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx36.bF.RSSI_Cap_Reset_En = uValue; ++ ++ // write byte 0x36 ++ err = ddTDA182I2Write(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRSSI_Cap_Reset_En: ++// ++// DESCRIPTION: Get the RSSI_Cap_Reset_En bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRSSI_Cap_Reset_En ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x36 ++ err = ddTDA182I2Read(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx36.bF.RSSI_Cap_Reset_En; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRSSI_Cap_Val: ++// ++// DESCRIPTION: Set the RSSI_Cap_Val bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRSSI_Cap_Val ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx36.bF.RSSI_Cap_Val = uValue; ++ ++ // write byte 0x36 ++ err = ddTDA182I2Write(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRSSI_Cap_Val: ++// ++// DESCRIPTION: Get the RSSI_Cap_Val bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRSSI_Cap_Val ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x36 ++ err = ddTDA182I2Read(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx36.bF.RSSI_Cap_Val; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRSSI_Dicho_not: ++// ++// DESCRIPTION: Set the RSSI_Dicho_not bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRSSI_Dicho_not ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx36.bF.RSSI_Dicho_not = uValue; ++ ++ // write byte 0x36 ++ err = ddTDA182I2Write(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRSSI_Dicho_not: ++// ++// DESCRIPTION: Get the RSSI_Dicho_not bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRSSI_Dicho_not ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x36 ++ err = ddTDA182I2Read(pObj, 0x36, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx36.bF.RSSI_Dicho_not; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetDDS_Polarity: ++// ++// DESCRIPTION: Set the DDS_Polarity bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetDDS_Polarity ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx37.bF.DDS_Polarity = uValue; ++ ++ // write byte 0x37 ++ err = ddTDA182I2Write(pObj, 0x37, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetDDS_Polarity: ++// ++// DESCRIPTION: Get the DDS_Polarity bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetDDS_Polarity ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x37 ++ err = ddTDA182I2Read(pObj, 0x37, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx37.bF.DDS_Polarity; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetRFCAL_DeltaGain: ++// ++// DESCRIPTION: Set the RFCAL_DeltaGain bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetRFCAL_DeltaGain ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx37.bF.RFCAL_DeltaGain = uValue; ++ ++ // read byte 0x37 ++ err = ddTDA182I2Write(pObj, 0x37, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetRFCAL_DeltaGain: ++// ++// DESCRIPTION: Get the RFCAL_DeltaGain bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetRFCAL_DeltaGain ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x37 ++ err = ddTDA182I2Read(pObj, 0x37, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx37.bF.RFCAL_DeltaGain; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2SetIRQ_Polarity: ++// ++// DESCRIPTION: Set the IRQ_Polarity bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2SetIRQ_Polarity ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8 uValue // I: Item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set value ++ pObj->I2CMap.uBx37.bF.IRQ_Polarity = uValue; ++ ++ // read byte 0x37 ++ err = ddTDA182I2Write(pObj, 0x37, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2GetIRQ_Polarity: ++// ++// DESCRIPTION: Get the IRQ_Polarity bit(s) status ++// ++// RETURN: tmdd_ERR_TUNER_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_PARAMETER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2GetIRQ_Polarity ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_PARAMETER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x37 ++ err = ddTDA182I2Read(pObj, 0x37, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx37.bF.IRQ_Polarity; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_0 ++// ++// DESCRIPTION: Get the rfcal_log_0 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_0 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x38 ++ err = ddTDA182I2Read(pObj, 0x38, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx38.bF.rfcal_log_0; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_1 ++// ++// DESCRIPTION: Get the rfcal_log_1 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_1 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x39 ++ err = ddTDA182I2Read(pObj, 0x39, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx39.bF.rfcal_log_1; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_2 ++// ++// DESCRIPTION: Get the rfcal_log_2 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_2 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x3A ++ err = ddTDA182I2Read(pObj, 0x3A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx3A.bF.rfcal_log_2; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_3 ++// ++// DESCRIPTION: Get the rfcal_log_3 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_3 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x3B ++ err = ddTDA182I2Read(pObj, 0x3B, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx3B.bF.rfcal_log_3; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_4 ++// ++// DESCRIPTION: Get the rfcal_log_4 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_4 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x3C ++ err = ddTDA182I2Read(pObj, 0x3C, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx3C.bF.rfcal_log_4; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_5 ++// ++// DESCRIPTION: Get the rfcal_log_5 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_5 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x3D ++ err = ddTDA182I2Read(pObj, 0x3D, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx3D.bF.rfcal_log_5; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_6 ++// ++// DESCRIPTION: Get the rfcal_log_6 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_6 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x3E ++ err = ddTDA182I2Read(pObj, 0x3E, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx3E.bF.rfcal_log_6; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_7 ++// ++// DESCRIPTION: Get the rfcal_log_7 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_7 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x3F ++ err = ddTDA182I2Read(pObj, 0x3F, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx3F.bF.rfcal_log_7; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_8 ++// ++// DESCRIPTION: Get the rfcal_log_8 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_8 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x40 ++ err = ddTDA182I2Read(pObj, 0x40, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx40.bF.rfcal_log_8; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_9 ++// ++// DESCRIPTION: Get the rfcal_log_9 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_9 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x41 ++ err = ddTDA182I2Read(pObj, 0x41, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx41.bF.rfcal_log_9; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_10 ++// ++// DESCRIPTION: Get the rfcal_log_10 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_10 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x42 ++ err = ddTDA182I2Read(pObj, 0x42, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx42.bF.rfcal_log_10; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2Getrfcal_log_11 ++// ++// DESCRIPTION: Get the rfcal_log_11 bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2Getrfcal_log_11 ++( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue // I: Address of the variable to output item value ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ // test the parameter ++ if (puValue == Null) ++ err = ddTDA182I2_ERR_BAD_UNIT_NUMBER; ++ ++ if(err == TM_OK) ++ { ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ } ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // read byte 0x43 ++ err = ddTDA182I2Read(pObj, 0x43, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Read(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // get value ++ *puValue = pObj->I2CMap.uBx43.bF.rfcal_log_11; ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++//------------------------------------------------------------------------------------- ++// FUNCTION: tmddTDA182I2LaunchRF_CAL ++// ++// DESCRIPTION: Launch the RF_CAL bit(s) status ++// ++// RETURN: ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_BAD_UNIT_NUMBER ++// ddTDA182I2_ERR_NOT_INITIALIZED ++// tmdd_ERR_IIC_ERR ++// TM_OK ++// ++// NOTES: ++//------------------------------------------------------------------------------------- ++// ++tmErrorCode_t ++tmddTDA182I2LaunchRF_CAL ++( ++ tmUnitSelect_t tUnit // I: Unit number ++ ) ++{ ++ ptmddTDA182I2Object_t pObj = Null; ++ tmErrorCode_t err = TM_OK; ++ ++ /* Get Instance Object */ ++ err = ddTDA182I2GetInstance(tUnit, &pObj); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2GetInstance(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2MutexAcquire(pObj, ddTDA182I2_MUTEX_TIMEOUT); ++ } ++ ++ if(err == TM_OK) ++ { ++ // set Calc_PLL & RF_CAL ++ pObj->I2CMap.uBx19.MSM_byte_1 = 0x21; ++ ++ // write byte 0x19 ++ err = ddTDA182I2Write(pObj, 0x19, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ if(err == TM_OK) ++ { ++ // trigger MSM_Launch ++ pObj->I2CMap.uBx1A.bF.MSM_Launch = 1; ++ ++ // write byte 0x1A ++ err = ddTDA182I2Write(pObj, 0x1A, 1); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2Write(0x%08X) failed.", tUnit)); ++ ++ // reset MSM_Launch (buffer only, no write) ++ pObj->I2CMap.uBx1A.bF.MSM_Launch = 0; ++ ++ if(pObj->bIRQWait) ++ { ++ if(err == TM_OK) ++ { ++ err = ddTDA182I2WaitIRQ(pObj, 1700, 50, 0x0C); ++ tmASSERTExT(err, TM_OK, (DEBUGLVL_ERROR, "ddTDA182I2WaitIRQ(0x%08X) failed.", tUnit)); ++ } ++ ++ } ++ } ++ ++ (void)ddTDA182I2MutexRelease(pObj); ++ } ++ ++ return err; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_tda18272.h b/drivers/drivers/media/dvb/dvb-usb/tuner_tda18272.h +--- a/drivers/media/dvb/dvb-usb/tuner_tda18272.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_tda18272.h 2016-04-02 19:17:52.176066045 -0300 +@@ -0,0 +1,7412 @@ ++#ifndef __TUNER_TDA18272_H ++#define __TUNER_TDA18272_H ++ ++/** ++ ++@file ++ ++@brief TDA18272 tuner module declaration ++ ++One can manipulate TDA18272 tuner through TDA18272 module. ++TDA18272 module is derived from tuner module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_tda18272.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ TDA18272_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ int StandardBandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build TDA18272 tuner module. ++ BuildTda18272Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0, // I2C device address is 0xc0 in 8-bit format. ++ CRYSTAL_FREQ_16000000HZ, // Crystal frequency is 16.0 MHz. ++ TDA18272_UNIT_0, // Unit number is 0. ++ TDA18272_IF_OUTPUT_VPP_0P7V // IF output Vp-p is 0.7 V. ++ ); ++ ++ ++ ++ ++ ++ // Get TDA18272 tuner extra module. ++ pTunerExtra = (TDA18272_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set TDA18272 standard and bandwidth mode. ++ pTunerExtra->SetStandardBandwidthMode(pTuner, TDA18272_STANDARD_BANDWIDTH_DVBT_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get TDA18272 bandwidth. ++ pTunerExtra->GetStandardBandwidthMode(pTuner, &StandardBandwidthMode); ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++ ++ ++ ++#include "tuner_base.h" ++ ++ ++ ++ ++ ++// Defined by Realtek for tuner TDA18272. ++#define TMBSL_TDA18272 ++ ++ ++ ++ ++ ++// The following context is source code provided by NXP. ++ ++ ++ ++ ++ ++// NXP source code - .\cfg\tmbslTDA182I2_InstanceCustom.h ++ ++ ++ /* ++ Copyright (C) 2006-2009 NXP B.V., All Rights Reserved. ++ This source code and any compilation or derivative thereof is the proprietary ++ information of NXP B.V. and is confidential in nature. Under no circumstances ++ is this software to be exposed to or placed under an Open Source License of ++ any type without the expressed written permission of NXP B.V. ++ * ++ * \file tmbslTDA182I2_InstanceCustom.h ++ * ++ * 1 ++ * ++ * \date %modify_time% ++ * ++ * \brief Describe briefly the purpose of this file. ++ * ++ * REFERENCE DOCUMENTS : ++ * ++ * ++ * Detailed description may be added here. ++ * ++ * \section info Change Information ++ * ++*/ ++ ++#ifndef _TMBSL_TDA182I2_INSTANCE_CUSTOM_H ++#define _TMBSL_TDA182I2_INSTANCE_CUSTOM_H ++ ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++/*============================================================================*/ ++/* Types and defines: */ ++/*============================================================================*/ ++ ++/* Driver settings version definition */ ++#define TMBSL_TDA182I2_SETTINGS_CUSTOMER_NUM 0 /* SW Settings Customer Number */ ++#define TMBSL_TDA182I2_SETTINGS_PROJECT_NUM 0 /* SW Settings Project Number */ ++#define TMBSL_TDA182I2_SETTINGS_MAJOR_VER 0 /* SW Settings Major Version */ ++#define TMBSL_TDA182I2_SETTINGS_MINOR_VER 0 /* SW Settings Minor Version */ ++ ++/* Custom Driver Instance Parameters: (Path 0) */ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_MASTER \ ++ tmTDA182I2_PowerStandbyWithXtalOn, /* Current Power state */ \ ++ tmTDA182I2_PowerStandbyWithXtalOn, /* Minimum Power state */ \ ++ 0, /* RF */ \ ++ tmTDA182I2_DVBT_8MHz, /* Standard mode */ \ ++ True, /* Master */ \ ++ 0, /* LT_Enable */ \ ++ 1, /* PSM_AGC1 */ \ ++ 0, /* AGC1_6_15dB */ \ ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_MASTER_DIGITAL \ ++ tmTDA182I2_PowerStandbyWithXtalOn, /* Current Power state */ \ ++ tmTDA182I2_PowerStandbyWithLNAOnAndWithXtalOnAndSynthe, /* Minimum Power state */ \ ++ 0, /* RF */ \ ++ tmTDA182I2_DVBT_8MHz, /* Standard mode */ \ ++ True, /* Master */ \ ++ 1, /* LT_Enable */ \ ++ 0, /* PSM_AGC1 */ \ ++ 1, /* AGC1_6_15dB */ \ ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_SLAVE \ ++ tmTDA182I2_PowerStandbyWithXtalOn, /* Current Power state */ \ ++ tmTDA182I2_PowerStandbyWithXtalOn, /* Minimum Power state */ \ ++ 0, /* RF */ \ ++ tmTDA182I2_DVBT_8MHz, /* Standard mode */ \ ++ False, /* Master */ \ ++ 0, /* LT_Enable */ \ ++ 1, /* PSM_AGC1 */ \ ++ 0, /* AGC1_6_15dB */ \ ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_SLAVE_DIGITAL \ ++ tmTDA182I2_PowerStandbyWithXtalOn, /* Current Power state */ \ ++ tmTDA182I2_PowerStandbyWithXtalOn, /* Minimum Power state */ \ ++ 0, /* RF */ \ ++ tmTDA182I2_DVBT_8MHz, /* Standard mode */ \ ++ False, /* Master */ \ ++ 0, /* LT_Enable */ \ ++ 1, /* PSM_AGC1 */ \ ++ 0, /* AGC1_6_15dB */ \ ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL \ ++ { /* Std_Array */ /* DVB-T 6MHz */ \ ++ 3250000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_6MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_1Vpp_min_6_24dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Enabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_0_4MHz, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_102dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u105dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u105dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Enabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_2_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Enabled, /* AGC5_Atten_3dB */ \ ++ 0x02, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Enabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Free, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* DVB-T 7MHz */ \ ++ 3500000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_7MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_min_8pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_1Vpp_min_6_24dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Enabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_102dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u105dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u105dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Enabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_2_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Enabled, /* AGC5_Atten_3dB */ \ ++ 0x02, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Enabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Free, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* DVB-T 8MHz */ \ ++ 4000000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_8MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_1Vpp_min_6_24dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Enabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_102dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u105dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u105dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Enabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_2_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Enabled, /* AGC5_Atten_3dB */ \ ++ 0x02, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Enabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Free, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* QAM 6MHz */ \ ++ 3600000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_6MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_min_8pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_1Vpp_min_6_24dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Disabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u105dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u105dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x02, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Free, /* LPF_Gain */ \ ++ True, /* AGC1_freeze */ \ ++ True /* LTO_STO_immune */ \ ++ }, \ ++ { /* QAM 8MHz */ \ ++ 5000000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_9MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_min_8pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_1Vpp_min_6_24dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Disabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_0_85MHz, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u105dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u105dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x02, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Free, /* LPF_Gain */ \ ++ True, /* AGC1_freeze */ \ ++ True /* LTO_STO_immune */ \ ++ }, \ ++ { /* ISDBT 6MHz */ \ ++ 3250000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_6MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_6Vpp_min_10_3_19_7dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Enabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_0_4MHz, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_102dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u105dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u105dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Enabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_2_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Enabled, /* AGC5_Atten_3dB */ \ ++ 0x02, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Enabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Free, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* ATSC 6MHz */ \ ++ 3250000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_6MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_6Vpp_min_10_3_19_7dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Enabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_0_4MHz, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d100_u94dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_104dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_104dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d112_u107dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d112_u107dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Enabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_3_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Enabled, /* AGC5_Atten_3dB */ \ ++ 0x02, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Enabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Free, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* DMB-T 8MHz */ \ ++ 4000000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_8MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_1Vpp_min_6_24dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Enabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_102dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u105dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u105dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Enabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_2_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Enabled, /* AGC5_Atten_3dB */ \ ++ 0x02, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Enabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Free, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_ANALOG \ ++ { /* Analog M/N */ \ ++ 5400000, /* IF */ \ ++ 1750000, /* CF_Offset */ \ ++ tmTDA182I2_LPF_6MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Disabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Disabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Enabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x01, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* Analog B */ \ ++ 6400000, /* IF */ \ ++ 2250000, /* CF_Offset */ \ ++ tmTDA182I2_LPF_7MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Disabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Disabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_High_band*/ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Enabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x01, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* Analog G/H */ \ ++ 6750000, /* IF */ \ ++ 2750000, /* CF_Offset */ \ ++ tmTDA182I2_LPF_8MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Disabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Disabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Enabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x01, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* Analog I */ \ ++ 7250000, /* IF */ \ ++ 2750000, /* CF_Offset */ \ ++ tmTDA182I2_LPF_8MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Disabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Disabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Enabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x01, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* Analog D/K */ \ ++ 6850000, /* IF */ \ ++ 2750000, /* CF_Offset */ \ ++ tmTDA182I2_LPF_8MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Enabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Disabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Enabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x01, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* Analog L */ \ ++ 6750000, /* IF */ \ ++ 2750000, /* CF_Offset */ \ ++ tmTDA182I2_LPF_8MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Enabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Disabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Enabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x01, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* Analog L' */ \ ++ 1250000, /* IF */ \ ++ -2750000, /* CF_Offset */ \ ++ tmTDA182I2_LPF_8MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Disabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Disabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x01, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* Analog FM Radio */ \ ++ 1250000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_1_5MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Disabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_0_85MHz, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x02, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* Blind Scanning copy of PAL-I */ \ ++ 7250000, /* IF */ \ ++ 2750000, /* CF_Offset */ \ ++ tmTDA182I2_LPF_8MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Disabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Disabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Enabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Disabled, /* AGC5_Atten_3dB */ \ ++ 0x01, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ }, \ ++ { /* ScanXpress */ \ ++ 5000000, /* IF */ \ ++ 0, /* CF_Offset */ \ ++ tmTDA182I2_LPF_9MHz, /* LPF */ \ ++ tmTDA182I2_LPFOffset_0pc, /* LPF_Offset */ \ ++ tmTDA182I2_IF_AGC_Gain_1Vpp_min_6_24dB, /* IF_Gain */ \ ++ tmTDA182I2_IF_Notch_Enabled, /* IF_Notch */ \ ++ tmTDA182I2_IF_HPF_Disabled, /* IF_HPF */ \ ++ tmTDA182I2_DC_Notch_Enabled, /* DC_Notch */ \ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV, /* AGC1_LNA_TOP */ \ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2_RF_Attenuator_TOP */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3_RF_AGC_TOP_Low_band */ \ ++ tmTDA182I2_AGC3_RF_AGC_TOP_102dBuV, /* AGC3_RF_AGC_TOP_High_band */ \ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u105dBuV, /* AGC4_IR_Mixer_TOP */ \ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u105dBuV, /* AGC5_IF_AGC_TOP */ \ ++ tmTDA182I2_AGC5_Detector_HPF_Disabled, /* AGC5_Detector_HPF */ \ ++ tmTDA182I2_AGC3_Adapt_Enabled, /* AGC3_Adapt */ \ ++ tmTDA182I2_AGC3_Adapt_TOP_2_Step, /* AGC3_Adapt_TOP */ \ ++ tmTDA182I2_AGC5_Atten_3dB_Enabled, /* AGC5_Atten_3dB */ \ ++ 0x0e, /* GSK : settings V2.0.0 */ \ ++ tmTDA182I2_H3H5_VHF_Filter6_Enabled, /* H3H5_VHF_Filter6 */ \ ++ tmTDA182I2_LPF_Gain_Free, /* LPF_Gain */ \ ++ False, /* AGC1_freeze */ \ ++ False /* LTO_STO_immune */ \ ++ } ++/* Custom Driver Instance Parameters: (Path 1) */ ++ ++/******************************************************************/ ++/* Mode selection for PATH0 */ ++/******************************************************************/ ++ ++#ifdef TMBSL_TDA18272 ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_MODE_PATH0 TMBSL_TDA182I2_INSTANCE_CUSTOM_MASTER ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL_SELECTION_PATH0 TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_ANALOG_SELECTION_PATH0 TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_ANALOG ++ ++#else ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_MODE_PATH0 TMBSL_TDA182I2_INSTANCE_CUSTOM_MASTER_DIGITAL ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL_SELECTION_PATH0 TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL ++ ++#endif ++ ++/******************************************************************/ ++/* Mode selection for PATH1 */ ++/******************************************************************/ ++ ++#ifdef TMBSL_TDA18272 ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_MODE_PATH1 TMBSL_TDA182I2_INSTANCE_CUSTOM_SLAVE ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL_SELECTION_PATH1 TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_ANALOG_SELECTION_PATH1 TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_ANALOG ++ ++#else ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_MODE_PATH1 TMBSL_TDA182I2_INSTANCE_CUSTOM_SLAVE_DIGITAL ++ ++#define TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL_SELECTION_PATH1 TMBSL_TDA182I2_INSTANCE_CUSTOM_STD_DIGITAL ++ ++#endif ++ ++/******************************************************************/ ++/* End of Mode selection */ ++/******************************************************************/ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _TMBSL_TDA182I2_INSTANCE_CUSTOM_H */ ++ ++ ++//#endif ++//*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\inc\tmFlags.h ++ ++ ++ /* */ ++ /* */ ++ /* -- DO NOT EDIT -- file built by */ ++ /* */ ++ /*------------------------------------------------------------------------- */ ++ /* (C) Copyright 2000 Koninklijke Philips Electronics N.V., All Rights Reserved*/ ++ /* */ ++ /* This source code and any compilation or derivative thereof is the sole */ ++ /* property of Philips Corporation and is provided pursuant to a Software */ ++ /* License Agreement. This code is the proprietary information of */ ++ /* Philips Corporation and is confidential in nature. Its use and */ ++ /* dissemination by any party other than Philips Corporation is strictly */ ++ /* limited by the confidential information provisions of the Agreement */ ++ /* referenced above. */ ++ /*------------------------------------------------------------------------- */ ++ /* */ ++ ++ /* */ ++ /* DOCUMENT REF: DVP Build Process Specification */ ++ /* */ ++ /* NOTES: This file defines the TMFL_xxx build flags. */ ++ /* */ ++ #if !defined(_TMFLAGS_H_SEEN_) ++ #define _TMFLAGS_H_SEEN_ ++ /* configuration */ ++ /* */ ++ /* FILENAME: tmFlags.h */ ++ /* */ ++ /* DESCRIPTION: Generated by */ ++ #define TMFL_BUILD_VERSION 00.00.00 ++ #define TMFL_CPU 0x00020011 ++ #define TMFL_ENDIAN 1 ++ #define TMFL_OS 0x03020500 ++ #define TMFL_CPU_IS_X86 1 ++ #define TMFL_CPU_IS_MIPS 0 ++ #define TMFL_CPU_IS_HP 0 ++ #define TMFL_CPU_IS_TM 0 ++ #define TMFL_CPU_IS_ARM 0 ++ #define TMFL_CPU_IS_REAL 0 ++ #define TMFL_OS_IS_BTM 0 ++ #define TMFL_OS_IS_CE 0 ++ #define TMFL_OS_IS_NT 1 ++ #define TMFL_OS_IS_PSOS 0 ++ #define TMFL_OS_IS_NULLOS 0 ++ #define TMFL_OS_IS_ECOS 0 ++ #define TMFL_OS_IS_VXWORKS 0 ++ #define TMFL_OS_IS_MTOS 0 ++ #define TMFL_OS_IS_CEXEC 0 ++ /* DO NOT CHANGE THIS FILE INDEPENDENTLY !!! */ ++ /* IT MUST BE SYNCHONISED WITH THE TMFLAGS TEMPLATE FILE ON THE */ ++ /* MOREUSE WEB SITE http://pww.rtg.sc.philips.com/cmd/html/global_files.html */ ++ /* CONTACT MOREUSE BEFORE ADDING NEW VALUES */ ++ /* constants */ ++ #define TMFL_CPU_TYPE_MASK 0xffff0000 ++ #define TMFL_CPU_TYPE_X86 0x00010000 ++ #define TMFL_CPU_TYPE_MIPS 0x00020000 ++ #define TMFL_CPU_TYPE_TM 0x00030000 ++ #define TMFL_CPU_TYPE_HP 0x00040000 ++ #define TMFL_CPU_TYPE_ARM 0x00050000 ++ #define TMFL_CPU_TYPE_REAL 0x00060000 ++ #define TMFL_CPU_MODEL_MASK 0x0000ffff ++ #define TMFL_CPU_MODEL_I486 0x00000001 ++ #define TMFL_CPU_MODEL_R3940 0x00000002 ++ #define TMFL_CPU_MODEL_R4300 0x00000003 ++ #define TMFL_CPU_MODEL_TM1100 0x00000004 ++ #define TMFL_CPU_MODEL_TM1300 0x00000005 ++ #define TMFL_CPU_MODEL_TM32 0x00000006 ++ #define TMFL_CPU_MODEL_HP 0x00000007 ++ #define TMFL_CPU_MODEL_R4640 0x00000008 ++ #define TMFL_CPU_MODEL_ARM7 0x00000009 ++ #define TMFL_CPU_MODEL_ARM920T 0x0000000a ++ #define TMFL_CPU_MODEL_ARM940T 0x0000000b ++ #define TMFL_CPU_MODEL_ARM10 0x0000000c ++ #define TMFL_CPU_MODEL_STRONGARM 0x0000000d ++ #define TMFL_CPU_MODEL_RD24120 0x0000000e ++ #define TMFL_CPU_MODEL_ARM926EJS 0x0000000f ++ #define TMFL_CPU_MODEL_ARM946 0x00000010 ++ #define TMFL_CPU_MODEL_R1910 0x00000011 ++ #define TMFL_CPU_MODEL_R4450 0x00000012 ++ #define TMFL_CPU_MODEL_TM3260 0x00000013 ++ #define TMFL_ENDIAN_BIG 1 ++ #define TMFL_ENDIAN_LITTLE 0 ++ #define TMFL_OS_MASK 0xff000000 ++ #define TMFL_OS_VERSION_MASK 0x00ffffff ++ #define TMFL_OS_BTM 0x00000000 ++ #define TMFL_OS_CE 0x01000000 ++ #define TMFL_OS_CE212 0x01020102 ++ #define TMFL_OS_CE300 0x01030000 ++ #define TMFL_OS_NT 0x02000000 ++ #define TMFL_OS_NT4 0x02040000 ++ #define TMFL_OS_PSOS 0x03000000 ++ #define TMFL_OS_PSOS250 0x03020500 ++ #define TMFL_OS_PSOS200 0x03020000 ++ #define TMFL_OS_NULLOS 0x04000000 ++ #define TMFL_OS_ECOS 0x05000000 ++ #define TMFL_OS_VXWORKS 0x06000000 ++ #define TMFL_OS_MTOS 0x07000000 ++ #define TMFL_OS_CEXEC 0x08000000 ++ #define TMFL_SCOPE_SP 0 ++ #define TMFL_SCOPE_MP 1 ++ #define TMFL_REL_ASSERT 0x00000002 ++ #define TMFL_REL_DEBUG 0x00000001 ++ #define TMFL_REL_RETAIL 0x00000000 ++ #define TMFL_CPU_I486 0x00010001 ++ #define TMFL_CPU_R3940 0x00020002 ++ #define TMFL_CPU_R4300 0x00020003 ++ #define TMFL_CPU_TM1100 0x00030004 ++ #define TMFL_CPU_TM1300 0x00030005 ++ #define TMFL_CPU_TM32 0x00030006 ++ #define TMFL_CPU_HP 0x00040007 ++ #define TMFL_CPU_R4640 0x00020008 ++ #define TMFL_CPU_ARM7 0x00050009 ++ #define TMFL_CPU_ARM920T 0x0005000a ++ #define TMFL_CPU_ARM940T 0x0005000b ++ #define TMFL_CPU_ARM10 0x0005000c ++ #define TMFL_CPU_STRONGARM 0x0005000d ++ #define TMFL_CPU_RD24120 0x0006000e ++ #define TMFL_CPU_ARM926EJS 0x0005000f ++ #define TMFL_CPU_ARM946 0x00050010 ++ #define TMFL_CPU_R1910 0x00020011 ++ #define TMFL_CPU_R4450 0x00020012 ++ #define TMFL_CPU_TM3260 0x00030013 ++ #define TMFL_MODE_KERNEL 1 ++ #define TMFL_MODE_USER 0 ++ ++ #endif /* !defined(_TMFLAGS_H_SEEN_) */ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\inc\tmNxTypes.h ++ ++ ++/*==========================================================================*/ ++/* (Copyright (C) 2003 Koninklijke Philips Electronics N.V. */ ++/* All rights reserved. */ ++/* This source code and any compilation or derivative thereof is the */ ++/* proprietary information of Koninklijke Philips Electronics N.V. */ ++/* and is confidential in nature. */ ++/* Under no circumstances is this software to be exposed to or placed */ ++/* under an Open Source License of any type without the expressed */ ++/* written permission of Koninklijke Philips Electronics N.V. */ ++/*==========================================================================*/ ++/* ++* Copyright (C) 2000,2001 ++* Koninklijke Philips Electronics N.V. ++* All Rights Reserved. ++* ++* Copyright (C) 2000,2001 TriMedia Technologies, Inc. ++* All Rights Reserved. ++* ++*############################################################ ++* ++* Module name : tmNxTypes.h %version: 4 % ++* ++* Last Update : %date_modified: Tue Jul 8 18:08:00 2003 % ++* ++* Description: TriMedia/MIPS global type definitions. ++* ++* Document Ref: DVP Software Coding Guidelines Specification ++* DVP/MoReUse Naming Conventions specification ++* DVP Software Versioning Specification ++* DVP Device Library Architecture Specification ++* DVP Board Support Library Architecture Specification ++* DVP Hardware API Architecture Specification ++* ++* ++*############################################################ ++*/ ++ ++#ifndef TM_NX_TYPES_H ++#define TM_NX_TYPES_H ++ ++//----------------------------------------------------------------------------- ++// Standard include files: ++//----------------------------------------------------------------------------- ++// ++ ++//----------------------------------------------------------------------------- ++// Project include files: ++//----------------------------------------------------------------------------- ++// ++//#include "tmFlags.h" // DVP common build control flags ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++ //----------------------------------------------------------------------------- ++ // Types and defines: ++ //----------------------------------------------------------------------------- ++ // ++ ++ /*Under the TCS, may have been included by our client. In ++ order to avoid errors, we take account of this possibility, but in order to ++ support environments where the TCS is not available, we do not include the ++ file by name.*/ ++ ++#ifndef _TMtypes_h ++#define _TMtypes_h ++ ++#define False 0 ++#define True 1 ++ ++#ifdef TMFL_NATIVE_C_FORCED ++ #undef TMFL_DOT_NET_2_0_TYPES ++#undef NXPFE ++#endif ++ ++#ifndef TMFL_DOT_NET_2_0_TYPES ++ #ifdef __cplusplus ++ #define Null 0 ++ #else ++ #define Null ((Void *) 0) ++ #endif ++#else ++ #define Null nullptr ++#endif ++ ++ // ++ // Standard Types ++ // ++ ++ typedef signed char CInt8; // 8 bit signed integer ++ typedef signed short CInt16; // 16 bit signed integer ++ typedef signed long CInt32; // 32 bit signed integer ++ typedef unsigned char CUInt8; // 8 bit unsigned integer ++ typedef unsigned short CUInt16; // 16 bit unsigned integer ++ typedef unsigned long CUInt32; // 32 bit unsigned integer ++// typedef float CFloat; // 32 bit floating point ++ typedef unsigned int CBool; // Boolean (True/False) ++ typedef char CChar; // character, character array ptr ++ typedef int CInt; // machine-natural integer ++ typedef unsigned int CUInt; // machine-natural unsigned integer ++ ++#ifndef TMFL_DOT_NET_2_0_TYPES ++ typedef CInt8 Int8; // 8 bit signed integer ++ typedef CInt16 Int16; // 16 bit signed integer ++ typedef CInt32 Int32; // 32 bit signed integer ++ typedef CUInt8 UInt8; // 8 bit unsigned integer ++ typedef CUInt16 UInt16; // 16 bit unsigned integer ++ typedef CUInt32 UInt32; // 32 bit unsigned integer ++// typedef CFloat Float; // 32 bit floating point ++ typedef CBool Bool; // Boolean (True/False) ++ typedef CChar Char; // character, character array ptr ++ typedef CInt Int; // machine-natural integer ++ typedef CUInt UInt; // machine-natural unsigned integer ++ typedef char *String; // Null terminated 8 bit char str ++ ++ //----------------------------------------------------------------------------- ++ // Legacy TM Types/Structures (Not necessarily DVP Coding Guideline compliant) ++ // NOTE: For DVP Coding Gudeline compliant code, do not use these types. ++ // ++ typedef char *Address; // Ready for address-arithmetic ++ typedef char const *ConstAddress; ++ typedef unsigned char Byte; // Raw byte ++// typedef float Float32; // Single-precision float ++// typedef double Float64; // Double-precision float ++ typedef void *Pointer; // Pointer to anonymous object ++ typedef void const *ConstPointer; ++ typedef char const *ConstString; ++#else ++ using namespace System; ++ typedef int Int; ++ typedef SByte Int8; ++ typedef Byte UInt8; ++ typedef float Float32; ++ typedef unsigned int Bool; ++#endif ++ ++ ++ typedef Int Endian; ++#define BigEndian 0 ++#define LittleEndian 1 ++ ++ typedef struct tmVersion ++ { ++ UInt8 majorVersion; ++ UInt8 minorVersion; ++ UInt16 buildVersion; ++ } tmVersion_t, *ptmVersion_t; ++#endif /*ndef _TMtypes_h*/ ++ ++ /*Define DVP types that are not TCS types.*/ ++ ++#ifndef TMFL_DOT_NET_2_0_TYPES ++ typedef Int8 *pInt8; // 8 bit signed integer ++ typedef Int16 *pInt16; // 16 bit signed integer ++ typedef Int32 *pInt32; // 32 bit signed integer ++ typedef UInt8 *pUInt8; // 8 bit unsigned integer ++ typedef UInt16 *pUInt16; // 16 bit unsigned integer ++ typedef UInt32 *pUInt32; // 32 bit unsigned integer ++ typedef void Void, *pVoid; // Void (typeless) ++// typedef Float *pFloat; // 32 bit floating point ++// typedef double Double, *pDouble; // 32/64 bit floating point ++ typedef Bool *pBool; // Boolean (True/False) ++ typedef Char *pChar; // character, character array ptr ++ typedef Int *pInt; // machine-natural integer ++ typedef UInt *pUInt; // machine-natural unsigned integer ++ typedef String *pString; // Null terminated 8 bit char str, ++#else ++ typedef Void *pVoid; // Void (typeless) ++#endif ++ ++#if 0 /*added by Realtek 2011-11-24.*/ ++ /*Assume that 64-bit integers are supported natively by C99 compilers and Visual ++ C version 6.00 and higher. More discrimination in this area may be added ++ here as necessary.*/ ++#ifndef TMFL_DOT_NET_2_0_TYPES ++#if defined __STDC_VERSION__ && __STDC_VERSION__ > 199409L ++ /*This can be enabled only when all explicit references to the hi and lo ++ structure members are eliminated from client code.*/ ++#define TMFL_NATIVE_INT64 1 ++ typedef signed long long int Int64, *pInt64; // 64-bit integer ++ typedef unsigned long long int UInt64, *pUInt64; // 64-bit bitmask ++ // #elif defined _MSC_VER && _MSC_VER >= 1200 ++ // /*This can be enabled only when all explicit references to the hi and lo ++ // structure members are eliminated from client code.*/ ++ // #define TMFL_NATIVE_INT64 1 ++ // typedef signed __int64 Int64, *pInt64; // 64-bit integer ++ // typedef unsigned __int64 UInt64, *pUInt64; // 64-bit bitmask ++#else /*!(defined __STDC_VERSION__ && __STDC_VERSION__ > 199409L)*/ ++#define TMFL_NATIVE_INT64 0 ++ typedef ++ struct ++ { ++ /*Get the correct endianness (this has no impact on any other part of ++ the system, but may make memory dumps easier to understand).*/ ++#if TMFL_ENDIAN == TMFL_ENDIAN_BIG ++ Int32 hi; UInt32 lo; ++#else ++ UInt32 lo; Int32 hi; ++#endif ++ } ++ Int64, *pInt64; // 64-bit integer ++ typedef ++ struct ++ { ++#if TMFL_ENDIAN == TMFL_ENDIAN_BIG ++ UInt32 hi; UInt32 lo; ++#else ++ UInt32 lo; UInt32 hi; ++#endif ++ } ++ UInt64, *pUInt64; // 64-bit bitmask ++#endif /*defined __STDC_VERSION__ && __STDC_VERSION__ > 199409L*/ ++#endif /*TMFL_DOT_NET_2_0_TYPES*/ ++#endif /*added by Realtek 2011-11-24.*/ ++ ++ // Maximum length of device name in all BSP and capability structures ++#define HAL_DEVICE_NAME_LENGTH 16 ++ ++ typedef CUInt32 tmErrorCode_t; ++ typedef CUInt32 tmProgressCode_t; ++ ++ /* timestamp definition */ ++#ifndef TMFL_DOT_NET_2_0_TYPES ++// typedef UInt64 tmTimeStamp_t, *ptmTimeStamp_t; /*added by Realtek 2011-11-24.*/ ++#endif ++ //for backwards compatibility with the older tmTimeStamp_t definition ++#define ticks lo ++#define hiTicks hi ++ ++ typedef union tmColor3 // 3 byte color structure ++ { ++ unsigned long u32; ++#if (TMFL_ENDIAN == TMFL_ENDIAN_BIG) ++ struct { ++UInt32 : 8; ++ UInt32 red : 8; ++ UInt32 green : 8; ++ UInt32 blue : 8; ++ } rgb; ++ struct { ++UInt32 : 8; ++ UInt32 y : 8; ++ UInt32 u : 8; ++ UInt32 v : 8; ++ } yuv; ++ struct { ++UInt32 : 8; ++ UInt32 u : 8; ++ UInt32 m : 8; ++ UInt32 l : 8; ++ } uml; ++#else ++ struct { ++ UInt32 blue : 8; ++ UInt32 green : 8; ++ UInt32 red : 8; ++UInt32 : 8; ++ } rgb; ++ struct { ++ UInt32 v : 8; ++ UInt32 u : 8; ++ UInt32 y : 8; ++UInt32 : 8; ++ } yuv; ++ struct { ++ UInt32 l : 8; ++ UInt32 m : 8; ++ UInt32 u : 8; ++UInt32 : 8; ++ } uml; ++#endif ++ } tmColor3_t, *ptmColor3_t; ++ ++ typedef union tmColor4 // 4 byte color structure ++ { ++ unsigned long u32; ++#if (TMFL_ENDIAN == TMFL_ENDIAN_BIG) ++ struct { ++ UInt32 alpha : 8; ++ UInt32 red : 8; ++ UInt32 green : 8; ++ UInt32 blue : 8; ++ } argb; ++ struct { ++ UInt32 alpha : 8; ++ UInt32 y : 8; ++ UInt32 u : 8; ++ UInt32 v : 8; ++ } ayuv; ++ struct { ++ UInt32 alpha : 8; ++ UInt32 u : 8; ++ UInt32 m : 8; ++ UInt32 l : 8; ++ } auml; ++#else ++ struct { ++ UInt32 blue : 8; ++ UInt32 green : 8; ++ UInt32 red : 8; ++ UInt32 alpha : 8; ++ } argb; ++ struct { ++ UInt32 v : 8; ++ UInt32 u : 8; ++ UInt32 y : 8; ++ UInt32 alpha : 8; ++ } ayuv; ++ struct { ++ UInt32 l : 8; ++ UInt32 m : 8; ++ UInt32 u : 8; ++ UInt32 alpha : 8; ++ } auml; ++#endif ++ } tmColor4_t, *ptmColor4_t; ++ ++ //----------------------------------------------------------------------------- ++ // Hardware device power states ++ // ++ typedef enum tmPowerState ++ { ++ tmPowerOn, // Device powered on (D0 state) ++ tmPowerStandby, // Device power standby (D1 state) ++ tmPowerSuspend, // Device power suspended (D2 state) ++ tmPowerOff // Device powered off (D3 state) ++ ++ } tmPowerState_t, *ptmPowerState_t; ++ ++ //----------------------------------------------------------------------------- ++ // Software Version Structure ++ // ++ typedef struct tmSWVersion ++ { ++ UInt32 compatibilityNr; // Interface compatibility number ++ UInt32 majorVersionNr; // Interface major version number ++ UInt32 minorVersionNr; // Interface minor version number ++ ++ } tmSWVersion_t, *ptmSWVersion_t; ++ ++ /*Under the TCS, may have been included by our client. In ++ order to avoid errors, we take account of this possibility, but in order to ++ support environments where the TCS is not available, we do not include the ++ file by name.*/ ++#ifndef _TMBOARDDEF_H_ ++#define _TMBOARDDEF_H_ ++ ++ //----------------------------------------------------------------------------- ++ // HW Unit Selection ++ // ++ typedef CInt tmUnitSelect_t, *ptmUnitSelect_t; ++ ++#define tmUnitNone (-1) ++#define tmUnit0 0 ++#define tmUnit1 1 ++#define tmUnit2 2 ++#define tmUnit3 3 ++#define tmUnit4 4 ++ ++ /*+compatibility*/ ++#define unitSelect_t tmUnitSelect_t ++#define unit0 tmUnit0 ++#define unit1 tmUnit1 ++#define unit2 tmUnit2 ++#define unit3 tmUnit3 ++#define unit4 tmUnit4 ++#define DEVICE_NAME_LENGTH HAL_DEVICE_NAME_LENGTH ++ /*-compatibility*/ ++ ++#endif /*ndef _TMBOARDDEF_H_ */ ++ ++ //----------------------------------------------------------------------------- ++ // Instance handle ++ // ++ typedef Int tmInstance_t, *ptmInstance_t; ++ ++#ifndef TMFL_DOT_NET_2_0_TYPES ++ // Callback function declaration ++ typedef Void (*ptmCallback_t) (UInt32 events, Void *pData, UInt32 userData); ++#define tmCallback_t ptmCallback_t /*compatibility*/ ++#endif ++ //----------------------------------------------------------------------------- ++ // INLINE keyword for inline functions in all environments ++ // ++ // WinNT/WinCE: Use TMSHARED_DATA_BEGIN/TMSHARED_DATA_END for multiprocess ++ // shared data on a single CPU. To define data variables that are shared ++ // across all processes for WinNT/WinCE, use the defined #pragma macros ++ // TMSHARED_DATA_BEGIN/TMSHARED_DATA_END and initialize the data variables ++ // as shown in the example below. Data defined outside of the begin/end ++ // section or not initialized will not be shared across all processes for ++ // WinNT/WinCE; there will be a separate instance of the variable in each ++ // process. Use WinNT Explorer "QuickView" on the target DLL or text edit ++ // the target DLL *.map file to verify the shared data section presence and ++ // size (shared/static variables will not be named in the MAP file but will ++ // be included in the shared section virtual size). ++ // NOTE: All data variables in the multiprocess section _MUST_BE_INITIALIZED_ ++ // to be shared across processes; if no explicit initialization is ++ // done, the data variables will not be shared across processes. This ++ // shared data mechanism only applies to WinNT/WinCE multiprocess data ++ // on a single CPU (pSOS shares all data across tasks by default). Use ++ // the TMML MP shared data region for shared data across multiple CPUs ++ // and multiple processes. Example (note global variable naming): ++ // ++ // #if (TMFL_OS_IS_CE || TMFL_OS_IS_NT) ++ // #pragma TMSHARED_DATA_BEGIN // Multiprocess shared data begin ++ // #endif ++ // ++ // static g = ; ++ // gtm = ; ++ // ++ // #if (TMFL_OS_IS_CE || TMFL_OS_IS_NT) ++ // #pragma TMSHARED_DATA_END // Multiprocess shared data end ++ // #endif ++ // ++ ++#if TMFL_OS_IS_CE || TMFL_OS_IS_NT ++#ifndef inline ++#define inline __inline ++#endif ++ ++ // ++ // Places shared data in named DLL data segment for WinNT/WinCE builds. ++ // NOTE: These pragma defines require DLLFLAGS += -section:.tmShare,RWS in the ++ // nt.mak and ce.mak target OS makefiles for this mechanism to work. ++ // ++#define TMSHARED_DATA_BEGIN data_seg(".tmShare") ++#define TMSHARED_DATA_END data_seg() ++ ++#elif TMFL_OS_IS_PSOS && TMFL_CPU_IS_MIPS ++ ++ // NOTE regarding the keyword INLINE: ++ // ++ // Inline is not an ANSI-C keyword, hence every compiler can implement inlining ++ // the way it wants to. When using the dcc compiler this might possibly lead to ++ // redeclaration warnings when linking. For example: ++ // ++ // dld: warning: Redeclaration of tmmlGetMemHandle ++ // dld: Defined in root.o ++ // dld: and tmmlApi.o(../../lib/pSOS-MIPS/libtmml.a) ++ // ++ // For the dcc compiler inlining is not on by default. When building a retail ++ // version ( _TMTGTREL=ret), inlining is turned on explicitly in the dvp1 pSOS ++ // makefiles by specifying -XO, which enables all standard optimizations plus ++ // some others, including inlining (see the Language User's Manual, D-CC and ++ // D-C++ Compiler Suites p46). When building a debug version ( _TMTGTREL=dbg), ++ // the optimizations are not turned on (and even if they were they would have ++ // been overruled by -g anyway). ++ // ++ // When a .h file with inline function declarations gets included in multiple ++ // source files, redeclaration warnings are issued. ++ // ++ // When building a retail version those functions are inlined, but in addition ++ // the function is also declared within the .o file, resulting in redeclaration ++ // warnings as the same function is also defined by including that same header ++ // file in other source files. Defining the functions as static inline rather ++ // than inline solves the problem, as now the additional function declaration ++ // is omitted (as now the compiler realizes that there is no point in keeping ++ // that declaration as it can only be called from within this specific file, ++ // but it isn't, because all calls are already inline). ++ // ++ // When building a debug version no inlining is done, but the functions are ++ // still defined within the .o file, again resulting in redeclaration warnings. ++ // Again, defining the functions to be static inline rather than inline solves ++ // the problem. ++ ++ // Now if we would change the definition of the inline keyword for pSOS from ++ // __inline__ to static __inline__, all inline function definitions throughout ++ // the code would not issue redeclaration warnings anymore, but all static ++ // inline definitions would. ++ // If we don't change the definition of the inline keyword, all inline func- ++ // tion definitions would return redeclaration warnings. ++ // ++ // As this is a pSOS linker bug, it was decided not to change the code but ++ // rather to ignore the issued warnings. ++ // ++ ++#define inline __inline__ ++ ++#elif TMFL_OS_IS_PSOS && TMFL_CPU_IS_TM ++ // TriMedia keyword is already inline ++ ++#elif TMFL_OS_IS_ECOS && TMFL_CPU_IS_MIPS ++ ++#define inline __inline__ ++ ++// #elif (TMFL_OS_IS_HPUNIX || TMFL_OS_IS_NULLOS) ++ // ++ // TMFL_OS_IS_HPUNIX is the HP Unix workstation target OS environment for the ++ // DVP SDE2 using the GNU gcc toolset. It is the same as TMFL_OS_IS_NULLOS ++ // (which is inaccurately named because it is the HP Unix CPU/OS target ++ // environment). ++ // ++ /* LM; 02/07/2202; to be able to use Insure, I modify the definition of inline */ ++ /* #define inline __inline__ */ ++// #define inline ++ ++#elif TMFL_OS_IS_ECOS && TMFL_CPU_IS_MIPS ++ ++#define inline ++ ++#else // TMFL_OS_IS_??? ++ ++#error confusing value in TMFL_OS! ++ ++#endif // TMFL_OS_IS_XXX ++ ++ /*Assume that |restrict| is supported by tmcc and C99 compilers only. More ++ discrimination in this area may be added here as necessary.*/ ++#if !(defined __TCS__ || \ ++ (defined __STDC_VERSION__ && __STDC_VERSION__ > 199409L)) ++#define restrict /**/ ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif //ndef TMNXTYPES_H ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\inc\tmCompId.h ++ ++ ++/*==========================================================================*/ ++/* (Copyright (C) 2003 Koninklijke Philips Electronics N.V. */ ++/* All rights reserved. */ ++/* This source code and any compilation or derivative thereof is the */ ++/* proprietary information of Koninklijke Philips Electronics N.V. */ ++/* and is confidential in nature. */ ++/* Under no circumstances is this software to be exposed to or placed */ ++/* under an Open Source License of any type without the expressed */ ++/* written permission of Koninklijke Philips Electronics N.V. */ ++/*==========================================================================*/ ++//----------------------------------------------------------------------------- ++// MoReUse - 2001-11-12 Continuus Version 16 ++// ++// Added ++// CID_COMP_TRICK ++// CID_COMP_TODISK ++// CID_COMP_FROMDISK ++// ++// Removed ++// CID_COMP_RTC Twice the same request - duplicate removed ++// ++// (C) Copyright 2000-2001 Koninklijke Philips Electronics N.V., ++// All rights reserved ++// ++// This source code and any compilation or derivative thereof is the sole ++// property of Philips Corporation and is provided pursuant to a Software ++// License Agreement. This code is the proprietary information of Philips ++// Corporation and is confidential in nature. Its use and dissemination by ++// any party other than Philips Corporation is strictly limited by the ++// confidential information provisions of the Agreement referenced above. ++//----------------------------------------------------------------------------- ++// FILE NAME: tmCompId.h ++// ++// DESCRIPTION: This header file identifies the standard component identifiers ++// for DVP platforms. The objective of DVP component IDs is to ++// enable unique identification of software components at all ++// classes, types, and layers. In addition, standard status ++// values are also defined to make determination of typical error ++// cases much easier. The component identifier bitfields are ++// four bit aligned to ease in reading the hexadecimal value. ++// ++// The process to create a new component ID follows the sequence ++// of steps: ++// ++// 1) Select a component class: The class is the most general ++// component classification. If none of the classifications ++// match and the component can still be uniquely identified ++// by its type/tag/layer combination, use CID_CLASS_NONE. ++// For customers, the CID_CLASS_CUSTOMER value is defined. ++// If that value is used in the CID_CLASS_BITMASK field, ++// all other bits in the component ID are user defined. ++// ++// 2) Select a component type: The component type is used to ++// classify how a component processes data. Components may ++// have only output pins (source), only input pins (sink), ++// input and output pins with or without data modifications ++// (filter), control of data flow without input/output pins ++// (control), data storage/access/retrieval (database), ++// or component group (subsystem). If the component does ++// not fit into any type classification, use CID_TYPE_NONE. ++// ++// 3) Create a component ID: The component ID is used to ++// classify the specific type and/or attributes of a software ++// component API interface. The currently defined list should ++// be scanned for a component match. If no component match ++// can be found, define a new component tag that descibes the ++// component clearly. Component name abbreviations/acronyms ++// are generally used; build a name starting from left to ++// right with the most general ('A' or 'AUD' for audio, 'V' or ++// 'VID' for video, etc.) to the most specific ('AC3' or 'MP3' ++// as specific audio filter types) terms for the component. ++// ++// NOTE: Component layer (CID_LAYER_XXX) and status (CID_ERR_XXX) ++// values are defined within the software component APIs ++// header files, not in this file. ++// ++// DOCUMENT REF: DVP Software Coding Guidelines specification ++// DVP/MoReUse Naming Conventions specification ++// ++// NOTES: The 32 bit component identifier bitfields are defined in the ++// diagram below: ++// ++// +----------------------------------------- 4 bit Component Class ++// / +----------------------------------- 4 bit Component Type ++// / / +-------------------------- 8 bit Component Tag ++// / / / +----------------- 4 bit Component Layer ++// / / / / +----- 12 bit Component Status ++// / / / / / ++// |31 28|27 24|23 16|15 12|11 0| bit ++// +------+------+------------+------+------------------+ ++// |Class | Type |ComponentTag|Layer | Error/Progress | ++// +------+------+------------+------+------------------+ ++// ++//----------------------------------------------------------------------------- ++// ++#ifndef TM_COMP_ID_H //------------------- ++#define TM_COMP_ID_H ++ ++//----------------------------------------------------------------------------- ++// Standard include files: ++//----------------------------------------------------------------------------- ++// ++ ++//----------------------------------------------------------------------------- ++// Project include files: ++//----------------------------------------------------------------------------- ++// ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++//----------------------------------------------------------------------------- ++// Types and defines: ++//----------------------------------------------------------------------------- ++// ++ ++//----------------------------------------------------------------------------- ++// TM_OK is the 32 bit global status value used by all DVP software components ++// to indicate successful function/operation status. If a non-zero value is ++// returned as status, it should use the component ID formats defined. ++// ++#define TM_OK 0 // Global success return status ++ ++ ++// ++// NOTE: Component ID types are defined as unsigned 32 bit integers (UInt32). ++// ++//----------------------------------------------------------------------------- ++// Component Class definitions (bits 31:28, 4 bits) ++// NOTE: A class of 0x0 must not be defined to ensure that the overall 32 bit ++// component ID/status combination is always non-0 (no TM_OK conflict). ++// ++#define CID_CLASS_BITSHIFT 28 // Component class bit shift ++#define CID_CLASS_BITMASK (0xF << CID_CLASS_BITSHIFT) // Class AND bitmsk ++#define CID_GET_CLASS(compId) ((compId & CID_CLASS_BITMASK) >> CID_CLASS_BITSHIFT) ++// ++#define CID_CLASS_NONE (0x1 << CID_CLASS_BITSHIFT) // No class information ++#define CID_CLASS_VIDEO (0x2 << CID_CLASS_BITSHIFT) // Video data component ++#define CID_CLASS_AUDIO (0x3 << CID_CLASS_BITSHIFT) // Audio data component ++#define CID_CLASS_GRAPHICS (0x4 << CID_CLASS_BITSHIFT) // Graphics component ++#define CID_CLASS_BUS (0x5 << CID_CLASS_BITSHIFT) // In/out/control bus ++#define CID_CLASS_INFRASTR (0x6 << CID_CLASS_BITSHIFT) // Infrastructure comp. ++ // Up to 0xE = Philips reserved class IDs ++#define CID_CLASS_CUSTOMER (0xF << CID_CLASS_BITSHIFT) // Customer rsvd class ++ ++ ++//----------------------------------------------------------------------------- ++// Component Type definitions (bits 27:24, 4 bits) ++// ++#define CID_TYPE_BITSHIFT 24 // Component type bit shift ++#define CID_TYPE_BITMASK (0xF << CID_TYPE_BITSHIFT) // Type AND bitmask ++#define CID_GET_TYPE(compId) ((compId & CID_TYPE_BITMASK) >> CID_TYPE_BITSHIFT) ++// ++#define CID_TYPE_NONE (0x0 << CID_TYPE_BITSHIFT) // No data connections ++#define CID_TYPE_SOURCE (0x1 << CID_TYPE_BITSHIFT) // Source, output pins ++#define CID_TYPE_SINK (0x2 << CID_TYPE_BITSHIFT) // Sink, input pins ++#define CID_TYPE_ENCODER (0x3 << CID_TYPE_BITSHIFT) // Data encoder ++#define CID_TYPE_DECODER (0x4 << CID_TYPE_BITSHIFT) // Data decoder ++#define CID_TYPE_MUX (0x5 << CID_TYPE_BITSHIFT) // Data multiplexer ++#define CID_TYPE_DEMUX (0x6 << CID_TYPE_BITSHIFT) // Data demultiplexer ++#define CID_TYPE_DIGITIZER (0x7 << CID_TYPE_BITSHIFT) // Data digitizer ++#define CID_TYPE_RENDERER (0x8 << CID_TYPE_BITSHIFT) // Data renderer ++#define CID_TYPE_FILTER (0x9 << CID_TYPE_BITSHIFT) // Data filter/processr ++#define CID_TYPE_CONTROL (0xA << CID_TYPE_BITSHIFT) // Data control/switch ++#define CID_TYPE_DATABASE (0xB << CID_TYPE_BITSHIFT) // Data store/access ++#define CID_TYPE_SUBSYSTEM (0xC << CID_TYPE_BITSHIFT) // MultiComp subsystem ++#define CID_TYPE_CUSTOMER (0xF << CID_TYPE_BITSHIFT) // Customer Defined Type ++ // Up to 0xF = Philips reserved type IDs ++ ++ ++//----------------------------------------------------------------------------- ++// Component Tag definitions (bits 23:16, 8 bits) ++// NOTE: Component tags are defined in groups, dependent on the class and type. ++// ++#define CID_TAG_BITSHIFT 16 // Component tag bit shift ++#define CID_TAG_BITMASK (0xFF << CID_TAG_BITSHIFT) // Comp tag AND bitmask ++// ++#define CID_TAG_NONE (0x00 << CID_TAG_BITSHIFT) // No tag information ++ // Up to 0xFF = Philips reserved component tags ++#define CID_TAG_CUSTOMER (0xE0 << CID_TAG_BITSHIFT) ++ ++#define TAG(number) ((number) << CID_TAG_BITSHIFT) // Create tag from num ++ ++//----------------------------------------------------------------------------- ++// Component Layer definitions (bits 15:12, 4 bits) ++// ++#define CID_LAYER_BITSHIFT 12 // Component layer bit shift ++#define CID_LAYER_BITMASK (0xF << CID_LAYER_BITSHIFT) // Layer AND bitmask ++#define CID_GET_LAYER(compId) ((compId & CID_LAYER_BITMASK) >> CID_LAYER_BITSHIFT) ++// ++#define CID_LAYER_NONE (0x0 << CID_LAYER_BITSHIFT) // No layer info ++#define CID_LAYER_BTM (0x1 << CID_LAYER_BITSHIFT) // Boot manager layer ++#define CID_LAYER_HWAPI (0x2 << CID_LAYER_BITSHIFT) // Hardware API layer ++#define CID_LAYER_BSL (0x3 << CID_LAYER_BITSHIFT) // Board Supp. Lib lyr ++#define CID_LAYER_DEVLIB (0x4 << CID_LAYER_BITSHIFT) // Device Library lyr ++#define CID_LAYER_TMAL (0x5 << CID_LAYER_BITSHIFT) // Application layer ++#define CID_LAYER_TMOL (0x6 << CID_LAYER_BITSHIFT) // OSDependent layer ++#define CID_LAYER_CUSTOMER (0xF << CID_LAYER_BITSHIFT) // Customer Defined Layer ++ // Up to 0xF = Philips reserved layer IDs ++ ++ ++ ++//----------------------------------------------------------------------------- ++// Component Identifier definitions (bits 31:12, 20 bits) ++// NOTE: These DVP platform component identifiers are designed to be unique ++// within the system. The component identifier encompasses the class ++// (CID_CLASS_XXX), type (CID_TYPE_XXX), tag, and layer (CID_LAYER_XXX) ++// fields to form the unique component identifier. This allows any ++// error/progress status value to be identified as to its original ++// source, whether or not the source component's header file is present. ++// The standard error/progress status definitions should be used ++// whenever possible to ease status interpretation. No layer ++// information is defined at this point; it should be OR'd into the API ++// status values defined in the API's header file. ++// ++#if (CID_LAYER_NONE != 0) ++#error ERROR: DVP component identifiers require the layer type 'NONE' = 0 ! ++#endif ++ ++// ++// Classless Types/Components (don't fit into other class categories) ++// ++#define CTYP_NOCLASS_NOTYPE (CID_CLASS_NONE | CID_TYPE_NONE) ++#define CTYP_NOCLASS_SOURCE (CID_CLASS_NONE | CID_TYPE_SOURCE) ++#define CTYP_NOCLASS_SINK (CID_CLASS_NONE | CID_TYPE_SINK) ++#define CTYP_NOCLASS_MUX (CID_CLASS_NONE | CID_TYPE_MUX) ++#define CTYP_NOCLASS_DEMUX (CID_CLASS_NONE | CID_TYPE_DEMUX) ++#define CTYP_NOCLASS_FILTER (CID_CLASS_NONE | CID_TYPE_FILTER) ++#define CTYP_NOCLASS_CONTROL (CID_CLASS_NONE | CID_TYPE_CONTROL) ++#define CTYP_NOCLASS_DATABASE (CID_CLASS_NONE | CID_TYPE_DATABASE) ++#define CTYP_NOCLASS_SUBSYS (CID_CLASS_NONE | CID_TYPE_SUBSYSTEM) ++// ++#define CID_COMP_CLOCK (TAG(0x01) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_DMA (TAG(0x02) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_PIC (TAG(0x03) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_NORFLASH (TAG(0x04) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_NANDFLASH (TAG(0x05) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_GPIO (TAG(0x06) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_SMARTCARD (TAG(0x07) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_UDMA (TAG(0x08) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_DSP (TAG(0x09) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_TIMER (TAG(0x0A) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_TSDMA (TAG(0x0B) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_MMIARB (TAG(0x0C) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_EEPROM (TAG(0x0D) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_PARPORT (TAG(0x0E) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_VSS (TAG(0x0F) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_TSIO (TAG(0x10) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_DBG (TAG(0x11) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_TTE (TAG(0x12) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_AVPROP (TAG(0x13) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_BLASTER (TAG(0x14) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_CAPTURE (TAG(0x15) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_STP (TAG(0x16) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_SYN (TAG(0x17) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_TTX (TAG(0x18) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_MIU (TAG(0x19) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_INTDRV (TAG(0x1A) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_RESET (TAG(0x1B) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_CONFIG (TAG(0x1C) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_VCTRL (TAG(0x1D) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_TUNER (TAG(0x1E) | CTYP_NOCLASS_NOTYPE) ++#define CID_COMP_DEMOD (TAG(0x1F) | CTYP_NOCLASS_NOTYPE) ++ ++ ++#define CID_COMP_FREAD (TAG(0x01) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_CDRREAD (TAG(0x02) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_VSB (TAG(0x03) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_ANALOGTVTUNER (TAG(0x04) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_TPINMPEG2 (TAG(0x05) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_DREAD (TAG(0x06) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_TREAD (TAG(0x07) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_RTC (TAG(0x08) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_TOUCHC (TAG(0x09) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_KEYPAD (TAG(0x0A) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_ADC (TAG(0x0B) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_READLIST (TAG(0x0C) | CTYP_NOCLASS_SOURCE) ++#define CID_COMP_FROMDISK (TAG(0x0D) | CTYP_NOCLASS_SOURCE) ++ ++#define CID_COMP_FWRITE (TAG(0x01) | CTYP_NOCLASS_SINK) ++#define CID_COMP_CDWRITE (TAG(0x02) | CTYP_NOCLASS_SINK) ++#define CID_COMP_CHARLCD (TAG(0x03) | CTYP_NOCLASS_SINK) ++#define CID_COMP_PWM (TAG(0x04) | CTYP_NOCLASS_SINK) ++#define CID_COMP_DAC (TAG(0x05) | CTYP_NOCLASS_SINK) ++#define CID_COMP_TSDMAINJECTOR (TAG(0x06) | CTYP_NOCLASS_SINK) ++#define CID_COMP_TODISK (TAG(0x07) | CTYP_NOCLASS_SINK) ++ ++#define CID_COMP_MUXMPEGPS (TAG(0x01) | CTYP_NOCLASS_MUX) ++#define CID_COMP_MUXMPEG (TAG(0x02) | CTYP_NOCLASS_MUX) ++ ++#define CID_COMP_DEMUXMPEGTS (TAG(0x01) | CTYP_NOCLASS_DEMUX) ++#define CID_COMP_DEMUXMPEGPS (TAG(0x02) | CTYP_NOCLASS_DEMUX) ++ ++#define CID_COMP_COPYIO (TAG(0x01) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_COPYINPLACE (TAG(0x02) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_UART (TAG(0x03) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_SSI (TAG(0x04) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_MODEMV34 (TAG(0x05) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_MODEMV42 (TAG(0x06) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_HTMLPARSER (TAG(0x07) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_VMSP (TAG(0x08) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_X (TAG(0x09) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_TXTSUBTDECEBU (TAG(0x0A) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_CPI (TAG(0x0B) | CTYP_NOCLASS_FILTER) ++#define CID_COMP_TRICK (TAG(0x0C) | CTYP_NOCLASS_FILTER) ++ ++#define CID_COMP_REMCTL5 (TAG(0x01) | CTYP_NOCLASS_CONTROL) ++#define CID_COMP_INFRARED (TAG(0x02) | CTYP_NOCLASS_CONTROL) ++ ++#define CID_COMP_PSIP (TAG(0x01) | CTYP_NOCLASS_DATABASE) ++#define CID_COMP_IDE (TAG(0x02) | CTYP_NOCLASS_DATABASE) ++#define CID_COMP_DISKSCHED (TAG(0x03) | CTYP_NOCLASS_DATABASE) ++#define CID_COMP_AVFS (TAG(0x04) | CTYP_NOCLASS_DATABASE) ++#define CID_COMP_MDB (TAG(0x05) | CTYP_NOCLASS_DATABASE) ++ ++#define CID_COMP_IRDMMPEG (TAG(0x01) | CTYP_NOCLASS_SUBSYS) ++#define CID_COMP_STORSYS (TAG(0x02) | CTYP_NOCLASS_SUBSYS) ++ ++// ++// Video Class Types/Components (video types handle video/graphics data) ++// ++#define CTYP_VIDEO_SINK (CID_CLASS_VIDEO | CID_TYPE_SINK) ++#define CTYP_VIDEO_SOURCE (CID_CLASS_VIDEO | CID_TYPE_SOURCE) ++#define CTYP_VIDEO_ENCODER (CID_CLASS_VIDEO | CID_TYPE_ENCODER) ++#define CTYP_VIDEO_DECODER (CID_CLASS_VIDEO | CID_TYPE_DECODER) ++#define CTYP_VIDEO_DIGITIZER (CID_CLASS_VIDEO | CID_TYPE_DIGITIZER) ++#define CTYP_VIDEO_RENDERER (CID_CLASS_VIDEO | CID_TYPE_RENDERER) ++#define CTYP_VIDEO_FILTER (CID_CLASS_VIDEO | CID_TYPE_FILTER) ++#define CTYP_VIDEO_SUBSYS (CID_CLASS_VIDEO | CID_TYPE_SUBSYSTEM) ++// ++#define CID_COMP_LCD (TAG(0x01) | CTYP_VIDEO_SINK) ++ ++#define CID_COMP_VCAPVI (TAG(0x01) | CTYP_VIDEO_SOURCE) ++#define CID_COMP_VIP (TAG(0x02) | CTYP_VIDEO_SOURCE) ++#define CID_COMP_VI (TAG(0x03) | CTYP_VIDEO_SOURCE) ++#define CID_COMP_VSLICER (TAG(0x04) | CTYP_VIDEO_SOURCE) ++#define CID_COMP_FBREAD (TAG(0x05) | CTYP_VIDEO_SOURCE) ++#define CID_COMP_QVI (TAG(0x06) | CTYP_VIDEO_SOURCE) ++#define CID_COMP_CAMERA (TAG(0x07) | CTYP_VIDEO_SOURCE) ++ ++#define CID_COMP_VENCM1 (TAG(0x01) | CTYP_VIDEO_ENCODER) ++#define CID_COMP_VENCM2 (TAG(0x02) | CTYP_VIDEO_ENCODER) ++#define CID_COMP_VENCMJ (TAG(0x03) | CTYP_VIDEO_ENCODER) ++#define CID_COMP_VENCH263 (TAG(0x04) | CTYP_VIDEO_ENCODER) ++#define CID_COMP_VENCH261 (TAG(0x05) | CTYP_VIDEO_ENCODER) ++ ++#define CID_COMP_VDECM1 (TAG(0x01) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDECM2 (TAG(0x02) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDECMPEG (TAG(0x03) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDECMJ (TAG(0x04) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDECSUBPICSVCD (TAG(0x05) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDECH263 (TAG(0x06) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDECH261 (TAG(0x07) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDEC (TAG(0x08) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDECSUBPICDVD (TAG(0x09) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDECSUBPICBMPDVD (TAG(0x0A) | CTYP_VIDEO_DECODER) ++#define CID_COMP_VDECSUBPICRENDDVD (TAG(0x0B) | CTYP_VIDEO_DECODER) ++#define CID_COMP_M4PP (TAG(0x0C) | CTYP_VIDEO_DECODER) ++#define CID_COMP_M4MC (TAG(0x0D) | CTYP_VIDEO_DECODER) ++#define CID_COMP_M4CSC (TAG(0x0E) | CTYP_VIDEO_DECODER) ++ ++#define CID_COMP_VDIG (TAG(0x01) | CTYP_VIDEO_DIGITIZER) ++#define CID_COMP_VDIGVIRAW (TAG(0x02) | CTYP_VIDEO_DIGITIZER) ++ ++#define CID_COMP_VREND (TAG(0x01) | CTYP_VIDEO_RENDERER) ++#define CID_COMP_HDVO (TAG(0x02) | CTYP_VIDEO_RENDERER) ++#define CID_COMP_VRENDGFXVO (TAG(0x03) | CTYP_VIDEO_RENDERER) ++#define CID_COMP_AICP (TAG(0x04) | CTYP_VIDEO_RENDERER) ++#define CID_COMP_VRENDVORAW (TAG(0x05) | CTYP_VIDEO_RENDERER) ++#define CID_COMP_VO (TAG(0x06) | CTYP_VIDEO_RENDERER) ++#define CID_COMP_QVO (TAG(0x06) | CTYP_VIDEO_RENDERER) ++#define CID_COMP_VRENDVOICP (TAG(0x07) | CTYP_VIDEO_RENDERER) ++#define CID_COMP_VMIX (TAG(0x08) | CTYP_VIDEO_RENDERER) ++#define CID_COMP_GFX (TAG(0x09) | CTYP_VIDEO_RENDERER) ++ ++#define CID_COMP_MBS (TAG(0x01) | CTYP_VIDEO_FILTER) ++#define CID_COMP_VTRANS (TAG(0x02) | CTYP_VIDEO_FILTER) ++#define CID_COMP_QNM (TAG(0x03) | CTYP_VIDEO_FILTER) ++#define CID_COMP_ICP (TAG(0x04) | CTYP_VIDEO_FILTER) ++#define CID_COMP_VTRANSNM (TAG(0x05) | CTYP_VIDEO_FILTER) ++#define CID_COMP_QFD (TAG(0x06) | CTYP_VIDEO_FILTER) // film detector ++#define CID_COMP_VRENDDVDVO (TAG(0x07) | CTYP_VIDEO_FILTER) ++#define CID_COMP_VTRANSCRYSTAL (TAG(0x08) | CTYP_VIDEO_FILTER) ++ ++#define CID_COMP_VSYSMT3 (TAG(0x01) | CTYP_VIDEO_SUBSYS) //obsolescent ++#define CID_COMP_VSYSSTB (TAG(0x01) | CTYP_VIDEO_SUBSYS) ++#define CID_COMP_DVDVIDSYS (TAG(0x02) | CTYP_VIDEO_SUBSYS) ++#define CID_COMP_VDECUD (TAG(0x03) | CTYP_VIDEO_SUBSYS) ++#define CID_COMP_VIDSYS (TAG(0x04) | CTYP_VIDEO_SUBSYS) ++// ++// Audio Class Types/Components (audio types primarily handle audio data) ++// ++#define CTYP_AUDIO_NONE (CID_CLASS_AUDIO | CID_TYPE_NONE) ++#define CTYP_AUDIO_SINK (CID_CLASS_AUDIO | CID_TYPE_SINK) ++#define CTYP_AUDIO_SOURCE (CID_CLASS_AUDIO | CID_TYPE_SOURCE) ++#define CTYP_AUDIO_ENCODER (CID_CLASS_AUDIO | CID_TYPE_ENCODER) ++#define CTYP_AUDIO_DECODER (CID_CLASS_AUDIO | CID_TYPE_DECODER) ++#define CTYP_AUDIO_DIGITIZER (CID_CLASS_AUDIO | CID_TYPE_DIGITIZER) ++#define CTYP_AUDIO_RENDERER (CID_CLASS_AUDIO | CID_TYPE_RENDERER) ++#define CTYP_AUDIO_FILTER (CID_CLASS_AUDIO | CID_TYPE_FILTER) ++#define CTYP_AUDIO_SUBSYS (CID_CLASS_AUDIO | CID_TYPE_SUBSYSTEM) ++// ++ ++#define CID_COMP_AI (TAG(0x01) | CTYP_AUDIO_NONE) ++#define CID_COMP_AO (TAG(0x03) | CTYP_AUDIO_NONE) ++#define CID_COMP_ADAI (TAG(0x04) | CTYP_AUDIO_NONE) ++ ++#define CID_COMP_SDAC (TAG(0x01) | CTYP_AUDIO_SINK) ++ ++#define CID_COMP_ADIGAI (TAG(0x01) | CTYP_AUDIO_DIGITIZER) ++#define CID_COMP_ADIGSPDIF (TAG(0x02) | CTYP_AUDIO_DIGITIZER) ++ ++#define CID_COMP_ARENDAO (TAG(0x01) | CTYP_AUDIO_RENDERER) ++#define CID_COMP_ARENDSPDIF (TAG(0x02) | CTYP_AUDIO_RENDERER) ++ ++#define CID_COMP_NOISESEQ (TAG(0x03) | CTYP_AUDIO_SOURCE) ++ ++#define CID_COMP_AENCAC3 (TAG(0x01) | CTYP_AUDIO_ENCODER) ++#define CID_COMP_AENCMPEG1 (TAG(0x02) | CTYP_AUDIO_ENCODER) ++#define CID_COMP_AENCAAC (TAG(0x03) | CTYP_AUDIO_ENCODER) ++#define CID_COMP_AENCG723 (TAG(0x04) | CTYP_AUDIO_ENCODER) ++#define CID_COMP_AENCG728 (TAG(0x05) | CTYP_AUDIO_ENCODER) ++#define CID_COMP_AENCWMA (TAG(0x06) | CTYP_AUDIO_ENCODER) ++ ++#define CID_COMP_ADECPROLOGIC (TAG(0x01) | CTYP_AUDIO_DECODER) ++#define CID_COMP_ADECAC3 (TAG(0x02) | CTYP_AUDIO_DECODER) ++#define CID_COMP_ADECMPEG1 (TAG(0x03) | CTYP_AUDIO_DECODER) ++#define CID_COMP_ADECMP3 (TAG(0x04) | CTYP_AUDIO_DECODER) ++#define CID_COMP_ADECAAC (TAG(0x05) | CTYP_AUDIO_DECODER) ++#define CID_COMP_ADECG723 (TAG(0x06) | CTYP_AUDIO_DECODER) ++#define CID_COMP_ADECG728 (TAG(0x07) | CTYP_AUDIO_DECODER) ++#define CID_COMP_ADECWMA (TAG(0x08) | CTYP_AUDIO_DECODER) ++#define CID_COMP_ADECTHRU (TAG(0x09) | CTYP_AUDIO_DECODER) ++#define CID_COMP_ADEC (TAG(0x0A) | CTYP_AUDIO_DECODER) ++ ++#define CID_COMP_ASPLIB (TAG(0x01) | CTYP_AUDIO_FILTER) ++#define CID_COMP_IIR (TAG(0x02) | CTYP_AUDIO_FILTER) ++#define CID_COMP_ASPEQ2 (TAG(0x03) | CTYP_AUDIO_FILTER) ++#define CID_COMP_ASPEQ5 (TAG(0x04) | CTYP_AUDIO_FILTER) ++#define CID_COMP_ASPBASSREDIR (TAG(0x05) | CTYP_AUDIO_FILTER) ++#define CID_COMP_ASPLAT2 (TAG(0x06) | CTYP_AUDIO_FILTER) ++#define CID_COMP_ASPPLUGIN (TAG(0x07) | CTYP_AUDIO_FILTER) ++#define CID_COMP_AMIXDTV (TAG(0x08) | CTYP_AUDIO_FILTER) ++#define CID_COMP_AMIXSIMPLE (TAG(0x09) | CTYP_AUDIO_FILTER) ++#define CID_COMP_AMIXSTB (TAG(0x0A) | CTYP_AUDIO_FILTER) ++#define CID_COMP_ASPEQ (TAG(0x0B) | CTYP_AUDIO_FILTER) ++#define CID_COMP_ATESTSIG (TAG(0x0C) | CTYP_AUDIO_FILTER) ++ ++#define CID_COMP_AUDSUBSYS (TAG(0x01) | CTYP_AUDIO_SUBSYS) ++#define CID_COMP_AUDSYSSTB (TAG(0x02) | CTYP_AUDIO_SUBSYS) ++#define CID_COMP_AUDSYSDVD (TAG(0x03) | CTYP_AUDIO_SUBSYS) ++ ++// ++// Graphics Class Types/Components ++// ++#define CTYP_GRAPHICS_RENDERER (CID_CLASS_GRAPHICS | CID_TYPE_SINK) ++// ++#define CID_COMP_WM (TAG(0x01) | CTYP_GRAPHICS_RENDERER) ++#define CID_COMP_WIDGET (TAG(0x02) | CTYP_GRAPHICS_RENDERER) ++#define CID_COMP_OM (TAG(0x03) | CTYP_GRAPHICS_RENDERER) ++#define CID_COMP_HTMLRENDER (TAG(0x04) | CTYP_GRAPHICS_RENDERER) ++#define CID_COMP_VRENDEIA708 (TAG(0x05) | CTYP_GRAPHICS_RENDERER) ++#define CID_COMP_VRENDEIA608 (TAG(0x06) | CTYP_GRAPHICS_RENDERER) ++// ++#define CTYP_GRAPHICS_DRAW (CID_CLASS_GRAPHICS | CID_TYPE_NONE) ++// ++#define CID_COMP_DRAW (TAG(0x10) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_DRAW_UT (TAG(0x11) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_DRAW_DE (TAG(0x12) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_DRAW_REF (TAG(0x13) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_DRAW_TMH (TAG(0x14) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_DRAW_TMT (TAG(0x15) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_DRAW_TMTH (TAG(0x16) | CTYP_GRAPHICS_DRAW) ++// ++#define CID_COMP_3D (TAG(0x30) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_JAWT (TAG(0x31) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_JINPUT (TAG(0x32) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_LWM (TAG(0x33) | CTYP_GRAPHICS_DRAW) ++#define CID_COMP_2D (TAG(0x34) | CTYP_GRAPHICS_DRAW) ++ ++ ++// ++// Bus Class Types/Components (busses connect hardware components together) ++// ++#define CTYP_BUS_NOTYPE (CID_CLASS_BUS | CID_TYPE_NONE) ++// ++#define CID_COMP_XIO (TAG(0x01) | CTYP_BUS_NOTYPE) ++#define CID_COMP_IIC (TAG(0x02) | CTYP_BUS_NOTYPE) ++#define CID_COMP_PCI (TAG(0x03) | CTYP_BUS_NOTYPE) ++#define CID_COMP_P1394 (TAG(0x04) | CTYP_BUS_NOTYPE) ++#define CID_COMP_ENET (TAG(0x05) | CTYP_BUS_NOTYPE) ++#define CID_COMP_ATA (TAG(0x06) | CTYP_BUS_NOTYPE) ++#define CID_COMP_CAN (TAG(0x07) | CTYP_BUS_NOTYPE) ++#define CID_COMP_UCGDMA (TAG(0x08) | CTYP_BUS_NOTYPE) ++#define CID_COMP_I2S (TAG(0x09) | CTYP_BUS_NOTYPE) ++#define CID_COMP_SPI (TAG(0x0A) | CTYP_BUS_NOTYPE) ++#define CID_COMP_PCM (TAG(0x0B) | CTYP_BUS_NOTYPE) ++#define CID_COMP_L3 (TAG(0x0C) | CTYP_BUS_NOTYPE) ++ ++// ++// Infrastructure Class Types/Components ++#define CTYP_INFRASTR_NOTYPE (CID_CLASS_INFRASTR | CID_TYPE_NONE) ++// ++#define CID_COMP_OSAL (TAG(0x01) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_MML (TAG(0x02) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_TSSA_DEFAULTS (TAG(0x03) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_RPC (TAG(0x04) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_THI (TAG(0x05) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_REGISTRY (TAG(0x06) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_TMMAN (TAG(0x07) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_LDT (TAG(0x08) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_CPUCONN (TAG(0x09) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_COMMQUE (TAG(0x0A) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_BSLMGR (TAG(0x0B) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_CR (TAG(0x0C) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_NODE (TAG(0x0D) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_COM (TAG(0x0E) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_UTIL (TAG(0x0F) | CTYP_INFRASTR_NOTYPE) ++#define CID_COMP_SGLIST (TAG(0x10) | CTYP_INFRASTR_NOTYPE) ++ ++//----------------------------------------------------------------------------- ++// Component Standard Error/Progress Status definitions (bits 11:0, 12 bits) ++// NOTE: These status codes are OR'd with the component identifier to create ++// component unique 32 bit status values. The component status values ++// should be defined in the header files where the APIs are defined. ++// ++#define CID_ERR_BITMASK 0xFFF // Component error AND bitmask ++#define CID_ERR_BITSHIFT 0 // Component error bit shift ++#define CID_GET_ERROR(compId) ((compId & CID_ERR_BITMASK) >> CID_ERR_BITSHIFT) ++// ++#define TM_ERR_COMPATIBILITY 0x001 // SW Interface compatibility ++#define TM_ERR_MAJOR_VERSION 0x002 // SW Major Version error ++#define TM_ERR_COMP_VERSION 0x003 // SW component version error ++#define TM_ERR_BAD_MODULE_ID 0x004 // SW - HW module ID error ++#define TM_ERR_BAD_UNIT_NUMBER 0x005 // Invalid device unit number ++#define TM_ERR_BAD_INSTANCE 0x006 // Bad input instance value ++#define TM_ERR_BAD_HANDLE 0x007 // Bad input handle ++#define TM_ERR_BAD_INDEX 0x008 // Bad input index ++#define TM_ERR_BAD_PARAMETER 0x009 // Invalid input parameter ++#define TM_ERR_NO_INSTANCES 0x00A // No instances available ++#define TM_ERR_NO_COMPONENT 0x00B // Component is not present ++#define TM_ERR_NO_RESOURCES 0x00C // Resource is not available ++#define TM_ERR_INSTANCE_IN_USE 0x00D // Instance is already in use ++#define TM_ERR_RESOURCE_OWNED 0x00E // Resource is already in use ++#define TM_ERR_RESOURCE_NOT_OWNED 0x00F // Caller does not own resource ++#define TM_ERR_INCONSISTENT_PARAMS 0x010 // Inconsistent input params ++#define TM_ERR_NOT_INITIALIZED 0x011 // Component is not initialized ++#define TM_ERR_NOT_ENABLED 0x012 // Component is not enabled ++#define TM_ERR_NOT_SUPPORTED 0x013 // Function is not supported ++#define TM_ERR_INIT_FAILED 0x014 // Initialization failed ++#define TM_ERR_BUSY 0x015 // Component is busy ++#define TM_ERR_NOT_BUSY 0x016 // Component is not busy ++#define TM_ERR_READ 0x017 // Read error ++#define TM_ERR_WRITE 0x018 // Write error ++#define TM_ERR_ERASE 0x019 // Erase error ++#define TM_ERR_LOCK 0x01A // Lock error ++#define TM_ERR_UNLOCK 0x01B // Unlock error ++#define TM_ERR_OUT_OF_MEMORY 0x01C // Memory allocation failed ++#define TM_ERR_BAD_VIRT_ADDRESS 0x01D // Bad virtual address ++#define TM_ERR_BAD_PHYS_ADDRESS 0x01E // Bad physical address ++#define TM_ERR_TIMEOUT 0x01F // Timeout error ++#define TM_ERR_OVERFLOW 0x020 // Data overflow/overrun error ++#define TM_ERR_FULL 0x021 // Queue (etc.) is full ++#define TM_ERR_EMPTY 0x022 // Queue (etc.) is empty ++#define TM_ERR_NOT_STARTED 0x023 // Component stream not started ++#define TM_ERR_ALREADY_STARTED 0x024 // Comp. stream already started ++#define TM_ERR_NOT_STOPPED 0x025 // Component stream not stopped ++#define TM_ERR_ALREADY_STOPPED 0x026 // Comp. stream already stopped ++#define TM_ERR_ALREADY_SETUP 0x027 // Component already setup ++#define TM_ERR_NULL_PARAMETER 0x028 // Null input parameter ++#define TM_ERR_NULL_DATAINFUNC 0x029 // Null data input function ++#define TM_ERR_NULL_DATAOUTFUNC 0x02A // Null data output function ++#define TM_ERR_NULL_CONTROLFUNC 0x02B // Null control function ++#define TM_ERR_NULL_COMPLETIONFUNC 0x02C // Null completion function ++#define TM_ERR_NULL_PROGRESSFUNC 0x02D // Null progress function ++#define TM_ERR_NULL_ERRORFUNC 0x02E // Null error handler function ++#define TM_ERR_NULL_MEMALLOCFUNC 0x02F // Null memory alloc function ++#define TM_ERR_NULL_MEMFREEFUNC 0x030 // Null memory free function ++#define TM_ERR_NULL_CONFIGFUNC 0x031 // Null configuration function ++#define TM_ERR_NULL_PARENT 0x032 // Null parent data ++#define TM_ERR_NULL_IODESC 0x033 // Null in/out descriptor ++#define TM_ERR_NULL_CTRLDESC 0x034 // Null control descriptor ++#define TM_ERR_UNSUPPORTED_DATACLASS 0x035 // Unsupported data class ++#define TM_ERR_UNSUPPORTED_DATATYPE 0x036 // Unsupported data type ++#define TM_ERR_UNSUPPORTED_DATASUBTYPE 0x037 // Unsupported data subtype ++#define TM_ERR_FORMAT 0x038 // Invalid/unsupported format ++#define TM_ERR_INPUT_DESC_FLAGS 0x039 // Bad input descriptor flags ++#define TM_ERR_OUTPUT_DESC_FLAGS 0x03A // Bad output descriptor flags ++#define TM_ERR_CAP_REQUIRED 0x03B // Capabilities required ??? ++#define TM_ERR_BAD_TMALFUNC_TABLE 0x03C // Bad TMAL function table ++#define TM_ERR_INVALID_CHANNEL_ID 0x03D // Invalid channel identifier ++#define TM_ERR_INVALID_COMMAND 0x03E // Invalid command/request ++#define TM_ERR_STREAM_MODE_CONFUSION 0x03F // Stream mode config conflict ++#define TM_ERR_UNDERRUN 0x040 // Data underflow/underrun ++#define TM_ERR_EMPTY_PACKET_RECVD 0x041 // Empty data packet received ++#define TM_ERR_OTHER_DATAINOUT_ERR 0x042 // Other data input/output err ++#define TM_ERR_STOP_REQUESTED 0x043 // Stop in progress ++#define TM_ERR_PIN_NOT_STARTED 0x044 // Pin not started ++#define TM_ERR_PIN_ALREADY_STARTED 0x045 // Pin already started ++#define TM_ERR_PIN_NOT_STOPPED 0x046 // Pin not stopped ++#define TM_ERR_PIN_ALREADY_STOPPED 0x047 // Pin already stopped ++#define TM_ERR_STOP_PIN_REQUESTED 0x048 // Stop of a single pin is in progress (obsolescent) ++#define TM_ERR_PAUSE_PIN_REQUESTED 0x048 // Stop of a single pin is in progress ++#define TM_ERR_ASSERTION 0x049 // Assertion failure ++#define TM_ERR_HIGHWAY_BANDWIDTH 0x04A // Highway bandwidth bus error ++#define TM_ERR_HW_RESET_FAILED 0x04B // Hardware reset failed ++#define TM_ERR_PIN_PAUSED 0x04C // Pin Paused ++ ++// Add new standard error/progress status codes here ++ ++#define TM_ERR_COMP_UNIQUE_START 0x800 // 0x800-0xDFF: Component unique ++ ++#define TM_ERR_CUSTOMER_START 0xC00 ++ ++// DVP Standard assert error code start offset ++// NOTE: This define should be added to the component's base error value and ++// standard error code(s) to define assert error codes. For example: ++// #define TMBSL_ERR_MGR_ASSERT_BAD_PARAM ++// (TMBSL_ERR_MGR_BASE + TM_ERR_ASSERT_START + TM_ERR_BAD_PARAMETER) ++// ++#define TM_ERR_ASSERT_START 0xE00 // 0xE00-0xEFF: Assert failures ++#define TM_ERR_ASSERT_LAST 0xEFF // Last assert error range value ++#define CID_IS_ASSERT_ERROR(compId) \ ++ ((CID_GET_ERROR(compId) >= TM_ERR_ASSERT_START) && \ ++ (CID_GET_ERROR(compId) <= TM_ERR_ASSERT_LAST)) ++ ++// DVP Standard fatal error code start offset ++// NOTE: This define should be added to the component's base error value and ++// standard error code(s) to define fatal error codes. For example: ++// #define TMML_ERR_FATAL_OUT_OF_MEMORY ++// (TMML_ERR_BASE + TM_ERR_FATAL_START + TM_ERR_OUT_OF_MEMORY) ++// ++#define TM_ERR_FATAL_START 0xF00 // 0xF00-0xFFF: Fatal failures ++#define TM_ERR_FATAL_LAST 0xFFF // Last fatal error range value ++#define CID_IS_FATAL_ERROR(compId) \ ++ ((CID_GET_ERROR(compId) >= TM_ERR_FATAL_START) && \ ++ (CID_GET_ERROR(compId) <= TM_ERR_FATAL_LAST)) ++ ++ ++//----------------------------------------------------------------------------- ++// DVP hardware module IDs ++// ++#define VMPG_100_MOD_ID 0x00000100 ++#define C1394_101_MOD_ID 0x00000101 ++#define FPBC_102_MOD_ID 0x00000102 ++#define JTAG_103_MOD_ID 0x00000103 ++#define EJTAG_104_MOD_ID 0x00000104 ++#define IIC_105_MOD_ID 0x00000105 ++#define SMCARD_106_MOD_ID 0x00000106 ++#define UART_107_MOD_ID 0x00000107 ++/* #define CLOCKS_108_MOD_ID 0x00000108 */ ++#define USB_109_MOD_ID 0x00000109 ++#define BOOT_10A_MOD_ID 0x0000010A ++#define MPBC_10B_MOD_ID 0x0000010B ++#define SSI_10C_MOD_ID 0x0000010C ++#define AI_10D_MOD_ID 0x0000010D ++#define VMSP_10E_MOD_ID 0x0000010E ++#define GPIO_10F_MOD_ID 0x0000010F ++#define SPDI_110_MOD_ID 0x00000110 ++#define AICP_111_MOD_ID 0x00000111 ++#define TPBC_112_MOD_ID 0x00000112 ++#define PCI_113_MOD_ID 0x00000113 ++#define MMI_114_MOD_ID 0x00000114 ++#define ORCA3_115_MOD_ID 0x00000115 ++#define DBG_116_MOD_ID 0x00000116 ++#define DE_117_MOD_ID 0x00000117 ++#define AICP_118_MOD_ID 0x00000118 ++#define MBS_119_MOD_ID 0x00000119 ++#define VIP_11A_MOD_ID 0x0000011A ++#define PIMI_11B_MOD_ID 0x0000011B ++#define PIB_11C_MOD_ID 0x0000011C ++#define PIC_11D_MOD_ID 0x0000011D ++#define TMDBG_11F_MOD_ID 0x0000011F ++#define AO_120_MOD_ID 0x00000120 ++#define SPDO_121_MOD_ID 0x00000121 ++#define FPIMI_122_MOD_ID 0x00000122 ++#define RESET_123_MOD_ID 0x00000123 ++#define NULL_124_MOD_ID 0x00000124 ++#define TSDMA_125_MOD_ID 0x00000125 ++#define GLBREG_126_MOD_ID 0x00000126 ++#define TMDBG_127_MOD_ID 0x00000127 ++#define GLBREG_128_MOD_ID 0x00000128 ++#define DMA_130_MOD_ID 0x00000130 ++#define IR_131_MOD_ID 0x00000131 ++#define GFX2D_131_MOD_ID 0x00000132 // TODO: Remove after code corrected ++#define GFX2D_132_MOD_ID 0x00000132 ++#define P1284_133_MOD_ID 0x00000133 ++#define QNM_134_MOD_ID 0x00000134 ++#define OSD_136_MOD_ID 0x00000136 ++#define MIX_137_MOD_ID 0x00000137 ++#define DENC_138_MOD_ID 0x00000138 ++#define SYN_13A_MOD_ID 0x0000013A ++#define CLOCKS_13E_MOD_ID 0x0000013E ++#define CONFIG_13F_MOD_ID 0x0000013F ++#define MIU_A04C_MOD_ID 0x0000A04C ++#define DISP_A04D_MOD_ID 0x0000A04D ++#define VCTRL_A04E_MOD_ID 0x0000A04E ++ ++ ++#define PR3930_2B10_MOD_ID 0x00002B10 ++#define PR3940_2B11_MOD_ID 0x00002B11 ++ ++#define TM3218_2B80_MOD_ID 0x00002B80 ++#define TM64_2b81_MOD_ID 0x00002B81 ++ ++#define QNM_A017_MOD_ID 0x0000A017 ++ ++// There is no HW module ID for TS IO ROUTER. We assign ++// a SW module ID to this module, because it is needed by Clock ++// device and HWAPI libraries. Use 010Eh for lower word ++// (for lack of better reason ! because IO Router is closely ++// associated with VMSP module) ++ ++#define IORT_1010E_MOD_ID 0x0001010E ++ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif // TMCOMPID_H //----------------- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\inc\tmFrontEnd.h ++ ++ ++/** ++ Copyright (C) 2007 NXP B.V., All Rights Reserved. ++ This source code and any compilation or derivative thereof is the proprietary ++ information of NXP B.V. and is confidential in nature. Under no circumstances ++ is this software to be exposed to or placed under an Open Source License of ++ any type without the expressed written permission of NXP B.V. ++ * ++ * \file tmFrontEnd.h ++ * %version: CFR_STB#0.4.1.7 % ++ * ++ * \date %date_modified% ++ * ++ * \brief Describe briefly the purpose of this file. ++ * ++ * REFERENCE DOCUMENTS : ++ * ++ * Detailed description may be added here. ++ * ++ * \section info Change Information ++ * ++ * \verbatim ++ Date Modified by CRPRNr TASKNr Maintenance description ++ -------------|-----------|-------|-------|----------------------------------- ++ 26-Mar-2008 | B.GUILLOT | 13122 | 23456 | Creation ++ -------------|-----------|-------|-------|----------------------------------- ++ \endverbatim ++ * ++*/ ++ ++ ++#ifndef TMFRONTEND_H ++#define TMFRONTEND_H ++ ++/*============================================================================*/ ++/* INCLUDE FILES */ ++/*============================================================================*/ ++ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++ ++/*============================================================================*/ ++/* ENUM OR TYPE DEFINITION */ ++/*============================================================================*/ ++#define TMFRONTEND_DVBT2MAXPLPNB 250 ++ ++/* standard*/ ++typedef enum _tmFrontEndStandard_t { ++ tmFrontEndStandardDVBT, ++ tmFrontEndStandardDVBS, ++ tmFrontEndStandardDVBC, ++ tmFrontEndStandardDSS, ++ tmFrontEndStandardBSD, ++ tmFrontEndStandardDVBH, ++ tmFrontEndStandardAnalogDVBT, ++ tmFrontEndStandardDVBS2, ++ tmFrontEndStandardDVBT2, ++ tmFrontEndStandardMax ++} tmFrontEndStandard_t, *ptmFrontEndStandard_t; ++ ++/* spectral inversion*/ ++typedef enum _tmFrontEndSpecInv_t { ++ tmFrontEndSpecInvAuto = 0, ++ tmFrontEndSpecInvOff, ++ tmFrontEndSpecInvOn, ++ tmFrontEndSpecInvMax ++} tmFrontEndSpecInv_t, *ptmFrontEndSpecInv_t; ++ ++/* modulation*/ ++typedef enum _tmFrontEndModulation_t { ++ tmFrontEndModulationAuto = 0, ++ tmFrontEndModulationBpsk, ++ tmFrontEndModulationQpsk, ++ tmFrontEndModulationQam4, ++ tmFrontEndModulationPsk8, ++ tmFrontEndModulationQam16, ++ tmFrontEndModulationQam32, ++ tmFrontEndModulationQam64, ++ tmFrontEndModulationQam128, ++ tmFrontEndModulationQam256, ++ tmFrontEndModulationQam512, ++ tmFrontEndModulationQam1024, ++ tmFrontEndModulation8VSB, ++ tmFrontEndModulation16VSB, ++ tmFrontEndModulationQam, ++ tmFrontEndModulationMax ++} tmFrontEndModulation_t, *ptmFrontEndModulation_t; ++ ++/* viterbi rate*/ ++typedef enum _tmFrontEndCodeRate_t { ++ tmFrontEndCodeRateAuto = 0, ++ tmFrontEndCodeRate_1_4, ++ tmFrontEndCodeRate_1_3, ++ tmFrontEndCodeRate_2_5, ++ tmFrontEndCodeRate_1_2, ++ tmFrontEndCodeRate_3_5, ++ tmFrontEndCodeRate_2_3, ++ tmFrontEndCodeRate_3_4, ++ tmFrontEndCodeRate_4_5, ++ tmFrontEndCodeRate_5_6, ++ tmFrontEndCodeRate_6_7, ++ tmFrontEndCodeRate_7_8, ++ tmFrontEndCodeRate_8_9, ++ tmFrontEndCodeRate_9_10, ++ tmFrontEndCodeRate_NotRelevant, ++ tmFrontEndCodeRateMax ++} tmFrontEndCodeRate_t, *ptmFrontEndCodeRate_t; ++ ++/* frequency offset*/ ++typedef enum _tmFrontEndRfOffset_t { ++ tmFrontEndRfOffsetAuto = 0, ++ tmFrontEndRfOffsetNull, ++ tmFrontEndRfOffsetPlus125, ++ tmFrontEndRfOffsetMinus125, ++ tmFrontEndRfOffsetPlus166, ++ tmFrontEndRfOffsetMinus166, ++ tmFrontEndRfOffsetPlus333, ++ tmFrontEndRfOffsetMinus333, ++ tmFrontEndRfOffsetPlus500, ++ tmFrontEndRfOffsetMinus500, ++ tmFrontEndRfOffsetMax ++} tmFrontEndRfOffset_t, *ptmFrontEndRfOffset_t; ++ ++/* frequency offset*/ ++typedef enum _tmFrontEndRfOffsetMode_t { ++ tmFrontEndRfOffsetModeAuto, ++ tmFrontEndRfOffsetModeManual, ++ tmFrontEndRfOffsetModeMax ++} tmFrontEndRfOffsetMode_t, *ptmFrontEndRfOffsetMode_t; ++ ++/* guard interval*/ ++typedef enum _tmFrontEndGI_t { ++ tmFrontEndGIAuto = 0, ++ tmFrontEndGI_1_32, ++ tmFrontEndGI_1_16, ++ tmFrontEndGI_1_8, ++ tmFrontEndGI_1_4, ++ tmFrontEndGI_1_128, ++ tmFrontEndGI_19_128, ++ tmFrontEndGI_19_256, ++ tmFrontEndGIMax ++} tmFrontEndGI_t, *ptmFrontEndGI_t; ++ ++/* fast Fourrier transform size*/ ++typedef enum _tmFrontEndFft_t { ++ tmFrontEndFftAuto = 0, ++ tmFrontEndFft2K, ++ tmFrontEndFft8K, ++ tmFrontEndFft4K, ++ tmFrontEndFft16K, ++ tmFrontEndFft32K, ++ tmFrontEndFftMax ++} tmFrontEndFft_t, *ptmFrontEndFft_t; ++ ++/* hierarchy*/ ++typedef enum _tmFrontEndHier_t { ++ tmFrontEndHierAuto = 0, ++ tmFrontEndHierNo, ++ tmFrontEndHierAlpha1, ++ tmFrontEndHierAlpha2, ++ tmFrontEndHierAlpha4, ++ tmFrontEndHierMax ++} tmFrontEndHier_t, *ptmFrontEndHier_t; ++ ++/* priority*/ ++typedef enum _tmFrontEndPrior_t { ++ tmFrontEndPriorAuto = 0, ++ tmFrontEndPriorHigh, ++ tmFrontEndPriorLow, ++ tmFrontEndPriorMax ++} tmFrontEndPrior_t, *ptmFrontEndPrior_t; ++ ++/* roll off */ ++typedef enum _tmFrontEndRollOff_t { ++ tmFrontEndRollOffAuto = 0, ++ tmFrontEndRollOff_0_15, ++ tmFrontEndRollOff_0_20, ++ tmFrontEndRollOff_0_25, ++ tmFrontEndRollOff_0_35, ++ tmFrontEndRollOffMax ++} tmFrontEndRollOff_t, *ptmFrontEndRollOff_t; ++ ++/* LNB polarity */ ++typedef enum _tmFrontEndLNBPolarity_t { ++ tmFrontEndLNBPolarityAuto = 0, ++ tmFrontEndLNBPolarityHigh, ++ tmFrontEndLNBPolarityLow, ++ tmFrontEndLNBPolarityMax ++} tmFrontEndLNBPolarity_t, *ptmFrontEndLNBPolarity_t; ++ ++/* continuous tone */ ++typedef enum _tmFrontEndContinuousTone_t { ++ tmFrontEndContinuousToneAuto = 0, ++ tmFrontEndContinuousToneOff, ++ tmFrontEndContinuousTone22KHz, ++ tmFrontEndContinuousToneMax ++} tmFrontEndContinuousTone_t, *ptmFrontEndContinuousTone_t; ++ ++typedef enum _tmFrontEndChannelType_t ++{ ++ tmFrontEndChannelTypeNone = 0x00, /* No detection */ ++ tmFrontEndChannelTypeDigital = 0x01, /* Digital channel */ ++ tmFrontEndChannelTypeAnalog = 0x02, /* Analog channel */ ++ tmFrontEndChannelTypeUnknown = 0x20 /* unknown channel type */ ++} tmFrontEndChannelType_t; ++ ++typedef enum _tmFrontEndChannelConfidence_t ++{ ++ tmFrontEndConfidenceNotAvailable, ++ tmFrontEndConfidenceNull, ++ tmFrontEndConfidenceLow, ++ tmFrontEndConfidenceMedium, ++ tmFrontEndConfidenceHigh ++} tmFrontEndConfidence_t; ++ ++typedef enum _tmFrontEndDVBT2PLPType_t ++{ ++ tmFrontEndDVBT2PLPTypeAuto, ++ tmFrontEndDVBT2PLPTypeCommon, ++ tmFrontEndDVBT2PLPType1, ++ tmFrontEndDVBT2PLPType2, ++ tmFrontEndDVBT2PLPTypeMax ++} tmFrontEndDVBT2PLPType_t; ++ ++typedef enum _tmFrontEndDVBT2PLPPayloadType_t ++{ ++ tmFrontEndDVBT2PLPPayloadTypeAuto, ++ tmFrontEndDVBT2PLPPayloadTypeGFPS, ++ tmFrontEndDVBT2PLPPayloadTypeGCS, ++ tmFrontEndDVBT2PLPPayloadTypeGSE, ++ tmFrontEndDVBT2PLPPayloadTypeTS, ++ tmFrontEndDVBT2PLPPayloadTypeMax ++} tmFrontEndDVBT2PLPPayloadType_t; ++ ++typedef enum _tmFrontEndRotationState_t ++{ ++ tmFrontEndRotationStateAuto, ++ tmFrontEndRotationStateOn, ++ tmFrontEndRotationStateOff, ++ tmFrontEndRotationStateMax ++} tmFrontEndRotationState; ++ ++typedef enum _tmFrontEndDVBT2FECType_t ++{ ++ tmFrontEndDVBT2FECTypeAuto, ++ tmFrontEndDVBT2FECType16K, ++ tmFrontEndDVBT2FECType64K, ++ tmFrontEndDVBT2FECTypeMax ++} tmFrontEndDVBT2FECType_t; ++ ++typedef enum _tmFrontEndDVBT2InputType_t ++{ ++ tmFrontEndDVBT2InputTypeAuto, ++ tmFrontEndDVBT2InputTypeSISO, ++ tmFrontEndDVBT2InputTypeMISO, ++ tmFrontEndDVBT2InputTypeMax ++} tmFrontEndDVBT2InputType_t; ++ ++typedef enum _tmFrontEndFECMode_t ++{ ++ tmFrontEndFECModeUnknown = 0, ++ tmFrontEndFECModeAnnexA, ++ tmFrontEndFECModeAnnexB, ++ tmFrontEndFECModeAnnexC, ++ tmFrontEndFECModeMax ++} tmFrontEndFECMode_t; ++ ++typedef struct _tmFrontEndFracNb8_t ++{ ++ Int8 lInteger; ++ UInt8 uDivider; ++}tmFrontEndFracNb8_t; ++ ++typedef struct _tmFrontEndFracNb16_t ++{ ++ Int16 lInteger; ++ UInt16 uDivider; ++}tmFrontEndFracNb16_t; ++ ++typedef struct _tmFrontEndFracNb32_t ++{ ++ Int32 lInteger; ++ UInt32 uDivider; ++}tmFrontEndFracNb32_t; ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* TMFRONTEND_H */ ++/*============================================================================*/ ++/* END OF FILE */ ++/*============================================================================*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\inc\tmUnitParams.h ++ ++ ++/** ++ Copyright (C) 2007 NXP B.V., All Rights Reserved. ++ This source code and any compilation or derivative thereof is the proprietary ++ information of NXP B.V. and is confidential in nature. Under no circumstances ++ is this software to be exposed to or placed under an Open Source License of ++ any type without the expressed written permission of NXP B.V. ++ * ++ * \file tmUnitParams.h ++ * %version: 2 % ++ * ++ * \date %date_modified% ++ * ++ * \brief Describe briefly the purpose of this file. ++ * ++ * REFERENCE DOCUMENTS : ++ * ++ * Detailed description may be added here. ++ * ++ * \section info Change Information ++ * ++ * \verbatim ++ Date Modified by CRPRNr TASKNr Maintenance description ++ -------------|-----------|-------|-------|----------------------------------- ++ 26-Mar-2008 | B.GUILLOT | 13122 | 23456 | Creation ++ -------------|-----------|-------|-------|----------------------------------- ++ \endverbatim ++ * ++*/ ++ ++ ++#ifndef TMUNITPARAMS_H ++#define TMUNITPARAMS_H ++ ++/*============================================================================*/ ++/* INCLUDE FILES */ ++/*============================================================================*/ ++ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++ ++/*============================================================================*/ ++/* ENUM OR TYPE DEFINITION */ ++/*============================================================================*/ ++ ++ ++/******************************************************************************/ ++/** \brief "These macros map to tmUnitSelect_t variables parts" ++* ++******************************************************************************/ ++ ++#define UNIT_VALID(_tUnIt) (((_tUnIt)&0x80000000)==0) ++ ++#define UNIT_PATH_INDEX_MASK (0x0000001F) ++#define UNIT_PATH_INDEX_POS (0) ++ ++#define UNIT_PATH_TYPE_MASK (0x000003E0) ++#define UNIT_PATH_TYPE_POS (5) ++ ++#define UNIT_PATH_CONFIG_MASK (0x0003FC00) ++#define UNIT_PATH_CONFIG_POS (10) ++ ++#define UNIT_SYSTEM_INDEX_MASK (0x007C0000) ++#define UNIT_SYSTEM_INDEX_POS (18) ++ ++#define UNIT_SYSTEM_CONFIG_MASK (0x7F800000) ++#define UNIT_SYSTEM_CONFIG_POS (23) ++ ++ ++ ++ ++#define UNIT_PATH_INDEX_GET(_tUnIt) ((_tUnIt)&UNIT_PATH_INDEX_MASK) ++#define UNIT_PATH_INDEX_VAL(_val) (((_val)<> UNIT_PATH_TYPE_POS) ++#define UNIT_PATH_TYPE_VAL(_val) (((_val)<> UNIT_PATH_CONFIG_POS) ++#define UNIT_PATH_CONFIG_VAL(_val) (((_val)<> UNIT_SYSTEM_INDEX_POS) ++#define UNIT_SYSTEM_INDEX_VAL(_val) (((_val)<> UNIT_SYSTEM_CONFIG_POS) ++#define UNIT_SYSTEM_CONFIG_VAL(_val) (((_val)< ", __FUNCTION__, __LINE__ ); \ ++ } \ ++ P_DBGPRINTEx(_level, _format, __VA_ARGS__); \ ++ } \ ++} ++*/ ++#else ++//#define tmDBGPRINTEx(_level, _format, ...) ++#endif ++ ++#define tmASSERTExTR(_retVar, _expr, _strings) ++/* ++{ ++ if((_retVar) != (_expr)) ++ { ++ tmDBGPRINTEx _strings ; ++ return _retVar; ++ } ++} ++*/ ++ ++#define tmASSERTExT(_retVar, _expr, _strings) ++/*{ \ ++ if((_retVar) != (_expr)) \ ++ { \ ++ tmDBGPRINTEx _strings ; \ ++ } \ ++} ++*/ ++/*============================================================================*/ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* TMBSLFRONTENDTYPES_H */ ++/*============================================================================*/ ++/* END OF FILE */ ++/*============================================================================*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmbslTDA182I2\inc\tmbslTDA18272.h ++ ++ ++/** ++Copyright (C) 2008 NXP B.V., All Rights Reserved. ++This source code and any compilation or derivative thereof is the proprietary ++information of NXP B.V. and is confidential in nature. Under no circumstances ++is this software to be exposed to or placed under an Open Source License of ++any type without the expressed written permission of NXP B.V. ++* ++* \file tmbslTDA18272.h ++* %version: 21 % ++* ++* \date %date_modified% ++* ++* \brief Describe briefly the purpose of this file. ++* ++* REFERENCE DOCUMENTS : ++* ++* Detailed description may be added here. ++* ++* \section info Change Information ++* ++* \verbatim ++Date Modified by CRPRNr TASKNr Maintenance description ++-------------|-----------|-------|-------|----------------------------------- ++| | | | ++-------------|-----------|-------|-------|----------------------------------- ++| | | | ++-------------|-----------|-------|-------|----------------------------------- ++\endverbatim ++* ++*/ ++ ++#ifndef _TMBSL_TDA18272_H ++#define _TMBSL_TDA18272_H ++ ++/*------------------------------------------------------------------------------*/ ++/* Standard include files: */ ++/*------------------------------------------------------------------------------*/ ++ ++/*------------------------------------------------------------------------------*/ ++/* Project include files: */ ++/*------------------------------------------------------------------------------*/ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++ /*------------------------------------------------------------------------------*/ ++ /* Types and defines: */ ++ /*------------------------------------------------------------------------------*/ ++ ++ /* SW Error codes */ ++#define TDA182I2_ERR_BASE (CID_COMP_TUNER | CID_LAYER_BSL) ++#define TDA182I2_ERR_COMP (CID_COMP_TUNER | CID_LAYER_BSL | TM_ERR_COMP_UNIQUE_START) ++ ++#define TDA182I2_ERR_BAD_UNIT_NUMBER (TDA182I2_ERR_BASE + TM_ERR_BAD_UNIT_NUMBER) ++#define TDA182I2_ERR_NOT_INITIALIZED (TDA182I2_ERR_BASE + TM_ERR_NOT_INITIALIZED) ++#define TDA182I2_ERR_INIT_FAILED (TDA182I2_ERR_BASE + TM_ERR_INIT_FAILED) ++#define TDA182I2_ERR_BAD_PARAMETER (TDA182I2_ERR_BASE + TM_ERR_BAD_PARAMETER) ++#define TDA182I2_ERR_NOT_SUPPORTED (TDA182I2_ERR_BASE + TM_ERR_NOT_SUPPORTED) ++#define TDA182I2_ERR_HW_FAILED (TDA182I2_ERR_COMP + 0x0001) ++#define TDA182I2_ERR_NOT_READY (TDA182I2_ERR_COMP + 0x0002) ++#define TDA182I2_ERR_BAD_VERSION (TDA182I2_ERR_COMP + 0x0003) ++ ++ ++ typedef enum _tmTDA182I2PowerState_t { ++ tmTDA182I2_PowerNormalMode = 0, /* Device normal mode */ ++ tmTDA182I2_PowerStandbyWithLNAOnAndWithXtalOnAndSynthe, /* Device standby mode with LNA and Xtal Output and Synthe */ ++ tmTDA182I2_PowerStandbyWithLNAOnAndWithXtalOn, /* Device standby mode with LNA and Xtal Output */ ++ tmTDA182I2_PowerStandbyWithXtalOn, /* Device standby mode with Xtal Output */ ++ tmTDA182I2_PowerStandby, /* Device standby mode */ ++ tmTDA182I2_PowerMax ++ } tmTDA182I2PowerState_t, *ptmTDA182I2PowerState_t; ++ ++ typedef enum _tmTDA182I2StandardMode_t { ++ tmTDA182I2_DVBT_6MHz = 0, /* Digital TV DVB-T 6MHz */ ++ tmTDA182I2_DVBT_7MHz, /* Digital TV DVB-T 7MHz */ ++ tmTDA182I2_DVBT_8MHz, /* Digital TV DVB-T 8MHz */ ++ tmTDA182I2_QAM_6MHz, /* Digital TV QAM 6MHz */ ++ tmTDA182I2_QAM_8MHz, /* Digital TV QAM 8MHz */ ++ tmTDA182I2_ISDBT_6MHz, /* Digital TV ISDBT 6MHz */ ++ tmTDA182I2_ATSC_6MHz, /* Digital TV ATSC 6MHz */ ++ tmTDA182I2_DMBT_8MHz, /* Digital TV DMB-T 8MHz */ ++ tmTDA182I2_ANLG_MN, /* Analog TV M/N */ ++ tmTDA182I2_ANLG_B, /* Analog TV B */ ++ tmTDA182I2_ANLG_GH, /* Analog TV G/H */ ++ tmTDA182I2_ANLG_I, /* Analog TV I */ ++ tmTDA182I2_ANLG_DK, /* Analog TV D/K */ ++ tmTDA182I2_ANLG_L, /* Analog TV L */ ++ tmTDA182I2_ANLG_LL, /* Analog TV L' */ ++ tmTDA182I2_FM_Radio, /* Analog FM Radio */ ++ tmTDA182I2_Scanning, /* analog preset blind Scanning */ ++ tmTDA182I2_ScanXpress, /* ScanXpress */ ++ tmTDA182I2_StandardMode_Max ++ } tmTDA182I2StandardMode_t, *ptmTDA182I2StandardMode_t; ++ ++ typedef enum _tmTDA182I2LPF_t { ++ tmTDA182I2_LPF_6MHz = 0, /* 6MHz LPFc */ ++ tmTDA182I2_LPF_7MHz, /* 7MHz LPFc */ ++ tmTDA182I2_LPF_8MHz, /* 8MHz LPFc */ ++ tmTDA182I2_LPF_9MHz, /* 9MHz LPFc */ ++ tmTDA182I2_LPF_1_5MHz, /* 1.5MHz LPFc */ ++ tmTDA182I2_LPF_Max ++ } tmTDA182I2LPF_t, *ptmTDA182I2LPF_t; ++ ++ typedef enum _tmTDA182I2LPFOffset_t { ++ tmTDA182I2_LPFOffset_0pc = 0, /* LPFc 0% */ ++ tmTDA182I2_LPFOffset_min_4pc, /* LPFc -4% */ ++ tmTDA182I2_LPFOffset_min_8pc, /* LPFc -8% */ ++ tmTDA182I2_LPFOffset_min_12pc, /* LPFc -12% */ ++ tmTDA182I2_LPFOffset_Max ++ } tmTDA182I2LPFOffset_t, *ptmTDA182I2LPFOffset_t; ++ ++ typedef enum _tmTDA182I2IF_AGC_Gain_t { ++ tmTDA182I2_IF_AGC_Gain_2Vpp_0_30dB = 0, /* 2Vpp 0 - 30dB IF AGC Gain */ ++ tmTDA182I2_IF_AGC_Gain_1_25Vpp_min_4_26dB, /* 1.25Vpp -4 - 26dB IF AGC Gain */ ++ tmTDA182I2_IF_AGC_Gain_1Vpp_min_6_24dB, /* 1Vpp -6 - 24dB IF AGC Gain */ ++ tmTDA182I2_IF_AGC_Gain_0_8Vpp_min_8_22dB, /* 0.8Vpp -8 - 22dB IF AGC Gain */ ++ tmTDA182I2_IF_AGC_Gain_0_85Vpp_min_7_5_22_5dB, /* 0.85Vpp -7.5 - 22.5dB IF AGC Gain */ ++ tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, /* 0.7Vpp -9 - 21dB IF AGC Gain */ ++ tmTDA182I2_IF_AGC_Gain_0_6Vpp_min_10_3_19_7dB, /* 0.6Vpp -10.3 - 19.7dB IF AGC Gain */ ++ tmTDA182I2_IF_AGC_Gain_0_5Vpp_min_12_18dB, /* 0.5Vpp -12 - 18dB IF AGC Gain */ ++ tmTDA182I2_IF_AGC_Gain_Max ++ } tmTDA182I2IF_AGC_Gain_t, *ptmTDA182I2IF_AGC_Gain_t; ++ ++ typedef enum _tmTDA182I2IF_Notch_t { ++ tmTDA182I2_IF_Notch_Disabled = 0, /* IF Notch Enabled */ ++ tmTDA182I2_IF_Notch_Enabled, /* IF Notch Disabled */ ++ tmTDA182I2_IF_Notch_Max ++ } tmTDA182I2IF_Notch_t, *ptmTDA182I2IF_Notch_t; ++ ++ typedef enum _tmTDA182I2IF_HPF_t { ++ tmTDA182I2_IF_HPF_Disabled = 0, /* IF HPF 0.4MHz */ ++ tmTDA182I2_IF_HPF_0_4MHz, /* IF HPF 0.4MHz */ ++ tmTDA182I2_IF_HPF_0_85MHz, /* IF HPF 0.85MHz */ ++ tmTDA182I2_IF_HPF_1MHz, /* IF HPF 1MHz */ ++ tmTDA182I2_IF_HPF_1_5MHz, /* IF HPF 1.5MHz */ ++ tmTDA182I2_IF_HPF_Max ++ } tmTDA182I2IF_HPF_t, *ptmTDA182I2IF_HPF_t; ++ ++ typedef enum _tmTDA182I2DC_Notch_t { ++ tmTDA182I2_DC_Notch_Disabled = 0, /* IF Notch Enabled */ ++ tmTDA182I2_DC_Notch_Enabled, /* IF Notch Disabled */ ++ tmTDA182I2_DC_Notch_Max ++ } tmTDA182I2DC_Notch_t, *ptmTDA182I2DC_Notch_t; ++ ++ typedef enum _tmTDA182I2AGC1_LNA_TOP_t { ++ tmTDA182I2_AGC1_LNA_TOP_d95_u89dBuV = 0, /* AGC1 LNA TOP down 95 up 89 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u93dBuV_do_not_use, /* AGC1 LNA TOP down 95 up 93 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u94dBuV_do_not_use, /* AGC1 LNA TOP down 95 up 94 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d95_u95dBuV_do_not_use, /* AGC1 LNA TOP down 95 up 95 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d99_u89dBuV, /* AGC1 LNA TOP down 99 up 89 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d99_u93dBuV, /* AGC1 LNA TOP down 95 up 93 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d99_u94dBuV, /* AGC1 LNA TOP down 99 up 94 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d99_u95dBuV, /* AGC1 LNA TOP down 99 up 95 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d99_u9SdBuV, /* AGC1 LNA TOP down 99 up 95 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d100_u93dBuV, /* AGC1 LNA TOP down 100 up 93 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d100_u94dBuV, /* AGC1 LNA TOP down 100 up 94 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d100_u95dBuV, /* AGC1 LNA TOP down 100 up 95 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d100_u9SdBuV, /* AGC1 LNA TOP down 100 up 95 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d101_u93dBuV, /* AGC1 LNA TOP down 101 up 93 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d101_u94dBuV, /* AGC1 LNA TOP down 101 up 94 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d101_u95dBuV, /* AGC1 LNA TOP down 101 up 95 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_d101_u9SdBuV, /* AGC1 LNA TOP down 101 up 95 dBuV */ ++ tmTDA182I2_AGC1_LNA_TOP_Max ++ } tmTDA182I2AGC1_LNA_TOP_t, *ptmTDA182I2AGC1_LNA_TOP_t; ++ ++ typedef enum _tmTDA182I2AGC2_RF_Attenuator_TOP_t { ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d89_u81dBuV = 0, /* AGC2 RF Attenuator TOP down 89 up 81 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d91_u83dBuV, /* AGC2 RF Attenuator TOP down 91 up 83 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d93_u85dBuV, /* AGC2 RF Attenuator TOP down 93 up 85 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d95_u87dBuV, /* AGC2 RF Attenuator TOP down 95 up 87 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d88_u88dBuV, /* AGC2 RF Attenuator TOP down 88 up 81 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d89_u82dBuV, /* AGC2 RF Attenuator TOP down 89 up 82 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u83dBuV, /* AGC2 RF Attenuator TOP down 90 up 83 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d91_u84dBuV, /* AGC2 RF Attenuator TOP down 91 up 84 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d92_u85dBuV, /* AGC2 RF Attenuator TOP down 92 up 85 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d93_u86dBuV, /* AGC2 RF Attenuator TOP down 93 up 86 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d94_u87dBuV, /* AGC2 RF Attenuator TOP down 94 up 87 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d95_u88dBuV, /* AGC2 RF Attenuator TOP down 95 up 88 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d87_u81dBuV, /* AGC2 RF Attenuator TOP down 87 up 81 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d88_u82dBuV, /* AGC2 RF Attenuator TOP down 88 up 82 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d89_u83dBuV, /* AGC2 RF Attenuator TOP down 89 up 83 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d90_u84dBuV, /* AGC2 RF Attenuator TOP down 90 up 84 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d91_u85dBuV, /* AGC2 RF Attenuator TOP down 91 up 85 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d92_u86dBuV, /* AGC2 RF Attenuator TOP down 92 up 86 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d93_u87dBuV, /* AGC2 RF Attenuator TOP down 93 up 87 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d94_u88dBuV, /* AGC2 RF Attenuator TOP down 94 up 88 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_d95_u89dBuV, /* AGC2 RF Attenuator TOP down 95 up 89 dBuV */ ++ tmTDA182I2_AGC2_RF_Attenuator_TOP_Max ++ } tmTDA182I2AGC2_RF_Attenuator_TOP_t, *ptmTDA182I2AGC2_RF_Attenuator_TOP_t; ++ ++ typedef enum _tmTDA182I2AGC3_RF_AGC_TOP_t { ++ tmTDA182I2_AGC3_RF_AGC_TOP_94dBuV = 0, /* AGC3 RF AGC TOP 94 dBuV */ ++ tmTDA182I2_AGC3_RF_AGC_TOP_96dBuV, /* AGC3 RF AGC TOP 96 dBuV */ ++ tmTDA182I2_AGC3_RF_AGC_TOP_98dBuV, /* AGC3 RF AGC TOP 98 dBuV */ ++ tmTDA182I2_AGC3_RF_AGC_TOP_100dBuV, /* AGC3 RF AGC TOP 100 dBuV */ ++ tmTDA182I2_AGC3_RF_AGC_TOP_102dBuV, /* AGC3 RF AGC TOP 102 dBuV */ ++ tmTDA182I2_AGC3_RF_AGC_TOP_104dBuV, /* AGC3 RF AGC TOP 104 dBuV */ ++ tmTDA182I2_AGC3_RF_AGC_TOP_106dBuV, /* AGC3 RF AGC TOP 106 dBuV */ ++ tmTDA182I2_AGC3_RF_AGC_TOP_107dBuV, /* AGC3 RF AGC TOP 107 dBuV */ ++ tmTDA182I2_AGC3_RF_AGC_TOP_Max ++ } tmTDA182I2AGC3_RF_AGC_TOP_t, *ptmTDA182I2AGC3_RF_AGC_TOP_t; ++ ++#define tmTDA182I2_AGC3_RF_AGC_TOP_FREQ_LIM 291000000 ++ ++ typedef enum _tmTDA182I2AGC4_IR_Mixer_TOP_t { ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u99dBuV = 0, /* AGC4 IR_Mixer TOP down 105 up 99 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u100dBuV, /* AGC4 IR_Mixer TOP down 105 up 100 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d105_u101dBuV, /* AGC4 IR_Mixer TOP down 105 up 101 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d107_u101dBuV, /* AGC4 IR_Mixer TOP down 107 up 101 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d107_u102dBuV, /* AGC4 IR_Mixer TOP down 107 up 102 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d107_u103dBuV, /* AGC4 IR_Mixer TOP down 107 up 103 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d108_u103dBuV, /* AGC4 IR_Mixer TOP down 108 up 103 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d109_u103dBuV, /* AGC4 IR_Mixer TOP down 109 up 103 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d109_u104dBuV, /* AGC4 IR_Mixer TOP down 109 up 104 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d109_u105dBuV, /* AGC4 IR_Mixer TOP down 109 up 105 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u104dBuV, /* AGC4 IR_Mixer TOP down 110 up 104 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u105dBuV, /* AGC4 IR_Mixer TOP down 110 up 105 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d110_u106dBuV, /* AGC4 IR_Mixer TOP down 110 up 106 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d112_u106dBuV, /* AGC4 IR_Mixer TOP down 112 up 106 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d112_u107dBuV, /* AGC4 IR_Mixer TOP down 112 up 107 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_d112_u108dBuV, /* AGC4 IR_Mixer TOP down 112 up 108 dBuV */ ++ tmTDA182I2_AGC4_IR_Mixer_TOP_Max ++ } tmTDA182I2AGC4_IR_Mixer_TOP_t, *ptmTDA182I2AGC4_IR_Mixer_TOP_t; ++ ++ typedef enum _tmTDA182I2AGC5_IF_AGC_TOP_t { ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u99dBuV = 0, /* AGC5 IF AGC TOP down 105 up 99 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u100dBuV, /* AGC5 IF AGC TOP down 105 up 100 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d105_u101dBuV, /* AGC5 IF AGC TOP down 105 up 101 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d107_u101dBuV, /* AGC5 IF AGC TOP down 107 up 101 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d107_u102dBuV, /* AGC5 IF AGC TOP down 107 up 102 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d107_u103dBuV, /* AGC5 IF AGC TOP down 107 up 103 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d108_u103dBuV, /* AGC5 IF AGC TOP down 108 up 103 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d109_u103dBuV, /* AGC5 IF AGC TOP down 109 up 103 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d109_u104dBuV, /* AGC5 IF AGC TOP down 109 up 104 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d109_u105dBuV, /* AGC5 IF AGC TOP down 109 up 105 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u104dBuV, /* AGC5 IF AGC TOP down 108 up 104 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u105dBuV, /* AGC5 IF AGC TOP down 108 up 105 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d110_u106dBuV, /* AGC5 IF AGC TOP down 108 up 106 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d112_u106dBuV, /* AGC5 IF AGC TOP down 108 up 106 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d112_u107dBuV, /* AGC5 IF AGC TOP down 108 up 107 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_d112_u108dBuV, /* AGC5 IF AGC TOP down 108 up 108 dBuV */ ++ tmTDA182I2_AGC5_IF_AGC_TOP_Max ++ } tmTDA182I2AGC5_IF_AGC_TOP_t, *ptmTDA182I2AGC5_IF_AGC_TOP_t; ++ ++ typedef enum _tmTDA182I2AGC5_Detector_HPF_t { ++ tmTDA182I2_AGC5_Detector_HPF_Disabled = 0, /* AGC5_Detector_HPF Enabled */ ++ tmTDA182I2_AGC5_Detector_HPF_Enabled, /* IF Notch Disabled */ ++ tmTDA182I2_AGC5_Detector_HPF_Max ++ } tmTDA182I2AGC5_Detector_HPF_t, *ptmTDA182I2AGC5_Detector_HPFh_t; ++ ++ typedef enum _tmTDA182I2AGC3_Adapt_t { ++ tmTDA182I2_AGC3_Adapt_Enabled = 0, /* AGC3_Adapt Enabled */ ++ tmTDA182I2_AGC3_Adapt_Disabled, /* AGC3_Adapt Disabled */ ++ tmTDA182I2_AGC3_Adapt_Max ++ } tmTDA182I2AGC3_Adapt_t, *ptmTDA182I2AGC3_Adapt_t; ++ ++ typedef enum _tmTDA182I2AGC3_Adapt_TOP_t { ++ tmTDA182I2_AGC3_Adapt_TOP_0_Step = 0, /* same level as AGC3 TOP */ ++ tmTDA182I2_AGC3_Adapt_TOP_1_Step, /* 1 level below AGC3 TOP */ ++ tmTDA182I2_AGC3_Adapt_TOP_2_Step, /* 2 level below AGC3 TOP */ ++ tmTDA182I2_AGC3_Adapt_TOP_3_Step, /* 3 level below AGC3 TOP */ ++ } tmTDA182I2AGC3_Adapt_TOP_t, *ptmTDA182I2AGC3_Adapt_TOP_t; ++ ++ typedef enum _tmTDA182I2AGC5_Atten_3dB_t { ++ tmTDA182I2_AGC5_Atten_3dB_Disabled = 0, /* AGC5_Atten_3dB Disabled */ ++ tmTDA182I2_AGC5_Atten_3dB_Enabled, /* AGC5_Atten_3dB Enabled */ ++ tmTDA182I2_AGC5_Atten_3dB_Max ++ } tmTDA182I2AGC5_Atten_3dB_t, *ptmTDA182I2AGC5_Atten_3dB_t; ++ ++ typedef enum _tmTDA182I2H3H5_VHF_Filter6_t { ++ tmTDA182I2_H3H5_VHF_Filter6_Disabled = 0, /* H3H5_VHF_Filter6 Disabled */ ++ tmTDA182I2_H3H5_VHF_Filter6_Enabled, /* H3H5_VHF_Filter6 Enabled */ ++ tmTDA182I2_H3H5_VHF_Filter6_Max ++ } tmTDA182I2H3H5_VHF_Filter6_t, *ptmTDA182I2H3H5_VHF_Filter6_t; ++ ++ typedef enum _tmTDA182I2_LPF_Gain_t { ++ tmTDA182I2_LPF_Gain_Unknown = 0, /* LPF_Gain Unknown */ ++ tmTDA182I2_LPF_Gain_Frozen, /* LPF_Gain Frozen */ ++ tmTDA182I2_LPF_Gain_Free /* LPF_Gain Free */ ++ } tmTDA182I2_LPF_Gain_t, *ptmTDA182I2_LPF_Gain_t; ++ ++ typedef struct _tmTDA182I2StdCoefficients ++ { ++ UInt32 IF; ++ Int32 CF_Offset; ++ tmTDA182I2LPF_t LPF; ++ tmTDA182I2LPFOffset_t LPF_Offset; ++ tmTDA182I2IF_AGC_Gain_t IF_Gain; ++ tmTDA182I2IF_Notch_t IF_Notch; ++ tmTDA182I2IF_HPF_t IF_HPF; ++ tmTDA182I2DC_Notch_t DC_Notch; ++ tmTDA182I2AGC1_LNA_TOP_t AGC1_LNA_TOP; ++ tmTDA182I2AGC2_RF_Attenuator_TOP_t AGC2_RF_Attenuator_TOP; ++ tmTDA182I2AGC3_RF_AGC_TOP_t AGC3_RF_AGC_TOP_Low_band; ++ tmTDA182I2AGC3_RF_AGC_TOP_t AGC3_RF_AGC_TOP_High_band; ++ tmTDA182I2AGC4_IR_Mixer_TOP_t AGC4_IR_Mixer_TOP; ++ tmTDA182I2AGC5_IF_AGC_TOP_t AGC5_IF_AGC_TOP; ++ tmTDA182I2AGC5_Detector_HPF_t AGC5_Detector_HPF; ++ tmTDA182I2AGC3_Adapt_t AGC3_Adapt; ++ tmTDA182I2AGC3_Adapt_TOP_t AGC3_Adapt_TOP; ++ tmTDA182I2AGC5_Atten_3dB_t AGC5_Atten_3dB; ++ UInt8 GSK; ++ tmTDA182I2H3H5_VHF_Filter6_t H3H5_VHF_Filter6; ++ tmTDA182I2_LPF_Gain_t LPF_Gain; ++ Bool AGC1_Freeze; ++ Bool LTO_STO_immune; ++ } tmTDA182I2StdCoefficients, *ptmTDA182I2StdCoefficients; ++ ++ typedef enum _tmTDA182I2RFFilterRobustness_t { ++ tmTDA182I2RFFilterRobustness_Low = 0, ++ tmTDA182I2RFFilterRobustness_High, ++ tmTDA182I2RFFilterRobustness_Error, ++ tmTDA182I2RFFilterRobustness_Max ++ } tmTDA182I2RFFilterRobustness_t, *ptmTDA182I2RFFilterRobustness_t; ++/* ++ typedef struct _tmTDA182I2RFFilterRating { ++ double VHFLow_0_Margin; ++ double VHFLow_1_Margin; ++ double VHFHigh_0_Margin; ++ double VHFHigh_1_Margin; ++ double UHFLow_0_Margin; ++ double UHFLow_1_Margin; ++ double UHFHigh_0_Margin; ++ double UHFHigh_1_Margin; ++ tmTDA182I2RFFilterRobustness_t VHFLow_0_RFFilterRobustness; ++ tmTDA182I2RFFilterRobustness_t VHFLow_1_RFFilterRobustness; ++ tmTDA182I2RFFilterRobustness_t VHFHigh_0_RFFilterRobustness; ++ tmTDA182I2RFFilterRobustness_t VHFHigh_1_RFFilterRobustness; ++ tmTDA182I2RFFilterRobustness_t UHFLow_0_RFFilterRobustness; ++ tmTDA182I2RFFilterRobustness_t UHFLow_1_RFFilterRobustness; ++ tmTDA182I2RFFilterRobustness_t UHFHigh_0_RFFilterRobustness; ++ tmTDA182I2RFFilterRobustness_t UHFHigh_1_RFFilterRobustness; ++ } tmTDA182I2RFFilterRating, *ptmTDA182I2RFFilterRating; ++*/ ++ tmErrorCode_t ++ tmbslTDA182I2Init( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmbslFrontEndDependency_t* psSrvFunc, /* I: setup parameters */ ++ TUNER_MODULE *pTuner // Added by Realtek ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2DeInit ( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetSWVersion ( ++ ptmSWVersion_t pSWVersion /* I: Receives SW Version */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2CheckHWVersion ( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2SetPowerState ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmTDA182I2PowerState_t powerState /* I: Power state of this device */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetPowerState ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmTDA182I2PowerState_t *pPowerState /* O: Power state of this device */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2SetStandardMode ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmTDA182I2StandardMode_t StandardMode /* I: Standard mode of this device */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetStandardMode ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmTDA182I2StandardMode_t *pStandardMode /* O: Standard mode of this device */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2SetRf( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uRF, /* I: RF frequency in hertz */ ++ tmTDA182I2IF_AGC_Gain_t IF_Gain // Added by realtek ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetRf( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* pRF /* O: RF frequency in hertz */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2Reset( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetIF( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* puIF /* O: IF Frequency in hertz */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetCF_Offset( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* puOffset /* O: Center frequency offset in hertz */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetLockStatus( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmbslFrontEndState_t* pLockStatus /* O: PLL Lock status */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetPowerLevel( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* pPowerLevel /* O: Power Level in dBuV */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2SetIRQWait( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ Bool bWait /* I: Determine if we need to wait IRQ in driver functions */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetIRQWait( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ Bool* pbWait /* O: Determine if we need to wait IRQ in driver functions */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetIRQ( ++ tmUnitSelect_t tUnit /* I: Unit number */, ++ Bool* pbIRQ /* O: IRQ triggered */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2WaitIRQ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 timeOut, /* I: timeOut for IRQ wait */ ++ UInt32 waitStep, /* I: wait step */ ++ UInt8 irqStatus /* I: IRQs to wait */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2GetXtalCal_End( ++ tmUnitSelect_t tUnit /* I: Unit number */, ++ Bool* pbXtalCal_End /* O: XtalCal_End triggered */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2WaitXtalCal_End( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 timeOut, /* I: timeOut for IRQ wait */ ++ UInt32 waitStep /* I: wait step */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2SoftReset( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++ ); ++/* ++ tmErrorCode_t ++ tmbslTDA182I2CheckRFFilterRobustness ++ ( ++ tmUnitSelect_t tUnit, // I: Unit number ++ ptmTDA182I2RFFilterRating rating // O: RF Filter rating ++ ); ++*/ ++ tmErrorCode_t ++ tmbslTDA182I2Write ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uIndex, /* I: Start index to write */ ++ UInt32 WriteLen, /* I: Number of bytes to write */ ++ UInt8* pData /* I: Data to write */ ++ ); ++ tmErrorCode_t ++ tmbslTDA182I2Read ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uIndex, /* I: Start index to read */ ++ UInt32 ReadLen, /* I: Number of bytes to read */ ++ UInt8* pData /* I: Data to read */ ++ ); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _TMBSL_TDA18272_H */ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmbslTDA182I2\inc\tmbslTDA182I2local.h ++ ++ ++/** ++Copyright (C) 2008 NXP B.V., All Rights Reserved. ++This source code and any compilation or derivative thereof is the proprietary ++information of NXP B.V. and is confidential in nature. Under no circumstances ++is this software to be exposed to or placed under an Open Source License of ++any type without the expressed written permission of NXP B.V. ++* ++* \file tmbslTDA182I2local.h ++* %version: 9 % ++* ++* \date %date_modified% ++* ++* \brief Describe briefly the purpose of this file. ++* ++* REFERENCE DOCUMENTS : ++* ++* Detailed description may be added here. ++* ++* \section info Change Information ++* ++* \verbatim ++Date Modified by CRPRNr TASKNr Maintenance description ++-------------|-----------|-------|-------|----------------------------------- ++| | | | ++-------------|-----------|-------|-------|----------------------------------- ++| | | | ++-------------|-----------|-------|-------|----------------------------------- ++\endverbatim ++* ++*/ ++ ++#ifndef _TMBSL_TDA182I2LOCAL_H ++#define _TMBSL_TDA182I2LOCAL_H ++ ++/*------------------------------------------------------------------------------*/ ++/* Standard include files: */ ++/*------------------------------------------------------------------------------*/ ++ ++/*------------------------------------------------------------------------------*/ ++/* Project include files: */ ++/*------------------------------------------------------------------------------*/ ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++/*------------------------------------------------------------------------------*/ ++/* Types and defines: */ ++/*------------------------------------------------------------------------------*/ ++ ++#define TDA182I2_MUTEX_TIMEOUT TMBSL_FRONTEND_MUTEX_TIMEOUT_INFINITE ++ ++#ifdef TMBSL_TDA18272 ++ #define TMBSL_TDA182I2_COMPONENT_NAME_STR "TDA18272" ++#else /* TMBSL_TDA18272 */ ++ #define TMBSL_TDA182I2_COMPONENT_NAME_STR "TDA18212" ++#endif /* TMBSL_TDA18272 */ ++ ++#define _SYSTEMFUNC (pObj->SystemFunc) ++#define POBJ_SRVFUNC_SIO pObj->sRWFunc ++#define POBJ_SRVFUNC_STIME pObj->sTime ++#define P_DBGPRINTEx pObj->sDebug.Print ++#define P_DBGPRINTVALID ((pObj != Null) && (pObj->sDebug.Print != Null)) ++ ++ ++/*-------------*/ ++/* ERROR CODES */ ++/*-------------*/ ++ ++#define TDA182I2_MAX_UNITS 2 ++ ++ typedef struct _tmTDA182I2Object_t ++ { ++ tmUnitSelect_t tUnit; ++ tmUnitSelect_t tUnitW; ++ ptmbslFrontEndMutexHandle pMutex; ++ Bool init; ++ tmbslFrontEndIoFunc_t sRWFunc; ++ tmbslFrontEndTimeFunc_t sTime; ++ tmbslFrontEndDebugFunc_t sDebug; ++ tmbslFrontEndMutexFunc_t sMutex; ++ tmTDA182I2PowerState_t curPowerState; ++ tmTDA182I2PowerState_t minPowerState; ++ UInt32 uRF; ++ tmTDA182I2StandardMode_t StandardMode; ++ Bool Master; ++ UInt8 LT_Enable; ++ UInt8 PSM_AGC1; ++ UInt8 AGC1_6_15dB; ++ tmTDA182I2StdCoefficients Std_Array[tmTDA182I2_StandardMode_Max]; ++ ++ // Added by Realtek. ++ TUNER_MODULE *pTuner; ++ ++ } tmTDA182I2Object_t, *ptmTDA182I2Object_t, **pptmTDA182I2Object_t; ++ ++/* suppress warning about static */ ++#pragma GCC diagnostic ignored "-Wunused-function" ++static tmErrorCode_t TDA182I2Init(tmUnitSelect_t tUnit); ++static tmErrorCode_t TDA182I2Wait(ptmTDA182I2Object_t pObj, UInt32 Time); ++static tmErrorCode_t TDA182I2WaitXtalCal_End( ptmTDA182I2Object_t pObj, UInt32 timeOut, UInt32 waitStep); ++ ++extern tmErrorCode_t TDA182I2MutexAcquire(ptmTDA182I2Object_t pObj, UInt32 timeOut); ++extern tmErrorCode_t TDA182I2MutexRelease(ptmTDA182I2Object_t pObj); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _TMBSL_TDA182I2LOCAL_H */ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmbslTDA182I2\inc\tmbslTDA182I2Instance.h ++ ++ ++//----------------------------------------------------------------------------- ++// $Header: ++// (C) Copyright 2001 NXP Semiconductors, All rights reserved ++// ++// This source code and any compilation or derivative thereof is the sole ++// property of NXP Corporation and is provided pursuant to a Software ++// License Agreement. This code is the proprietary information of NXP ++// Corporation and is confidential in nature. Its use and dissemination by ++// any party other than NXP Corporation is strictly limited by the ++// confidential information provisions of the Agreement referenced above. ++//----------------------------------------------------------------------------- ++// FILE NAME: tmbslTDA182I2Instance.h ++// ++// DESCRIPTION: define the static Objects ++// ++// DOCUMENT REF: DVP Software Coding Guidelines v1.14 ++// DVP Board Support Library Architecture Specification v0.5 ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++#ifndef _TMBSLTDA182I2_INSTANCE_H //----------------- ++#define _TMBSLTDA182I2_INSTANCE_H ++ ++tmErrorCode_t TDA182I2AllocInstance (tmUnitSelect_t tUnit, pptmTDA182I2Object_t ppDrvObject); ++tmErrorCode_t TDA182I2DeAllocInstance (tmUnitSelect_t tUnit); ++tmErrorCode_t TDA182I2GetInstance (tmUnitSelect_t tUnit, pptmTDA182I2Object_t ppDrvObject); ++ ++ ++#endif // _TMBSLTDA182I2_INSTANCE_H //--------------- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmddTDA182I2\inc\tmddTDA182I2.h ++ ++ ++/** ++Copyright (C) 2008 NXP B.V., All Rights Reserved. ++This source code and any compilation or derivative thereof is the proprietary ++information of NXP B.V. and is confidential in nature. Under no circumstances ++is this software to be exposed to or placed under an Open Source License of ++any type without the expressed written permission of NXP B.V. ++* ++* \file tmddTDA182I2.h ++* %version: 11 % ++* ++* \date %date_modified% ++* ++* \brief Describe briefly the purpose of this file. ++* ++* REFERENCE DOCUMENTS : ++* ++* Detailed description may be added here. ++* ++* \section info Change Information ++* ++* \verbatim ++Date Modified by CRPRNr TASKNr Maintenance description ++-------------|-----------|-------|-------|----------------------------------- ++| | | | ++-------------|-----------|-------|-------|----------------------------------- ++| | | | ++-------------|-----------|-------|-------|----------------------------------- ++\endverbatim ++* ++*/ ++#ifndef _TMDD_TDA182I2_H //----------------- ++#define _TMDD_TDA182I2_H ++ ++//----------------------------------------------------------------------------- ++// Standard include files: ++//----------------------------------------------------------------------------- ++// ++ ++//----------------------------------------------------------------------------- ++// Project include files: ++//----------------------------------------------------------------------------- ++// ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++ //----------------------------------------------------------------------------- ++ // Types and defines: ++ //----------------------------------------------------------------------------- ++ // ++ ++ /* SW Error codes */ ++#define ddTDA182I2_ERR_BASE (CID_COMP_TUNER | CID_LAYER_BSL) ++#define ddTDA182I2_ERR_COMP (CID_COMP_TUNER | CID_LAYER_BSL | TM_ERR_COMP_UNIQUE_START) ++ ++#define ddTDA182I2_ERR_BAD_UNIT_NUMBER (ddTDA182I2_ERR_BASE + TM_ERR_BAD_UNIT_NUMBER) ++#define ddTDA182I2_ERR_NOT_INITIALIZED (ddTDA182I2_ERR_BASE + TM_ERR_NOT_INITIALIZED) ++#define ddTDA182I2_ERR_INIT_FAILED (ddTDA182I2_ERR_BASE + TM_ERR_INIT_FAILED) ++#define ddTDA182I2_ERR_BAD_PARAMETER (ddTDA182I2_ERR_BASE + TM_ERR_BAD_PARAMETER) ++#define ddTDA182I2_ERR_NOT_SUPPORTED (ddTDA182I2_ERR_BASE + TM_ERR_NOT_SUPPORTED) ++#define ddTDA182I2_ERR_HW_FAILED (ddTDA182I2_ERR_COMP + 0x0001) ++#define ddTDA182I2_ERR_NOT_READY (ddTDA182I2_ERR_COMP + 0x0002) ++#define ddTDA182I2_ERR_BAD_VERSION (ddTDA182I2_ERR_COMP + 0x0003) ++ ++ ++ typedef enum _tmddTDA182I2PowerState_t { ++ tmddTDA182I2_PowerNormalMode, /* Device normal mode */ ++ tmddTDA182I2_PowerStandbyWithLNAOnAndWithXtalOnAndWithSyntheOn, /* Device standby mode with LNA and Xtal Output and Synthe on*/ ++ tmddTDA182I2_PowerStandbyWithLNAOnAndWithXtalOn, /* Device standby mode with LNA and Xtal Output */ ++ tmddTDA182I2_PowerStandbyWithXtalOn, /* Device standby mode with Xtal Output */ ++ tmddTDA182I2_PowerStandby, /* Device standby mode */ ++ tmddTDA182I2_PowerMax ++ } tmddTDA182I2PowerState_t, *ptmddTDA182I2PowerState_t; ++ ++ typedef enum _tmddTDA182I2_LPF_Gain_t { ++ tmddTDA182I2_LPF_Gain_Unknown = 0, /* LPF_Gain Unknown */ ++ tmddTDA182I2_LPF_Gain_Frozen, /* LPF_Gain Frozen */ ++ tmddTDA182I2_LPF_Gain_Free /* LPF_Gain Free */ ++ } tmddTDA182I2_LPF_Gain_t, *ptmddTDA182I2_LPF_Gain_t; ++ ++ tmErrorCode_t ++ tmddTDA182I2Init ++ ( ++ tmUnitSelect_t tUnit, // I: Unit number ++ tmbslFrontEndDependency_t* psSrvFunc /* I: setup parameters */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2DeInit ++ ( ++ tmUnitSelect_t tUnit // I: Unit number ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetSWVersion ++ ( ++ ptmSWVersion_t pSWVersion // I: Receives SW Version ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Reset ++ ( ++ tmUnitSelect_t tUnit // I: Unit number ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetLPF_Gain_Mode ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uMode /* I: Unknown/Free/Frozen */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetLPF_Gain_Mode ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 *puMode /* O: Unknown/Free/Frozen */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Write ++ ( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt32 uIndex, // I: Start index to write ++ UInt32 uNbBytes, // I: Number of bytes to write ++ UInt8* puBytes // I: Pointer on an array of bytes ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Read ++ ( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt32 uIndex, // I: Start index to read ++ UInt32 uNbBytes, // I: Number of bytes to read ++ UInt8* puBytes // I: Pointer on an array of bytes ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPOR ++ ( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetLO_Lock ++ ( ++ tmUnitSelect_t tUnit, // I: Unit number ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMS ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIdentity ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt16* puValue // I: Address of the variable to output item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMinorRevision ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMajorRevision ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetTM_D ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetTM_ON ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetTM_ON ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPowerState ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ tmddTDA182I2PowerState_t powerState // I: Power state of this device ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPowerState ++ ( ++ tmUnitSelect_t tUnit, // I: Unit number ++ ptmddTDA182I2PowerState_t pPowerState // O: Power state of this device ++ ); ++ ++ tmErrorCode_t ++ tmddTDA182I2GetPower_Level ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIRQ_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIRQ_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetXtalCal_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetXtalCal_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_RSSI_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RSSI_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_LOCalc_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_LOCalc_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_RFCAL_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RFCAL_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_IRCAL_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_IRCAL_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_RCCal_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RCCal_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIRQ_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 irqStatus /* I: IRQs to clear */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetXtalCal_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetXtalCal_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_RSSI_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RSSI_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_LOCalc_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_LOCalc_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_RFCal_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RFCal_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_IRCAL_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_IRCAL_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_RCCal_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RCCal_Clear ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIRQ_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIRQ_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetXtalCal_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetXtalCal_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_RSSI_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RSSI_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_LOCalc_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_LOCalc_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_RFCal_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RFCal_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_IRCAL_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_IRCAL_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_RCCal_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RCCal_Set ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIRQ_status ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_XtalCal_End ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RSSI_End ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_LOCalc_End ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RFCal_End ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_IRCAL_End ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_RCCal_End ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetLT_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetLT_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC1_6_15dB ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC1_6_15dB ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC1_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC1_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC2_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC2_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGCs_Up_Step_assym ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGCs_Up_Step_assym ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGCs_Up_Step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGCs_Up_Step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPulse_Shaper_Disable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPulse_Shaper_Disable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGCK_Step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGCK_Step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGCK_Mode ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGCK_Mode ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPD_RFAGC_Adapt ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPD_RFAGC_Adapt ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFAGC_Adapt_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFAGC_Adapt_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFAGC_Low_BW ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFAGC_Low_BW ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_Atten_3dB ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_Atten_3dB ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFAGC_Top ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFAGC_Top ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_Mixer_Top ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_Mixer_Top ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGCs_Do_Step_assym ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGCs_Do_Step_assym ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC5_Ana ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC5_Ana ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC5_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC5_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIF_Level ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIF_Level ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIF_HP_Fc ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIF_HP_Fc ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIF_ATSC_Notch ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIF_ATSC_Notch ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetLP_FC_Offset ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetLP_FC_Offset ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetLP_FC ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetLP_FC ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetI2C_Clock_Mode ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetI2C_Clock_Mode ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetDigital_Clock_Mode ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetDigital_Clock_Mode ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetXtalOsc_AnaReg_En ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetXtalOsc_AnaReg_En ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetXTout ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetXTout ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIF_Freq ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIF_Freq ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* puValue // I: Address of the variable to output item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_Freq ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_Freq ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32* puValue // I: Address of the variable to output item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRSSI_Meas ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRSSI_Meas ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_CAL_AV ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_CAL_AV ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_CAL ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_CAL ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_CAL_Loop ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_CAL_Loop ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_Cal_Image ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_Cal_Image ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_CAL_Wanted ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_CAL_Wanted ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRC_Cal ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRC_Cal ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetCalc_PLL ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetCalc_PLL ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetXtalCal_Launch ++ ( ++ tmUnitSelect_t tUnit // I: Unit number ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetXtalCal_Launch ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetMSM_Launch ++ ( ++ tmUnitSelect_t tUnit // I: Unit number ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetMSM_Launch ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPSM_AGC1 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPSM_AGC1 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPSM_StoB ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPSM_StoB ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPSMRFpoly ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPSMRFpoly ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPSM_Mixer ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPSM_Mixer ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPSM_Ifpoly ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPSM_Ifpoly ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPSM_Lodriver ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPSM_Lodriver ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetDCC_Bypass ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetDCC_Bypass ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetDCC_Slow ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetDCC_Slow ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetDCC_psm ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetDCC_psm ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetFmax_Lo ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetFmax_Lo ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_Loop ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_Loop ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_Target ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_Target ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_GStep ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_GStep ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_Corr_Boost ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_Corr_Boost ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_FreqLow_Sel ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_FreqLow_Sel ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_mode_ram_store ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_mode_ram_store ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_FreqLow ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_FreqLow ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_FreqMid ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_FreqMid ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetCoarse_IR_FreqHigh ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetCoarse_IR_FreqHigh ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_FreqHigh ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_FreqHigh ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ ++ tmErrorCode_t ++ tmddTDA182I2SetPD_Vsync_Mgt ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPD_Vsync_Mgt ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPD_Ovld ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPD_Ovld ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetPD_Udld ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetPD_Udld ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC_Ovld_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC_Ovld_TOP ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC_Ovld_Timer ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC_Ovld_Timer ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_Mixer_loop_off ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_Mixer_loop_off ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIR_Mixer_Do_step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIR_Mixer_Do_step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetHi_Pass ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetHi_Pass ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIF_Notch ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIF_Notch ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC1_loop_off ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC1_loop_off ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC1_Do_step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC1_Do_step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetForce_AGC1_gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetForce_AGC1_gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC1_Gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC1_Gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC5_loop_off ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC5_loop_off ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC5_Do_step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC5_Do_step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetForce_AGC5_gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetForce_AGC5_gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC5_Gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC5_Gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq0 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq0 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq1 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq1 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq2 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq2 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq3 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq3 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq4 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq4 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq5 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq5 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq6 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq6 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq7 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq7 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq8 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq8 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq9 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq9 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq10 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq10 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Freq11 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Freq11 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset0 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset0 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset1 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset1 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset2 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset2 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset3 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset3 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset4 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset4 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset5 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset5 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset6 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset6 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset7 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset7 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset8 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset8 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset9 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset9 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset10 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset10 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Offset11 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Offset11 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_SW_Algo_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_SW_Algo_Enable ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_Filter_Bypass ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_Filter_Bypass ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC2_loop_off ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC2_loop_off ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetForce_AGC2_gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetForce_AGC2_gain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_Filter_Gv ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_Filter_Gv ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_Filter_Band ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_Filter_Band ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_Filter_Cap ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_Filter_Cap ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetAGC2_Do_step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC2_Do_step ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetGain_Taper ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetGain_Taper ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_BPF ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_BPF ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRF_BPF_Bypass ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRF_BPF_Bypass ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetN_CP_Current ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetN_CP_Current ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetUp_AGC5 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetDo_AGC5 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetUp_AGC4 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetDo_AGC4 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetUp_AGC2 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetDo_AGC2 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetUp_AGC1 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetDo_AGC1 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC2_Gain_Read ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC1_Gain_Read ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetTOP_AGC3_Read ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC5_Gain_Read ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetAGC4_Gain_Read ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRSSI ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRSSI ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRSSI_AV ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRSSI_AV ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRSSI_Cap_Reset_En ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRSSI_Cap_Reset_En ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRSSI_Cap_Val ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRSSI_Cap_Val ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRSSI_Ck_Speed ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRSSI_Ck_Speed ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRSSI_Dicho_not ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRSSI_Dicho_not ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_Phi2 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_Phi2 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetDDS_Polarity ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue // I: Item value ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetDDS_Polarity ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetRFCAL_DeltaGain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetRFCAL_DeltaGain ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIRQ_Polarity ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8 uValue /* I: Item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIRQ_Polarity ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_0 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_1 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_2 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_3 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_4 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_5 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_6 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_7 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_8 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_9 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_10 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2Getrfcal_log_11 ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt8* puValue /* I: Address of the variable to output item value */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2LaunchRF_CAL ++ ( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2WaitIRQ ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 timeOut, /* I: timeout */ ++ UInt32 waitStep, /* I: wait step */ ++ UInt8 irqStatus /* I: IRQs to wait */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2WaitXtalCal_End ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ UInt32 timeOut, /* I: timeout */ ++ UInt32 waitStep /* I: wait step */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2SetIRQWait ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ Bool bWait /* I: Determine if we need to wait IRQ in driver functions */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2GetIRQWait ++ ( ++ tmUnitSelect_t tUnit, /* I: Unit number */ ++ Bool* pbWait /* O: Determine if we need to wait IRQ in driver functions */ ++ ); ++ tmErrorCode_t ++ tmddTDA182I2AGC1_Adapt ++ ( ++ tmUnitSelect_t tUnit /* I: Unit number */ ++ ); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif // _TMDD_TDA182I2_H //--------------- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmddTDA182I2\inc\tmddTDA182I2local.h ++ ++ ++//----------------------------------------------------------------------------- ++// $Header: ++// (C) Copyright 2007 NXP Semiconductors, All rights reserved ++// ++// This source code and any compilation or derivative thereof is the sole ++// property of NXP Corporation and is provided pursuant to a Software ++// License Agreement. This code is the proprietary information of NXP ++// Corporation and is confidential in nature. Its use and dissemination by ++// any party other than NXP Corporation is strictly limited by the ++// confidential information provisions of the Agreement referenced above. ++//----------------------------------------------------------------------------- ++// FILE NAME: tmddTDA182I2local.h ++// ++// DESCRIPTION: define the Object for the TDA182I2 ++// ++// DOCUMENT REF: DVP Software Coding Guidelines v1.14 ++// DVP Board Support Library Architecture Specification v0.5 ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++// ++#ifndef _TMDD_TDA182I2LOCAL_H //----------------- ++#define _TMDD_TDA182I2LOCAL_H ++ ++//----------------------------------------------------------------------------- ++// Standard include files: ++//----------------------------------------------------------------------------- ++ ++//#include "tmddTDA182I2.h" ++ ++/*------------------------------------------------------------------------------*/ ++/* Project include files: */ ++/*------------------------------------------------------------------------------*/ ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#endif ++ ++ //----------------------------------------------------------------------------- ++ // Types and defines: ++ //----------------------------------------------------------------------------- ++ // ++ ++#define ddTDA182I2_MUTEX_TIMEOUT TMBSL_FRONTEND_MUTEX_TIMEOUT_INFINITE ++ ++#define _SYSTEMFUNC (pObj->SystemFunc) ++ ++#define POBJ_SRVFUNC_SIO pObj->sRWFunc ++#define POBJ_SRVFUNC_STIME pObj->sTime ++#define P_DBGPRINTEx pObj->sDebug.Print ++#define P_DBGPRINTVALID ((pObj != Null) && (pObj->sDebug.Print != Null)) ++ ++#define TDA182I2_DD_COMP_NUM 2 // Major protocol change - Specification change required ++#define TDA182I2_DD_MAJOR_VER 4 // Minor protocol change - Specification change required ++#define TDA182I2_DD_MINOR_VER 7 // Software update - No protocol change - No specification change required ++ ++#define TDA182I2_POWER_LEVEL_MIN 40 ++#define TDA182I2_POWER_LEVEL_MAX 110 ++ ++#define TDA182I2_MAX_UNITS 2 ++#define TDA182I2_I2C_MAP_NB_BYTES 68 ++ ++#define TDA182I2_DEVICE_ID_MASTER 1 ++#define TDA182I2_DEVICE_ID_SLAVE 0 ++ ++ ++ typedef struct _TDA182I2_I2C_Map_t ++ { ++ union ++ { ++ UInt8 ID_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 MS:1; ++ UInt8 Ident_1:7; ++#else ++ UInt8 Ident_1:7; ++ UInt8 MS:1; ++#endif ++ }bF; ++ }uBx00; ++ ++ union ++ { ++ UInt8 ID_byte_2; ++ struct ++ { ++ UInt8 Ident_2:8; ++ }bF; ++ }uBx01; ++ ++ union ++ { ++ UInt8 ID_byte_3; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 Major_rev:4; ++ UInt8 Minor_rev:4; ++#else ++ UInt8 Minor_rev:4; ++ UInt8 Major_rev:4; ++#endif ++ }bF; ++ }uBx02; ++ ++ union ++ { ++ UInt8 Thermo_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 TM_D:7; ++#else ++ UInt8 TM_D:7; ++ UInt8 UNUSED_I0_D0:1; ++#endif ++ }bF; ++ }uBx03; ++ ++ union ++ { ++ UInt8 Thermo_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:7; ++ UInt8 TM_ON:1; ++#else ++ UInt8 TM_ON:1; ++ UInt8 UNUSED_I0_D0:7; ++#endif ++ }bF; ++ }uBx04; ++ ++ union ++ { ++ UInt8 Power_state_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:6; ++ UInt8 POR:1; ++ UInt8 LO_Lock:1; ++#else ++ UInt8 LO_Lock:1; ++ UInt8 POR:1; ++ UInt8 UNUSED_I0_D0:6; ++#endif ++ }bF; ++ }uBx05; ++ ++ union ++ { ++ UInt8 Power_state_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:4; ++ UInt8 SM:1; ++ UInt8 SM_Synthe:1; ++ UInt8 SM_LT:1; ++ UInt8 SM_XT:1; ++#else ++ UInt8 SM_XT:1; ++ UInt8 SM_LT:1; ++ UInt8 SM_Synthe:1; ++ UInt8 SM:1; ++ UInt8 UNUSED_I0_D0:4; ++#endif ++ }bF; ++ }uBx06; ++ ++ union ++ { ++ UInt8 Input_Power_Level_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 Power_Level:7; ++#else ++ UInt8 Power_Level:7; ++ UInt8 UNUSED_I0_D0:1; ++#endif ++ }bF; ++ }uBx07; ++ ++ union ++ { ++ UInt8 IRQ_status; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 IRQ_status:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 MSM_XtalCal_End:1; ++ UInt8 MSM_RSSI_End:1; ++ UInt8 MSM_LOCalc_End:1; ++ UInt8 MSM_RFCal_End:1; ++ UInt8 MSM_IRCAL_End:1; ++ UInt8 MSM_RCCal_End:1; ++#else ++ UInt8 MSM_RCCal_End:1; ++ UInt8 MSM_IRCAL_End:1; ++ UInt8 MSM_RFCal_End:1; ++ UInt8 MSM_LOCalc_End:1; ++ UInt8 MSM_RSSI_End:1; ++ UInt8 MSM_XtalCal_End:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 IRQ_status:1; ++#endif ++ }bF; ++ }uBx08; ++ ++ union ++ { ++ UInt8 IRQ_enable; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 IRQ_Enable:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 XtalCal_Enable:1; ++ UInt8 MSM_RSSI_Enable:1; ++ UInt8 MSM_LOCalc_Enable:1; ++ UInt8 MSM_RFCAL_Enable:1; ++ UInt8 MSM_IRCAL_Enable:1; ++ UInt8 MSM_RCCal_Enable:1; ++#else ++ UInt8 MSM_RCCal_Enable:1; ++ UInt8 MSM_IRCAL_Enable:1; ++ UInt8 MSM_RFCAL_Enable:1; ++ UInt8 MSM_LOCalc_Enable:1; ++ UInt8 MSM_RSSI_Enable:1; ++ UInt8 XtalCal_Enable:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 IRQ_Enable:1; ++#endif ++ }bF; ++ }uBx09; ++ ++ union ++ { ++ UInt8 IRQ_clear; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 IRQ_Clear:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 XtalCal_Clear:1; ++ UInt8 MSM_RSSI_Clear:1; ++ UInt8 MSM_LOCalc_Clear:1; ++ UInt8 MSM_RFCal_Clear:1; ++ UInt8 MSM_IRCAL_Clear:1; ++ UInt8 MSM_RCCal_Clear:1; ++#else ++ UInt8 MSM_RCCal_Clear:1; ++ UInt8 MSM_IRCAL_Clear:1; ++ UInt8 MSM_RFCal_Clear:1; ++ UInt8 MSM_LOCalc_Clear:1; ++ UInt8 MSM_RSSI_Clear:1; ++ UInt8 XtalCal_Clear:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 IRQ_Clear:1; ++#endif ++ }bF; ++ }uBx0A; ++ ++ union ++ { ++ UInt8 IRQ_set; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 IRQ_Set:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 XtalCal_Set:1; ++ UInt8 MSM_RSSI_Set:1; ++ UInt8 MSM_LOCalc_Set:1; ++ UInt8 MSM_RFCal_Set:1; ++ UInt8 MSM_IRCAL_Set:1; ++ UInt8 MSM_RCCal_Set:1; ++#else ++ UInt8 MSM_RCCal_Set:1; ++ UInt8 MSM_IRCAL_Set:1; ++ UInt8 MSM_RFCal_Set:1; ++ UInt8 MSM_LOCalc_Set:1; ++ UInt8 MSM_RSSI_Set:1; ++ UInt8 XtalCal_Set:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 IRQ_Set:1; ++#endif ++ }bF; ++ }uBx0B; ++ ++ union ++ { ++ UInt8 AGC1_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 LT_Enable:1; ++ UInt8 AGC1_6_15dB:1; ++ UInt8 UNUSED_I0_D0:2; ++ UInt8 AGC1_TOP:4; ++#else ++ UInt8 AGC1_TOP:4; ++ UInt8 UNUSED_I0_D0:2; ++ UInt8 AGC1_6_15dB:1; ++ UInt8 LT_Enable:1; ++#endif ++ }bF; ++ }uBx0C; ++ ++ union ++ { ++ UInt8 AGC2_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:3; ++ UInt8 AGC2_TOP:5; ++#else ++ UInt8 AGC2_TOP:5; ++ UInt8 UNUSED_I0_D0:3; ++#endif ++ }bF; ++ }uBx0D; ++ ++ union ++ { ++ UInt8 AGCK_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 AGCs_Up_Step_assym:2; ++ UInt8 AGCs_Up_Step:1; ++ UInt8 Pulse_Shaper_Disable:1; ++ UInt8 AGCK_Step:2; ++ UInt8 AGCK_Mode:2; ++#else ++ UInt8 AGCK_Mode:2; ++ UInt8 AGCK_Step:2; ++ UInt8 Pulse_Shaper_Disable:1; ++ UInt8 AGCs_Up_Step:1; ++ UInt8 AGCs_Up_Step_assym:2; ++#endif ++ }bF; ++ }uBx0E; ++ ++ union ++ { ++ UInt8 RF_AGC_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 PD_RFAGC_Adapt:1; ++ UInt8 RFAGC_Adapt_TOP:2; ++ UInt8 RFAGC_Low_BW:1; ++ UInt8 RF_Atten_3dB:1; ++ UInt8 RFAGC_Top:3; ++#else ++ UInt8 RFAGC_Top:3; ++ UInt8 RF_Atten_3dB:1; ++ UInt8 RFAGC_Low_BW:1; ++ UInt8 RFAGC_Adapt_TOP:2; ++ UInt8 PD_RFAGC_Adapt:1; ++#endif ++ }bF; ++ }uBx0F; ++ ++ union ++ { ++ UInt8 IR_Mixer_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:4; ++ UInt8 IR_Mixer_Top:4; ++#else ++ UInt8 IR_Mixer_Top:4; ++ UInt8 UNUSED_I0_D0:4; ++#endif ++ }bF; ++ }uBx10; ++ ++ union ++ { ++ UInt8 AGC5_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 AGCs_Do_Step_assym:2; ++ UInt8 AGC5_Ana:1; ++ UInt8 AGC5_TOP:4; ++#else ++ UInt8 AGC5_TOP:4; ++ UInt8 AGC5_Ana:1; ++ UInt8 AGCs_Do_Step_assym:2; ++ UInt8 UNUSED_I0_D0:1; ++#endif ++ }bF; ++ }uBx11; ++ ++ union ++ { ++ UInt8 IF_AGC_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:5; ++ UInt8 IF_level:3; ++#else ++ UInt8 IF_level:3; ++ UInt8 UNUSED_I0_D0:5; ++#endif ++ }bF; ++ }uBx12; ++ ++ union ++ { ++ UInt8 IF_Byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 IF_HP_Fc:2; ++ UInt8 IF_ATSC_Notch:1; ++ UInt8 LP_FC_Offset:2; ++ UInt8 LP_Fc:3; ++#else ++ UInt8 LP_Fc:3; ++ UInt8 LP_FC_Offset:2; ++ UInt8 IF_ATSC_Notch:1; ++ UInt8 IF_HP_Fc:2; ++#endif ++ }bF; ++ }uBx13; ++ ++ union ++ { ++ UInt8 Reference_Byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 I2C_Clock_Mode:1; ++ UInt8 Digital_Clock_Mode:1; ++ UInt8 UNUSED_I1_D0:1; ++ UInt8 XtalOsc_AnaReg_En:1; ++ UInt8 UNUSED_I0_D0:2; ++ UInt8 XTout:2; ++#else ++ UInt8 XTout:2; ++ UInt8 UNUSED_I0_D0:2; ++ UInt8 XtalOsc_AnaReg_En:1; ++ UInt8 UNUSED_I1_D0:1; ++ UInt8 Digital_Clock_Mode:1; ++ UInt8 I2C_Clock_Mode:1; ++#endif ++ }bF; ++ }uBx14; ++ ++ union ++ { ++ UInt8 IF_Frequency_byte; ++ struct ++ { ++ UInt8 IF_Freq:8; ++ }bF; ++ }uBx15; ++ ++ union ++ { ++ UInt8 RF_Frequency_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:4; ++ UInt8 RF_Freq_1:4; ++#else ++ UInt8 RF_Freq_1:4; ++ UInt8 UNUSED_I0_D0:4; ++#endif ++ }bF; ++ }uBx16; ++ ++ union ++ { ++ UInt8 RF_Frequency_byte_2; ++ struct ++ { ++ UInt8 RF_Freq_2:8; ++ }bF; ++ }uBx17; ++ ++ ++ union ++ { ++ UInt8 RF_Frequency_byte_3; ++ struct ++ { ++ UInt8 RF_Freq_3:8; ++ }bF; ++ }uBx18; ++ ++ union ++ { ++ UInt8 MSM_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RSSI_Meas:1; ++ UInt8 RF_CAL_AV:1; ++ UInt8 RF_CAL:1; ++ UInt8 IR_CAL_Loop:1; ++ UInt8 IR_Cal_Image:1; ++ UInt8 IR_CAL_Wanted:1; ++ UInt8 RC_Cal:1; ++ UInt8 Calc_PLL:1; ++#else ++ UInt8 Calc_PLL:1; ++ UInt8 RC_Cal:1; ++ UInt8 IR_CAL_Wanted:1; ++ UInt8 IR_Cal_Image:1; ++ UInt8 IR_CAL_Loop:1; ++ UInt8 RF_CAL:1; ++ UInt8 RF_CAL_AV:1; ++ UInt8 RSSI_Meas:1; ++#endif ++ }bF; ++ }uBx19; ++ ++ union ++ { ++ UInt8 MSM_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:6; ++ UInt8 XtalCal_Launch:1; ++ UInt8 MSM_Launch:1; ++#else ++ UInt8 MSM_Launch:1; ++ UInt8 XtalCal_Launch:1; ++ UInt8 UNUSED_I0_D0:6; ++#endif ++ }bF; ++ }uBx1A; ++ ++ union ++ { ++ UInt8 PowerSavingMode; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 PSM_AGC1:2; ++ UInt8 PSM_StoB:1; ++ UInt8 PSMRFpoly:1; ++ UInt8 PSM_Mixer:1; ++ UInt8 PSM_Ifpoly:1; ++ UInt8 PSM_Lodriver:2; ++#else ++ UInt8 PSM_Lodriver:2; ++ UInt8 PSM_Ifpoly:1; ++ UInt8 PSM_Mixer:1; ++ UInt8 PSMRFpoly:1; ++ UInt8 PSM_StoB:1; ++ UInt8 PSM_AGC1:2; ++#endif ++ }bF; ++ }uBx1B; ++ ++ union ++ { ++ UInt8 DCC_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 DCC_Bypass:1; ++ UInt8 DCC_Slow:1; ++ UInt8 DCC_psm:1; ++ UInt8 UNUSED_I0_D0:5; ++#else ++ UInt8 UNUSED_I0_D0:5; ++ UInt8 DCC_psm:1; ++ UInt8 DCC_Slow:1; ++ UInt8 DCC_Bypass:1; ++#endif ++ }bF; ++ }uBx1C; ++ ++ union ++ { ++ UInt8 FLO_max_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:2; ++ UInt8 Fmax_Lo:6; ++#else ++ UInt8 Fmax_Lo:6; ++ UInt8 UNUSED_I0_D0:2; ++#endif ++ }bF; ++ }uBx1D; ++ ++ union ++ { ++ UInt8 IR_Cal_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 IR_Loop:2; ++ UInt8 IR_Target:3; ++ UInt8 IR_GStep:3; ++#else ++ UInt8 IR_GStep:3; ++ UInt8 IR_Target:3; ++ UInt8 IR_Loop:2; ++#endif ++ }bF; ++ }uBx1E; ++ ++ union ++ { ++ UInt8 IR_Cal_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 IR_Corr_Boost:1; ++ UInt8 IR_FreqLow_Sel:1; ++ UInt8 IR_mode_ram_store:1; ++ UInt8 IR_FreqLow:5; ++#else ++ UInt8 IR_FreqLow:5; ++ UInt8 IR_mode_ram_store:1; ++ UInt8 IR_FreqLow_Sel:1; ++ UInt8 IR_Corr_Boost:1; ++#endif ++ }bF; ++ }uBx1F; ++ ++ union ++ { ++ UInt8 IR_Cal_byte_3; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:3; ++ UInt8 IR_FreqMid:5; ++#else ++ UInt8 IR_FreqMid:5; ++ UInt8 UNUSED_I0_D0:3; ++#endif ++ }bF; ++ }uBx20; ++ ++ union ++ { ++ UInt8 IR_Cal_byte_4; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:2; ++ UInt8 Coarse_IR_FreqHigh:1; ++ UInt8 IR_FreqHigh:5; ++#else ++ UInt8 IR_FreqHigh:5; ++ UInt8 Coarse_IR_FreqHigh:1; ++ UInt8 UNUSED_I0_D0:2; ++#endif ++ }bF; ++ }uBx21; ++ ++ union ++ { ++ UInt8 Vsync_Mgt_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 PD_Vsync_Mgt:1; ++ UInt8 PD_Ovld:1; ++ UInt8 PD_Udld:1; ++ UInt8 AGC_Ovld_TOP:3; ++ UInt8 AGC_Ovld_Timer:2; ++#else ++ UInt8 AGC_Ovld_Timer:2; ++ UInt8 AGC_Ovld_TOP:3; ++ UInt8 PD_Udld:1; ++ UInt8 PD_Ovld:1; ++ UInt8 PD_Vsync_Mgt:1; ++#endif ++ }bF; ++ }uBx22; ++ ++ union ++ { ++ UInt8 IR_Mixer_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 IR_Mixer_loop_off:1; ++ UInt8 IR_Mixer_Do_step:2; ++ UInt8 UNUSED_I0_D0:3; ++ UInt8 Hi_Pass:1; ++ UInt8 IF_Notch:1; ++#else ++ UInt8 IF_Notch:1; ++ UInt8 Hi_Pass:1; ++ UInt8 UNUSED_I0_D0:3; ++ UInt8 IR_Mixer_Do_step:2; ++ UInt8 IR_Mixer_loop_off:1; ++#endif ++ }bF; ++ }uBx23; ++ ++ union ++ { ++ UInt8 AGC1_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 AGC1_loop_off:1; ++ UInt8 AGC1_Do_step:2; ++ UInt8 Force_AGC1_gain:1; ++ UInt8 AGC1_Gain:4; ++#else ++ UInt8 AGC1_Gain:4; ++ UInt8 Force_AGC1_gain:1; ++ UInt8 AGC1_Do_step:2; ++ UInt8 AGC1_loop_off:1; ++#endif ++ }bF; ++ }uBx24; ++ ++ union ++ { ++ UInt8 AGC5_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 AGC5_loop_off:1; ++ UInt8 AGC5_Do_step:2; ++ UInt8 UNUSED_I1_D0:1; ++ UInt8 Force_AGC5_gain:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 AGC5_Gain:2; ++#else ++ UInt8 AGC5_Gain:2; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 Force_AGC5_gain:1; ++ UInt8 UNUSED_I1_D0:1; ++ UInt8 AGC5_Do_step:2; ++ UInt8 AGC5_loop_off:1; ++#endif ++ }bF; ++ }uBx25; ++ ++ union ++ { ++ UInt8 RF_Cal_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RFCAL_Offset_Cprog0:2; ++ UInt8 RFCAL_Freq0:2; ++ UInt8 RFCAL_Offset_Cprog1:2; ++ UInt8 RFCAL_Freq1:2; ++#else ++ UInt8 RFCAL_Freq1:2; ++ UInt8 RFCAL_Offset_Cprog1:2; ++ UInt8 RFCAL_Freq0:2; ++ UInt8 RFCAL_Offset_Cprog0:2; ++#endif ++ }bF; ++ }uBx26; ++ ++ union ++ { ++ UInt8 RF_Cal_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RFCAL_Offset_Cprog2:2; ++ UInt8 RFCAL_Freq2:2; ++ UInt8 RFCAL_Offset_Cprog3:2; ++ UInt8 RFCAL_Freq3:2; ++#else ++ UInt8 RFCAL_Freq3:2; ++ UInt8 RFCAL_Offset_Cprog3:2; ++ UInt8 RFCAL_Freq2:2; ++ UInt8 RFCAL_Offset_Cprog2:2; ++#endif ++ }bF; ++ }uBx27; ++ ++ union ++ { ++ UInt8 RF_Cal_byte_3; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RFCAL_Offset_Cprog4:2; ++ UInt8 RFCAL_Freq4:2; ++ UInt8 RFCAL_Offset_Cprog5:2; ++ UInt8 RFCAL_Freq5:2; ++#else ++ UInt8 RFCAL_Freq5:2; ++ UInt8 RFCAL_Offset_Cprog5:2; ++ UInt8 RFCAL_Freq4:2; ++ UInt8 RFCAL_Offset_Cprog4:2; ++#endif ++ }bF; ++ }uBx28; ++ ++ union ++ { ++ UInt8 RF_Cal_byte_4; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RFCAL_Offset_Cprog6:2; ++ UInt8 RFCAL_Freq6:2; ++ UInt8 RFCAL_Offset_Cprog7:2; ++ UInt8 RFCAL_Freq7:2; ++#else ++ UInt8 RFCAL_Freq7:2; ++ UInt8 RFCAL_Offset_Cprog7:2; ++ UInt8 RFCAL_Freq6:2; ++ UInt8 RFCAL_Offset_Cprog6:2; ++#endif ++ }bF; ++ }uBx29; ++ ++ union ++ { ++ UInt8 RF_Cal_byte_5; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RFCAL_Offset_Cprog8:2; ++ UInt8 RFCAL_Freq8:2; ++ UInt8 RFCAL_Offset_Cprog9:2; ++ UInt8 RFCAL_Freq9:2; ++#else ++ UInt8 RFCAL_Freq9:2; ++ UInt8 RFCAL_Offset_Cprog9:2; ++ UInt8 RFCAL_Freq8:2; ++ UInt8 RFCAL_Offset_Cprog8:2; ++#endif ++ }bF; ++ }uBx2A; ++ ++ union ++ { ++ UInt8 RF_Cal_byte_6; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RFCAL_Offset_Cprog10:2; ++ UInt8 RFCAL_Freq10:2; ++ UInt8 RFCAL_Offset_Cprog11:2; ++ UInt8 RFCAL_Freq11:2; ++#else ++ UInt8 RFCAL_Freq11:2; ++ UInt8 RFCAL_Offset_Cprog11:2; ++ UInt8 RFCAL_Freq10:2; ++ UInt8 RFCAL_Offset_Cprog10:2; ++#endif ++ }bF; ++ }uBx2B; ++ ++ union ++ { ++ UInt8 RF_Filters_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RF_Filter_Bypass:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 AGC2_loop_off:1; ++ UInt8 Force_AGC2_gain:1; ++ UInt8 RF_Filter_Gv:2; ++ UInt8 RF_Filter_Band:2; ++#else ++ ++ UInt8 RF_Filter_Band:2; ++ UInt8 RF_Filter_Gv:2; ++ UInt8 Force_AGC2_gain:1; ++ UInt8 AGC2_loop_off:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 RF_Filter_Bypass:1; ++#endif ++ }bF; ++ }uBx2C; ++ ++ union ++ { ++ UInt8 RF_Filters_byte_2; ++ struct ++ { ++ UInt8 RF_Filter_Cap:8; ++ }bF; ++ }uBx2D; ++ ++ union ++ { ++ UInt8 RF_Filters_byte_3; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 AGC2_Do_step:2; ++ UInt8 Gain_Taper:6; ++#else ++ UInt8 Gain_Taper:6; ++ UInt8 AGC2_Do_step:2; ++#endif ++ }bF; ++ }uBx2E; ++ ++ union ++ { ++ UInt8 RF_Band_Pass_Filter_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RF_BPF_Bypass:1; ++ UInt8 UNUSED_I0_D0:4; ++ UInt8 RF_BPF:3; ++#else ++ UInt8 RF_BPF:3; ++ UInt8 UNUSED_I0_D0:4; ++ UInt8 RF_BPF_Bypass:1; ++#endif ++ }bF; ++ }uBx2F; ++ ++ union ++ { ++ UInt8 CP_Current_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 N_CP_Current:7; ++#else ++ UInt8 N_CP_Current:7; ++ UInt8 UNUSED_I0_D0:1; ++#endif ++ }bF; ++ }uBx30; ++ ++ union ++ { ++ UInt8 AGCs_DetOut_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 Up_AGC5:1; ++ UInt8 Do_AGC5:1; ++ UInt8 Up_AGC4:1; ++ UInt8 Do_AGC4:1; ++ UInt8 Up_AGC2:1; ++ UInt8 Do_AGC2:1; ++ UInt8 Up_AGC1:1; ++ UInt8 Do_AGC1:1; ++#else ++ UInt8 Do_AGC1:1; ++ UInt8 Up_AGC1:1; ++ UInt8 Do_AGC2:1; ++ UInt8 Up_AGC2:1; ++ UInt8 Do_AGC4:1; ++ UInt8 Up_AGC4:1; ++ UInt8 Do_AGC5:1; ++ UInt8 Up_AGC5:1; ++#endif ++ }bF; ++ }uBx31; ++ ++ union ++ { ++ UInt8 RFAGCs_Gain_byte_1; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:2; ++ UInt8 AGC2_Gain_Read:2; ++ UInt8 AGC1_Gain_Read:4; ++#else ++ UInt8 AGC1_Gain_Read:4; ++ UInt8 AGC2_Gain_Read:2; ++ UInt8 UNUSED_I0_D0:2; ++#endif ++ }bF; ++ }uBx32; ++ ++ union ++ { ++ UInt8 RFAGCs_Gain_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:5; ++ UInt8 TOP_AGC3_Read:3; ++#else ++ UInt8 TOP_AGC3_Read:3; ++ UInt8 UNUSED_I0_D0:5; ++#endif ++ }bF; ++ }uBx33; ++ ++ union ++ { ++ UInt8 IFAGCs_Gain_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I0_D0:3; ++ UInt8 AGC5_Gain_Read:2; ++ UInt8 AGC4_Gain_Read:3; ++#else ++ UInt8 AGC4_Gain_Read:3; ++ UInt8 AGC5_Gain_Read:2; ++ UInt8 UNUSED_I0_D0:3; ++#endif ++ }bF; ++ }uBx34; ++ ++ union ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++#else ++#endif ++ UInt8 RSSI_byte_1; ++ UInt8 RSSI; ++ }uBx35; ++ ++ union ++ { ++ UInt8 RSSI_byte_2; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 UNUSED_I1_D0:2; ++ UInt8 RSSI_AV:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 RSSI_Cap_Reset_En:1; ++ UInt8 RSSI_Cap_Val:1; ++ UInt8 RSSI_Ck_Speed:1; ++ UInt8 RSSI_Dicho_not:1; ++#else ++ UInt8 RSSI_Dicho_not:1; ++ UInt8 RSSI_Ck_Speed:1; ++ UInt8 RSSI_Cap_Val:1; ++ UInt8 RSSI_Cap_Reset_En:1; ++ UInt8 UNUSED_I0_D0:1; ++ UInt8 RSSI_AV:1; ++ UInt8 UNUSED_I1_D0:2; ++#endif ++ }bF; ++ }uBx36; ++ ++ union ++ { ++ UInt8 Misc_byte; ++ struct ++ { ++#ifdef _TARGET_PLATFORM_MSB_FIRST ++ UInt8 RFCAL_Phi2:2; ++ UInt8 DDS_Polarity:1; ++ UInt8 RFCAL_DeltaGain:4; ++ UInt8 IRQ_Polarity:1; ++#else ++ UInt8 IRQ_Polarity:1; ++ UInt8 RFCAL_DeltaGain:4; ++ UInt8 DDS_Polarity:1; ++ UInt8 RFCAL_Phi2:2; ++#endif ++ }bF; ++ }uBx37; ++ ++ union ++ { ++ UInt8 rfcal_log_0; ++ struct ++ { ++ UInt8 rfcal_log_0:8; ++ }bF; ++ }uBx38; ++ ++ union ++ { ++ UInt8 rfcal_log_1; ++ struct ++ { ++ UInt8 rfcal_log_1:8; ++ }bF; ++ }uBx39; ++ ++ union ++ { ++ UInt8 rfcal_log_2; ++ struct ++ { ++ UInt8 rfcal_log_2:8; ++ }bF; ++ }uBx3A; ++ ++ union ++ { ++ UInt8 rfcal_log_3; ++ struct ++ { ++ UInt8 rfcal_log_3:8; ++ }bF; ++ }uBx3B; ++ ++ union ++ { ++ UInt8 rfcal_log_4; ++ struct ++ { ++ UInt8 rfcal_log_4:8; ++ }bF; ++ }uBx3C; ++ ++ union ++ { ++ UInt8 rfcal_log_5; ++ struct ++ { ++ UInt8 rfcal_log_5:8; ++ }bF; ++ }uBx3D; ++ ++ union ++ { ++ UInt8 rfcal_log_6; ++ struct ++ { ++ UInt8 rfcal_log_6:8; ++ }bF; ++ }uBx3E; ++ ++ union ++ { ++ UInt8 rfcal_log_7; ++ struct ++ { ++ UInt8 rfcal_log_7:8; ++ }bF; ++ }uBx3F; ++ ++ union ++ { ++ UInt8 rfcal_log_8; ++ struct ++ { ++ UInt8 rfcal_log_8:8; ++ }bF; ++ }uBx40; ++ ++ union ++ { ++ UInt8 rfcal_log_9; ++ struct ++ { ++ UInt8 rfcal_log_9:8; ++ }bF; ++ }uBx41; ++ ++ union ++ { ++ UInt8 rfcal_log_10; ++ struct ++ { ++ UInt8 rfcal_log_10:8; ++ }bF; ++ }uBx42; ++ ++ union ++ { ++ UInt8 rfcal_log_11; ++ struct ++ { ++ UInt8 rfcal_log_11:8; ++ }bF; ++ }uBx43; ++ ++ } TDA182I2_I2C_Map_t, *pTDA182I2_I2C_Map_t; ++ ++ typedef struct _tmTDA182I2_RFCalProg_t { ++ UInt8 Cal_number; ++ Int8 DeltaCprog; ++ Int8 CprogOffset; ++ } tmTDA182I2_RFCalProg_t, *ptmTDA182I2_RFCalProg_t; ++ ++ typedef struct _tmTDA182I2_RFCalCoeffs_t { ++ UInt8 Sub_band; ++ UInt8 Cal_number; ++ Int32 RF_A1; ++ Int32 RF_B1; ++ } tmTDA182I2_RFCalCoeffs_t, *ptmTDA182I2_RFCalCoeffs_t; ++ ++#define TDA182I2_RFCAL_PROG_ROW (12) ++#define TDA182I2_RFCAL_COEFFS_ROW (8) ++ ++ typedef struct _tmddTDA182I2Object_t { ++ tmUnitSelect_t tUnit; ++ tmUnitSelect_t tUnitW; ++ ptmbslFrontEndMutexHandle pMutex; ++ Bool init; ++ tmbslFrontEndIoFunc_t sRWFunc; ++ tmbslFrontEndTimeFunc_t sTime; ++ tmbslFrontEndDebugFunc_t sDebug; ++ tmbslFrontEndMutexFunc_t sMutex; ++ tmddTDA182I2PowerState_t curPowerState; ++ Bool bIRQWait; ++ TDA182I2_I2C_Map_t I2CMap; ++ } tmddTDA182I2Object_t, *ptmddTDA182I2Object_t, **pptmddTDA182I2Object_t; ++ ++ ++ extern tmErrorCode_t ddTDA182I2GetIRQ_status(ptmddTDA182I2Object_t pObj, UInt8* puValue); ++ extern tmErrorCode_t ddTDA182I2GetMSM_XtalCal_End(ptmddTDA182I2Object_t pObj, UInt8* puValue); ++ ++ extern tmErrorCode_t ddTDA182I2WaitIRQ(ptmddTDA182I2Object_t pObj, UInt32 timeOut, UInt32 waitStep, UInt8 irqStatus); ++ extern tmErrorCode_t ddTDA182I2WaitXtalCal_End(ptmddTDA182I2Object_t pObj, UInt32 timeOut, UInt32 waitStep); ++ ++ extern tmErrorCode_t ddTDA182I2Write(ptmddTDA182I2Object_t pObj, UInt8 uSubAddress, UInt8 uNbData); ++ extern tmErrorCode_t ddTDA182I2Read(ptmddTDA182I2Object_t pObj, UInt8 uSubAddress, UInt8 uNbData); ++ extern tmErrorCode_t ddTDA182I2Wait(ptmddTDA182I2Object_t pObj, UInt32 Time); ++ ++ extern tmErrorCode_t ddTDA182I2MutexAcquire(ptmddTDA182I2Object_t pObj, UInt32 timeOut); ++ extern tmErrorCode_t ddTDA182I2MutexRelease(ptmddTDA182I2Object_t pObj); ++ extern tmErrorCode_t tmddTDA182I2AGC1_Adapt(tmUnitSelect_t tUnit); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif // _TMDD_TDA182I2LOCAL_H //--------------- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// NXP source code - .\tmddTDA182I2\inc\tmddTDA182I2Instance.h ++ ++ ++/*----------------------------------------------------------------------------- ++// $Header: ++// (C) Copyright 2001 NXP Semiconductors, All rights reserved ++// ++// This source code and any compilation or derivative thereof is the sole ++// property of NXP Corporation and is provided pursuant to a Software ++// License Agreement. This code is the proprietary information of NXP ++// Corporation and is confidential in nature. Its use and dissemination by ++// any party other than NXP Corporation is strictly limited by the ++// confidential information provisions of the Agreement referenced above. ++//----------------------------------------------------------------------------- ++// FILE NAME: tmddTDA182I2Instance.h ++// ++// DESCRIPTION: define the static Objects ++// ++// DOCUMENT REF: DVP Software Coding Guidelines v1.14 ++// DVP Board Support Library Architecture Specification v0.5 ++// ++// NOTES: ++//----------------------------------------------------------------------------- ++*/ ++#ifndef _TMDDTDA182I2_INSTANCE_H //----------------- ++#define _TMDDTDA182I2_INSTANCE_H ++ ++tmErrorCode_t ddTDA182I2AllocInstance (tmUnitSelect_t tUnit, pptmddTDA182I2Object_t ppDrvObject); ++tmErrorCode_t ddTDA182I2DeAllocInstance (tmUnitSelect_t tUnit); ++tmErrorCode_t ddTDA182I2GetInstance (tmUnitSelect_t tUnit, pptmddTDA182I2Object_t ppDrvObject); ++ ++ ++#endif // _TMDDTDA182I2_INSTANCE_H //--------------- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is TDA18272 tuner API source code ++ ++ ++ ++ ++ ++// Definitions ++ ++// Unit number ++enum TDA18272_UNIT_NUM ++{ ++ TDA18272_UNIT_0, // For master tuner or single tuner only. ++ TDA18272_UNIT_1, // For slave tuner only. ++}; ++ ++ ++// IF output Vp-p mode ++enum TDA18272_IF_OUTPUT_VPP_MODE ++{ ++ TDA18272_IF_OUTPUT_VPP_2V = tmTDA182I2_IF_AGC_Gain_2Vpp_0_30dB, ++ TDA18272_IF_OUTPUT_VPP_1P25V = tmTDA182I2_IF_AGC_Gain_1_25Vpp_min_4_26dB, ++ TDA18272_IF_OUTPUT_VPP_1V = tmTDA182I2_IF_AGC_Gain_1Vpp_min_6_24dB, ++ TDA18272_IF_OUTPUT_VPP_0P8V = tmTDA182I2_IF_AGC_Gain_0_8Vpp_min_8_22dB, ++ TDA18272_IF_OUTPUT_VPP_0P85V = tmTDA182I2_IF_AGC_Gain_0_85Vpp_min_7_5_22_5dB, ++ TDA18272_IF_OUTPUT_VPP_0P7V = tmTDA182I2_IF_AGC_Gain_0_7Vpp_min_9_21dB, ++ TDA18272_IF_OUTPUT_VPP_0P6V = tmTDA182I2_IF_AGC_Gain_0_6Vpp_min_10_3_19_7dB, ++ TDA18272_IF_OUTPUT_VPP_0P5V = tmTDA182I2_IF_AGC_Gain_0_5Vpp_min_12_18dB, ++ TDA18272_IF_OUTPUT_VPP_MAX = tmTDA182I2_IF_AGC_Gain_Max, ++}; ++ ++ ++// Standard bandwidth mode ++enum TDA18272_STANDARD_BANDWIDTH_MODE ++{ ++ TDA18272_STANDARD_BANDWIDTH_DVBT_6MHZ = tmTDA182I2_DVBT_6MHz, ++ TDA18272_STANDARD_BANDWIDTH_DVBT_7MHZ = tmTDA182I2_DVBT_7MHz, ++ TDA18272_STANDARD_BANDWIDTH_DVBT_8MHZ = tmTDA182I2_DVBT_8MHz, ++ TDA18272_STANDARD_BANDWIDTH_QAM_6MHZ = tmTDA182I2_QAM_6MHz, ++ TDA18272_STANDARD_BANDWIDTH_QAM_8MHZ = tmTDA182I2_QAM_8MHz, ++ TDA18272_STANDARD_BANDWIDTH_ISDBT_6MHZ = tmTDA182I2_ISDBT_6MHz, ++ TDA18272_STANDARD_BANDWIDTH_ATSC_6MHZ = tmTDA182I2_ATSC_6MHz, ++ TDA18272_STANDARD_BANDWIDTH_DMBT_8MHZ = tmTDA182I2_DMBT_8MHz, ++}; ++ ++ ++// Power mode ++enum TDA18272_POWER_MODE ++{ ++ TDA18272_POWER_NORMAL = tmTDA182I2_PowerNormalMode, ++ TDA18272_POWER_STANDBY_WITH_XTALOUT_LNA_SYNTHE_ON = tmTDA182I2_PowerStandbyWithLNAOnAndWithXtalOnAndSynthe, ++ TDA18272_POWER_STANDBY_WITH_XTALOUT_LNA_ON = tmTDA182I2_PowerStandbyWithLNAOnAndWithXtalOn, ++ TDA18272_POWER_STANDBY_WITH_XTALOUT_ON = tmTDA182I2_PowerStandbyWithXtalOn, ++ TDA18272_POWER_STANDBY = tmTDA182I2_PowerStandby, ++}; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildTda18272Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr, ++ unsigned long CrystalFreqHz, ++ int UnitNo, ++ int IfOutputVppMode ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++tda18272_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++tda18272_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++tda18272_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++tda18272_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++tda18272_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++tda18272_SetStandardBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int StandardBandwidthMode ++ ); ++ ++int ++tda18272_GetStandardBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pStandardBandwidthMode ++ ); ++ ++int ++tda18272_SetPowerMode( ++ TUNER_MODULE *pTuner, ++ int PowerMode ++ ); ++ ++int ++tda18272_GetPowerMode( ++ TUNER_MODULE *pTuner, ++ int *pPowerMode ++ ); ++ ++int ++tda18272_GetIfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pIfFreqHz ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is implemented for TDA18272 source code. ++ ++ ++// Functions ++tmErrorCode_t ++tda18272_Read( ++ tmUnitSelect_t tUnit, ++ UInt32 AddrSize, ++ UInt8* pAddr, ++ UInt32 ReadLen, ++ UInt8* pData ++ ); ++ ++tmErrorCode_t ++tda18272_Write( ++ tmUnitSelect_t tUnit, ++ UInt32 AddrSize, ++ UInt8* pAddr, ++ UInt32 WriteLen, ++ UInt8* pData ++ ); ++ ++tmErrorCode_t ++tda18272_Wait( ++ tmUnitSelect_t tUnit, ++ UInt32 tms ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_tua9001.c b/drivers/drivers/media/dvb/dvb-usb/tuner_tua9001.c +--- a/drivers/media/dvb/dvb-usb/tuner_tua9001.c 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_tua9001.c 2016-04-02 19:17:52.176066045 -0300 +@@ -0,0 +1,1245 @@ ++/** ++ ++@file ++ ++@brief TUA9001 tuner module definition ++ ++One can manipulate TUA9001 tuner through TUA9001 module. ++TUA9001 module is derived from tuner module. ++ ++*/ ++ ++ ++#include "tuner_tua9001.h" ++ ++ ++ ++ ++ ++/** ++ ++@brief TUA9001 tuner module builder ++ ++Use BuildTua9001Module() to build TUA9001 module, set all module function pointers with the corresponding functions, ++and initialize module private variables. ++ ++ ++@param [in] ppTuner Pointer to TUA9001 tuner module pointer ++@param [in] pTunerModuleMemory Pointer to an allocated tuner module memory ++@param [in] pBaseInterfaceModuleMemory Pointer to an allocated base interface module memory ++@param [in] pI2cBridgeModuleMemory Pointer to an allocated I2C bridge module memory ++@param [in] DeviceAddr TUA9001 I2C device address ++ ++ ++@note ++ -# One should call BuildTua9001Module() to build TUA9001 module before using it. ++ ++*/ ++void ++BuildTua9001Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr ++ ) ++{ ++ TUNER_MODULE *pTuner; ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Set tuner module pointer. ++ *ppTuner = pTunerModuleMemory; ++ ++ // Get tuner module. ++ pTuner = *ppTuner; ++ ++ // Set base interface module pointer and I2C bridge module pointer. ++ pTuner->pBaseInterface = pBaseInterfaceModuleMemory; ++ pTuner->pI2cBridge = pI2cBridgeModuleMemory; ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ ++ ++ // Set tuner type. ++ pTuner->TunerType = TUNER_TYPE_TUA9001; ++ ++ // Set tuner I2C device address. ++ pTuner->DeviceAddr = DeviceAddr; ++ ++ ++ // Initialize tuner parameter setting status. ++ pTuner->IsRfFreqHzSet = NO; ++ ++ // Initialize tuner module variables. ++ // Note: Need to give both RF frequency and bandwidth for TUA9001 tuning function, ++ // so we have to give a default RF frequncy. ++ pTuner->RfFreqHz = TUA9001_RF_FREQ_HZ_DEFAULT; ++ ++ ++ // Set tuner module manipulating function pointers. ++ pTuner->GetTunerType = tua9001_GetTunerType; ++ pTuner->GetDeviceAddr = tua9001_GetDeviceAddr; ++ ++ pTuner->Initialize = tua9001_Initialize; ++ pTuner->SetRfFreqHz = tua9001_SetRfFreqHz; ++ pTuner->GetRfFreqHz = tua9001_GetRfFreqHz; ++ ++ ++ // Initialize tuner extra module variables. ++ // Note: Need to give both RF frequency and bandwidth for TUA9001 tuning function, ++ // so we have to give a default bandwidth. ++ pExtra->BandwidthMode = TUA9001_BANDWIDTH_MODE_DEFAULT; ++ pExtra->IsBandwidthModeSet = NO; ++ ++ // Set tuner extra module function pointers. ++ pExtra->SetBandwidthMode = tua9001_SetBandwidthMode; ++ pExtra->GetBandwidthMode = tua9001_GetBandwidthMode; ++ pExtra->GetRegBytesWithRegAddr = tua9001_GetRegBytesWithRegAddr; ++ pExtra->SetSysRegByte = tua9001_SetSysRegByte; ++ pExtra->GetSysRegByte = tua9001_GetSysRegByte; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_TUNER_TYPE ++ ++*/ ++void ++tua9001_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ) ++{ ++ // Get tuner type from tuner module. ++ *pTunerType = pTuner->TunerType; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_DEVICE_ADDR ++ ++*/ ++void ++tua9001_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ) ++{ ++ // Get tuner I2C device address from tuner module. ++ *pDeviceAddr = pTuner->DeviceAddr; ++ ++ ++ return; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_INITIALIZE ++ ++*/ ++int ++tua9001_Initialize( ++ TUNER_MODULE *pTuner ++ ) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Initialize TUA9001 tuner. ++ if(initializeTua9001(pTuner) != TUA9001_TUNER_OK) ++ goto error_status_initialize_tuner; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_initialize_tuner: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_SET_RF_FREQ_HZ ++ ++*/ ++int ++tua9001_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ long RfFreqKhz; ++ int BandwidthMode; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Get bandwidth mode. ++ BandwidthMode = pExtra->BandwidthMode; ++ ++ // Calculate RF frequency in KHz. ++ // Note: RfFreqKhz = round(RfFreqHz / 1000) ++ RfFreqKhz = (long)((RfFreqHz + 500) / 1000); ++ ++ // Set TUA9001 RF frequency and bandwidth. ++ if(tuneTua9001(pTuner, RfFreqKhz, BandwidthMode) != TUA9001_TUNER_OK) ++ goto error_status_set_tuner_rf_frequency; ++ ++ ++ // Set tuner RF frequency parameter. ++ pTuner->RfFreqHz = (unsigned long)(RfFreqKhz * 1000); ++ pTuner->IsRfFreqHzSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@see TUNER_FP_GET_RF_FREQ_HZ ++ ++*/ ++int ++tua9001_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ) ++{ ++ // Get tuner RF frequency in Hz from tuner module. ++ if(pTuner->IsRfFreqHzSet != YES) ++ goto error_status_get_tuner_rf_frequency; ++ ++ *pRfFreqHz = pTuner->RfFreqHz; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_rf_frequency: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set TUA9001 tuner bandwidth mode. ++ ++*/ ++int ++tua9001_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ long RfFreqKhz; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Get RF frequncy in KHz. ++ // Note: Doesn't need to take round() of RfFreqHz, because its value unit is 1000 Hz. ++ RfFreqKhz = (long)(pTuner->RfFreqHz / 1000); ++ ++ // Set TUA9001 RF frequency and bandwidth. ++ if(tuneTua9001(pTuner, RfFreqKhz, BandwidthMode) != TUA9001_TUNER_OK) ++ goto error_status_set_tuner_bandwidth; ++ ++ ++ // Set tuner bandwidth parameter. ++ pExtra->BandwidthMode = BandwidthMode; ++ pExtra->IsBandwidthModeSet = YES; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get TUA9001 tuner bandwidth mode. ++ ++*/ ++int ++tua9001_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ ++ // Get tuner bandwidth in Hz from tuner module. ++ if(pExtra->IsBandwidthModeSet != YES) ++ goto error_status_get_tuner_bandwidth; ++ ++ *pBandwidthMode = pExtra->BandwidthMode; ++ ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_bandwidth: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get register bytes with address. ++ ++*/ ++int ++tua9001_GetRegBytesWithRegAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char RegAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ) ++{ ++ // Get tuner register byte. ++ //if(rtl2832usb_ReadWithRegAddr(DeviceAddr, RegAddr, pReadingBytes, ByteNum) != FUNCTION_SUCCESS) ++ // goto error_status_get_tuner_registers_with_address; ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char TunerDeviceAddr; ++ ++ struct dvb_usb_device *d; ++ ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ // Get tuner device address. ++ pTuner->GetDeviceAddr(pTuner,&TunerDeviceAddr); ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ if( read_rtl2832_tuner_register( d, TunerDeviceAddr, RegAddr, pReadingBytes, ByteNum ) ) ++ goto error_status_get_tuner_registers_with_address; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_tuner_registers_with_address: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Set system register byte. ++ ++*/ ++int ++tua9001_SetSysRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char WritingByte ++ ) ++{ ++ // Set demod system register byte. ++// if(RTK_SYS_Byte_Write(RegAddr, LEN_1_BYTE, &WritingByte) != TRUE) ++// goto error_status_set_system_registers; ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ struct dvb_usb_device *d; ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ if ( write_usb_sys_char_bytes( d, RTD2832U_SYS, RegAddr, &WritingByte, LEN_1_BYTE) ) ++ goto error_status_set_system_registers; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_set_system_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++/** ++ ++@brief Get system register byte. ++ ++*/ ++int ++tua9001_GetSysRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char *pReadingByte ++ ) ++{ ++ // Get demod system register byte. ++// if(RTK_SYS_Byte_Read(RegAddr, LEN_1_BYTE, pReadingByte) != TRUE) ++// goto error_status_get_system_registers; ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ struct dvb_usb_device *d; ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ if ( read_usb_sys_char_bytes(d, RTD2832U_SYS, RegAddr, pReadingByte, LEN_1_BYTE) ) ++ goto error_status_get_system_registers; ++ ++ return FUNCTION_SUCCESS; ++ ++ ++error_status_get_system_registers: ++ return FUNCTION_ERROR; ++} ++ ++ ++ ++ ++ ++// TUA9001 custom-implement functions ++ ++ ++int tua9001setRESETN (TUNER_MODULE *pTuner, unsigned int i_state) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ unsigned char Byte; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Get GPO value. ++ ++ if(pExtra->GetSysRegByte(pTuner, GPO_ADDR, &Byte) != FUNCTION_SUCCESS) ++ goto error_status_get_system_registers; ++ ++ // Note: Hardware PCB has inverter in this pin, should give inverted value on GPIO3. ++ if (i_state == TUA9001_H_LEVEL) ++ { ++ /* set tuner RESETN pin to "H" */ ++ // Note: The GPIO3 output value should be '0'. ++ Byte &= ~BIT_3_MASK; ++ } ++ else ++ { ++ /* set tuner RESETN pin to "L" */ ++ // Note: The GPIO3 output value should be '1'. ++ Byte |= BIT_3_MASK; ++ } ++ ++ // Set GPO value. ++ if(pExtra->SetSysRegByte(pTuner, GPO_ADDR, Byte) != FUNCTION_SUCCESS) ++ goto error_status_set_system_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_set_system_registers: ++error_status_get_system_registers: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ ++int tua9001setRXEN (TUNER_MODULE *pTuner, unsigned int i_state) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ unsigned char Byte; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ // Get GPO value. ++ if(pExtra->GetSysRegByte(pTuner, GPO_ADDR, &Byte) != FUNCTION_SUCCESS) ++ goto error_status_get_system_registers; ++ ++ if (i_state == TUA9001_H_LEVEL) ++ { ++ /* set tuner RXEN pin to "H" */ ++ // Note: The GPIO1 output value should be '1'. ++ Byte |= BIT_1_MASK; ++ } ++ else ++ { ++ /* set tuner RXEN pin to "L" */ ++ // Note: The GPIO1 output value should be '0'. ++ Byte &= ~BIT_1_MASK; ++ } ++ ++ // Set GPO value. ++ if(pExtra->SetSysRegByte(pTuner, GPO_ADDR, Byte) != FUNCTION_SUCCESS) ++ goto error_status_set_system_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_set_system_registers: ++error_status_get_system_registers: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ ++int tua9001setCEN (TUNER_MODULE *pTuner, unsigned int i_state) ++{ ++ // Do nothing. ++ // Note: Hardware PCB always gives 'H' to tuner CEN pin. ++ return TUA9001_TUNER_OK; ++} ++ ++ ++ ++int tua9001waitloop (TUNER_MODULE *pTuner, unsigned int i_looptime) ++{ ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ unsigned long WaitTimeMs; ++ ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ /* wait time = i_looptime * 1 uS */ ++ // Note: 1. The unit of WaitMs() function is ms. ++ // 2. WaitTimeMs = ceil(i_looptime / 1000) ++ WaitTimeMs = i_looptime / 1000; ++ ++ if((i_looptime % 1000) > 0) ++ WaitTimeMs += 1; ++ ++ pBaseInterface->WaitMs(pBaseInterface, WaitTimeMs); ++ ++ ++ return TUA9001_TUNER_OK; ++} ++ ++ ++ ++int tua9001i2cBusWrite (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data, ++ unsigned int length) ++{ ++ ++#if 0 ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char ByteNum; ++ unsigned char WritingBytes[I2C_BUFFER_LEN]; ++ unsigned int i; ++ ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ ++ /* I2C write data format */ ++ /* STA device_address ACK register_address ACK H_Byte-Data ACK L_Byte-Data !ACK STO */ ++ ++ /* STA = start condition, ACK = Acknowledge, STO = stop condition */ ++ /* *data = pointer to data source */ ++ /* length = number of bytes to write */ ++ ++ // Determine byte number. ++ ByteNum = length + LEN_1_BYTE; ++ ++ // Determine writing bytes. ++ WritingBytes[0] = registerAddress; ++ ++ for(i = 0; i < length; i++) ++ WritingBytes[LEN_1_BYTE + i] = data[i]; ++ ++ ++ // Send I2C writing command. ++ if(pBaseInterface->I2cWrite(pBaseInterface, deviceAddress, WritingBytes, ByteNum) != FUNCTION_SUCCESS) ++ goto error_status_set_tuner_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_set_tuner_registers: ++ return TUA9001_TUNER_ERR; ++#endif ++ BASE_INTERFACE_MODULE *pBaseInterface; ++ ++ unsigned char ByteNum; ++ unsigned char WritingBytes[I2C_BUFFER_LEN]; ++ unsigned int i=0; ++ ++ I2C_BRIDGE_MODULE *pI2cBridge; ++ ++ struct dvb_usb_device *d; ++ ++ // Get base interface. ++ pBaseInterface = pTuner->pBaseInterface; ++ ++ // Get I2C bridge. ++ pI2cBridge = pTuner->pI2cBridge; ++ ++ // Get tuner device address. ++ pBaseInterface->GetUserDefinedDataPointer(pBaseInterface, (void **)&d); ++ ++ // Determine byte number. ++ ByteNum = length; ++ ++ // Determine writing bytes. ++ //WritingBytes[0] = registerAddress; ++ ++ for(i = 0; i < length; i++) ++ WritingBytes[i] = data[i]; ++ ++ // Send I2C writing command. ++ if( write_rtl2832_tuner_register( d, deviceAddress, registerAddress, WritingBytes, ByteNum ) ) ++ goto error_status_set_tuner_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_set_tuner_registers: ++ return TUA9001_TUNER_ERR; ++ ++} ++ ++ ++ ++int tua9001i2cBusRead (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data, ++ unsigned int length) ++{ ++ TUA9001_EXTRA_MODULE *pExtra; ++ ++ ++ // Get tuner extra module. ++ pExtra = &(pTuner->Extra.Tua9001); ++ ++ ++ /* I2C read data format */ ++ /* STA device_address ACK register_address ACK STA H_Byte-Data ACK device_address_read ACK H_Byte-Data ACK L_Byte-Data ACKH STO */ ++ ++ /* STA = start condition, ACK = Acknowledge (generated by TUA9001), ACKH = Acknowledge (generated by Host), STO = stop condition */ ++ /* *data = pointer to data destination */ ++ /* length = number of bytes to read */ ++ ++ // Get tuner register bytes with address. ++ // Note: We must use re-start I2C reading format for TUA9001 tuner register reading. ++ if(pExtra->GetRegBytesWithRegAddr(pTuner, deviceAddress, registerAddress, data, length) != FUNCTION_SUCCESS) ++ goto error_status_get_tuner_registers; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status_get_tuner_registers: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is source code provided by Infineon. ++ ++ ++ ++ ++ ++// Infineon source code - driver_tua9001.c ++ ++ ++/* ============================================================================ ++** Copyright (C) 1997-2007 Infineon AG All rights reserved. ++** ============================================================================ ++** ++** ============================================================================ ++** Revision Information : ++** File name: driver_tua9001.c ++** Version: V 1.01 ++** Date: ++** ++** ============================================================================ ++** History: ++** ++** Date Author Comment ++** ---------------------------------------------------------------------------- ++** ++** 2007.11.06 Walter Pichler created. ++** 2008.04.08 Walter Pichler adaption to TUA 9001E ++** ++** ============================================================================ ++*/ ++ ++/*============================================================================ ++Includes ++============================================================================*/ ++ ++//#include "driver_tua9001.h" ++//#include "driver_tua9001_NeededFunctions.h" /* Note: This function have to be provided by the user */ ++ ++/*============================================================================ ++Local compiler keeys ( usage depends on the application ) ++============================================================================*/ ++ ++#define CRYSTAL_26_0_MHZ ++//#define CRYSTAL_19_2_MHZ ++//#define CRYSTAL_20_48_MHZ ++ ++//#define AGC_BY_IIC ++//#define AGC_BY_AGC_BUS ++#define AGC_BY_EXT_PIN ++ ++ ++/*============================================================================ ++Named Constants Definitions ( usage depends on the application ) ++============================================================================*/ ++ ++#define TUNERs_TUA9001_DEVADDR 0xC0 ++ ++/* Note: The correct device address depends hardware settings. See Datasheet ++ and User Manual for details. */ ++ ++/*============================================================================ ++Local Named Constants Definitions ++============================================================================*/ ++#define OPERATIONAL_MODE 0x03 ++#define CHANNEL_BANDWITH 0x04 ++#define SW_CONTR_TIME_SLICING 0x05 ++#define BASEBAND_GAIN_CONTROL 0x06 ++#define MANUAL_BASEBAND_GAIN 0x0b ++#define REFERENCE_FREQUENCY 0x1d ++#define CHANNEL_WORD 0x1f ++#define CHANNEL_OFFSET 0x20 ++#define CHANNEL_FILTER_TRIMMING 0x2f ++#define OUTPUT_BUFFER 0x32 ++#define RF_AGC_CONFIG_A 0x36 ++#define RF_AGC_CONFIG_B 0x37 ++#define UHF_LNA_SELECT 0x39 ++#define LEVEL_DETECTOR 0x3a ++#define MIXER_CURRENT 0x3b ++#define PORT_CONTROL 0x3e ++#define CRYSTAL_TRIMMING 0x41 ++#define CHANNEL_FILTER_STATUS 0x60 ++#define SIG_STRENGHT_INDICATION 0x62 ++#define PLL_LOCK 0x69 ++#define RECEIVER_STATE 0x70 ++#define RF_INPUT 0x71 ++#define BASEBAND_GAIN 0x72 ++#define CHIP_IDENT_CODE 0x7e ++#define CHIP_REVISION 0x7f ++ ++#define TUNERs_TUA9001_BW_8 0xcf ++#define TUNERs_TUA9001_BW_7 0x10 ++#define TUNERs_TUA9001_BW_6 0x20 ++#define TUNERs_TUA9001_BW_5 0x30 ++ ++ ++ ++ ++/*============================================================================ ++ Types definition ++============================================================================*/ ++ ++ ++ ++ ++/*============================================================================ ++ Public Functions ++============================================================================*/ ++ ++ ++/** ++ * tuner initialisation ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int initializeTua9001 (TUNER_MODULE *pTuner) ++{ ++// unsigned int counter; ++ char i2cseq[2]; ++// tua9001tunerReceiverState_t tunerState; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ /* Note: CEN may also be hard wired in the application*/ ++ if(tua9001setCEN (pTuner, TUA9001_H_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* asserting Chip enable */ ++ ++ if(tua9001setRESETN (pTuner, TUA9001_L_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* asserting RESET */ ++ ++ if(tua9001setRXEN (pTuner, TUA9001_L_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* RXEN to low >> IDLE STATE */ ++ ++ /* Note: 20ms assumes that all external power supplies are settled. If not, add more time here */ ++ tua9001waitloop (pTuner, 20); /* wait for 20 uS */ ++ ++ if(tua9001setRESETN (pTuner, TUA9001_H_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* de-asserting RESET */ ++ ++ /* This is to wait for the Crystal Oscillator to settle .. wait until IDLE mode is reached */ ++// counter = 6; ++// do ++// { ++// counter --; ++// tua9001waitloop (pTuner, 1000); /* wait for 1 mS */ ++// if(getReceiverStateTua9001 (pTuner, &tunerState) != TUA9001_TUNER_OK) goto error_status; ++// }while ((tunerState != TUA9001_IDLE) && (counter)); ++ ++// if (tunerState != TUA9001_IDLE) ++// return TUA9001_TUNER_ERR; /* error >> break initialization */ ++ ++ // Replace the above check loop with 6 ms delay. ++ // Because maybe there are undefined cases in getReceiverStateTua9001(), we have to avoid using the function. ++ tua9001waitloop (pTuner, 6000); /* wait for 6 mS */ ++ ++ /**** Overwrite default register value ****/ ++ i2cseq[0] = 0x65; /* Waiting time before PLL cal. start */ ++ i2cseq[1] = 0x12; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1e, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0xB8; /* VCO Varactor bias fine tuning */ ++ i2cseq[1] = 0x88; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x25, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x54; /* LNA switching Threshold for UHF1/2 */ ++ i2cseq[1] = 0x60; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x39, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; ++ i2cseq[1] = 0xC0; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x3b, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0xF0; /* LO- Path Set LDO output voltage */ ++ i2cseq[1] = 0x00; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x3a, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; /* Set EXTAGC interval */ ++ i2cseq[1] = 0x00; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x08, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; /* Set max. capacitive load */ ++ i2cseq[1] = 0x30; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x32, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ ++ /**** Set Crystal Reference Frequency an Trim value ****/ ++ ++#if defined(CRYSTAL_26_0_MHZ) // Frequency 26 MHz ++ i2cseq[0] = 0x01; ++ i2cseq[1] = 0xB0; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1d, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x70; // NDK 3225 series 26 MHz XTAL ++ i2cseq[1] = 0x3a; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x41, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ i2cseq[0] = 0x1C; ++ i2cseq[1] = 0x78; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x40, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++#elif defined(CRYSTAL_19_2_MHZ) // Frequency 19.2 MHz ++ i2cseq[0] = 0x01; ++ i2cseq[1] = 0xA0; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1d, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ // Note: Insert optimised register values for 0x40 / 0x41 for used crystal ++ // contact application support for further information ++#elif defined(CRYSTAL_20_48_MHZ) // Frequency 20,48 MHz ++ i2cseq[0] = 0x01; ++ i2cseq[1] = 0xA8; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1d, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ // Note: Insert optimised register values for 0x40 / 0x41 for used crystal ++ // contact application support for further information ++#endif ++ ++ ++ ++ /**** Set desired Analog Baseband AGC mode ****/ ++#if defined (AGC_BY_IIC) ++ i2cseq[0] = 0x00; /* Bypass AGC controller >> IIC based AGC */ ++ i2cseq[1] = 0x40; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x06, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++#elif defined(AGC_BY_AGC_BUS) ++ i2cseq[0] = 0x00; /* Digital AGC bus */ ++ i2cseq[1] = 0x00; /* 0,5 dB steps */ ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x06, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++#elif defined(AGC_BY_EXT_PIN) ++ i2cseq[0] = 0x40; /* Ext. AGC pin */ ++ i2cseq[1] = 0x00; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x06, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++#endif ++ ++ ++ /**** set desired RF AGC parameter *****/ ++ i2cseq[0] = 0x1c; /* Set Wideband Detector Current (100 uA) */ ++ i2cseq[1] = 0x00; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x2c, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0xC0; /* Set RF AGC Threshold (-32.5dBm) */ ++ i2cseq[1] = 0x13; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x36, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x6f; /* RF AGC Parameter */ ++ i2cseq[1] = 0x18; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x37, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; /* aditional VCO settings */ ++ i2cseq[1] = 0x08; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x27, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x00; /* aditional PLL settings */ ++ i2cseq[1] = 0x01; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x2a, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ i2cseq[0] = 0x0a; /* VCM correction */ ++ i2cseq[1] = 0x40; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x34, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ ++/** ++ * tuner tune ++ * @param i_freq tuning frequency ++ * @param i_bandwidth channel bandwidth ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tuneTua9001 (TUNER_MODULE *pTuner, long i_freq, tua9001tunerDriverBW_t i_bandwidth) ++{ ++ char i2cseq[2]; ++ unsigned int divider_factor; ++ unsigned int ch_offset; ++// unsigned int counter; ++ unsigned int lo_path_settings; ++// tua9001tunerReceiverState_t tunerState; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ ++ ++ /* de-assert RXEN >> IDLE STATE */ ++ if(tua9001setRXEN (pTuner, TUA9001_L_LEVEL) != TUA9001_TUNER_OK) goto error_status; ++ ++ ++ /* calculate divider factor */ ++ if (i_freq < 1000000) /* divider factor and channel offset for UHF/VHF III */ ++ { ++ ch_offset = 0x1C20; /* channel offset 150 MHz */ ++ divider_factor = (unsigned int) (((i_freq - 150000) * 48) / 1000); ++ lo_path_settings = 0xb6de; ++ } ++ ++ else /* calculate divider factor for L-Band Frequencies */ ++ { ++ ch_offset = 0x5460; /* channel offset 450 MHz */ ++ divider_factor = (unsigned int) (((i_freq - 450000) * 48) / 1000); ++ lo_path_settings = 0xbede; ++ } ++ ++ ++ // Set LO Path ++ i2cseq[0] = lo_path_settings >> 8; ++ i2cseq[1] = lo_path_settings & 0xff; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x2b, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ // Set channel offset ++ i2cseq [0] = ch_offset >> 8; ++ i2cseq [1] = ch_offset & 0xff; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x20, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ // Set Frequency ++ i2cseq [0] = divider_factor >> 8; ++ i2cseq [1] = divider_factor & 0xff; ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x1f, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ // Set bandwidth ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x04, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; /* get current register value */ ++ i2cseq [0] &= TUNERs_TUA9001_BW_8; ++ ++ switch (i_bandwidth) ++ { ++ case TUA9001_TUNER_BANDWIDTH_8MHZ: ++ // Do nothing. ++ break; ++ case TUA9001_TUNER_BANDWIDTH_7MHZ: i2cseq [0] |= TUNERs_TUA9001_BW_7; ++ break; ++ case TUA9001_TUNER_BANDWIDTH_6MHZ: i2cseq [0] |= TUNERs_TUA9001_BW_6; ++ break; ++ case TUA9001_TUNER_BANDWIDTH_5MHZ: i2cseq [0] |= TUNERs_TUA9001_BW_5; ++ break; ++ default: ++ goto error_status; ++ break; ++ } ++ ++ if(tua9001i2cBusWrite (pTuner, DeviceAddr, 0x04, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; ++ ++ /* assert RXEN >> RX STATE */ ++ if(tua9001setRXEN (pTuner, TUA9001_H_LEVEL) != TUA9001_TUNER_OK) goto error_status; ++ ++ /* This is to wait for the RX state to settle .. wait until RX mode is reached */ ++// counter = 3; ++// do ++// { ++// counter --; ++// tua9001waitloop (pTuner, 1000); /* wait for 1 mS */ ++// if(getReceiverStateTua9001 (pTuner, &tunerState) != TUA9001_TUNER_OK) goto error_status; ++// }while ((tunerState != TUA9001_RX) && (counter)); ++ ++// if (tunerState != TUA9001_RX) ++// { ++// if(tua9001setRXEN (pTuner, TUA9001_L_LEVEL) != TUA9001_TUNER_OK) goto error_status; /* d-assert RXEN >> IDLE STATE */ ++// return TUA9001_TUNER_ERR; /* error >> tuning fail */ ++// } ++ ++ // Replace the above check loop with 3 ms delay. ++ // Because maybe there are undefined cases in getReceiverStateTua9001(), we have to avoid using the function. ++ tua9001waitloop (pTuner, 3000); /* wait for 3 mS */ ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++/** ++ * Get pll locked state ++ * @param o_pll pll locked state ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int getPllLockedStateTua9001 (TUNER_MODULE *pTuner, tua9001tunerPllLocked_t *o_pll) ++{ ++ char i2cseq[2]; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x69, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; /* get current register value */ ++ ++ o_pll[0] = (i2cseq[1] & 0x08) ? TUA9001_PLL_LOCKED : TUA9001_PLL_NOT_LOCKED; ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++/** ++ * Get tuner state ++ * @param o_tunerState tuner state ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++/* ++int getReceiverStateTua9001 (TUNER_MODULE *pTuner, tua9001tunerReceiverState_t *o_tunerState) ++{ ++ char i2cseq[2]; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x70, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; // get current register value ++ ++// switch (i2cseq[1] & ~0x1f) ++ // Note: Maybe the MSB byte is i2cseq[0] ++ // The original code looks like the MSB byte is i2cseq[1] ++ // Note: ~0x1f = 0xffffffe0, not 0xe0 --> i2cseq[0] & ~0x1f result is wrong. ++ switch (i2cseq[0] & 0xe0) ++ { ++ case 0x80: o_tunerState [0] = TUA9001_IDLE; break; ++ case 0x40: o_tunerState [0] = TUA9001_RX; break; ++ case 0x20: o_tunerState [0] = TUA9001_STANDBY; break; ++ default: goto error_status; break; ++ } ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++*/ ++ ++/** ++ * Get active input ++ * @param o_activeInput active input info ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++/* ++int getActiveInputTua9001 (TUNER_MODULE *pTuner, tua9001tunerActiveInput_t *o_activeInput) ++{ ++ char i2cseq[2]; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x71, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; // get current register value ++ ++// switch (i2cseq[1] & ~0x0f) ++ // Note: Maybe the MSB byte is i2cseq[0] ++ // The original code looks like the MSB byte is i2cseq[1] ++ // Note: ~0x0f = 0xfffffff0, not 0xf0 --> i2cseq[0] & ~0x0f result is wrong. ++ switch (i2cseq[0] & 0xf0) ++ { ++ case 0x80: o_activeInput [0] = TUA9001_L_INPUT_ACTIVE; break; ++ case 0x20: o_activeInput [0] = TUA9001_UHF_INPUT_ACTIVE; break; ++ case 0x10: o_activeInput [0] = TUA9001_VHF_INPUT_ACTIVE; break; ++ default: goto error_status; break; ++ } ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++*/ ++ ++/** ++ * Get baseband gain value ++ * @param o_basebandGain baseband gain value ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int getBasebandGainTua9001 (TUNER_MODULE *pTuner, char *o_basebandGain) ++{ ++ char i2cseq[2]; ++ unsigned char DeviceAddr; ++ ++ // Get tuner deviece address. ++ pTuner->GetDeviceAddr(pTuner, &DeviceAddr); ++ ++ if(tua9001i2cBusRead (pTuner, DeviceAddr, 0x72, i2cseq, 2) != TUA9001_TUNER_OK) goto error_status; /* get current register value */ ++// o_basebandGain [0] = i2cseq [1]; ++ // Note: Maybe the MSB byte is i2cseq[0] ++ // The original code looks like the MSB byte is i2cseq[1] ++ o_basebandGain [0] = i2cseq [0]; ++ ++ return TUA9001_TUNER_OK; ++ ++ ++error_status: ++ return TUA9001_TUNER_ERR; ++} ++ ++ ++ +diff -rpuN a/drivers/media/dvb/dvb-usb/tuner_tua9001.h b/drivers/drivers/media/dvb/dvb-usb/tuner_tua9001.h +--- a/drivers/media/dvb/dvb-usb/tuner_tua9001.h 1969-12-31 21:00:00.000000000 -0300 ++++ b/drivers/drivers/media/dvb/dvb-usb/tuner_tua9001.h 2016-04-02 19:17:52.180066045 -0300 +@@ -0,0 +1,493 @@ ++#ifndef __TUNER_TUA9001_H ++#define __TUNER_TUA9001_H ++ ++/** ++ ++@file ++ ++@brief TUA9001 tuner module declaration ++ ++One can manipulate TUA9001 tuner through TUA9001 module. ++TUA9001 module is derived from tunerd module. ++ ++ ++ ++@par Example: ++@code ++ ++// The example is the same as the tuner example in tuner_base.h except the listed lines. ++ ++ ++ ++#include "tuner_tua9001.h" ++ ++ ++... ++ ++ ++ ++int main(void) ++{ ++ TUNER_MODULE *pTuner; ++ TUA9001_EXTRA_MODULE *pTunerExtra; ++ ++ TUNER_MODULE TunerModuleMemory; ++ BASE_INTERFACE_MODULE BaseInterfaceModuleMemory; ++ I2C_BRIDGE_MODULE I2cBridgeModuleMemory; ++ ++ int BandwidthMode; ++ ++ ++ ... ++ ++ ++ ++ // Build TUA9001 tuner module. ++ BuildTua9001Module( ++ &pTuner, ++ &TunerModuleMemory, ++ &BaseInterfaceModuleMemory, ++ &I2cBridgeModuleMemory, ++ 0xc0 // I2C device address is 0xc0 in 8-bit format. ++ ); ++ ++ ++ ++ ++ ++ // Get TUA9001 tuner extra module. ++ pTunerExtra = (T2266_EXTRA_MODULE *)(pTuner->pExtra); ++ ++ ++ ++ ++ ++ // ==== Initialize tuner and set its parameters ===== ++ ++ ... ++ ++ // Set TUA9001 bandwidth. ++ pTunerExtra->SetBandwidthMode(pTuner, TUA9001_BANDWIDTH_6MHZ); ++ ++ ++ ++ ++ ++ // ==== Get tuner information ===== ++ ++ ... ++ ++ // Get TUA9001 bandwidth. ++ pTunerExtra->GetBandwidthMode(pTuner, &BandwidthMode); ++ ++ ++ ++ ++ ++ // See the example for other tuner functions in tuner_base.h ++ ++ ++ return 0; ++} ++ ++ ++@endcode ++ ++*/ ++ ++ ++#include "tuner_base.h" ++//#include "i2c_rtl2832usb.h" ++ ++ ++ ++ ++ ++// The following context is source code provided by Infineon. ++ ++ ++ ++ ++ ++// Infineon source code - driver_tua9001.h ++ ++ ++ ++/* ============================================================================ ++** Copyright (C) 1997-2007 Infineon AG All rights reserved. ++** ============================================================================ ++** ++** ============================================================================ ++** Revision Information : ++** File name: driver_tua9001.h ++** Version: ++** Date: ++** ++** ============================================================================ ++** History: ++** ++** Date Author Comment ++** ---------------------------------------------------------------------------- ++** ++** 2007.11.06 Walter Pichler created. ++** ============================================================================ ++*/ ++ ++ ++/*============================================================================ ++ Named Constants Definitions ++============================================================================*/ ++ ++#define TUA9001_TUNER_OK 0 ++#define TUA9001_TUNER_ERR 0xff ++ ++#define TUA9001_H_LEVEL 1 ++#define TUA9001_L_LEVEL 0 ++ ++ ++/*============================================================================ ++ Types definition ++============================================================================*/ ++ ++ ++typedef enum { ++ TUA9001_TUNER_BANDWIDTH_8MHZ, ++ TUA9001_TUNER_BANDWIDTH_7MHZ, ++ TUA9001_TUNER_BANDWIDTH_6MHZ, ++ TUA9001_TUNER_BANDWIDTH_5MHZ, ++ } tua9001tunerDriverBW_t; ++ ++ ++typedef enum { ++ TUA9001_PLL_LOCKED, ++ TUA9001_PLL_NOT_LOCKED ++ }tua9001tunerPllLocked_t; ++ ++ ++typedef enum { ++ TUA9001_STANDBY, ++ TUA9001_IDLE, ++ TUA9001_RX ++ } tua9001tunerReceiverState_t; ++ ++ ++typedef enum { ++ TUA9001_L_INPUT_ACTIVE, ++ TUA9001_UHF_INPUT_ACTIVE, ++ TUA9001_VHF_INPUT_ACTIVE ++ } tua9001tunerActiveInput_t; ++ ++ ++ ++/*============================================================================ ++ Public functions ++============================================================================*/ ++ ++/** ++ * tuner initialisation ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int initializeTua9001 (TUNER_MODULE *pTuner); ++ ++ ++/** ++ * tuner tune ++ * @param i_freq tuning frequency ++ * @param i_bandwidth channel bandwidth ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int tuneTua9001 (TUNER_MODULE *pTuner, long i_freq, tua9001tunerDriverBW_t i_bandwidth); ++ ++ ++/** ++ * Get tuner state ++ * @param o_tunerState tuner state ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int getReceiverStateTua9001 (TUNER_MODULE *pTuner, tua9001tunerReceiverState_t *o_tunerState); ++ ++/** ++ * Get active input ++ * @param o_activeInput active input info ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int getActiveInputTua9001 (TUNER_MODULE *pTuner, tua9001tunerActiveInput_t *o_activeInput); ++ ++ ++/** ++ * Get baseband gain value ++ * @param o_basebandGain baseband gain value ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++extern int getBasebandGainTua9001 (TUNER_MODULE *pTuner, char *o_basebandGain); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// Infineon source code - driver_tua9001_NeededFunctions.h ++ ++ ++ ++/*======================================================================================================================== ++ additional needed external funtions ( have to be provided by the user! ) ++========================================================================================================================*/ ++ ++/** ++ * set / reset tuner reset input ++ * @param i_state level ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tua9001setRESETN (TUNER_MODULE *pTuner, unsigned int i_state); ++ ++ ++/** ++ * set / reset tuner receive enable input ++ * @param i_state level ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tua9001setRXEN (TUNER_MODULE *pTuner, unsigned int i_state); ++ ++ ++/** ++ * set / reset tuner chiop enable input ++ * @param i_state level ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tua9001setCEN (TUNER_MODULE *pTuner, unsigned int i_state); ++ ++ ++/** ++ * waitloop ++ * @param i_looptime * 1uS ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++int tua9001waitloop (TUNER_MODULE *pTuner, unsigned int i_looptime); ++ ++ ++/** ++ * i2cBusWrite ++ * @param deviceAdress chip address ++ * @param registerAdress register address ++ * @param *data pointer to data source ++ * @param length number of bytes to transmit ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++ int tua9001i2cBusWrite (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data, ++ unsigned int length); ++ ++ ++/** ++ * i2cBusRead ++ * @param deviceAdress chip address ++ * @param registerAdress register address ++ * @param *data pointer to data destination ++ * @param length number of bytes to read ++ * @retval TUA9001_TUNER_OK No error ++ * @retval TUA9001_TUNER_ERR Error ++*/ ++ ++ int tua9001i2cBusRead (TUNER_MODULE *pTuner, unsigned char deviceAddress, unsigned char registerAddress, char *data, ++ unsigned int length); ++ ++/*======================================================================================================================== ++ end of additional needed external funtions ++========================================================================================================================*/ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++// The following context is TUA9001 tuner API source code ++ ++ ++ ++ ++ ++/** ++ ++@file ++ ++@brief TUA9001 tuner module declaration ++ ++One can manipulate TUA9001 tuner through TUA9001 module. ++TUA9001 module is derived from tuner module. ++ ++*/ ++ ++ ++ ++ ++ ++// Definitions ++ ++// Constant ++#define GPO_ADDR 0x1 ++ ++// Bandwidth modes ++enum TUA9001_BANDWIDTH_MODE ++{ ++ TUA9001_BANDWIDTH_5MHZ = TUA9001_TUNER_BANDWIDTH_5MHZ, ++ TUA9001_BANDWIDTH_6MHZ = TUA9001_TUNER_BANDWIDTH_6MHZ, ++ TUA9001_BANDWIDTH_7MHZ = TUA9001_TUNER_BANDWIDTH_7MHZ, ++ TUA9001_BANDWIDTH_8MHZ = TUA9001_TUNER_BANDWIDTH_8MHZ, ++}; ++ ++// Default value ++#define TUA9001_RF_FREQ_HZ_DEFAULT 50000000; ++#define TUA9001_BANDWIDTH_MODE_DEFAULT TUA9001_BANDWIDTH_5MHZ; ++ ++ ++ ++ ++ ++// Builder ++void ++BuildTua9001Module( ++ TUNER_MODULE **ppTuner, ++ TUNER_MODULE *pTunerModuleMemory, ++ BASE_INTERFACE_MODULE *pBaseInterfaceModuleMemory, ++ I2C_BRIDGE_MODULE *pI2cBridgeModuleMemory, ++ unsigned char DeviceAddr ++ ); ++ ++ ++ ++ ++ ++// Manipulaing functions ++void ++tua9001_GetTunerType( ++ TUNER_MODULE *pTuner, ++ int *pTunerType ++ ); ++ ++void ++tua9001_GetDeviceAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char *pDeviceAddr ++ ); ++ ++int ++tua9001_Initialize( ++ TUNER_MODULE *pTuner ++ ); ++ ++int ++tua9001_SetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long RfFreqHz ++ ); ++ ++int ++tua9001_GetRfFreqHz( ++ TUNER_MODULE *pTuner, ++ unsigned long *pRfFreqHz ++ ); ++ ++ ++ ++ ++ ++// Extra manipulaing functions ++int ++tua9001_SetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int BandwidthMode ++ ); ++ ++int ++tua9001_GetBandwidthMode( ++ TUNER_MODULE *pTuner, ++ int *pBandwidthMode ++ ); ++ ++int ++tua9001_GetRegBytesWithRegAddr( ++ TUNER_MODULE *pTuner, ++ unsigned char DeviceAddr, ++ unsigned char RegAddr, ++ unsigned char *pReadingBytes, ++ unsigned char ByteNum ++ ); ++ ++int ++tua9001_SetSysRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char WritingByte ++ ); ++ ++int ++tua9001_GetSysRegByte( ++ TUNER_MODULE *pTuner, ++ unsigned short RegAddr, ++ unsigned char *pReadingByte ++ ); ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++#endif +diff -rpuN a/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig +--- a/media/dvb/dvb-usb/Kconfig 2016-04-02 14:51:42.000000000 -0300 ++++ b/drivers/media/dvb/dvb-usb/Kconfig 2016-04-02 19:14:37.716065720 -0300 +@@ -422,3 +422,10 @@ config DVB_USB_RTL28XXU + select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE + help + Say Y here to support the Realtek RTL28xxU DVB USB receiver. ++ ++config DVB_USB_RTL2832U ++ tristate "Realtek RTL2832 DVB-T USB2.0 support" ++ depends on DVB_USB && EXPERIMENTAL ++ default m ++ help ++ Say Y or M to support the Realtek RTL2832 / R820T DVB-T receiver +diff -rpuN a/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile +--- a/media/dvb/dvb-usb/Makefile 2016-04-02 14:51:42.000000000 -0300 ++++ b/drivers/media/dvb/dvb-usb/Makefile 2016-04-02 19:14:37.680065762 -0300 +@@ -109,6 +109,18 @@ obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111 + + dvb-usb-rtl28xxu-objs = rtl28xxu.o + obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o ++# DVB-T (Realtek RTL2832 - Rafael Micro r820t) ++dvb-usb-rtl2832u-objs := demod_rtl2832.o dvbt_demod_base.o dvbt_nim_base.o foundation.o \ ++ math_mpi.o nim_rtl2832_mxl5007t.o nim_rtl2832_fc2580.o nim_rtl2832_mt2266.o \ ++ rtl2832u.o rtl2832u_fe.o rtl2832u_io.o tuner_mxl5007t.o tuner_fc2580.o \ ++ tuner_mt2266.o tuner_tua9001.o nim_rtl2832_tua9001.o tuner_fc0012.o \ ++ nim_rtl2832_fc0012.o demod_rtl2836.o dtmb_demod_base.o dtmb_nim_base.o \ ++ nim_rtl2836_fc2580.o nim_rtl2836_mxl5007t.o tuner_e4000.o nim_rtl2832_e4000.o \ ++ tuner_mt2063.o demod_rtl2840.o tuner_max3543.o nim_rtl2832_mt2063.o \ ++ nim_rtl2832_max3543.o nim_rtl2840_mt2063.o nim_rtl2840_max3543.o \ ++ qam_demod_base.o qam_nim_base.o tuner_tda18272.o nim_rtl2832_tda18272.o \ ++ nim_rtl2832_fc0013.o tuner_fc0013.o rtl2832u_audio.o tuner_r820t.o nim_rtl2832_r820t.o ++obj-$(CONFIG_DVB_USB_RTL2832U) += dvb-usb-rtl2832u.o + + ccflags-y += -I$(srctree)/drivers/media/dvb/dvb-core + ccflags-y += -I$(srctree)/drivers/media/dvb/frontends/ diff --git a/projects/H3/patches/linux/linux-501_tivo_slide_pro.patch b/projects/H3/patches/linux/linux-501_tivo_slide_pro.patch new file mode 100644 index 00000000000..4fea6965239 --- /dev/null +++ b/projects/H3/patches/linux/linux-501_tivo_slide_pro.patch @@ -0,0 +1,57 @@ +From 716d6bc9f73bd366d4b64b473055af79810d67fc Mon Sep 17 00:00:00 2001 +From: Forest +Date: Thu, 12 Mar 2015 23:43:12 -0700 +Subject: [PATCH] hid: enable all buttons on the TiVo Slide Pro remote + +The linux kernel has supported the TiVo Slide remote control for some time, +but does not recognize the USB ID of the newer Slide Pro. This patch adds +the missing data structures so the newer remote will be recognized by the +driver, thereby allowing the TiVo, LiveTV, and Thumbs Up/Down buttons to be +mapped with a hwdb file. + +Signed-off-by: Forest +--- + drivers/hid/hid-core.c | 1 + + drivers/hid/hid-ids.h | 1 + + drivers/hid/hid-tivo.c | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 1d0f2b6..722a925 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1980,6 +1980,7 @@ static const struct hid_device_id hid_have_special_driver[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index 2dd6485..c739d3b 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -900,6 +900,7 @@ + #define USB_VENDOR_ID_TIVO 0x150a + #define USB_DEVICE_ID_TIVO_SLIDE_BT 0x1200 + #define USB_DEVICE_ID_TIVO_SLIDE 0x1201 ++#define USB_DEVICE_ID_TIVO_SLIDE_PRO 0x1203 + + #define USB_VENDOR_ID_TOPSEED 0x0766 + #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 +diff --git a/drivers/hid/hid-tivo.c b/drivers/hid/hid-tivo.c +index d790d8d..d986969 100644 +--- a/drivers/hid/hid-tivo.c ++++ b/drivers/hid/hid-tivo.c +@@ -64,6 +64,7 @@ static const struct hid_device_id tivo_devices[] = { + /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_PRO) }, + { } + }; + MODULE_DEVICE_TABLE(hid, tivo_devices); +-- +1.9.1 + diff --git a/projects/H3/patches/linux/linux-502-ouya_controller_support.patch b/projects/H3/patches/linux/linux-502-ouya_controller_support.patch new file mode 100644 index 00000000000..f625eb79ee1 --- /dev/null +++ b/projects/H3/patches/linux/linux-502-ouya_controller_support.patch @@ -0,0 +1,315 @@ +diff -Naur linux-3.15-rc6.orig/drivers/hid/hid-core.c linux-3.15-rc6/drivers/hid/hid-core.c +--- linux-3.15-rc6.orig/drivers/hid/hid-core.c 2014-06-06 13:46:49.711845049 -0700 ++++ linux-3.15-rc6/drivers/hid/hid-core.c 2014-06-06 13:50:33.019965538 -0700 +@@ -1848,6 +1848,7 @@ + { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT780) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT880) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_OUYA, USB_DEVICE_ID_OUYA_CONTROLLER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) }, +diff -Naur linux-3.15-rc6.orig/drivers/hid/hid-ids.h linux-3.15-rc6/drivers/hid/hid-ids.h +--- linux-3.15-rc6.orig/drivers/hid/hid-ids.h 2014-06-06 13:46:49.711845049 -0700 ++++ linux-3.15-rc6/drivers/hid/hid-ids.h 2014-06-06 13:51:36.146564828 -0700 +@@ -700,6 +700,9 @@ + #define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 + #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 + ++#define USB_VENDOR_ID_OUYA 0x2836 ++#define USB_DEVICE_ID_OUYA_CONTROLLER 0x0001 ++ + #define USB_VENDOR_ID_PANASONIC 0x04da + #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 + #define USB_DEVICE_ID_PANABOARD_UBT880 0x104d +diff -Naur linux-3.15-rc6.orig/drivers/hid/hid-ouya.c linux-3.15-rc6/drivers/hid/hid-ouya.c +--- linux-3.15-rc6.orig/drivers/hid/hid-ouya.c 1969-12-31 16:00:00.000000000 -0800 ++++ linux-3.15-rc6/drivers/hid/hid-ouya.c 2014-06-06 13:52:22.785007560 -0700 +@@ -0,0 +1,260 @@ ++/* ++ * HID driver for OUYA Game Controller(s) ++ * ++ * Copyright (c) 2013 OUYA ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "hid-ids.h" ++ ++#define OUYA_TOUCHPAD_FIXUP (1 << 0) ++ ++struct ouya_sc { ++ unsigned long quirks; ++}; ++ ++/* Fixed report descriptor */ ++static __u8 ouya_rdesc_fixed[] = { ++ ++ 0x05, 0x01, /* Usage Page (Desktop), */ ++ 0x09, 0x05, /* Usage (Game Pad), */ ++ ++ 0xA1, 0x01, /* Collection (Application), */ ++ 0x85, 0x07, /* Report ID (7), */ ++ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x09, 0x30, /* Usage (X), */ ++ 0x09, 0x31, /* Usage (Y), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x35, 0x00, /* Physical Minimum (0), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x95, 0x02, /* Report Count (2), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x09, 0x33, /* Usage (Rx), */ ++ 0x09, 0x34, /* Usage (Ry), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x35, 0x00, /* Physical Minimum (0), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x95, 0x02, /* Report Count (2), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x09, 0x32, /* Usage (Z), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x35, 0x00, /* Physical Minimum (0), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x95, 0x01, /* Report Count (1), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x09, 0x35, /* Usage (Rz), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x35, 0x00, /* Physical Minimum (0), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x95, 0x01, /* Report Count (1), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0x05, 0x09, /* Usage Page (Button), */ ++ 0x19, 0x01, /* Usage Minimum (01h), */ ++ 0x29, 0x10, /* Usage Maximum (10h), */ ++ 0x95, 0x10, /* Report Count (16), */ ++ 0x75, 0x01, /* Report Size (1), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ ++ /* ORIGINAL REPORT DESCRIPTOR FOR TOUCHPAD INPUT */ ++ /* 06 00 ff a1 02 09 02 15 00 26 ff 00 35 00 46 ff 00 95 03 75 08 81 02 c0 */ ++ ++ 0x06, 0x00, 0xFF, /* Usage Page (Custom), */ ++ 0x09, 0x02, /* Usage (Mouse), */ ++ 0x09, 0x01, /* Usage (Pointer), */ ++ 0xA1, 0x00, /* Collection (Physical), */ ++ 0x05, 0x09, /* Usage Page (Button), */ ++ 0x19, 0x01, /* Usage Minimum (01h), */ ++ 0x29, 0x03, /* Usage Maximum (03h), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x25, 0x01, /* Logical Maximum (1), */ ++ 0x95, 0x03, /* Report Count (3), */ ++ 0x75, 0x01, /* Report Size (1), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0x95, 0x01, /* Report Count (1), */ ++ 0x75, 0x05, /* Report Size (5), */ ++ 0x81, 0x01, /* Input (Constant), */ ++ 0x05, 0x01, /* Usage Page (Desktop), */ ++ 0x09, 0x30, /* Usage (X), */ ++ 0x09, 0x31, /* Usage (Y), */ ++ 0x15, 0x81, /* Logical Minimum (-127), */ ++ 0x25, 0x7f, /* Logical Maximum (127), */ ++ 0x95, 0x02, /* Report Count (2), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x81, 0x06, /* Input (Relative), */ ++ 0xC0, /* End Collection, */ ++ ++ 0x06, 0x00, 0xFF, /* Usage Page (Custom), */ ++ 0xA1, 0x02, /* Collection (Logical), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x95, 0x07, /* Report Count (7), */ ++ 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x09, 0x01, /* Usage (Pointer), */ ++ 0x91, 0x02, /* Output (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xC0, /* End Collection */ ++ ++ ++ 0x06, 0x00, 0xFF, /* Usage Page (Custom), */ ++ 0x05, 0x0C, /* Usage Page (Consumer), */ ++ 0x09, 0x01, /* Usage (Consumer Control), */ ++ ++ 0xA1, 0x01, /* Collection (Application), */ ++ 0x85, 0x03, /* Report ID (3), */ ++ 0x05, 0x01, /* Usage Page (Desktop), */ ++ 0x09, 0x06, /* Usage (Keyboard), */ ++ 0xA1, 0x02, /* Collection (Logical), */ ++ 0x05, 0x06, /* Usage Page (Generic), */ ++ 0x09, 0x20, /* Usage (Battery Strgth), */ ++ 0x15, 0x00, /* Logical Minimum (0), */ ++ 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x95, 0x01, /* Report Count (1), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0x06, 0xBC, 0xFF, /* Usage Page (Custom), */ ++ ++ 0x0A, 0xAD, 0xBD, /* UNKNOWN */ ++ ++ 0x75, 0x08, /* Report Size (8), */ ++ 0x95, 0x06, /* Report Count (6), */ ++ 0x81, 0x02, /* Input (Variable), */ ++ 0xC0, /* End Collection, */ ++ ++ 0xC0, /* End Collection */ ++ ++ 0x00 ++}; ++ ++static __u8 *ouya_report_fixup(struct hid_device *hdev, __u8 *rdesc, ++ unsigned int *rsize) ++{ ++ struct ouya_sc *sc = hid_get_drvdata(hdev); ++ ++ if (sc->quirks & OUYA_TOUCHPAD_FIXUP) { ++ rdesc = ouya_rdesc_fixed; ++ *rsize = sizeof(ouya_rdesc_fixed); ++ } ++ return rdesc; ++} ++ ++static int ouya_input_mapping(struct hid_device *hdev, struct hid_input *hi, ++ struct hid_field *field, struct hid_usage *usage, ++ unsigned long **bit, int *max) ++{ ++ struct ouya_sc *sc = hid_get_drvdata(hdev); ++ ++ if (!(sc->quirks & OUYA_TOUCHPAD_FIXUP)) { ++ return 0; ++ } ++ ++ if ((usage->hid & 0x90000) == 0x90000 && ++ (field->physical & 0xff000000) == 0xff000000 && ++ usage->collection_index == 5 && ++ field->report_count == 3) { ++ ++ hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_MOUSE + (usage->hid - 0x90001)); ++ ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int ouya_probe(struct hid_device *hdev, const struct hid_device_id *id) ++{ ++ int ret; ++ struct ouya_sc *sc; ++ ++ sc = kzalloc(sizeof(*sc), GFP_KERNEL); ++ if (sc == NULL) { ++ hid_err(hdev, "can't alloc ouya descriptor\n"); ++ return -ENOMEM; ++ } ++ ++ if(((hdev->version & 0xff00) == 0x0100 && (hdev->version & 0xff) >= 0x04) || ++ ((hdev->version & 0xff00) == 0xe100 && (hdev->version & 0xff) >= 0x3a)) { ++ hid_info(hdev, "ouya controller - new version\n"); ++ sc->quirks = OUYA_TOUCHPAD_FIXUP; ++ } else { ++ sc->quirks = 0; ++ } ++ hid_set_drvdata(hdev, sc); ++ ++ ret = hid_parse(hdev); ++ if (ret) { ++ hid_err(hdev, "parse failed\n"); ++ goto err_free; ++ } ++ ++ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ++ HID_CONNECT_HIDDEV_FORCE); ++ if (ret) { ++ hid_err(hdev, "hw start failed\n"); ++ goto err_free; ++ } ++ ++ return 0; ++ ++err_free: ++ kfree(sc); ++ return ret; ++} ++ ++static void ouya_remove(struct hid_device *hdev) ++{ ++ hid_hw_stop(hdev); ++ kfree(hid_get_drvdata(hdev)); ++} ++ ++static const struct hid_device_id ouya_devices[] = { ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_OUYA, USB_DEVICE_ID_OUYA_CONTROLLER) }, ++ { } ++}; ++MODULE_DEVICE_TABLE(hid, ouya_devices); ++ ++static struct hid_driver ouya_driver = { ++ .name = "ouya", ++ .id_table = ouya_devices, ++ .probe = ouya_probe, ++ .remove = ouya_remove, ++ .input_mapping = ouya_input_mapping, ++ .report_fixup = ouya_report_fixup ++}; ++ ++static int __init ouya_init(void) ++{ ++ return hid_register_driver(&ouya_driver); ++} ++ ++static void __exit ouya_exit(void) ++{ ++ hid_unregister_driver(&ouya_driver); ++} ++ ++module_init(ouya_init); ++module_exit(ouya_exit); +diff -Naur linux-3.15-rc6.orig/drivers/hid/Kconfig linux-3.15-rc6/drivers/hid/Kconfig +--- linux-3.15-rc6.orig/drivers/hid/Kconfig 2014-06-06 13:46:49.710845040 -0700 ++++ linux-3.15-rc6/drivers/hid/Kconfig 2014-06-06 13:48:41.674908325 -0700 +@@ -499,6 +499,12 @@ + - Ortek WKB-2000 + - Skycable wireless presenter + ++config HID_OUYA ++ tristate "OUYA Game Controller" ++ depends on USB_HID ++ ---help--- ++ Support for OUYA Game Controller. ++ + config HID_PANTHERLORD + tristate "Pantherlord/GreenAsia game controller" + depends on HID +diff -Naur linux-3.15-rc6.orig/drivers/hid/Makefile linux-3.15-rc6/drivers/hid/Makefile +--- linux-3.15-rc6.orig/drivers/hid/Makefile 2014-06-06 13:46:49.710845040 -0700 ++++ linux-3.15-rc6/drivers/hid/Makefile 2014-06-06 13:49:23.951309760 -0700 +@@ -68,6 +68,7 @@ + obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o + obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o + obj-$(CONFIG_HID_ORTEK) += hid-ortek.o ++obj-$(CONFIG_HID_OUYA) += hid-ouya.o + obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o + obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o + obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o diff --git a/projects/H3/patches/linux/linux-503-XBOX_remote_support.patch b/projects/H3/patches/linux/linux-503-XBOX_remote_support.patch new file mode 100644 index 00000000000..42df23407ed --- /dev/null +++ b/projects/H3/patches/linux/linux-503-XBOX_remote_support.patch @@ -0,0 +1,1029 @@ +diff -Naur linux-3.9.4/drivers/staging/media/lirc/Kconfig linux-3.9.4.patch/drivers/staging/media/lirc/Kconfig +--- linux-3.9.4/drivers/staging/media/lirc/Kconfig 2013-05-24 20:45:59.000000000 +0200 ++++ linux-3.9.4.patch/drivers/staging/media/lirc/Kconfig 2013-05-30 18:18:57.238957100 +0200 +@@ -63,10 +63,17 @@ + help + Driver for the SIR IrDA port + ++config LIRC_XBOX ++ tristate "XBOX USB IR Remote" ++ depends on LIRC && USB ++ help ++ Driver for the Microsoft XBOX USB IR Remote ++ + config LIRC_ZILOG + tristate "Zilog/Hauppauge IR Transmitter" + depends on LIRC && I2C + help + Driver for the Zilog/Hauppauge IR Transmitter, found on + PVR-150/500, HVR-1200/1250/1700/1800, HD-PVR and other cards ++ + endif +diff -Naur linux-3.9.4/drivers/staging/media/lirc/lirc_xbox.c linux-3.9.4.patch/drivers/staging/media/lirc/lirc_xbox.c +--- linux-3.9.4/drivers/staging/media/lirc/lirc_xbox.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.9.4.patch/drivers/staging/media/lirc/lirc_xbox.c 2013-05-30 18:40:22.523775446 +0200 +@@ -0,0 +1,995 @@ ++/* ++ * lirc_xbox - USB remote support for LIRC ++ * (supports Microsoft XBOX DVD Dongle) ++ * ++ * Copyright (C) 2003-2004 Paul Miller ++ * ++ * This driver was derived from: ++ * Vladimir Dergachev 's 2002 ++ * "USB ATI Remote support" (input device) ++ * Adrian Dewhurst 's 2002 ++ * "USB StreamZap remote driver" (LIRC) ++ * Artur Lipowski 's 2002 ++ * "lirc_dev" and "lirc_gpio" LIRC modules ++ * Michael Wojciechowski ++ * initial xbox support ++ * Vassilis Virvilis 2006 ++ * reworked the patch for lirc submission ++ * Paul Miller's 2004 ++ * lirc_atiusb - removed all ati remote support ++ * $Id: lirc_xbox.c,v 1.88 2011/06/03 11:11:11 jmartin Exp $ ++ */ ++ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++ ++//#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33) ++//#include ++//#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++//#include "drivers/kcompat.h" ++//#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35) ++#include ++#include ++//#else ++//#include "drivers/lirc.h" ++//#include "drivers/lirc_dev/lirc_dev.h" ++//#endif ++ ++#define DRIVER_VERSION "$Revision: 0.01 $" ++#define DRIVER_AUTHOR "Jason Martin " ++#define DRIVER_DESC "XBOX DVD Dongle USB remote driver for LIRC" ++#define DRIVER_NAME "lirc_xbox" ++ ++#define CODE_LENGTH 6 ++#define CODE_MIN_LENGTH 6 ++#define DECODE_LENGTH 1 ++ ++#ifndef URB_ASYNC_UNLINK ++#define URB_ASYNC_UNLINK 0 ++#endif ++ ++/* module parameters */ ++#ifdef CONFIG_USB_DEBUG ++static int debug = 1; ++#else ++static int debug; ++#endif ++ ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG fmt, ## args); \ ++ } while (0) ++ ++/* ++ * USB_BUFF_LEN must be the maximum value of the code_length array. ++ * It is used for static arrays. ++ */ ++#define USB_BUFF_LEN 6 ++ ++static int mask = 0xFFFF; /* channel acceptance bit mask */ ++static int unique; /* enable channel-specific codes */ ++static int repeat = 10; /* repeat time in 1/100 sec */ ++static unsigned long repeat_jiffies; /* repeat timeout */ ++ ++/* get hi and low bytes of a 16-bits int */ ++#define HI(a) ((unsigned char)((a) >> 8)) ++#define LO(a) ((unsigned char)((a) & 0xff)) ++ ++/* general constants */ ++#define SEND_FLAG_IN_PROGRESS 1 ++#define SEND_FLAG_COMPLETE 2 ++#define FREE_ALL 0xFF ++ ++/* endpoints */ ++#define EP_KEYS 0 ++#define EP_MOUSE 1 ++#define EP_MOUSE_ADDR 0x81 ++#define EP_KEYS_ADDR 0x82 ++ ++/* USB vendor ids for XBOX DVD Dongles */ ++#define VENDOR_MS1 0x040b ++#define VENDOR_MS2 0x045e ++#define VENDOR_MS3 0xFFFF ++ ++static struct usb_device_id usb_remote_table[] = { ++ /* Gamester Xbox DVD Movie Playback Kit IR */ ++ { USB_DEVICE(VENDOR_MS1, 0x6521) }, ++ ++ /* Microsoft Xbox DVD Movie Playback Kit IR */ ++ { USB_DEVICE(VENDOR_MS2, 0x0284) }, ++ ++ /* ++ * Some Chinese manufacturer -- conflicts with the joystick from the ++ * same manufacturer ++ */ ++ { USB_DEVICE(VENDOR_MS3, 0xFFFF) }, ++ ++ /* Terminating entry */ ++ { } ++}; ++ ++/* init strings */ ++#define USB_OUTLEN 7 ++ ++static char init1[] = {0x01, 0x00, 0x20, 0x14}; ++static char init2[] = {0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20}; ++ ++struct in_endpt { ++ /* inner link in list of endpoints for the remote specified by ir */ ++ struct list_head iep_list_link; ++ struct xbox_dev *ir; ++ struct urb *urb; ++ struct usb_endpoint_descriptor *ep; ++ ++ /* buffers and dma */ ++ unsigned char *buf; ++ unsigned int len; ++ dma_addr_t dma; ++ ++ /* handle repeats */ ++ unsigned char old[USB_BUFF_LEN]; ++ unsigned long old_jiffies; ++}; ++ ++struct out_endpt { ++ struct xbox_dev *ir; ++ struct urb *urb; ++ struct usb_endpoint_descriptor *ep; ++ ++ /* buffers and dma */ ++ unsigned char *buf; ++ dma_addr_t dma; ++ ++ /* handle sending (init strings) */ ++ int send_flags; ++ wait_queue_head_t wait; ++}; ++ ++ ++/* data structure for each usb remote */ ++struct xbox_dev { ++ /* inner link in list of all remotes managed by this module */ ++ struct list_head remote_list_link; ++ /* Number of usb interfaces associated with this device */ ++ int dev_refcount; ++ ++ /* usb */ ++ struct usb_device *usbdev; ++ /* Head link to list of all inbound endpoints in this remote */ ++ struct list_head iep_listhead; ++ struct out_endpt *out_init; ++ int devnum; ++ ++ /* lirc */ ++ struct lirc_driver *d; ++ int connected; ++ ++ /* locking */ ++ struct mutex lock; ++}; ++ ++/* list of all registered devices via the remote_list_link in xbox_dev */ ++static struct list_head remote_list; ++ ++/* ++ * Convenience macros to retrieve a pointer to the surrounding struct from ++ * the given list_head reference within, pointed at by link. ++ */ ++#define get_iep_from_link(link) \ ++ list_entry((link), struct in_endpt, iep_list_link); ++#define get_irctl_from_link(link) \ ++ list_entry((link), struct xbox_dev, remote_list_link); ++ ++/* send packet - used to initialize remote */ ++static void send_packet(struct out_endpt *oep, u16 cmd, unsigned char *data) ++{ ++ struct xbox_dev *ir = oep->ir; ++ DECLARE_WAITQUEUE(wait, current); ++ int timeout = HZ; /* 1 second */ ++ unsigned char buf[USB_OUTLEN]; ++ ++ dprintk(DRIVER_NAME "[%d]: send called (%#x)\n", ir->devnum, cmd); ++ ++ mutex_lock(&ir->lock); ++ oep->urb->transfer_buffer_length = LO(cmd) + 1; ++ oep->urb->dev = oep->ir->usbdev; ++ oep->send_flags = SEND_FLAG_IN_PROGRESS; ++ ++ memcpy(buf+1, data, LO(cmd)); ++ buf[0] = HI(cmd); ++ memcpy(oep->buf, buf, LO(cmd)+1); ++ ++ set_current_state(TASK_INTERRUPTIBLE); ++ add_wait_queue(&oep->wait, &wait); ++ ++ if (usb_submit_urb(oep->urb, GFP_ATOMIC)) { ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&oep->wait, &wait); ++ mutex_unlock(&ir->lock); ++ return; ++ } ++ mutex_unlock(&ir->lock); ++ ++ while (timeout && (oep->urb->status == -EINPROGRESS) ++ && !(oep->send_flags & SEND_FLAG_COMPLETE)) { ++ timeout = schedule_timeout(timeout); ++ rmb(); ++ } ++ ++ dprintk(DRIVER_NAME "[%d]: send complete (%#x)\n", ir->devnum, cmd); ++ ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&oep->wait, &wait); ++ oep->urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(oep->urb); ++} ++ ++static int unregister_from_lirc(struct xbox_dev *ir) ++{ ++ struct lirc_driver *d = ir->d; ++ int devnum; ++ ++ devnum = ir->devnum; ++ dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); ++ ++ lirc_unregister_driver(d->minor); ++ ++ printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); ++ return 0; ++} ++ ++static int set_use_inc(void *data) ++{ ++ struct xbox_dev *ir = data; ++ struct list_head *pos, *n; ++ struct in_endpt *iep; ++ int rtn; ++ ++ if (!ir) { ++ printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); ++ return -EIO; ++ } ++ dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); ++ ++ mutex_lock(&ir->lock); ++ if (!ir->connected) { ++ if (!ir->usbdev) { ++ mutex_unlock(&ir->lock); ++ dprintk(DRIVER_NAME "[%d]: !ir->usbdev\n", ir->devnum); ++ return -ENOENT; ++ } ++ ++ /* Iterate through the inbound endpoints */ ++ list_for_each_safe(pos, n, &ir->iep_listhead) { ++ /* extract the current in_endpt */ ++ iep = get_iep_from_link(pos); ++ iep->urb->dev = ir->usbdev; ++ dprintk(DRIVER_NAME "[%d]: linking iep 0x%02x (%p)\n", ++ ir->devnum, iep->ep->bEndpointAddress, iep); ++ rtn = usb_submit_urb(iep->urb, GFP_ATOMIC); ++ if (rtn) { ++ printk(DRIVER_NAME "[%d]: open result = %d " ++ "error submitting urb\n", ++ ir->devnum, rtn); ++ mutex_unlock(&ir->lock); ++ return -EIO; ++ } ++ } ++ ir->connected = 1; ++ } ++ mutex_unlock(&ir->lock); ++ ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ ++ struct xbox_dev *ir = data; ++ struct list_head *pos, *n; ++ struct in_endpt *iep; ++ ++ if (!ir) { ++ printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); ++ return; ++ } ++ dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); ++ ++ mutex_lock(&ir->lock); ++ if (ir->connected) { ++ /* Free inbound usb urbs */ ++ list_for_each_safe(pos, n, &ir->iep_listhead) { ++ iep = get_iep_from_link(pos); ++ dprintk(DRIVER_NAME "[%d]: unlinking iep 0x%02x (%p)\n", ++ ir->devnum, iep->ep->bEndpointAddress, iep); ++ usb_kill_urb(iep->urb); ++ } ++ ir->connected = 0; ++ } ++ mutex_unlock(&ir->lock); ++} ++ ++static void print_data(struct in_endpt *iep, char *buf, int len) ++{ ++ const int clen = CODE_LENGTH; ++ char codes[clen * 3 + 1]; ++ int i; ++ ++ if (len <= 0) ++ return; ++ ++ for (i = 0; i < len && i < clen; i++) ++ snprintf(codes+i*3, 4, "%02x ", buf[i] & 0xFF); ++ printk(DRIVER_NAME "[%d]: data received %s (ep=0x%x length=%d)\n", ++ iep->ir->devnum, codes, iep->ep->bEndpointAddress, len); ++} ++ ++static int code_check_xbox(struct in_endpt *iep, int len) ++{ ++ // struct xbox_dev *ir = iep->ir; ++ const int clen = CODE_LENGTH; ++ ++ if (len != clen) { ++ dprintk(DRIVER_NAME ": We got %d instead of %d bytes from xbox " ++ "ir.. ?\n", len, clen); ++ return -1; ++ } ++ ++ /* check for repeats */ ++ if (memcmp(iep->old, iep->buf, len) == 0) { ++ if (iep->old_jiffies + repeat_jiffies > jiffies) ++ return -1; ++ } else { ++ /* ++ * the third byte of xbox ir packet seems to contain key info ++ * the last two bytes are.. some kind of clock? ++ */ ++ iep->buf[0] = iep->buf[2]; ++ memset(iep->buf + 1, 0, len - 1); ++ memcpy(iep->old, iep->buf, len); ++ } ++ iep->old_jiffies = jiffies; ++ ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++static void usb_remote_recv(struct urb *urb, struct pt_regs *regs) ++#else ++static void usb_remote_recv(struct urb *urb) ++#endif ++{ ++ struct in_endpt *iep; ++ int len, result = -1; ++ ++ if (!urb) ++ return; ++ iep = urb->context; ++ if (!iep) { ++ urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(urb); ++ return; ++ } ++ if (!iep->ir->usbdev) ++ return; ++ ++ len = urb->actual_length; ++ if (debug) ++ print_data(iep, urb->transfer_buffer, len); ++ ++ switch (urb->status) { ++ ++ case 0: ++ result = code_check_xbox(iep, len); ++ ++ if (result < 0) ++ break; ++ ++ lirc_buffer_write(iep->ir->d->rbuf, iep->buf); ++ wake_up(&iep->ir->d->rbuf->wait_poll); ++ break; ++ ++ case -ECONNRESET: ++ case -ENOENT: ++ case -ESHUTDOWN: ++ urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(urb); ++ return; ++ ++ case -EPIPE: ++ default: ++ break; ++ } ++ ++ usb_submit_urb(urb, GFP_ATOMIC); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) ++static void usb_remote_send(struct urb *urb, struct pt_regs *regs) ++#else ++static void usb_remote_send(struct urb *urb) ++#endif ++{ ++ struct out_endpt *oep; ++ ++ if (!urb) ++ return; ++ oep = urb->context; ++ if (!oep) { ++ urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(urb); ++ return; ++ } ++ if (!oep->ir->usbdev) ++ return; ++ ++ dprintk(DRIVER_NAME "[%d]: usb out called\n", oep->ir->devnum); ++ ++ if (urb->status) ++ return; ++ ++ oep->send_flags |= SEND_FLAG_COMPLETE; ++ wmb(); ++ if (waitqueue_active(&oep->wait)) ++ wake_up(&oep->wait); ++} ++ ++ ++/* ++ * Initialization and removal ++ */ ++ ++/* ++ * Free iep according to mem_failure which specifies a checkpoint into the ++ * initialization sequence for rollback recovery. ++ */ ++static void free_in_endpt(struct in_endpt *iep, int mem_failure) ++{ ++ struct xbox_dev *ir; ++ dprintk(DRIVER_NAME ": free_in_endpt(%p, %d)\n", iep, mem_failure); ++ if (!iep) ++ return; ++ ++ ir = iep->ir; ++ if (!ir) { ++ dprintk(DRIVER_NAME ": free_in_endpt: WARNING! null ir\n"); ++ return; ++ } ++ mutex_lock(&ir->lock); ++ switch (mem_failure) { ++ case FREE_ALL: ++ case 5: ++ list_del(&iep->iep_list_link); ++ dprintk(DRIVER_NAME "[%d]: free_in_endpt removing ep=0x%0x " ++ "from list\n", ir->devnum, iep->ep->bEndpointAddress); ++ case 4: ++ if (iep->urb) { ++ iep->urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(iep->urb); ++ usb_free_urb(iep->urb); ++ iep->urb = 0; ++ } else ++ dprintk(DRIVER_NAME "[%d]: free_in_endpt null urb!\n", ++ ir->devnum); ++ case 3: ++ usb_free_coherent(iep->ir->usbdev, iep->len, iep->buf, iep->dma); ++ iep->buf = 0; ++ case 2: ++ kfree(iep); ++ } ++ mutex_unlock(&ir->lock); ++} ++ ++/* ++ * Construct a new inbound endpoint for this remote, and add it to the list of ++ * in_epts in ir. ++ */ ++static struct in_endpt *new_in_endpt(struct xbox_dev *ir, ++ struct usb_endpoint_descriptor *ep) ++{ ++ struct usb_device *dev = ir->usbdev; ++ struct in_endpt *iep; ++ int pipe, maxp, len, addr; ++ int mem_failure; ++ ++ addr = ep->bEndpointAddress; ++ pipe = usb_rcvintpipe(dev, addr); ++ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); ++ ++/* len = (maxp > USB_BUFLEN) ? USB_BUFLEN : maxp; ++ * len -= (len % CODE_LENGTH); */ ++ len = CODE_LENGTH; ++ ++ dprintk(DRIVER_NAME "[%d]: acceptable inbound endpoint (0x%x) found " ++ "(maxp=%d len=%d)\n", ir->devnum, addr, maxp, len); ++ ++ mem_failure = 0; ++ iep = kzalloc(sizeof(*iep), GFP_KERNEL); ++ if (!iep) { ++ mem_failure = 1; ++ goto new_in_endpt_failure_check; ++ } ++ iep->ir = ir; ++ iep->ep = ep; ++ iep->len = len; ++ ++ iep->buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &iep->dma); ++ if (!iep->buf) { ++ mem_failure = 2; ++ goto new_in_endpt_failure_check; ++ } ++ ++ iep->urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!iep->urb) ++ mem_failure = 3; ++ ++new_in_endpt_failure_check: ++ ++ if (mem_failure) { ++ free_in_endpt(iep, mem_failure); ++ printk(DRIVER_NAME "[%d]: ep=0x%x out of memory (code=%d)\n", ++ ir->devnum, addr, mem_failure); ++ return NULL; ++ } ++ list_add_tail(&iep->iep_list_link, &ir->iep_listhead); ++ dprintk(DRIVER_NAME "[%d]: adding ep=0x%0x to list\n", ++ ir->devnum, iep->ep->bEndpointAddress); ++ return iep; ++} ++ ++static void free_out_endpt(struct out_endpt *oep, int mem_failure) ++{ ++ struct xbox_dev *ir; ++ dprintk(DRIVER_NAME ": free_out_endpt(%p, %d)\n", oep, mem_failure); ++ if (!oep) ++ return; ++ ++ wake_up_all(&oep->wait); ++ ++ ir = oep->ir; ++ if (!ir) { ++ dprintk(DRIVER_NAME ": free_out_endpt: WARNING! null ir\n"); ++ return; ++ } ++ mutex_lock(&ir->lock); ++ switch (mem_failure) { ++ case FREE_ALL: ++ case 4: ++ if (oep->urb) { ++ oep->urb->transfer_flags |= URB_ASYNC_UNLINK; ++ usb_unlink_urb(oep->urb); ++ usb_free_urb(oep->urb); ++ oep->urb = 0; ++ } else { ++ dprintk(DRIVER_NAME "[%d]: free_out_endpt: null urb!\n", ++ ir->devnum); ++ } ++ case 3: ++ usb_free_coherent(oep->ir->usbdev, USB_OUTLEN, ++ oep->buf, oep->dma); ++ oep->buf = 0; ++ case 2: ++ kfree(oep); ++ } ++ mutex_unlock(&ir->lock); ++} ++ ++static struct out_endpt *new_out_endpt(struct xbox_dev *ir, ++ struct usb_endpoint_descriptor *ep) ++{ ++ struct usb_device *dev = ir->usbdev; ++ struct out_endpt *oep; ++ int mem_failure; ++ ++ dprintk(DRIVER_NAME "[%d]: acceptable outbound endpoint (0x%x) found\n", ++ ir->devnum, ep->bEndpointAddress); ++ ++ mem_failure = 0; ++ oep = kzalloc(sizeof(*oep), GFP_KERNEL); ++ if (!oep) ++ mem_failure = 1; ++ else { ++ oep->ir = ir; ++ oep->ep = ep; ++ init_waitqueue_head(&oep->wait); ++ ++ oep->buf = usb_alloc_coherent(dev, USB_OUTLEN, ++ GFP_ATOMIC, &oep->dma); ++ if (!oep->buf) ++ mem_failure = 2; ++ else { ++ oep->urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!oep->urb) ++ mem_failure = 3; ++ } ++ } ++ if (mem_failure) { ++ free_out_endpt(oep, mem_failure); ++ printk(DRIVER_NAME "[%d]: ep=0x%x out of memory (code=%d)\n", ++ ir->devnum, ep->bEndpointAddress, mem_failure); ++ return NULL; ++ } ++ return oep; ++} ++ ++static void free_irctl(struct xbox_dev *ir, int mem_failure) ++{ ++ struct list_head *pos, *n; ++ struct in_endpt *in; ++ dprintk(DRIVER_NAME ": free_irctl(%p, %d)\n", ir, mem_failure); ++ ++ if (!ir) ++ return; ++ ++ list_for_each_safe(pos, n, &ir->iep_listhead) { ++ in = get_iep_from_link(pos); ++ free_in_endpt(in, FREE_ALL); ++ } ++ if (ir->out_init) { ++ free_out_endpt(ir->out_init, FREE_ALL); ++ ir->out_init = NULL; ++ } ++ ++ mutex_lock(&ir->lock); ++ switch (mem_failure) { ++ case FREE_ALL: ++ case 6: ++ if (!--ir->dev_refcount) { ++ list_del(&ir->remote_list_link); ++ dprintk(DRIVER_NAME "[%d]: free_irctl: removing " ++ "remote from list\n", ir->devnum); ++ } else { ++ dprintk(DRIVER_NAME "[%d]: free_irctl: refcount at %d," ++ "aborting free_irctl\n", ++ ir->devnum, ir->dev_refcount); ++ mutex_unlock(&ir->lock); ++ return; ++ } ++ case 5: ++ case 4: ++ case 3: ++ if (ir->d) { ++ switch (mem_failure) { ++ case 5: ++ lirc_buffer_free(ir->d->rbuf); ++ case 4: ++ kfree(ir->d->rbuf); ++ case 3: ++ kfree(ir->d); ++ } ++ } else ++ printk(DRIVER_NAME "[%d]: ir->d is a null pointer!\n", ++ ir->devnum); ++ case 2: ++ mutex_unlock(&ir->lock); ++ kfree(ir); ++ return; ++ } ++ mutex_unlock(&ir->lock); ++} ++ ++static struct xbox_dev *new_irctl(struct usb_interface *intf) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct xbox_dev *ir; ++ struct lirc_driver *driver; ++ int devnum, dclen; ++ int mem_failure; ++ ++ devnum = dev->devnum; ++ ++ dprintk(DRIVER_NAME "[%d]: remote type = XBOX DVD Dongle\n", devnum); ++ ++ mem_failure = 0; ++ ir = kzalloc(sizeof(*ir), GFP_KERNEL); ++ if (!ir) { ++ mem_failure = 1; ++ goto new_irctl_failure_check; ++ } ++ ++ dclen = DECODE_LENGTH; ++ ++ /* ++ * add this infrared remote struct to remote_list, keeping track ++ * of the number of drivers registered. ++ */ ++ dprintk(DRIVER_NAME "[%d]: adding remote to list\n", devnum); ++ list_add_tail(&ir->remote_list_link, &remote_list); ++ ir->dev_refcount = 1; ++ ++ driver = kzalloc(sizeof(*driver), GFP_KERNEL); ++ if (!driver) { ++ mem_failure = 2; ++ goto new_irctl_failure_check; ++ } ++ ++ ir->d = driver; ++ driver->rbuf = kmalloc(sizeof(*(driver->rbuf)), GFP_KERNEL); ++ if (!driver->rbuf) { ++ mem_failure = 3; ++ goto new_irctl_failure_check; ++ } ++ ++ if (lirc_buffer_init(driver->rbuf, dclen, 2)) { ++ mem_failure = 4; ++ goto new_irctl_failure_check; ++ } ++ ++ strcpy(driver->name, DRIVER_NAME " "); ++ driver->minor = -1; ++ driver->code_length = dclen * 8; ++ driver->features = LIRC_CAN_REC_LIRCCODE; ++ driver->data = ir; ++ driver->set_use_inc = &set_use_inc; ++ driver->set_use_dec = &set_use_dec; ++ driver->dev = &intf->dev; ++ driver->owner = THIS_MODULE; ++ ir->usbdev = dev; ++ ir->devnum = devnum; ++ ++ mutex_init(&ir->lock); ++ INIT_LIST_HEAD(&ir->iep_listhead); ++ ++new_irctl_failure_check: ++ ++ if (mem_failure) { ++ free_irctl(ir, mem_failure); ++ printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", ++ devnum, mem_failure); ++ return NULL; ++ } ++ return ir; ++} ++ ++/* ++ * Scan the global list of remotes to see if the device listed is one of them. ++ * If it is, the corresponding xbox_dev is returned, with its dev_refcount ++ * incremented. Otherwise, returns null. ++ */ ++static struct xbox_dev *get_prior_reg_ir(struct usb_device *dev) ++{ ++ struct list_head *pos; ++ struct xbox_dev *ir = NULL; ++ ++ dprintk(DRIVER_NAME "[%d]: scanning remote_list...\n", dev->devnum); ++ list_for_each(pos, &remote_list) { ++ ir = get_irctl_from_link(pos); ++ if (ir->usbdev != dev) { ++ dprintk(DRIVER_NAME "[%d]: device %d isn't it...", ++ dev->devnum, ir->devnum); ++ ir = NULL; ++ } else { ++ dprintk(DRIVER_NAME "[%d]: prior instance found.\n", ++ dev->devnum); ++ ir->dev_refcount++; ++ break; ++ } ++ } ++ return ir; ++} ++ ++/* ++ * If the USB interface has an out endpoint for control. ++ */ ++static void send_outbound_init(struct xbox_dev *ir) ++{ ++ if (ir->out_init) { ++ struct out_endpt *oep = ir->out_init; ++ dprintk(DRIVER_NAME "[%d]: usb_remote_probe: initializing " ++ "outbound ep\n", ir->devnum); ++ usb_fill_int_urb(oep->urb, ir->usbdev, ++ usb_sndintpipe(ir->usbdev, oep->ep->bEndpointAddress), ++ oep->buf, USB_OUTLEN, usb_remote_send, ++ oep, oep->ep->bInterval); ++ oep->urb->transfer_dma = oep->dma; ++ oep->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ send_packet(oep, 0x8004, init1); ++ send_packet(oep, 0x8007, init2); ++ } ++} ++ ++/* Log driver and usb info */ ++static void log_usb_dev_info(struct usb_device *dev) ++{ ++ char buf[63], name[128] = ""; ++ ++ if (dev->descriptor.iManufacturer ++ && usb_string(dev, dev->descriptor.iManufacturer, ++ buf, sizeof(buf)) > 0) ++ strlcpy(name, buf, sizeof(name)); ++ if (dev->descriptor.iProduct ++ && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0) ++ snprintf(name + strlen(name), sizeof(name) - strlen(name), ++ " %s", buf); ++ printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", dev->devnum, name, ++ dev->bus->busnum, dev->devnum); ++} ++ ++ ++static int usb_remote_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct usb_host_interface *idesc; ++ struct usb_endpoint_descriptor *ep; ++ struct in_endpt *iep; ++ struct xbox_dev *ir; ++ int i; ++ ++ dprintk(DRIVER_NAME "[%d]: usb_remote_probe: dev:%p, intf:%p, id:%p)\n", ++ dev->devnum, dev, intf, id); ++ ++ idesc = intf->cur_altsetting; ++ ++ /* Check if a usb remote has already been registered for this device */ ++ ir = get_prior_reg_ir(dev); ++ ++ if (!ir) { ++ ir = new_irctl(intf); ++ if (!ir) ++ return -ENOMEM; ++ } ++ ++ /* ++ * step through the endpoints to find first in and first out endpoint ++ * of type interrupt transfer ++ */ ++ for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { ++ ep = &idesc->endpoint[i].desc; ++ dprintk(DRIVER_NAME "[%d]: processing endpoint %d\n", ++ dev->devnum, i); ++ if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == ++ USB_DIR_IN) && ++ ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == ++ USB_ENDPOINT_XFER_INT)) { ++ ++ iep = new_in_endpt(ir, ep); ++ if (iep) ++ { ++ usb_fill_int_urb(iep->urb, dev, ++ usb_rcvintpipe(dev, ++ iep->ep->bEndpointAddress), ++ iep->buf, iep->len, usb_remote_recv, ++ iep, iep->ep->bInterval); ++ iep->urb->transfer_dma = iep->dma; ++ iep->urb->transfer_flags |= ++ URB_NO_TRANSFER_DMA_MAP; ++ } ++ } ++ ++ if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == ++ USB_DIR_OUT) && ++ ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == ++ USB_ENDPOINT_XFER_INT) && ++ (ir->out_init == NULL)) ++ ir->out_init = new_out_endpt(ir, ep); ++ } ++ if (list_empty(&ir->iep_listhead)) { ++ printk(DRIVER_NAME "[%d]: inbound endpoint not found\n", ++ ir->devnum); ++ free_irctl(ir, FREE_ALL); ++ return -ENODEV; ++ } ++ if (ir->dev_refcount == 1) { ++ ir->d->minor = lirc_register_driver(ir->d); ++ if (ir->d->minor < 0) { ++ free_irctl(ir, FREE_ALL); ++ return -ENODEV; ++ } ++ ++ /* Note new driver registration in kernel logs */ ++ log_usb_dev_info(dev); ++ ++ /* outbound data (initialization) */ ++ send_outbound_init(ir); ++ } ++ ++ usb_set_intfdata(intf, ir); ++ return 0; ++} ++ ++static void usb_remote_disconnect(struct usb_interface *intf) ++{ ++ /* struct usb_device *dev = interface_to_usbdev(intf); */ ++ struct xbox_dev *ir = usb_get_intfdata(intf); ++ usb_set_intfdata(intf, NULL); ++ ++ dprintk(DRIVER_NAME ": disconnecting remote %d:\n", ++ (ir ? ir->devnum : -1)); ++ if (!ir || !ir->d) ++ return; ++ ++ if (ir->usbdev) { ++ /* Only unregister once */ ++ ir->usbdev = NULL; ++ unregister_from_lirc(ir); ++ } ++ ++ /* This also removes the current remote from remote_list */ ++ free_irctl(ir, FREE_ALL); ++} ++ ++static struct usb_driver usb_remote_driver = { ++ .name = DRIVER_NAME, ++ .probe = usb_remote_probe, ++ .disconnect = usb_remote_disconnect, ++ .id_table = usb_remote_table ++}; ++ ++static int __init usb_remote_init(void) ++{ ++ int i; ++ ++ INIT_LIST_HEAD(&remote_list); ++ ++ printk(KERN_INFO "\n" DRIVER_NAME ": " DRIVER_DESC " " ++ DRIVER_VERSION "\n"); ++ printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); ++ dprintk(DRIVER_NAME ": debug mode enabled: " ++ "$Id: lirc_xbox.c,v 1.88 2011/06/05 11:11:11 jmartin Exp $\n"); ++ ++ repeat_jiffies = repeat*HZ/100; ++ ++ i = usb_register(&usb_remote_driver); ++ if (i) { ++ printk(DRIVER_NAME ": usb register failed, result = %d\n", i); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static void __exit usb_remote_exit(void) ++{ ++ usb_deregister(&usb_remote_driver); ++} ++ ++module_init(usb_remote_init); ++module_exit(usb_remote_exit); ++ ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_LICENSE("GPL"); ++MODULE_DEVICE_TABLE(usb, usb_remote_table); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Debug enabled or not (default: 0)"); ++ ++module_param(mask, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(mask, "Set channel acceptance bit mask (default: 0xFFFF)"); ++ ++module_param(unique, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(unique, "Enable channel-specific codes (default: 0)"); ++ ++module_param(repeat, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(repeat, "Repeat timeout (1/100 sec) (default: 10)"); +diff -Naur linux-3.9.4/drivers/staging/media/lirc/Makefile linux-3.9.4.patch/drivers/staging/media/lirc/Makefile +--- linux-3.9.4/drivers/staging/media/lirc/Makefile 2013-05-24 20:45:59.000000000 +0200 ++++ linux-3.9.4.patch/drivers/staging/media/lirc/Makefile 2013-05-30 18:17:39.163634834 +0200 +@@ -10,4 +10,5 @@ + obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o + obj-$(CONFIG_LIRC_SIR) += lirc_sir.o + obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir.o ++obj-$(CONFIG_LIRC_XBOX) += lirc_xbox.o + obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o diff --git a/projects/H3/patches/linux/linux-504-spinelplus-remote-0.2.patch b/projects/H3/patches/linux/linux-504-spinelplus-remote-0.2.patch new file mode 100644 index 00000000000..3e38ba7d0f5 --- /dev/null +++ b/projects/H3/patches/linux/linux-504-spinelplus-remote-0.2.patch @@ -0,0 +1,161 @@ +diff -Naur linux-3.9/drivers/hid/hid-core.c linux-3.9.patch/drivers/hid/hid-core.c +--- linux-3.9/drivers/hid/hid-core.c 2013-04-29 02:36:01.000000000 +0200 ++++ linux-3.9.patch/drivers/hid/hid-core.c 2013-04-29 17:08:40.528324010 +0200 +@@ -1681,6 +1681,9 @@ + { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_OUYA, USB_DEVICE_ID_OUYA_CONTROLLER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) }, +diff -Naur linux-3.9/drivers/hid/hid-ids.h linux-3.9.patch/drivers/hid/hid-ids.h +--- linux-3.9/drivers/hid/hid-ids.h 2013-04-29 02:36:01.000000000 +0200 ++++ linux-3.9.patch/drivers/hid/hid-ids.h 2013-04-29 17:08:40.537323981 +0200 +@@ -663,6 +663,9 @@ + + #define USB_VENDOR_ID_PHILIPS 0x0471 + #define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617 ++#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1 0x206c ++#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2 0x20cc ++#define USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3 0x0613 + + #define USB_VENDOR_ID_PI_ENGINEERING 0x05f3 + #define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff +diff -Naur linux-3.9/drivers/hid/hid-spinelplus.c linux-3.9.patch/drivers/hid/hid-spinelplus.c +--- linux-3.9/drivers/hid/hid-spinelplus.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.9.patch/drivers/hid/hid-spinelplus.c 2013-04-29 17:08:40.537323981 +0200 +@@ -0,0 +1,104 @@ ++/* ++ * HID driver for "PHILIPS MCE USB IR Receiver- Spinel plus" remotes ++ * ++ * Copyright (c) 2010 Panagiotis Skintzos ++ * ++ * Renamed to Spinel, cleanup and modified to also support ++ * Spinel Plus 0471:20CC by Stephan Raue 2012. ++ */ ++ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the Free ++ * Software Foundation; either version 2 of the License, or (at your option) ++ * any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "hid-ids.h" ++ ++#define spinelplus_map_key(c) set_bit(EV_REP, hi->input->evbit); \ ++ hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) ++ ++static int spinelplus_input_mapping(struct hid_device *hdev, ++ struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, ++ unsigned long **bit, int *max) ++{ ++ switch (usage->hid) { ++ case 0xffbc000d: spinelplus_map_key(KEY_MEDIA); break; ++ case 0xffbc0024: spinelplus_map_key(KEY_MEDIA); break; ++ case 0xffbc0027: spinelplus_map_key(KEY_ZOOM); break; ++ case 0xffbc0033: spinelplus_map_key(KEY_HOME); break; ++ case 0xffbc0035: spinelplus_map_key(KEY_CAMERA); break; ++ case 0xffbc0036: spinelplus_map_key(KEY_EPG); break; ++ case 0xffbc0037: spinelplus_map_key(KEY_DVD); break; ++ case 0xffbc0038: spinelplus_map_key(KEY_HOME); break; ++ case 0xffbc0039: spinelplus_map_key(KEY_MP3); break; ++ case 0xffbc003a: spinelplus_map_key(KEY_VIDEO); break; ++ case 0xffbc005a: spinelplus_map_key(KEY_TEXT); break; ++ case 0xffbc005b: spinelplus_map_key(KEY_RED); break; ++ case 0xffbc005c: spinelplus_map_key(KEY_GREEN); break; ++ case 0xffbc005d: spinelplus_map_key(KEY_YELLOW); break; ++ case 0xffbc005e: spinelplus_map_key(KEY_BLUE); break; ++ default: ++ return 0; ++ } ++ return 1; ++} ++ ++static int spinelplus_probe(struct hid_device *hdev, ++ const struct hid_device_id *id) ++{ ++ int ret; ++ /* Connect only to hid input (not hiddev & hidraw)*/ ++ unsigned int cmask = HID_CONNECT_HIDINPUT; ++ ++ ret = hid_parse(hdev); ++ if (ret) { ++ dev_err(&hdev->dev, "parse failed\n"); ++ goto err_free; ++ } ++ ++ ret = hid_hw_start(hdev, cmask); ++ if (ret) { ++ dev_err(&hdev->dev, "hw start failed\n"); ++ goto err_free; ++ } ++ ++ return 0; ++err_free: ++ return ret; ++} ++ ++static const struct hid_device_id spinelplus_devices[] = { ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_1) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS,USB_DEVICE_ID_PHILIPS_SPINEL_PLUS_3) }, ++ { } ++}; ++MODULE_DEVICE_TABLE(hid, spinelplus_devices); ++ ++static struct hid_driver spinelplus_driver = { ++ .name = "SpinelPlus", ++ .id_table = spinelplus_devices, ++ .input_mapping = spinelplus_input_mapping, ++ .probe = spinelplus_probe, ++}; ++ ++static int __init spinelplus_init(void) ++{ ++ return hid_register_driver(&spinelplus_driver); ++} ++ ++static void __exit spinelplus_exit(void) ++{ ++ hid_unregister_driver(&spinelplus_driver); ++} ++ ++module_init(spinelplus_init); ++module_exit(spinelplus_exit); ++MODULE_LICENSE("GPL"); +diff -Naur linux-3.9/drivers/hid/Kconfig linux-3.9.patch/drivers/hid/Kconfig +--- linux-3.9/drivers/hid/Kconfig 2013-04-29 02:36:01.000000000 +0200 ++++ linux-3.9.patch/drivers/hid/Kconfig 2013-04-29 17:08:40.538323977 +0200 +@@ -602,6 +602,12 @@ + ---help--- + Support for Steelseries SRW-S1 steering wheel + ++config HID_SPINELPLUS ++ tristate "Spinel Plus remote control" ++ depends on USB_HID ++ ---help--- ++ Say Y here if you have a Spinel Plus (0471:206c/20cc/0613) remote ++ + config HID_SUNPLUS + tristate "Sunplus wireless desktop" + depends on USB_HID +diff -Naur linux-3.9/drivers/hid/Makefile linux-3.9.patch/drivers/hid/Makefile +--- linux-3.9/drivers/hid/Makefile 2013-04-29 02:36:01.000000000 +0200 ++++ linux-3.9.patch/drivers/hid/Makefile 2013-04-29 17:09:26.744173841 +0200 +@@ -101,6 +101,7 @@ + obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o + obj-$(CONFIG_HID_SONY) += hid-sony.o + obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o ++obj-$(CONFIG_HID_SPINELPLUS) += hid-spinelplus.o + obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o + obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o + obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o diff --git a/projects/H3/patches/linux/linux-505-add_Formosa_eHome_Infrared_Receiver.patch b/projects/H3/patches/linux/linux-505-add_Formosa_eHome_Infrared_Receiver.patch new file mode 100644 index 00000000000..e2afb63e3de --- /dev/null +++ b/projects/H3/patches/linux/linux-505-add_Formosa_eHome_Infrared_Receiver.patch @@ -0,0 +1,11 @@ +--- linux-3.2.2.orig/drivers/media/rc/mceusb.c 2012-01-30 23:37:12.374473509 +0100 ++++ linux-3.2.2/drivers/media/rc/mceusb.c 2012-01-30 23:40:57.989652931 +0100 +@@ -350,6 +350,8 @@ + { USB_DEVICE(VENDOR_FORMOSA, 0xe015) }, + /* Formosa21 / eHome Infrared Receiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe016) }, ++ /* Formosa21 / eHome Infrared Receiver */ ++ { USB_DEVICE(VENDOR_FORMOSA, 0xe042) }, + /* Formosa aim / Trust MCE Infrared Receiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe017), + .driver_info = MCE_GEN2_NO_TX }, diff --git a/projects/H3/patches/linux/linux-506-add_Adaptec_eHome_Infrared_Receiver.patch b/projects/H3/patches/linux/linux-506-add_Adaptec_eHome_Infrared_Receiver.patch new file mode 100644 index 00000000000..18e87ec3eb4 --- /dev/null +++ b/projects/H3/patches/linux/linux-506-add_Adaptec_eHome_Infrared_Receiver.patch @@ -0,0 +1,21 @@ +diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c +index baa1203..fee1f95 100644 +--- a/drivers/media/rc/mceusb.c ++++ b/drivers/media/rc/mceusb.c +@@ -200,6 +200,7 @@ static bool debug; + #define VENDOR_REALTEK 0x0bda + #define VENDOR_TIVO 0x105a + #define VENDOR_CONEXANT 0x0572 ++#define VENDOR_ADAPTEC 0x03f3 + + enum mceusb_model_type { + MCE_GEN2 = 0, /* Most boards */ +@@ -414,6 +415,8 @@ static struct usb_device_id mceusb_dev_table[] = { + /* Conexant Hybrid TV RDU253S Polaris */ + { USB_DEVICE(VENDOR_CONEXANT, 0x58a5), + .driver_info = CX_HYBRID_TV }, ++ /* Adaptec / HP eHome Receiver */ ++ { USB_DEVICE(VENDOR_ADAPTEC, 0x0094) }, + /* Terminating entry */ + { } + }; diff --git a/projects/H3/patches/linux/linux-507-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch b/projects/H3/patches/linux/linux-507-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch new file mode 100644 index 00000000000..67fc7a0de8c --- /dev/null +++ b/projects/H3/patches/linux/linux-507-add_SMK_Manufacturing_Inc_Infrared_Receiver.patch @@ -0,0 +1,13 @@ +diff -Naur linux-3.9.4/drivers/media/rc/mceusb.c linux-3.9.4.patch/drivers/media/rc/mceusb.c +--- linux-3.9.4/drivers/media/rc/mceusb.c 2013-05-24 20:45:59.000000000 +0200 ++++ linux-3.9.4.patch/drivers/media/rc/mceusb.c 2013-05-27 12:28:12.811230633 +0200 +@@ -309,6 +309,9 @@ + /* SMK/I-O Data GV-MC7/RCKIT Receiver */ + { USB_DEVICE(VENDOR_SMK, 0x0353), + .driver_info = MCE_GEN2_NO_TX }, ++ /* SMK Manufacturing, Inc. Receiver */ ++ { USB_DEVICE(VENDOR_SMK, 0x0357), ++ .driver_info = MCE_GEN2_NO_TX }, + /* Tatung eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, + /* Shuttle eHome Infrared Transceiver */ diff --git a/projects/H3/patches/linux/linux-508-Removed-MCE-customer-code-restriction-in-rc6-decode.patch b/projects/H3/patches/linux/linux-508-Removed-MCE-customer-code-restriction-in-rc6-decode.patch new file mode 100644 index 00000000000..9f84e6659fc --- /dev/null +++ b/projects/H3/patches/linux/linux-508-Removed-MCE-customer-code-restriction-in-rc6-decode.patch @@ -0,0 +1,22 @@ +--- linux/drivers/media/rc/ir-rc6-decoder.c 2012-11-25 22:08:13.148418669 -0800 ++++ linux.patch/drivers/media/rc/ir-rc6-decoder.c 2012-11-25 22:07:48.864417975 -0800 +@@ -39,7 +39,6 @@ + #define RC6_STARTBIT_MASK 0x08 /* for the header bits */ + #define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */ + #define RC6_6A_LCC_MASK 0xffff0000 /* RC6-6A-32 long customer code mask */ +-#define RC6_6A_MCE_CC 0x800f0000 /* MCE customer code */ + #ifndef CHAR_BIT + #define CHAR_BIT 8 /* Normally in */ + #endif +@@ -242,9 +241,8 @@ again: + } + + scancode = data->body; +- if (data->count == RC6_6A_32_NBITS && +- (scancode & RC6_6A_LCC_MASK) == RC6_6A_MCE_CC) { +- /* MCE RC */ ++ if (data->count == RC6_6A_32_NBITS) { ++ /* MCE compatible RC */ + toggle = (scancode & RC6_6A_MCE_TOGGLE_MASK) ? 1 : 0; + scancode &= ~RC6_6A_MCE_TOGGLE_MASK; + } else { diff --git a/projects/H3/patches/linux/linux-509-support-for-dvbsky-usb-receiver.patch b/projects/H3/patches/linux/linux-509-support-for-dvbsky-usb-receiver.patch new file mode 100644 index 00000000000..0dfca5a1ad2 --- /dev/null +++ b/projects/H3/patches/linux/linux-509-support-for-dvbsky-usb-receiver.patch @@ -0,0 +1,3456 @@ +From 3f61b08b6026e4de8c659d9796ea40b040dc5d92 Mon Sep 17 00:00:00 2001 +From: fritz +Date: Tue, 26 Mar 2013 10:02:35 +0100 +Subject: [PATCH] support for dvbsky-usb receiver + +--- + drivers/media/dvb/dvb-usb/Kconfig | 1 + + drivers/media/dvb/dvb-usb/dw2102.c | 282 ++++- + drivers/media/dvb/frontends/Kconfig | 7 + + drivers/media/dvb/frontends/Makefile | 1 + + drivers/media/dvb/frontends/m88ds3103.c | 1710 ++++++++++++++++++++++++++ + drivers/media/dvb/frontends/m88ds3103.h | 53 + + drivers/media/dvb/frontends/m88ds3103_priv.h | 403 ++++++ + drivers/media/rc/keymaps/Makefile | 1 + + drivers/media/rc/keymaps/rc-dvbsky.c | 78 ++ + drivers/media/video/cx23885/Kconfig | 1 + + drivers/media/video/cx23885/cx23885-cards.c | 163 ++- + drivers/media/video/cx23885/cx23885-dvb.c | 100 +- + drivers/media/video/cx23885/cx23885-f300.c | 55 + + drivers/media/video/cx23885/cx23885-f300.h | 6 + + drivers/media/video/cx23885/cx23885-input.c | 18 + + drivers/media/video/cx23885/cx23885.h | 6 +- + drivers/media/video/cx88/Kconfig | 1 + + drivers/media/video/cx88/cx88-cards.c | 22 + + drivers/media/video/cx88/cx88-dvb.c | 85 ++ + drivers/media/video/cx88/cx88-input.c | 4 + + drivers/media/video/cx88/cx88.h | 1 + + include/media/rc-map.h | 1 + + 22 files changed, 2995 insertions(+), 4 deletions(-) + create mode 100644 drivers/media/dvb/frontends/m88ds3103.c + create mode 100644 drivers/media/dvb/frontends/m88ds3103.h + create mode 100644 drivers/media/dvb/frontends/m88ds3103_priv.h + create mode 100644 drivers/media/rc/keymaps/rc-dvbsky.c + +diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig +index 63bf456..18bd6fe 100644 +--- a/drivers/media/dvb/dvb-usb/Kconfig ++++ b/drivers/media/dvb/dvb-usb/Kconfig +@@ -279,6 +279,7 @@ config DVB_USB_DW2102 + select DVB_STV0288 if !DVB_FE_CUSTOMISE + select DVB_STB6000 if !DVB_FE_CUSTOMISE + select DVB_CX24116 if !DVB_FE_CUSTOMISE ++ select DVB_M88DS3103 if !DVB_FE_CUSTOMISE + select DVB_SI21XX if !DVB_FE_CUSTOMISE + select DVB_TDA10023 if !DVB_FE_CUSTOMISE + select DVB_MT312 if !DVB_FE_CUSTOMISE +diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c +index 451c5a7..25722c7 100644 +--- a/drivers/media/dvb/dvb-usb/dw2102.c ++++ b/drivers/media/dvb/dvb-usb/dw2102.c +@@ -19,6 +19,7 @@ + #include "stb6000.h" + #include "eds1547.h" + #include "cx24116.h" ++#include "m88ds3103.h" + #include "tda1002x.h" + #include "mt312.h" + #include "zl10039.h" +@@ -834,6 +835,39 @@ static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) + return 0; + } + ++static int dvbsky_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) ++{ ++ int i; ++ u8 obuf[] = { 0x1e, 0x00 }; ++ u8 ibuf[] = { 0 }; ++ struct i2c_msg msg[] = { ++ { ++ .addr = 0x51, ++ .flags = 0, ++ .buf = obuf, ++ .len = 2, ++ }, { ++ .addr = 0x51, ++ .flags = I2C_M_RD, ++ .buf = ibuf, ++ .len = 1, ++ ++ } ++ }; ++ ++ for (i = 0; i < 6; i++) { ++ obuf[1] = i; ++ if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) ++ break; ++ else ++ mac[i] = ibuf[0]; ++ ++ debug_dump(mac, 6, printk); ++ } ++ ++ return 0; ++} ++ + static int su3000_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, +@@ -882,6 +916,43 @@ static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) + return 0; + } + ++static int bstusb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ ++ struct dvb_usb_adapter *udev_adap = ++ (struct dvb_usb_adapter *)(fe->dvb->priv); ++ ++ u8 obuf[3] = { 0xe, 0x80, 0 }; ++ u8 ibuf[] = { 0 }; ++ ++ info("US6830: %s!\n", __func__); ++ ++ if (voltage == SEC_VOLTAGE_OFF) ++ obuf[2] = 0; ++ else ++ obuf[2] = 1; ++ ++ if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ return 0; ++} ++ ++static int bstusb_restart(struct dvb_frontend *fe) ++{ ++ ++ struct dvb_usb_adapter *udev_adap = ++ (struct dvb_usb_adapter *)(fe->dvb->priv); ++ ++ u8 obuf[3] = { 0x36, 3, 0 }; ++ u8 ibuf[] = { 0 }; ++ ++ if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x36 transfer failed."); ++ ++ return 0; ++} ++ + static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) + { + static u8 led_off[] = { 0 }; +@@ -987,6 +1058,24 @@ static struct ds3000_config su3000_ds3000_config = { + .ci_mode = 1, + }; + ++static struct m88ds3103_config US6830_ds3103_config = { ++ .demod_address = 0x68, ++ .ci_mode = 1, ++ .pin_ctrl = 0x83, ++ .ts_mode = 0, ++ .start_ctrl = bstusb_restart, ++ .set_voltage = bstusb_set_voltage, ++}; ++ ++static struct m88ds3103_config US6832_ds3103_config = { ++ .demod_address = 0x68, ++ .ci_mode = 1, ++ .pin_ctrl = 0x80, ++ .ts_mode = 0, ++ .start_ctrl = bstusb_restart, ++ .set_voltage = bstusb_set_voltage, ++}; ++ + static int dw2104_frontend_attach(struct dvb_usb_adapter *d) + { + struct dvb_tuner_ops *tuner_ops = NULL; +@@ -1214,6 +1303,87 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d) + return 0; + } + ++static int US6830_frontend_attach(struct dvb_usb_adapter *d) ++{ ++ u8 obuf[3] = { 0xe, 0x04, 1 }; ++ u8 ibuf[] = { 0 }; ++ ++ info("US6830: %s!\n", __func__); ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ obuf[0] = 0xe; ++ obuf[1] = 0x83; ++ obuf[2] = 0; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ msleep(20); ++ ++ obuf[0] = 0xe; ++ obuf[1] = 0x83; ++ obuf[2] = 1; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ obuf[0] = 0x51; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) ++ err("command 0x51 transfer failed."); ++ ++ d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6830_ds3103_config, ++ &d->dev->i2c_adap); ++ if (d->fe_adap[0].fe == NULL) ++ return -EIO; ++ ++ info("Attached M88DS3103!\n"); ++ ++ return 0; ++} ++ ++static int US6832_frontend_attach(struct dvb_usb_adapter *d) ++{ ++ u8 obuf[3] = { 0xe, 0x04, 1 }; ++ u8 ibuf[] = { 0 }; ++ ++ info("US6832: %s!\n", __func__); ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ obuf[0] = 0xe; ++ obuf[1] = 0x83; ++ obuf[2] = 0; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ msleep(20); ++ obuf[0] = 0xe; ++ obuf[1] = 0x83; ++ obuf[2] = 1; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) ++ err("command 0x0e transfer failed."); ++ ++ obuf[0] = 0x51; ++ ++ if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) ++ err("command 0x51 transfer failed."); ++ ++ d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6832_ds3103_config, ++ &d->dev->i2c_adap); ++ if (d->fe_adap[0].fe == NULL) ++ return -EIO; ++ ++ info("Attached M88DS3103!\n"); ++ ++ return 0; ++} ++ + static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) + { + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, +@@ -1451,6 +1621,9 @@ enum dw2102_table_entry { + TEVII_S480_1, + TEVII_S480_2, + X3M_SPC1400HD, ++ BST_US6830HD, ++ BST_US6831HD, ++ BST_US6832HD, + }; + + static struct usb_device_id dw2102_table[] = { +@@ -1469,6 +1642,9 @@ static struct usb_device_id dw2102_table[] = { + [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, + [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, + [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)}, ++ [BST_US6830HD] = {USB_DEVICE(0x0572, 0x6830)}, ++ [BST_US6831HD] = {USB_DEVICE(0x0572, 0x6831)}, ++ [BST_US6832HD] = {USB_DEVICE(0x0572, 0x6832)}, + { } + }; + +@@ -1874,6 +2050,106 @@ static struct dvb_usb_device_properties su3000_properties = { + } + }; + ++static struct dvb_usb_device_properties US6830_properties = { ++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, ++ .usb_ctrl = DEVICE_SPECIFIC, ++ .size_of_priv = sizeof(struct su3000_state), ++ .power_ctrl = su3000_power_ctrl, ++ .num_adapters = 1, ++ .identify_state = su3000_identify_state, ++ .i2c_algo = &su3000_i2c_algo, ++ ++ .rc.legacy = { ++ .rc_map_table = rc_map_su3000_table, ++ .rc_map_size = ARRAY_SIZE(rc_map_su3000_table), ++ .rc_interval = 150, ++ .rc_query = dw2102_rc_query, ++ }, ++ ++ .read_mac_address = dvbsky_read_mac_address, ++ ++ .generic_bulk_ctrl_endpoint = 0x01, ++ ++ .adapter = { ++ { ++ .num_frontends = 1, ++ .fe = {{ ++ .streaming_ctrl = su3000_streaming_ctrl, ++ .frontend_attach = US6830_frontend_attach, ++ .stream = { ++ .type = USB_BULK, ++ .count = 8, ++ .endpoint = 0x82, ++ .u = { ++ .bulk = { ++ .buffersize = 4096, ++ } ++ } ++ } ++ }}, ++ } ++ }, ++ .num_device_descs = 2, ++ .devices = { ++ { "Bestunar US6830 HD", ++ { &dw2102_table[BST_US6830HD], NULL }, ++ { NULL }, ++ }, ++ { "Bestunar US6831 HD", ++ { &dw2102_table[BST_US6831HD], NULL }, ++ { NULL }, ++ }, ++ } ++}; ++ ++static struct dvb_usb_device_properties US6832_properties = { ++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, ++ .usb_ctrl = DEVICE_SPECIFIC, ++ .size_of_priv = sizeof(struct su3000_state), ++ .power_ctrl = su3000_power_ctrl, ++ .num_adapters = 1, ++ .identify_state = su3000_identify_state, ++ .i2c_algo = &su3000_i2c_algo, ++ ++ .rc.legacy = { ++ .rc_map_table = rc_map_su3000_table, ++ .rc_map_size = ARRAY_SIZE(rc_map_su3000_table), ++ .rc_interval = 150, ++ .rc_query = dw2102_rc_query, ++ }, ++ ++ .read_mac_address = dvbsky_read_mac_address, ++ ++ .generic_bulk_ctrl_endpoint = 0x01, ++ ++ .adapter = { ++ { ++ .num_frontends = 1, ++ .fe = {{ ++ .streaming_ctrl = su3000_streaming_ctrl, ++ .frontend_attach = US6832_frontend_attach, ++ .stream = { ++ .type = USB_BULK, ++ .count = 8, ++ .endpoint = 0x82, ++ .u = { ++ .bulk = { ++ .buffersize = 4096, ++ } ++ } ++ } ++ }}, ++ } ++ }, ++ .num_device_descs = 1, ++ .devices = { ++ { "Bestunar US6832 HD", ++ { &dw2102_table[BST_US6832HD], NULL }, ++ { NULL }, ++ }, ++ } ++}; ++ + static int dw2102_probe(struct usb_interface *intf, + const struct usb_device_id *id) + { +@@ -1930,7 +2206,11 @@ static int dw2102_probe(struct usb_interface *intf, + 0 == dvb_usb_device_init(intf, p7500, + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &su3000_properties, +- THIS_MODULE, NULL, adapter_nr)) ++ THIS_MODULE, NULL, adapter_nr) || ++ 0 == dvb_usb_device_init(intf, &US6830_properties, ++ THIS_MODULE, NULL, adapter_nr) || ++ 0 == dvb_usb_device_init(intf, &US6832_properties, ++ THIS_MODULE, NULL, adapter_nr)) + return 0; + + return -ENODEV; +diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig +index 2124670..eabf9d9 100644 +--- a/drivers/media/dvb/frontends/Kconfig ++++ b/drivers/media/dvb/frontends/Kconfig +@@ -214,6 +214,13 @@ config DVB_CX24116 + help + A DVB-S/S2 tuner module. Say Y when you want to support this frontend. + ++config DVB_M88DS3103 ++ tristate "Montage DS3103 based" ++ depends on DVB_CORE && I2C ++ default m if DVB_FE_CUSTOMISE ++ help ++ A DVB-S/S2 tuner module. Say Y when you want to support this frontend. ++ + config DVB_SI21XX + tristate "Silicon Labs SI21XX based" + depends on DVB_CORE && I2C +diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile +index 86fa808..870d5e3 100644 +--- a/drivers/media/dvb/frontends/Makefile ++++ b/drivers/media/dvb/frontends/Makefile +@@ -98,4 +98,5 @@ obj-$(CONFIG_DVB_A8293) += a8293.o + obj-$(CONFIG_DVB_TDA10071) += tda10071.o + obj-$(CONFIG_DVB_RTL2830) += rtl2830.o + obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o ++obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o + +diff --git a/drivers/media/dvb/frontends/m88ds3103.c b/drivers/media/dvb/frontends/m88ds3103.c +new file mode 100644 +index 0000000..315809d +--- /dev/null ++++ b/drivers/media/dvb/frontends/m88ds3103.c +@@ -0,0 +1,1710 @@ ++/* ++ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver ++ ++ Copyright (C) 2011 Max nibble ++ Copyright (C) 2010 Montage Technology ++ Copyright (C) 2009 Konstantin Dimitrov. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "dvb_frontend.h" ++#include "m88ds3103.h" ++#include "m88ds3103_priv.h" ++ ++static int debug; ++module_param(debug, int, 0644); ++MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); ++ ++#define dprintk(args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_INFO "m88ds3103: " args); \ ++ } while (0) ++ ++/*demod register operations.*/ ++static int m88ds3103_writereg(struct m88ds3103_state *state, int reg, int data) ++{ ++ u8 buf[] = { reg, data }; ++ struct i2c_msg msg = { .addr = state->config->demod_address, ++ .flags = 0, .buf = buf, .len = 2 }; ++ int err; ++ ++ if (debug > 1) ++ printk("m88ds3103: %s: write reg 0x%02x, value 0x%02x\n", ++ __func__, reg, data); ++ ++ err = i2c_transfer(state->i2c, &msg, 1); ++ if (err != 1) { ++ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," ++ " value == 0x%02x)\n", __func__, err, reg, data); ++ return -EREMOTEIO; ++ } ++ return 0; ++} ++ ++static int m88ds3103_readreg(struct m88ds3103_state *state, u8 reg) ++{ ++ int ret; ++ u8 b0[] = { reg }; ++ u8 b1[] = { 0 }; ++ struct i2c_msg msg[] = { ++ { .addr = state->config->demod_address, .flags = 0, ++ .buf = b0, .len = 1 }, ++ { .addr = state->config->demod_address, .flags = I2C_M_RD, ++ .buf = b1, .len = 1 } ++ }; ++ ret = i2c_transfer(state->i2c, msg, 2); ++ ++ if (ret != 2) { ++ printk(KERN_ERR "%s: reg=0x%x (error=%d)\n", ++ __func__, reg, ret); ++ return ret; ++ } ++ ++ if (debug > 1) ++ printk(KERN_INFO "m88ds3103: read reg 0x%02x, value 0x%02x\n", ++ reg, b1[0]); ++ ++ return b1[0]; ++} ++ ++/*tuner register operations.*/ ++static int m88ds3103_tuner_writereg(struct m88ds3103_state *state, int reg, int data) ++{ ++ u8 buf[] = { reg, data }; ++ struct i2c_msg msg = { .addr = 0x60, ++ .flags = 0, .buf = buf, .len = 2 }; ++ int err; ++ ++ m88ds3103_writereg(state, 0x03, 0x11); ++ err = i2c_transfer(state->i2c, &msg, 1); ++ ++ if (err != 1) { ++ printk("%s: writereg error(err == %i, reg == 0x%02x," ++ " value == 0x%02x)\n", __func__, err, reg, data); ++ return -EREMOTEIO; ++ } ++ ++ return 0; ++} ++ ++static int m88ds3103_tuner_readreg(struct m88ds3103_state *state, u8 reg) ++{ ++ int ret; ++ u8 b0[] = { reg }; ++ u8 b1[] = { 0 }; ++ struct i2c_msg msg[] = { ++ { .addr = 0x60, .flags = 0, ++ .buf = b0, .len = 1 }, ++ { .addr = 0x60, .flags = I2C_M_RD, ++ .buf = b1, .len = 1 } ++ }; ++ ++ m88ds3103_writereg(state, 0x03, 0x11); ++ ret = i2c_transfer(state->i2c, msg, 2); ++ ++ if (ret != 2) { ++ printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret); ++ return ret; ++ } ++ ++ return b1[0]; ++} ++ ++/* Bulk demod I2C write, for firmware download. */ ++static int m88ds3103_writeregN(struct m88ds3103_state *state, int reg, ++ const u8 *data, u16 len) ++{ ++ int ret = -EREMOTEIO; ++ struct i2c_msg msg; ++ u8 *buf; ++ ++ buf = kmalloc(len + 1, GFP_KERNEL); ++ if (buf == NULL) { ++ printk("Unable to kmalloc\n"); ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ *(buf) = reg; ++ memcpy(buf + 1, data, len); ++ ++ msg.addr = state->config->demod_address; ++ msg.flags = 0; ++ msg.buf = buf; ++ msg.len = len + 1; ++ ++ if (debug > 1) ++ printk(KERN_INFO "m88ds3103: %s: write regN 0x%02x, len = %d\n", ++ __func__, reg, len); ++ ++ ret = i2c_transfer(state->i2c, &msg, 1); ++ if (ret != 1) { ++ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n", ++ __func__, ret, reg); ++ ret = -EREMOTEIO; ++ } ++ ++error: ++ kfree(buf); ++ ++ return ret; ++} ++ ++static int m88ds3103_load_firmware(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ const struct firmware *fw; ++ int i, ret = 0; ++ ++ dprintk("%s()\n", __func__); ++ ++ if (state->skip_fw_load) ++ return 0; ++ /* Load firmware */ ++ /* request the firmware, this will block until someone uploads it */ ++ if(state->demod_id == DS3000_ID){ ++ printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__, ++ DS3000_DEFAULT_FIRMWARE); ++ ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE, ++ state->i2c->dev.parent); ++ }else if(state->demod_id == DS3103_ID){ ++ printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__, ++ DS3103_DEFAULT_FIRMWARE); ++ ret = request_firmware(&fw, DS3103_DEFAULT_FIRMWARE, ++ state->i2c->dev.parent); ++ } ++ ++ printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__); ++ if (ret) { ++ printk(KERN_ERR "%s: No firmware uploaded (timeout or file not " ++ "found?)\n", __func__); ++ return ret; ++ } ++ ++ /* Make sure we don't recurse back through here during loading */ ++ state->skip_fw_load = 1; ++ ++ dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n", ++ fw->size, ++ fw->data[0], ++ fw->data[1], ++ fw->data[fw->size - 2], ++ fw->data[fw->size - 1]); ++ ++ /* stop internal mcu. */ ++ m88ds3103_writereg(state, 0xb2, 0x01); ++ /* split firmware to download.*/ ++ for(i = 0; i < FW_DOWN_LOOP; i++){ ++ ret = m88ds3103_writeregN(state, 0xb0, &(fw->data[FW_DOWN_SIZE*i]), FW_DOWN_SIZE); ++ if(ret != 1) break; ++ } ++ /* start internal mcu. */ ++ if(ret == 1) ++ m88ds3103_writereg(state, 0xb2, 0x00); ++ ++ release_firmware(fw); ++ ++ dprintk("%s: Firmware upload %s\n", __func__, ++ ret == 1 ? "complete" : "failed"); ++ ++ if(ret == 1) ret = 0; ++ ++ /* Ensure firmware is always loaded if required */ ++ state->skip_fw_load = 0; ++ ++ return ret; ++} ++ ++ ++static int m88ds3103_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 data; ++ ++ dprintk("%s(%d)\n", __func__, voltage); ++ ++ dprintk("m88ds3103:pin_ctrl = (%02x)\n", state->config->pin_ctrl); ++ ++ if(state->config->set_voltage) ++ state->config->set_voltage(fe, voltage); ++ ++ data = m88ds3103_readreg(state, 0xa2); ++ ++ if(state->config->pin_ctrl & 0x80){ /*If control pin is assigned.*/ ++ data &= ~0x03; /* bit0 V/H, bit1 off/on */ ++ if(state->config->pin_ctrl & 0x02) ++ data |= 0x02; ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_18: ++ if((state->config->pin_ctrl & 0x01) == 0) ++ data |= 0x01; ++ break; ++ case SEC_VOLTAGE_13: ++ if(state->config->pin_ctrl & 0x01) ++ data |= 0x01; ++ break; ++ case SEC_VOLTAGE_OFF: ++ if(state->config->pin_ctrl & 0x02) ++ data &= ~0x02; ++ else ++ data |= 0x02; ++ break; ++ } ++ } ++ ++ m88ds3103_writereg(state, 0xa2, data); ++ ++ return 0; ++} ++ ++static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t* status) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ int lock = 0; ++ ++ *status = 0; ++ ++ switch (state->delivery_system){ ++ case SYS_DVBS: ++ lock = m88ds3103_readreg(state, 0xd1); ++ dprintk("%s: SYS_DVBS status=%x.\n", __func__, lock); ++ ++ if ((lock & 0x07) == 0x07){ ++ /*if((m88ds3103_readreg(state, 0x0d) & 0x07) == 0x07)*/ ++ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER ++ | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; ++ ++ } ++ break; ++ case SYS_DVBS2: ++ lock = m88ds3103_readreg(state, 0x0d); ++ dprintk("%s: SYS_DVBS2 status=%x.\n", __func__, lock); ++ ++ if ((lock & 0x8f) == 0x8f) ++ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER ++ | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; ++ ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static int m88ds3103_read_ber(struct dvb_frontend *fe, u32* ber) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 tmp1, tmp2, tmp3; ++ u32 ldpc_frame_cnt, pre_err_packags, code_rate_fac = 0; ++ ++ dprintk("%s()\n", __func__); ++ ++ switch (state->delivery_system) { ++ case SYS_DVBS: ++ m88ds3103_writereg(state, 0xf9, 0x04); ++ tmp3 = m88ds3103_readreg(state, 0xf8); ++ if ((tmp3&0x10) == 0){ ++ tmp1 = m88ds3103_readreg(state, 0xf7); ++ tmp2 = m88ds3103_readreg(state, 0xf6); ++ tmp3 |= 0x10; ++ m88ds3103_writereg(state, 0xf8, tmp3); ++ state->preBer = (tmp1<<8) | tmp2; ++ } ++ break; ++ case SYS_DVBS2: ++ tmp1 = m88ds3103_readreg(state, 0x7e) & 0x0f; ++ switch(tmp1){ ++ case 0: code_rate_fac = 16008 - 80; break; ++ case 1: code_rate_fac = 21408 - 80; break; ++ case 2: code_rate_fac = 25728 - 80; break; ++ case 3: code_rate_fac = 32208 - 80; break; ++ case 4: code_rate_fac = 38688 - 80; break; ++ case 5: code_rate_fac = 43040 - 80; break; ++ case 6: code_rate_fac = 48408 - 80; break; ++ case 7: code_rate_fac = 51648 - 80; break; ++ case 8: code_rate_fac = 53840 - 80; break; ++ case 9: code_rate_fac = 57472 - 80; break; ++ case 10: code_rate_fac = 58192 - 80; break; ++ } ++ ++ tmp1 = m88ds3103_readreg(state, 0xd7) & 0xff; ++ tmp2 = m88ds3103_readreg(state, 0xd6) & 0xff; ++ tmp3 = m88ds3103_readreg(state, 0xd5) & 0xff; ++ ldpc_frame_cnt = (tmp1 << 16) | (tmp2 << 8) | tmp3; ++ ++ tmp1 = m88ds3103_readreg(state, 0xf8) & 0xff; ++ tmp2 = m88ds3103_readreg(state, 0xf7) & 0xff; ++ pre_err_packags = tmp1<<8 | tmp2; ++ ++ if (ldpc_frame_cnt > 1000){ ++ m88ds3103_writereg(state, 0xd1, 0x01); ++ m88ds3103_writereg(state, 0xf9, 0x01); ++ m88ds3103_writereg(state, 0xf9, 0x00); ++ m88ds3103_writereg(state, 0xd1, 0x00); ++ state->preBer = pre_err_packags; ++ } ++ break; ++ default: ++ break; ++ } ++ *ber = state->preBer; ++ ++ return 0; ++} ++ ++static int m88ds3103_read_signal_strength(struct dvb_frontend *fe, ++ u16 *signal_strength) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u16 gain; ++ u8 gain1, gain2, gain3 = 0; ++ ++ dprintk("%s()\n", __func__); ++ ++ gain1 = m88ds3103_tuner_readreg(state, 0x3d) & 0x1f; ++ dprintk("%s: gain1 = 0x%02x \n", __func__, gain1); ++ ++ if (gain1 > 15) gain1 = 15; ++ gain2 = m88ds3103_tuner_readreg(state, 0x21) & 0x1f; ++ dprintk("%s: gain2 = 0x%02x \n", __func__, gain2); ++ ++ if(state->tuner_id == TS2022_ID){ ++ gain3 = (m88ds3103_tuner_readreg(state, 0x66)>>3) & 0x07; ++ dprintk("%s: gain3 = 0x%02x \n", __func__, gain3); ++ ++ if (gain2 > 16) gain2 = 16; ++ if (gain2 < 2) gain2 = 2; ++ if (gain3 > 6) gain3 = 6; ++ }else{ ++ if (gain2 > 13) gain2 = 13; ++ gain3 = 0; ++ } ++ ++ gain = gain1*23 + gain2*35 + gain3*29; ++ *signal_strength = 60000 - gain*55; ++ ++ return 0; ++} ++ ++ ++static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *p_snr) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 val, npow1, npow2, spow1, cnt; ++ u16 tmp, snr; ++ u32 npow, spow, snr_total; ++ static const u16 mes_log10[] ={ ++ 0, 3010, 4771, 6021, 6990, 7781, 8451, 9031, 9542, 10000, ++ 10414, 10792, 11139, 11461, 11761, 12041, 12304, 12553, 12788, 13010, ++ 13222, 13424, 13617, 13802, 13979, 14150, 14314, 14472, 14624, 14771, ++ 14914, 15052, 15185, 15315, 15441, 15563, 15682, 15798, 15911, 16021, ++ 16128, 16232, 16335, 16435, 16532, 16628, 16721, 16812, 16902, 16990, ++ 17076, 17160, 17243, 17324, 17404, 17482, 17559, 17634, 17709, 17782, ++ 17853, 17924, 17993, 18062, 18129, 18195, 18261, 18325, 18388, 18451, ++ 18513, 18573, 18633, 18692, 18751, 18808, 18865, 18921, 18976, 19031 ++ }; ++ static const u16 mes_loge[] ={ ++ 0, 6931, 10986, 13863, 16094, 17918, 19459, 20794, 21972, 23026, ++ 23979, 24849, 25649, 26391, 27081, 27726, 28332, 28904, 29444, 29957, ++ 30445, 30910, 31355, 31781, 32189, 32581, 32958, 33322, 33673, 34012, ++ 34340, 34657, ++ }; ++ ++ dprintk("%s()\n", __func__); ++ ++ snr = 0; ++ ++ switch (state->delivery_system){ ++ case SYS_DVBS: ++ cnt = 10; snr_total = 0; ++ while(cnt > 0){ ++ val = m88ds3103_readreg(state, 0xff); ++ snr_total += val; ++ cnt--; ++ } ++ tmp = (u16)(snr_total/80); ++ if(tmp > 0){ ++ if (tmp > 32) tmp = 32; ++ snr = (mes_loge[tmp - 1] * 100) / 45; ++ }else{ ++ snr = 0; ++ } ++ break; ++ case SYS_DVBS2: ++ cnt = 10; npow = 0; spow = 0; ++ while(cnt >0){ ++ npow1 = m88ds3103_readreg(state, 0x8c) & 0xff; ++ npow2 = m88ds3103_readreg(state, 0x8d) & 0xff; ++ npow += (((npow1 & 0x3f) + (u16)(npow2 << 6)) >> 2); ++ ++ spow1 = m88ds3103_readreg(state, 0x8e) & 0xff; ++ spow += ((spow1 * spow1) >> 1); ++ cnt--; ++ } ++ npow /= 10; spow /= 10; ++ if(spow == 0){ ++ snr = 0; ++ }else if(npow == 0){ ++ snr = 19; ++ }else{ ++ if(spow > npow){ ++ tmp = (u16)(spow / npow); ++ if (tmp > 80) tmp = 80; ++ snr = mes_log10[tmp - 1]*3; ++ }else{ ++ tmp = (u16)(npow / spow); ++ if (tmp > 80) tmp = 80; ++ snr = -(mes_log10[tmp - 1] / 1000); ++ } ++ } ++ break; ++ default: ++ break; ++ } ++ *p_snr = snr; ++ ++ return 0; ++} ++ ++ ++static int m88ds3103_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 tmp1, tmp2, tmp3, data; ++ ++ dprintk("%s()\n", __func__); ++ ++ switch (state->delivery_system) { ++ case SYS_DVBS: ++ data = m88ds3103_readreg(state, 0xf8); ++ data |= 0x40; ++ m88ds3103_writereg(state, 0xf8, data); ++ tmp1 = m88ds3103_readreg(state, 0xf5); ++ tmp2 = m88ds3103_readreg(state, 0xf4); ++ *ucblocks = (tmp1 <<8) | tmp2; ++ data &= ~0x20; ++ m88ds3103_writereg(state, 0xf8, data); ++ data |= 0x20; ++ m88ds3103_writereg(state, 0xf8, data); ++ data &= ~0x40; ++ m88ds3103_writereg(state, 0xf8, data); ++ break; ++ case SYS_DVBS2: ++ tmp1 = m88ds3103_readreg(state, 0xda); ++ tmp2 = m88ds3103_readreg(state, 0xd9); ++ tmp3 = m88ds3103_readreg(state, 0xd8); ++ *ucblocks = (tmp1 <<16)|(tmp2 <<8)|tmp3; ++ data = m88ds3103_readreg(state, 0xd1); ++ data |= 0x01; ++ m88ds3103_writereg(state, 0xd1, data); ++ data &= ~0x01; ++ m88ds3103_writereg(state, 0xd1, data); ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static int m88ds3103_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 data_a1, data_a2; ++ ++ dprintk("%s(%d)\n", __func__, tone); ++ if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { ++ printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone); ++ return -EINVAL; ++ } ++ ++ data_a1 = m88ds3103_readreg(state, 0xa1); ++ data_a2 = m88ds3103_readreg(state, 0xa2); ++ if(state->demod_id == DS3103_ID) ++ data_a2 &= 0xdf; /* Normal mode */ ++ switch (tone) { ++ case SEC_TONE_ON: ++ dprintk("%s: SEC_TONE_ON\n", __func__); ++ data_a1 |= 0x04; ++ data_a1 &= ~0x03; ++ data_a1 &= ~0x40; ++ data_a2 &= ~0xc0; ++ break; ++ case SEC_TONE_OFF: ++ dprintk("%s: SEC_TONE_OFF\n", __func__); ++ data_a2 &= ~0xc0; ++ data_a2 |= 0x80; ++ break; ++ } ++ m88ds3103_writereg(state, 0xa2, data_a2); ++ m88ds3103_writereg(state, 0xa1, data_a1); ++ return 0; ++} ++ ++static int m88ds3103_send_diseqc_msg(struct dvb_frontend *fe, ++ struct dvb_diseqc_master_cmd *d) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ int i, ret = 0; ++ u8 tmp, time_out; ++ ++ /* Dump DiSEqC message */ ++ if (debug) { ++ printk(KERN_INFO "m88ds3103: %s(", __func__); ++ for (i = 0 ; i < d->msg_len ;) { ++ printk(KERN_INFO "0x%02x", d->msg[i]); ++ if (++i < d->msg_len) ++ printk(KERN_INFO ", "); ++ } ++ } ++ ++ tmp = m88ds3103_readreg(state, 0xa2); ++ tmp &= ~0xc0; ++ if(state->demod_id == DS3103_ID) ++ tmp &= ~0x20; ++ m88ds3103_writereg(state, 0xa2, tmp); ++ ++ for (i = 0; i < d->msg_len; i ++) ++ m88ds3103_writereg(state, (0xa3+i), d->msg[i]); ++ ++ tmp = m88ds3103_readreg(state, 0xa1); ++ tmp &= ~0x38; ++ tmp &= ~0x40; ++ tmp |= ((d->msg_len-1) << 3) | 0x07; ++ tmp &= ~0x80; ++ m88ds3103_writereg(state, 0xa1, tmp); ++ /* 1.5 * 9 * 8 = 108ms */ ++ time_out = 150; ++ while (time_out > 0){ ++ msleep(10); ++ time_out -= 10; ++ tmp = m88ds3103_readreg(state, 0xa1); ++ if ((tmp & 0x40) == 0) ++ break; ++ } ++ if (time_out == 0){ ++ tmp = m88ds3103_readreg(state, 0xa1); ++ tmp &= ~0x80; ++ tmp |= 0x40; ++ m88ds3103_writereg(state, 0xa1, tmp); ++ ret = 1; ++ } ++ tmp = m88ds3103_readreg(state, 0xa2); ++ tmp &= ~0xc0; ++ tmp |= 0x80; ++ m88ds3103_writereg(state, 0xa2, tmp); ++ return ret; ++} ++ ++ ++static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, ++ fe_sec_mini_cmd_t burst) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 val, time_out; ++ ++ dprintk("%s()\n", __func__); ++ ++ val = m88ds3103_readreg(state, 0xa2); ++ val &= ~0xc0; ++ if(state->demod_id == DS3103_ID) ++ val &= 0xdf; /* Normal mode */ ++ m88ds3103_writereg(state, 0xa2, val); ++ /* DiSEqC burst */ ++ if (burst == SEC_MINI_B) ++ m88ds3103_writereg(state, 0xa1, 0x01); ++ else ++ m88ds3103_writereg(state, 0xa1, 0x02); ++ ++ msleep(13); ++ ++ time_out = 5; ++ do{ ++ val = m88ds3103_readreg(state, 0xa1); ++ if ((val & 0x40) == 0) ++ break; ++ msleep(1); ++ time_out --; ++ } while (time_out > 0); ++ ++ val = m88ds3103_readreg(state, 0xa2); ++ val &= ~0xc0; ++ val |= 0x80; ++ m88ds3103_writereg(state, 0xa2, val); ++ ++ return 0; ++} ++ ++static void m88ds3103_release(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ ++ dprintk("%s\n", __func__); ++ kfree(state); ++} ++ ++static int m88ds3103_check_id(struct m88ds3103_state *state) ++{ ++ int val_00, val_01; ++ ++ /*check demod id*/ ++ val_01 = m88ds3103_readreg(state, 0x01); ++ printk(KERN_INFO "DS3000 chip version: %x attached.\n", val_01); ++ ++ if(val_01 == 0xD0) ++ state->demod_id = DS3103_ID; ++ else if(val_01 == 0xC0) ++ state->demod_id = DS3000_ID; ++ else ++ state->demod_id = UNKNOW_ID; ++ ++ /*check tuner id*/ ++ val_00 = m88ds3103_tuner_readreg(state, 0x00); ++ printk(KERN_INFO "TS202x chip version[1]: %x attached.\n", val_00); ++ val_00 &= 0x03; ++ if(val_00 == 0) ++ { ++ m88ds3103_tuner_writereg(state, 0x00, 0x01); ++ msleep(3); ++ } ++ m88ds3103_tuner_writereg(state, 0x00, 0x03); ++ msleep(5); ++ ++ val_00 = m88ds3103_tuner_readreg(state, 0x00); ++ printk(KERN_INFO "TS202x chip version[2]: %x attached.\n", val_00); ++ val_00 &= 0xff; ++ if((val_00 == 0x01) || (val_00 == 0x41) || (val_00 == 0x81)) ++ state->tuner_id = TS2020_ID; ++ else if(((val_00 & 0xc0)== 0xc0) || (val_00 == 0x83)) ++ state->tuner_id = TS2022_ID; ++ else ++ state->tuner_id = UNKNOW_ID; ++ ++ return state->demod_id; ++} ++ ++static struct dvb_frontend_ops m88ds3103_ops; ++static int m88ds3103_initilaze(struct dvb_frontend *fe); ++ ++struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *config, ++ struct i2c_adapter *i2c) ++{ ++ struct m88ds3103_state *state = NULL; ++ ++ dprintk("%s\n", __func__); ++ ++ /* allocate memory for the internal state */ ++ state = kzalloc(sizeof(struct m88ds3103_state), GFP_KERNEL); ++ if (state == NULL) { ++ printk(KERN_ERR "Unable to kmalloc\n"); ++ goto error2; ++ } ++ ++ state->config = config; ++ state->i2c = i2c; ++ state->preBer = 0xffff; ++ state->delivery_system = SYS_DVBS; /*Default to DVB-S.*/ ++ ++ /* check demod id */ ++ if(m88ds3103_check_id(state) == UNKNOW_ID){ ++ printk(KERN_ERR "Unable to find Montage chip\n"); ++ goto error3; ++ } ++ ++ memcpy(&state->frontend.ops, &m88ds3103_ops, ++ sizeof(struct dvb_frontend_ops)); ++ state->frontend.demodulator_priv = state; ++ ++ m88ds3103_initilaze(&state->frontend); ++ ++ return &state->frontend; ++ ++error3: ++ kfree(state); ++error2: ++ return NULL; ++} ++EXPORT_SYMBOL(m88ds3103_attach); ++ ++static int m88ds3103_set_carrier_offset(struct dvb_frontend *fe, ++ s32 carrier_offset_khz) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ s32 tmp; ++ ++ tmp = carrier_offset_khz; ++ tmp *= 65536; ++ ++ tmp = (2*tmp + MT_FE_MCLK_KHZ) / (2*MT_FE_MCLK_KHZ); ++ ++ if (tmp < 0) ++ tmp += 65536; ++ ++ m88ds3103_writereg(state, 0x5f, tmp >> 8); ++ m88ds3103_writereg(state, 0x5e, tmp & 0xff); ++ ++ return 0; ++} ++ ++static int m88ds3103_set_symrate(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ u16 value; ++ ++ value = (((c->symbol_rate / 1000) << 15) + (MT_FE_MCLK_KHZ / 4)) / (MT_FE_MCLK_KHZ / 2); ++ m88ds3103_writereg(state, 0x61, value & 0x00ff); ++ m88ds3103_writereg(state, 0x62, (value & 0xff00) >> 8); ++ ++ return 0; ++} ++ ++static int m88ds3103_set_CCI(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 tmp; ++ ++ tmp = m88ds3103_readreg(state, 0x56); ++ tmp &= ~0x01; ++ m88ds3103_writereg(state, 0x56, tmp); ++ ++ tmp = m88ds3103_readreg(state, 0x76); ++ tmp &= ~0x80; ++ m88ds3103_writereg(state, 0x76, tmp); ++ ++ return 0; ++} ++ ++static int m88ds3103_init_reg(struct m88ds3103_state *state, const u8 *p_reg_tab, u32 size) ++{ ++ u32 i; ++ ++ for(i = 0; i < size; i+=2) ++ m88ds3103_writereg(state, p_reg_tab[i], p_reg_tab[i+1]); ++ ++ return 0; ++} ++ ++static int m88ds3103_get_locked_sym_rate(struct m88ds3103_state *state, u32 *sym_rate_KSs) ++{ ++ u16 tmp; ++ u32 sym_rate_tmp; ++ u8 val_0x6d, val_0x6e; ++ ++ val_0x6d = m88ds3103_readreg(state, 0x6d); ++ val_0x6e = m88ds3103_readreg(state, 0x6e); ++ ++ tmp = (u16)((val_0x6e<<8) | val_0x6d); ++ ++ sym_rate_tmp = (u32)(tmp * MT_FE_MCLK_KHZ); ++ sym_rate_tmp = (u32)(sym_rate_tmp / (1<<16)); ++ *sym_rate_KSs = sym_rate_tmp; ++ ++ return 0; ++} ++ ++static int m88ds3103_get_channel_info(struct m88ds3103_state *state, u8 *p_mode, u8 *p_coderate) ++{ ++ u8 tmp, val_0x7E; ++ ++ if(state->delivery_system == SYS_DVBS2){ ++ val_0x7E = m88ds3103_readreg(state, 0x7e); ++ tmp = (u8)((val_0x7E&0xC0) >> 6); ++ *p_mode = tmp; ++ tmp = (u8)(val_0x7E & 0x0f); ++ *p_coderate = tmp; ++ } else { ++ *p_mode = 0; ++ tmp = m88ds3103_readreg(state, 0xe6); ++ tmp = (u8)(tmp >> 5); ++ *p_coderate = tmp; ++ } ++ ++ return 0; ++} ++ ++static int m88ds3103_set_clock_ratio(struct m88ds3103_state *state) ++{ ++ u8 val, mod_fac, tmp1, tmp2; ++ u32 input_datarate, locked_sym_rate_KSs; ++ u32 MClk_KHz = 96000; ++ u8 mod_mode, code_rate, divid_ratio = 0; ++ ++ locked_sym_rate_KSs = 0; ++ m88ds3103_get_locked_sym_rate(state, &locked_sym_rate_KSs); ++ if(locked_sym_rate_KSs == 0) ++ return 0; ++ ++ m88ds3103_get_channel_info(state, &mod_mode, &code_rate); ++ ++ if (state->delivery_system == SYS_DVBS2) ++ { ++ switch(mod_mode) { ++ case 1: mod_fac = 3; break; ++ case 2: mod_fac = 4; break; ++ case 3: mod_fac = 5; break; ++ default: mod_fac = 2; break; ++ } ++ ++ switch(code_rate) { ++ case 0: input_datarate = locked_sym_rate_KSs*mod_fac/8/4; break; ++ case 1: input_datarate = locked_sym_rate_KSs*mod_fac/8/3; break; ++ case 2: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/5; break; ++ case 3: input_datarate = locked_sym_rate_KSs*mod_fac/8/2; break; ++ case 4: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/5; break; ++ case 5: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3; break; ++ case 6: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/4; break; ++ case 7: input_datarate = locked_sym_rate_KSs*mod_fac*4/8/5; break; ++ case 8: input_datarate = locked_sym_rate_KSs*mod_fac*5/8/6; break; ++ case 9: input_datarate = locked_sym_rate_KSs*mod_fac*8/8/9; break; ++ case 10: input_datarate = locked_sym_rate_KSs*mod_fac*9/8/10; break; ++ default: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3; break; ++ } ++ ++ if(state->demod_id == DS3000_ID) ++ input_datarate = input_datarate * 115 / 100; ++ ++ if(input_datarate < 4800) {tmp1 = 15;tmp2 = 15;} //4.8MHz TS clock ++ else if(input_datarate < 4966) {tmp1 = 14;tmp2 = 15;} //4.966MHz TS clock ++ else if(input_datarate < 5143) {tmp1 = 14;tmp2 = 14;} //5.143MHz TS clock ++ else if(input_datarate < 5333) {tmp1 = 13;tmp2 = 14;} //5.333MHz TS clock ++ else if(input_datarate < 5538) {tmp1 = 13;tmp2 = 13;} //5.538MHz TS clock ++ else if(input_datarate < 5760) {tmp1 = 12;tmp2 = 13;} //5.76MHz TS clock allan 0809 ++ else if(input_datarate < 6000) {tmp1 = 12;tmp2 = 12;} //6MHz TS clock ++ else if(input_datarate < 6260) {tmp1 = 11;tmp2 = 12;} //6.26MHz TS clock ++ else if(input_datarate < 6545) {tmp1 = 11;tmp2 = 11;} //6.545MHz TS clock ++ else if(input_datarate < 6857) {tmp1 = 10;tmp2 = 11;} //6.857MHz TS clock ++ else if(input_datarate < 7200) {tmp1 = 10;tmp2 = 10;} //7.2MHz TS clock ++ else if(input_datarate < 7578) {tmp1 = 9;tmp2 = 10;} //7.578MHz TS clock ++ else if(input_datarate < 8000) {tmp1 = 9;tmp2 = 9;} //8MHz TS clock ++ else if(input_datarate < 8470) {tmp1 = 8;tmp2 = 9;} //8.47MHz TS clock ++ else if(input_datarate < 9000) {tmp1 = 8;tmp2 = 8;} //9MHz TS clock ++ else if(input_datarate < 9600) {tmp1 = 7;tmp2 = 8;} //9.6MHz TS clock ++ else if(input_datarate < 10285) {tmp1 = 7;tmp2 = 7;} //10.285MHz TS clock ++ else if(input_datarate < 12000) {tmp1 = 6;tmp2 = 6;} //12MHz TS clock ++ else if(input_datarate < 14400) {tmp1 = 5;tmp2 = 5;} //14.4MHz TS clock ++ else if(input_datarate < 18000) {tmp1 = 4;tmp2 = 4;} //18MHz TS clock ++ else {tmp1 = 3;tmp2 = 3;} //24MHz TS clock ++ ++ if(state->demod_id == DS3000_ID) { ++ val = (u8)((tmp1<<4) + tmp2); ++ m88ds3103_writereg(state, 0xfe, val); ++ } else { ++ tmp1 = m88ds3103_readreg(state, 0x22); ++ tmp2 = m88ds3103_readreg(state, 0x24); ++ ++ tmp1 >>= 6; ++ tmp1 &= 0x03; ++ tmp2 >>= 6; ++ tmp2 &= 0x03; ++ ++ if((tmp1 == 0x00) && (tmp2 == 0x01)) ++ MClk_KHz = 144000; ++ else if((tmp1 == 0x00) && (tmp2 == 0x03)) ++ MClk_KHz = 72000; ++ else if((tmp1 == 0x01) && (tmp2 == 0x01)) ++ MClk_KHz = 115200; ++ else if((tmp1 == 0x02) && (tmp2 == 0x01)) ++ MClk_KHz = 96000; ++ else if((tmp1 == 0x03) && (tmp2 == 0x00)) ++ MClk_KHz = 192000; ++ else ++ return 0; ++ ++ if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/ ++ input_datarate = 5200; ++ ++ if(input_datarate != 0) ++ divid_ratio = (u8)(MClk_KHz / input_datarate); ++ else ++ divid_ratio = 0xFF; ++ ++ if(divid_ratio > 128) ++ divid_ratio = 128; ++ ++ if(divid_ratio < 2) ++ divid_ratio = 2; ++ ++ tmp1 = (u8)(divid_ratio / 2); ++ tmp2 = (u8)(divid_ratio / 2); ++ ++ if((divid_ratio % 2) != 0) ++ tmp2 += 1; ++ ++ tmp1 -= 1; ++ tmp2 -= 1; ++ ++ tmp1 &= 0x3f; ++ tmp2 &= 0x3f; ++ ++ val = m88ds3103_readreg(state, 0xfe); ++ val &= 0xF0; ++ val |= (tmp2 >> 2) & 0x0f; ++ m88ds3103_writereg(state, 0xfe, val); ++ ++ val = (u8)((tmp2 & 0x03) << 6); ++ val |= tmp1; ++ m88ds3103_writereg(state, 0xea, val); ++ } ++ } else { ++ mod_fac = 2; ++ ++ switch(code_rate) { ++ case 4: input_datarate = locked_sym_rate_KSs*mod_fac/2/8; break; ++ case 3: input_datarate = locked_sym_rate_KSs*mod_fac*2/3/8; break; ++ case 2: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8; break; ++ case 1: input_datarate = locked_sym_rate_KSs*mod_fac*5/6/8; break; ++ case 0: input_datarate = locked_sym_rate_KSs*mod_fac*7/8/8; break; ++ default: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8; break; ++ } ++ ++ if(state->demod_id == DS3000_ID) ++ input_datarate = input_datarate * 115 / 100; ++ ++ if(input_datarate < 6857) {tmp1 = 7;tmp2 = 7;} //6.857MHz TS clock ++ else if(input_datarate < 7384) {tmp1 = 6;tmp2 = 7;} //7.384MHz TS clock ++ else if(input_datarate < 8000) {tmp1 = 6;tmp2 = 6;} //8MHz TS clock ++ else if(input_datarate < 8727) {tmp1 = 5;tmp2 = 6;} //8.727MHz TS clock ++ else if(input_datarate < 9600) {tmp1 = 5;tmp2 = 5;} //9.6MHz TS clock ++ else if(input_datarate < 10666) {tmp1 = 4;tmp2 = 5;} //10.666MHz TS clock ++ else if(input_datarate < 12000) {tmp1 = 4;tmp2 = 4;} //12MHz TS clock ++ else if(input_datarate < 13714) {tmp1 = 3;tmp2 = 4;} //13.714MHz TS clock ++ else if(input_datarate < 16000) {tmp1 = 3;tmp2 = 3;} //16MHz TS clock ++ else if(input_datarate < 19200) {tmp1 = 2;tmp2 = 3;} //19.2MHz TS clock ++ else {tmp1 = 2;tmp2 = 2;} //24MHz TS clock ++ ++ if(state->demod_id == DS3000_ID) { ++ val = m88ds3103_readreg(state, 0xfe); ++ val &= 0xc0; ++ val |= ((u8)((tmp1<<3) + tmp2)); ++ m88ds3103_writereg(state, 0xfe, val); ++ } else { ++ if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/ ++ input_datarate = 5200; ++ ++ if(input_datarate != 0) ++ divid_ratio = (u8)(MClk_KHz / input_datarate); ++ else ++ divid_ratio = 0xFF; ++ ++ if(divid_ratio > 128) ++ divid_ratio = 128; ++ ++ if(divid_ratio < 2) ++ divid_ratio = 2; ++ ++ tmp1 = (u8)(divid_ratio / 2); ++ tmp2 = (u8)(divid_ratio / 2); ++ ++ if((divid_ratio % 2) != 0) ++ tmp2 += 1; ++ ++ tmp1 -= 1; ++ tmp2 -= 1; ++ ++ tmp1 &= 0x3f; ++ tmp2 &= 0x3f; ++ ++ val = m88ds3103_readreg(state, 0xfe); ++ val &= 0xF0; ++ val |= (tmp2 >> 2) & 0x0f; ++ m88ds3103_writereg(state, 0xfe, val); ++ ++ val = (u8)((tmp2 & 0x03) << 6); ++ val |= tmp1; ++ m88ds3103_writereg(state, 0xea, val); ++ } ++ } ++ return 0; ++} ++ ++static int m88ds3103_demod_connect(struct dvb_frontend *fe, s32 carrier_offset_khz) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ u16 value; ++ u8 val1,val2,data; ++ ++ dprintk("connect delivery system = %d\n", state->delivery_system); ++ ++ /* ds3000 global reset */ ++ m88ds3103_writereg(state, 0x07, 0x80); ++ m88ds3103_writereg(state, 0x07, 0x00); ++ /* ds3000 build-in uC reset */ ++ m88ds3103_writereg(state, 0xb2, 0x01); ++ /* ds3000 software reset */ ++ m88ds3103_writereg(state, 0x00, 0x01); ++ ++ switch (state->delivery_system) { ++ case SYS_DVBS: ++ /* initialise the demod in DVB-S mode */ ++ if(state->demod_id == DS3000_ID){ ++ m88ds3103_init_reg(state, ds3000_dvbs_init_tab, sizeof(ds3000_dvbs_init_tab)); ++ ++ value = m88ds3103_readreg(state, 0xfe); ++ value &= 0xc0; ++ value |= 0x1b; ++ m88ds3103_writereg(state, 0xfe, value); ++ ++ if(state->config->ci_mode) ++ val1 = 0x80; ++ else if(state->config->ts_mode) ++ val1 = 0x60; ++ else ++ val1 = 0x20; ++ m88ds3103_writereg(state, 0xfd, val1); ++ ++ }else if(state->demod_id == DS3103_ID){ ++ m88ds3103_init_reg(state, ds3103_dvbs_init_tab, sizeof(ds3103_dvbs_init_tab)); ++ ++ /* set ts clock */ ++ if(state->config->ci_mode == 2){ ++ val1 = 6; val2 = 6; ++ }else if(state->config->ts_mode == 0) { ++ val1 = 3; val2 = 3; ++ }else{ ++ val1 = 0; val2 = 0; ++ } ++ val1 -= 1; val2 -= 1; ++ val1 &= 0x3f; val2 &= 0x3f; ++ data = m88ds3103_readreg(state, 0xfe); ++ data &= 0xf0; ++ data |= (val2 >> 2) & 0x0f; ++ m88ds3103_writereg(state, 0xfe, data); ++ data = (val2 & 0x03) << 6; ++ data |= val1; ++ m88ds3103_writereg(state, 0xea, data); ++ ++ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d)); ++ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30)); ++ ++ /* set master clock */ ++ val1 = m88ds3103_readreg(state, 0x22); ++ val2 = m88ds3103_readreg(state, 0x24); ++ ++ val1 &= 0x3f; ++ val2 &= 0x3f; ++ val1 |= 0x80; ++ val2 |= 0x40; ++ ++ m88ds3103_writereg(state, 0x22, val1); ++ m88ds3103_writereg(state, 0x24, val2); ++ ++ if(state->config->ci_mode) ++ val1 = 0x03; ++ else if(state->config->ts_mode) ++ val1 = 0x06; ++ else ++ val1 = 0x42; ++ m88ds3103_writereg(state, 0xfd, val1); ++ } ++ break; ++ case SYS_DVBS2: ++ /* initialise the demod in DVB-S2 mode */ ++ if(state->demod_id == DS3000_ID){ ++ m88ds3103_init_reg(state, ds3000_dvbs2_init_tab, sizeof(ds3000_dvbs2_init_tab)); ++ ++ if (c->symbol_rate >= 30000000) ++ m88ds3103_writereg(state, 0xfe, 0x54); ++ else ++ m88ds3103_writereg(state, 0xfe, 0x98); ++ ++ }else if(state->demod_id == DS3103_ID){ ++ m88ds3103_init_reg(state, ds3103_dvbs2_init_tab, sizeof(ds3103_dvbs2_init_tab)); ++ ++ /* set ts clock */ ++ if(state->config->ci_mode == 2){ ++ val1 = 6; val2 = 6; ++ }else if(state->config->ts_mode == 0){ ++ val1 = 5; val2 = 4; ++ }else{ ++ val1 = 0; val2 = 0; ++ } ++ val1 -= 1; val2 -= 1; ++ val1 &= 0x3f; val2 &= 0x3f; ++ data = m88ds3103_readreg(state, 0xfe); ++ data &= 0xf0; ++ data |= (val2 >> 2) & 0x0f; ++ m88ds3103_writereg(state, 0xfe, data); ++ data = (val2 & 0x03) << 6; ++ data |= val1; ++ m88ds3103_writereg(state, 0xea, data); ++ ++ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d)); ++ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30)); ++ ++ /* set master clock */ ++ val1 = m88ds3103_readreg(state, 0x22); ++ val2 = m88ds3103_readreg(state, 0x24); ++ ++ val1 &= 0x3f; ++ val2 &= 0x3f; ++ if((state->config->ci_mode == 2) || (state->config->ts_mode == 1)){ ++ val1 |= 0x80; ++ val2 |= 0x40; ++ }else{ ++ if (c->symbol_rate >= 28000000){ ++ val1 |= 0xc0; ++ }else if (c->symbol_rate >= 18000000){ ++ val2 |= 0x40; ++ }else{ ++ val1 |= 0x80; ++ val2 |= 0x40; ++ } ++ } ++ m88ds3103_writereg(state, 0x22, val1); ++ m88ds3103_writereg(state, 0x24, val2); ++ } ++ ++ if(state->config->ci_mode) ++ val1 = 0x03; ++ else if(state->config->ts_mode) ++ val1 = 0x06; ++ else ++ val1 = 0x42; ++ m88ds3103_writereg(state, 0xfd, val1); ++ ++ break; ++ default: ++ return 1; ++ } ++ /* disable 27MHz clock output */ ++ m88ds3103_writereg(state, 0x29, 0x80); ++ /* enable ac coupling */ ++ m88ds3103_writereg(state, 0x25, 0x8a); ++ ++ if ((c->symbol_rate / 1000) <= 3000){ ++ m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 32 * 100 / 64 = 400*/ ++ m88ds3103_writereg(state, 0xc8, 0x20); ++ m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/ ++ m88ds3103_writereg(state, 0xc7, 0x00); ++ }else if((c->symbol_rate / 1000) <= 10000){ ++ m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 16 * 100 / 64 = 200*/ ++ m88ds3103_writereg(state, 0xc8, 0x10); ++ m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/ ++ m88ds3103_writereg(state, 0xc7, 0x00); ++ }else{ ++ m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 6 * 100 / 64 = 75*/ ++ m88ds3103_writereg(state, 0xc8, 0x06); ++ m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/ ++ m88ds3103_writereg(state, 0xc7, 0x00); ++ } ++ ++ m88ds3103_set_symrate(fe); ++ ++ m88ds3103_set_CCI(fe); ++ ++ m88ds3103_set_carrier_offset(fe, carrier_offset_khz); ++ ++ /* ds3000 out of software reset */ ++ m88ds3103_writereg(state, 0x00, 0x00); ++ /* start ds3000 build-in uC */ ++ m88ds3103_writereg(state, 0xb2, 0x00); ++ ++ return 0; ++} ++ ++static int m88ds3103_set_frontend(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ struct dtv_frontend_properties *c = &fe->dtv_property_cache; ++ ++ int i; ++ fe_status_t status; ++ u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf, div4, capCode, changePLL; ++ s32 offset_khz, lpf_offset_KHz; ++ u16 value, ndiv, lpf_coeff; ++ u32 f3db, gdiv28, realFreq; ++ u8 RFgain; ++ ++ dprintk("%s() ", __func__); ++ dprintk("c frequency = %d\n", c->frequency); ++ dprintk("symbol rate = %d\n", c->symbol_rate); ++ dprintk("delivery system = %d\n", c->delivery_system); ++ ++ realFreq = c->frequency; ++ lpf_offset_KHz = 0; ++ if(c->symbol_rate < 5000000){ ++ lpf_offset_KHz = FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz; ++ realFreq += FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz; ++ } ++ ++ if (state->config->set_ts_params) ++ state->config->set_ts_params(fe, 0); ++ ++ div4 = 0; ++ RFgain = 0; ++ if(state->tuner_id == TS2022_ID){ ++ m88ds3103_tuner_writereg(state, 0x10, 0x0a); ++ m88ds3103_tuner_writereg(state, 0x11, 0x40); ++ if (realFreq < 1103000) { ++ m88ds3103_tuner_writereg(state, 0x10, 0x1b); ++ div4 = 1; ++ ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ; ++ }else { ++ ndiv = (realFreq * (6 + 8) * 2)/MT_FE_CRYSTAL_KHZ; ++ } ++ ndiv = ndiv + ndiv%2; ++ if(ndiv < 4095) ++ ndiv = ndiv - 1024; ++ else if (ndiv < 6143) ++ ndiv = ndiv + 1024; ++ else ++ ndiv = ndiv + 3072; ++ ++ m88ds3103_tuner_writereg(state, 0x01, (ndiv & 0x3f00) >> 8); ++ }else{ ++ m88ds3103_tuner_writereg(state, 0x10, 0x00); ++ if (realFreq < 1146000){ ++ m88ds3103_tuner_writereg(state, 0x10, 0x11); ++ div4 = 1; ++ ndiv = (realFreq * (6 + 8) * 4) / MT_FE_CRYSTAL_KHZ; ++ }else{ ++ m88ds3103_tuner_writereg(state, 0x10, 0x01); ++ ndiv = (realFreq * (6 + 8) * 2) / MT_FE_CRYSTAL_KHZ; ++ } ++ ndiv = ndiv + ndiv%2; ++ ndiv = ndiv - 1024; ++ m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8)&0x0f); ++ } ++ /* set pll */ ++ m88ds3103_tuner_writereg(state, 0x02, ndiv & 0x00ff); ++ m88ds3103_tuner_writereg(state, 0x03, 0x06); ++ m88ds3103_tuner_writereg(state, 0x51, 0x0f); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x10); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ ++ if(state->tuner_id == TS2022_ID){ ++ if(( realFreq >= 1650000 ) && (realFreq <= 1850000)){ ++ msleep(5); ++ value = m88ds3103_tuner_readreg(state, 0x14); ++ value &= 0x7f; ++ if(value < 64){ ++ m88ds3103_tuner_writereg(state, 0x10, 0x82); ++ m88ds3103_tuner_writereg(state, 0x11, 0x6f); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x0f); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x10); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ } ++ } ++ msleep(5); ++ value = m88ds3103_tuner_readreg(state, 0x14); ++ value &= 0x1f; ++ ++ if(value > 19){ ++ value = m88ds3103_tuner_readreg(state, 0x10); ++ value &= 0x1d; ++ m88ds3103_tuner_writereg(state, 0x10, value); ++ } ++ }else{ ++ msleep(5); ++ value = m88ds3103_tuner_readreg(state, 0x66); ++ changePLL = (((value & 0x80) >> 7) != div4); ++ ++ if(changePLL){ ++ m88ds3103_tuner_writereg(state, 0x10, 0x11); ++ div4 = 1; ++ ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ; ++ ndiv = ndiv + ndiv%2; ++ ndiv = ndiv - 1024; ++ ++ m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8) & 0x0f); ++ m88ds3103_tuner_writereg(state, 0x02, ndiv & 0xff); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x0f); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x10); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ } ++ } ++ /*set the RF gain*/ ++ if(state->tuner_id == TS2020_ID) ++ m88ds3103_tuner_writereg(state, 0x60, 0x79); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x17); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x08); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ msleep(5); ++ ++ if(state->tuner_id == TS2020_ID){ ++ RFgain = m88ds3103_tuner_readreg(state, 0x3d); ++ RFgain &= 0x0f; ++ if(RFgain < 15){ ++ if(RFgain < 4) ++ RFgain = 0; ++ else ++ RFgain = RFgain -3; ++ value = ((RFgain << 3) | 0x01) & 0x79; ++ m88ds3103_tuner_writereg(state, 0x60, value); ++ m88ds3103_tuner_writereg(state, 0x51, 0x17); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x08); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ } ++ } ++ ++ /* set the LPF */ ++ if(state->tuner_id == TS2022_ID){ ++ m88ds3103_tuner_writereg(state, 0x25, 0x00); ++ m88ds3103_tuner_writereg(state, 0x27, 0x70); ++ m88ds3103_tuner_writereg(state, 0x41, 0x09); ++ m88ds3103_tuner_writereg(state, 0x08, 0x0b); ++ } ++ ++ f3db = ((c->symbol_rate / 1000) *135) / 200 + 2000; ++ f3db += lpf_offset_KHz; ++ if (f3db < 7000) ++ f3db = 7000; ++ if (f3db > 40000) ++ f3db = 40000; ++ ++ gdiv28 = (MT_FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000; ++ m88ds3103_tuner_writereg(state, 0x04, gdiv28 & 0xff); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1b); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x04); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ msleep(5); ++ ++ value = m88ds3103_tuner_readreg(state, 0x26); ++ capCode = value & 0x3f; ++ if(state->tuner_id == TS2022_ID){ ++ m88ds3103_tuner_writereg(state, 0x41, 0x0d); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x1b); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x04); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ ++ msleep(2); ++ ++ value = m88ds3103_tuner_readreg(state, 0x26); ++ value &= 0x3f; ++ value = (capCode + value) / 2; ++ } ++ else ++ value = capCode; ++ ++ gdiv28 = gdiv28 * 207 / (value * 2 + 151); ++ mlpf_max = gdiv28 * 135 / 100; ++ mlpf_min = gdiv28 * 78 / 100; ++ if (mlpf_max > 63) ++ mlpf_max = 63; ++ ++ if(state->tuner_id == TS2022_ID) ++ lpf_coeff = 3200; ++ else ++ lpf_coeff = 2766; ++ ++ nlpf = (f3db * gdiv28 * 2 / lpf_coeff / (MT_FE_CRYSTAL_KHZ / 1000) + 1) / 2 ; ++ if (nlpf > 23) nlpf = 23; ++ if (nlpf < 1) nlpf = 1; ++ ++ lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2; ++ ++ if (lpf_mxdiv < mlpf_min){ ++ nlpf++; ++ lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2; ++ } ++ ++ if (lpf_mxdiv > mlpf_max) ++ lpf_mxdiv = mlpf_max; ++ ++ m88ds3103_tuner_writereg(state, 0x04, lpf_mxdiv); ++ m88ds3103_tuner_writereg(state, 0x06, nlpf); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1b); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x04); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ msleep(5); ++ ++ if(state->tuner_id == TS2022_ID){ ++ msleep(2); ++ value = m88ds3103_tuner_readreg(state, 0x26); ++ capCode = value & 0x3f; ++ ++ m88ds3103_tuner_writereg(state, 0x41, 0x09); ++ ++ m88ds3103_tuner_writereg(state, 0x51, 0x1b); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x04); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ ++ msleep(2); ++ value = m88ds3103_tuner_readreg(state, 0x26); ++ value &= 0x3f; ++ value = (capCode + value) / 2; ++ ++ value = value | 0x80; ++ m88ds3103_tuner_writereg(state, 0x25, value); ++ m88ds3103_tuner_writereg(state, 0x27, 0x30); ++ ++ m88ds3103_tuner_writereg(state, 0x08, 0x09); ++ } ++ ++ /* Set the BB gain */ ++ m88ds3103_tuner_writereg(state, 0x51, 0x1e); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x01); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ if(state->tuner_id == TS2020_ID){ ++ if(RFgain == 15){ ++ msleep(40); ++ value = m88ds3103_tuner_readreg(state, 0x21); ++ value &= 0x0f; ++ if(value < 3){ ++ m88ds3103_tuner_writereg(state, 0x60, 0x61); ++ m88ds3103_tuner_writereg(state, 0x51, 0x17); ++ m88ds3103_tuner_writereg(state, 0x51, 0x1f); ++ m88ds3103_tuner_writereg(state, 0x50, 0x08); ++ m88ds3103_tuner_writereg(state, 0x50, 0x00); ++ } ++ } ++ } ++ msleep(60); ++ ++ offset_khz = (ndiv - ndiv % 2 + 1024) * MT_FE_CRYSTAL_KHZ ++ / (6 + 8) / (div4 + 1) / 2 - realFreq; ++ ++ m88ds3103_demod_connect(fe, offset_khz+lpf_offset_KHz); ++ ++ for (i = 0; i < 30 ; i++) { ++ m88ds3103_read_status(fe, &status); ++ if (status & FE_HAS_LOCK){ ++ break; ++ } ++ msleep(20); ++ } ++ ++ if((status & FE_HAS_LOCK) == 0){ ++ state->delivery_system = (state->delivery_system == SYS_DVBS) ? SYS_DVBS2 : SYS_DVBS; ++ m88ds3103_demod_connect(fe, offset_khz); ++ ++ for (i = 0; i < 30 ; i++) { ++ m88ds3103_read_status(fe, &status); ++ if (status & FE_HAS_LOCK){ ++ break; ++ } ++ msleep(20); ++ } ++ } ++ ++ if (status & FE_HAS_LOCK){ ++ if(state->config->ci_mode == 2) ++ m88ds3103_set_clock_ratio(state); ++ if(state->config->start_ctrl){ ++ if(state->first_lock == 0){ ++ state->config->start_ctrl(fe); ++ state->first_lock = 1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static int m88ds3103_tune(struct dvb_frontend *fe, ++ bool re_tune, ++ unsigned int mode_flags, ++ unsigned int *delay, ++ fe_status_t *status) ++{ ++ *delay = HZ / 5; ++ ++ dprintk("%s() ", __func__); ++ dprintk("re_tune = %d\n", re_tune); ++ ++ if (re_tune) { ++ int ret = m88ds3103_set_frontend(fe); ++ if (ret) ++ return ret; ++ } ++ ++ return m88ds3103_read_status(fe, status); ++} ++ ++static enum dvbfe_algo m88ds3103_get_algo(struct dvb_frontend *fe) ++{ ++ return DVBFE_ALGO_HW; ++} ++ ++ /* ++ * Power config will reset and load initial firmware if required ++ */ ++static int m88ds3103_initilaze(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ int ret; ++ ++ dprintk("%s()\n", __func__); ++ /* hard reset */ ++ m88ds3103_writereg(state, 0x07, 0x80); ++ m88ds3103_writereg(state, 0x07, 0x00); ++ msleep(1); ++ ++ m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08)); ++ msleep(1); ++ ++ if(state->tuner_id == TS2020_ID){ ++ /* TS2020 init */ ++ m88ds3103_tuner_writereg(state, 0x42, 0x73); ++ msleep(2); ++ m88ds3103_tuner_writereg(state, 0x05, 0x01); ++ m88ds3103_tuner_writereg(state, 0x62, 0xb5); ++ m88ds3103_tuner_writereg(state, 0x07, 0x02); ++ m88ds3103_tuner_writereg(state, 0x08, 0x01); ++ } ++ else if(state->tuner_id == TS2022_ID){ ++ /* TS2022 init */ ++ m88ds3103_tuner_writereg(state, 0x62, 0x6c); ++ msleep(2); ++ m88ds3103_tuner_writereg(state, 0x42, 0x6c); ++ msleep(2); ++ m88ds3103_tuner_writereg(state, 0x7d, 0x9d); ++ m88ds3103_tuner_writereg(state, 0x7c, 0x9a); ++ m88ds3103_tuner_writereg(state, 0x7a, 0x76); ++ ++ m88ds3103_tuner_writereg(state, 0x3b, 0x01); ++ m88ds3103_tuner_writereg(state, 0x63, 0x88); ++ ++ m88ds3103_tuner_writereg(state, 0x61, 0x85); ++ m88ds3103_tuner_writereg(state, 0x22, 0x30); ++ m88ds3103_tuner_writereg(state, 0x30, 0x40); ++ m88ds3103_tuner_writereg(state, 0x20, 0x23); ++ m88ds3103_tuner_writereg(state, 0x24, 0x02); ++ m88ds3103_tuner_writereg(state, 0x12, 0xa0); ++ } ++ ++ if(state->demod_id == DS3103_ID){ ++ m88ds3103_writereg(state, 0x07, 0xe0); ++ m88ds3103_writereg(state, 0x07, 0x00); ++ msleep(1); ++ } ++ m88ds3103_writereg(state, 0xb2, 0x01); ++ ++ /* Load the firmware if required */ ++ ret = m88ds3103_load_firmware(fe); ++ if (ret != 0){ ++ printk(KERN_ERR "%s: Unable initialize firmware\n", __func__); ++ return ret; ++ } ++ if(state->demod_id == DS3103_ID){ ++ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d)); ++ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30)); ++ } ++ ++ return 0; ++} ++ ++/* ++ * Initialise or wake up device ++ */ ++static int m88ds3103_initfe(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ u8 val; ++ ++ dprintk("%s()\n", __func__); ++ ++ /* 1st step to wake up demod */ ++ m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08)); ++ m88ds3103_writereg(state, 0x04, 0xfe & m88ds3103_readreg(state, 0x04)); ++ m88ds3103_writereg(state, 0x23, 0xef & m88ds3103_readreg(state, 0x23)); ++ ++ /* 2nd step to wake up tuner */ ++ val = m88ds3103_tuner_readreg(state, 0x00) & 0xff; ++ if((val & 0x01) == 0){ ++ m88ds3103_tuner_writereg(state, 0x00, 0x01); ++ msleep(50); ++ } ++ m88ds3103_tuner_writereg(state, 0x00, 0x03); ++ msleep(50); ++ ++ return 0; ++} ++ ++/* Put device to sleep */ ++static int m88ds3103_sleep(struct dvb_frontend *fe) ++{ ++ struct m88ds3103_state *state = fe->demodulator_priv; ++ ++ dprintk("%s()\n", __func__); ++ ++ /* 1st step to sleep tuner */ ++ m88ds3103_tuner_writereg(state, 0x00, 0x00); ++ ++ /* 2nd step to sleep demod */ ++ m88ds3103_writereg(state, 0x08, 0xfe & m88ds3103_readreg(state, 0x08)); ++ m88ds3103_writereg(state, 0x04, 0x01 | m88ds3103_readreg(state, 0x04)); ++ m88ds3103_writereg(state, 0x23, 0x10 | m88ds3103_readreg(state, 0x23)); ++ ++ ++ return 0; ++} ++ ++static struct dvb_frontend_ops m88ds3103_ops = { ++ .delsys = { SYS_DVBS, SYS_DVBS2}, ++ .info = { ++ .name = "Montage DS3103/TS2022", ++ .type = FE_QPSK, ++ .frequency_min = 950000, ++ .frequency_max = 2150000, ++ .frequency_stepsize = 1011, /* kHz for QPSK frontends */ ++ .frequency_tolerance = 5000, ++ .symbol_rate_min = 1000000, ++ .symbol_rate_max = 45000000, ++ .caps = FE_CAN_INVERSION_AUTO | ++ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | ++ FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | ++ FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | ++ FE_CAN_2G_MODULATION | ++ FE_CAN_QPSK | FE_CAN_RECOVER ++ }, ++ ++ .release = m88ds3103_release, ++ ++ .init = m88ds3103_initfe, ++ .sleep = m88ds3103_sleep, ++ .read_status = m88ds3103_read_status, ++ .read_ber = m88ds3103_read_ber, ++ .read_signal_strength = m88ds3103_read_signal_strength, ++ .read_snr = m88ds3103_read_snr, ++ .read_ucblocks = m88ds3103_read_ucblocks, ++ .set_tone = m88ds3103_set_tone, ++ .set_voltage = m88ds3103_set_voltage, ++ .diseqc_send_master_cmd = m88ds3103_send_diseqc_msg, ++ .diseqc_send_burst = m88ds3103_diseqc_send_burst, ++ .get_frontend_algo = m88ds3103_get_algo, ++ .tune = m88ds3103_tune, ++ .set_frontend = m88ds3103_set_frontend, ++}; ++ ++MODULE_DESCRIPTION("DVB Frontend module for Montage DS3103/TS2022 hardware"); ++MODULE_AUTHOR("Max nibble"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/dvb/frontends/m88ds3103.h b/drivers/media/dvb/frontends/m88ds3103.h +new file mode 100644 +index 0000000..c7b690e +--- /dev/null ++++ b/drivers/media/dvb/frontends/m88ds3103.h +@@ -0,0 +1,53 @@ ++/* ++ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef M88DS3103_H ++#define M88DS3103_H ++ ++#include ++ ++struct m88ds3103_config { ++ /* the demodulator's i2c address */ ++ u8 demod_address; ++ u8 ci_mode; ++ u8 pin_ctrl; ++ u8 ts_mode; /* 0: Parallel, 1: Serial */ ++ ++ /* Set device param to start dma */ ++ int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); ++ /* Start to transfer data */ ++ int (*start_ctrl)(struct dvb_frontend *fe); ++ /* Set LNB voltage */ ++ int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); ++}; ++ ++#if defined(CONFIG_DVB_M88DS3103) || \ ++ (defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE)) ++extern struct dvb_frontend *m88ds3103_attach( ++ const struct m88ds3103_config *config, ++ struct i2c_adapter *i2c); ++#else ++static inline struct dvb_frontend *m88ds3103_attach( ++ const struct m88ds3103_config *config, ++ struct i2c_adapter *i2c) ++{ ++ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); ++ return NULL; ++} ++#endif /* CONFIG_DVB_M88DS3103 */ ++#endif /* M88DS3103_H */ +diff --git a/drivers/media/dvb/frontends/m88ds3103_priv.h b/drivers/media/dvb/frontends/m88ds3103_priv.h +new file mode 100644 +index 0000000..2838514 +--- /dev/null ++++ b/drivers/media/dvb/frontends/m88ds3103_priv.h +@@ -0,0 +1,403 @@ ++/* ++ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef M88DS3103_PRIV_H ++#define M88DS3103_PRIV_H ++ ++#define FW_DOWN_SIZE 32 ++#define FW_DOWN_LOOP (8192/FW_DOWN_SIZE) ++#define DS3103_DEFAULT_FIRMWARE "dvb-fe-ds3103.fw" ++#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds300x.fw" ++#define MT_FE_MCLK_KHZ 96000 /* in kHz */ ++#define MT_FE_CRYSTAL_KHZ 27000 /* in kHz */ ++#define FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz 3000 ++#define DS3000_ID 0x3000 ++#define DS3103_ID 0x3103 ++#define TS2020_ID 0x2020 ++#define TS2022_ID 0x2022 ++#define UNKNOW_ID 0x0000 ++ ++struct m88ds3103_state { ++ struct i2c_adapter *i2c; ++ const struct m88ds3103_config *config; ++ ++ struct dvb_frontend frontend; ++ ++ u32 preBer; ++ u8 skip_fw_load; ++ u8 first_lock; /* The first time of signal lock */ ++ u16 demod_id; /* demod chip type */ ++ u16 tuner_id; /* tuner chip type */ ++ fe_delivery_system_t delivery_system; ++}; ++ ++/* For M88DS3103 demod dvbs mode.*/ ++static u8 ds3103_dvbs_init_tab[] = { ++ 0x23, 0x07, ++ 0x08, 0x03, ++ 0x0c, 0x02, ++ 0x21, 0x54, ++ 0x25, 0x82, ++ 0x27, 0x31, ++ 0x30, 0x08, ++ 0x31, 0x40, ++ 0x32, 0x32, ++ 0x33, 0x35, ++ 0x35, 0xff, ++ 0x3a, 0x00, ++ 0x37, 0x10, ++ 0x38, 0x10, ++ 0x39, 0x02, ++ 0x42, 0x60, ++ 0x4a, 0x80, ++ 0x4b, 0x04, ++ 0x4d, 0x91, ++ 0x5d, 0xc8, ++ 0x50, 0x36, ++ 0x51, 0x36, ++ 0x52, 0x36, ++ 0x53, 0x36, ++ 0x63, 0x0f, ++ 0x64, 0x30, ++ 0x65, 0x40, ++ 0x68, 0x26, ++ 0x69, 0x4c, ++ 0x70, 0x20, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x40, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x60, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x80, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0xa0, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x1f, ++ 0x76, 0x38, ++ 0x77, 0xa6, ++ 0x78, 0x0c, ++ 0x79, 0x80, ++ 0x7f, 0x14, ++ 0x7c, 0x00, ++ 0xae, 0x82, ++ 0x80, 0x64, ++ 0x81, 0x66, ++ 0x82, 0x44, ++ 0x85, 0x04, ++ 0xcd, 0xf4, ++ 0x90, 0x33, ++ 0xa0, 0x44, ++ 0xc0, 0x08, ++ 0xc3, 0x10, ++ 0xc4, 0x08, ++ 0xc5, 0xf0, ++ 0xc6, 0xff, ++ 0xc7, 0x00, ++ 0xc8, 0x1a, ++ 0xc9, 0x80, ++ 0xe0, 0xf8, ++ 0xe6, 0x8b, ++ 0xd0, 0x40, ++ 0xf8, 0x20, ++ 0xfa, 0x0f, ++ 0x00, 0x00, ++ 0xbd, 0x01, ++ 0xb8, 0x00, ++}; ++/* For M88DS3103 demod dvbs2 mode.*/ ++static u8 ds3103_dvbs2_init_tab[] = { ++ 0x23, 0x07, ++ 0x08, 0x07, ++ 0x0c, 0x02, ++ 0x21, 0x54, ++ 0x25, 0x82, ++ 0x27, 0x31, ++ 0x30, 0x08, ++ 0x32, 0x32, ++ 0x33, 0x35, ++ 0x35, 0xff, ++ 0x3a, 0x00, ++ 0x37, 0x10, ++ 0x38, 0x10, ++ 0x39, 0x02, ++ 0x42, 0x60, ++ 0x4a, 0x80, ++ 0x4b, 0x04, ++ 0x4d, 0x91, ++ 0x5d, 0xc8, ++ 0x50, 0x36, ++ 0x51, 0x36, ++ 0x52, 0x36, ++ 0x53, 0x36, ++ 0x63, 0x0f, ++ 0x64, 0x10, ++ 0x65, 0x20, ++ 0x68, 0x46, ++ 0x69, 0xcd, ++ 0x70, 0x20, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x40, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x60, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x80, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0xa0, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x1f, ++ 0x76, 0x38, ++ 0x77, 0xa6, ++ 0x78, 0x0c, ++ 0x79, 0x80, ++ 0x7f, 0x14, ++ 0x85, 0x08, ++ 0xcd, 0xf4, ++ 0x90, 0x33, ++ 0x86, 0x00, ++ 0x87, 0x0f, ++ 0x89, 0x00, ++ 0x8b, 0x44, ++ 0x8c, 0x66, ++ 0x9d, 0xc1, ++ 0x8a, 0x10, ++ 0xad, 0x40, ++ 0xa0, 0x44, ++ 0xc0, 0x08, ++ 0xc1, 0x10, ++ 0xc2, 0x08, ++ 0xc3, 0x10, ++ 0xc4, 0x08, ++ 0xc5, 0xf0, ++ 0xc6, 0xff, ++ 0xc7, 0x00, ++ 0xc8, 0x1a, ++ 0xc9, 0x80, ++ 0xca, 0x23, ++ 0xcb, 0x24, ++ 0xcc, 0xf4, ++ 0xce, 0x74, ++ 0x00, 0x00, ++ 0xbd, 0x01, ++ 0xb8, 0x00, ++}; ++ ++/* For M88DS3000 demod dvbs mode.*/ ++static u8 ds3000_dvbs_init_tab[] = { ++ 0x23, 0x05, ++ 0x08, 0x03, ++ 0x0c, 0x02, ++ 0x21, 0x54, ++ 0x25, 0x82, ++ 0x27, 0x31, ++ 0x30, 0x08, ++ 0x31, 0x40, ++ 0x32, 0x32, ++ 0x33, 0x35, ++ 0x35, 0xff, ++ 0x3a, 0x00, ++ 0x37, 0x10, ++ 0x38, 0x10, ++ 0x39, 0x02, ++ 0x42, 0x60, ++ 0x4a, 0x40, ++ 0x4b, 0x04, ++ 0x4d, 0x91, ++ 0x5d, 0xc8, ++ 0x50, 0x77, ++ 0x51, 0x77, ++ 0x52, 0x36, ++ 0x53, 0x36, ++ 0x56, 0x01, ++ 0x63, 0x47, ++ 0x64, 0x30, ++ 0x65, 0x40, ++ 0x68, 0x26, ++ 0x69, 0x4c, ++ 0x70, 0x20, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x40, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x60, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x80, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0xa0, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x1f, ++ 0x76, 0x00, ++ 0x77, 0xd1, ++ 0x78, 0x0c, ++ 0x79, 0x80, ++ 0x7f, 0x04, ++ 0x7c, 0x00, ++ 0x80, 0x86, ++ 0x81, 0xa6, ++ 0x85, 0x04, ++ 0xcd, 0xf4, ++ 0x90, 0x33, ++ 0xa0, 0x44, ++ 0xc0, 0x18, ++ 0xc3, 0x10, ++ 0xc4, 0x08, ++ 0xc5, 0x80, ++ 0xc6, 0x80, ++ 0xc7, 0x0a, ++ 0xc8, 0x1a, ++ 0xc9, 0x80, ++ 0xfe, 0xb6, ++ 0xe0, 0xf8, ++ 0xe6, 0x8b, ++ 0xd0, 0x40, ++ 0xf8, 0x20, ++ 0xfa, 0x0f, ++ 0xad, 0x20, ++ 0xae, 0x07, ++ 0xb8, 0x00, ++}; ++ ++/* For M88DS3000 demod dvbs2 mode.*/ ++static u8 ds3000_dvbs2_init_tab[] = { ++ 0x23, 0x0f, ++ 0x08, 0x07, ++ 0x0c, 0x02, ++ 0x21, 0x54, ++ 0x25, 0x82, ++ 0x27, 0x31, ++ 0x30, 0x08, ++ 0x31, 0x32, ++ 0x32, 0x32, ++ 0x33, 0x35, ++ 0x35, 0xff, ++ 0x3a, 0x00, ++ 0x37, 0x10, ++ 0x38, 0x10, ++ 0x39, 0x02, ++ 0x42, 0x60, ++ 0x4a, 0x80, ++ 0x4b, 0x04, ++ 0x4d, 0x91, ++ 0x5d, 0x88, ++ 0x50, 0x36, ++ 0x51, 0x36, ++ 0x52, 0x36, ++ 0x53, 0x36, ++ 0x63, 0x60, ++ 0x64, 0x10, ++ 0x65, 0x10, ++ 0x68, 0x04, ++ 0x69, 0x29, ++ 0x70, 0x20, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x40, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x60, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x80, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0xa0, ++ 0x71, 0x70, ++ 0x72, 0x04, ++ 0x73, 0x00, ++ 0x70, 0x1f, ++ 0xa0, 0x44, ++ 0xc0, 0x08, ++ 0xc1, 0x10, ++ 0xc2, 0x08, ++ 0xc3, 0x10, ++ 0xc4, 0x08, ++ 0xc5, 0xf0, ++ 0xc6, 0xf0, ++ 0xc7, 0x0a, ++ 0xc8, 0x1a, ++ 0xc9, 0x80, ++ 0xca, 0x23, ++ 0xcb, 0x24, ++ 0xce, 0x74, ++ 0x56, 0x01, ++ 0x90, 0x03, ++ 0x76, 0x80, ++ 0x77, 0x42, ++ 0x78, 0x0a, ++ 0x79, 0x80, ++ 0xad, 0x40, ++ 0xae, 0x07, ++ 0x7f, 0xd4, ++ 0x7c, 0x00, ++ 0x80, 0xa8, ++ 0x81, 0xda, ++ 0x7c, 0x01, ++ 0x80, 0xda, ++ 0x81, 0xec, ++ 0x7c, 0x02, ++ 0x80, 0xca, ++ 0x81, 0xeb, ++ 0x7c, 0x03, ++ 0x80, 0xba, ++ 0x81, 0xdb, ++ 0x85, 0x08, ++ 0x86, 0x00, ++ 0x87, 0x02, ++ 0x89, 0x80, ++ 0x8b, 0x44, ++ 0x8c, 0xaa, ++ 0x8a, 0x10, ++ 0xba, 0x00, ++ 0xf5, 0x04, ++ 0xd2, 0x32, ++ 0xb8, 0x00, ++}; ++ ++#endif /* M88DS3103_PRIV_H */ +diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile +index 49ce266..e6a882b 100644 +--- a/drivers/media/rc/keymaps/Makefile ++++ b/drivers/media/rc/keymaps/Makefile +@@ -26,6 +26,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \ + rc-dm1105-nec.o \ + rc-dntv-live-dvb-t.o \ + rc-dntv-live-dvbt-pro.o \ ++ rc-dvbsky.o \ + rc-em-terratec.o \ + rc-encore-enltv2.o \ + rc-encore-enltv.o \ +diff --git a/drivers/media/rc/keymaps/rc-dvbsky.c b/drivers/media/rc/keymaps/rc-dvbsky.c +new file mode 100644 +index 0000000..2bd9977 +--- /dev/null ++++ b/drivers/media/rc/keymaps/rc-dvbsky.c +@@ -0,0 +1,78 @@ ++/* rc-dvbsky.c - Keytable for Dvbsky Remote Controllers ++ * ++ * keymap imported from ir-keymaps.c ++ * ++ * ++ * Copyright (c) 2010-2011 by Mauro Carvalho Chehab ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++/* ++ * This table contains the complete RC5 code, instead of just the data part ++ */ ++ ++static struct rc_map_table rc5_dvbsky[] = { ++ { 0x0000, KEY_0 }, ++ { 0x0001, KEY_1 }, ++ { 0x0002, KEY_2 }, ++ { 0x0003, KEY_3 }, ++ { 0x0004, KEY_4 }, ++ { 0x0005, KEY_5 }, ++ { 0x0006, KEY_6 }, ++ { 0x0007, KEY_7 }, ++ { 0x0008, KEY_8 }, ++ { 0x0009, KEY_9 }, ++ { 0x000a, KEY_MUTE }, ++ { 0x000d, KEY_OK }, ++ { 0x000b, KEY_STOP }, ++ { 0x000c, KEY_EXIT }, ++ { 0x000e, KEY_CAMERA }, /*Snap shot*/ ++ { 0x000f, KEY_SUBTITLE }, /*PIP*/ ++ { 0x0010, KEY_VOLUMEUP }, ++ { 0x0011, KEY_VOLUMEDOWN }, ++ { 0x0012, KEY_FAVORITES }, ++ { 0x0013, KEY_LIST }, /*Info*/ ++ { 0x0016, KEY_PAUSE }, ++ { 0x0017, KEY_PLAY }, ++ { 0x001f, KEY_RECORD }, ++ { 0x0020, KEY_CHANNELDOWN }, ++ { 0x0021, KEY_CHANNELUP }, ++ { 0x0025, KEY_POWER2 }, ++ { 0x0026, KEY_REWIND }, ++ { 0x0027, KEY_FASTFORWARD }, ++ { 0x0029, KEY_LAST }, ++ { 0x002b, KEY_MENU }, ++ { 0x002c, KEY_EPG }, ++ { 0x002d, KEY_ZOOM }, ++}; ++ ++static struct rc_map_list rc5_dvbsky_map = { ++ .map = { ++ .scan = rc5_dvbsky, ++ .size = ARRAY_SIZE(rc5_dvbsky), ++ .rc_type = RC_TYPE_RC5, ++ .name = RC_MAP_DVBSKY, ++ } ++}; ++ ++static int __init init_rc_map_rc5_dvbsky(void) ++{ ++ return rc_map_register(&rc5_dvbsky_map); ++} ++ ++static void __exit exit_rc_map_rc5_dvbsky(void) ++{ ++ rc_map_unregister(&rc5_dvbsky_map); ++} ++ ++module_init(init_rc_map_rc5_dvbsky) ++module_exit(exit_rc_map_rc5_dvbsky) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Mauro Carvalho Chehab "); +diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig +index b391e9b..20337c7 100644 +--- a/drivers/media/video/cx23885/Kconfig ++++ b/drivers/media/video/cx23885/Kconfig +@@ -20,6 +20,7 @@ config VIDEO_CX23885 + select DVB_LNBP21 if !DVB_FE_CUSTOMISE + select DVB_STV6110 if !DVB_FE_CUSTOMISE + select DVB_CX24116 if !DVB_FE_CUSTOMISE ++ select DVB_M88DS3103 if !DVB_FE_CUSTOMISE + select DVB_STV0900 if !DVB_FE_CUSTOMISE + select DVB_DS3000 if !DVB_FE_CUSTOMISE + select DVB_STV0367 if !DVB_FE_CUSTOMISE +diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c +index 19b5499..c707f19 100644 +--- a/drivers/media/video/cx23885/cx23885-cards.c ++++ b/drivers/media/video/cx23885/cx23885-cards.c +@@ -497,7 +497,31 @@ struct cx23885_board cx23885_boards[] = { + .name = "TerraTec Cinergy T PCIe Dual", + .portb = CX23885_MPEG_DVB, + .portc = CX23885_MPEG_DVB, +- } ++ }, ++ ++ [CX23885_BOARD_BST_PS8512] = { ++ .name = "Bestunar PS8512", ++ .portb = CX23885_MPEG_DVB, ++ }, ++ [CX23885_BOARD_DVBSKY_S950] = { ++ .name = "DVBSKY S950", ++ .portb = CX23885_MPEG_DVB, ++ }, ++ [CX23885_BOARD_DVBSKY_S952] = { ++ .name = "DVBSKY S952", ++ .portb = CX23885_MPEG_DVB, ++ .portc = CX23885_MPEG_DVB, ++ }, ++ [CX23885_BOARD_DVBSKY_S950_CI] = { ++ .ci_type = 3, ++ .name = "DVBSKY S950CI DVB-S2 CI", ++ .portb = CX23885_MPEG_DVB, ++ }, ++ [CX23885_BOARD_DVBSKY_C2800E_CI] = { ++ .ci_type = 3, ++ .name = "DVBSKY C2800E DVB-C CI", ++ .portb = CX23885_MPEG_DVB, ++ }, + }; + const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); + +@@ -705,6 +729,26 @@ struct cx23885_subid cx23885_subids[] = { + .subvendor = 0x153b, + .subdevice = 0x117e, + .card = CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL, ++ }, { ++ .subvendor = 0x14f1, ++ .subdevice = 0x8512, ++ .card = CX23885_BOARD_BST_PS8512, ++ }, { ++ .subvendor = 0x4254, ++ .subdevice = 0x0950, ++ .card = CX23885_BOARD_DVBSKY_S950, ++ }, { ++ .subvendor = 0x4254, ++ .subdevice = 0x0952, ++ .card = CX23885_BOARD_DVBSKY_S952, ++ }, { ++ .subvendor = 0x4254, ++ .subdevice = 0x950C, ++ .card = CX23885_BOARD_DVBSKY_S950_CI, ++ }, { ++ .subvendor = 0x4254, ++ .subdevice = 0x2800, ++ .card = CX23885_BOARD_DVBSKY_C2800E_CI, + }, + }; + const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); +@@ -1216,9 +1260,83 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) + /* enable irq */ + cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ + break; ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_BST_PS8512: ++ cx23885_gpio_enable(dev, GPIO_2, 1); ++ cx23885_gpio_clear(dev, GPIO_2); ++ msleep(100); ++ cx23885_gpio_set(dev, GPIO_2); ++ break; ++ case CX23885_BOARD_DVBSKY_S952: ++ cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */ ++ ++ cx23885_gpio_enable(dev, GPIO_2, 1); ++ cx23885_gpio_enable(dev, GPIO_11, 1); ++ ++ cx23885_gpio_clear(dev, GPIO_2); ++ cx23885_gpio_clear(dev, GPIO_11); ++ msleep(100); ++ cx23885_gpio_set(dev, GPIO_2); ++ cx23885_gpio_set(dev, GPIO_11); ++ break; ++ case CX23885_BOARD_DVBSKY_S950_CI: ++ case CX23885_BOARD_DVBSKY_C2800E_CI: ++ /* GPIO-0 INTA from CiMax, input ++ GPIO-1 reset CiMax, output, high active ++ GPIO-2 reset demod, output, low active ++ GPIO-3 to GPIO-10 data/addr for CAM ++ GPIO-11 ~CS0 to CiMax1 ++ GPIO-12 ~CS1 to CiMax2 ++ GPIO-13 ADL0 load LSB addr ++ GPIO-14 ADL1 load MSB addr ++ GPIO-15 ~RDY from CiMax ++ GPIO-17 ~RD to CiMax ++ GPIO-18 ~WR to CiMax ++ */ ++ cx_set(GP0_IO, 0x00060002); /* GPIO 1/2 as output */ ++ cx_clear(GP0_IO, 0x00010004); /*GPIO 0 as input*/ ++ mdelay(100);/* reset delay */ ++ cx_set(GP0_IO, 0x00060004); /* GPIO as out, reset high */ ++ cx_clear(GP0_IO, 0x00010002); ++ cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */ ++ /* GPIO-15 IN as ~ACK, rest as OUT */ ++ cx_write(MC417_OEN, 0x00001000); ++ /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */ ++ cx_write(MC417_RWD, 0x0000c300); ++ /* enable irq */ ++ cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ ++ break; + } + } + ++static int cx23885_ir_patch(struct i2c_adapter *i2c, u8 reg, u8 mask) ++{ ++ struct i2c_msg msgs[2]; ++ u8 tx_buf[2], rx_buf[1]; ++ /* Write register address */ ++ tx_buf[0] = reg; ++ msgs[0].addr = 0x4c; ++ msgs[0].flags = 0; ++ msgs[0].len = 1; ++ msgs[0].buf = (char *) tx_buf; ++ /* Read data from register */ ++ msgs[1].addr = 0x4c; ++ msgs[1].flags = I2C_M_RD; ++ msgs[1].len = 1; ++ msgs[1].buf = (char *) rx_buf; ++ ++ i2c_transfer(i2c, msgs, 2); ++ ++ tx_buf[0] = reg; ++ tx_buf[1] = rx_buf[0] | mask; ++ msgs[0].addr = 0x4c; ++ msgs[0].flags = 0; ++ msgs[0].len = 2; ++ msgs[0].buf = (char *) tx_buf; ++ ++ return i2c_transfer(i2c, msgs, 1); ++} ++ + int cx23885_ir_init(struct cx23885_dev *dev) + { + static struct v4l2_subdev_io_pin_config ir_rxtx_pin_cfg[] = { +@@ -1301,6 +1419,22 @@ int cx23885_ir_init(struct cx23885_dev *dev) + v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, + ir_rx_pin_cfg_count, ir_rx_pin_cfg); + break; ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: ++ case CX23885_BOARD_DVBSKY_S950_CI: ++ case CX23885_BOARD_DVBSKY_C2800E_CI: ++ dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); ++ if (dev->sd_ir == NULL) { ++ ret = -ENODEV; ++ break; ++ } ++ v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, ++ ir_rx_pin_cfg_count, ir_rx_pin_cfg); ++ ++ cx23885_ir_patch(&(dev->i2c_bus[2].i2c_adap),0x1f,0x80); ++ cx23885_ir_patch(&(dev->i2c_bus[2].i2c_adap),0x23,0x80); ++ break; + case CX23885_BOARD_HAUPPAUGE_HVR1250: + if (!enable_885_ir) + break; +@@ -1332,6 +1466,11 @@ void cx23885_ir_fini(struct cx23885_dev *dev) + break; + case CX23885_BOARD_TEVII_S470: + case CX23885_BOARD_HAUPPAUGE_HVR1250: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: ++ case CX23885_BOARD_DVBSKY_S950_CI: ++ case CX23885_BOARD_DVBSKY_C2800E_CI: + cx23885_irq_remove(dev, PCI_MSK_AV_CORE); + /* sd_ir is a duplicate pointer to the AV Core, just clear it */ + dev->sd_ir = NULL; +@@ -1375,6 +1514,11 @@ void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) + break; + case CX23885_BOARD_TEVII_S470: + case CX23885_BOARD_HAUPPAUGE_HVR1250: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: ++ case CX23885_BOARD_DVBSKY_S950_CI: ++ case CX23885_BOARD_DVBSKY_C2800E_CI: + if (dev->sd_ir) + cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); + break; +@@ -1459,6 +1603,10 @@ void cx23885_card_setup(struct cx23885_dev *dev) + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S950_CI: ++ case CX23885_BOARD_DVBSKY_C2800E_CI: + case CX23885_BOARD_TEVII_S470: + case CX23885_BOARD_DVBWORLD_2005: + ts1->gen_ctrl_val = 0x5; /* Parallel */ +@@ -1489,6 +1637,14 @@ void cx23885_card_setup(struct cx23885_dev *dev) + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; ++ case CX23885_BOARD_DVBSKY_S952: ++ ts1->gen_ctrl_val = 0x5; /* Parallel */ ++ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ++ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; ++ ts2->gen_ctrl_val = 0xe; /* Serial bus + punctured clock */ ++ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ++ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; ++ break; + case CX23885_BOARD_HAUPPAUGE_HVR1250: + case CX23885_BOARD_HAUPPAUGE_HVR1500: + case CX23885_BOARD_HAUPPAUGE_HVR1500Q: +@@ -1541,6 +1697,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) + case CX23885_BOARD_MPX885: + case CX23885_BOARD_MYGICA_X8507: + case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: ++ case CX23885_BOARD_DVBSKY_S950_CI: ++ case CX23885_BOARD_DVBSKY_C2800E_CI: + dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, + &dev->i2c_bus[2].i2c_adap, + "cx25840", 0x88 >> 1, NULL); +diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c +index 6835eb1..e5b39b5 100644 +--- a/drivers/media/video/cx23885/cx23885-dvb.c ++++ b/drivers/media/video/cx23885/cx23885-dvb.c +@@ -51,6 +51,7 @@ + #include "stv6110.h" + #include "lnbh24.h" + #include "cx24116.h" ++#include "m88ds3103.h" + #include "cimax2.h" + #include "lgs8gxx.h" + #include "netup-eeprom.h" +@@ -489,6 +490,37 @@ static struct xc5000_config mygica_x8506_xc5000_config = { + .if_khz = 5380, + }; + ++/* bestunar single dvb-s2 */ ++static struct m88ds3103_config bst_ds3103_config = { ++ .demod_address = 0x68, ++ .ci_mode = 0, ++ .pin_ctrl = 0x82, ++ .ts_mode = 0, ++ .set_voltage = bst_set_voltage, ++}; ++/* DVBSKY dual dvb-s2 */ ++static struct m88ds3103_config dvbsky_ds3103_config_pri = { ++ .demod_address = 0x68, ++ .ci_mode = 0, ++ .pin_ctrl = 0x82, ++ .ts_mode = 0, ++ .set_voltage = bst_set_voltage, ++}; ++static struct m88ds3103_config dvbsky_ds3103_config_sec = { ++ .demod_address = 0x68, ++ .ci_mode = 0, ++ .pin_ctrl = 0x82, ++ .ts_mode = 1, ++ .set_voltage = dvbsky_set_voltage_sec, ++}; ++ ++static struct m88ds3103_config dvbsky_ds3103_ci_config = { ++ .demod_address = 0x68, ++ .ci_mode = 2, ++ .pin_ctrl = 0x82, ++ .ts_mode = 0, ++}; ++ + static int cx23885_dvb_set_frontend(struct dvb_frontend *fe) + { + struct dtv_frontend_properties *p = &fe->dtv_property_cache; +@@ -1173,6 +1205,41 @@ static int dvb_register(struct cx23885_tsport *port) + break; + } + break; ++ ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ i2c_bus = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(m88ds3103_attach, ++ &bst_ds3103_config, ++ &i2c_bus->i2c_adap); ++ break; ++ ++ case CX23885_BOARD_DVBSKY_S952: ++ switch (port->nr) { ++ /* port B */ ++ case 1: ++ i2c_bus = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(m88ds3103_attach, ++ &dvbsky_ds3103_config_pri, ++ &i2c_bus->i2c_adap); ++ break; ++ /* port C */ ++ case 2: ++ i2c_bus = &dev->i2c_bus[0]; ++ fe0->dvb.frontend = dvb_attach(m88ds3103_attach, ++ &dvbsky_ds3103_config_sec, ++ &i2c_bus->i2c_adap); ++ break; ++ } ++ break; ++ ++ case CX23885_BOARD_DVBSKY_S950_CI: ++ i2c_bus = &dev->i2c_bus[1]; ++ fe0->dvb.frontend = dvb_attach(m88ds3103_attach, ++ &dvbsky_ds3103_ci_config, ++ &i2c_bus->i2c_adap); ++ break; ++ + default: + printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " + " isn't supported yet\n", +@@ -1221,7 +1288,7 @@ static int dvb_register(struct cx23885_tsport *port) + printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n", + port->nr, port->frontends.adapter.proposed_mac); + +- netup_ci_init(port); ++ netup_ci_init(port, false); + break; + } + case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: { +@@ -1248,6 +1315,36 @@ static int dvb_register(struct cx23885_tsport *port) + memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); + break; + } ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952:{ ++ u8 eeprom[256]; /* 24C02 i2c eeprom */ ++ ++ if(port->nr > 2) ++ break; ++ ++ dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; ++ tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); ++ printk(KERN_INFO "DVBSKY PCIe MAC= %pM\n", eeprom + 0xc0+(port->nr-1)*8); ++ memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0 + ++ (port->nr-1)*8, 6); ++ break; ++ } ++ case CX23885_BOARD_DVBSKY_S950_CI: { ++ u8 eeprom[256]; /* 24C02 i2c eeprom */ ++ ++ if(port->nr > 2) ++ break; ++ ++ dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; ++ tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); ++ printk(KERN_INFO "DVBSKY PCIe MAC= %pM\n", eeprom + 0xc0+(port->nr-1)*8); ++ memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xc0 + ++ (port->nr-1)*8, 6); ++ ++ netup_ci_init(port, true); ++ break; ++ } + } + + return ret; +@@ -1330,6 +1427,7 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port) + + switch (port->dev->board) { + case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: ++ case CX23885_BOARD_DVBSKY_S950_CI: + netup_ci_exit(port); + break; + case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: +diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/video/cx23885/cx23885-f300.c +index 93998f2..f8b8c55 100644 +--- a/drivers/media/video/cx23885/cx23885-f300.c ++++ b/drivers/media/video/cx23885/cx23885-f300.c +@@ -175,3 +175,58 @@ int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) + + return f300_xfer(fe, buf); + } ++ ++/* bst control */ ++int bst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct cx23885_tsport *port = fe->dvb->priv; ++ struct cx23885_dev *dev = port->dev; ++ ++ cx23885_gpio_enable(dev, GPIO_1, 1); ++ cx23885_gpio_enable(dev, GPIO_0, 1); ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ cx23885_gpio_set(dev, GPIO_1); ++ cx23885_gpio_clear(dev, GPIO_0); ++ break; ++ case SEC_VOLTAGE_18: ++ cx23885_gpio_set(dev, GPIO_1); ++ cx23885_gpio_set(dev, GPIO_0); ++ break; ++ case SEC_VOLTAGE_OFF: ++ cx23885_gpio_clear(dev, GPIO_1); ++ cx23885_gpio_clear(dev, GPIO_0); ++ break; ++ } ++ ++ ++ return 0; ++} ++ ++int dvbsky_set_voltage_sec(struct dvb_frontend *fe, fe_sec_voltage_t voltage) ++{ ++ struct cx23885_tsport *port = fe->dvb->priv; ++ struct cx23885_dev *dev = port->dev; ++ ++ cx23885_gpio_enable(dev, GPIO_12, 1); ++ cx23885_gpio_enable(dev, GPIO_13, 1); ++ ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ cx23885_gpio_set(dev, GPIO_13); ++ cx23885_gpio_clear(dev, GPIO_12); ++ break; ++ case SEC_VOLTAGE_18: ++ cx23885_gpio_set(dev, GPIO_13); ++ cx23885_gpio_set(dev, GPIO_12); ++ break; ++ case SEC_VOLTAGE_OFF: ++ cx23885_gpio_clear(dev, GPIO_13); ++ cx23885_gpio_clear(dev, GPIO_12); ++ break; ++ } ++ ++ ++ return 0; ++} +\ No newline at end of file +diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/video/cx23885/cx23885-f300.h +index e73344c..f93f37d 100644 +--- a/drivers/media/video/cx23885/cx23885-f300.h ++++ b/drivers/media/video/cx23885/cx23885-f300.h +@@ -1,2 +1,8 @@ ++extern int dvbsky_set_voltage_sec(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage); ++ ++extern int bst_set_voltage(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage); ++ + extern int f300_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage); +diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c +index ce765e3..2026ec1 100644 +--- a/drivers/media/video/cx23885/cx23885-input.c ++++ b/drivers/media/video/cx23885/cx23885-input.c +@@ -87,6 +87,10 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) + case CX23885_BOARD_HAUPPAUGE_HVR1290: + case CX23885_BOARD_TEVII_S470: + case CX23885_BOARD_HAUPPAUGE_HVR1250: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: ++ case CX23885_BOARD_DVBSKY_S950_CI: + /* + * The only boards we handle right now. However other boards + * using the CX2388x integrated IR controller should be similar +@@ -138,6 +142,10 @@ static int cx23885_input_ir_start(struct cx23885_dev *dev) + case CX23885_BOARD_HAUPPAUGE_HVR1850: + case CX23885_BOARD_HAUPPAUGE_HVR1290: + case CX23885_BOARD_HAUPPAUGE_HVR1250: ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: ++ case CX23885_BOARD_DVBSKY_S950_CI: + /* + * The IR controller on this board only returns pulse widths. + * Any other mode setting will fail to set up the device. +@@ -279,6 +287,16 @@ int cx23885_input_init(struct cx23885_dev *dev) + /* A guess at the remote */ + rc_map = RC_MAP_TEVII_NEC; + break; ++ case CX23885_BOARD_BST_PS8512: ++ case CX23885_BOARD_DVBSKY_S950: ++ case CX23885_BOARD_DVBSKY_S952: ++ case CX23885_BOARD_DVBSKY_S950_CI: ++ /* Integrated CX2388[58] IR controller */ ++ driver_type = RC_DRIVER_IR_RAW; ++ allowed_protos = RC_TYPE_ALL; ++ /* A guess at the remote */ ++ rc_map = RC_MAP_DVBSKY; ++ break; + default: + return -ENODEV; + } +diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h +index f020f05..0e22e44 100644 +--- a/drivers/media/video/cx23885/cx23885.h ++++ b/drivers/media/video/cx23885/cx23885.h +@@ -89,6 +89,10 @@ + #define CX23885_BOARD_MPX885 32 + #define CX23885_BOARD_MYGICA_X8507 33 + #define CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL 34 ++#define CX23885_BOARD_BST_PS8512 35 ++#define CX23885_BOARD_DVBSKY_S952 36 ++#define CX23885_BOARD_DVBSKY_S950 37 ++#define CX23885_BOARD_DVBSKY_S950_CI 38 + + #define GPIO_0 0x00000001 + #define GPIO_1 0x00000002 +@@ -227,7 +231,7 @@ struct cx23885_board { + */ + u32 clk_freq; + struct cx23885_input input[MAX_CX23885_INPUT]; +- int ci_type; /* for NetUP */ ++ int ci_type; /* 1 and 2 for NetUP, 3 for DVBSky. */ + /* Force bottom field first during DMA (888 workaround) */ + u32 force_bff; + }; +diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig +index 3598dc0..0daef63 100644 +--- a/drivers/media/video/cx88/Kconfig ++++ b/drivers/media/video/cx88/Kconfig +@@ -57,6 +57,7 @@ config VIDEO_CX88_DVB + select DVB_ISL6421 if !DVB_FE_CUSTOMISE + select DVB_S5H1411 if !DVB_FE_CUSTOMISE + select DVB_CX24116 if !DVB_FE_CUSTOMISE ++ select DVB_M88DS3103 if !DVB_FE_CUSTOMISE + select DVB_STV0299 if !DVB_FE_CUSTOMISE + select DVB_STV0288 if !DVB_FE_CUSTOMISE + select DVB_STB6000 if !DVB_FE_CUSTOMISE +diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c +index cbd5d11..d4e576e 100644 +--- a/drivers/media/video/cx88/cx88-cards.c ++++ b/drivers/media/video/cx88/cx88-cards.c +@@ -2309,6 +2309,18 @@ static const struct cx88_board cx88_boards[] = { + } }, + .mpeg = CX88_MPEG_DVB, + }, ++ [CX88_BOARD_BST_PS8312] = { ++ .name = "Bestunar PS8312 DVB-S/S2", ++ .tuner_type = UNSET, ++ .radio_type = UNSET, ++ .tuner_addr = ADDR_UNSET, ++ .radio_addr = ADDR_UNSET, ++ .input = {{ ++ .type = CX88_VMUX_DVB, ++ .vmux = 0, ++ } }, ++ .mpeg = CX88_MPEG_DVB, ++ }, + }; + + /* ------------------------------------------------------------------ */ +@@ -2813,6 +2825,10 @@ static const struct cx88_subid cx88_subids[] = { + .subvendor = 0x1822, + .subdevice = 0x0023, + .card = CX88_BOARD_TWINHAN_VP1027_DVBS, ++ }, { ++ .subvendor = 0x14f1, ++ .subdevice = 0x8312, ++ .card = CX88_BOARD_BST_PS8312, + }, + }; + +@@ -3547,6 +3563,12 @@ static void cx88_card_setup(struct cx88_core *core) + cx_write(MO_SRST_IO, 1); + msleep(100); + break; ++ case CX88_BOARD_BST_PS8312: ++ cx_write(MO_GP1_IO, 0x808000); ++ msleep(100); ++ cx_write(MO_GP1_IO, 0x808080); ++ msleep(100); ++ break; + } /*end switch() */ + + +diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c +index 003937c..b1bb055 100644 +--- a/drivers/media/video/cx88/cx88-dvb.c ++++ b/drivers/media/video/cx88/cx88-dvb.c +@@ -54,6 +54,7 @@ + #include "stv0288.h" + #include "stb6000.h" + #include "cx24116.h" ++#include "m88ds3103.h" + #include "stv0900.h" + #include "stb6100.h" + #include "stb6100_proc.h" +@@ -458,6 +459,56 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe, + return core->prev_set_voltage(fe, voltage); + return 0; + } ++/*CX88_BOARD_BST_PS8312*/ ++static int bst_dvbs_set_voltage(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage) ++{ ++ struct cx8802_dev *dev= fe->dvb->priv; ++ struct cx88_core *core = dev->core; ++ ++ cx_write(MO_GP1_IO, 0x111111); ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ cx_write(MO_GP1_IO, 0x020200); ++ break; ++ case SEC_VOLTAGE_18: ++ cx_write(MO_GP1_IO, 0x020202); ++ break; ++ case SEC_VOLTAGE_OFF: ++ cx_write(MO_GP1_IO, 0x111100); ++ break; ++ } ++ ++ if (core->prev_set_voltage) ++ return core->prev_set_voltage(fe, voltage); ++ return 0; ++} ++ ++static int bst_dvbs_set_voltage_v2(struct dvb_frontend *fe, ++ fe_sec_voltage_t voltage) ++{ ++ struct cx8802_dev *dev= fe->dvb->priv; ++ struct cx88_core *core = dev->core; ++ ++ cx_write(MO_GP1_IO, 0x111101); ++ switch (voltage) { ++ case SEC_VOLTAGE_13: ++ cx_write(MO_GP1_IO, 0x020200); ++ break; ++ case SEC_VOLTAGE_18: ++ ++ cx_write(MO_GP1_IO, 0x020202); ++ break; ++ case SEC_VOLTAGE_OFF: ++ ++ cx_write(MO_GP1_IO, 0x111110); ++ break; ++ } ++ ++ if (core->prev_set_voltage) ++ return core->prev_set_voltage(fe, voltage); ++ return 0; ++} + + static int vp1027_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +@@ -700,6 +751,11 @@ static struct ds3000_config tevii_ds3000_config = { + .set_ts_params = ds3000_set_ts_param, + }; + ++static struct m88ds3103_config dvbsky_ds3103_config = { ++ .demod_address = 0x68, ++ .set_ts_params = ds3000_set_ts_param, ++}; ++ + static const struct stv0900_config prof_7301_stv0900_config = { + .demod_address = 0x6a, + /* demod_mode = 0,*/ +@@ -1470,6 +1526,35 @@ static int dvb_register(struct cx8802_dev *dev) + fe0->dvb.frontend->ops.set_voltage = + tevii_dvbs_set_voltage; + break; ++ case CX88_BOARD_BST_PS8312: ++ fe0->dvb.frontend = dvb_attach(m88ds3103_attach, ++ &dvbsky_ds3103_config, ++ &core->i2c_adap); ++ if (fe0->dvb.frontend != NULL){ ++ int ret; ++ u8 b0[] = { 0x60 }; ++ u8 b1[2] = { 0 }; ++ struct i2c_msg msg[] = { ++ { ++ .addr = 0x50, ++ .flags = 0, ++ .buf = b0, ++ .len = 1 ++ }, { ++ .addr = 0x50, ++ .flags = I2C_M_RD, ++ .buf = b1, ++ .len = 2 ++ } ++ }; ++ ret = i2c_transfer(&core->i2c_adap, msg, 2); ++ printk("PS8312: config = %02x, %02x", b1[0],b1[1]); ++ if(b1[0] == 0xaa) ++ fe0->dvb.frontend->ops.set_voltage = bst_dvbs_set_voltage_v2; ++ else ++ fe0->dvb.frontend->ops.set_voltage = bst_dvbs_set_voltage; ++ } ++ break; + case CX88_BOARD_OMICOM_SS4_PCI: + case CX88_BOARD_TBS_8920: + case CX88_BOARD_PROF_7300: +diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c +index ebf448c..bcdcc8f 100644 +--- a/drivers/media/video/cx88/cx88-input.c ++++ b/drivers/media/video/cx88/cx88-input.c +@@ -419,6 +419,10 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) + rc_type = RC_TYPE_NEC; + ir->sampling = 0xff00; /* address */ + break; ++ case CX88_BOARD_BST_PS8312: ++ ir_codes = RC_MAP_DVBSKY; ++ ir->sampling = 0xff00; /* address */ ++ break; + } + + if (!ir_codes) { +diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h +index c9659de..a988f14 100644 +--- a/drivers/media/video/cx88/cx88.h ++++ b/drivers/media/video/cx88/cx88.h +@@ -246,6 +246,7 @@ extern const struct sram_channel const cx88_sram_channels[]; + #define CX88_BOARD_WINFAST_DTV1800H_XC4000 88 + #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F36 89 + #define CX88_BOARD_WINFAST_TV2000_XP_GLOBAL_6F43 90 ++#define CX88_BOARD_BST_PS8312 91 + + enum cx88_itype { + CX88_VMUX_COMPOSITE1 = 1, +diff --git a/include/media/rc-map.h b/include/media/rc-map.h +index 8db6741..7176dac 100644 +--- a/include/media/rc-map.h ++++ b/include/media/rc-map.h +@@ -85,6 +85,7 @@ void rc_map_init(void); + #define RC_MAP_DM1105_NEC "rc-dm1105-nec" + #define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro" + #define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t" ++#define RC_MAP_DVBSKY "rc-dvbsky" + #define RC_MAP_EMPTY "rc-empty" + #define RC_MAP_EM_TERRATEC "rc-em-terratec" + #define RC_MAP_ENCORE_ENLTV2 "rc-encore-enltv2" +-- +1.8.2.2 + diff --git a/projects/H3/patches/linux/linux-999-enable_g_ether.patch b/projects/H3/patches/linux/linux-999-enable_g_ether.patch new file mode 100644 index 00000000000..e566cbd5872 --- /dev/null +++ b/projects/H3/patches/linux/linux-999-enable_g_ether.patch @@ -0,0 +1,12 @@ +diff -rpuN a/drivers/usb/sunxi_usb/udc/sunxi_udc.c b/drivers/usb/sunxi_usb/udc/sunxi_udc.c +--- a/drivers/usb/sunxi_usb/udc/sunxi_udc.c 2016-06-12 16:08:07.000000000 +0200 ++++ b/drivers/usb/sunxi_usb/udc/sunxi_udc.c 2016-06-12 16:51:30.000000000 +0200 +@@ -57,7 +57,7 @@ + static sunxi_udc_io_t g_sunxi_udc_io; + static u32 usb_connect = 0; + static u32 is_controller_alive = 0; +-static u8 is_udc_enable = 0; /* is udc enable by gadget? */ ++static u8 is_udc_enable = 1; /* is udc enable by gadget? */ + + #ifdef CONFIG_USB_SUNXI_USB0_OTG + static struct platform_device *g_udc_pdev = NULL; diff --git a/projects/H3/patches/mt7610u/mt7610u-000-build-fix.patch b/projects/H3/patches/mt7610u/mt7610u-000-build-fix.patch new file mode 100644 index 00000000000..7948c4f5ea5 --- /dev/null +++ b/projects/H3/patches/mt7610u/mt7610u-000-build-fix.patch @@ -0,0 +1,17 @@ +diff -Nur a/include/os/rt_linux.h b/include/os/rt_linux.h +--- a/include/os/rt_linux.h 2016-04-12 21:56:36.000000000 +0200 ++++ b/include/os/rt_linux.h 2016-04-12 21:59:47.571744543 +0200 +@@ -277,8 +277,13 @@ + + typedef struct _OS_FS_INFO_ + { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) ++ uid_t fsuid; ++ gid_t fsgid; ++#else + kuid_t fsuid; + kgid_t fsgid; ++#endif + mm_segment_t fs; + } OS_FS_INFO; + diff --git a/projects/H3/patches/systemd/systemd-000-btrfs-remove-quota-support.patch b/projects/H3/patches/systemd/systemd-000-btrfs-remove-quota-support.patch new file mode 100644 index 00000000000..cb53846dca6 --- /dev/null +++ b/projects/H3/patches/systemd/systemd-000-btrfs-remove-quota-support.patch @@ -0,0 +1,312 @@ +diff -Nur a/src/basic/btrfs-ctree.h b/src/basic/btrfs-ctree.h +--- a/src/basic/btrfs-ctree.h 2016-02-06 12:30:04.503129468 +0100 ++++ b/src/basic/btrfs-ctree.h 2016-02-06 12:27:13.000000000 +0100 +@@ -4,6 +4,7 @@ + + #include "macro.h" + #include "sparse-endian.h" ++#include "missing.h" + + /* Stolen from btrfs' ctree.h */ + +diff -Nur a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c +--- a/src/basic/btrfs-util.c 2016-02-06 11:57:03.000000000 +0100 ++++ b/src/basic/btrfs-util.c 2016-02-06 13:22:47.297815187 +0100 +@@ -543,6 +543,7 @@ + return 0; + } + ++#if 0 + int btrfs_qgroup_get_quota_fd(int fd, uint64_t qgroupid, BtrfsQuotaInfo *ret) { + + struct btrfs_ioctl_search_args args = { +@@ -759,6 +760,7 @@ + + return btrfs_subvol_get_subtree_quota_fd(fd, subvol_id, ret); + } ++#endif + + int btrfs_defrag_fd(int fd) { + struct stat st; +@@ -787,6 +789,7 @@ + return btrfs_defrag_fd(fd); + } + ++#if 0 + int btrfs_quota_enable_fd(int fd, bool b) { + struct btrfs_ioctl_quota_ctl_args args = { + .cmd = b ? BTRFS_QUOTA_CTL_ENABLE : BTRFS_QUOTA_CTL_DISABLE, +@@ -891,6 +894,7 @@ + + return btrfs_subvol_set_subtree_quota_limit_fd(fd, subvol_id, referenced_max); + } ++#endif + + int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) { + struct btrfs_ioctl_vol_args args = {}; +@@ -979,6 +983,7 @@ + return btrfs_resize_loopback_fd(fd, new_size, grow_only); + } + ++#if 0 + int btrfs_qgroupid_make(uint64_t level, uint64_t id, uint64_t *ret) { + assert(ret); + +@@ -1160,6 +1165,7 @@ + int btrfs_qgroup_unassign(int fd, uint64_t child, uint64_t parent) { + return qgroup_assign_or_unassign(fd, false, child, parent); + } ++#endif + + static int subvol_remove_children(int fd, const char *subvolume, uint64_t subvol_id, BtrfsRemoveFlags flags) { + struct btrfs_ioctl_search_args args = { +@@ -1204,7 +1210,7 @@ + * already empty, this will just work. */ + strncpy(vol_args.name, subvolume, sizeof(vol_args.name)-1); + if (ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &vol_args) >= 0) { +- (void) btrfs_qgroup_destroy_recursive(fd, subvol_id); /* for the leaf subvolumes, the qgroup id is identical to the subvol id */ ++ //(void) btrfs_qgroup_destroy_recursive(fd, subvol_id); /* for the leaf subvolumes, the qgroup id is identical to the subvol id */ + return 0; + } + if (!(flags & BTRFS_REMOVE_RECURSIVE) || errno != ENOTEMPTY) +@@ -1290,7 +1296,7 @@ + if (ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &vol_args) < 0) + return -errno; + +- (void) btrfs_qgroup_destroy_recursive(fd, subvol_id); ++ //(void) btrfs_qgroup_destroy_recursive(fd, subvol_id); + return 0; + } + +@@ -1316,6 +1322,7 @@ + return subvol_remove_children(fd, subvolume, 0, flags); + } + ++#if 0 + int btrfs_qgroup_copy_limits(int fd, uint64_t old_qgroupid, uint64_t new_qgroupid) { + + struct btrfs_ioctl_search_args args = { +@@ -1506,6 +1513,7 @@ + + return changed; + } ++#endif + + static int subvol_snapshot_children(int old_fd, int new_fd, const char *subvolume, uint64_t old_subvol_id, BtrfsSnapshotFlags flags) { + +@@ -1539,8 +1547,8 @@ + if (ioctl(new_fd, BTRFS_IOC_SNAP_CREATE_V2, &vol_args) < 0) + return -errno; + +- if (!(flags & BTRFS_SNAPSHOT_RECURSIVE) && +- !(flags & BTRFS_SNAPSHOT_QUOTA)) ++ if (!(flags & BTRFS_SNAPSHOT_RECURSIVE) /*&& ++ !(flags & BTRFS_SNAPSHOT_QUOTA)*/) + return 0; + + if (old_subvol_id == 0) { +@@ -1553,13 +1561,13 @@ + if (r < 0) + return r; + +- if (flags & BTRFS_SNAPSHOT_QUOTA) +- (void) copy_quota_hierarchy(new_fd, old_subvol_id, new_subvol_id); ++ //if (flags & BTRFS_SNAPSHOT_QUOTA) ++ // (void) copy_quota_hierarchy(new_fd, old_subvol_id, new_subvol_id); + + if (!(flags & BTRFS_SNAPSHOT_RECURSIVE)) { + +- if (flags & BTRFS_SNAPSHOT_QUOTA) +- (void) copy_subtree_quota_limits(new_fd, old_subvol_id, new_subvol_id); ++ //if (flags & BTRFS_SNAPSHOT_QUOTA) ++ // (void) copy_subtree_quota_limits(new_fd, old_subvol_id, new_subvol_id); + + return 0; + } +@@ -1681,8 +1689,8 @@ + break; + } + +- if (flags & BTRFS_SNAPSHOT_QUOTA) +- (void) copy_subtree_quota_limits(new_fd, old_subvol_id, new_subvol_id); ++ //if (flags & BTRFS_SNAPSHOT_QUOTA) ++ // (void) copy_subtree_quota_limits(new_fd, old_subvol_id, new_subvol_id); + + return 0; + } +@@ -1708,14 +1716,14 @@ + + r = copy_directory_fd(old_fd, new_path, true); + if (r < 0) { +- (void) btrfs_subvol_remove(new_path, BTRFS_REMOVE_QUOTA); ++ //(void) btrfs_subvol_remove(new_path, BTRFS_REMOVE_QUOTA); + return r; + } + + if (flags & BTRFS_SNAPSHOT_READ_ONLY) { + r = btrfs_subvol_set_read_only(new_path, true); + if (r < 0) { +- (void) btrfs_subvol_remove(new_path, BTRFS_REMOVE_QUOTA); ++ //(void) btrfs_subvol_remove(new_path, BTRFS_REMOVE_QUOTA); + return r; + } + } +@@ -1747,6 +1755,7 @@ + return btrfs_subvol_snapshot_fd(old_fd, new_path, flags); + } + ++#if 0 + int btrfs_qgroup_find_parents(int fd, uint64_t qgroupid, uint64_t **ret) { + + struct btrfs_ioctl_search_args args = { +@@ -2054,3 +2063,4 @@ + + return -ENXIO; + } ++#endif +diff -Nur a/src/shared/import-util.c b/src/shared/import-util.c +--- a/src/shared/import-util.c 2015-11-18 08:59:06.000000000 +0100 ++++ b/src/shared/import-util.c 2016-02-06 13:11:07.000000000 +0100 +@@ -207,6 +207,7 @@ + return true; + } + ++#if 0 + int import_assign_pool_quota_and_warn(const char *path) { + int r; + +@@ -232,3 +233,4 @@ + + return 0; + } ++#endif +diff -Nur a/src/shared/machine-image.c b/src/shared/machine-image.c +--- a/src/shared/machine-image.c 2015-11-18 08:59:06.000000000 +0100 ++++ b/src/shared/machine-image.c 2016-02-06 13:10:17.000000000 +0100 +@@ -201,7 +201,7 @@ + if (r < 0) + return r; + +- if (btrfs_quota_scan_ongoing(fd) == 0) { ++ /*if (btrfs_quota_scan_ongoing(fd) == 0) { + BtrfsQuotaInfo quota; + + r = btrfs_subvol_get_subtree_quota_fd(fd, 0, "a); +@@ -212,7 +212,7 @@ + (*ret)->limit = quota.referenced_max; + (*ret)->limit_exclusive = quota.exclusive_max; + } +- } ++ }*/ + + return 1; + } +@@ -601,7 +601,7 @@ + + /* Enable "subtree" quotas for the copy, if we didn't + * copy any quota from the source. */ +- (void) btrfs_subvol_auto_qgroup(i->path, 0, true); ++ //(void) btrfs_subvol_auto_qgroup(i->path, 0, true); + + break; + +@@ -738,6 +738,7 @@ + return 0; + } + ++#if 0 + int image_set_limit(Image *i, uint64_t referenced_max) { + assert(i); + +@@ -757,6 +758,7 @@ + (void) btrfs_subvol_auto_qgroup(i->path, 0, true); + return btrfs_subvol_set_subtree_quota_limit(i->path, 0, referenced_max); + } ++#endif + + int image_name_lock(const char *name, int operation, LockFile *ret) { + const char *p; +diff -Nur a/src/shared/machine-pool.c b/src/shared/machine-pool.c +--- a/src/shared/machine-pool.c 2015-11-18 08:59:06.000000000 +0100 ++++ b/src/shared/machine-pool.c 2016-02-06 13:13:35.000000000 +0100 +@@ -200,13 +200,13 @@ + if (r > 0) { + (void) btrfs_subvol_make_label("/var/lib/machines"); + +- r = btrfs_quota_enable("/var/lib/machines", true); ++ /*r = btrfs_quota_enable("/var/lib/machines", true); + if (r < 0) + log_warning_errno(r, "Failed to enable quota for /var/lib/machines, ignoring: %m"); + + r = btrfs_subvol_auto_qgroup("/var/lib/machines", 0, true); + if (r < 0) +- log_warning_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines, ignoring: %m"); ++ log_warning_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines, ignoring: %m");*/ + + return 1; + } +@@ -291,13 +291,13 @@ + } + mntdir_mounted = true; + +- r = btrfs_quota_enable(mntdir, true); ++ /*r = btrfs_quota_enable(mntdir, true); + if (r < 0) + log_warning_errno(r, "Failed to enable quota, ignoring: %m"); + + r = btrfs_subvol_auto_qgroup(mntdir, 0, true); + if (r < 0) +- log_warning_errno(r, "Failed to set up default quota hierarchy, ignoring: %m"); ++ log_warning_errno(r, "Failed to set up default quota hierarchy, ignoring: %m");*/ + + if (chmod(mntdir, 0700) < 0) { + r = sd_bus_error_set_errnof(error, errno, "Failed to fix owner: %m"); +@@ -406,8 +406,8 @@ + /* Also bump the quota, of both the subvolume leaf qgroup, as + * well as of any subtree quota group by the same id but a + * higher level, if it exists. */ +- (void) btrfs_qgroup_set_limit("/var/lib/machines", 0, new_size); +- (void) btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, new_size); ++ //(void) btrfs_qgroup_set_limit("/var/lib/machines", 0, new_size); ++ //(void) btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, new_size); + + log_info("Grew /var/lib/machines btrfs loopback file system to %s.", format_bytes(buf, sizeof(buf), new_size)); + return 1; +diff -Nur a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +--- a/src/tmpfiles/tmpfiles.c 2015-11-18 08:59:06.000000000 +0100 ++++ b/src/tmpfiles/tmpfiles.c 2016-02-06 13:17:20.000000000 +0100 +@@ -1219,13 +1219,13 @@ + case CREATE_DIRECTORY: + case TRUNCATE_DIRECTORY: + case CREATE_SUBVOLUME: +- case CREATE_SUBVOLUME_INHERIT_QUOTA: +- case CREATE_SUBVOLUME_NEW_QUOTA: ++ //case CREATE_SUBVOLUME_INHERIT_QUOTA: ++ //case CREATE_SUBVOLUME_NEW_QUOTA: + + RUN_WITH_UMASK(0000) + mkdir_parents_label(i->path, 0755); + +- if (IN_SET(i->type, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) { ++ if (IN_SET(i->type, CREATE_SUBVOLUME/*, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA*/)) { + + if (btrfs_is_subvol(isempty(arg_root) ? "/" : arg_root) <= 0) + +@@ -1277,7 +1277,7 @@ + + log_debug("%s directory \"%s\".", creation_mode_verb_to_string(creation), i->path); + +- if (IN_SET(i->type, CREATE_SUBVOLUME_NEW_QUOTA, CREATE_SUBVOLUME_INHERIT_QUOTA)) { ++ /*if (IN_SET(i->type, CREATE_SUBVOLUME_NEW_QUOTA, CREATE_SUBVOLUME_INHERIT_QUOTA)) { + r = btrfs_subvol_auto_qgroup(i->path, 0, i->type == CREATE_SUBVOLUME_NEW_QUOTA); + if (r == -ENOTTY) { + log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" because of unsupported file system or because directory is not a subvolume: %m", i->path); +@@ -1297,7 +1297,7 @@ + log_debug("Adjusted quota for subvolume \"%s\".", i->path); + if (r == 0) + log_debug("Quota for subvolume \"%s\" already in place, no change made.", i->path); +- } ++ }*/ + + r = path_set_perms(i, i->path); + if (r < 0) diff --git a/projects/H3/patches/systemd/systemd-001-fix-sctp-define.patch b/projects/H3/patches/systemd/systemd-001-fix-sctp-define.patch new file mode 100644 index 00000000000..697b422cee0 --- /dev/null +++ b/projects/H3/patches/systemd/systemd-001-fix-sctp-define.patch @@ -0,0 +1,20 @@ +diff -Nur a/src/core/socket.c b/src/core/socket.c +--- a/src/core/socket.c 2016-02-11 17:28:00.000000000 +0100 ++++ b/src/core/socket.c 2016-02-23 21:39:03.117473944 +0100 +@@ -26,7 +26,6 @@ + #include + #include + #include +-#include + + #include "sd-event.h" + #include "alloc-util.h" +@@ -58,6 +57,8 @@ + #include "unit.h" + #include "user-util.h" + ++#define SCTP_NODELAY 3 ++ + static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { + [SOCKET_DEAD] = UNIT_INACTIVE, + [SOCKET_START_PRE] = UNIT_ACTIVATING, diff --git a/projects/H3/patches/u-boot/u-boot-01-led-support-default-state.patch b/projects/H3/patches/u-boot/u-boot-01-led-support-default-state.patch new file mode 100644 index 00000000000..88819f7d654 --- /dev/null +++ b/projects/H3/patches/u-boot/u-boot-01-led-support-default-state.patch @@ -0,0 +1,178 @@ +diff -Nur a/arch/arm/Kconfig leds/arch/arm/Kconfig +--- a/arch/arm/Kconfig 2016-09-12 16:05:51.000000000 +0200 ++++ leds/arch/arm/Kconfig 2016-09-21 19:17:56.246729135 +0200 +@@ -584,6 +584,8 @@ + select DM_KEYBOARD + select DM_SERIAL + select DM_USB if DISTRO_DEFAULTS ++ select LED ++ select LED_GPIO + select OF_BOARD_SETUP + select OF_CONTROL + select OF_SEPARATE +diff -Nur a/board/sunxi/board.c leds/board/sunxi/board.c +--- a/board/sunxi/board.c 2016-09-12 16:05:51.000000000 +0200 ++++ leds/board/sunxi/board.c 2016-09-21 19:14:16.236727224 +0200 +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -682,6 +683,12 @@ + { + __maybe_unused int ret; + ++#ifdef CONFIG_LED ++ ret = led_set_default_states(); ++ if (ret) ++ return ret; ++#endif ++ + setenv("fel_booted", NULL); + setenv("fel_scriptaddr", NULL); + /* determine if we are running in FEL mode */ +diff -Nur a/drivers/led/led_gpio.c leds/drivers/led/led_gpio.c +--- a/drivers/led/led_gpio.c 2016-09-12 16:05:51.000000000 +0200 ++++ leds/drivers/led/led_gpio.c 2016-09-21 19:14:16.236727224 +0200 +@@ -67,6 +67,7 @@ + node = fdt_next_subnode(blob, node)) { + struct led_uclass_plat *uc_plat; + const char *label; ++ const char *state; + + label = fdt_getprop(blob, node, "label", NULL); + if (!label) { +@@ -74,6 +75,7 @@ + fdt_get_name(blob, node, NULL)); + return -EINVAL; + } ++ state = fdt_getprop(blob, node, "default-state", NULL); + ret = device_bind_driver_to_node(parent, "gpio_led", + fdt_get_name(blob, node, NULL), + node, &dev); +@@ -81,6 +83,15 @@ + return ret; + uc_plat = dev_get_uclass_platdata(dev); + uc_plat->label = label; ++ if (state) { ++ if(!strcmp(state, "on")) ++ uc_plat->default_state = LED_STATE_ON; ++ else if(!strcmp(state, "keep")) ++ uc_plat->default_state = LED_STATE_KEEP; ++ else ++ uc_plat->default_state = LED_STATE_OFF; ++ } else ++ uc_plat->default_state = LED_STATE_OFF; + } + + return 0; +diff -Nur a/drivers/led/led-uclass.c leds/drivers/led/led-uclass.c +--- a/drivers/led/led-uclass.c 2016-09-12 16:05:51.000000000 +0200 ++++ leds/drivers/led/led-uclass.c 2016-09-21 19:14:16.236727224 +0200 +@@ -12,6 +12,21 @@ + #include + #include + ++int led_autoset(struct udevice *dev) ++{ ++ struct led_uclass_plat *uc_pdata; ++ int ret = 0; ++ ++ uc_pdata = dev_get_uclass_platdata(dev); ++ if (!uc_pdata->label) ++ return -EMEDIUMTYPE; ++ ++ if (uc_pdata->default_state != LED_STATE_KEEP) ++ ret = led_set_on(dev, uc_pdata->default_state == LED_STATE_ON); ++ ++ return ret; ++} ++ + int led_get_by_label(const char *label, struct udevice **devp) + { + struct udevice *dev; +@@ -32,6 +47,26 @@ + return -ENODEV; + } + ++int led_set_default_states(void) ++{ ++ struct udevice *dev; ++ struct uclass *uc; ++ int ret; ++ ++ ret = uclass_get(UCLASS_LED, &uc); ++ if (ret) ++ return ret; ++ for (uclass_first_device(UCLASS_LED, &dev); ++ dev; ++ uclass_next_device(&dev)) { ++ ret = led_autoset(dev); ++ if (ret == -EMEDIUMTYPE || ret == -ENOSYS) ++ ret = 0; ++ } ++ ++ return ret; ++} ++ + int led_set_on(struct udevice *dev, int on) + { + struct led_ops *ops = led_get_ops(dev); +diff -Nur a/include/led.h leds/include/led.h +--- a/include/led.h 2016-09-12 16:05:51.000000000 +0200 ++++ leds/include/led.h 2016-09-21 19:14:16.236727224 +0200 +@@ -8,6 +8,14 @@ + #ifndef __LED_H + #define __LED_H + ++/* LED default states ++ */ ++enum led_default_state { ++ LED_STATE_OFF, ++ LED_STATE_ON, ++ LED_STATE_KEEP ++}; ++ + /** + * struct led_uclass_plat - Platform data the uclass stores about each device + * +@@ -15,6 +23,7 @@ + */ + struct led_uclass_plat { + const char *label; ++ enum led_default_state default_state; + }; + + struct led_ops { +@@ -31,6 +40,14 @@ + #define led_get_ops(dev) ((struct led_ops *)(dev)->driver->ops) + + /** ++ * led_autoset() - set the state of an LED according to fdt ++ * ++ * @dev: LED device to set ++ * @return 0 if OK, -ve on error ++ */ ++int led_autoset(struct udevice *dev); ++ ++/** + * led_get_by_label() - Find an LED device by label + * + * @label: LED label to look up +@@ -40,6 +57,13 @@ + int led_get_by_label(const char *label, struct udevice **devp); + + /** ++ * led_set_default_states() - set the state of all LEDs according to fdt ++ * ++ * @return 0 if OK, -ve on error ++ */ ++int led_set_default_states(void); ++ ++/** + * led_set_on() - set the state of an LED + * + * @dev: LED device to change diff --git a/projects/H3/patches/u-boot/u-boot-02-disable-usb.patch b/projects/H3/patches/u-boot/u-boot-02-disable-usb.patch new file mode 100644 index 00000000000..d73f5325eb7 --- /dev/null +++ b/projects/H3/patches/u-boot/u-boot-02-disable-usb.patch @@ -0,0 +1,13 @@ +diff -Nur a/arch/arm/Kconfig usb/arch/arm/Kconfig +--- a/arch/arm/Kconfig 2016-09-12 16:05:51.000000000 +0200 ++++ usb/arch/arm/Kconfig 2016-09-21 19:19:44.533396743 +0200 +@@ -590,9 +590,6 @@ + select SPL_STACK_R if SUPPORT_SPL + select SPL_SYS_MALLOC_SIMPLE if SUPPORT_SPL + select SYS_NS16550 +- select USB if DISTRO_DEFAULTS +- select USB_STORAGE if DISTRO_DEFAULTS +- select USB_KEYBOARD if DISTRO_DEFAULTS + select USE_TINY_PRINTF + + config TARGET_TS4600 diff --git a/projects/H3/patches/u-boot/u-boot-03-add-h3-video-driver.patch b/projects/H3/patches/u-boot/u-boot-03-add-h3-video-driver.patch new file mode 100644 index 00000000000..3ed3235f5ff --- /dev/null +++ b/projects/H3/patches/u-boot/u-boot-03-add-h3-video-driver.patch @@ -0,0 +1,1506 @@ +From b973987576822640f35dbb805a048b1706dc8e6d Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Tue, 8 Nov 2016 01:04:32 +0100 +Subject: [PATCH] sunxi: video: Add video driver for H3 SoC + +Signed-off-by: Jernej Skrabec +--- + arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 42 ++ + arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 6 + + arch/arm/include/asm/arch-sunxi/display2.h | 261 ++++++++ + arch/arm/mach-sunxi/clock_sun6i.c | 30 + + board/sunxi/Kconfig | 4 +- + drivers/video/Makefile | 1 + + drivers/video/sun8i_display.c | 928 ++++++++++++++++++++++++++ + include/configs/sunxi-common.h | 4 + + scripts/config_whitelist.txt | 1 + + 9 files changed, 1275 insertions(+), 2 deletions(-) + create mode 100644 arch/arm/include/asm/arch-sunxi/display2.h + create mode 100644 drivers/video/sun8i_display.c + +diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +index be9fcfd..a414f69 100644 +--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h ++++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +@@ -67,12 +67,20 @@ struct sunxi_ccm_reg { + u32 dram_pll_cfg; /* 0xf8 PLL_DDR cfg register, A33 only */ + u32 mbus_reset; /* 0xfc MBUS reset control, A33 only */ + u32 dram_clk_gate; /* 0x100 DRAM module gating */ ++#ifdef CONFIG_MACH_SUN8I ++ u32 de_clk_cfg; /* 0x104 DE module clock */ ++#else + u32 be0_clk_cfg; /* 0x104 BE0 module clock */ ++#endif + u32 be1_clk_cfg; /* 0x108 BE1 module clock */ + u32 fe0_clk_cfg; /* 0x10c FE0 module clock */ + u32 fe1_clk_cfg; /* 0x110 FE1 module clock */ + u32 mp_clk_cfg; /* 0x114 MP module clock */ ++#ifdef CONFIG_MACH_SUN8I ++ u32 tcon0_clk_cfg; /* 0x118 TCON0 module clock */ ++#else + u32 lcd0_ch0_clk_cfg; /* 0x118 LCD0 CH0 module clock */ ++#endif + u32 lcd1_ch0_clk_cfg; /* 0x11c LCD1 CH0 module clock */ + u32 reserved14[3]; + u32 lcd0_ch1_clk_cfg; /* 0x12c LCD0 CH1 module clock */ +@@ -85,7 +93,11 @@ struct sunxi_ccm_reg { + u32 dmic_clk_cfg; /* 0x148 Digital Mic module clock*/ + u32 reserved15; + u32 hdmi_clk_cfg; /* 0x150 HDMI module clock */ ++#ifdef CONFIG_MACH_SUN8I ++ u32 hdmi_slow_clk_cfg; /* 0x154 HDMI slow module clock */ ++#else + u32 ps_clk_cfg; /* 0x154 PS module clock */ ++#endif + u32 mtc_clk_cfg; /* 0x158 MTC module clock */ + u32 mbus0_clk_cfg; /* 0x15c MBUS0 module clock */ + u32 mbus1_clk_cfg; /* 0x160 MBUS1 module clock */ +@@ -220,6 +232,15 @@ struct sunxi_ccm_reg { + #define CCM_MIPI_PLL_CTRL_LDO_EN (0x3 << 22) + #define CCM_MIPI_PLL_CTRL_EN (0x1 << 31) + ++#define CCM_PLL10_CTRL_M_SHIFT 0 ++#define CCM_PLL10_CTRL_M_MASK (0xf << CCM_PLL10_CTRL_M_SHIFT) ++#define CCM_PLL10_CTRL_M(n) ((((n) - 1) & 0xf) << 0) ++#define CCM_PLL10_CTRL_N_SHIFT 8 ++#define CCM_PLL10_CTRL_N_MASK (0x7f << CCM_PLL10_CTRL_N_SHIFT) ++#define CCM_PLL10_CTRL_N(n) ((((n) - 1) & 0x7f) << 8) ++#define CCM_PLL10_CTRL_INTEGER_MODE (0x1 << 24) ++#define CCM_PLL10_CTRL_EN (0x1 << 31) ++ + #define CCM_PLL11_CTRL_N(n) ((((n) - 1) & 0x3f) << 8) + #define CCM_PLL11_CTRL_SIGMA_DELTA_EN (0x1 << 24) + #define CCM_PLL11_CTRL_UPD (0x1 << 30) +@@ -271,9 +292,12 @@ struct sunxi_ccm_reg { + #define AHB_GATE_OFFSET_DRC0 25 + #define AHB_GATE_OFFSET_DE_FE0 14 + #define AHB_GATE_OFFSET_DE_BE0 12 ++#define AHB_GATE_OFFSET_DE 12 + #define AHB_GATE_OFFSET_HDMI 11 + #define AHB_GATE_OFFSET_LCD1 5 + #define AHB_GATE_OFFSET_LCD0 4 ++#define AHB_GATE_OFFSET_TCON1 4 ++#define AHB_GATE_OFFSET_TCON0 3 + + #define CCM_MMC_CTRL_M(x) ((x) - 1) + #define CCM_MMC_CTRL_OCLK_DLY(x) ((x) << 8) +@@ -346,6 +370,9 @@ struct sunxi_ccm_reg { + #define CCM_LCD_CH0_CTRL_RST 0 + #define CCM_LCD_CH0_CTRL_GATE (0x1 << 31) + ++#define CCM_TCON0_CTRL_GATE (0x1 << 31) ++#define CCM_TCON0_CTRL_M(n) ((((n) - 1) & 0xf) << 0) ++ + #define CCM_LCD_CH1_CTRL_M(n) ((((n) - 1) & 0xf) << 0) + #define CCM_LCD_CH1_CTRL_HALF_SCLK1 0 /* no seperate sclk1 & 2 on sun6i */ + #define CCM_LCD_CH1_CTRL_PLL3 (0 << 24) +@@ -355,6 +382,7 @@ struct sunxi_ccm_reg { + #define CCM_LCD_CH1_CTRL_GATE (0x1 << 31) + + #define CCM_HDMI_CTRL_M(n) ((((n) - 1) & 0xf) << 0) ++#define CCM_HDMI_CTRL_M_MASK (0xf << 0) + #define CCM_HDMI_CTRL_PLL_MASK (3 << 24) + #define CCM_HDMI_CTRL_PLL3 (0 << 24) + #define CCM_HDMI_CTRL_PLL7 (1 << 24) +@@ -363,6 +391,8 @@ struct sunxi_ccm_reg { + #define CCM_HDMI_CTRL_DDC_GATE (0x1 << 30) + #define CCM_HDMI_CTRL_GATE (0x1 << 31) + ++#define CCM_HDMI_SLOW_CTRL_DDC_GATE (1 << 31) ++ + #if defined(CONFIG_MACH_SUN50I) + #define MBUS_CLK_DEFAULT 0x81000002 /* PLL6x2 / 3 */ + #elif defined(CONFIG_MACH_SUN8I) +@@ -390,9 +420,13 @@ struct sunxi_ccm_reg { + #define AHB_RESET_OFFSET_DRC0 25 + #define AHB_RESET_OFFSET_DE_FE0 14 + #define AHB_RESET_OFFSET_DE_BE0 12 ++#define AHB_RESET_OFFSET_DE 12 + #define AHB_RESET_OFFSET_HDMI 11 ++#define AHB_RESET_OFFSET_HDMI2 10 + #define AHB_RESET_OFFSET_LCD1 5 + #define AHB_RESET_OFFSET_LCD0 4 ++#define AHB_RESET_OFFSET_TCON1 4 ++#define AHB_RESET_OFFSET_TCON0 3 + + /* ahb_reset2 offsets */ + #define AHB_RESET_OFFSET_EPHY 2 +@@ -406,6 +440,7 @@ struct sunxi_ccm_reg { + + /* CCM bits common to all Display Engine (and IEP) clock ctrl regs */ + #define CCM_DE_CTRL_M(n) ((((n) - 1) & 0xf) << 0) ++#ifndef CONFIG_MACH_SUN8I + #define CCM_DE_CTRL_PLL_MASK (0xf << 24) + #define CCM_DE_CTRL_PLL3 (0 << 24) + #define CCM_DE_CTRL_PLL7 (1 << 24) +@@ -413,6 +448,11 @@ struct sunxi_ccm_reg { + #define CCM_DE_CTRL_PLL8 (3 << 24) + #define CCM_DE_CTRL_PLL9 (4 << 24) + #define CCM_DE_CTRL_PLL10 (5 << 24) ++#else ++#define CCM_DE_CTRL_PLL_MASK (3 << 24) ++#define CCM_DE_CTRL_PLL6_2X (0 << 24) ++#define CCM_DE_CTRL_PLL10 (1 << 24) ++#endif + #define CCM_DE_CTRL_GATE (1 << 31) + + /* CCU security switch, H3 only */ +@@ -423,7 +463,9 @@ struct sunxi_ccm_reg { + #ifndef __ASSEMBLY__ + void clock_set_pll1(unsigned int hz); + void clock_set_pll3(unsigned int hz); ++void clock_set_pll3_factors(int m, int n); + void clock_set_pll5(unsigned int clk, bool sigma_delta_enable); ++void clock_set_pll10(unsigned int hz); + void clock_set_pll11(unsigned int clk, bool sigma_delta_enable); + void clock_set_mipi_pll(unsigned int hz); + unsigned int clock_get_pll3(void); +diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +index 5f93830..9758a14 100644 +--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h ++++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +@@ -46,7 +46,9 @@ + #define SUNXI_USB1_BASE 0x01c14000 + #endif + #define SUNXI_SS_BASE 0x01c15000 ++#ifndef CONFIG_MACH_SUN8I_H3 + #define SUNXI_HDMI_BASE 0x01c16000 ++#endif + #define SUNXI_SPI2_BASE 0x01c17000 + #define SUNXI_SATA_BASE 0x01c18000 + #ifdef CONFIG_SUNXI_GEN_SUN4I +@@ -163,6 +165,10 @@ defined(CONFIG_MACH_SUN50I) + #define SUNXI_MP_BASE 0x01e80000 + #define SUNXI_AVG_BASE 0x01ea0000 + ++#ifdef CONFIG_MACH_SUN8I_H3 ++#define SUNXI_HDMI_BASE 0x01ee0000 ++#endif ++ + #define SUNXI_RTC_BASE 0x01f00000 + #define SUNXI_PRCM_BASE 0x01f01400 + +diff --git a/arch/arm/include/asm/arch-sunxi/display2.h b/arch/arm/include/asm/arch-sunxi/display2.h +new file mode 100644 +index 0000000..755adeb +--- /dev/null ++++ b/arch/arm/include/asm/arch-sunxi/display2.h +@@ -0,0 +1,261 @@ ++/* ++ * Sunxi platform display controller register and constant defines ++ * ++ * (C) Copyright 2016 Jernej Skrabec ++ * ++ * Based on work by: ++ * Copyright (C) 2016 Jean-Francois Moine ++ * Copyright (c) 2016 Allwinnertech Co., Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#ifndef _SUNXI_DISPLAY_H ++#define _SUNXI_DISPLAY_H ++ ++struct sun8i_lcdc_reg { ++ u32 gctl; ++ u32 gint0; ++ u32 gint1; ++ u32 dum0[13]; ++ u32 tcon0_ctl; /* 0x40 */ ++ u32 dum1[19]; ++ u32 tcon1_ctl; /* 0x90 */ ++ u32 basic0; /* XI/YI */ ++ u32 basic1; /* LS_XO/LS_YO */ ++ u32 basic2; /* XO/YO */ ++ u32 basic3; /* HT/HBP */ ++ u32 basic4; /* VT/VBP */ ++ u32 basic5; /* HSPW/VSPW */ ++ u32 dum2; ++ u32 ps_sync; /* 0xb0 */ ++ u32 dum3[15]; ++ u32 io_pol; /* 0xf0 */ ++ u32 io_tri; ++ u32 dum4[2]; ++ ++ u32 ceu_ctl; /* 0x100 */ ++ u32 dum5[3]; ++ u32 ceu_rr; ++ u32 ceu_rg; ++ u32 ceu_rb; ++ u32 ceu_rc; ++ u32 ceu_gr; ++ u32 ceu_gg; ++ u32 ceu_gb; ++ u32 ceu_gc; ++ u32 ceu_br; ++ u32 ceu_bg; ++ u32 ceu_bb; ++ u32 ceu_bc; ++ u32 ceu_rv; ++ u32 ceu_gv; ++ u32 ceu_bv; ++ u32 dum6[45]; ++ ++ u32 mux_ctl; /* 0x200 */ ++ u32 dum7[63]; ++ ++ u32 fill_ctl; /* 0x300 */ ++ u32 fill_start0; ++ u32 fill_end0; ++ u32 fill_data0; ++}; ++ ++/* global control */ ++struct de_glb { ++ u32 ctl; ++#define DE_MUX_GLB_CTL_rt_en BIT(0) ++#define DE_MUX_GLB_CTL_finish_irq_en BIT(4) ++#define DE_MUX_GLB_CTL_rtwb_port BIT(12) ++ u32 status; ++ u32 dbuff; ++ u32 size; ++}; ++ ++/* alpha blending */ ++struct de_bld { ++ u32 fcolor_ctl; /* 00 */ ++ struct { ++ u32 fcolor; ++ u32 insize; ++ u32 offset; ++ u32 dum; ++ } attr[4]; ++ u32 dum0[15]; /* (end of clear offset) */ ++ u32 route; /* 80 */ ++ u32 premultiply; ++ u32 bkcolor; ++ u32 output_size; ++ u32 bld_mode[4]; ++ u32 dum1[4]; ++ u32 ck_ctl; /* b0 */ ++ u32 ck_cfg; ++ u32 dum2[2]; ++ u32 ck_max[4]; /* c0 */ ++ u32 dum3[4]; ++ u32 ck_min[4]; /* e0 */ ++ u32 dum4[3]; ++ u32 out_ctl; /* fc */ ++}; ++ ++/* VI channel */ ++struct de_vi { ++ struct { ++ u32 attr; ++#define VI_CFG_ATTR_en BIT(0) ++#define VI_CFG_ATTR_fcolor_en BIT(4) ++#define VI_CFG_ATTR_fmt_SHIFT 8 ++#define VI_CFG_ATTR_fmt_MASK GENMASK(12, 8) ++#define VI_CFG_ATTR_ui_sel BIT(15) ++#define VI_CFG_ATTR_top_down BIT(23) ++ u32 size; ++ u32 coord; ++#define VI_N_PLANES 3 ++ u32 pitch[VI_N_PLANES]; ++ u32 top_laddr[VI_N_PLANES]; ++ u32 bot_laddr[VI_N_PLANES]; ++ } cfg[4]; ++ u32 fcolor[4]; /* c0 */ ++ u32 top_haddr[VI_N_PLANES]; /* d0 */ ++ u32 bot_haddr[VI_N_PLANES]; /* dc */ ++ u32 ovl_size[2]; /* e8 */ ++ u32 hori[2]; /* f0 */ ++ u32 vert[2]; /* f8 */ ++}; ++ ++struct de_ui { ++ struct { ++ u32 attr; ++#define UI_CFG_ATTR_en BIT(0) ++#define UI_CFG_ATTR_alpmod_SHIFT 1 ++#define UI_CFG_ATTR_alpmod_MASK GENMASK(2, 1) ++#define UI_CFG_ATTR_fcolor_en BIT(4) ++#define UI_CFG_ATTR_fmt_SHIFT 8 ++#define UI_CFG_ATTR_fmt_MASK GENMASK(12, 8) ++#define UI_CFG_ATTR_top_down BIT(23) ++#define UI_CFG_ATTR_alpha_SHIFT 24 ++#define UI_CFG_ATTR_alpha_MASK GENMASK(31, 24) ++ u32 size; ++ u32 coord; ++ u32 pitch; ++ u32 top_laddr; ++ u32 bot_laddr; ++ u32 fcolor; ++ u32 dum; ++ } cfg[4]; /* 00 */ ++ u32 top_haddr; /* 80 */ ++ u32 bot_haddr; ++ u32 ovl_size; /* 88 */ ++}; ++ ++#define HDMI_EDID_BLOCK_SIZE 128 ++ ++/* ++ * HDMI register addresses ++ */ ++#define SUN8I_HDMI_PHY_CTRL_REG (u32*)(SUNXI_HDMI_BASE + 0x10020) ++#define SUN8I_HDMI_PHY_UNK1_REG (u32*)(SUNXI_HDMI_BASE + 0x10024) ++#define SUN8I_HDMI_PHY_UNK2_REG (u32*)(SUNXI_HDMI_BASE + 0x10028) ++#define SUN8I_HDMI_PHY_PLL_REG (u32*)(SUNXI_HDMI_BASE + 0x1002c) ++#define SUN8I_HDMI_PHY_CLK_REG (u32*)(SUNXI_HDMI_BASE + 0x10030) ++#define SUN8I_HDMI_PHY_UNK3_REG (u32*)(SUNXI_HDMI_BASE + 0x10034) ++#define SUN8I_HDMI_PHY_STATUS_REG (u32*)(SUNXI_HDMI_BASE + 0x10038) ++ ++#define SUN8I_HDMI_IH_I2CM_STAT0 (u32*)(SUNXI_HDMI_BASE + 0x0013) ++ ++#define SUN8I_HDMI_I2CM_SLAVE (u32*)(SUNXI_HDMI_BASE + 0x0EE0) ++#define SUN8I_HDMI_I2CM_ADDRESS (u32*)(SUNXI_HDMI_BASE + 0x0EE1) ++#define SUN8I_HDMI_I2CM_DATAI (u32*)(SUNXI_HDMI_BASE + 0x8EE1) ++#define SUN8I_HDMI_I2CM_OPERATION (u32*)(SUNXI_HDMI_BASE + 0x0EE2) ++#define SUN8I_HDMI_I2CM_INT (u32*)(SUNXI_HDMI_BASE + 0x0EE3) ++#define SUN8I_HDMI_I2CM_DIV (u32*)(SUNXI_HDMI_BASE + 0x8EE3) ++#define SUN8I_HDMI_I2CM_SEGADDR (u32*)(SUNXI_HDMI_BASE + 0x4EE0) ++#define SUN8I_HDMI_I2CM_SOFTRSTZ (u32*)(SUNXI_HDMI_BASE + 0x4EE1) ++#define SUN8I_HDMI_I2CM_SEGPTR (u32*)(SUNXI_HDMI_BASE + 0xCEE0) ++#define SUN8I_HDMI_I2CM_SS_SCL_HCNT_0_ADDR (u32*)(SUNXI_HDMI_BASE + 0x4EE2) ++#define SUN8I_HDMI_I2CM_SS_SCL_LCNT_0_ADDR (u32*)(SUNXI_HDMI_BASE + 0xCEE2) ++ ++/* ++ * DE register constants. ++ */ ++/* TODO: move to appropriate place */ ++#define SUN8I_DE_BASE 0x01000000 ++#define SUN8I_DE_GATE_REG (u32*)(SUN8I_DE_BASE + 0x0004) ++#define SUN8I_DE_MOD_REG (u32*)(SUN8I_DE_BASE + 0x0000) ++#define SUN8I_DE_RESET_REG (u32*)(SUN8I_DE_BASE + 0x0008) ++#define SUN8I_DE_DIV_REG (u32*)(SUN8I_DE_BASE + 0x000c) ++#define SUN8I_DE_SEL_REG (u32*)(SUN8I_DE_BASE + 0x0010) ++ ++#define DE_MUX0_BASE (u8*)(SUN8I_DE_BASE + 0x00100000) ++/* MUX registers (addr / MUX base) */ ++#define DE_MUX_GLB_REGS 0x00000 /* global control */ ++#define DE_MUX_BLD_REGS 0x01000 /* alpha blending */ ++#define DE_MUX_CHAN_REGS 0x02000 /* VI/UI overlay channels */ ++#define DE_MUX_CHAN_SZ 0x1000 /* size of a channel */ ++#define DE_MUX_VSU_REGS 0x20000 /* VSU */ ++#define DE_MUX_GSU1_REGS 0x30000 /* GSUs */ ++#define DE_MUX_GSU2_REGS 0x40000 ++#define DE_MUX_GSU3_REGS 0x50000 ++#define DE_MUX_FCE_REGS 0xa0000 /* FCE */ ++#define DE_MUX_BWS_REGS 0xa2000 /* BWS */ ++#define DE_MUX_LTI_REGS 0xa4000 /* LTI */ ++#define DE_MUX_PEAK_REGS 0xa6000 /* PEAK */ ++#define DE_MUX_ASE_REGS 0xa8000 /* ASE */ ++#define DE_MUX_FCC_REGS 0xaa000 /* FCC */ ++#define DE_MUX_DCSC_REGS 0xb0000 /* DCSC/SMBL */ ++ ++#define DE2_FORMAT_ARGB_8888 0 ++#define DE2_FORMAT_BGRA_8888 3 ++#define DE2_FORMAT_XRGB_8888 4 ++#define DE2_FORMAT_RGB_888 8 ++#define DE2_FORMAT_BGR_888 9 ++ ++/* coordinates and sizes */ ++#define XY(x, y) (((y) << 16) | (x)) ++#define WH(w, h) (((h - 1) << 16) | (w - 1)) ++ ++/* ++ * LCDC register constants. ++ */ ++#define SUN8I_TCON_GCTL_TCON_En (1 << 31) ++#define SUN8I_TCON_GINT0_TCON1_Vb_Int_En (1 << 30) ++#define SUN8I_TCON_GINT0_TCON1_Vb_Int_Flag (1 << 14) ++#define SUN8I_TCON0_CTL_TCON_En (1 << 31) ++#define SUN8I_TCON1_CTL_TCON_En (1 << 31) ++#define SUN8I_TCON1_CTL_Interlace_En (1 << 20) ++#define SUN8I_TCON1_CTL_Start_Delay_SHIFT 4 ++/*#define SUN8I_TCON1_CTL_Start_Delay_MASK GENMASK(8, 4)*/ ++#define SUN8I_TCON1_IO_POL_IO0_inv (1 << 24) ++#define SUN8I_TCON1_IO_POL_IO1_inv (1 << 25) ++#define SUN8I_TCON1_IO_POL_IO2_inv (1 << 26) ++#define SUN8I_TCON_CEU_CTL_ceu_en (1 << 31) ++ ++#define SUNXI_LCDC_X(x) (((x) - 1) << 16) ++#define SUNXI_LCDC_Y(y) (((y) - 1) << 0) ++#define SUNXI_LCDC_TCON_VSYNC_MASK (1 << 24) ++#define SUNXI_LCDC_TCON_HSYNC_MASK (1 << 25) ++#define SUNXI_LCDC_CTRL_IO_MAP_MASK (1 << 0) ++#define SUNXI_LCDC_CTRL_IO_MAP_TCON0 (0 << 0) ++#define SUNXI_LCDC_CTRL_IO_MAP_TCON1 (1 << 0) ++#define SUNXI_LCDC_CTRL_TCON_ENABLE (1 << 31) ++#define SUNXI_LCDC_TCON1_CTRL_SRC_BLUE (1 << 1) ++#define SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(n) (((n) & 0x1f) << 4) ++#define SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE (1 << 20) ++#define SUNXI_LCDC_TCON1_CTRL_ENABLE (1 << 31) ++#define SUNXI_LCDC_TCON1_TIMING_H_BP(n) (((n) - 1) << 0) ++#define SUNXI_LCDC_TCON1_TIMING_H_TOTAL(n) (((n) - 1) << 16) ++#define SUNXI_LCDC_TCON1_TIMING_V_BP(n) (((n) - 1) << 0) ++#define SUNXI_LCDC_TCON1_TIMING_V_TOTAL(n) ((n) << 16) ++ ++/* ++ * HDMI register constants. ++ */ ++#define SUNXI_HDMI_HPD_DETECT (1 << 19) ++ ++#define SUN8I_HMDI_DDC_CTRL_RESET (1 << 0) ++#define SUN8I_HMDI_DDC_ADDR_SLAVE_ADDR (0x50 << 0) ++#define SUN8I_HMDI_DDC_ADDR_SEG_ADDR (0x30 << 0) ++ ++ ++#endif /* _SUNXI_DISPLAY_H */ +diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c +index ed8cd9b..bcf9aa1 100644 +--- a/arch/arm/mach-sunxi/clock_sun6i.c ++++ b/arch/arm/mach-sunxi/clock_sun6i.c +@@ -141,6 +141,17 @@ void clock_set_pll3(unsigned int clk) + &ccm->pll3_cfg); + } + ++void clock_set_pll3_factors(int m, int n) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ /* PLL3 rate = 24000000 * n / m */ ++ writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE | ++ CCM_PLL3_CTRL_N(n) | CCM_PLL3_CTRL_M(m), ++ &ccm->pll3_cfg); ++} ++ + void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) + { + struct sunxi_ccm_reg * const ccm = +@@ -213,6 +224,23 @@ void clock_set_mipi_pll(unsigned int clk) + } + #endif + ++void clock_set_pll10(unsigned int clk) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ const int m = 2; /* 12 MHz steps */ ++ ++ if (clk == 0) { ++ clrbits_le32(&ccm->pll10_cfg, CCM_PLL10_CTRL_EN); ++ return; ++ } ++ ++ /* PLL10 rate = 24000000 * n / m */ ++ writel(CCM_PLL10_CTRL_EN | CCM_PLL10_CTRL_INTEGER_MODE | ++ CCM_PLL10_CTRL_N(clk / (24000000 / m)) | CCM_PLL10_CTRL_M(m), ++ &ccm->pll10_cfg); ++} ++ + #ifdef CONFIG_MACH_SUN8I_A33 + void clock_set_pll11(unsigned int clk, bool sigma_delta_enable) + { +@@ -267,6 +295,7 @@ unsigned int clock_get_mipi_pll(void) + return ((src / 1000) * n * k / m) * 1000; + } + ++#ifndef CONFIG_MACH_SUN8I + void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz) + { + int pll = clock_get_pll6() * 2; +@@ -278,3 +307,4 @@ void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz) + writel(CCM_DE_CTRL_GATE | CCM_DE_CTRL_PLL6_2X | CCM_DE_CTRL_M(div), + clk_cfg); + } ++#endif +diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig +index c0ffeb3..77fdc8f 100644 +--- a/board/sunxi/Kconfig ++++ b/board/sunxi/Kconfig +@@ -458,7 +458,7 @@ config AXP_GPIO + + config VIDEO + bool "Enable graphical uboot console on HDMI, LCD or VGA" +- depends on !MACH_SUN8I_A83T && !MACH_SUN8I_H3 && !MACH_SUN9I && !MACH_SUN50I ++ depends on !MACH_SUN8I_A83T && !MACH_SUN9I && !MACH_SUN50I + default y + ---help--- + Say Y here to add support for using a cfb console on the HDMI, LCD +@@ -467,7 +467,7 @@ config VIDEO + + config VIDEO_HDMI + bool "HDMI output support" +- depends on VIDEO && !MACH_SUN8I ++ depends on VIDEO + default y + ---help--- + Say Y here to add support for outputting video over HDMI. +diff --git a/drivers/video/Makefile b/drivers/video/Makefile +index db34904..d05b745 100644 +--- a/drivers/video/Makefile ++++ b/drivers/video/Makefile +@@ -52,6 +52,7 @@ obj-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o + obj-$(CONFIG_VIDEO_SANDBOX_SDL) += sandbox_sdl.o + obj-$(CONFIG_VIDEO_SM501) += sm501.o + obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o ++obj-$(CONFIG_VIDEO_SUNXI_H3) += sun8i_display.o videomodes.o + obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o + obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o + obj-$(CONFIG_VIDEO_VESA) += vesa.o +diff --git a/drivers/video/sun8i_display.c b/drivers/video/sun8i_display.c +new file mode 100644 +index 0000000..e596e4c +--- /dev/null ++++ b/drivers/video/sun8i_display.c +@@ -0,0 +1,928 @@ ++/* ++ * Display driver for sunxi Allwinner SoCs with DE2. ++ * ++ * Copyright (C) 2016 Jernej Skrabec ++ * ++ * Based on sunxi_display.c: ++ * (C) Copyright 2013-2014 Luc Verhaegen ++ * (C) Copyright 2014-2015 Hans de Goede ++ * ++ * Based on Linux DRM driver: ++ * Copyright (C) 2016 Jean-Francois Moine ++ * Copyright (c) 2016 Allwinnertech Co., Ltd. ++ * ++ * Based on rk_hdmi.c: ++ * Copyright (c) 2015 Google, Inc ++ * Copyright 2014 Rockchip Inc. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "videomodes.h" ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++enum sunxi_monitor { ++ sunxi_monitor_none, ++ sunxi_monitor_dvi, ++ sunxi_monitor_hdmi, ++}; ++#define SUNXI_MONITOR_LAST sunxi_monitor_hdmi ++ ++struct sunxi_display { ++ GraphicDevice graphic_device; ++ enum sunxi_monitor monitor; ++ unsigned int depth; ++ unsigned int fb_addr; ++ unsigned int fb_size; ++} sunxi_display; ++ ++#ifdef CONFIG_VIDEO_HDMI ++ ++static void sun8i_hdmi_phy_init(void) ++{ ++ unsigned long tmo; ++ u32 tmp; ++ ++ writel(0, SUN8I_HDMI_PHY_CTRL_REG); ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, BIT(0)); ++ udelay(5); ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, BIT(16)); ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, BIT(1)); ++ udelay(10); ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, BIT(2)); ++ udelay(5); ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, BIT(3)); ++ udelay(40); ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, BIT(19)); ++ udelay(100); ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, BIT(18)); ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, 7 << 4); ++ ++ /* Note that Allwinner code doesn't fail in case of timeout */ ++ tmo = timer_get_us() + 2000; ++ while ((readl(SUN8I_HDMI_PHY_STATUS_REG) & 0x80) == 0) { ++ if (timer_get_us() > tmo) { ++ printf("Warning: HDMI phy init timeout!\n"); ++ break; ++ } ++ } ++ ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, 0xf << 8); ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, BIT(7)); ++ ++ writel(0x39dc5040, SUN8I_HDMI_PHY_PLL_REG); ++ writel(0x80084343, SUN8I_HDMI_PHY_CLK_REG); ++ udelay(10000); ++ writel(1, SUN8I_HDMI_PHY_UNK3_REG); ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(25)); ++ udelay(100000); ++ tmp = (readl(SUN8I_HDMI_PHY_STATUS_REG) & 0x1f800) >> 11; ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(31) | BIT(30)); ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, tmp); ++ writel(0x01FF0F7F, SUN8I_HDMI_PHY_CTRL_REG); ++ writel(0x80639000, SUN8I_HDMI_PHY_UNK1_REG); ++ writel(0x0F81C405, SUN8I_HDMI_PHY_UNK2_REG); ++ ++ /* enable read access to HDMI controller*/ ++ writel(0x54524545, SUNXI_HDMI_BASE + 0x10010); ++ ++ writeb(0x00, SUNXI_HDMI_BASE + 0x8080); ++ ++ udelay(1); ++ ++ writeb(0x00, SUNXI_HDMI_BASE + 0xF01F); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x8403); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x904C); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x904E); ++ writeb(0xff, SUNXI_HDMI_BASE + 0xD04C); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x8250); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x8A50); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x8272); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x40C0); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x86F0); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x0EE3); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x8EE2); ++ writeb(0xf0, SUNXI_HDMI_BASE + 0xA049); ++ writeb(0x1e, SUNXI_HDMI_BASE + 0xB045); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x00C1); ++ writeb(0x03, SUNXI_HDMI_BASE + 0x00C1); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x00C0); ++ writeb(0x10, SUNXI_HDMI_BASE + 0x40C1); ++ writeb(0xfd, SUNXI_HDMI_BASE + 0x0081); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x0081); ++ writeb(0xfd, SUNXI_HDMI_BASE + 0x0081); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x0010); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x0011); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x8010); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x8011); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x0013); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x8012); ++ writeb(0xff, SUNXI_HDMI_BASE + 0x8013); ++} ++ ++static int sun8i_hdmi_hpd_detect(int hpd_delay) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ unsigned long tmo = timer_get_us() + hpd_delay * 1000; ++ int status = 0; ++ ++ /* Set pll3 to 297 MHz */ ++ clock_set_pll3(297000000); ++ ++ /* Set hdmi parent to pll3 */ ++ clrsetbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_PLL_MASK, ++ CCM_HDMI_CTRL_PLL3); ++ ++ /* Set ahb gating to pass */ ++ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI); ++ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI2); ++ setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI); ++ setbits_le32(&ccm->hdmi_slow_clk_cfg, CCM_HDMI_SLOW_CTRL_DDC_GATE); ++ ++ /* Clock on */ ++ setbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); ++ ++ sun8i_hdmi_phy_init(); ++ ++ while (timer_get_us() < tmo) { ++ if (readl(SUN8I_HDMI_PHY_STATUS_REG) & SUNXI_HDMI_HPD_DETECT) { ++ status = 1; ++ break; ++ } ++ } ++ ++ return status; ++} ++ ++static void sunxi_hdmi_shutdown(void) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ writel(0, SUN8I_HDMI_PHY_CTRL_REG); ++ clrbits_le32(&ccm->hdmi_clk_cfg, CCM_HDMI_CTRL_GATE); ++ clrbits_le32(&ccm->hdmi_slow_clk_cfg, CCM_HDMI_SLOW_CTRL_DDC_GATE); ++ clrbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_HDMI); ++ clrbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI); ++ clrbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_HDMI2); ++ clock_set_pll3(0); ++} ++ ++static int sun8i_hdmi_ddc_wait_i2c_done(int msec) ++{ ++ u32 val; ++ ulong start; ++ ++ start = get_timer(0); ++ do { ++ val = readb(SUN8I_HDMI_IH_I2CM_STAT0); ++ writeb(val, SUN8I_HDMI_IH_I2CM_STAT0); ++ ++ if (val & 0x2) ++ return 0; ++ if (val & 0x1) ++ return -EIO; ++ ++ udelay(100); ++ } while (get_timer(start) < msec); ++ ++ return 1; ++} ++ ++static int sunxi_hdmi_ddc_read(int block, u8 *buf) ++{ ++ int shift = (block % 2) * 0x80; ++ int trytime = 5; ++ int edid_read_err = 0; ++ u32 op = (block == 0) ? 1 : 2; ++ int n; ++ ++ writeb(block >> 1, SUN8I_HDMI_I2CM_SEGPTR); ++ ++ while (trytime--) { ++ edid_read_err = 0; ++ ++ for (n = 0; n < HDMI_EDID_BLOCK_SIZE; n++) { ++ writeb(shift + n, SUN8I_HDMI_I2CM_ADDRESS); ++ writeb(op, SUN8I_HDMI_I2CM_OPERATION); ++ ++ if (sun8i_hdmi_ddc_wait_i2c_done(10)) { ++ edid_read_err = 1; ++ break; ++ } ++ ++ *buf++ = readb(SUN8I_HDMI_I2CM_DATAI); ++ } ++ ++ if (!edid_read_err) ++ break; ++ } ++ ++ return edid_read_err; ++} ++ ++static int sunxi_hdmi_edid_get_block(int block, u8 *buf) ++{ ++ int r, retries = 2; ++ ++ do { ++ r = sunxi_hdmi_ddc_read(block, buf); ++ if (r) ++ continue; ++ r = edid_check_checksum(buf); ++ if (r) { ++ printf("EDID block %d: checksum error%s\n", ++ block, retries ? ", retrying" : ""); ++ } ++ } while (r && retries--); ++ ++ return r; ++} ++ ++static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) ++{ ++ struct edid1_info edid1; ++ struct edid_cea861_info cea681[4]; ++ struct edid_detailed_timing *t = ++ (struct edid_detailed_timing *)edid1.monitor_details.timing; ++ int i, r, ext_blocks = 0; ++ ++ /* Reset i2c controller */ ++ writeb(0, SUN8I_HDMI_I2CM_SOFTRSTZ); ++ ++ writeb(0x05, SUN8I_HDMI_I2CM_DIV); ++ writeb(0x08, SUN8I_HDMI_I2CM_INT); ++ writeb(0xd8, SUN8I_HDMI_I2CM_SS_SCL_HCNT_0_ADDR); ++ writeb(0xfe, SUN8I_HDMI_I2CM_SS_SCL_LCNT_0_ADDR); ++ writeb(SUN8I_HMDI_DDC_ADDR_SLAVE_ADDR, SUN8I_HDMI_I2CM_SLAVE); ++ writeb(SUN8I_HMDI_DDC_ADDR_SEG_ADDR, SUN8I_HDMI_I2CM_SEGADDR); ++ ++ r = sunxi_hdmi_edid_get_block(0, (u8 *)&edid1); ++ if (r == 0) { ++ r = edid_check_info(&edid1); ++ if (r) { ++ printf("EDID: invalid EDID data\n"); ++ r = -EINVAL; ++ } ++ } ++ if (r == 0) { ++ ext_blocks = edid1.extension_flag; ++ if (ext_blocks > 4) ++ ext_blocks = 4; ++ for (i = 0; i < ext_blocks; i++) { ++ if (sunxi_hdmi_edid_get_block(1 + i, ++ (u8 *)&cea681[i]) != 0) { ++ ext_blocks = i; ++ break; ++ } ++ } ++ } ++ ++ if (r) ++ return r; ++ ++ /* We want version 1.3 or 1.2 with detailed timing info */ ++ if (edid1.version != 1 || (edid1.revision < 3 && ++ !EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(edid1))) { ++ printf("EDID: unsupported version %d.%d\n", ++ edid1.version, edid1.revision); ++ return -EINVAL; ++ } ++ ++ /* Take the first usable detailed timing */ ++ for (i = 0; i < 4; i++, t++) { ++ r = video_edid_dtd_to_ctfb_res_modes(t, mode); ++ if (r == 0) ++ break; ++ } ++ if (i == 4) { ++ printf("EDID: no usable detailed timing found\n"); ++ return -ENOENT; ++ } ++ ++ /* Check for basic audio support, if found enable hdmi output */ ++ sunxi_display.monitor = sunxi_monitor_dvi; ++ for (i = 0; i < ext_blocks; i++) { ++ if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG || ++ cea681[i].revision < 2) ++ continue; ++ ++ if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i])) ++ sunxi_display.monitor = sunxi_monitor_hdmi; ++ } ++ ++ return 0; ++} ++ ++#endif /* CONFIG_VIDEO_HDMI */ ++ ++/* ++ * This is the entity that mixes and matches the different layers and inputs. ++ * Allwinner calls it display engine, but here is called composer. ++ */ ++static void sunxi_composer_init(void) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ ++ clock_set_pll10(432000000); ++ ++ /* Set DE parent to pll10 */ ++ clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE_CTRL_PLL_MASK, ++ CCM_DE_CTRL_PLL10); ++ ++ /* Set ahb gating to pass */ ++ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE); ++ setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE); ++ ++ /* Clock on */ ++ setbits_le32(&ccm->de_clk_cfg, CCM_DE_CTRL_GATE); ++} ++ ++static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode, ++ unsigned int address) ++{ ++ struct de_glb * const de_glb_regs = ++ (struct de_glb *)(DE_MUX0_BASE + DE_MUX_GLB_REGS); ++ struct de_bld * const de_bld_regs = ++ (struct de_bld *)(DE_MUX0_BASE + DE_MUX_BLD_REGS); ++ struct de_ui * const de_ui_regs = ++ (struct de_ui *)(DE_MUX0_BASE + DE_MUX_CHAN_REGS + ++ DE_MUX_CHAN_SZ * 1); ++ u32 size = WH(mode->xres, mode->yres); ++ int channel, i; ++ u32 data; ++ ++ /* enable clock */ ++ setbits_le32(SUN8I_DE_RESET_REG, 1); ++ setbits_le32(SUN8I_DE_GATE_REG, 1); ++ setbits_le32(SUN8I_DE_MOD_REG, 1); ++ ++ clrbits_le32(SUN8I_DE_SEL_REG, 1); ++ ++ writel(DE_MUX_GLB_CTL_rt_en, &de_glb_regs->ctl); ++ writel(0, &de_glb_regs->status); ++ writel(1, &de_glb_regs->dbuff); ++ writel(size, &de_glb_regs->size); ++ ++ for (channel = 0; channel < 4; channel++) { ++ void *chan = DE_MUX0_BASE + DE_MUX_CHAN_REGS + ++ DE_MUX_CHAN_SZ * channel; ++ memset(chan, 0, channel == 0 ? ++ sizeof(struct de_vi) : sizeof(struct de_ui)); ++ } ++ ++ memset(de_bld_regs, 0, 0x44); ++ writel(0x00000101, &de_bld_regs->fcolor_ctl); ++ ++ writel(1, &de_bld_regs->route); ++ ++ writel(0, &de_bld_regs->premultiply); ++ writel(0xff000000, &de_bld_regs->bkcolor); ++ ++ writel(0x03010301, &de_bld_regs->bld_mode[0]); ++ writel(0x03010301, &de_bld_regs->bld_mode[1]); ++ ++ writel(size, &de_bld_regs->output_size); ++ writel(mode->vmode & FB_VMODE_INTERLACED ? 2 : 0, ++ &de_bld_regs->out_ctl); ++ writel(0, &de_bld_regs->ck_ctl); ++ ++ for (i = 0; i < 4; i++) { ++ writel(0xff000000, &de_bld_regs->attr[i].fcolor); ++ writel(size, &de_bld_regs->attr[i].insize); ++ } ++ ++ writel(0, DE_MUX0_BASE + DE_MUX_VSU_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_GSU1_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_GSU2_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_GSU3_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_FCE_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_BWS_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_LTI_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_PEAK_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_ASE_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_FCC_REGS); ++ writel(0, DE_MUX0_BASE + DE_MUX_DCSC_REGS); ++ ++ data = UI_CFG_ATTR_en | (DE2_FORMAT_XRGB_8888 << UI_CFG_ATTR_fmt_SHIFT) | ++ (1 << UI_CFG_ATTR_alpmod_SHIFT) | (0xff << UI_CFG_ATTR_alpha_SHIFT); ++ writel(data, &de_ui_regs->cfg[0].attr); ++ writel(size, &de_ui_regs->cfg[0].size); ++ writel(0, &de_ui_regs->cfg[0].coord); ++ writel(4 * mode->xres, &de_ui_regs->cfg[0].pitch); ++ writel(address, &de_ui_regs->cfg[0].top_laddr); ++ writel(size, &de_ui_regs->ovl_size); ++} ++ ++static void sunxi_composer_enable(void) ++{ ++ struct de_glb * const de_glb_regs = ++ (struct de_glb *)(DE_MUX0_BASE + DE_MUX_GLB_REGS); ++ ++ writel(1, &de_glb_regs->dbuff); ++} ++ ++/* ++ * LCDC, what allwinner calls a CRTC, so timing controller and serializer. ++ */ ++static void sunxi_lcdc_pll_set(int dotclock, int *clk_div) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ int value, n, m, x = 0, diff; ++ int best_n = 0, best_m = 0, best_diff = 0x0FFFFFFF; ++ ++ if (dotclock <= 27000) ++ x = 11; ++ else if (dotclock <= 74250) ++ x = 4; ++ else if (dotclock <= 148500) ++ x = 2; ++ else if (dotclock <= 297000) ++ x = 1; ++ ++ /* ++ * Find the lowest divider resulting in a matching clock, if there ++ * is no match, pick the closest lower clock, as monitors tend to ++ * not sync to higher frequencies. ++ */ ++ for (m = 1; m <= 16; m++) { ++ n = (m * x * dotclock) / 24000; ++ ++ if ((n >= 1) && (n <= 128)) { ++ value = (24000 * n) / m / x; ++ diff = dotclock - value; ++ if (diff < best_diff) { ++ best_diff = diff; ++ best_m = m; ++ best_n = n; ++ } ++ } ++ } ++ ++ clock_set_pll3_factors(best_m, best_n); ++ printf("dotclock: %dkHz = %dkHz: (24MHz * %d) / %d / %d\n", ++ dotclock, (clock_get_pll3() / 1000) / x, ++ best_n, best_m, x); ++ ++ writel(CCM_TCON0_CTRL_GATE | CCM_TCON0_CTRL_M(x), ++ &ccm->tcon0_clk_cfg); ++ ++ *clk_div = x; ++} ++ ++static void sunxi_lcdc_init(void) ++{ ++ struct sunxi_ccm_reg * const ccm = ++ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; ++ struct sun8i_lcdc_reg * const lcdc = ++ (struct sun8i_lcdc_reg *)SUNXI_LCD0_BASE; ++ ++ /* Reset off */ ++ setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_TCON0); ++ ++ /* Clock on */ ++ setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_TCON0); ++ setbits_le32(&ccm->tcon0_clk_cfg, CCM_TCON0_CTRL_GATE); ++ ++ /* Init lcdc */ ++ clrbits_le32(&lcdc->tcon0_ctl, SUN8I_TCON0_CTL_TCON_En); /* Disable tcon0 */ ++ clrbits_le32(&lcdc->gctl, SUN8I_TCON_GCTL_TCON_En); /* Disable tcon globally */ ++ writel(0, &lcdc->gint0); /* Disable all interrupts */ ++ ++ /* Set all io lines to tristate */ ++ writel(0x0fffffff, &lcdc->io_tri); ++} ++ ++static void sunxi_lcdc_enable(void) ++{ ++ struct sun8i_lcdc_reg * const lcdc = ++ (struct sun8i_lcdc_reg *)SUNXI_LCD0_BASE; ++ ++ setbits_le32(&lcdc->gctl, SUN8I_TCON_GCTL_TCON_En); ++} ++ ++static int sunxi_lcdc_get_clk_delay(const struct ctfb_res_modes *mode, int tcon) ++{ ++ int delay; ++ ++ delay = mode->lower_margin + mode->vsync_len + mode->upper_margin; ++ if (mode->vmode == FB_VMODE_INTERLACED) ++ delay /= 2; ++ if (tcon == 1) ++ delay -= 2; ++ ++ return (delay > 31) ? 31 : delay; ++} ++ ++#if defined CONFIG_VIDEO_HDMI ++static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, ++ int *clk_div) ++{ ++ struct sun8i_lcdc_reg * const lcdc = ++ (struct sun8i_lcdc_reg *)SUNXI_LCD0_BASE; ++ int bp, clk_delay, total, yres; ++ ++ setbits_le32(&lcdc->gctl, SUN8I_TCON_GCTL_TCON_En); ++ ++ clk_delay = sunxi_lcdc_get_clk_delay(mode, 1); ++ writel(SUNXI_LCDC_TCON1_CTRL_ENABLE | ++ ((mode->vmode == FB_VMODE_INTERLACED) ? ++ SUNXI_LCDC_TCON1_CTRL_INTERLACE_ENABLE : 0) | ++ SUNXI_LCDC_TCON1_CTRL_CLK_DELAY(clk_delay), &lcdc->tcon1_ctl); ++ ++ yres = mode->yres; ++ if (mode->vmode == FB_VMODE_INTERLACED) ++ yres /= 2; ++ writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), ++ &lcdc->basic0); ++ writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), ++ &lcdc->basic1); ++ writel(SUNXI_LCDC_X(mode->xres) | SUNXI_LCDC_Y(yres), ++ &lcdc->basic2); ++ ++ bp = mode->hsync_len + mode->left_margin; ++ total = mode->xres + mode->right_margin + bp; ++ writel(SUNXI_LCDC_TCON1_TIMING_H_TOTAL(total) | ++ SUNXI_LCDC_TCON1_TIMING_H_BP(bp), &lcdc->basic3); ++ ++ bp = mode->vsync_len + mode->upper_margin; ++ total = mode->yres + mode->lower_margin + bp; ++ if (mode->vmode == FB_VMODE_NONINTERLACED) ++ total *= 2; ++ writel(SUNXI_LCDC_TCON1_TIMING_V_TOTAL(total) | ++ SUNXI_LCDC_TCON1_TIMING_V_BP(bp), &lcdc->basic4); ++ ++ writel(SUNXI_LCDC_X(mode->hsync_len) | SUNXI_LCDC_Y(mode->vsync_len), ++ &lcdc->basic5); ++ ++ writel(0, &lcdc->ceu_ctl); ++ writel(0, &lcdc->fill_ctl); ++ ++ sunxi_lcdc_pll_set(mode->pixclock_khz, clk_div); ++} ++#endif /* CONFIG_VIDEO_HDMI */ ++ ++#ifdef CONFIG_VIDEO_HDMI ++ ++static void sunxi_hdmi_setup_info_frames(const struct ctfb_res_modes *mode) ++{ ++ u8 tmp; ++ ++ if (mode->pixclock_khz <= 27000) ++ tmp = 0x40; /* SD-modes, ITU601 colorspace */ ++ else ++ tmp = 0x80; /* HD-modes, ITU709 colorspace */ ++ ++ if (mode->xres * 100 / mode->yres < 156) ++ tmp |= 0x18; /* 4 : 3 */ ++ else ++ tmp |= 0x28; /* 16 : 9 */ ++ ++ setbits_8(SUNXI_HDMI_BASE + 0x0040, 0x08); ++ writeb(0x60, SUNXI_HDMI_BASE + 0x4045); ++ writeb(tmp, SUNXI_HDMI_BASE + 0xC044); ++ writeb(0x88, SUNXI_HDMI_BASE + 0xC045); ++} ++ ++static int hdmi_phy_set(u32 divider) ++{ ++ u32 tmp; ++ ++ switch(divider) ++ { ++ case 1: ++ writel(0x30dc5fc0, SUN8I_HDMI_PHY_PLL_REG); ++ writel(0x800863C0, SUN8I_HDMI_PHY_CLK_REG); ++ mdelay(10); ++ writel(0x00000001, SUN8I_HDMI_PHY_UNK3_REG); ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(25)); ++ mdelay(200); ++ tmp = (readl(SUN8I_HDMI_PHY_STATUS_REG) & 0x1f800) >> 11; ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(31) | BIT(30)); ++ if (tmp < 0x3d) ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, tmp + 2); ++ else ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, 0x3f); ++ mdelay(100); ++ writel(0x01FFFF7F, SUN8I_HDMI_PHY_CTRL_REG); ++ writel(0x8063b000, SUN8I_HDMI_PHY_UNK1_REG); ++ writel(0x0F8246B5, SUN8I_HDMI_PHY_UNK2_REG); ++ break; ++ case 2: ++ writel(0x39dc5040, SUN8I_HDMI_PHY_PLL_REG); ++ writel(0x80084381, SUN8I_HDMI_PHY_CLK_REG); ++ mdelay(10); ++ writel(0x00000001, SUN8I_HDMI_PHY_UNK3_REG); ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(25)); ++ mdelay(100); ++ tmp = (readl(SUN8I_HDMI_PHY_STATUS_REG) & 0x1f800) >> 11; ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(31) | BIT(30)); ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, tmp); ++ writel(0x01FFFF7F, SUN8I_HDMI_PHY_CTRL_REG); ++ writel(0x8063a800, SUN8I_HDMI_PHY_UNK1_REG); ++ writel(0x0F81C485, SUN8I_HDMI_PHY_UNK2_REG); ++ break; ++ case 4: ++ writel(0x39dc5040, SUN8I_HDMI_PHY_PLL_REG); ++ writel(0x80084343, SUN8I_HDMI_PHY_CLK_REG); ++ mdelay(10); ++ writel(0x00000001, SUN8I_HDMI_PHY_UNK3_REG); ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(25)); ++ mdelay(100); ++ tmp = (readl(SUN8I_HDMI_PHY_STATUS_REG) & 0x1f800) >> 11; ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(31) | BIT(30)); ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, tmp); ++ writel(0x01FFFF7F, SUN8I_HDMI_PHY_CTRL_REG); ++ writel(0x8063b000, SUN8I_HDMI_PHY_UNK1_REG); ++ writel(0x0F81C405, SUN8I_HDMI_PHY_UNK2_REG); ++ break; ++ case 11: ++ writel(0x39dc5040, SUN8I_HDMI_PHY_PLL_REG); ++ writel(0x8008430a, SUN8I_HDMI_PHY_CLK_REG); ++ mdelay(10); ++ writel(0x00000001, SUN8I_HDMI_PHY_UNK3_REG); ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(25)); ++ mdelay(100); ++ tmp = (readl(SUN8I_HDMI_PHY_STATUS_REG) & 0x1f800) >> 11; ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, BIT(31) | BIT(30)); ++ setbits_le32(SUN8I_HDMI_PHY_PLL_REG, tmp); ++ writel(0x01FFFF7F, SUN8I_HDMI_PHY_CTRL_REG); ++ writel(0x8063b000, SUN8I_HDMI_PHY_UNK1_REG); ++ writel(0x0F81C405, SUN8I_HDMI_PHY_UNK2_REG); ++ break; ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode, ++ int clk_div) ++{ ++ u8 invidconf, v_blanking; ++ u32 h_blanking; ++ ++ if(hdmi_phy_set(clk_div) != 0) { ++ printf("HDMI divider is invalid!\n"); ++ return; ++ } ++ ++ invidconf = 0; ++ if(mode->vmode & FB_VMODE_INTERLACED) ++ invidconf |= 0x01; ++ if(mode->sync & FB_SYNC_HOR_HIGH_ACT) ++ invidconf |= 0x20; ++ if(mode->sync & FB_SYNC_VERT_HIGH_ACT) ++ invidconf |= 0x40; ++ ++ h_blanking = mode->left_margin + mode->right_margin + mode->hsync_len; ++ v_blanking = mode->upper_margin + mode->lower_margin + mode->vsync_len; ++ ++ writeb(invidconf | 0x10, SUNXI_HDMI_BASE + 0x0040); ++ writeb(((invidconf < 96) ? 0x03 : 0x00), SUNXI_HDMI_BASE + 0x10001); ++ ++ writeb(mode->xres >> 8, SUNXI_HDMI_BASE + 0x8040); ++ writeb(mode->xres, SUNXI_HDMI_BASE + 0x0041); ++ writeb(mode->yres >> 8, SUNXI_HDMI_BASE + 0x8042); ++ writeb(mode->yres, SUNXI_HDMI_BASE + 0x0043); ++ writeb(mode->vsync_len, SUNXI_HDMI_BASE + 0x4043); ++ writeb(h_blanking >> 8, SUNXI_HDMI_BASE + 0x0042); ++ writeb(h_blanking, SUNXI_HDMI_BASE + 0x8041); ++ writeb(mode->lower_margin, SUNXI_HDMI_BASE + 0x4042); ++ writeb(mode->right_margin >> 8, SUNXI_HDMI_BASE + 0x4041); ++ writeb(mode->right_margin, SUNXI_HDMI_BASE + 0x4040); ++ writeb(mode->hsync_len >> 8, SUNXI_HDMI_BASE + 0xC041); ++ writeb(mode->hsync_len, SUNXI_HDMI_BASE + 0xC040); ++ writeb(v_blanking, SUNXI_HDMI_BASE + 0x8043); ++ ++ writeb(0x0c, SUNXI_HDMI_BASE + 0x0045); ++ writeb(0x20, SUNXI_HDMI_BASE + 0x8044); ++ writeb(0x01, SUNXI_HDMI_BASE + 0x8045); ++ writeb(0x0b, SUNXI_HDMI_BASE + 0x0046); ++ writeb(0x16, SUNXI_HDMI_BASE + 0x0047); ++ writeb(0x21, SUNXI_HDMI_BASE + 0x8046); ++ ++ writeb(0x40, SUNXI_HDMI_BASE + 0x0401); ++ writeb(0x07, SUNXI_HDMI_BASE + 0x8400); ++ ++ // default value, written 0 by rk_hdmi ++ writeb(0x00, SUNXI_HDMI_BASE + 0x8401); ++ ++ writeb(0x47, SUNXI_HDMI_BASE + 0x0402); ++ writeb(0x01, SUNXI_HDMI_BASE + 0x0800); ++ writeb(0x07, SUNXI_HDMI_BASE + 0x0801); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x8800); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x8801); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x0802); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x0803); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x8802); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x8803); ++ ++ if (sunxi_display.monitor == sunxi_monitor_hdmi) ++ sunxi_hdmi_setup_info_frames(mode); ++ ++ writeb(0x00, SUNXI_HDMI_BASE + 0x0082); ++ writeb(0x00, SUNXI_HDMI_BASE + 0x0081); ++} ++ ++static void sunxi_hdmi_enable(void) ++{ ++ setbits_le32(SUN8I_HDMI_PHY_CTRL_REG, 0xf << 12); ++ printf("hdmi enabled\n"); ++} ++ ++#endif /* CONFIG_VIDEO_HDMI */ ++ ++static void sunxi_engines_init(void) ++{ ++ sunxi_composer_init(); ++ sunxi_lcdc_init(); ++} ++ ++static void sunxi_mode_set(const struct ctfb_res_modes *mode, ++ unsigned int address) ++{ ++ int __maybe_unused clk_div; ++ ++ switch (sunxi_display.monitor) { ++ case sunxi_monitor_none: ++ break; ++ case sunxi_monitor_dvi: ++ case sunxi_monitor_hdmi: ++#ifdef CONFIG_VIDEO_HDMI ++ sunxi_composer_mode_set(mode, address); ++ sunxi_lcdc_tcon0_mode_set(mode, &clk_div); ++ sunxi_hdmi_mode_set(mode, clk_div); ++ sunxi_composer_enable(); ++ sunxi_lcdc_enable(); ++ sunxi_hdmi_enable(); ++#endif ++ break; ++ } ++} ++ ++static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor) ++{ ++ switch (monitor) { ++ case sunxi_monitor_none: return "none"; ++ case sunxi_monitor_dvi: return "dvi"; ++ case sunxi_monitor_hdmi: return "hdmi"; ++ } ++ return NULL; /* never reached */ ++} ++ ++ulong board_get_usable_ram_top(ulong total_size) ++{ ++ return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE; ++} ++ ++static bool sunxi_has_hdmi(void) ++{ ++#ifdef CONFIG_VIDEO_HDMI ++ return true; ++#else ++ return false; ++#endif ++} ++ ++static enum sunxi_monitor sunxi_get_default_mon(bool allow_hdmi) ++{ ++ if (allow_hdmi && sunxi_has_hdmi()) ++ return sunxi_monitor_dvi; ++ else ++ return sunxi_monitor_none; ++} ++ ++void *video_hw_init(void) ++{ ++ static GraphicDevice *graphic_device = &sunxi_display.graphic_device; ++ const struct ctfb_res_modes *mode; ++ struct ctfb_res_modes custom; ++ const char *options; ++#ifdef CONFIG_VIDEO_HDMI ++ int ret, hpd, hpd_delay, edid; ++#endif ++ int i, overscan_offset, overscan_x, overscan_y; ++ unsigned int fb_dma_addr; ++ char mon[16]; ++ ++ memset(&sunxi_display, 0, sizeof(struct sunxi_display)); ++ ++ video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, ++ &sunxi_display.depth, &options); ++#ifdef CONFIG_VIDEO_HDMI ++ hpd = video_get_option_int(options, "hpd", 1); ++ hpd_delay = video_get_option_int(options, "hpd_delay", 500); ++ edid = video_get_option_int(options, "edid", 1); ++#endif ++ overscan_x = video_get_option_int(options, "overscan_x", -1); ++ overscan_y = video_get_option_int(options, "overscan_y", -1); ++ sunxi_display.monitor = sunxi_get_default_mon(true); ++ video_get_option_string(options, "monitor", mon, sizeof(mon), ++ sunxi_get_mon_desc(sunxi_display.monitor)); ++ for (i = 0; i <= SUNXI_MONITOR_LAST; i++) { ++ if (strcmp(mon, sunxi_get_mon_desc(i)) == 0) { ++ sunxi_display.monitor = i; ++ break; ++ } ++ } ++ if (i > SUNXI_MONITOR_LAST) ++ printf("Unknown monitor: '%s', falling back to '%s'\n", ++ mon, sunxi_get_mon_desc(sunxi_display.monitor)); ++ ++#ifdef CONFIG_VIDEO_HDMI ++ /* If HDMI/DVI is selected do HPD & EDID, and handle fallback */ ++ if (sunxi_display.monitor == sunxi_monitor_dvi || ++ sunxi_display.monitor == sunxi_monitor_hdmi) { ++ /* Always call hdp_detect, as it also enables clocks, etc. */ ++ ret = sun8i_hdmi_hpd_detect(hpd_delay); ++ if (ret) { ++ printf("HDMI connected: "); ++ if (edid && sunxi_hdmi_edid_get_mode(&custom) == 0) ++ mode = &custom; ++ } else if (hpd) { ++ sunxi_hdmi_shutdown(); ++ sunxi_display.monitor = sunxi_get_default_mon(false); ++ } /* else continue with hdmi/dvi without a cable connected */ ++ } ++#endif ++ ++ switch (sunxi_display.monitor) { ++ case sunxi_monitor_none: ++ return NULL; ++ case sunxi_monitor_dvi: ++ case sunxi_monitor_hdmi: ++ if (!sunxi_has_hdmi()) { ++ printf("HDMI/DVI not supported on this board\n"); ++ sunxi_display.monitor = sunxi_monitor_none; ++ return NULL; ++ } ++ break; ++ } ++ ++ if (overscan_x == -1) ++ overscan_x = 0; ++ if (overscan_y == -1) ++ overscan_y = 0; ++ ++ sunxi_display.fb_size = ++ (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff; ++ overscan_offset = (overscan_y * mode->xres + overscan_x) * 4; ++ /* We want to keep the fb_base for simplefb page aligned, where as ++ * the sunxi dma engines will happily accept an unaligned address. */ ++ if (overscan_offset) ++ sunxi_display.fb_size += 0x1000; ++ ++ if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) { ++ printf("Error need %dkB for fb, but only %dkB is reserved\n", ++ sunxi_display.fb_size >> 10, ++ CONFIG_SUNXI_MAX_FB_SIZE >> 10); ++ return NULL; ++ } ++ ++ printf("Setting up a %dx%d%s %s console (overscan %dx%d)\n", ++ mode->xres, mode->yres, ++ (mode->vmode == FB_VMODE_INTERLACED) ? "i" : "", ++ sunxi_get_mon_desc(sunxi_display.monitor), ++ overscan_x, overscan_y); ++ ++ gd->fb_base = gd->bd->bi_dram[0].start + ++ gd->bd->bi_dram[0].size - sunxi_display.fb_size; ++ sunxi_engines_init(); ++ ++ fb_dma_addr = gd->fb_base; ++ sunxi_display.fb_addr = gd->fb_base; ++ if (overscan_offset) { ++ fb_dma_addr += 0x1000 - (overscan_offset & 0xfff); ++ sunxi_display.fb_addr += (overscan_offset + 0xfff) & ~0xfff; ++ memset((void *)gd->fb_base, 0, sunxi_display.fb_size); ++ flush_cache(gd->fb_base, sunxi_display.fb_size); ++ } ++ sunxi_mode_set(mode, fb_dma_addr); ++ ++ /* ++ * These are the only members of this structure that are used. All the ++ * others are driver specific. The pitch is stored in plnSizeX. ++ */ ++ graphic_device->frameAdrs = sunxi_display.fb_addr; ++ graphic_device->gdfIndex = GDF_32BIT_X888RGB; ++ graphic_device->gdfBytesPP = 4; ++ graphic_device->winSizeX = mode->xres - 2 * overscan_x; ++ graphic_device->winSizeY = mode->yres - 2 * overscan_y; ++ graphic_device->plnSizeX = mode->xres * graphic_device->gdfBytesPP; ++ ++ return graphic_device; ++} +diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h +index e0464df..c63c1bc 100644 +--- a/include/configs/sunxi-common.h ++++ b/include/configs/sunxi-common.h +@@ -284,9 +284,13 @@ extern int soft_i2c_gpio_scl; + #define CONFIG_SUNXI_MAX_FB_SIZE (16 << 20) + + /* Do we want to initialize a simple FB? */ ++#ifndef CONFIG_MACH_SUN8I_H3 + #define CONFIG_VIDEO_DT_SIMPLEFB + + #define CONFIG_VIDEO_SUNXI ++#else ++#define CONFIG_VIDEO_SUNXI_H3 ++#endif + + #define CONFIG_VIDEO_LOGO + #define CONFIG_VIDEO_STD_TIMINGS +diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt +index 11b5a22..cef476f 100644 +--- a/scripts/config_whitelist.txt ++++ b/scripts/config_whitelist.txt +@@ -8270,6 +8270,7 @@ CONFIG_VIDEO_SM501_8BPP + CONFIG_VIDEO_SM501_PCI + CONFIG_VIDEO_STD_TIMINGS + CONFIG_VIDEO_SUNXI ++CONFIG_VIDEO_SUNXI_H3 + CONFIG_VIDEO_VCXK + CONFIG_VID_FLS_ENV + CONFIG_VM86 diff --git a/projects/H3/patches/u-boot/u-boot-04-enable-h3-video.patch b/projects/H3/patches/u-boot/u-boot-04-enable-h3-video.patch new file mode 100644 index 00000000000..e3ffd7a2b28 --- /dev/null +++ b/projects/H3/patches/u-boot/u-boot-04-enable-h3-video.patch @@ -0,0 +1,79 @@ +From c620038640de2a2bdaf55804c51b3083f63e03ac Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Mon, 14 Nov 2016 21:40:13 +0100 +Subject: [PATCH] sunxi: video: Enable H3 video driver in defconfigs + +Signed-off-by: Jernej Skrabec +--- + configs/orangepi_2_defconfig | 1 + + configs/orangepi_lite_defconfig | 1 + + configs/orangepi_one_defconfig | 1 + + configs/orangepi_pc_defconfig | 1 + + configs/orangepi_pc_plus_defconfig | 1 + + configs/orangepi_plus2e_defconfig | 1 + + configs/orangepi_plus_defconfig | 1 + + 7 files changed, 7 insertions(+) + +diff --git a/configs/orangepi_2_defconfig b/configs/orangepi_2_defconfig +index 4727aca..dea819d 100644 +--- a/configs/orangepi_2_defconfig ++++ b/configs/orangepi_2_defconfig +@@ -16,3 +16,4 @@ CONFIG_SPL=y + CONFIG_SUN8I_EMAC=y + CONFIG_SY8106A_POWER=y + CONFIG_USB_EHCI_HCD=y ++CONFIG_VIDEO=y +diff --git a/configs/orangepi_lite_defconfig b/configs/orangepi_lite_defconfig +index 8545835..8801825 100644 +--- a/configs/orangepi_lite_defconfig ++++ b/configs/orangepi_lite_defconfig +@@ -12,3 +12,4 @@ CONFIG_SPL=y + # CONFIG_CMD_FLASH is not set + # CONFIG_CMD_FPGA is not set + CONFIG_USB_EHCI_HCD=y ++CONFIG_VIDEO=y +diff --git a/configs/orangepi_one_defconfig b/configs/orangepi_one_defconfig +index 01b4ece..fc72a96 100644 +--- a/configs/orangepi_one_defconfig ++++ b/configs/orangepi_one_defconfig +@@ -13,3 +13,4 @@ CONFIG_SPL=y + # CONFIG_CMD_FPGA is not set + CONFIG_SUN8I_EMAC=y + CONFIG_USB_EHCI_HCD=y ++CONFIG_VIDEO=y +diff --git a/configs/orangepi_pc_defconfig b/configs/orangepi_pc_defconfig +index 910d68e..e0b579d 100644 +--- a/configs/orangepi_pc_defconfig ++++ b/configs/orangepi_pc_defconfig +@@ -15,3 +15,4 @@ CONFIG_SPL=y + CONFIG_SUN8I_EMAC=y + CONFIG_SY8106A_POWER=y + CONFIG_USB_EHCI_HCD=y ++CONFIG_VIDEO=y +diff --git a/configs/orangepi_pc_plus_defconfig b/configs/orangepi_pc_plus_defconfig +index f43682b..9b8d407 100644 +--- a/configs/orangepi_pc_plus_defconfig ++++ b/configs/orangepi_pc_plus_defconfig +@@ -16,3 +16,4 @@ CONFIG_SPL=y + CONFIG_SUN8I_EMAC=y + CONFIG_SY8106A_POWER=y + CONFIG_USB_EHCI_HCD=y ++CONFIG_VIDEO=y +diff --git a/configs/orangepi_plus2e_defconfig b/configs/orangepi_plus2e_defconfig +index df05d37..0eb9466 100644 +--- a/configs/orangepi_plus2e_defconfig ++++ b/configs/orangepi_plus2e_defconfig +@@ -17,3 +17,4 @@ CONFIG_SPL=y + CONFIG_SUN8I_EMAC=y + CONFIG_SY8106A_POWER=y + CONFIG_USB_EHCI_HCD=y ++CONFIG_VIDEO=y +diff --git a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig +index bf88fef..c773ef2 100644 +--- a/configs/orangepi_plus_defconfig ++++ b/configs/orangepi_plus_defconfig +@@ -18,3 +18,4 @@ CONFIG_SPL=y + CONFIG_SUN8I_EMAC=y + CONFIG_SY8106A_POWER=y + CONFIG_USB_EHCI_HCD=y ++CONFIG_VIDEO=y diff --git a/projects/H3/patches/u-boot/u-boot-05-enable-splash.patch b/projects/H3/patches/u-boot/u-boot-05-enable-splash.patch new file mode 100644 index 00000000000..0e9481f338f --- /dev/null +++ b/projects/H3/patches/u-boot/u-boot-05-enable-splash.patch @@ -0,0 +1,42 @@ +diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h +index c63c1bc..4cb057d 100644 +--- a/include/configs/sunxi-common.h ++++ b/include/configs/sunxi-common.h +@@ -293,6 +293,10 @@ extern int soft_i2c_gpio_scl; + #endif + + #define CONFIG_VIDEO_LOGO ++#define CONFIG_HIDE_LOGO_VERSION ++#define CONFIG_SPLASH_SCREEN_ALIGN ++#define CONFIG_VIDEO_BMP_RLE8 ++#define CONFIG_VIDEO_BMP_LOGO + #define CONFIG_VIDEO_STD_TIMINGS + #define CONFIG_I2C_EDID + #define VIDEO_LINE_LEN (pGD->plnSizeX) +@@ -480,15 +484,15 @@ extern int soft_i2c_gpio_scl; + "stdin=serial\0" + #endif + +-#ifdef CONFIG_VIDEO ++/*#ifdef CONFIG_VIDEO + #define CONSOLE_STDOUT_SETTINGS \ + "stdout=serial,vga\0" \ + "stderr=serial,vga\0" +-#else ++#else*/ + #define CONSOLE_STDOUT_SETTINGS \ + "stdout=serial\0" \ + "stderr=serial\0" +-#endif ++/*#endif*/ + + #define CONSOLE_ENV_SETTINGS \ + CONSOLE_STDIN_SETTINGS \ +@@ -500,6 +504,7 @@ extern int soft_i2c_gpio_scl; + DFU_ALT_INFO_RAM \ + "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ + "console=ttyS0,115200\0" \ ++ "splashpos=m,m\0" \ + BOOTCMD_SUNXI_COMPAT \ + BOOTENV + diff --git a/projects/H3/patches/u-boot/u-boot-06-fix-screen-switch.patch b/projects/H3/patches/u-boot/u-boot-06-fix-screen-switch.patch new file mode 100644 index 00000000000..ed30e0883ab --- /dev/null +++ b/projects/H3/patches/u-boot/u-boot-06-fix-screen-switch.patch @@ -0,0 +1,22 @@ +diff --git a/drivers/video/sun8i_display.c b/drivers/video/sun8i_display.c +index e596e4c..5c7d83f 100644 +--- a/drivers/video/sun8i_display.c ++++ b/drivers/video/sun8i_display.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include "videomodes.h" + +@@ -899,8 +900,7 @@ void *video_hw_init(void) + sunxi_get_mon_desc(sunxi_display.monitor), + overscan_x, overscan_y); + +- gd->fb_base = gd->bd->bi_dram[0].start + +- gd->bd->bi_dram[0].size - sunxi_display.fb_size; ++ gd->fb_base = (unsigned long)memalign(0x1000, sunxi_display.fb_size); + sunxi_engines_init(); + + fb_dma_addr = gd->fb_base; diff --git a/projects/H3/patches/u-boot/u-boot-99-add-banana-pi-m2p-board.patch b/projects/H3/patches/u-boot/u-boot-99-add-banana-pi-m2p-board.patch new file mode 100644 index 00000000000..dc8baf07da1 --- /dev/null +++ b/projects/H3/patches/u-boot/u-boot-99-add-banana-pi-m2p-board.patch @@ -0,0 +1,24 @@ +diff --git a/configs/Sinovoip_BPI_M2_plus_defconfig b/configs/Sinovoip_BPI_M2_plus_defconfig +new file mode 100644 +index 0000000..43562a2 +--- /dev/null ++++ b/configs/Sinovoip_BPI_M2_plus_defconfig +@@ -0,0 +1,18 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_SUNXI=y ++CONFIG_MACH_SUN8I_H3=y ++CONFIG_DRAM_CLK=624 ++CONFIG_DRAM_ZQ=3881979 ++CONFIG_DRAM_ODT_EN=y ++CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-bananapi-m2-plus" ++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set ++CONFIG_SPL=y ++# CONFIG_CMD_IMLS is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_CMD_FPGA is not set ++CONFIG_SUN8I_EMAC=y ++# CONFIG_USB_EHCI_HCD is not set ++CONFIG_MMC_SUNXI_SLOT_EXTRA=2 ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_VIDEO=y diff --git a/projects/H3/patches/u-boot/u-boot-99-add-beelink-x2-board.patch b/projects/H3/patches/u-boot/u-boot-99-add-beelink-x2-board.patch new file mode 100644 index 00000000000..ba1001ac3c4 --- /dev/null +++ b/projects/H3/patches/u-boot/u-boot-99-add-beelink-x2-board.patch @@ -0,0 +1,20 @@ +diff -Nur a/configs/beelink_x2_defconfig b/configs/beelink_x2_defconfig +--- a/configs/beelink_x2_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ b/configs/beelink_x2_defconfig 2016-09-12 16:05:51.000000000 +0200 +@@ -0,0 +1,16 @@ ++CONFIG_ARM=y ++CONFIG_ARCH_SUNXI=y ++CONFIG_MACH_SUN8I_H3=y ++CONFIG_DRAM_CLK=624 ++CONFIG_DRAM_ZQ=3881979 ++CONFIG_DRAM_ODT_EN=y ++CONFIG_MMC_SUNXI_SLOT_EXTRA=2 ++CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-pc-plus" ++# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set ++CONFIG_SPL=y ++# CONFIG_CMD_IMLS is not set ++# CONFIG_CMD_FLASH is not set ++# CONFIG_CMD_FPGA is not set ++CONFIG_SUN8I_EMAC=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_VIDEO=y diff --git a/projects/H3/patches/u-boot/u-boot-99-lower-h3-dram-clocks.patch b/projects/H3/patches/u-boot/u-boot-99-lower-h3-dram-clocks.patch new file mode 100644 index 00000000000..6cbaf80803a --- /dev/null +++ b/projects/H3/patches/u-boot/u-boot-99-lower-h3-dram-clocks.patch @@ -0,0 +1,60 @@ +diff -Nur a/configs/orangepi_2_defconfig b/configs/orangepi_2_defconfig +--- a/configs/orangepi_2_defconfig 2016-09-12 16:05:51.000000000 +0200 ++++ b/configs/orangepi_2_defconfig 2016-10-10 16:23:36.356921217 +0200 +@@ -1,7 +1,7 @@ + CONFIG_ARM=y + CONFIG_ARCH_SUNXI=y + CONFIG_MACH_SUN8I_H3=y +-CONFIG_DRAM_CLK=672 ++CONFIG_DRAM_CLK=624 + CONFIG_DRAM_ZQ=3881979 + CONFIG_DRAM_ODT_EN=y + CONFIG_USB1_VBUS_PIN="PG13" +diff -Nur a/configs/orangepi_lite_defconfig b/configs/orangepi_lite_defconfig +--- a/configs/orangepi_lite_defconfig 2016-09-12 16:05:51.000000000 +0200 ++++ b/configs/orangepi_lite_defconfig 2016-10-10 16:23:27.200254424 +0200 +@@ -1,7 +1,7 @@ + CONFIG_ARM=y + CONFIG_ARCH_SUNXI=y + CONFIG_MACH_SUN8I_H3=y +-CONFIG_DRAM_CLK=672 ++CONFIG_DRAM_CLK=624 + CONFIG_DRAM_ZQ=3881979 + CONFIG_DRAM_ODT_EN=y + CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-lite" +diff -Nur a/configs/orangepi_one_defconfig b/configs/orangepi_one_defconfig +--- a/configs/orangepi_one_defconfig 2016-09-12 16:05:51.000000000 +0200 ++++ b/configs/orangepi_one_defconfig 2016-10-10 16:23:43.183587977 +0200 +@@ -1,7 +1,7 @@ + CONFIG_ARM=y + CONFIG_ARCH_SUNXI=y + CONFIG_MACH_SUN8I_H3=y +-CONFIG_DRAM_CLK=672 ++CONFIG_DRAM_CLK=624 + CONFIG_DRAM_ZQ=3881979 + CONFIG_DRAM_ODT_EN=y + CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-orangepi-one" +diff -Nur a/configs/orangepi_plus2e_defconfig b/configs/orangepi_plus2e_defconfig +--- a/configs/orangepi_plus2e_defconfig 2016-09-12 16:05:51.000000000 +0200 ++++ b/configs/orangepi_plus2e_defconfig 2016-10-10 16:23:59.986921543 +0200 +@@ -1,7 +1,7 @@ + CONFIG_ARM=y + CONFIG_ARCH_SUNXI=y + CONFIG_MACH_SUN8I_H3=y +-CONFIG_DRAM_CLK=672 ++CONFIG_DRAM_CLK=624 + CONFIG_DRAM_ZQ=3881979 + CONFIG_DRAM_ODT_EN=y + CONFIG_MMC_SUNXI_SLOT_EXTRA=2 +diff -Nur a/configs/orangepi_plus_defconfig b/configs/orangepi_plus_defconfig +--- a/configs/orangepi_plus_defconfig 2016-09-12 16:05:51.000000000 +0200 ++++ b/configs/orangepi_plus_defconfig 2016-10-10 16:24:10.836921692 +0200 +@@ -1,7 +1,7 @@ + CONFIG_ARM=y + CONFIG_ARCH_SUNXI=y + CONFIG_MACH_SUN8I_H3=y +-CONFIG_DRAM_CLK=672 ++CONFIG_DRAM_CLK=624 + CONFIG_DRAM_ZQ=3881979 + CONFIG_DRAM_ODT_EN=y + CONFIG_MMC_SUNXI_SLOT_EXTRA=2 diff --git a/projects/H3/sys_config/bpim2p.fex b/projects/H3/sys_config/bpim2p.fex new file mode 100644 index 00000000000..708737babac --- /dev/null +++ b/projects/H3/sys_config/bpim2p.fex @@ -0,0 +1,1105 @@ +[product] +version = "100" +machine = "bpim2p" + +;--------------------------------------------------------------------------------------------------------- +; eraseflag - 1 erase data partition, 0 - do not erase data partition +; next_work - action after burn, 0x0 by config, 0x1, normal, 0x2 reboot 0x3 ,shutdown,0x4 reupdate ,0x5 boot +;--------------------------------------------------------------------------------------------------------- +[platform] +debug_mode = 1 +eraseflag = 1 +next_work = 2 + +;---------------------------------------------------------------------------------- +;[target] system bootup configuration +;boot_clock = CPU boot frequency, Unit: MHz +;storage_type = boot medium, 0-nand, 1-card0, 2-card2, -1(defualt)auto scan +;---------------------------------------------------------------------------------- +[target] +boot_clock = 1008 +storage_type = -1 + +;--------------------------------------------------------------------------------- +; used : 1: used this config, 0: not +; start_type : 1: start system directly when power supply, 0: wait IR/KEY to power on +; irkey_used : 1: ir key used, 0: not +; pmukey_used: 1: physical button used, 0: not +; led_power : 1: light, 0: off +; led_state : 1: light, 0: off +;--------------------------------------------------------------------------------- +[box_start_os] +used = 1 +start_type = 1 +irkey_used = 1 +pmukey_used = 1 +pmukey_num = 30 +led_power = 0 +led_state = 0 + +;--------------------------------------------------------------------------------------------------------- +; if 1 == standby_mode, then support super standby; +; else, support normal standby. +;--------------------------------------------------------------------------------------------------------- +[pm_para] +standby_mode = 1 + +; THIS PARAMETERS SEEMS TO BE USED ONLY FOR TESTING +[card0_boot_para] +card_ctrl = 0 +card_high_speed = 1 +card_line = 4 +sdc_d1 = port:PF00<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_d2 = port:PF05<2><1><2> + +[twi_para] +twi_port = 0 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[uart_para] +uart_debug_port = 0 +uart_debug_tx = port:PA04<2><1> +uart_debug_rx = port:PA05<2><1> + +[force_uart_para] +force_uart_port = 0 +force_uart_tx = port:PF02<3><1> +force_uart_rx = port:PF04<3><1> + +[jtag_para] +jtag_enable = 0 +jtag_ms = port:PA00<3> +jtag_ck = port:PA01<3> +jtag_do = port:PA02<3> +jtag_di = port:PA03<3> + +[clock] +pll_video = 297 +pll_ve = 402 +pll_periph0 = 600 +pll_gpu = 576 +pll_periph1 = 600 +pll_de = 864 + +;***************************************************************************** +;sdram configuration +; +;dram_para2 = 0x00001200 ;Representative enable dram Dual +;dram_para2 = 0x00001100 ;on behalf of a single channel is enabled dram +;***************************************************************************** +[dram_para] +dram_clk = 624 +dram_type = 3 +dram_zq = 0x3b3bfb +dram_odt_en = 0x1 +dram_para1 = 0x10E40000 +dram_para2 = 0x0000 +dram_mr0 = 0x1840 +dram_mr1 = 0x40 +dram_mr2 = 0x18 +dram_mr3 = 0x2 +dram_tpr0 = 0x0048A192 +dram_tpr1 = 0x01C2418D +dram_tpr2 = 0x00076051 +dram_tpr3 = 0 +dram_tpr4 = 0 +dram_tpr5 = 0 +dram_tpr6 = 100 +dram_tpr7 = 0 +dram_tpr8 = 0 +dram_tpr9 = 0 +dram_tpr10 = 0 +dram_tpr11 = 0x6aaa0000 +dram_tpr12 = 0x7979 +dram_tpr13 = 0x800800 + +;--------------------------------------------------------------------------------------------------------- +; wakeup_src_para: +; sometimes, u would like to add more wakeup src in standby mode, these para will be +; help; +; u need to make sure the standby mode support the wakeup src. Also, some hw +; condition must be guaranteed. +; including: +; cpu_en: power on or off. +; 1: mean power on +; 0: mean power off +; cpu_freq: indicating lowest freq. unit is Mhz; +; dram selfresh_en: selfresh or not. +; 1: enable enter selfresh +; 0: disable enter selfresh +; dram_pll: if not enter selfresh, indicating lowest freq. unit is Mhz; +; wakeup_src: to make the scenario work, the wakeup src is needed. +;--------------------------------------------------------------------------------------------------------- +[wakeup_src_para] +cpu_en = 0 +cpu_freq = 48 +; (cpu:apb:ahb) +pll_ratio = 273 +dram_selfresh_en = 1 +dram_freq = 36 +wakeup_src0 = +wakeup_src_wl = port:PG10<4><0> +wakeup_src_bt = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +;i2c configuration +;---------------------------------------------------------------------------------- +[twi0] +twi_used = 1 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[twi1] +twi_used = 0 +twi_scl = port:PA18<3> +twi_sda = port:PA19<3> + +[twi2] +twi_used = 0 +twi_scl = port:PE12<3> +twi_sda = port:PE13<3> + +;---------------------------------------------------------------------------------- +;uart configuration +;uart_type --- 2 (2 wire), 4 (4 wire), 8 (8 wire, full function) +;---------------------------------------------------------------------------------- +[uart0] +uart_used = 1 +uart_port = 0 +uart_type = 2 +uart_tx = port:PA04<2><1> +uart_rx = port:PA05<2><1> + +[uart1] +uart_used = 1 +uart_port = 1 +uart_type = 4 +uart_tx = port:PG06<2><1> +uart_rx = port:PG07<2><1> +uart_rts = port:PG08<2><1> +uart_cts = port:PG09<2><1> + +[uart2] +uart_used = 0 +uart_port = 2 +uart_type = 4 +uart_tx = port:PA00<2><1> +uart_rx = port:PA01<2><1> +uart_rts = port:PA02<2><1> +uart_cts = port:PA03<2><1> + +[uart3] +uart_used = 0 +uart_port = 3 +uart_type = 2 +uart_tx = port:PA13<3><1> +uart_rx = port:PA14<3><1> +uart_rts = port:PA15<3><1> +uart_cts = port:PA16<3><1> + +;---------------------------------------------------------------------------------- +;SPI controller configuration +;---------------------------------------------------------------------------------- +[spi0] +spi_used = 1 +spi_cs_bitmap = 1 +spi_mosi = port:PC00<3> +spi_miso = port:PC01<3> +spi_sclk = port:PC02<3> +spi_cs0 = port:PC03<3><1> + +[spi1] +spi_used = 0 +spi_cs_bitmap = 1 +spi_cs0 = port:PA13<2><1> +spi_sclk = port:PA14<2> +spi_mosi = port:PA15<2> +spi_miso = port:PA16<2> + +;---------------------------------------------------------------------------------- +;SPI device configuration +;---------------------------------------------------------------------------------- +[spi_devices] +spi_dev_num = 1 + +[spi_board0] +modalias = "spidev" +max_speed_hz = 33000000 +bus_num = 0 +chip_select = 0 +mode = 0 +full_duplex = 1 +manual_cs = 0 + +[leds_para] +leds_used = 1 +red_led = port:PL10<1><0> +red_led_active_low = 1 + +;---------------------------------------------------------------------------------- +;thermal configuration +;ths_trip_count : temperature trigger number +;ths_trip_0 : first temperature trigger +;ths_trip_1 : second temperature trigger +;ths_trip_2 : third temperature trigger, when upto this temperature, system shutdown +;ths_trip_0_min : first temperature trigger's min freq +;ths_trip_0_max : first temperature trigger's max freq +;ths_trip_1_min : second temperature trigger's min freq +;ths_trip_1_max : second temperature trigger's max freq +;---------------------------------------------------------------------------------- +[ths_para] +ths_used = 1 +ths_trip1_count = 8 +ths_trip1_0 = 65 +ths_trip1_1 = 70 +ths_trip1_2 = 75 +ths_trip1_3 = 80 +ths_trip1_4 = 85 +ths_trip1_5 = 90 +ths_trip1_6 = 95 +ths_trip1_7 = 105 +ths_trip1_0_min = 0 +ths_trip1_0_max = 1 +ths_trip1_1_min = 1 +ths_trip1_1_max = 2 +ths_trip1_2_min = 2 +ths_trip1_2_max = 3 +ths_trip1_3_min = 3 +ths_trip1_3_max = 4 +ths_trip1_4_min = 4 +ths_trip1_4_max = 6 +ths_trip1_5_min = 6 +ths_trip1_5_max = 8 +ths_trip1_6_min = 8 +ths_trip1_6_max = 10 +ths_trip1_7_min = 0 +ths_trip1_7_max = 0 +ths_trip2_count = 1 +ths_trip2_0 = 105 + +;---------------------------------------------------------------------------------- +;cooler_table cooler_count <=32 +;---------------------------------------------------------------------------------- +[cooler_table] +cooler_count = 11 +cooler0 = "1200000 4 4294967295 0" +cooler1 = "1008000 4 4294967295 0" +cooler2 = "816000 4 4294967295 0" +cooler3 = "720000 4 4294967295 0" +cooler4 = "648000 4 4294967295 0" +cooler5 = "480000 4 4294967295 0" +cooler6 = "312000 4 4294967295 0" +cooler7 = "240000 4 4294967295 0" +cooler8 = "240000 3 4294967295 0" +cooler9 = "240000 2 4294967295 0" +cooler10 = "240000 1 4294967295 0" + +[nand0_para] +nand_support_2ch = 0 + +nand0_used = 0 +nand0_we = port:PC00<2> +nand0_ale = port:PC01<2> +nand0_cle = port:PC02<2> +nand0_ce1 = port:PC03<2> +nand0_ce0 = port:PC04<2> +nand0_nre = port:PC05<2> +nand0_rb0 = port:PC06<2> +nand0_rb1 = port:PC07<2> +nand0_d0 = port:PC08<2> +nand0_d1 = port:PC09<2> +nand0_d2 = port:PC10<2> +nand0_d3 = port:PC11<2> +nand0_d4 = port:PC12<2> +nand0_d5 = port:PC13<2> +nand0_d6 = port:PC14<2> +nand0_d7 = port:PC15<2> +nand0_ndqs = port:PC16<2> + +;---------------------------------------------------------------------------------- +;disp init configuration +; +;disp_mode (0:screen0; 1:screen1) +;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;) +;screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50) +; (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:PAL 14:NTSC) +;fbx format (0:ARGB 1:ABGR 2:RGBA 3:BGRA 5:RGB565 8:RGB888 12:ARGB4444 16:ARGB1555 18:RGBA5551) +;fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0) +;lcdx_backlight (lcd init backlight,the range:[0,256],default:197 +;---------------------------------------------------------------------------------- +[disp_init] +disp_init_enable = 1 +disp_mode = 0 +screen0_output_type = 3 +screen0_output_mode = 10 +screen1_output_type = 0 +screen1_output_mode = 0 +fb0_format = 0 +fb0_width = 0 +fb0_height = 0 + +fb1_format = 0 +fb1_width = 0 +fb1_height = 0 + +;---------------------------------------------------------------------------------- +;hdmi configuration +;---------------------------------------------------------------------------------- +[hdmi_para] +hdmi_used = 1 +hdmi_power = "vcc-hdmi-18" +hdcp_enable = 0 + +[tv_para] +tv_used = 0 +tv_dac_used = 1 +tv_dac_src0 = 0 + +;---------------------------------------------------------------------------------- +;pwm config +;---------------------------------------------------------------------------------- +[pwm0_para] +pwm_used = 0 +pwm_positive = port:PA05<3><0> + +;------------------------------------------------------------------------------; +; 10/100/100Mbps Ethernet MAC Controller Configure ; +;------------------------------------------------------------------------------; +; Options: ; +; gmac_used --- 0: not used, 1: external phy, 2: internal phy ; +; gmac_powerx -- A[:B] A: axp channel, B: voltage value ; +; If set gamc_phy to use internal PHY, do not config port ; +;------------------------------------------------------------------------------; +; MII RMII MII RMII MII RMII ; +; PD00 * PD06 * * PD12 * * ; +; PD01 * PD07 * PD13 * * ; +; PD02 * * PD08 * PD14 * ; +; PD03 * * PD09 * * PD15 * ; +; PD04 * PD10 * * PD16 * * ; +; PD05 * PD11 * * PD17 * * ; +;------------------------------------------------------------------------------; +[gmac0] +gmac_used = 1 +gmac_rxd3 = port:PD00<2><3> +gmac_rxd2 = port:PD01<2><3> +gmac_rxd1 = port:PD02<2><3> +gmac_rxd0 = port:PD03<2><3> +gmac_rxclk = port:PD04<2><3> +gmac_rxdv = port:PD05<2><3> +;gmac_rxerr = port:PD06<2><3> +gmac_txd3 = port:PD07<2><3> +gmac_txd2 = port:PD08<2><3> +gmac_txd1 = port:PD09<2><3> +gmac_txd0 = port:PD10<2><3> +;gmac_crs = port:PD11<2><3> +gmac_txclk = port:PD12<2><3> +gmac_txen = port:PD13<2><3> +;gmac_txerr = port:PD14<2><3> +gmac_col = port:PD15<2><3> +gmac_mdc = port:PD16<2><3> +gmac_mdio = port:PD17<2><3> +gmac_power1 = + +[gmac_phy_power] +gmac_phy_power_en = port:PD06<1><0> + +;-------------------------------------------------------------------------------- +;vip (video input port) configuration +;vip_used: 0:disable 1:enable +;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer +;vip_dev_qty: The quantity of devices linked to capture bus +; +;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and +; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! +; +;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1, +;vip_dev(x)_pos must be configured! +; +;vip_dev(x)_isp_used 0:not use isp 1:use isp +;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb +;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby +;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable +;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable +;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply +;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply +;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply +;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply +;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply +;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply +;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply +;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply +;x indicates the index of the devices which are linked to the same capture bus +;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 +;fill handle string as below: +;axp22_eldo3 +;axp22_dldo4 +;axp22_eldo2 +;fill handle string "" when not using any pmu power supply +;-------------------------------------------------------------------------------- +[csi0] +vip_used = 0 +vip_mode = 0 +vip_dev_qty = 1 +vip_define_sensor_list = 0 + +vip_csi_pck = port:PE00<2> +vip_csi_mck = port:PE01<2> +vip_csi_hsync = port:PE02<2> +vip_csi_vsync = port:PE03<2> +vip_csi_d0 = port:PE04<2> +vip_csi_d1 = port:PE05<2> +vip_csi_d2 = port:PE06<2> +vip_csi_d3 = port:PE07<2> +vip_csi_d4 = port:PE08<2> +vip_csi_d5 = port:PE09<2> +vip_csi_d6 = port:PE10<2> +vip_csi_d7 = port:PE11<2> +vip_csi_sck = port:PE12<2> +vip_csi_sda = port:PE13<2> + +vip_dev0_mname = "ov5640" +vip_dev0_pos = "rear" +vip_dev0_lane = 4 +vip_dev0_twi_id = 2 +vip_dev0_twi_addr = 0x78 +vip_dev0_isp_used = 1 +vip_dev0_fmt = 1 +vip_dev0_stby_mode = 1 +vip_dev0_vflip = 0 +vip_dev0_hflip = 0 +vip_dev0_iovdd = "" +vip_dev0_iovdd_vol = 2800000 +vip_dev0_avdd = "" +vip_dev0_avdd_vol = 2800000 +vip_dev0_dvdd = "" +vip_dev0_dvdd_vol = 1500000 +vip_dev0_afvdd = "" +vip_dev0_afvdd_vol = 2800000 +vip_dev0_power_en = port:PD14<1> +vip_dev0_reset = port:PE14<1> +vip_dev0_pwdn = port:PE15<1> +vip_dev0_flash_en = +vip_dev0_flash_mode = +vip_dev0_af_pwdn = + +vip_dev0_act_used = 0 +vip_dev0_act_name = "ad5820_act" +vip_dev0_act_slave = 0x18 + + +vip_dev1_mname = "" +vip_dev1_pos = "front" +vip_dev1_lane = 1 +vip_dev1_twi_id = 0 +vip_dev1_twi_addr = +vip_dev1_isp_used = 0 +vip_dev1_fmt = 1 +vip_dev1_stby_mode = 0 +vip_dev1_vflip = 0 +vip_dev1_hflip = 0 +vip_dev1_iovdd = "" +vip_dev1_iovdd_vol = 2800000 +vip_dev1_avdd = "" +vip_dev1_avdd_vol = 2800000 +vip_dev1_dvdd = "" +vip_dev1_dvdd_vol = 1500000 +vip_dev1_afvdd = "" +vip_dev1_afvdd_vol = 2800000 +vip_dev1_power_en = +vip_dev1_reset = +vip_dev1_pwdn = +vip_dev1_flash_en = +vip_dev1_flash_mode = +vip_dev1_af_pwdn = + +;---------------------------------------------------------------------------------- +;Deinterlace configuration +;---------------------------------------------------------------------------------- +[di_para] +di_used = 1 +di_by_pass = 0 + +;-------------------------------------------------------------------------------- +; SDMMC PINS MAPPING | +; ------------------------------------------------------------------------------| +; Config Guide | +; sdc_used: 1-enable card, 0-disable card | +; sdc_detmode: card detect mode | +; 1-detect card by gpio polling | +; 2-detect card by gpio irq(must use IO with irq function) | +; 3-no detect, always in for boot card | +; 4-manually insert and remove by /proc/driver/sunxi-mmc.x/insert| +; sdc_buswidth: card bus width, 1-1bit, 4-4bit, 8-8bit | +; sdc_use_wp: 1-with write protect IO, 0-no write protect IO | +; sdc_isio: for sdio card | +; sdc_regulator: power control.if card supports UHS-I/DDR and HS200 timing for| +; SD3.0 or eMMC4.5, regulator must be configured. the value is | +; the ldo name of AXP221, eg: sdc_regulator = "axp22_eldo2" | +; other: GPIO Mapping configuration | +; ------------------------------------------------------------------------------| +; Note: | +; 1 if detmode=2, sdc_det's config=6 | +; else if detmode=1, sdc_det's config=0 | +; else sdc_det IO is not necessary | +; 2 if the customer wants to support UHS-I and HS200 features, he must provide| +; an independent power supply for the card. This is only used in platforms | +; that supports SD3.0 cards and eMMC4.4+ flashes | +;-------------------------------------------------------------------------------- +[mmc0_para] +sdc_used = 1 +sdc_detmode = 1 +sdc_buswidth = 4 +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_d1 = port:PF00<2><1><2> +sdc_d2 = port:PF05<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_det = port:PF06<0><1><2> +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" + +[mmc1_para] +sdc_used = 1 +sdc_detmode = 4 +sdc_buswidth = 4 +sdc_clk = port:PG00<2><1><3> +sdc_cmd = port:PG01<2><1><3> +sdc_d0 = port:PG02<2><1><3> +sdc_d1 = port:PG03<2><1><3> +sdc_d2 = port:PG04<2><1><3> +sdc_d3 = port:PG05<2><1><3> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 1 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +[mmc2_para] +sdc_used = 1 +sdc_detmode = 1 +sdc_buswidth = 8 +sdc_clk = port:PC05<3><1><2> +sdc_cmd = port:PC06<3><1><2> +sdc_d0 = port:PC08<3><1><2> +sdc_d1 = port:PC09<3><1><2> +sdc_d2 = port:PC10<3><1><2> +sdc_d3 = port:PC11<3><1><2> +sdc_d4 = port:PC12<3><1><2> +sdc_d5 = port:PC13<3><1><2> +sdc_d6 = port:PC14<3><1><2> +sdc_d7 = port:PC15<3><1><2> +emmc_rst = port:PC16<3><1><2> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +; ------------------------------------------------------------------------------| +; sim card configuration +;-------------------------------------------------------------------------------- +[smc_para] +smc_used = 0 +smc_rst = port:PA09<2> +smc_vppen = port:PA20<3> +smc_vppp = port:PA21<3> +smc_det = port:PA10<2> +smc_vccen = port:PA06<2> +smc_sck = port:PA07<2> +smc_sda = port:PA08<2> + + +;-------------------------------- +; [usbc0]: Controller 0 configuration. +; usb used: USB enable flag. Set, indicating that the system USB module is available, is set to 0, it means that the system USB is disabled. +; usb_port_type: USB port usage. 0: device only; 1: host only; 2: OTG +; usb_detect_type: USB port of checking. 0: not detected; 1: vbus / id checks; 2: id / dpdm check +; usb_id_gpio: USB ID pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: USB DET_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_drv_vbus_gpio: USB DRY_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: "axp_ctrl", represents axp offer +; usb_restrict_gpio: usb limiting control pin +; usb_restric_flag: usb limiting standard set +;-------------------------------- +;-------------------------------- +; USB0 OTG +;-------------------------------- +[usbc0] +usb_used = 1 +usb_port_type = 1 +usb_detect_type = 0 +usb_id_gpio = port:PL06<0><1> +usb_det_vbus_gpio = "axp_ctrl" +usb_drv_vbus_gpio = port:PD11<1><0><0> +usb_host_init_state = 1 +usb_restrict_gpio = +usb_restric_flag = 0 +usb_restric_voltage = 3550000 +usb_restric_capacity= 5 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB1 Host +;-------------------------------- +[usbc1] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB2 Host +;-------------------------------- +[usbc2] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB3 Host +;-------------------------------- +[usbc3] +usb_used = 0 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB Device +;-------------------------------- +[usb_feature] +vendor_id = 0x18D1 +mass_storage_id = 0x0001 +adb_id = 0x0002 + +manufacturer_name = "USB Developer" +product_name = "Android" +serial_number = "20080411" + +[msc_feature] +vendor_name = "USB 2.0" +product_name = "USB Flash Driver" +release = 100 +luns = 3 + +[serial_feature] +serial_unique = 0 + + +;-------------------------------------------------------------------------------- +;wifi/bt/fm/gps/nfc modules configuration +;module_power0: axp used by module, "axp22_dldo1" - use dldo1, not use keep it empty +;module_power0_vol: power0 voltage, mv; +;chip_en: enable chip io +;lpo_use_apclk: ""- not use, "losc_out"- a23/33/H3, "ac10032k1"、"ac10032k2"、"ac10032k3"- a80 +;-------------------------------------------------------------------------------- +[module_para] +module_power0 = "vcc-wifi-33" +module_power0_vol = 0 +module_power1 = +module_power1_vol = 1 +module_power2 = +module_power2_vol = +module_power3 = +module_power3_vol = +chip_en = +lpo_use_apclk = "losc_out" + +;-------------------------------------------------------------------------------- +;wifi configuration +;wifi_sdc_id: 0- SDC0, 1- SDC1, 2- SDC2, 3- SDC3 +;wifi_usbc_id: 0- USB0, 1- USB1, 2- USB2 +;wifi_usbc_type: 1- EHCI(speed 2.0), 2- OHCI(speed 1.0) +;wl_reg_on: wifi function enable pin +;wl_host_wake: wlan device wake-up host pin +;wl_host_wake_invert: whether wl_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[wifi_para] +wifi_used = 1 +wifi_sdc_id = 1 +wifi_usbc_id = +wifi_usbc_type = +wl_reg_on = port:PL07<1><0> +wl_host_wake = port:PG10<0><0> +wl_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;bluetooth configuration +;bt_used: 0- no used, 1- used +;bt_uard_id: 0- uart0, 1- uart1, 2- uart2 +;bt_rst_n: bt function enable io +;bt_wake: host wake-up bluetooth device +;bt_host_wake: bt device wake-up host +;bt_host_wake_invert: whether bt_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[bt_para] +bt_used = 1 +bt_uart_id = 1 +bt_uart_baud = 1500000 +bt_rst_n = port:PG12<1><0> +bt_wake = port:PG13<1><0> +bt_host_wake = port:PG11<0><0> +bt_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;daudio_master:1: SND_SOC_DAIFMT_CBM_CFM(codec clk & FRM master) use +; 2: SND_SOC_DAIFMT_CBS_CFM(codec clk slave & FRM master) not use +; 3: SND_SOC_DAIFMT_CBM_CFS(codec clk master & frame slave) not use +; 4: SND_SOC_DAIFMT_CBS_CFS(codec clk & FRM slave) use +;daudio_select:0 is pcm.1 is i2s +;audio_format: 1:SND_SOC_DAIFMT_I2S(standard i2s format). use +; 2:SND_SOC_DAIFMT_RIGHT_J(right justfied format). +; 3:SND_SOC_DAIFMT_LEFT_J(left justfied format) +; 4:SND_SOC_DAIFMT_DSP_A(pcm. MSB is available on 2nd BCLK rising edge after LRC rising edge). use +; 5:SND_SOC_DAIFMT_DSP_B(pcm. MSB is available on 1nd BCLK rising edge after LRC rising edge) +;signal_inversion:1:SND_SOC_DAIFMT_NB_NF(normal bit clock + frame) use +; 2:SND_SOC_DAIFMT_NB_IF(normal BCLK + inv FRM) +; 3:SND_SOC_DAIFMT_IB_NF(invert BCLK + nor FRM) use +; 4:SND_SOC_DAIFMT_IB_IF(invert BCLK + FRM) +;over_sample_rate: support 128fs/192fs/256fs/384fs/512fs/768fs +;sample_resolution :16bits/20bits/24bits +;word_select_size :16bits/20bits/24bits/32bits +;pcm_sync_period :16/32/64/128/256 +;msb_lsb_first :0: msb first; 1: lsb first +;sign_extend :0: zero pending; 1: sign extend +;slot_index :slot index: 0: the 1st slot - 3: the 4th slot +;slot_width :8 bit width / 16 bit width +;frame_width :0: long frame = 2 clock width; 1: short frame +;tx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;rx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;-------------------------------------------------------------------------------- +[pcm0] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PA18<2><1> +i2s_bclk = port:PA19<2><1> +i2s_dout0 = port:PA20<2><1> +i2s_din = port:PA21<2><1> + + +[pcm1] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PG10<2><1> +i2s_bclk = port:PG11<2><1> +i2s_dout0 = port:PG12<2><1> +i2s_din = port:PG13<2><1> + + +[audio0] +audio_used = 0 +lineout_vol = 0x1f +cap_vol = 0x5 +audio_hp_ldo = "none" +adcagc_used = 0 +adcdrc_used = 0 +dacdrc_used = 0 +adchpf_used = 0 +dachpf_used = 0 +audio_pa_ctrl = port:PA16<1><0> + +[spdif0] +spdif_used = 0 +spdif_dout = port:PA17<2><1> + +[audiohub] +hub_used = 0 +codec_used = 1 +spdif_used = 0 +hdmi_used = 1 + +;---------------------------------------------------------------------------------- +;ir rx --- infra remote configuration +;---------------------------------------------------------------------------------- +[s_cir0] +ir_used = 1 +ir_rx = port:PL11<2><1> +ir_power_key_code0 = 0x57 +ir_addr_code0 = 0x9f00 +ir_power_key_code1 = 0x1a +ir_addr_code1 = 0xfb04 +ir_power_key_code2 = 0x14 +ir_addr_code2 = 0x7F80 +ir_power_key_code3 = 0x15 +ir_addr_code3 = 0x7F80 +ir_power_key_code4 = 0x0b +ir_addr_code4 = 0xF708 +ir_power_key_code5 = 0x03 +ir_addr_code5 = 0x00EF +ir_power_key_code6 = 0x9f +ir_addr_code6 = 0x4CB3 +ir_power_key_code7 = 0x0a +ir_addr_code7 = 0x7748 +ir_power_key_code8 = 0x45 +ir_addr_code8 = 0xbd02 +ir_power_key_code9 = 0x4d +ir_addr_code9 = 0xde21 +ir_power_key_code10 = 0x18 +ir_addr_code10 = 0xfe01 +ir_power_key_code11 = 0x57 +ir_addr_code11 = 0xff00 +ir_power_key_code12 = 0x4d +ir_addr_code12 = 0xff40 + +;---------------------------------------------------------------------------------- +;ir tx--- infra remote configuration +;---------------------------------------------------------------------------------- +[cir] +ir_used = 1 +ir_tx = port:PH07<2> + + +;---------------------------------------------------------------------------------- +; dvfs voltage-frequency table configuration +; +; pmuic_type:0:none, 1:gpio, 2:i2c +; pmu_gpio0: gpio config. +; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low. +; +; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk +; 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator +; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz +; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz +; +; LV_count: count of LV_freq/LV_volt, must be < 16 +; +; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz] +; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz] +; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz] +; LV4: core vdd is 1.20v if cpu frequency is (816Mhz, 1008Mhz] +; LV5: core vdd is 1.10v if cpu frequency is (648Mhz, 816Mhz] +; LV6: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV7: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV8: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; +;---------------------------------------------------------------------------------- +[dvfs_table] +pmuic_type = 0 +pmu_gpio0 = port:PL06<1><1><2><1> +pmu_level0 = 11300 +pmu_level1 = 1100 +;extremity_freq = 1296000000 +max_freq = 1200000000 +min_freq = 648000000 +LV_count = 2 +LV1_freq = 1200000000 +LV1_volt = 1300 +LV2_freq = 648000000 +LV2_volt = 1300 + +[gpu_dvfs_table] + +G_LV_count = 3 + +G_LV0_freq = 312000000 +G_LV0_volt = 1200000 + +G_LV1_freq = 384000000 +G_LV1_volt = 1200000 + +G_LV2_freq = 456000000 +G_LV2_volt = 1200000 + +;---------------------------------------------------------------------------------- +;virtual device +;virtual device for pinctrl testing +;device have pin PA1 PA2 +;---------------------------------------------------------------------------------- +[Vdevice] +Vdevice_used = 0 +Vdevice_0 = port:PH10<5><1><2> +Vdevice_1 = port:PH11<5><1><2> + +;---------------------------------------------------------------------------------- +;s_uart0 config parameters +;s_uart_used --s_uart0 whether used for arisc debugging +;---------------------------------------------------------------------------------- +[s_uart0] +s_uart_used = 0 +s_uart_tx = port:PL02<2> +s_uart_rx = port:PL03<2> + +;---------------------------------------------------------------------------------- +;s_rsb0 config parameters +;s_rsb_used --s_rsb0 whether used for arisc +;---------------------------------------------------------------------------------- +[s_rsb0] +s_rsb_used = 1 +s_rsb_sck = port:PL00<2><1><2> +s_rsb_sda = port:PL01<2><1><2> + +;---------------------------------------------------------------------------------- +;s_jtag0 config parameters +;s_jtag0_used --s_jtag0 whether used for arisc +; +;---------------------------------------------------------------------------------- +[s_jtag0] +s_jtag_used = 0 +s_jtag_tms = port:PL04<2><1><2> +s_jtag_tck = port:PL05<2><1><2> +s_jtag_tdo = port:PL06<2><1><2> +s_jtag_tdi = port:PL07<2><1><2> + +;---------------------------------------------------------------------------------- +;s_powchk cpus power check +;s_powchk_used --power check whether used for arisc in super standby +; bit31:enable power updat, bit1:wakeup when power state exception +; bit0:wakeup when power consumption exception +;s_power_reg the expected regs stand for power on/off state +;s_system_power the limit maxmum power consumption when super standby (unit: mw) +; +;---------------------------------------------------------------------------------- +[s_powchk] +s_powchk_used = 0x80000000 +s_power_reg = 0x00000000 +s_system_power = 50 + +;---------------------------------------------------------------------------------- +;scr configuration +;---------------------------------------------------------------------------------- +[sim0] +scr_used = 0 +scr_vccen = port:PA06<2> +scr_slk = port:PA07<2> +scr_sda = port:PA08<2> +scr_rst = port:PA09<2> +scr_det = port:PA10<2> + + +;-------------------------------------------------------------------------------- +;tsc configuration +;-------------------------------------------------------------------------------- +[ts0] +tsc_used = 0 +tsc_clk = port:PE00<3> +tsc_err = port:PE01<3> +tsc_sync = port:PE02<3> +tsc_dvld = port:PE03<3> +tsc_d0 = port:PE04<3> +tsc_d1 = port:PE05<3> +tsc_d2 = port:PE06<3> +tsc_d3 = port:PE07<3> +tsc_d4 = port:PE08<3> +tsc_d5 = port:PE09<3> +tsc_d6 = port:PE10<3> +tsc_d7 = port:PE11<3> + +;-------------------------------------------------------------------------------- +;gpio key +;-------------------------------------------------------------------------------- +[gpio_power_key] +key_used = 1 +key_io = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +; key para +; +; key_used --0:not used, 1:used +; key_cnt --how many key button attach to keyadc. +; key*_vol --the threshold of input voltage of key. +; +; For example: if key2_vol < $(keyadc value) < key3_vol, then key3 be reported. +;---------------------------------------------------------------------------------- +[key_para] +key_used = 0 +key_cnt = 5 +key1_vol = 222 +key2_vol = 444 +key3_vol = 666 +key4_vol = 857 +key5_vol = 2000 + +;---------------------------------------------------------------------------------- +;display seven segment para +;---------------------------------------------------------------------------------- +[d7s_para] +d7s_used = 0 +din_gpio = port:PD00<1><1> +clk_gpio = port:PD01<1><1> +stb_gpio = port:PD02<1><1> + +;---------------------------------------------------------------------------------- +;mali parameters +;---------------------------------------------------------------------------------- +[mali_para] +mali_used = 1 +mali_clkdiv = 1 +mali_extreme_freq = 600 +mali_extreme_vol = 1400 + +;---------------------------------------------------------------------------------- +; 1wire parameters (since pin 37 is not a GPIO but SPDIF instead please choose +; any of the GPIO pins defined above and please don't forget to delete this pin +; from the gpio list to get 1-wire working. PA10 on physical pin 35 is prepared +; below but to work it needs 'w1_used = 1' +;---------------------------------------------------------------------------------- +[w1_para] +w1_used = 0 +gpio = 10 + +[corekeeper] +corekeeper_enabled = 1 diff --git a/projects/H3/sys_config/bx2.fex b/projects/H3/sys_config/bx2.fex new file mode 100755 index 00000000000..39d010805d7 --- /dev/null +++ b/projects/H3/sys_config/bx2.fex @@ -0,0 +1,1070 @@ +[product] +version = "100" +machine = "bx2" + +;--------------------------------------------------------------------------------------------------------- +; eraseflag - 1 erase data partition, 0 - do not erase data partition +; next_work - action after burn, 0x0 by config, 0x1, normal, 0x2 reboot 0x3 ,shutdown,0x4 reupdate ,0x5 boot +;--------------------------------------------------------------------------------------------------------- +[platform] +debug_mode = 1 +eraseflag = 1 +next_work = 2 + +;---------------------------------------------------------------------------------- +;[target] system bootup configuration +;boot_clock = CPU boot frequency, Unit: MHz +;storage_type = boot medium, 0-nand, 1-card0, 2-card2, -1(defualt)auto scan +;---------------------------------------------------------------------------------- +[target] +boot_clock = 1008 +storage_type = -1 + +;--------------------------------------------------------------------------------- +; used : 1: used this config, 0: not +; start_type : 1: start system directly when power supply, 0: wait IR/KEY to power on +; irkey_used : 1: ir key used, 0: not +; pmukey_used: 1: physical button used, 0: not +; led_power : 1: light, 0: off +; led_state : 1: light, 0: off +;--------------------------------------------------------------------------------- +[box_start_os] +used = 1 +start_type = 1 +irkey_used = 1 +pmukey_used = 1 +pmukey_num = 3 +led_power = 0 +led_state = 0 + +;--------------------------------------------------------------------------------------------------------- +; if 1 == standby_mode, then support super standby; +; else, support normal standby. +;--------------------------------------------------------------------------------------------------------- +[pm_para] +standby_mode = 1 + +; THIS PARAMETERS SEEMS TO BE USED ONLY FOR TESTING +[card0_boot_para] +card_ctrl = 0 +card_high_speed = 1 +card_line = 4 +sdc_d1 = port:PF00<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_d2 = port:PF05<2><1><2> + +[twi_para] +twi_port = 0 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[uart_para] +uart_debug_port = 0 +uart_debug_tx = port:PA04<2><1> +uart_debug_rx = port:PA05<2><1> + +[force_uart_para] +force_uart_port = 0 +force_uart_tx = port:PF02<3><1> +force_uart_rx = port:PF04<3><1> + +[jtag_para] +jtag_enable = 0 +jtag_ms = port:PA00<3> +jtag_ck = port:PA01<3> +jtag_do = port:PA02<3> +jtag_di = port:PA03<3> + +[clock] +pll_video = 297 +pll_ve = 402 +pll_periph0 = 600 +pll_gpu = 576 +pll_periph1 = 600 +pll_de = 864 + +;***************************************************************************** +;sdram configuration +; +;dram_para2 = 0x00001200 ;Representative enable dram Dual +;dram_para2 = 0x00001100 ;on behalf of a single channel is enabled dram +;***************************************************************************** +[dram_para] +dram_clk = 624 +dram_type = 3 +dram_zq = 0x3b3bfb +dram_odt_en = 0x1 +dram_para1 = 0x10E40000 +dram_para2 = 0x0000 +dram_mr0 = 0x1840 +dram_mr1 = 0x40 +dram_mr2 = 0x18 +dram_mr3 = 0x2 +dram_tpr0 = 0x0048A192 +dram_tpr1 = 0x01C2418D +dram_tpr2 = 0x00076051 +dram_tpr3 = 0 +dram_tpr4 = 0 +dram_tpr5 = 0 +dram_tpr6 = 100 +dram_tpr7 = 0x93890240 +dram_tpr8 = 0 +dram_tpr9 = 0 +dram_tpr10 = 0 +dram_tpr11 = 0x6aaa0000 +dram_tpr12 = 0x7979 +dram_tpr13 = 0x1802800 + +;--------------------------------------------------------------------------------------------------------- +; wakeup_src_para: +; sometimes, u would like to add more wakeup src in standby mode, these para will be +; help; +; u need to make sure the standby mode support the wakeup src. Also, some hw +; condition must be guaranteed. +; including: +; cpu_en: power on or off. +; 1: mean power on +; 0: mean power off +; cpu_freq: indicating lowest freq. unit is Mhz; +; dram selfresh_en: selfresh or not. +; 1: enable enter selfresh +; 0: disable enter selfresh +; dram_pll: if not enter selfresh, indicating lowest freq. unit is Mhz; +; wakeup_src: to make the scenario work, the wakeup src is needed. +;--------------------------------------------------------------------------------------------------------- +[wakeup_src_para] +cpu_en = 0 +cpu_freq = 48 +pll_ratio = 273 +dram_selfresh_en = 1 +dram_freq = 36 +wakeup_src0 = +wakeup_src_wl = port:PG10<4><0> +wakeup_src_bt = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +;i2c configuration +;---------------------------------------------------------------------------------- +[twi0] +twi_used = 1 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[twi1] +twi_used = 1 +twi_scl = port:PA18<3> +twi_sda = port:PA19<3> + +[twi2] +twi_used = 0 +twi_scl = port:PE12<3> +twi_sda = port:PE13<3> + +;---------------------------------------------------------------------------------- +;uart configuration +;uart_type --- 2 (2 wire), 4 (4 wire), 8 (8 wire, full function) +;---------------------------------------------------------------------------------- +[uart0] +uart_used = 1 +uart_port = 0 +uart_type = 2 +uart_tx = port:PA04<2><1> +uart_rx = port:PA05<2><1> + +[uart1] +uart_used = 0 +uart_port = 1 +uart_type = 2 +uart_tx = port:PG06<2><1> +uart_rx = port:PG07<2><1> +uart_rts = port:PG08<2><1> +uart_cts = port:PG09<2><1> + +[uart2] +uart_used = 0 +uart_port = 2 +uart_type = 4 +uart_tx = port:PA00<2><1> +uart_rx = port:PA01<2><1> +uart_rts = port:PA02<2><1> +uart_cts = port:PA03<2><1> + +[uart3] +uart_used = 0 +uart_port = 3 +uart_type = 2 +uart_tx = port:PA13<3><1> +uart_rx = port:PA14<3><1> +uart_rts = port:PA15<3><1> +uart_cts = port:PA16<3><1> + +;---------------------------------------------------------------------------------- +;SPI controller configuration +;---------------------------------------------------------------------------------- +[spi0] +spi_used = 0 +spi_cs_bitmap = 1 +spi_mosi = port:PC00<3> +spi_miso = port:PC01<3> +spi_sclk = port:PC02<3> +spi_cs0 = port:PC03<3><1> + +[spi1] +spi_used = 0 +spi_cs_bitmap = 1 +spi_cs0 = port:PA13<2><1> +spi_sclk = port:PA14<2> +spi_mosi = port:PA15<2> +spi_miso = port:PA16<2> + +;---------------------------------------------------------------------------------- +;SPI device configuration +;---------------------------------------------------------------------------------- +[spi_devices] +spi_dev_num = 1 + +[spi_board0] +modalias = "m25p32" +max_speed_hz = 33000000 +bus_num = 0 +chip_select = 0 +mode = 0 +full_duplex = 1 +manual_cs = 0 + +[leds_para] +leds_used = 1 +green_led = port:PL10<1><0> +green_led_active_low = 1 +red_led = port:PA15<1><0> +red_led_active_low = 0 + +;---------------------------------------------------------------------------------- +;thermal configuration +;ths_trip_count : temperature trigger number +;ths_trip_0 : first temperature trigger +;ths_trip_1 : second temperature trigger +;ths_trip_2 : third temperature trigger, when upto this temperature, system shutdown +;ths_trip_0_min : first temperature trigger's min freq +;ths_trip_0_max : first temperature trigger's max freq +;ths_trip_1_min : second temperature trigger's min freq +;ths_trip_1_max : second temperature trigger's max freq +;---------------------------------------------------------------------------------- +[ths_para] +ths_used = 1 +ths_trip1_count = 8 +ths_trip1_0 = 65 +ths_trip1_1 = 70 +ths_trip1_2 = 75 +ths_trip1_3 = 80 +ths_trip1_4 = 85 +ths_trip1_5 = 90 +ths_trip1_6 = 95 +ths_trip1_7 = 105 +ths_trip1_0_min = 0 +ths_trip1_0_max = 1 +ths_trip1_1_min = 1 +ths_trip1_1_max = 2 +ths_trip1_2_min = 2 +ths_trip1_2_max = 3 +ths_trip1_3_min = 3 +ths_trip1_3_max = 4 +ths_trip1_4_min = 4 +ths_trip1_4_max = 6 +ths_trip1_5_min = 6 +ths_trip1_5_max = 8 +ths_trip1_6_min = 8 +ths_trip1_6_max = 10 +ths_trip1_7_min = 0 +ths_trip1_7_max = 0 +ths_trip2_count = 1 +ths_trip2_0 = 105 + +;---------------------------------------------------------------------------------- +;cooler_table cooler_count <=32 +;---------------------------------------------------------------------------------- +[cooler_table] +cooler_count = 11 +cooler0 = "1200000 4 4294967295 0" +cooler1 = "1008000 4 4294967295 0" +cooler2 = "816000 4 4294967295 0" +cooler3 = "720000 4 4294967295 0" +cooler4 = "648000 4 4294967295 0" +cooler5 = "480000 4 4294967295 0" +cooler6 = "312000 4 4294967295 0" +cooler7 = "240000 4 4294967295 0" +cooler8 = "240000 3 4294967295 0" +cooler9 = "240000 2 4294967295 0" +cooler10 = "240000 1 4294967295 0" + +[nand0_para] +nand_support_2ch = 0 + +nand0_used = 0 +nand0_we = port:PC00<2> +nand0_ale = port:PC01<2> +nand0_cle = port:PC02<2> +nand0_ce1 = port:PC03<2> +nand0_ce0 = port:PC04<2> +nand0_nre = port:PC05<2> +nand0_rb0 = port:PC06<2> +nand0_rb1 = port:PC07<2> +nand0_d0 = port:PC08<2> +nand0_d1 = port:PC09<2> +nand0_d2 = port:PC10<2> +nand0_d3 = port:PC11<2> +nand0_d4 = port:PC12<2> +nand0_d5 = port:PC13<2> +nand0_d6 = port:PC14<2> +nand0_d7 = port:PC15<2> +nand0_ndqs = port:PC16<2> + +;---------------------------------------------------------------------------------- +;disp init configuration +; +;disp_mode (0:screen0; 1:screen1) +;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;) +;screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50) +; (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:PAL 14:NTSC) +;fbx format (0:ARGB 1:ABGR 2:RGBA 3:BGRA 5:RGB565 8:RGB888 12:ARGB4444 16:ARGB1555 18:RGBA5551) +;fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0) +;lcdx_backlight (lcd init backlight,the range:[0,256],default:197 +;---------------------------------------------------------------------------------- +[disp_init] +disp_init_enable = 1 +disp_mode = 0 +screen0_output_type = 3 +screen0_output_mode = 10 +screen1_output_type = 0 +screen1_output_mode = 0 +fb0_format = 0 +fb0_width = 0 +fb0_height = 0 + +fb1_format = 0 +fb1_width = 0 +fb1_height = 0 + +;---------------------------------------------------------------------------------- +;hdmi configuration +;---------------------------------------------------------------------------------- +[hdmi_para] +hdmi_used = 1 +hdmi_power = "vcc-hdmi-18" +hdcp_enable = 0 + +[tv_para] +tv_used = 0 +tv_dac_used = 1 +tv_dac_src0 = 0 + +;---------------------------------------------------------------------------------- +;pwm config +;---------------------------------------------------------------------------------- +[pwm0_para] +pwm_used = 0 +pwm_positive = port:PA05<3><0> + +;------------------------------------------------------------------------------; +; 10/100/100Mbps Ethernet MAC Controller Configure ; +;------------------------------------------------------------------------------; +; Options: ; +; gmac_used --- 0: not used, 1: external phy, 2: internal phy ; +; gmac_powerx -- A[:B] A: axp channel, B: voltage value ; +; If set gamc_phy to use internal PHY, do not config port ; +;------------------------------------------------------------------------------; +; MII RMII MII RMII MII RMII ; +; PD00 * PD06 * * PD12 * * ; +; PD01 * PD07 * PD13 * * ; +; PD02 * * PD08 * PD14 * ; +; PD03 * * PD09 * * PD15 * ; +; PD04 * PD10 * * PD16 * * ; +; PD05 * PD11 * * PD17 * * ; +;------------------------------------------------------------------------------; +[gmac0] +gmac_used = 2 +gmac_power1 = + +;-------------------------------------------------------------------------------- +;vip (video input port) configuration +;vip_used: 0:disable 1:enable +;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer +;vip_dev_qty: The quantity of devices linked to capture bus +; +;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and +; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! +; +;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1, +;vip_dev(x)_pos must be configured! +; +;vip_dev(x)_isp_used 0:not use isp 1:use isp +;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb +;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby +;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable +;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable +;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply +;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply +;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply +;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply +;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply +;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply +;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply +;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply +;x indicates the index of the devices which are linked to the same capture bus +;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 +;fill handle string as below: +;axp22_eldo3 +;axp22_dldo4 +;axp22_eldo2 +;fill handle string "" when not using any pmu power supply +;-------------------------------------------------------------------------------- +[csi0] +vip_used = 0 +vip_mode = 0 +vip_dev_qty = 1 +vip_define_sensor_list = 0 + +vip_csi_pck = port:PE00<2> +vip_csi_mck = port:PE01<2> +vip_csi_hsync = port:PE02<2> +vip_csi_vsync = port:PE03<2> +vip_csi_d0 = port:PE04<2> +vip_csi_d1 = port:PE05<2> +vip_csi_d2 = port:PE06<2> +vip_csi_d3 = port:PE07<2> +vip_csi_d4 = port:PE08<2> +vip_csi_d5 = port:PE09<2> +vip_csi_d6 = port:PE10<2> +vip_csi_d7 = port:PE11<2> +vip_csi_sck = port:PE12<2> +vip_csi_sda = port:PE13<2> + +vip_dev0_mname = "gc2035" +vip_dev0_pos = "front" +vip_dev0_lane = 1 +vip_dev0_twi_id = 2 +vip_dev0_twi_addr = 0x78 +vip_dev0_isp_used = 0 +vip_dev0_fmt = 0 +vip_dev0_stby_mode = 0 +vip_dev0_vflip = 1 +vip_dev0_hflip = 1 +vip_dev0_iovdd = "" +vip_dev0_iovdd_vol = 2800000 +vip_dev0_avdd = "" +vip_dev0_avdd_vol = 2800000 +vip_dev0_dvdd = "" +vip_dev0_dvdd_vol = 1800000 +vip_dev0_afvdd = "" +vip_dev0_afvdd_vol = 2800000 +vip_dev0_power_en = port:PA17<1><1> +vip_dev0_reset = port:PE14<1><1> +vip_dev0_pwdn = port:PE15<1><0> +vip_dev0_flash_en = +vip_dev0_flash_mode = +vip_dev0_af_pwdn = + +vip_dev0_act_used = 0 +vip_dev0_act_name = "ad5820_act" +vip_dev0_act_slave = 0x18 + + +vip_dev1_mname = "" +vip_dev1_pos = "rear" +vip_dev1_lane = 1 +vip_dev1_twi_id = 0 +vip_dev1_twi_addr = +vip_dev1_isp_used = 0 +vip_dev1_fmt = 1 +vip_dev1_stby_mode = 0 +vip_dev1_vflip = 0 +vip_dev1_hflip = 0 +vip_dev1_iovdd = "" +vip_dev1_iovdd_vol = 2800000 +vip_dev1_avdd = "" +vip_dev1_avdd_vol = 2800000 +vip_dev1_dvdd = "" +vip_dev1_dvdd_vol = 1500000 +vip_dev1_afvdd = "" +vip_dev1_afvdd_vol = 2800000 +vip_dev1_power_en = +vip_dev1_reset = +vip_dev1_pwdn = +vip_dev1_flash_en = +vip_dev1_flash_mode = +vip_dev1_af_pwdn = + +;---------------------------------------------------------------------------------- +;Deinterlace configuration +;---------------------------------------------------------------------------------- +[di_para] +di_used = 1 +di_by_pass = 0 + +;-------------------------------------------------------------------------------- +; SDMMC PINS MAPPING | +; ------------------------------------------------------------------------------| +; Config Guide | +; sdc_used: 1-enable card, 0-disable card | +; sdc_detmode: card detect mode | +; 1-detect card by gpio polling | +; 2-detect card by gpio irq(must use IO with irq function) | +; 3-no detect, always in for boot card | +; 4-manually insert and remove by /proc/driver/sunxi-mmc.x/insert| +; sdc_buswidth: card bus width, 1-1bit, 4-4bit, 8-8bit | +; sdc_use_wp: 1-with write protect IO, 0-no write protect IO | +; sdc_isio: for sdio card | +; sdc_regulator: power control.if card supports UHS-I/DDR and HS200 timing for| +; SD3.0 or eMMC4.5, regulator must be configured. the value is | +; the ldo name of AXP221, eg: sdc_regulator = "axp22_eldo2" | +; other: GPIO Mapping configuration | +; ------------------------------------------------------------------------------| +; Note: | +; 1 if detmode=2, sdc_det's config=6 | +; else if detmode=1, sdc_det's config=0 | +; else sdc_det IO is not necessary | +; 2 if the customer wants to support UHS-I and HS200 features, he must provide| +; an independent power supply for the card. This is only used in platforms | +; that supports SD3.0 cards and eMMC4.4+ flashes | +;-------------------------------------------------------------------------------- +[mmc0_para] +sdc_used = 1 +sdc_detmode = 1 +sdc_buswidth = 4 +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_d1 = port:PF00<2><1><2> +sdc_d2 = port:PF05<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_det = port:PF06<0><1><2> +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" + +[mmc1_para] +sdc_used = 1 +sdc_detmode = 4 +sdc_buswidth = 4 +sdc_clk = port:PG00<2><1><3> +sdc_cmd = port:PG01<2><1><3> +sdc_d0 = port:PG02<2><1><3> +sdc_d1 = port:PG03<2><1><3> +sdc_d2 = port:PG04<2><1><3> +sdc_d3 = port:PG05<2><1><3> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 1 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +[mmc2_para] +sdc_used = 1 +sdc_detmode = 1 +sdc_buswidth = 8 +sdc_clk = port:PC05<3><1><2> +sdc_cmd = port:PC06<3><1><2> +sdc_d0 = port:PC08<3><1><2> +sdc_d1 = port:PC09<3><1><2> +sdc_d2 = port:PC10<3><1><2> +sdc_d3 = port:PC11<3><1><2> +sdc_d4 = port:PC12<3><1><2> +sdc_d5 = port:PC13<3><1><2> +sdc_d6 = port:PC14<3><1><2> +sdc_d7 = port:PC15<3><1><2> +emmc_rst = port:PC16<3><1><2> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +; ------------------------------------------------------------------------------| +; sim card configuration +;-------------------------------------------------------------------------------- +[smc_para] +smc_used = 0 +smc_rst = port:PA09<2> +smc_vppen = port:PA20<3> +smc_vppp = port:PA21<3> +smc_det = port:PA10<2> +smc_vccen = port:PA06<2> +smc_sck = port:PA07<2> +smc_sda = port:PA08<2> + +;-------------------------------- +; [usbc0]: Controller 0 configuration. +; usb used: USB enable flag. Set, indicating that the system USB module is available, is set to 0, it means that the system USB is disabled. +; usb_port_type: USB port usage. 0: device only; 1: host only; 2: OTG +; usb_detect_type: USB port of checking. 0: not detected; 1: vbus / id checks; 2: id / dpdm check +; usb_id_gpio: USB ID pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: USB DET_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_drv_vbus_gpio: USB DRY_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: "axp_ctrl", represents axp offer +; usb_restrict_gpio: usb limiting control pin +; usb_restric_flag: usb limiting standard set +;-------------------------------- +;-------------------------------- +; USB0 OTG +;-------------------------------- +[usbc0] +usb_used = 1 +usb_port_type = 2 +usb_detect_type = 0 +usb_id_gpio = port:PA07<0><1> +usb_det_vbus_gpio = port:PA07<0><1> +usb_drv_vbus_gpio = port:PL02<1><0><0> +usb_host_init_state = 1 +usb_restrict_gpio = +usb_restric_flag = 0 +usb_restric_voltage = 3550000 +usb_restric_capacity= 5 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB1 Host +;-------------------------------- +[usbc1] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB2 Host +;-------------------------------- +[usbc2] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB3 Host +;-------------------------------- +[usbc3] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB Device +;-------------------------------- +[usb_feature] +vendor_id = 0x18D1 +mass_storage_id = 0x0001 +adb_id = 0x0002 + +manufacturer_name = "USB Developer" +product_name = "Android" +serial_number = "20080411" + +[msc_feature] +vendor_name = "USB 2.0" +product_name = "USB Flash Driver" +release = 100 +luns = 3 + +[serial_feature] +serial_unique = 0 + +;-------------------------------------------------------------------------------- +;wifi/bt/fm/gps/nfc modules configuration +;module_power0: axp used by module, "axp22_dldo1" - use dldo1, not use keep it empty +;module_power0_vol: power0 voltage, mv; +;chip_en: enable chip io +;lpo_use_apclk: ""- not use, "losc_out"- a23/33/H3, "ac10032k1"、"ac10032k2"、"ac10032k3"- a80 +;-------------------------------------------------------------------------------- +[module_para] +module_power0 = port:PL07<1><1> +module_power0_vol = 0 +module_power1 = port:PG13<1><0> +module_power1_vol = 1 +module_power2 = +module_power2_vol = +module_power3 = +module_power3_vol = +chip_en = +lpo_use_apclk = "losc_out" + +;-------------------------------------------------------------------------------- +;wifi configuration +;wifi_sdc_id: 0- SDC0, 1- SDC1, 2- SDC2, 3- SDC3 +;wifi_usbc_id: 0- USB0, 1- USB1, 2- USB2 +;wifi_usbc_type: 1- EHCI(speed 2.0), 2- OHCI(speed 1.0) +;wl_reg_on: wifi function enable pin +;wl_host_wake: wlan device wake-up host pin +;wl_host_wake_invert: whether wl_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[wifi_para] +wifi_used = 1 +wifi_sdc_id = 1 +wifi_usbc_id = +wifi_usbc_type = +wl_reg_on = port:PL07<1><0> +wl_host_wake = port:PG10<0><0> +wl_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;bluetooth configuration +;bt_used: 0 - no used, 1- used +;bt_uard_id: 0 - uart0, 1- uart1, 2- uart2 +;bt_rst_n: bt function enable io +;bt_wake: host wake-up bluetooth device +;bt_host_wake: bt device wake-up host +;bt_host_wake_invert: whether bt_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[bt_para] +bt_used = 0 +bt_uart_id = 1 +bt_rst_n = +bt_wake = +bt_host_wake = +bt_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;daudio_master:1: SND_SOC_DAIFMT_CBM_CFM(codec clk & FRM master) use +; 2: SND_SOC_DAIFMT_CBS_CFM(codec clk slave & FRM master) not use +; 3: SND_SOC_DAIFMT_CBM_CFS(codec clk master & frame slave) not use +; 4: SND_SOC_DAIFMT_CBS_CFS(codec clk & FRM slave) use +;daudio_select:0 is pcm.1 is i2s +;audio_format: 1:SND_SOC_DAIFMT_I2S(standard i2s format). use +; 2:SND_SOC_DAIFMT_RIGHT_J(right justfied format). +; 3:SND_SOC_DAIFMT_LEFT_J(left justfied format) +; 4:SND_SOC_DAIFMT_DSP_A(pcm. MSB is available on 2nd BCLK rising edge after LRC rising edge). use +; 5:SND_SOC_DAIFMT_DSP_B(pcm. MSB is available on 1nd BCLK rising edge after LRC rising edge) +;signal_inversion:1:SND_SOC_DAIFMT_NB_NF(normal bit clock + frame) use +; 2:SND_SOC_DAIFMT_NB_IF(normal BCLK + inv FRM) +; 3:SND_SOC_DAIFMT_IB_NF(invert BCLK + nor FRM) use +; 4:SND_SOC_DAIFMT_IB_IF(invert BCLK + FRM) +;over_sample_rate: support 128fs/192fs/256fs/384fs/512fs/768fs +;sample_resolution :16bits/20bits/24bits +;word_select_size :16bits/20bits/24bits/32bits +;pcm_sync_period :16/32/64/128/256 +;msb_lsb_first :0: msb first; 1: lsb first +;sign_extend :0: zero pending; 1: sign extend +;slot_index :slot index: 0: the 1st slot - 3: the 4th slot +;slot_width :8 bit width / 16 bit width +;frame_width :0: long frame = 2 clock width; 1: short frame +;tx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;rx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;-------------------------------------------------------------------------------- +[pcm0] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PA18<2><1> +i2s_bclk = port:PA19<2><1> +i2s_dout0 = port:PA20<2><1> +i2s_din = port:PA21<2><1> + +[pcm1] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PG10<2><1> +i2s_bclk = port:PG11<2><1> +i2s_dout0 = port:PG12<2><1> +i2s_din = port:PG13<2><1> + +[audio0] +audio_used = 1 +lineout_vol = 0x1f +cap_vol = 0x5 +audio_hp_ldo = "none" +adcagc_used = 0 +adcdrc_used = 0 +dacdrc_used = 0 +adchpf_used = 0 +dachpf_used = 0 +audio_pa_ctrl = port:PA16<1><0> + +[spdif0] +spdif_used = 1 +spdif_dout = port:PA17<2><1> + +[audiohub] +hub_used = 1 +codec_used = 1 +spdif_used = 1 +hdmi_used = 1 + +;---------------------------------------------------------------------------------- +;ir rx --- infra remote configuration +;---------------------------------------------------------------------------------- +[s_cir0] +ir_used = 1 +ir_rx = port:PL11<2><1> +ir_power_key_code0 = 0x57 +ir_addr_code0 = 0x9f00 +ir_power_key_code1 = 0x1a +ir_addr_code1 = 0xfb04 +ir_power_key_code2 = 0x14 +ir_addr_code2 = 0x7F80 +ir_power_key_code3 = 0x51 +ir_addr_code3 = 0x7F80 +ir_power_key_code4 = 0x0b +ir_addr_code4 = 0xF708 +ir_power_key_code5 = 0x03 +ir_addr_code5 = 0x00EF +ir_power_key_code6 = 0x9f +ir_addr_code6 = 0x4CB3 +ir_power_key_code7 = 0x0a +ir_addr_code7 = 0x7748 +ir_power_key_code8 = 0x45 +ir_addr_code8 = 0xbd02 +ir_power_key_code9 = 0x4d +ir_addr_code9 = 0xde21 +ir_power_key_code10 = 0x18 +ir_addr_code10 = 0xfe01 +ir_power_key_code11 = 0x57 +ir_addr_code11 = 0xff00 +ir_power_key_code12 = 0x4d +ir_addr_code12 = 0xff40 +ir_power_key_code13 = 0x88 +ir_addr_code13 = 0xdd22 + +;---------------------------------------------------------------------------------- +;ir tx--- infra remote configuration +;---------------------------------------------------------------------------------- +[cir] +ir_used = 1 +ir_tx = port:PH07<2> + +;---------------------------------------------------------------------------------- +; dvfs voltage-frequency table configuration +; +; pmuic_type:0:none, 1:gpio, 2:i2c +; pmu_gpio0: gpio config. +; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low. +; +; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk +; 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator +; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz +; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz +; +; LV_count: count of LV_freq/LV_volt, must be < 16 +; +; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz] +; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz] +; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz] +; LV4: core vdd is 1.20v if cpu frequency is (816Mhz, 1008Mhz] +; LV5: core vdd is 1.10v if cpu frequency is (648Mhz, 816Mhz] +; LV6: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV7: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV8: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; +;---------------------------------------------------------------------------------- +[dvfs_table] +pmuic_type = 0 +pmu_gpio0 = port:PL06<1><1><2><1> +pmu_level0 = 11300 +pmu_level1 = 1100 +;extremity_freq = 1296000000 +max_freq = 1200000000 +min_freq = 648000000 +LV_count = 2 +LV1_freq = 1200000000 +LV1_volt = 1300 +LV2_freq = 648000000 +LV2_volt = 1300 + +[gpu_dvfs_table] +G_LV_count = 3 +G_LV0_freq = 312000000 +G_LV0_volt = 1200000 +G_LV1_freq = 384000000 +G_LV1_volt = 1200000 +G_LV2_freq = 456000000 +G_LV2_volt = 1200000 + +;---------------------------------------------------------------------------------- +;virtual device +;virtual device for pinctrl testing +;device have pin PA1 PA2 +;---------------------------------------------------------------------------------- +[Vdevice] +Vdevice_used = 0 +Vdevice_0 = port:PH10<5><1><2> +Vdevice_1 = port:PH11<5><1><2> + +;---------------------------------------------------------------------------------- +;s_uart0 config parameters +;s_uart_used --s_uart0 whether used for arisc debugging +;---------------------------------------------------------------------------------- +[s_uart0] +s_uart_used = 0 +s_uart_tx = port:PL02<2> +s_uart_rx = port:PL03<2> + +;---------------------------------------------------------------------------------- +;s_rsb0 config parameters +;s_rsb_used --s_rsb0 whether used for arisc +;---------------------------------------------------------------------------------- +[s_rsb0] +s_rsb_used = 1 +s_rsb_sck = port:PL00<2><1><2> +s_rsb_sda = port:PL01<2><1><2> + +;---------------------------------------------------------------------------------- +;s_jtag0 config parameters +;s_jtag0_used --s_jtag0 whether used for arisc +; +;---------------------------------------------------------------------------------- +[s_jtag0] +s_jtag_used = 0 +s_jtag_tms = port:PL04<2><1><2> +s_jtag_tck = port:PL05<2><1><2> +s_jtag_tdo = port:PL06<2><1><2> +s_jtag_tdi = port:PL07<2><1><2> + +;---------------------------------------------------------------------------------- +;s_powchk cpus power check +;s_powchk_used --power check whether used for arisc in super standby +; bit31:enable power updat, bit1:wakeup when power state exception +; bit0:wakeup when power consumption exception +;s_power_reg the expected regs stand for power on/off state +;s_system_power the limit maxmum power consumption when super standby (unit: mw) +; +;---------------------------------------------------------------------------------- +[s_powchk] +s_powchk_used = 0x80000000 +s_power_reg = 0x00000000 +s_system_power = 50 + +;---------------------------------------------------------------------------------- +;scr configuration +;---------------------------------------------------------------------------------- +[sim0] +scr_used = 0 +scr_vccen = port:PA06<2> +scr_slk = port:PA07<2> +scr_sda = port:PA08<2> +scr_rst = port:PA09<2> +scr_det = port:PA10<2> + +;-------------------------------------------------------------------------------- +;tsc configuration +;-------------------------------------------------------------------------------- +[ts0] +tsc_used = 0 +tsc_clk = port:PE00<3> +tsc_err = port:PE01<3> +tsc_sync = port:PE02<3> +tsc_dvld = port:PE03<3> +tsc_d0 = port:PE04<3> +tsc_d1 = port:PE05<3> +tsc_d2 = port:PE06<3> +tsc_d3 = port:PE07<3> +tsc_d4 = port:PE08<3> +tsc_d5 = port:PE09<3> +tsc_d6 = port:PE10<3> +tsc_d7 = port:PE11<3> + +;-------------------------------------------------------------------------------- +;gpio key +;-------------------------------------------------------------------------------- +[gpio_power_key] +key_used = 1 +key_io = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +; key para +; +; key_used --0:not used, 1:used +; key_cnt --how many key button attach to keyadc. +; key*_vol --the threshold of input voltage of key. +; +; For example: if key2_vol < $(keyadc value) < key3_vol, then key3 be reported. +;---------------------------------------------------------------------------------- +[key_para] +key_used = 0 +key_cnt = 5 +key1_vol = 222 +key2_vol = 444 +key3_vol = 666 +key4_vol = 857 +key5_vol = 2000 + +;---------------------------------------------------------------------------------- +;display seven segment para +;---------------------------------------------------------------------------------- +[d7s_para] +d7s_used = 0 +din_gpio = port:PD00<1><1> +clk_gpio = port:PD01<1><1> +stb_gpio = port:PD02<1><1> + +;---------------------------------------------------------------------------------- +;mali parameters +;---------------------------------------------------------------------------------- +[mali_para] +mali_used = 1 +mali_clkdiv = 1 +mali_extreme_freq = 600 +mali_extreme_vol = 1400 + +;---------------------------------------------------------------------------------- +;1wire parameters (default - PA20) +;---------------------------------------------------------------------------------- +[w1_para] +w1_used = 0 +gpio = 20 diff --git a/projects/H3/sys_config/opi2.fex b/projects/H3/sys_config/opi2.fex new file mode 100755 index 00000000000..56c356943b3 --- /dev/null +++ b/projects/H3/sys_config/opi2.fex @@ -0,0 +1,1075 @@ +[product] +version = "100" +machine = "opi2" + +;--------------------------------------------------------------------------------------------------------- +; eraseflag - 1 erase data partition, 0 - do not erase data partition +; next_work - action after burn, 0x0 by config, 0x1, normal, 0x2 reboot 0x3 ,shutdown,0x4 reupdate ,0x5 boot +;--------------------------------------------------------------------------------------------------------- +[platform] +debug_mode = 1 +eraseflag = 1 +next_work = 2 + +;---------------------------------------------------------------------------------- +;[target] system bootup configuration +;boot_clock = CPU boot frequency, Unit: MHz +;storage_type = boot medium, 0-nand, 1-card0, 2-card2, -1(defualt)auto scan +;---------------------------------------------------------------------------------- +[target] +boot_clock = 1008 +storage_type = -1 + +;--------------------------------------------------------------------------------- +; used : 1: used this config, 0: not +; start_type : 1: start system directly when power supply, 0: wait IR/KEY to power on +; irkey_used : 1: ir key used, 0: not +; pmukey_used: 1: physical button used, 0: not +; led_power : 1: light, 0: off +; led_state : 1: light, 0: off +;--------------------------------------------------------------------------------- +[box_start_os] +used = 1 +start_type = 1 +irkey_used = 1 +pmukey_used = 1 +pmukey_num = 3 +led_power = 0 +led_state = 0 + +;--------------------------------------------------------------------------------------------------------- +; if 1 == standby_mode, then support super standby; +; else, support normal standby. +;--------------------------------------------------------------------------------------------------------- +[pm_para] +standby_mode = 1 + +; THIS PARAMETERS SEEMS TO BE USED ONLY FOR TESTING +[card0_boot_para] +card_ctrl = 0 +card_high_speed = 1 +card_line = 4 +sdc_d1 = port:PF00<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_d2 = port:PF05<2><1><2> + +[twi_para] +twi_port = 0 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[uart_para] +uart_debug_port = 0 +uart_debug_tx = port:PA04<2><1> +uart_debug_rx = port:PA05<2><1> + +[force_uart_para] +force_uart_port = 0 +force_uart_tx = port:PF02<3><1> +force_uart_rx = port:PF04<3><1> + +[jtag_para] +jtag_enable = 0 +jtag_ms = port:PA00<3> +jtag_ck = port:PA01<3> +jtag_do = port:PA02<3> +jtag_di = port:PA03<3> + +[clock] +pll_video = 297 +pll_ve = 402 +pll_periph0 = 600 +pll_gpu = 576 +pll_periph1 = 600 +pll_de = 864 + +;***************************************************************************** +;sdram configuration +; +;dram_para2 = 0x00001200 ;Representative enable dram Dual +;dram_para2 = 0x00001100 ;on behalf of a single channel is enabled dram +;***************************************************************************** +[dram_para] +dram_clk = 624 +dram_type = 3 +dram_zq = 0x3b3bfb +dram_odt_en = 0x1 +dram_para1 = 0x10E40000 +dram_para2 = 0x0000 +dram_mr0 = 0x1840 +dram_mr1 = 0x40 +dram_mr2 = 0x18 +dram_mr3 = 0x2 +dram_tpr0 = 0x0048A192 +dram_tpr1 = 0x01C2418D +dram_tpr2 = 0x00076051 +dram_tpr3 = 0 +dram_tpr4 = 0 +dram_tpr5 = 0 +dram_tpr6 = 100 +dram_tpr7 = 0 +dram_tpr8 = 0 +dram_tpr9 = 0 +dram_tpr10 = 0 +dram_tpr11 = 0x6aaa0000 +dram_tpr12 = 0x7979 +dram_tpr13 = 0x800800 + +;--------------------------------------------------------------------------------------------------------- +; wakeup_src_para: +; sometimes, u would like to add more wakeup src in standby mode, these para will be +; help; +; u need to make sure the standby mode support the wakeup src. Also, some hw +; condition must be guaranteed. +; including: +; cpu_en: power on or off. +; 1: mean power on +; 0: mean power off +; cpu_freq: indicating lowest freq. unit is Mhz; +; dram selfresh_en: selfresh or not. +; 1: enable enter selfresh +; 0: disable enter selfresh +; dram_pll: if not enter selfresh, indicating lowest freq. unit is Mhz; +; wakeup_src: to make the scenario work, the wakeup src is needed. +;--------------------------------------------------------------------------------------------------------- +[wakeup_src_para] +cpu_en = 0 +cpu_freq = 48 +; (cpu:apb:ahb) +pll_ratio = 273 +dram_selfresh_en = 1 +dram_freq = 36 +wakeup_src0 = +wakeup_src_wl = port:PG10<4><0> +wakeup_src_bt = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +;i2c configuration +;---------------------------------------------------------------------------------- +[twi0] +twi_used = 1 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[twi1] +twi_used = 0 +twi_scl = port:PA18<3> +twi_sda = port:PA19<3> + +[twi2] +twi_used = 0 +twi_scl = port:PE12<3> +twi_sda = port:PE13<3> + +;---------------------------------------------------------------------------------- +;uart configuration +;uart_type --- 2 (2 wire), 4 (4 wire), 8 (8 wire, full function) +;---------------------------------------------------------------------------------- +[uart0] +uart_used = 1 +uart_port = 0 +uart_type = 2 +uart_tx = port:PA04<2><1> +uart_rx = port:PA05<2><1> + +[uart1] +uart_used = 0 +uart_port = 1 +uart_type = 2 +uart_tx = port:PG06<2><1> +uart_rx = port:PG07<2><1> +uart_rts = port:PG08<2><1> +uart_cts = port:PG09<2><1> + +[uart2] +uart_used = 0 +uart_port = 2 +uart_type = 4 +uart_tx = port:PA00<2><1> +uart_rx = port:PA01<2><1> +uart_rts = port:PA02<2><1> +uart_cts = port:PA03<2><1> + +[uart3] +uart_used = 0 +uart_port = 3 +uart_type = 2 +uart_tx = port:PA13<3><1> +uart_rx = port:PA14<3><1> +uart_rts = port:PA15<3><1> +uart_cts = port:PA16<3><1> + +;---------------------------------------------------------------------------------- +;SPI controller configuration +;---------------------------------------------------------------------------------- +[spi0] +spi_used = 1 +spi_cs_bitmap = 1 +spi_mosi = port:PC00<3> +spi_miso = port:PC01<3> +spi_sclk = port:PC02<3> +spi_cs0 = port:PC03<3><1> + +[spi1] +spi_used = 0 +spi_cs_bitmap = 1 +spi_cs0 = port:PA13<2><1> +spi_sclk = port:PA14<2> +spi_mosi = port:PA15<2> +spi_miso = port:PA16<2> + +;---------------------------------------------------------------------------------- +;SPI device configuration +;---------------------------------------------------------------------------------- +[spi_devices] +spi_dev_num = 1 + +[spi_board0] +modalias = "spidev" +max_speed_hz = 33000000 +bus_num = 0 +chip_select = 0 +mode = 0 +full_duplex = 1 +manual_cs = 0 + +[leds_para] +leds_used = 1 +green_led = port:PL10<1><0> +green_led_active_low = 1 +red_led = port:PA15<1><0> +red_led_active_low = 0 + +;---------------------------------------------------------------------------------- +;thermal configuration +;ths_trip_count : temperature trigger number +;ths_trip_0 : first temperature trigger +;ths_trip_1 : second temperature trigger +;ths_trip_2 : third temperature trigger, when upto this temperature, system shutdown +;ths_trip_0_min : first temperature trigger's min freq +;ths_trip_0_max : first temperature trigger's max freq +;ths_trip_1_min : second temperature trigger's min freq +;ths_trip_1_max : second temperature trigger's max freq +;---------------------------------------------------------------------------------- +[ths_para] +ths_used = 1 +ths_trip1_count = 6 +ths_trip1_0 = 75 +ths_trip1_1 = 80 +ths_trip1_2 = 85 +ths_trip1_3 = 90 +ths_trip1_4 = 95 +ths_trip1_5 = 105 +ths_trip1_6 = 0 +ths_trip1_7 = 0 +ths_trip1_0_min = 0 +ths_trip1_0_max = 1 +ths_trip1_1_min = 1 +ths_trip1_1_max = 2 +ths_trip1_2_min = 2 +ths_trip1_2_max = 3 +ths_trip1_3_min = 3 +ths_trip1_3_max = 4 +ths_trip1_4_min = 4 +ths_trip1_4_max = 8 +ths_trip1_5_min = 8 +ths_trip1_5_max = 8 +ths_trip1_6_min = 0 +ths_trip1_6_max = 0 +ths_trip2_count = 1 +ths_trip2_0 = 105 + +;---------------------------------------------------------------------------------- +;cooler_table cooler_count <=32 +;---------------------------------------------------------------------------------- +[cooler_table] +cooler_count = 9 +cooler0 = "1296000 4 4294967295 0" +cooler1 = "1200000 4 4294967295 0" +cooler2 = "1008000 4 4294967295 0" +cooler3 = "816000 4 4294967295 0" +cooler4 = "648000 4 4294967295 0" +cooler5 = "480000 4 4294967295 0" +cooler6 = "480000 3 4294967295 0" +cooler7 = "480000 2 4294967295 0" +cooler8 = "480000 1 4294967295 0" + +[nand0_para] +nand_support_2ch = 0 + +nand0_used = 0 +nand0_we = port:PC00<2> +nand0_ale = port:PC01<2> +nand0_cle = port:PC02<2> +nand0_ce1 = port:PC03<2> +nand0_ce0 = port:PC04<2> +nand0_nre = port:PC05<2> +nand0_rb0 = port:PC06<2> +nand0_rb1 = port:PC07<2> +nand0_d0 = port:PC08<2> +nand0_d1 = port:PC09<2> +nand0_d2 = port:PC10<2> +nand0_d3 = port:PC11<2> +nand0_d4 = port:PC12<2> +nand0_d5 = port:PC13<2> +nand0_d6 = port:PC14<2> +nand0_d7 = port:PC15<2> +nand0_ndqs = port:PC16<2> + +;---------------------------------------------------------------------------------- +;disp init configuration +; +;disp_mode (0:screen0; 1:screen1) +;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;) +;screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50) +; (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:PAL 14:NTSC) +;fbx format (0:ARGB 1:ABGR 2:RGBA 3:BGRA 5:RGB565 8:RGB888 12:ARGB4444 16:ARGB1555 18:RGBA5551) +;fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0) +;lcdx_backlight (lcd init backlight,the range:[0,256],default:197 +;---------------------------------------------------------------------------------- +[disp_init] +disp_init_enable = 1 +disp_mode = 0 +screen0_output_type = 3 +screen0_output_mode = 10 +screen1_output_type = 0 +screen1_output_mode = 0 +fb0_format = 0 +fb0_width = 0 +fb0_height = 0 + +fb1_format = 0 +fb1_width = 0 +fb1_height = 0 + +;---------------------------------------------------------------------------------- +;hdmi configuration +;---------------------------------------------------------------------------------- +[hdmi_para] +hdmi_used = 1 +hdmi_power = "vcc-hdmi-18" +hdcp_enable = 0 + +[tv_para] +tv_used = 0 +tv_dac_used = 1 +tv_dac_src0 = 0 + +;---------------------------------------------------------------------------------- +;pwm config +;---------------------------------------------------------------------------------- +[pwm0_para] +pwm_used = 0 +pwm_positive = port:PA05<3><0> + +;------------------------------------------------------------------------------; +; 10/100/100Mbps Ethernet MAC Controller Configure ; +;------------------------------------------------------------------------------; +; Options: ; +; gmac_used --- 0: not used, 1: external phy, 2: internal phy ; +; gmac_powerx -- A[:B] A: axp channel, B: voltage value ; +; If set gamc_phy to use internal PHY, do not config port ; +;------------------------------------------------------------------------------; +; MII RMII MII RMII MII RMII ; +; PD00 * PD06 * * PD12 * * ; +; PD01 * PD07 * PD13 * * ; +; PD02 * * PD08 * PD14 * ; +; PD03 * * PD09 * * PD15 * ; +; PD04 * PD10 * * PD16 * * ; +; PD05 * PD11 * * PD17 * * ; +;------------------------------------------------------------------------------; +[gmac0] +gmac_used = 2 +gmac_power1 = + +;-------------------------------------------------------------------------------- +;vip (video input port) configuration +;vip_used: 0:disable 1:enable +;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer +;vip_dev_qty: The quantity of devices linked to capture bus +; +;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and +; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! +; +;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1, +;vip_dev(x)_pos must be configured! +; +;vip_dev(x)_isp_used 0:not use isp 1:use isp +;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb +;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby +;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable +;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable +;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply +;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply +;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply +;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply +;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply +;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply +;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply +;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply +;x indicates the index of the devices which are linked to the same capture bus +;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 +;fill handle string as below: +;axp22_eldo3 +;axp22_dldo4 +;axp22_eldo2 +;fill handle string "" when not using any pmu power supply +;-------------------------------------------------------------------------------- +[csi0] +vip_used = 0 +vip_mode = 0 +vip_dev_qty = 1 +vip_define_sensor_list = 0 + +vip_csi_pck = port:PE00<2> +vip_csi_mck = port:PE01<2> +vip_csi_hsync = port:PE02<2> +vip_csi_vsync = port:PE03<2> +vip_csi_d0 = port:PE04<2> +vip_csi_d1 = port:PE05<2> +vip_csi_d2 = port:PE06<2> +vip_csi_d3 = port:PE07<2> +vip_csi_d4 = port:PE08<2> +vip_csi_d5 = port:PE09<2> +vip_csi_d6 = port:PE10<2> +vip_csi_d7 = port:PE11<2> +vip_csi_sck = port:PE12<2> +vip_csi_sda = port:PE13<2> + +vip_dev0_mname = "gc2035" +vip_dev0_pos = "front" +vip_dev0_lane = 1 +vip_dev0_twi_id = 2 +vip_dev0_twi_addr = 0x78 +vip_dev0_isp_used = 0 +vip_dev0_fmt = 0 +vip_dev0_stby_mode = 0 +vip_dev0_vflip = 1 +vip_dev0_hflip = 1 +vip_dev0_iovdd = "" +vip_dev0_iovdd_vol = 2800000 +vip_dev0_avdd = "" +vip_dev0_avdd_vol = 2800000 +vip_dev0_dvdd = "" +vip_dev0_dvdd_vol = 1800000 +vip_dev0_afvdd = "" +vip_dev0_afvdd_vol = 2800000 +vip_dev0_power_en = port:PA17<1><1> +vip_dev0_reset = port:PE14<1><1> +vip_dev0_pwdn = port:PE15<1><0> +vip_dev0_flash_en = +vip_dev0_flash_mode = +vip_dev0_af_pwdn = + +vip_dev0_act_used = 0 +vip_dev0_act_name = "ad5820_act" +vip_dev0_act_slave = 0x18 + + +vip_dev1_mname = "" +vip_dev1_pos = "rear" +vip_dev1_lane = 1 +vip_dev1_twi_id = 0 +vip_dev1_twi_addr = +vip_dev1_isp_used = 0 +vip_dev1_fmt = 1 +vip_dev1_stby_mode = 0 +vip_dev1_vflip = 0 +vip_dev1_hflip = 0 +vip_dev1_iovdd = "" +vip_dev1_iovdd_vol = 2800000 +vip_dev1_avdd = "" +vip_dev1_avdd_vol = 2800000 +vip_dev1_dvdd = "" +vip_dev1_dvdd_vol = 1500000 +vip_dev1_afvdd = "" +vip_dev1_afvdd_vol = 2800000 +vip_dev1_power_en = +vip_dev1_reset = +vip_dev1_pwdn = +vip_dev1_flash_en = +vip_dev1_flash_mode = +vip_dev1_af_pwdn = + +;---------------------------------------------------------------------------------- +;Deinterlace configuration +;---------------------------------------------------------------------------------- +[di_para] +di_used = 1 +di_by_pass = 0 + +;-------------------------------------------------------------------------------- +; SDMMC PINS MAPPING | +; ------------------------------------------------------------------------------| +; Config Guide | +; sdc_used: 1-enable card, 0-disable card | +; sdc_detmode: card detect mode | +; 1-detect card by gpio polling | +; 2-detect card by gpio irq(must use IO with irq function) | +; 3-no detect, always in for boot card | +; 4-manually insert and remove by /proc/driver/sunxi-mmc.x/insert| +; sdc_buswidth: card bus width, 1-1bit, 4-4bit, 8-8bit | +; sdc_use_wp: 1-with write protect IO, 0-no write protect IO | +; sdc_isio: for sdio card | +; sdc_regulator: power control.if card supports UHS-I/DDR and HS200 timing for| +; SD3.0 or eMMC4.5, regulator must be configured. the value is | +; the ldo name of AXP221, eg: sdc_regulator = "axp22_eldo2" | +; other: GPIO Mapping configuration | +; ------------------------------------------------------------------------------| +; Note: | +; 1 if detmode=2, sdc_det's config=6 | +; else if detmode=1, sdc_det's config=0 | +; else sdc_det IO is not necessary | +; 2 if the customer wants to support UHS-I and HS200 features, he must provide| +; an independent power supply for the card. This is only used in platforms | +; that supports SD3.0 cards and eMMC4.4+ flashes | +;-------------------------------------------------------------------------------- +[mmc0_para] +sdc_used = 1 +sdc_detmode = 3 +sdc_buswidth = 4 +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_d1 = port:PF00<2><1><2> +sdc_d2 = port:PF05<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_det = port:PF06<0><1><2> +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" + +[mmc1_para] +sdc_used = 1 +sdc_detmode = 4 +sdc_buswidth = 4 +sdc_clk = port:PG00<2><1><3> +sdc_cmd = port:PG01<2><1><3> +sdc_d0 = port:PG02<2><1><3> +sdc_d1 = port:PG03<2><1><3> +sdc_d2 = port:PG04<2><1><3> +sdc_d3 = port:PG05<2><1><3> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 1 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +[mmc2_para] +sdc_used = 0 +sdc_detmode = 3 +sdc_buswidth = 8 +sdc_clk = port:PC05<3><1><2> +sdc_cmd = port:PC06<3><1><2> +sdc_d0 = port:PC08<3><1><2> +sdc_d1 = port:PC09<3><1><2> +sdc_d2 = port:PC10<3><1><2> +sdc_d3 = port:PC11<3><1><2> +sdc_d4 = port:PC12<3><1><2> +sdc_d5 = port:PC13<3><1><2> +sdc_d6 = port:PC14<3><1><2> +sdc_d7 = port:PC15<3><1><2> +emmc_rst = port:PC16<3><1><2> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +; ------------------------------------------------------------------------------| +; sim card configuration +;-------------------------------------------------------------------------------- +[smc_para] +smc_used = 0 +smc_rst = port:PA09<2> +smc_vppen = port:PA20<3> +smc_vppp = port:PA21<3> +smc_det = port:PA10<2> +smc_vccen = port:PA06<2> +smc_sck = port:PA07<2> +smc_sda = port:PA08<2> + +;-------------------------------- +; [usbc0]: Controller 0 configuration. +; usb used: USB enable flag. Set, indicating that the system USB module is available, is set to 0, it means that the system USB is disabled. +; usb_port_type: USB port usage. 0: device only; 1: host only; 2: OTG +; usb_detect_type: USB port of checking. 0: not detected; 1: vbus / id checks; 2: id / dpdm check +; usb_id_gpio: USB ID pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: USB DET_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_drv_vbus_gpio: USB DRY_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: "axp_ctrl", represents axp offer +; usb_restrict_gpio: usb limiting control pin +; usb_restric_flag: usb limiting standard set +;-------------------------------- +;-------------------------------- +; USB0 OTG +;-------------------------------- +[usbc0] +usb_used = 1 +usb_port_type = 2 +usb_detect_type = 0 +usb_id_gpio = port:PG12<0><1> +usb_det_vbus_gpio = port:PG12<0><1> +usb_drv_vbus_gpio = port:PL02<1><0><0> +usb_host_init_state = 1 +usb_restrict_gpio = +usb_restric_flag = 0 +usb_restric_voltage = 3550000 +usb_restric_capacity= 5 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB1 Host +;-------------------------------- +[usbc1] +usb_used = 1 +usb_drv_vbus_gpio = port:PG13<1><0><0> +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB2 Host +;-------------------------------- +[usbc2] +usb_used = 0 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB3 Host +;-------------------------------- +[usbc3] +usb_used = 0 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 0 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB Device +;-------------------------------- +[usb_feature] +vendor_id = 0x18D1 +mass_storage_id = 0x0001 +adb_id = 0x0002 + +manufacturer_name = "USB Developer" +product_name = "Android" +serial_number = "20080411" + +[msc_feature] +vendor_name = "USB 2.0" +product_name = "USB Flash Driver" +release = 100 +luns = 3 + +[serial_feature] +serial_unique = 0 + +;-------------------------------------------------------------------------------- +;wifi/bt/fm/gps/nfc modules configuration +;module_power0: axp used by module, "axp22_dldo1" - use dldo1, not use keep it empty +;module_power0_vol: power0 voltage, mv; +;chip_en: enable chip io +;lpo_use_apclk: ""- not use, "losc_out"- a23/33/H3, "ac10032k1"、"ac10032k2"、"ac10032k3"- a80 +;-------------------------------------------------------------------------------- +[module_para] +module_power0 = "vcc-wifi-33" +module_power0_vol = 0 +module_power1 = +module_power1_vol = +module_power2 = +module_power2_vol = +module_power3 = +module_power3_vol = +chip_en = +lpo_use_apclk = + +;-------------------------------------------------------------------------------- +;wifi configuration +;wifi_sdc_id: 0- SDC0, 1- SDC1, 2- SDC2, 3- SDC3 +;wifi_usbc_id: 0- USB0, 1- USB1, 2- USB2 +;wifi_usbc_type: 1- EHCI(speed 2.0), 2- OHCI(speed 1.0) +;wl_reg_on: wifi function enable pin +;wl_host_wake: wlan device wake-up host pin +;wl_host_wake_invert: whether wl_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[wifi_para] +wifi_used = 1 +wifi_sdc_id = 1 +wifi_usbc_id = +wifi_usbc_type = +wl_reg_on = port:PL07<1><0> +wl_host_wake = port:PG10<0><0> +wl_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;bluetooth configuration +;bt_used: 0 - no used, 1- used +;bt_uard_id: 0 - uart0, 1- uart1, 2- uart2 +;bt_rst_n: bt function enable io +;bt_wake: host wake-up bluetooth device +;bt_host_wake: bt device wake-up host +;bt_host_wake_invert: whether bt_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[bt_para] +bt_used = 0 +bt_uart_id = 1 +bt_rst_n = +bt_wake = +bt_host_wake = +bt_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;daudio_master:1: SND_SOC_DAIFMT_CBM_CFM(codec clk & FRM master) use +; 2: SND_SOC_DAIFMT_CBS_CFM(codec clk slave & FRM master) not use +; 3: SND_SOC_DAIFMT_CBM_CFS(codec clk master & frame slave) not use +; 4: SND_SOC_DAIFMT_CBS_CFS(codec clk & FRM slave) use +;daudio_select:0 is pcm.1 is i2s +;audio_format: 1:SND_SOC_DAIFMT_I2S(standard i2s format). use +; 2:SND_SOC_DAIFMT_RIGHT_J(right justfied format). +; 3:SND_SOC_DAIFMT_LEFT_J(left justfied format) +; 4:SND_SOC_DAIFMT_DSP_A(pcm. MSB is available on 2nd BCLK rising edge after LRC rising edge). use +; 5:SND_SOC_DAIFMT_DSP_B(pcm. MSB is available on 1nd BCLK rising edge after LRC rising edge) +;signal_inversion:1:SND_SOC_DAIFMT_NB_NF(normal bit clock + frame) use +; 2:SND_SOC_DAIFMT_NB_IF(normal BCLK + inv FRM) +; 3:SND_SOC_DAIFMT_IB_NF(invert BCLK + nor FRM) use +; 4:SND_SOC_DAIFMT_IB_IF(invert BCLK + FRM) +;over_sample_rate: support 128fs/192fs/256fs/384fs/512fs/768fs +;sample_resolution :16bits/20bits/24bits +;word_select_size :16bits/20bits/24bits/32bits +;pcm_sync_period :16/32/64/128/256 +;msb_lsb_first :0: msb first; 1: lsb first +;sign_extend :0: zero pending; 1: sign extend +;slot_index :slot index: 0: the 1st slot - 3: the 4th slot +;slot_width :8 bit width / 16 bit width +;frame_width :0: long frame = 2 clock width; 1: short frame +;tx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;rx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;-------------------------------------------------------------------------------- +[pcm0] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PA18<2><1> +i2s_bclk = port:PA19<2><1> +i2s_dout0 = port:PA20<2><1> +i2s_din = port:PA21<2><1> + +[pcm1] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PG10<2><1> +i2s_bclk = port:PG11<2><1> +i2s_dout0 = port:PG12<2><1> +i2s_din = port:PG13<2><1> + +[audio0] +audio_used = 1 +lineout_vol = 0x1f +cap_vol = 0x5 +audio_hp_ldo = "none" +adcagc_used = 0 +adcdrc_used = 0 +dacdrc_used = 0 +adchpf_used = 0 +dachpf_used = 0 +audio_pa_ctrl = port:PA16<1><0> + +[spdif0] +spdif_used = 0 +spdif_dout = port:PA17<2><1> + +[audiohub] +hub_used = 1 +codec_used = 1 +spdif_used = 0 +hdmi_used = 1 + +;---------------------------------------------------------------------------------- +;ir rx --- infra remote configuration +;---------------------------------------------------------------------------------- +[s_cir0] +ir_used = 1 +ir_rx = port:PL11<2><1> +ir_power_key_code0 = 0x57 +ir_addr_code0 = 0x9f00 +ir_power_key_code1 = 0x1a +ir_addr_code1 = 0xfb04 +ir_power_key_code2 = 0x14 +ir_addr_code2 = 0x7F80 +ir_power_key_code3 = 0x15 +ir_addr_code3 = 0x7F80 +ir_power_key_code4 = 0x0b +ir_addr_code4 = 0xF708 +ir_power_key_code5 = 0x03 +ir_addr_code5 = 0x00EF +ir_power_key_code6 = 0x9f +ir_addr_code6 = 0x4CB3 +ir_power_key_code7 = 0x0a +ir_addr_code7 = 0x7748 +ir_power_key_code8 = 0x45 +ir_addr_code8 = 0xbd02 +ir_power_key_code9 = 0x4d +ir_addr_code9 = 0xde21 +ir_power_key_code10 = 0x18 +ir_addr_code10 = 0xfe01 +ir_power_key_code11 = 0x57 +ir_addr_code11 = 0xff00 +ir_power_key_code12 = 0x4d +ir_addr_code12 = 0xff40 + +;---------------------------------------------------------------------------------- +;ir tx--- infra remote configuration +;---------------------------------------------------------------------------------- +[cir] +ir_used = 1 +ir_tx = port:PH07<2> + +;---------------------------------------------------------------------------------- +; dvfs voltage-frequency table configuration +; +; pmuic_type:0:none, 1:gpio, 2:i2c +; pmu_gpio0: gpio config. +; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low. +; +; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk +; 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator +; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz +; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz +; +; LV_count: count of LV_freq/LV_volt, must be < 16 +; +; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz] +; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz] +; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz] +; LV4: core vdd is 1.20v if cpu frequency is (816Mhz, 1008Mhz] +; LV5: core vdd is 1.10v if cpu frequency is (648Mhz, 816Mhz] +; LV6: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV7: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV8: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; +;---------------------------------------------------------------------------------- +[dvfs_table] +pmuic_type = 2 +pmu_gpio0 = port:PL06<1><1><2><1> +pmu_level0 = 11300 +pmu_level1 = 1100 +extremity_freq = 1296000000 +max_freq = 1200000000 +min_freq = 480000000 +LV_count = 7 +LV1_freq = 1296000000 +LV1_volt = 1320 +LV2_freq = 1200000000 +LV2_volt = 1240 +LV3_freq = 1104000000 +LV3_volt = 1180 +LV4_freq = 1008000000 +LV4_volt = 1140 +LV5_freq = 960000000 +LV5_volt = 1080 +LV6_freq = 816000000 +LV6_volt = 1020 +LV7_freq = 480000000 +LV7_volt = 980 + +[gpu_dvfs_table] +G_LV_count = 3 +G_LV0_freq = 312000000 +G_LV0_volt = 1200000 +G_LV1_freq = 384000000 +G_LV1_volt = 1200000 +G_LV2_freq = 456000000 +G_LV2_volt = 1200000 + +;---------------------------------------------------------------------------------- +;virtual device +;virtual device for pinctrl testing +;device have pin PA1 PA2 +;---------------------------------------------------------------------------------- +[Vdevice] +Vdevice_used = 0 +Vdevice_0 = port:PH10<5><1><2> +Vdevice_1 = port:PH11<5><1><2> + +;---------------------------------------------------------------------------------- +;s_uart0 config parameters +;s_uart_used --s_uart0 whether used for arisc debugging +;---------------------------------------------------------------------------------- +[s_uart0] +s_uart_used = 0 +s_uart_tx = port:PL02<2> +s_uart_rx = port:PL03<2> + +;---------------------------------------------------------------------------------- +;s_rsb0 config parameters +;s_rsb_used --s_rsb0 whether used for arisc +;---------------------------------------------------------------------------------- +[s_rsb0] +s_rsb_used = 1 +s_rsb_sck = port:PL00<2><1><2> +s_rsb_sda = port:PL01<2><1><2> + +;---------------------------------------------------------------------------------- +;s_jtag0 config parameters +;s_jtag0_used --s_jtag0 whether used for arisc +; +;---------------------------------------------------------------------------------- +[s_jtag0] +s_jtag_used = 0 +s_jtag_tms = port:PL04<2><1><2> +s_jtag_tck = port:PL05<2><1><2> +s_jtag_tdo = port:PL06<2><1><2> +s_jtag_tdi = port:PL07<2><1><2> + +;---------------------------------------------------------------------------------- +;s_powchk cpus power check +;s_powchk_used --power check whether used for arisc in super standby +; bit31:enable power updat, bit1:wakeup when power state exception +; bit0:wakeup when power consumption exception +;s_power_reg the expected regs stand for power on/off state +;s_system_power the limit maxmum power consumption when super standby (unit: mw) +; +;---------------------------------------------------------------------------------- +[s_powchk] +s_powchk_used = 0x80000000 +s_power_reg = 0x00000000 +s_system_power = 50 + +;---------------------------------------------------------------------------------- +;scr configuration +;---------------------------------------------------------------------------------- +[sim0] +scr_used = 0 +scr_vccen = port:PA06<2> +scr_slk = port:PA07<2> +scr_sda = port:PA08<2> +scr_rst = port:PA09<2> +scr_det = port:PA10<2> + +;-------------------------------------------------------------------------------- +;tsc configuration +;-------------------------------------------------------------------------------- +[ts0] +tsc_used = 0 +tsc_clk = port:PE00<3> +tsc_err = port:PE01<3> +tsc_sync = port:PE02<3> +tsc_dvld = port:PE03<3> +tsc_d0 = port:PE04<3> +tsc_d1 = port:PE05<3> +tsc_d2 = port:PE06<3> +tsc_d3 = port:PE07<3> +tsc_d4 = port:PE08<3> +tsc_d5 = port:PE09<3> +tsc_d6 = port:PE10<3> +tsc_d7 = port:PE11<3> + +;-------------------------------------------------------------------------------- +;gpio key +;-------------------------------------------------------------------------------- +[gpio_power_key] +key_used = 1 +key_io = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +; key para +; +; key_used --0:not used, 1:used +; key_cnt --how many key button attach to keyadc. +; key*_vol --the threshold of input voltage of key. +; +; For example: if key2_vol < $(keyadc value) < key3_vol, then key3 be reported. +;---------------------------------------------------------------------------------- +[key_para] +key_used = 0 +key_cnt = 5 +key1_vol = 222 +key2_vol = 444 +key3_vol = 666 +key4_vol = 857 +key5_vol = 2000 + +;---------------------------------------------------------------------------------- +;display seven segment para +;---------------------------------------------------------------------------------- +[d7s_para] +d7s_used = 0 +din_gpio = port:PD00<1><1> +clk_gpio = port:PD01<1><1> +stb_gpio = port:PD02<1><1> + +;---------------------------------------------------------------------------------- +;mali parameters +;---------------------------------------------------------------------------------- +[mali_para] +mali_used = 1 +mali_clkdiv = 1 +mali_extreme_freq = 600 +mali_extreme_vol = 1400 + +;---------------------------------------------------------------------------------- +;1wire parameters (default - PA20) +;---------------------------------------------------------------------------------- +[w1_para] +w1_used = 1 +gpio = 20 diff --git a/projects/H3/sys_config/opilite.fex b/projects/H3/sys_config/opilite.fex new file mode 100755 index 00000000000..a8e75bf0d7c --- /dev/null +++ b/projects/H3/sys_config/opilite.fex @@ -0,0 +1,1068 @@ +[product] +version = "100" +machine = "opilite" + +;--------------------------------------------------------------------------------------------------------- +; eraseflag - 1 erase data partition, 0 - do not erase data partition +; next_work - action after burn, 0x0 by config, 0x1, normal, 0x2 reboot 0x3 ,shutdown,0x4 reupdate ,0x5 boot +;--------------------------------------------------------------------------------------------------------- +[platform] +debug_mode = 1 +eraseflag = 1 +next_work = 2 + +;---------------------------------------------------------------------------------- +;[target] system bootup configuration +;boot_clock = CPU boot frequency, Unit: MHz +;storage_type = boot medium, 0-nand, 1-card0, 2-card2, -1(defualt)auto scan +;---------------------------------------------------------------------------------- +[target] +boot_clock = 1008 +storage_type = -1 + +;--------------------------------------------------------------------------------- +; used : 1: used this config, 0: not +; start_type : 1: start system directly when power supply, 0: wait IR/KEY to power on +; irkey_used : 1: ir key used, 0: not +; pmukey_used: 1: physical button used, 0: not +; led_power : 1: light, 0: off +; led_state : 1: light, 0: off +;--------------------------------------------------------------------------------- +[box_start_os] +used = 1 +start_type = 1 +irkey_used = 1 +pmukey_used = 1 +pmukey_num = 3 +led_power = 0 +led_state = 0 + +;--------------------------------------------------------------------------------------------------------- +; if 1 == standby_mode, then support super standby; +; else, support normal standby. +;--------------------------------------------------------------------------------------------------------- +[pm_para] +standby_mode = 1 + +; THIS PARAMETERS SEEMS TO BE USED ONLY FOR TESTING +[card0_boot_para] +card_ctrl = 0 +card_high_speed = 1 +card_line = 4 +sdc_d1 = port:PF00<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_d2 = port:PF05<2><1><2> + +[twi_para] +twi_port = 0 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[uart_para] +uart_debug_port = 0 +uart_debug_tx = port:PA04<2><1> +uart_debug_rx = port:PA05<2><1> + +[force_uart_para] +force_uart_port = 0 +force_uart_tx = port:PF02<3><1> +force_uart_rx = port:PF04<3><1> + +[jtag_para] +jtag_enable = 0 +jtag_ms = port:PA00<3> +jtag_ck = port:PA01<3> +jtag_do = port:PA02<3> +jtag_di = port:PA03<3> + +[clock] +pll_video = 297 +pll_ve = 402 +pll_periph0 = 600 +pll_gpu = 576 +pll_periph1 = 600 +pll_de = 864 + +;***************************************************************************** +;sdram configuration +; +;dram_para2 = 0x00001200 ;Representative enable dram Dual +;dram_para2 = 0x00001100 ;on behalf of a single channel is enabled dram +;***************************************************************************** +[dram_para] +dram_clk = 624 +dram_type = 3 +dram_zq = 0x3b3bfb +dram_odt_en = 0x1 +dram_para1 = 0x10E40000 +dram_para2 = 0x0000 +dram_mr0 = 0x1840 +dram_mr1 = 0x40 +dram_mr2 = 0x18 +dram_mr3 = 0x2 +dram_tpr0 = 0x0048A192 +dram_tpr1 = 0x01C2418D +dram_tpr2 = 0x00076051 +dram_tpr3 = 0 +dram_tpr4 = 0 +dram_tpr5 = 0 +dram_tpr6 = 100 +dram_tpr7 = 0 +dram_tpr8 = 0 +dram_tpr9 = 0 +dram_tpr10 = 0 +dram_tpr11 = 0x6aaa0000 +dram_tpr12 = 0x7979 +dram_tpr13 = 0x800800 + +;--------------------------------------------------------------------------------------------------------- +; wakeup_src_para: +; sometimes, u would like to add more wakeup src in standby mode, these para will be +; help; +; u need to make sure the standby mode support the wakeup src. Also, some hw +; condition must be guaranteed. +; including: +; cpu_en: power on or off. +; 1: mean power on +; 0: mean power off +; cpu_freq: indicating lowest freq. unit is Mhz; +; dram selfresh_en: selfresh or not. +; 1: enable enter selfresh +; 0: disable enter selfresh +; dram_pll: if not enter selfresh, indicating lowest freq. unit is Mhz; +; wakeup_src: to make the scenario work, the wakeup src is needed. +;--------------------------------------------------------------------------------------------------------- +[wakeup_src_para] +cpu_en = 0 +cpu_freq = 48 +pll_ratio = 273 +dram_selfresh_en = 1 +dram_freq = 36 +wakeup_src0 = +wakeup_src_wl = port:PG10<4><0> +wakeup_src_bt = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +;i2c configuration +;---------------------------------------------------------------------------------- +[twi0] +twi_used = 1 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[twi1] +twi_used = 0 +twi_scl = port:PA18<3> +twi_sda = port:PA19<3> + +[twi2] +twi_used = 0 +twi_scl = port:PE12<3> +twi_sda = port:PE13<3> + +;---------------------------------------------------------------------------------- +;uart configuration +;uart_type --- 2 (2 wire), 4 (4 wire), 8 (8 wire, full function) +;---------------------------------------------------------------------------------- +[uart0] +uart_used = 1 +uart_port = 0 +uart_type = 2 +uart_tx = port:PA04<2><1> +uart_rx = port:PA05<2><1> + +[uart1] +uart_used = 0 +uart_port = 1 +uart_type = 2 +uart_tx = port:PG06<2><1> +uart_rx = port:PG07<2><1> +uart_rts = port:PG08<2><1> +uart_cts = port:PG09<2><1> + +[uart2] +uart_used = 0 +uart_port = 2 +uart_type = 4 +uart_tx = port:PA00<2><1> +uart_rx = port:PA01<2><1> +uart_rts = port:PA02<2><1> +uart_cts = port:PA03<2><1> + +[uart3] +uart_used = 0 +uart_port = 3 +uart_type = 2 +uart_tx = port:PA13<3><1> +uart_rx = port:PA14<3><1> +uart_rts = port:PA15<3><1> +uart_cts = port:PA16<3><1> + +;---------------------------------------------------------------------------------- +;SPI controller configuration +;---------------------------------------------------------------------------------- +[spi0] +spi_used = 1 +spi_cs_bitmap = 1 +spi_mosi = port:PC00<3> +spi_miso = port:PC01<3> +spi_sclk = port:PC02<3> +spi_cs0 = port:PC03<3><1> + +[spi1] +spi_used = 0 +spi_cs_bitmap = 1 +spi_cs0 = port:PA13<2><1> +spi_sclk = port:PA14<2> +spi_mosi = port:PA15<2> +spi_miso = port:PA16<2> + +;---------------------------------------------------------------------------------- +;SPI device configuration +;---------------------------------------------------------------------------------- +[spi_devices] +spi_dev_num = 1 + +[spi_board0] +modalias = "spidev" +max_speed_hz = 33000000 +bus_num = 0 +chip_select = 0 +mode = 0 +full_duplex = 1 +manual_cs = 0 + +[leds_para] +leds_used = 1 +green_led = port:PL10<1><0> +green_led_active_low = 1 +red_led = port:PA15<1><0> +red_led_active_low = 0 + +;---------------------------------------------------------------------------------- +;thermal configuration +;ths_trip_count : temperature trigger number +;ths_trip_0 : first temperature trigger +;ths_trip_1 : second temperature trigger +;ths_trip_2 : third temperature trigger, when upto this temperature, system shutdown +;ths_trip_0_min : first temperature trigger's min freq +;ths_trip_0_max : first temperature trigger's max freq +;ths_trip_1_min : second temperature trigger's min freq +;ths_trip_1_max : second temperature trigger's max freq +;---------------------------------------------------------------------------------- +[ths_para] +ths_used = 1 +ths_trip1_count = 6 +ths_trip1_0 = 75 +ths_trip1_1 = 80 +ths_trip1_2 = 85 +ths_trip1_3 = 90 +ths_trip1_4 = 95 +ths_trip1_5 = 105 +ths_trip1_6 = 0 +ths_trip1_7 = 0 +ths_trip1_0_min = 0 +ths_trip1_0_max = 1 +ths_trip1_1_min = 1 +ths_trip1_1_max = 2 +ths_trip1_2_min = 2 +ths_trip1_2_max = 3 +ths_trip1_3_min = 3 +ths_trip1_3_max = 4 +ths_trip1_4_min = 4 +ths_trip1_4_max = 5 +ths_trip1_5_min = 5 +ths_trip1_5_max = 7 +ths_trip1_6_min = 0 +ths_trip1_6_max = 0 +ths_trip2_count = 1 +ths_trip2_0 = 105 + +;---------------------------------------------------------------------------------- +;cooler_table cooler_count <=32 +;---------------------------------------------------------------------------------- +[cooler_table] +cooler_count = 8 +cooler0 = "1200000 4 4294967295 0" +cooler1 = "912000 4 4294967295 0" +cooler2 = "768000 4 4294967295 0" +cooler3 = "648000 4 4294967295 0" +cooler4 = "480000 4 4294967295 0" +cooler5 = "480000 3 4294967295 0" +cooler6 = "480000 2 4294967295 0" +cooler7 = "480000 1 4294967295 0" + +[nand0_para] +nand_support_2ch = 0 + +nand0_used = 0 +nand0_we = port:PC00<2> +nand0_ale = port:PC01<2> +nand0_cle = port:PC02<2> +nand0_ce1 = port:PC03<2> +nand0_ce0 = port:PC04<2> +nand0_nre = port:PC05<2> +nand0_rb0 = port:PC06<2> +nand0_rb1 = port:PC07<2> +nand0_d0 = port:PC08<2> +nand0_d1 = port:PC09<2> +nand0_d2 = port:PC10<2> +nand0_d3 = port:PC11<2> +nand0_d4 = port:PC12<2> +nand0_d5 = port:PC13<2> +nand0_d6 = port:PC14<2> +nand0_d7 = port:PC15<2> +nand0_ndqs = port:PC16<2> + +;---------------------------------------------------------------------------------- +;disp init configuration +; +;disp_mode (0:screen0; 1:screen1) +;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;) +;screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50) +; (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:PAL 14:NTSC) +;fbx format (0:ARGB 1:ABGR 2:RGBA 3:BGRA 5:RGB565 8:RGB888 12:ARGB4444 16:ARGB1555 18:RGBA5551) +;fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0) +;lcdx_backlight (lcd init backlight,the range:[0,256],default:197 +;---------------------------------------------------------------------------------- +[disp_init] +disp_init_enable = 1 +disp_mode = 0 +screen0_output_type = 3 +screen0_output_mode = 10 +screen1_output_type = 0 +screen1_output_mode = 0 +fb0_format = 0 +fb0_width = 0 +fb0_height = 0 + +fb1_format = 0 +fb1_width = 0 +fb1_height = 0 + +;---------------------------------------------------------------------------------- +;hdmi configuration +;---------------------------------------------------------------------------------- +[hdmi_para] +hdmi_used = 1 +hdmi_power = "vcc-hdmi-18" +hdcp_enable = 0 + +[tv_para] +tv_used = 0 +tv_dac_used = 1 +tv_dac_src0 = 0 + +;---------------------------------------------------------------------------------- +;pwm config +;---------------------------------------------------------------------------------- +[pwm0_para] +pwm_used = 0 +pwm_positive = port:PA05<3><0> + +;------------------------------------------------------------------------------; +; 10/100/100Mbps Ethernet MAC Controller Configure ; +;------------------------------------------------------------------------------; +; Options: ; +; gmac_used --- 0: not used, 1: external phy, 2: internal phy ; +; gmac_powerx -- A[:B] A: axp channel, B: voltage value ; +; If set gamc_phy to use internal PHY, do not config port ; +;------------------------------------------------------------------------------; +; MII RMII MII RMII MII RMII ; +; PD00 * PD06 * * PD12 * * ; +; PD01 * PD07 * PD13 * * ; +; PD02 * * PD08 * PD14 * ; +; PD03 * * PD09 * * PD15 * ; +; PD04 * PD10 * * PD16 * * ; +; PD05 * PD11 * * PD17 * * ; +;------------------------------------------------------------------------------; +[gmac0] +gmac_used = 2 +gmac_power1 = + +;-------------------------------------------------------------------------------- +;vip (video input port) configuration +;vip_used: 0:disable 1:enable +;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer +;vip_dev_qty: The quantity of devices linked to capture bus +; +;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and +; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! +; +;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1, +;vip_dev(x)_pos must be configured! +; +;vip_dev(x)_isp_used 0:not use isp 1:use isp +;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb +;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby +;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable +;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable +;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply +;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply +;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply +;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply +;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply +;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply +;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply +;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply +;x indicates the index of the devices which are linked to the same capture bus +;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 +;fill handle string as below: +;axp22_eldo3 +;axp22_dldo4 +;axp22_eldo2 +;fill handle string "" when not using any pmu power supply +;-------------------------------------------------------------------------------- +[csi0] +vip_used = 0 +vip_mode = 0 +vip_dev_qty = 1 +vip_define_sensor_list = 0 + +vip_csi_pck = port:PE00<2> +vip_csi_mck = port:PE01<2> +vip_csi_hsync = port:PE02<2> +vip_csi_vsync = port:PE03<2> +vip_csi_d0 = port:PE04<2> +vip_csi_d1 = port:PE05<2> +vip_csi_d2 = port:PE06<2> +vip_csi_d3 = port:PE07<2> +vip_csi_d4 = port:PE08<2> +vip_csi_d5 = port:PE09<2> +vip_csi_d6 = port:PE10<2> +vip_csi_d7 = port:PE11<2> +vip_csi_sck = port:PE12<2> +vip_csi_sda = port:PE13<2> + +vip_dev0_mname = "gc2035" +vip_dev0_pos = "front" +vip_dev0_lane = 1 +vip_dev0_twi_id = 2 +vip_dev0_twi_addr = 0x78 +vip_dev0_isp_used = 0 +vip_dev0_fmt = 0 +vip_dev0_stby_mode = 0 +vip_dev0_vflip = 1 +vip_dev0_hflip = 1 +vip_dev0_iovdd = "" +vip_dev0_iovdd_vol = 2800000 +vip_dev0_avdd = "" +vip_dev0_avdd_vol = 2800000 +vip_dev0_dvdd = "" +vip_dev0_dvdd_vol = 1800000 +vip_dev0_afvdd = "" +vip_dev0_afvdd_vol = 2800000 +vip_dev0_power_en = port:PA17<1><1> +vip_dev0_reset = port:PE14<1><1> +vip_dev0_pwdn = port:PE15<1><0> +vip_dev0_flash_en = +vip_dev0_flash_mode = +vip_dev0_af_pwdn = + +vip_dev0_act_used = 0 +vip_dev0_act_name = "ad5820_act" +vip_dev0_act_slave = 0x18 + + +vip_dev1_mname = "" +vip_dev1_pos = "rear" +vip_dev1_lane = 1 +vip_dev1_twi_id = 0 +vip_dev1_twi_addr = +vip_dev1_isp_used = 0 +vip_dev1_fmt = 1 +vip_dev1_stby_mode = 0 +vip_dev1_vflip = 0 +vip_dev1_hflip = 0 +vip_dev1_iovdd = "" +vip_dev1_iovdd_vol = 2800000 +vip_dev1_avdd = "" +vip_dev1_avdd_vol = 2800000 +vip_dev1_dvdd = "" +vip_dev1_dvdd_vol = 1500000 +vip_dev1_afvdd = "" +vip_dev1_afvdd_vol = 2800000 +vip_dev1_power_en = +vip_dev1_reset = +vip_dev1_pwdn = +vip_dev1_flash_en = +vip_dev1_flash_mode = +vip_dev1_af_pwdn = + +;---------------------------------------------------------------------------------- +;Deinterlace configuration +;---------------------------------------------------------------------------------- +[di_para] +di_used = 1 +di_by_pass = 0 + +;-------------------------------------------------------------------------------- +; SDMMC PINS MAPPING | +; ------------------------------------------------------------------------------| +; Config Guide | +; sdc_used: 1-enable card, 0-disable card | +; sdc_detmode: card detect mode | +; 1-detect card by gpio polling | +; 2-detect card by gpio irq(must use IO with irq function) | +; 3-no detect, always in for boot card | +; 4-manually insert and remove by /proc/driver/sunxi-mmc.x/insert| +; sdc_buswidth: card bus width, 1-1bit, 4-4bit, 8-8bit | +; sdc_use_wp: 1-with write protect IO, 0-no write protect IO | +; sdc_isio: for sdio card | +; sdc_regulator: power control.if card supports UHS-I/DDR and HS200 timing for| +; SD3.0 or eMMC4.5, regulator must be configured. the value is | +; the ldo name of AXP221, eg: sdc_regulator = "axp22_eldo2" | +; other: GPIO Mapping configuration | +; ------------------------------------------------------------------------------| +; Note: | +; 1 if detmode=2, sdc_det's config=6 | +; else if detmode=1, sdc_det's config=0 | +; else sdc_det IO is not necessary | +; 2 if the customer wants to support UHS-I and HS200 features, he must provide| +; an independent power supply for the card. This is only used in platforms | +; that supports SD3.0 cards and eMMC4.4+ flashes | +;-------------------------------------------------------------------------------- +[mmc0_para] +sdc_used = 1 +sdc_detmode = 3 +sdc_buswidth = 4 +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_d1 = port:PF00<2><1><2> +sdc_d2 = port:PF05<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_det = port:PF06<0><1><2> +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" + +[mmc1_para] +sdc_used = 1 +sdc_detmode = 4 +sdc_buswidth = 4 +sdc_clk = port:PG00<2><1><3> +sdc_cmd = port:PG01<2><1><3> +sdc_d0 = port:PG02<2><1><3> +sdc_d1 = port:PG03<2><1><3> +sdc_d2 = port:PG04<2><1><3> +sdc_d3 = port:PG05<2><1><3> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 1 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +[mmc2_para] +sdc_used = 0 +sdc_detmode = 3 +sdc_buswidth = 8 +sdc_clk = port:PC05<3><1><2> +sdc_cmd = port:PC06<3><1><2> +sdc_d0 = port:PC08<3><1><2> +sdc_d1 = port:PC09<3><1><2> +sdc_d2 = port:PC10<3><1><2> +sdc_d3 = port:PC11<3><1><2> +sdc_d4 = port:PC12<3><1><2> +sdc_d5 = port:PC13<3><1><2> +sdc_d6 = port:PC14<3><1><2> +sdc_d7 = port:PC15<3><1><2> +emmc_rst = port:PC16<3><1><2> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +; ------------------------------------------------------------------------------| +; sim card configuration +;-------------------------------------------------------------------------------- +[smc_para] +smc_used = 0 +smc_rst = port:PA09<2> +smc_vppen = port:PA20<3> +smc_vppp = port:PA21<3> +smc_det = port:PA10<2> +smc_vccen = port:PA06<2> +smc_sck = port:PA07<2> +smc_sda = port:PA08<2> + +;-------------------------------- +; [usbc0]: Controller 0 configuration. +; usb used: USB enable flag. Set, indicating that the system USB module is available, is set to 0, it means that the system USB is disabled. +; usb_port_type: USB port usage. 0: device only; 1: host only; 2: OTG +; usb_detect_type: USB port of checking. 0: not detected; 1: vbus / id checks; 2: id / dpdm check +; usb_id_gpio: USB ID pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: USB DET_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_drv_vbus_gpio: USB DRY_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: "axp_ctrl", represents axp offer +; usb_restrict_gpio: usb limiting control pin +; usb_restric_flag: usb limiting standard set +;-------------------------------- +;-------------------------------- +; USB0 OTG +;-------------------------------- +[usbc0] +usb_used = 1 +usb_port_type = 2 +usb_detect_type = 0 +usb_id_gpio = port:PG12<0><1> +usb_det_vbus_gpio = port:PG12<0><1> +usb_drv_vbus_gpio = port:PL02<1><0><0> +usb_host_init_state = 1 +usb_restrict_gpio = +usb_restric_flag = 0 +usb_restric_voltage = 3550000 +usb_restric_capacity= 5 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB1 Host +;-------------------------------- +[usbc1] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB2 Host +;-------------------------------- +[usbc2] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB3 Host +;-------------------------------- +[usbc3] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB Device +;-------------------------------- +[usb_feature] +vendor_id = 0x18D1 +mass_storage_id = 0x0001 +adb_id = 0x0002 + +manufacturer_name = "USB Developer" +product_name = "Android" +serial_number = "20080411" + +[msc_feature] +vendor_name = "USB 2.0" +product_name = "USB Flash Driver" +release = 100 +luns = 3 + +[serial_feature] +serial_unique = 0 + +;-------------------------------------------------------------------------------- +;wifi/bt/fm/gps/nfc modules configuration +;module_power0: axp used by module, "axp22_dldo1" - use dldo1, not use keep it empty +;module_power0_vol: power0 voltage, mv; +;chip_en: enable chip io +;lpo_use_apclk: ""- not use, "losc_out"- a23/33/H3, "ac10032k1"、"ac10032k2"、"ac10032k3"- a80 +;-------------------------------------------------------------------------------- +[module_para] +module_power0 = "vcc-wifi-33" +module_power0_vol = 0 +module_power1 = +module_power1_vol = +module_power2 = +module_power2_vol = +module_power3 = +module_power3_vol = +chip_en = +lpo_use_apclk = + +;-------------------------------------------------------------------------------- +;wifi configuration +;wifi_sdc_id: 0- SDC0, 1- SDC1, 2- SDC2, 3- SDC3 +;wifi_usbc_id: 0- USB0, 1- USB1, 2- USB2 +;wifi_usbc_type: 1- EHCI(speed 2.0), 2- OHCI(speed 1.0) +;wl_reg_on: wifi function enable pin +;wl_host_wake: wlan device wake-up host pin +;wl_host_wake_invert: whether wl_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[wifi_para] +wifi_used = 1 +wifi_sdc_id = 1 +wifi_usbc_id = +wifi_usbc_type = +wl_reg_on = port:PL07<1><0> +wl_host_wake = port:PG10<0><0> +wl_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;bluetooth configuration +;bt_used: 0 - no used, 1- used +;bt_uard_id: 0 - uart0, 1- uart1, 2- uart2 +;bt_rst_n: bt function enable io +;bt_wake: host wake-up bluetooth device +;bt_host_wake: bt device wake-up host +;bt_host_wake_invert: whether bt_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[bt_para] +bt_used = 0 +bt_uart_id = 1 +bt_rst_n = +bt_wake = +bt_host_wake = +bt_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;daudio_master:1: SND_SOC_DAIFMT_CBM_CFM(codec clk & FRM master) use +; 2: SND_SOC_DAIFMT_CBS_CFM(codec clk slave & FRM master) not use +; 3: SND_SOC_DAIFMT_CBM_CFS(codec clk master & frame slave) not use +; 4: SND_SOC_DAIFMT_CBS_CFS(codec clk & FRM slave) use +;daudio_select:0 is pcm.1 is i2s +;audio_format: 1:SND_SOC_DAIFMT_I2S(standard i2s format). use +; 2:SND_SOC_DAIFMT_RIGHT_J(right justfied format). +; 3:SND_SOC_DAIFMT_LEFT_J(left justfied format) +; 4:SND_SOC_DAIFMT_DSP_A(pcm. MSB is available on 2nd BCLK rising edge after LRC rising edge). use +; 5:SND_SOC_DAIFMT_DSP_B(pcm. MSB is available on 1nd BCLK rising edge after LRC rising edge) +;signal_inversion:1:SND_SOC_DAIFMT_NB_NF(normal bit clock + frame) use +; 2:SND_SOC_DAIFMT_NB_IF(normal BCLK + inv FRM) +; 3:SND_SOC_DAIFMT_IB_NF(invert BCLK + nor FRM) use +; 4:SND_SOC_DAIFMT_IB_IF(invert BCLK + FRM) +;over_sample_rate: support 128fs/192fs/256fs/384fs/512fs/768fs +;sample_resolution :16bits/20bits/24bits +;word_select_size :16bits/20bits/24bits/32bits +;pcm_sync_period :16/32/64/128/256 +;msb_lsb_first :0: msb first; 1: lsb first +;sign_extend :0: zero pending; 1: sign extend +;slot_index :slot index: 0: the 1st slot - 3: the 4th slot +;slot_width :8 bit width / 16 bit width +;frame_width :0: long frame = 2 clock width; 1: short frame +;tx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;rx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;-------------------------------------------------------------------------------- +[pcm0] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PA18<2><1> +i2s_bclk = port:PA19<2><1> +i2s_dout0 = port:PA20<2><1> +i2s_din = port:PA21<2><1> + +[pcm1] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PG10<2><1> +i2s_bclk = port:PG11<2><1> +i2s_dout0 = port:PG12<2><1> +i2s_din = port:PG13<2><1> + +[audio0] +audio_used = 1 +lineout_vol = 0x1f +cap_vol = 0x5 +audio_hp_ldo = "none" +adcagc_used = 0 +adcdrc_used = 0 +dacdrc_used = 0 +adchpf_used = 0 +dachpf_used = 0 +audio_pa_ctrl = port:PA16<1><0> + +[spdif0] +spdif_used = 0 +spdif_dout = port:PA17<2><1> + +[audiohub] +hub_used = 1 +codec_used = 1 +spdif_used = 0 +hdmi_used = 1 + +;---------------------------------------------------------------------------------- +;ir rx --- infra remote configuration +;---------------------------------------------------------------------------------- +[s_cir0] +ir_used = 1 +ir_rx = port:PL11<2><1> +ir_power_key_code0 = 0x57 +ir_addr_code0 = 0x9f00 +ir_power_key_code1 = 0x1a +ir_addr_code1 = 0xfb04 +ir_power_key_code2 = 0x14 +ir_addr_code2 = 0x7F80 +ir_power_key_code3 = 0x15 +ir_addr_code3 = 0x7F80 +ir_power_key_code4 = 0x0b +ir_addr_code4 = 0xF708 +ir_power_key_code5 = 0x03 +ir_addr_code5 = 0x00EF +ir_power_key_code6 = 0x9f +ir_addr_code6 = 0x4CB3 +ir_power_key_code7 = 0x0a +ir_addr_code7 = 0x7748 +ir_power_key_code8 = 0x45 +ir_addr_code8 = 0xbd02 +ir_power_key_code9 = 0x4d +ir_addr_code9 = 0xde21 +ir_power_key_code10 = 0x18 +ir_addr_code10 = 0xfe01 +ir_power_key_code11 = 0x57 +ir_addr_code11 = 0xff00 +ir_power_key_code12 = 0x4d +ir_addr_code12 = 0xff40 + +;---------------------------------------------------------------------------------- +;ir tx--- infra remote configuration +;---------------------------------------------------------------------------------- +[cir] +ir_used = 1 +ir_tx = port:PH07<2> + +;---------------------------------------------------------------------------------- +; dvfs voltage-frequency table configuration +; +; pmuic_type:0:none, 1:gpio, 2:i2c +; pmu_gpio0: gpio config. +; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low. +; +; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk +; 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator +; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz +; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz +; +; LV_count: count of LV_freq/LV_volt, must be < 16 +; +; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz] +; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz] +; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz] +; LV4: core vdd is 1.20v if cpu frequency is (816Mhz, 1008Mhz] +; LV5: core vdd is 1.10v if cpu frequency is (648Mhz, 816Mhz] +; LV6: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV7: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV8: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; +;---------------------------------------------------------------------------------- +[dvfs_table] +pmuic_type = 1 +pmu_gpio0 = port:PL06<1><1><2><1> +pmu_level0 = 11300 +pmu_level1 = 1100 +max_freq = 1200000000 +min_freq = 480000000 +LV_count = 5 +LV1_freq = 1200000000 +LV1_volt = 1300 +LV2_freq = 1008000000 +LV2_volt = 1300 +LV3_freq = 912000000 +LV3_volt = 1100 +LV4_freq = 648000000 +LV4_volt = 1100 +LV5_freq = 480000000 +LV5_volt = 1100 + +[gpu_dvfs_table] +G_LV_count = 3 +G_LV0_freq = 312000000 +G_LV0_volt = 1200000 +G_LV1_freq = 384000000 +G_LV1_volt = 1200000 +G_LV2_freq = 456000000 +G_LV2_volt = 1200000 + +;---------------------------------------------------------------------------------- +;virtual device +;virtual device for pinctrl testing +;device have pin PA1 PA2 +;---------------------------------------------------------------------------------- +[Vdevice] +Vdevice_used = 0 +Vdevice_0 = port:PH10<5><1><2> +Vdevice_1 = port:PH11<5><1><2> + +;---------------------------------------------------------------------------------- +;s_uart0 config parameters +;s_uart_used --s_uart0 whether used for arisc debugging +;---------------------------------------------------------------------------------- +[s_uart0] +s_uart_used = 0 +s_uart_tx = port:PL02<2> +s_uart_rx = port:PL03<2> + +;---------------------------------------------------------------------------------- +;s_rsb0 config parameters +;s_rsb_used --s_rsb0 whether used for arisc +;---------------------------------------------------------------------------------- +[s_rsb0] +s_rsb_used = 1 +s_rsb_sck = port:PL00<2><1><2> +s_rsb_sda = port:PL01<2><1><2> + +;---------------------------------------------------------------------------------- +;s_jtag0 config parameters +;s_jtag0_used --s_jtag0 whether used for arisc +; +;---------------------------------------------------------------------------------- +[s_jtag0] +s_jtag_used = 0 +s_jtag_tms = port:PL04<2><1><2> +s_jtag_tck = port:PL05<2><1><2> +s_jtag_tdo = port:PL06<2><1><2> +s_jtag_tdi = port:PL07<2><1><2> + +;---------------------------------------------------------------------------------- +;s_powchk cpus power check +;s_powchk_used --power check whether used for arisc in super standby +; bit31:enable power updat, bit1:wakeup when power state exception +; bit0:wakeup when power consumption exception +;s_power_reg the expected regs stand for power on/off state +;s_system_power the limit maxmum power consumption when super standby (unit: mw) +; +;---------------------------------------------------------------------------------- +[s_powchk] +s_powchk_used = 0x80000000 +s_power_reg = 0x00000000 +s_system_power = 50 + +;---------------------------------------------------------------------------------- +;scr configuration +;---------------------------------------------------------------------------------- +[sim0] +scr_used = 0 +scr_vccen = port:PA06<2> +scr_slk = port:PA07<2> +scr_sda = port:PA08<2> +scr_rst = port:PA09<2> +scr_det = port:PA10<2> + +;-------------------------------------------------------------------------------- +;tsc configuration +;-------------------------------------------------------------------------------- +[ts0] +tsc_used = 0 +tsc_clk = port:PE00<3> +tsc_err = port:PE01<3> +tsc_sync = port:PE02<3> +tsc_dvld = port:PE03<3> +tsc_d0 = port:PE04<3> +tsc_d1 = port:PE05<3> +tsc_d2 = port:PE06<3> +tsc_d3 = port:PE07<3> +tsc_d4 = port:PE08<3> +tsc_d5 = port:PE09<3> +tsc_d6 = port:PE10<3> +tsc_d7 = port:PE11<3> + +;-------------------------------------------------------------------------------- +;gpio key +;-------------------------------------------------------------------------------- +[gpio_power_key] +key_used = 1 +key_io = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +; key para +; +; key_used --0:not used, 1:used +; key_cnt --how many key button attach to keyadc. +; key*_vol --the threshold of input voltage of key. +; +; For example: if key2_vol < $(keyadc value) < key3_vol, then key3 be reported. +;---------------------------------------------------------------------------------- +[key_para] +key_used = 0 +key_cnt = 5 +key1_vol = 222 +key2_vol = 444 +key3_vol = 666 +key4_vol = 857 +key5_vol = 2000 + +;---------------------------------------------------------------------------------- +;display seven segment para +;---------------------------------------------------------------------------------- +[d7s_para] +d7s_used = 0 +din_gpio = port:PD00<1><1> +clk_gpio = port:PD01<1><1> +stb_gpio = port:PD02<1><1> + +;---------------------------------------------------------------------------------- +;mali parameters +;---------------------------------------------------------------------------------- +[mali_para] +mali_used = 1 +mali_clkdiv = 1 +mali_extreme_freq = 600 +mali_extreme_vol = 1400 + +;---------------------------------------------------------------------------------- +;1wire parameters (default - PA20) +;---------------------------------------------------------------------------------- +[w1_para] +w1_used = 1 +gpio = 20 diff --git a/projects/H3/sys_config/opione.fex b/projects/H3/sys_config/opione.fex new file mode 100755 index 00000000000..49a606a76be --- /dev/null +++ b/projects/H3/sys_config/opione.fex @@ -0,0 +1,1068 @@ +[product] +version = "100" +machine = "opione" + +;--------------------------------------------------------------------------------------------------------- +; eraseflag - 1 erase data partition, 0 - do not erase data partition +; next_work - action after burn, 0x0 by config, 0x1, normal, 0x2 reboot 0x3 ,shutdown,0x4 reupdate ,0x5 boot +;--------------------------------------------------------------------------------------------------------- +[platform] +debug_mode = 1 +eraseflag = 1 +next_work = 2 + +;---------------------------------------------------------------------------------- +;[target] system bootup configuration +;boot_clock = CPU boot frequency, Unit: MHz +;storage_type = boot medium, 0-nand, 1-card0, 2-card2, -1(defualt)auto scan +;---------------------------------------------------------------------------------- +[target] +boot_clock = 1008 +storage_type = -1 + +;--------------------------------------------------------------------------------- +; used : 1: used this config, 0: not +; start_type : 1: start system directly when power supply, 0: wait IR/KEY to power on +; irkey_used : 1: ir key used, 0: not +; pmukey_used: 1: physical button used, 0: not +; led_power : 1: light, 0: off +; led_state : 1: light, 0: off +;--------------------------------------------------------------------------------- +[box_start_os] +used = 1 +start_type = 1 +irkey_used = 1 +pmukey_used = 1 +pmukey_num = 3 +led_power = 0 +led_state = 0 + +;--------------------------------------------------------------------------------------------------------- +; if 1 == standby_mode, then support super standby; +; else, support normal standby. +;--------------------------------------------------------------------------------------------------------- +[pm_para] +standby_mode = 1 + +; THIS PARAMETERS SEEMS TO BE USED ONLY FOR TESTING +[card0_boot_para] +card_ctrl = 0 +card_high_speed = 1 +card_line = 4 +sdc_d1 = port:PF00<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_d2 = port:PF05<2><1><2> + +[twi_para] +twi_port = 0 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[uart_para] +uart_debug_port = 0 +uart_debug_tx = port:PA04<2><1> +uart_debug_rx = port:PA05<2><1> + +[force_uart_para] +force_uart_port = 0 +force_uart_tx = port:PF02<3><1> +force_uart_rx = port:PF04<3><1> + +[jtag_para] +jtag_enable = 0 +jtag_ms = port:PA00<3> +jtag_ck = port:PA01<3> +jtag_do = port:PA02<3> +jtag_di = port:PA03<3> + +[clock] +pll_video = 297 +pll_ve = 402 +pll_periph0 = 600 +pll_gpu = 576 +pll_periph1 = 600 +pll_de = 864 + +;***************************************************************************** +;sdram configuration +; +;dram_para2 = 0x00001200 ;Representative enable dram Dual +;dram_para2 = 0x00001100 ;on behalf of a single channel is enabled dram +;***************************************************************************** +[dram_para] +dram_clk = 624 +dram_type = 3 +dram_zq = 0x3b3bfb +dram_odt_en = 0x1 +dram_para1 = 0x10E40000 +dram_para2 = 0x0000 +dram_mr0 = 0x1840 +dram_mr1 = 0x40 +dram_mr2 = 0x18 +dram_mr3 = 0x2 +dram_tpr0 = 0x0048A192 +dram_tpr1 = 0x01C2418D +dram_tpr2 = 0x00076051 +dram_tpr3 = 0 +dram_tpr4 = 0 +dram_tpr5 = 0 +dram_tpr6 = 100 +dram_tpr7 = 0 +dram_tpr8 = 0 +dram_tpr9 = 0 +dram_tpr10 = 0 +dram_tpr11 = 0x6aaa0000 +dram_tpr12 = 0x7979 +dram_tpr13 = 0x800800 + +;--------------------------------------------------------------------------------------------------------- +; wakeup_src_para: +; sometimes, u would like to add more wakeup src in standby mode, these para will be +; help; +; u need to make sure the standby mode support the wakeup src. Also, some hw +; condition must be guaranteed. +; including: +; cpu_en: power on or off. +; 1: mean power on +; 0: mean power off +; cpu_freq: indicating lowest freq. unit is Mhz; +; dram selfresh_en: selfresh or not. +; 1: enable enter selfresh +; 0: disable enter selfresh +; dram_pll: if not enter selfresh, indicating lowest freq. unit is Mhz; +; wakeup_src: to make the scenario work, the wakeup src is needed. +;--------------------------------------------------------------------------------------------------------- +[wakeup_src_para] +cpu_en = 0 +cpu_freq = 48 +pll_ratio = 273 +dram_selfresh_en = 1 +dram_freq = 36 +wakeup_src0 = +wakeup_src_wl = port:PG10<4><0> +wakeup_src_bt = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +;i2c configuration +;---------------------------------------------------------------------------------- +[twi0] +twi_used = 1 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[twi1] +twi_used = 0 +twi_scl = port:PA18<3> +twi_sda = port:PA19<3> + +[twi2] +twi_used = 0 +twi_scl = port:PE12<3> +twi_sda = port:PE13<3> + +;---------------------------------------------------------------------------------- +;uart configuration +;uart_type --- 2 (2 wire), 4 (4 wire), 8 (8 wire, full function) +;---------------------------------------------------------------------------------- +[uart0] +uart_used = 1 +uart_port = 0 +uart_type = 2 +uart_tx = port:PA04<2><1> +uart_rx = port:PA05<2><1> + +[uart1] +uart_used = 0 +uart_port = 1 +uart_type = 2 +uart_tx = port:PG06<2><1> +uart_rx = port:PG07<2><1> +uart_rts = port:PG08<2><1> +uart_cts = port:PG09<2><1> + +[uart2] +uart_used = 0 +uart_port = 2 +uart_type = 4 +uart_tx = port:PA00<2><1> +uart_rx = port:PA01<2><1> +uart_rts = port:PA02<2><1> +uart_cts = port:PA03<2><1> + +[uart3] +uart_used = 0 +uart_port = 3 +uart_type = 2 +uart_tx = port:PA13<3><1> +uart_rx = port:PA14<3><1> +uart_rts = port:PA15<3><1> +uart_cts = port:PA16<3><1> + +;---------------------------------------------------------------------------------- +;SPI controller configuration +;---------------------------------------------------------------------------------- +[spi0] +spi_used = 1 +spi_cs_bitmap = 1 +spi_mosi = port:PC00<3> +spi_miso = port:PC01<3> +spi_sclk = port:PC02<3> +spi_cs0 = port:PC03<3><1> + +[spi1] +spi_used = 0 +spi_cs_bitmap = 1 +spi_cs0 = port:PA13<2><1> +spi_sclk = port:PA14<2> +spi_mosi = port:PA15<2> +spi_miso = port:PA16<2> + +;---------------------------------------------------------------------------------- +;SPI device configuration +;---------------------------------------------------------------------------------- +[spi_devices] +spi_dev_num = 1 + +[spi_board0] +modalias = "spidev" +max_speed_hz = 33000000 +bus_num = 0 +chip_select = 0 +mode = 0 +full_duplex = 1 +manual_cs = 0 + +[leds_para] +leds_used = 1 +green_led = port:PL10<1><0> +green_led_active_low = 1 +red_led = port:PA15<1><0> +red_led_active_low = 0 + +;---------------------------------------------------------------------------------- +;thermal configuration +;ths_trip_count : temperature trigger number +;ths_trip_0 : first temperature trigger +;ths_trip_1 : second temperature trigger +;ths_trip_2 : third temperature trigger, when upto this temperature, system shutdown +;ths_trip_0_min : first temperature trigger's min freq +;ths_trip_0_max : first temperature trigger's max freq +;ths_trip_1_min : second temperature trigger's min freq +;ths_trip_1_max : second temperature trigger's max freq +;---------------------------------------------------------------------------------- +[ths_para] +ths_used = 1 +ths_trip1_count = 6 +ths_trip1_0 = 75 +ths_trip1_1 = 80 +ths_trip1_2 = 85 +ths_trip1_3 = 90 +ths_trip1_4 = 95 +ths_trip1_5 = 105 +ths_trip1_6 = 0 +ths_trip1_7 = 0 +ths_trip1_0_min = 0 +ths_trip1_0_max = 1 +ths_trip1_1_min = 1 +ths_trip1_1_max = 2 +ths_trip1_2_min = 2 +ths_trip1_2_max = 3 +ths_trip1_3_min = 3 +ths_trip1_3_max = 4 +ths_trip1_4_min = 4 +ths_trip1_4_max = 5 +ths_trip1_5_min = 5 +ths_trip1_5_max = 7 +ths_trip1_6_min = 0 +ths_trip1_6_max = 0 +ths_trip2_count = 1 +ths_trip2_0 = 105 + +;---------------------------------------------------------------------------------- +;cooler_table cooler_count <=32 +;---------------------------------------------------------------------------------- +[cooler_table] +cooler_count = 8 +cooler0 = "1200000 4 4294967295 0" +cooler1 = "912000 4 4294967295 0" +cooler2 = "768000 4 4294967295 0" +cooler3 = "648000 4 4294967295 0" +cooler4 = "480000 4 4294967295 0" +cooler5 = "480000 3 4294967295 0" +cooler6 = "480000 2 4294967295 0" +cooler7 = "480000 1 4294967295 0" + +[nand0_para] +nand_support_2ch = 0 + +nand0_used = 0 +nand0_we = port:PC00<2> +nand0_ale = port:PC01<2> +nand0_cle = port:PC02<2> +nand0_ce1 = port:PC03<2> +nand0_ce0 = port:PC04<2> +nand0_nre = port:PC05<2> +nand0_rb0 = port:PC06<2> +nand0_rb1 = port:PC07<2> +nand0_d0 = port:PC08<2> +nand0_d1 = port:PC09<2> +nand0_d2 = port:PC10<2> +nand0_d3 = port:PC11<2> +nand0_d4 = port:PC12<2> +nand0_d5 = port:PC13<2> +nand0_d6 = port:PC14<2> +nand0_d7 = port:PC15<2> +nand0_ndqs = port:PC16<2> + +;---------------------------------------------------------------------------------- +;disp init configuration +; +;disp_mode (0:screen0; 1:screen1) +;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;) +;screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50) +; (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:PAL 14:NTSC) +;fbx format (0:ARGB 1:ABGR 2:RGBA 3:BGRA 5:RGB565 8:RGB888 12:ARGB4444 16:ARGB1555 18:RGBA5551) +;fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0) +;lcdx_backlight (lcd init backlight,the range:[0,256],default:197 +;---------------------------------------------------------------------------------- +[disp_init] +disp_init_enable = 1 +disp_mode = 0 +screen0_output_type = 3 +screen0_output_mode = 10 +screen1_output_type = 0 +screen1_output_mode = 0 +fb0_format = 0 +fb0_width = 0 +fb0_height = 0 + +fb1_format = 0 +fb1_width = 0 +fb1_height = 0 + +;---------------------------------------------------------------------------------- +;hdmi configuration +;---------------------------------------------------------------------------------- +[hdmi_para] +hdmi_used = 1 +hdmi_power = "vcc-hdmi-18" +hdcp_enable = 0 + +[tv_para] +tv_used = 0 +tv_dac_used = 1 +tv_dac_src0 = 0 + +;---------------------------------------------------------------------------------- +;pwm config +;---------------------------------------------------------------------------------- +[pwm0_para] +pwm_used = 0 +pwm_positive = port:PA05<3><0> + +;------------------------------------------------------------------------------; +; 10/100/100Mbps Ethernet MAC Controller Configure ; +;------------------------------------------------------------------------------; +; Options: ; +; gmac_used --- 0: not used, 1: external phy, 2: internal phy ; +; gmac_powerx -- A[:B] A: axp channel, B: voltage value ; +; If set gamc_phy to use internal PHY, do not config port ; +;------------------------------------------------------------------------------; +; MII RMII MII RMII MII RMII ; +; PD00 * PD06 * * PD12 * * ; +; PD01 * PD07 * PD13 * * ; +; PD02 * * PD08 * PD14 * ; +; PD03 * * PD09 * * PD15 * ; +; PD04 * PD10 * * PD16 * * ; +; PD05 * PD11 * * PD17 * * ; +;------------------------------------------------------------------------------; +[gmac0] +gmac_used = 2 +gmac_power1 = + +;-------------------------------------------------------------------------------- +;vip (video input port) configuration +;vip_used: 0:disable 1:enable +;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer +;vip_dev_qty: The quantity of devices linked to capture bus +; +;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and +; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! +; +;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1, +;vip_dev(x)_pos must be configured! +; +;vip_dev(x)_isp_used 0:not use isp 1:use isp +;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb +;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby +;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable +;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable +;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply +;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply +;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply +;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply +;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply +;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply +;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply +;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply +;x indicates the index of the devices which are linked to the same capture bus +;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 +;fill handle string as below: +;axp22_eldo3 +;axp22_dldo4 +;axp22_eldo2 +;fill handle string "" when not using any pmu power supply +;-------------------------------------------------------------------------------- +[csi0] +vip_used = 0 +vip_mode = 0 +vip_dev_qty = 1 +vip_define_sensor_list = 0 + +vip_csi_pck = port:PE00<2> +vip_csi_mck = port:PE01<2> +vip_csi_hsync = port:PE02<2> +vip_csi_vsync = port:PE03<2> +vip_csi_d0 = port:PE04<2> +vip_csi_d1 = port:PE05<2> +vip_csi_d2 = port:PE06<2> +vip_csi_d3 = port:PE07<2> +vip_csi_d4 = port:PE08<2> +vip_csi_d5 = port:PE09<2> +vip_csi_d6 = port:PE10<2> +vip_csi_d7 = port:PE11<2> +vip_csi_sck = port:PE12<2> +vip_csi_sda = port:PE13<2> + +vip_dev0_mname = "gc2035" +vip_dev0_pos = "front" +vip_dev0_lane = 1 +vip_dev0_twi_id = 2 +vip_dev0_twi_addr = 0x78 +vip_dev0_isp_used = 0 +vip_dev0_fmt = 0 +vip_dev0_stby_mode = 0 +vip_dev0_vflip = 1 +vip_dev0_hflip = 1 +vip_dev0_iovdd = "" +vip_dev0_iovdd_vol = 2800000 +vip_dev0_avdd = "" +vip_dev0_avdd_vol = 2800000 +vip_dev0_dvdd = "" +vip_dev0_dvdd_vol = 1800000 +vip_dev0_afvdd = "" +vip_dev0_afvdd_vol = 2800000 +vip_dev0_power_en = port:PA17<1><1> +vip_dev0_reset = port:PE14<1><1> +vip_dev0_pwdn = port:PE15<1><0> +vip_dev0_flash_en = +vip_dev0_flash_mode = +vip_dev0_af_pwdn = + +vip_dev0_act_used = 0 +vip_dev0_act_name = "ad5820_act" +vip_dev0_act_slave = 0x18 + + +vip_dev1_mname = "" +vip_dev1_pos = "rear" +vip_dev1_lane = 1 +vip_dev1_twi_id = 0 +vip_dev1_twi_addr = +vip_dev1_isp_used = 0 +vip_dev1_fmt = 1 +vip_dev1_stby_mode = 0 +vip_dev1_vflip = 0 +vip_dev1_hflip = 0 +vip_dev1_iovdd = "" +vip_dev1_iovdd_vol = 2800000 +vip_dev1_avdd = "" +vip_dev1_avdd_vol = 2800000 +vip_dev1_dvdd = "" +vip_dev1_dvdd_vol = 1500000 +vip_dev1_afvdd = "" +vip_dev1_afvdd_vol = 2800000 +vip_dev1_power_en = +vip_dev1_reset = +vip_dev1_pwdn = +vip_dev1_flash_en = +vip_dev1_flash_mode = +vip_dev1_af_pwdn = + +;---------------------------------------------------------------------------------- +;Deinterlace configuration +;---------------------------------------------------------------------------------- +[di_para] +di_used = 1 +di_by_pass = 0 + +;-------------------------------------------------------------------------------- +; SDMMC PINS MAPPING | +; ------------------------------------------------------------------------------| +; Config Guide | +; sdc_used: 1-enable card, 0-disable card | +; sdc_detmode: card detect mode | +; 1-detect card by gpio polling | +; 2-detect card by gpio irq(must use IO with irq function) | +; 3-no detect, always in for boot card | +; 4-manually insert and remove by /proc/driver/sunxi-mmc.x/insert| +; sdc_buswidth: card bus width, 1-1bit, 4-4bit, 8-8bit | +; sdc_use_wp: 1-with write protect IO, 0-no write protect IO | +; sdc_isio: for sdio card | +; sdc_regulator: power control.if card supports UHS-I/DDR and HS200 timing for| +; SD3.0 or eMMC4.5, regulator must be configured. the value is | +; the ldo name of AXP221, eg: sdc_regulator = "axp22_eldo2" | +; other: GPIO Mapping configuration | +; ------------------------------------------------------------------------------| +; Note: | +; 1 if detmode=2, sdc_det's config=6 | +; else if detmode=1, sdc_det's config=0 | +; else sdc_det IO is not necessary | +; 2 if the customer wants to support UHS-I and HS200 features, he must provide| +; an independent power supply for the card. This is only used in platforms | +; that supports SD3.0 cards and eMMC4.4+ flashes | +;-------------------------------------------------------------------------------- +[mmc0_para] +sdc_used = 1 +sdc_detmode = 3 +sdc_buswidth = 4 +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_d1 = port:PF00<2><1><2> +sdc_d2 = port:PF05<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_det = port:PF06<0><1><2> +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" + +[mmc1_para] +sdc_used = 0 +sdc_detmode = 4 +sdc_buswidth = 4 +sdc_clk = port:PG00<2><1><3> +sdc_cmd = port:PG01<2><1><3> +sdc_d0 = port:PG02<2><1><3> +sdc_d1 = port:PG03<2><1><3> +sdc_d2 = port:PG04<2><1><3> +sdc_d3 = port:PG05<2><1><3> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 1 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +[mmc2_para] +sdc_used = 0 +sdc_detmode = 3 +sdc_buswidth = 8 +sdc_clk = port:PC05<3><1><2> +sdc_cmd = port:PC06<3><1><2> +sdc_d0 = port:PC08<3><1><2> +sdc_d1 = port:PC09<3><1><2> +sdc_d2 = port:PC10<3><1><2> +sdc_d3 = port:PC11<3><1><2> +sdc_d4 = port:PC12<3><1><2> +sdc_d5 = port:PC13<3><1><2> +sdc_d6 = port:PC14<3><1><2> +sdc_d7 = port:PC15<3><1><2> +emmc_rst = port:PC16<3><1><2> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +; ------------------------------------------------------------------------------| +; sim card configuration +;-------------------------------------------------------------------------------- +[smc_para] +smc_used = 0 +smc_rst = port:PA09<2> +smc_vppen = port:PA20<3> +smc_vppp = port:PA21<3> +smc_det = port:PA10<2> +smc_vccen = port:PA06<2> +smc_sck = port:PA07<2> +smc_sda = port:PA08<2> + +;-------------------------------- +; [usbc0]: Controller 0 configuration. +; usb used: USB enable flag. Set, indicating that the system USB module is available, is set to 0, it means that the system USB is disabled. +; usb_port_type: USB port usage. 0: device only; 1: host only; 2: OTG +; usb_detect_type: USB port of checking. 0: not detected; 1: vbus / id checks; 2: id / dpdm check +; usb_id_gpio: USB ID pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: USB DET_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_drv_vbus_gpio: USB DRY_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: "axp_ctrl", represents axp offer +; usb_restrict_gpio: usb limiting control pin +; usb_restric_flag: usb limiting standard set +;-------------------------------- +;-------------------------------- +; USB0 OTG +;-------------------------------- +[usbc0] +usb_used = 1 +usb_port_type = 2 +usb_detect_type = 0 +usb_id_gpio = port:PG12<0><1> +usb_det_vbus_gpio = port:PG12<0><1> +usb_drv_vbus_gpio = port:PL02<1><0><0> +usb_host_init_state = 1 +usb_restrict_gpio = +usb_restric_flag = 0 +usb_restric_voltage = 3550000 +usb_restric_capacity= 5 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB1 Host +;-------------------------------- +[usbc1] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB2 Host +;-------------------------------- +[usbc2] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB3 Host +;-------------------------------- +[usbc3] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB Device +;-------------------------------- +[usb_feature] +vendor_id = 0x18D1 +mass_storage_id = 0x0001 +adb_id = 0x0002 + +manufacturer_name = "USB Developer" +product_name = "Android" +serial_number = "20080411" + +[msc_feature] +vendor_name = "USB 2.0" +product_name = "USB Flash Driver" +release = 100 +luns = 3 + +[serial_feature] +serial_unique = 0 + +;-------------------------------------------------------------------------------- +;wifi/bt/fm/gps/nfc modules configuration +;module_power0: axp used by module, "axp22_dldo1" - use dldo1, not use keep it empty +;module_power0_vol: power0 voltage, mv; +;chip_en: enable chip io +;lpo_use_apclk: ""- not use, "losc_out"- a23/33/H3, "ac10032k1"、"ac10032k2"、"ac10032k3"- a80 +;-------------------------------------------------------------------------------- +[module_para] +module_power0 = "vcc-wifi-33" +module_power0_vol = 0 +module_power1 = +module_power1_vol = +module_power2 = +module_power2_vol = +module_power3 = +module_power3_vol = +chip_en = +lpo_use_apclk = + +;-------------------------------------------------------------------------------- +;wifi configuration +;wifi_sdc_id: 0- SDC0, 1- SDC1, 2- SDC2, 3- SDC3 +;wifi_usbc_id: 0- USB0, 1- USB1, 2- USB2 +;wifi_usbc_type: 1- EHCI(speed 2.0), 2- OHCI(speed 1.0) +;wl_reg_on: wifi function enable pin +;wl_host_wake: wlan device wake-up host pin +;wl_host_wake_invert: whether wl_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[wifi_para] +wifi_used = 0 +wifi_sdc_id = 1 +wifi_usbc_id = +wifi_usbc_type = +wl_reg_on = port:PL07<1><0> +wl_host_wake = port:PG10<0><0> +wl_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;bluetooth configuration +;bt_used: 0 - no used, 1- used +;bt_uard_id: 0 - uart0, 1- uart1, 2- uart2 +;bt_rst_n: bt function enable io +;bt_wake: host wake-up bluetooth device +;bt_host_wake: bt device wake-up host +;bt_host_wake_invert: whether bt_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[bt_para] +bt_used = 0 +bt_uart_id = 1 +bt_rst_n = +bt_wake = +bt_host_wake = +bt_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;daudio_master:1: SND_SOC_DAIFMT_CBM_CFM(codec clk & FRM master) use +; 2: SND_SOC_DAIFMT_CBS_CFM(codec clk slave & FRM master) not use +; 3: SND_SOC_DAIFMT_CBM_CFS(codec clk master & frame slave) not use +; 4: SND_SOC_DAIFMT_CBS_CFS(codec clk & FRM slave) use +;daudio_select:0 is pcm.1 is i2s +;audio_format: 1:SND_SOC_DAIFMT_I2S(standard i2s format). use +; 2:SND_SOC_DAIFMT_RIGHT_J(right justfied format). +; 3:SND_SOC_DAIFMT_LEFT_J(left justfied format) +; 4:SND_SOC_DAIFMT_DSP_A(pcm. MSB is available on 2nd BCLK rising edge after LRC rising edge). use +; 5:SND_SOC_DAIFMT_DSP_B(pcm. MSB is available on 1nd BCLK rising edge after LRC rising edge) +;signal_inversion:1:SND_SOC_DAIFMT_NB_NF(normal bit clock + frame) use +; 2:SND_SOC_DAIFMT_NB_IF(normal BCLK + inv FRM) +; 3:SND_SOC_DAIFMT_IB_NF(invert BCLK + nor FRM) use +; 4:SND_SOC_DAIFMT_IB_IF(invert BCLK + FRM) +;over_sample_rate: support 128fs/192fs/256fs/384fs/512fs/768fs +;sample_resolution :16bits/20bits/24bits +;word_select_size :16bits/20bits/24bits/32bits +;pcm_sync_period :16/32/64/128/256 +;msb_lsb_first :0: msb first; 1: lsb first +;sign_extend :0: zero pending; 1: sign extend +;slot_index :slot index: 0: the 1st slot - 3: the 4th slot +;slot_width :8 bit width / 16 bit width +;frame_width :0: long frame = 2 clock width; 1: short frame +;tx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;rx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;-------------------------------------------------------------------------------- +[pcm0] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PA18<2><1> +i2s_bclk = port:PA19<2><1> +i2s_dout0 = port:PA20<2><1> +i2s_din = port:PA21<2><1> + +[pcm1] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PG10<2><1> +i2s_bclk = port:PG11<2><1> +i2s_dout0 = port:PG12<2><1> +i2s_din = port:PG13<2><1> + +[audio0] +audio_used = 1 +lineout_vol = 0x1f +cap_vol = 0x5 +audio_hp_ldo = "none" +adcagc_used = 0 +adcdrc_used = 0 +dacdrc_used = 0 +adchpf_used = 0 +dachpf_used = 0 +audio_pa_ctrl = port:PA16<1><0> + +[spdif0] +spdif_used = 0 +spdif_dout = port:PA17<2><1> + +[audiohub] +hub_used = 1 +codec_used = 1 +spdif_used = 0 +hdmi_used = 1 + +;---------------------------------------------------------------------------------- +;ir rx --- infra remote configuration +;---------------------------------------------------------------------------------- +[s_cir0] +ir_used = 1 +ir_rx = port:PL11<2><1> +ir_power_key_code0 = 0x57 +ir_addr_code0 = 0x9f00 +ir_power_key_code1 = 0x1a +ir_addr_code1 = 0xfb04 +ir_power_key_code2 = 0x14 +ir_addr_code2 = 0x7F80 +ir_power_key_code3 = 0x15 +ir_addr_code3 = 0x7F80 +ir_power_key_code4 = 0x0b +ir_addr_code4 = 0xF708 +ir_power_key_code5 = 0x03 +ir_addr_code5 = 0x00EF +ir_power_key_code6 = 0x9f +ir_addr_code6 = 0x4CB3 +ir_power_key_code7 = 0x0a +ir_addr_code7 = 0x7748 +ir_power_key_code8 = 0x45 +ir_addr_code8 = 0xbd02 +ir_power_key_code9 = 0x4d +ir_addr_code9 = 0xde21 +ir_power_key_code10 = 0x18 +ir_addr_code10 = 0xfe01 +ir_power_key_code11 = 0x57 +ir_addr_code11 = 0xff00 +ir_power_key_code12 = 0x4d +ir_addr_code12 = 0xff40 + +;---------------------------------------------------------------------------------- +;ir tx--- infra remote configuration +;---------------------------------------------------------------------------------- +[cir] +ir_used = 1 +ir_tx = port:PH07<2> + +;---------------------------------------------------------------------------------- +; dvfs voltage-frequency table configuration +; +; pmuic_type:0:none, 1:gpio, 2:i2c +; pmu_gpio0: gpio config. +; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low. +; +; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk +; 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator +; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz +; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz +; +; LV_count: count of LV_freq/LV_volt, must be < 16 +; +; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz] +; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz] +; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz] +; LV4: core vdd is 1.20v if cpu frequency is (816Mhz, 1008Mhz] +; LV5: core vdd is 1.10v if cpu frequency is (648Mhz, 816Mhz] +; LV6: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV7: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV8: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; +;---------------------------------------------------------------------------------- +[dvfs_table] +pmuic_type = 1 +pmu_gpio0 = port:PL06<1><1><2><1> +pmu_level0 = 11300 +pmu_level1 = 1100 +max_freq = 1200000000 +min_freq = 480000000 +LV_count = 5 +LV1_freq = 1200000000 +LV1_volt = 1300 +LV2_freq = 1008000000 +LV2_volt = 1300 +LV3_freq = 912000000 +LV3_volt = 1100 +LV4_freq = 648000000 +LV4_volt = 1100 +LV5_freq = 480000000 +LV5_volt = 1100 + +[gpu_dvfs_table] +G_LV_count = 3 +G_LV0_freq = 312000000 +G_LV0_volt = 1200000 +G_LV1_freq = 384000000 +G_LV1_volt = 1200000 +G_LV2_freq = 456000000 +G_LV2_volt = 1200000 + +;---------------------------------------------------------------------------------- +;virtual device +;virtual device for pinctrl testing +;device have pin PA1 PA2 +;---------------------------------------------------------------------------------- +[Vdevice] +Vdevice_used = 0 +Vdevice_0 = port:PH10<5><1><2> +Vdevice_1 = port:PH11<5><1><2> + +;---------------------------------------------------------------------------------- +;s_uart0 config parameters +;s_uart_used --s_uart0 whether used for arisc debugging +;---------------------------------------------------------------------------------- +[s_uart0] +s_uart_used = 0 +s_uart_tx = port:PL02<2> +s_uart_rx = port:PL03<2> + +;---------------------------------------------------------------------------------- +;s_rsb0 config parameters +;s_rsb_used --s_rsb0 whether used for arisc +;---------------------------------------------------------------------------------- +[s_rsb0] +s_rsb_used = 1 +s_rsb_sck = port:PL00<2><1><2> +s_rsb_sda = port:PL01<2><1><2> + +;---------------------------------------------------------------------------------- +;s_jtag0 config parameters +;s_jtag0_used --s_jtag0 whether used for arisc +; +;---------------------------------------------------------------------------------- +[s_jtag0] +s_jtag_used = 0 +s_jtag_tms = port:PL04<2><1><2> +s_jtag_tck = port:PL05<2><1><2> +s_jtag_tdo = port:PL06<2><1><2> +s_jtag_tdi = port:PL07<2><1><2> + +;---------------------------------------------------------------------------------- +;s_powchk cpus power check +;s_powchk_used --power check whether used for arisc in super standby +; bit31:enable power updat, bit1:wakeup when power state exception +; bit0:wakeup when power consumption exception +;s_power_reg the expected regs stand for power on/off state +;s_system_power the limit maxmum power consumption when super standby (unit: mw) +; +;---------------------------------------------------------------------------------- +[s_powchk] +s_powchk_used = 0x80000000 +s_power_reg = 0x00000000 +s_system_power = 50 + +;---------------------------------------------------------------------------------- +;scr configuration +;---------------------------------------------------------------------------------- +[sim0] +scr_used = 0 +scr_vccen = port:PA06<2> +scr_slk = port:PA07<2> +scr_sda = port:PA08<2> +scr_rst = port:PA09<2> +scr_det = port:PA10<2> + +;-------------------------------------------------------------------------------- +;tsc configuration +;-------------------------------------------------------------------------------- +[ts0] +tsc_used = 0 +tsc_clk = port:PE00<3> +tsc_err = port:PE01<3> +tsc_sync = port:PE02<3> +tsc_dvld = port:PE03<3> +tsc_d0 = port:PE04<3> +tsc_d1 = port:PE05<3> +tsc_d2 = port:PE06<3> +tsc_d3 = port:PE07<3> +tsc_d4 = port:PE08<3> +tsc_d5 = port:PE09<3> +tsc_d6 = port:PE10<3> +tsc_d7 = port:PE11<3> + +;-------------------------------------------------------------------------------- +;gpio key +;-------------------------------------------------------------------------------- +[gpio_power_key] +key_used = 1 +key_io = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +; key para +; +; key_used --0:not used, 1:used +; key_cnt --how many key button attach to keyadc. +; key*_vol --the threshold of input voltage of key. +; +; For example: if key2_vol < $(keyadc value) < key3_vol, then key3 be reported. +;---------------------------------------------------------------------------------- +[key_para] +key_used = 0 +key_cnt = 5 +key1_vol = 222 +key2_vol = 444 +key3_vol = 666 +key4_vol = 857 +key5_vol = 2000 + +;---------------------------------------------------------------------------------- +;display seven segment para +;---------------------------------------------------------------------------------- +[d7s_para] +d7s_used = 0 +din_gpio = port:PD00<1><1> +clk_gpio = port:PD01<1><1> +stb_gpio = port:PD02<1><1> + +;---------------------------------------------------------------------------------- +;mali parameters +;---------------------------------------------------------------------------------- +[mali_para] +mali_used = 1 +mali_clkdiv = 1 +mali_extreme_freq = 600 +mali_extreme_vol = 1400 + +;---------------------------------------------------------------------------------- +;1wire parameters (default - PA20) +;---------------------------------------------------------------------------------- +[w1_para] +w1_used = 1 +gpio = 20 diff --git a/projects/H3/sys_config/opipc.fex b/projects/H3/sys_config/opipc.fex new file mode 100755 index 00000000000..6691bbae442 --- /dev/null +++ b/projects/H3/sys_config/opipc.fex @@ -0,0 +1,1074 @@ +[product] +version = "100" +machine = "opipc" + +;--------------------------------------------------------------------------------------------------------- +; eraseflag - 1 erase data partition, 0 - do not erase data partition +; next_work - action after burn, 0x0 by config, 0x1, normal, 0x2 reboot 0x3 ,shutdown,0x4 reupdate ,0x5 boot +;--------------------------------------------------------------------------------------------------------- +[platform] +debug_mode = 1 +eraseflag = 1 +next_work = 2 + +;---------------------------------------------------------------------------------- +;[target] system bootup configuration +;boot_clock = CPU boot frequency, Unit: MHz +;storage_type = boot medium, 0-nand, 1-card0, 2-card2, -1(defualt)auto scan +;---------------------------------------------------------------------------------- +[target] +boot_clock = 1008 +storage_type = -1 + +;--------------------------------------------------------------------------------- +; used : 1: used this config, 0: not +; start_type : 1: start system directly when power supply, 0: wait IR/KEY to power on +; irkey_used : 1: ir key used, 0: not +; pmukey_used: 1: physical button used, 0: not +; led_power : 1: light, 0: off +; led_state : 1: light, 0: off +;--------------------------------------------------------------------------------- +[box_start_os] +used = 1 +start_type = 1 +irkey_used = 1 +pmukey_used = 1 +pmukey_num = 3 +led_power = 0 +led_state = 0 + +;--------------------------------------------------------------------------------------------------------- +; if 1 == standby_mode, then support super standby; +; else, support normal standby. +;--------------------------------------------------------------------------------------------------------- +[pm_para] +standby_mode = 1 + +; THIS PARAMETERS SEEMS TO BE USED ONLY FOR TESTING +[card0_boot_para] +card_ctrl = 0 +card_high_speed = 1 +card_line = 4 +sdc_d1 = port:PF00<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_d2 = port:PF05<2><1><2> + +[twi_para] +twi_port = 0 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[uart_para] +uart_debug_port = 0 +uart_debug_tx = port:PA04<2><1> +uart_debug_rx = port:PA05<2><1> + +[force_uart_para] +force_uart_port = 0 +force_uart_tx = port:PF02<3><1> +force_uart_rx = port:PF04<3><1> + +[jtag_para] +jtag_enable = 0 +jtag_ms = port:PA00<3> +jtag_ck = port:PA01<3> +jtag_do = port:PA02<3> +jtag_di = port:PA03<3> + +[clock] +pll_video = 297 +pll_ve = 402 +pll_periph0 = 600 +pll_gpu = 576 +pll_periph1 = 600 +pll_de = 864 + +;***************************************************************************** +;sdram configuration +; +;dram_para2 = 0x00001200 ;Representative enable dram Dual +;dram_para2 = 0x00001100 ;on behalf of a single channel is enabled dram +;***************************************************************************** +[dram_para] +dram_clk = 624 +dram_type = 3 +dram_zq = 0x3b3bfb +dram_odt_en = 0x1 +dram_para1 = 0x10E40000 +dram_para2 = 0x0000 +dram_mr0 = 0x1840 +dram_mr1 = 0x40 +dram_mr2 = 0x18 +dram_mr3 = 0x2 +dram_tpr0 = 0x0048A192 +dram_tpr1 = 0x01C2418D +dram_tpr2 = 0x00076051 +dram_tpr3 = 0 +dram_tpr4 = 0 +dram_tpr5 = 0 +dram_tpr6 = 100 +dram_tpr7 = 0 +dram_tpr8 = 0 +dram_tpr9 = 0 +dram_tpr10 = 0 +dram_tpr11 = 0x6aaa0000 +dram_tpr12 = 0x7979 +dram_tpr13 = 0x800800 + +;--------------------------------------------------------------------------------------------------------- +; wakeup_src_para: +; sometimes, u would like to add more wakeup src in standby mode, these para will be +; help; +; u need to make sure the standby mode support the wakeup src. Also, some hw +; condition must be guaranteed. +; including: +; cpu_en: power on or off. +; 1: mean power on +; 0: mean power off +; cpu_freq: indicating lowest freq. unit is Mhz; +; dram selfresh_en: selfresh or not. +; 1: enable enter selfresh +; 0: disable enter selfresh +; dram_pll: if not enter selfresh, indicating lowest freq. unit is Mhz; +; wakeup_src: to make the scenario work, the wakeup src is needed. +;--------------------------------------------------------------------------------------------------------- +[wakeup_src_para] +cpu_en = 0 +cpu_freq = 48 +pll_ratio = 273 +dram_selfresh_en = 1 +dram_freq = 36 +wakeup_src0 = +wakeup_src_wl = port:PG10<4><0> +wakeup_src_bt = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +;i2c configuration +;---------------------------------------------------------------------------------- +[twi0] +twi_used = 1 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[twi1] +twi_used = 0 +twi_scl = port:PA18<3> +twi_sda = port:PA19<3> + +[twi2] +twi_used = 0 +twi_scl = port:PE12<3> +twi_sda = port:PE13<3> + +;---------------------------------------------------------------------------------- +;uart configuration +;uart_type --- 2 (2 wire), 4 (4 wire), 8 (8 wire, full function) +;---------------------------------------------------------------------------------- +[uart0] +uart_used = 1 +uart_port = 0 +uart_type = 2 +uart_tx = port:PA04<2><1> +uart_rx = port:PA05<2><1> + +[uart1] +uart_used = 0 +uart_port = 1 +uart_type = 2 +uart_tx = port:PG06<2><1> +uart_rx = port:PG07<2><1> +uart_rts = port:PG08<2><1> +uart_cts = port:PG09<2><1> + +[uart2] +uart_used = 0 +uart_port = 2 +uart_type = 4 +uart_tx = port:PA00<2><1> +uart_rx = port:PA01<2><1> +uart_rts = port:PA02<2><1> +uart_cts = port:PA03<2><1> + +[uart3] +uart_used = 0 +uart_port = 3 +uart_type = 2 +uart_tx = port:PA13<3><1> +uart_rx = port:PA14<3><1> +uart_rts = port:PA15<3><1> +uart_cts = port:PA16<3><1> + +;---------------------------------------------------------------------------------- +;SPI controller configuration +;---------------------------------------------------------------------------------- +[spi0] +spi_used = 1 +spi_cs_bitmap = 1 +spi_mosi = port:PC00<3> +spi_miso = port:PC01<3> +spi_sclk = port:PC02<3> +spi_cs0 = port:PC03<3><1> + +[spi1] +spi_used = 0 +spi_cs_bitmap = 1 +spi_cs0 = port:PA13<2><1> +spi_sclk = port:PA14<2> +spi_mosi = port:PA15<2> +spi_miso = port:PA16<2> + +;---------------------------------------------------------------------------------- +;SPI device configuration +;---------------------------------------------------------------------------------- +[spi_devices] +spi_dev_num = 1 + +[spi_board0] +modalias = "spidev" +max_speed_hz = 33000000 +bus_num = 0 +chip_select = 0 +mode = 0 +full_duplex = 1 +manual_cs = 0 + +[leds_para] +leds_used = 1 +green_led = port:PL10<1><0> +green_led_active_low = 1 +red_led = port:PA15<1><0> +red_led_active_low = 0 + +;---------------------------------------------------------------------------------- +;thermal configuration +;ths_trip_count : temperature trigger number +;ths_trip_0 : first temperature trigger +;ths_trip_1 : second temperature trigger +;ths_trip_2 : third temperature trigger, when upto this temperature, system shutdown +;ths_trip_0_min : first temperature trigger's min freq +;ths_trip_0_max : first temperature trigger's max freq +;ths_trip_1_min : second temperature trigger's min freq +;ths_trip_1_max : second temperature trigger's max freq +;---------------------------------------------------------------------------------- +[ths_para] +ths_used = 1 +ths_trip1_count = 6 +ths_trip1_0 = 75 +ths_trip1_1 = 80 +ths_trip1_2 = 85 +ths_trip1_3 = 90 +ths_trip1_4 = 95 +ths_trip1_5 = 105 +ths_trip1_6 = 0 +ths_trip1_7 = 0 +ths_trip1_0_min = 0 +ths_trip1_0_max = 1 +ths_trip1_1_min = 1 +ths_trip1_1_max = 2 +ths_trip1_2_min = 2 +ths_trip1_2_max = 3 +ths_trip1_3_min = 3 +ths_trip1_3_max = 4 +ths_trip1_4_min = 4 +ths_trip1_4_max = 8 +ths_trip1_5_min = 8 +ths_trip1_5_max = 8 +ths_trip1_6_min = 0 +ths_trip1_6_max = 0 +ths_trip2_count = 1 +ths_trip2_0 = 105 + +;---------------------------------------------------------------------------------- +;cooler_table cooler_count <=32 +;---------------------------------------------------------------------------------- +[cooler_table] +cooler_count = 9 +cooler0 = "1296000 4 4294967295 0" +cooler1 = "1200000 4 4294967295 0" +cooler2 = "1008000 4 4294967295 0" +cooler3 = "816000 4 4294967295 0" +cooler4 = "648000 4 4294967295 0" +cooler5 = "480000 4 4294967295 0" +cooler6 = "480000 3 4294967295 0" +cooler7 = "480000 2 4294967295 0" +cooler8 = "480000 1 4294967295 0" + +[nand0_para] +nand_support_2ch = 0 + +nand0_used = 0 +nand0_we = port:PC00<2> +nand0_ale = port:PC01<2> +nand0_cle = port:PC02<2> +nand0_ce1 = port:PC03<2> +nand0_ce0 = port:PC04<2> +nand0_nre = port:PC05<2> +nand0_rb0 = port:PC06<2> +nand0_rb1 = port:PC07<2> +nand0_d0 = port:PC08<2> +nand0_d1 = port:PC09<2> +nand0_d2 = port:PC10<2> +nand0_d3 = port:PC11<2> +nand0_d4 = port:PC12<2> +nand0_d5 = port:PC13<2> +nand0_d6 = port:PC14<2> +nand0_d7 = port:PC15<2> +nand0_ndqs = port:PC16<2> + +;---------------------------------------------------------------------------------- +;disp init configuration +; +;disp_mode (0:screen0; 1:screen1) +;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;) +;screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50) +; (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:PAL 14:NTSC) +;fbx format (0:ARGB 1:ABGR 2:RGBA 3:BGRA 5:RGB565 8:RGB888 12:ARGB4444 16:ARGB1555 18:RGBA5551) +;fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0) +;lcdx_backlight (lcd init backlight,the range:[0,256],default:197 +;---------------------------------------------------------------------------------- +[disp_init] +disp_init_enable = 1 +disp_mode = 0 +screen0_output_type = 3 +screen0_output_mode = 10 +screen1_output_type = 0 +screen1_output_mode = 0 +fb0_format = 0 +fb0_width = 0 +fb0_height = 0 + +fb1_format = 0 +fb1_width = 0 +fb1_height = 0 + +;---------------------------------------------------------------------------------- +;hdmi configuration +;---------------------------------------------------------------------------------- +[hdmi_para] +hdmi_used = 1 +hdmi_power = "vcc-hdmi-18" +hdcp_enable = 0 + +[tv_para] +tv_used = 0 +tv_dac_used = 1 +tv_dac_src0 = 0 + +;---------------------------------------------------------------------------------- +;pwm config +;---------------------------------------------------------------------------------- +[pwm0_para] +pwm_used = 0 +pwm_positive = port:PA05<3><0> + +;------------------------------------------------------------------------------; +; 10/100/100Mbps Ethernet MAC Controller Configure ; +;------------------------------------------------------------------------------; +; Options: ; +; gmac_used --- 0: not used, 1: external phy, 2: internal phy ; +; gmac_powerx -- A[:B] A: axp channel, B: voltage value ; +; If set gamc_phy to use internal PHY, do not config port ; +;------------------------------------------------------------------------------; +; MII RMII MII RMII MII RMII ; +; PD00 * PD06 * * PD12 * * ; +; PD01 * PD07 * PD13 * * ; +; PD02 * * PD08 * PD14 * ; +; PD03 * * PD09 * * PD15 * ; +; PD04 * PD10 * * PD16 * * ; +; PD05 * PD11 * * PD17 * * ; +;------------------------------------------------------------------------------; +[gmac0] +gmac_used = 2 +gmac_power1 = + +;-------------------------------------------------------------------------------- +;vip (video input port) configuration +;vip_used: 0:disable 1:enable +;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer +;vip_dev_qty: The quantity of devices linked to capture bus +; +;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and +; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! +; +;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1, +;vip_dev(x)_pos must be configured! +; +;vip_dev(x)_isp_used 0:not use isp 1:use isp +;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb +;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby +;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable +;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable +;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply +;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply +;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply +;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply +;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply +;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply +;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply +;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply +;x indicates the index of the devices which are linked to the same capture bus +;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 +;fill handle string as below: +;axp22_eldo3 +;axp22_dldo4 +;axp22_eldo2 +;fill handle string "" when not using any pmu power supply +;-------------------------------------------------------------------------------- +[csi0] +vip_used = 0 +vip_mode = 0 +vip_dev_qty = 1 +vip_define_sensor_list = 0 + +vip_csi_pck = port:PE00<2> +vip_csi_mck = port:PE01<2> +vip_csi_hsync = port:PE02<2> +vip_csi_vsync = port:PE03<2> +vip_csi_d0 = port:PE04<2> +vip_csi_d1 = port:PE05<2> +vip_csi_d2 = port:PE06<2> +vip_csi_d3 = port:PE07<2> +vip_csi_d4 = port:PE08<2> +vip_csi_d5 = port:PE09<2> +vip_csi_d6 = port:PE10<2> +vip_csi_d7 = port:PE11<2> +vip_csi_sck = port:PE12<2> +vip_csi_sda = port:PE13<2> + +vip_dev0_mname = "gc2035" +vip_dev0_pos = "front" +vip_dev0_lane = 1 +vip_dev0_twi_id = 2 +vip_dev0_twi_addr = 0x78 +vip_dev0_isp_used = 0 +vip_dev0_fmt = 0 +vip_dev0_stby_mode = 0 +vip_dev0_vflip = 1 +vip_dev0_hflip = 1 +vip_dev0_iovdd = "" +vip_dev0_iovdd_vol = 2800000 +vip_dev0_avdd = "" +vip_dev0_avdd_vol = 2800000 +vip_dev0_dvdd = "" +vip_dev0_dvdd_vol = 1800000 +vip_dev0_afvdd = "" +vip_dev0_afvdd_vol = 2800000 +vip_dev0_power_en = port:PA17<1><1> +vip_dev0_reset = port:PE14<1><1> +vip_dev0_pwdn = port:PE15<1><0> +vip_dev0_flash_en = +vip_dev0_flash_mode = +vip_dev0_af_pwdn = + +vip_dev0_act_used = 0 +vip_dev0_act_name = "ad5820_act" +vip_dev0_act_slave = 0x18 + + +vip_dev1_mname = "" +vip_dev1_pos = "rear" +vip_dev1_lane = 1 +vip_dev1_twi_id = 0 +vip_dev1_twi_addr = +vip_dev1_isp_used = 0 +vip_dev1_fmt = 1 +vip_dev1_stby_mode = 0 +vip_dev1_vflip = 0 +vip_dev1_hflip = 0 +vip_dev1_iovdd = "" +vip_dev1_iovdd_vol = 2800000 +vip_dev1_avdd = "" +vip_dev1_avdd_vol = 2800000 +vip_dev1_dvdd = "" +vip_dev1_dvdd_vol = 1500000 +vip_dev1_afvdd = "" +vip_dev1_afvdd_vol = 2800000 +vip_dev1_power_en = +vip_dev1_reset = +vip_dev1_pwdn = +vip_dev1_flash_en = +vip_dev1_flash_mode = +vip_dev1_af_pwdn = + +;---------------------------------------------------------------------------------- +;Deinterlace configuration +;---------------------------------------------------------------------------------- +[di_para] +di_used = 1 +di_by_pass = 0 + +;-------------------------------------------------------------------------------- +; SDMMC PINS MAPPING | +; ------------------------------------------------------------------------------| +; Config Guide | +; sdc_used: 1-enable card, 0-disable card | +; sdc_detmode: card detect mode | +; 1-detect card by gpio polling | +; 2-detect card by gpio irq(must use IO with irq function) | +; 3-no detect, always in for boot card | +; 4-manually insert and remove by /proc/driver/sunxi-mmc.x/insert| +; sdc_buswidth: card bus width, 1-1bit, 4-4bit, 8-8bit | +; sdc_use_wp: 1-with write protect IO, 0-no write protect IO | +; sdc_isio: for sdio card | +; sdc_regulator: power control.if card supports UHS-I/DDR and HS200 timing for| +; SD3.0 or eMMC4.5, regulator must be configured. the value is | +; the ldo name of AXP221, eg: sdc_regulator = "axp22_eldo2" | +; other: GPIO Mapping configuration | +; ------------------------------------------------------------------------------| +; Note: | +; 1 if detmode=2, sdc_det's config=6 | +; else if detmode=1, sdc_det's config=0 | +; else sdc_det IO is not necessary | +; 2 if the customer wants to support UHS-I and HS200 features, he must provide| +; an independent power supply for the card. This is only used in platforms | +; that supports SD3.0 cards and eMMC4.4+ flashes | +;-------------------------------------------------------------------------------- +[mmc0_para] +sdc_used = 1 +sdc_detmode = 3 +sdc_buswidth = 4 +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_d1 = port:PF00<2><1><2> +sdc_d2 = port:PF05<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_det = port:PF06<0><1><2> +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" + +[mmc1_para] +sdc_used = 0 +sdc_detmode = 4 +sdc_buswidth = 4 +sdc_clk = port:PG00<2><1><3> +sdc_cmd = port:PG01<2><1><3> +sdc_d0 = port:PG02<2><1><3> +sdc_d1 = port:PG03<2><1><3> +sdc_d2 = port:PG04<2><1><3> +sdc_d3 = port:PG05<2><1><3> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 1 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +[mmc2_para] +sdc_used = 0 +sdc_detmode = 3 +sdc_buswidth = 8 +sdc_clk = port:PC05<3><1><2> +sdc_cmd = port:PC06<3><1><2> +sdc_d0 = port:PC08<3><1><2> +sdc_d1 = port:PC09<3><1><2> +sdc_d2 = port:PC10<3><1><2> +sdc_d3 = port:PC11<3><1><2> +sdc_d4 = port:PC12<3><1><2> +sdc_d5 = port:PC13<3><1><2> +sdc_d6 = port:PC14<3><1><2> +sdc_d7 = port:PC15<3><1><2> +emmc_rst = port:PC16<3><1><2> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +; ------------------------------------------------------------------------------| +; sim card configuration +;-------------------------------------------------------------------------------- +[smc_para] +smc_used = 0 +smc_rst = port:PA09<2> +smc_vppen = port:PA20<3> +smc_vppp = port:PA21<3> +smc_det = port:PA10<2> +smc_vccen = port:PA06<2> +smc_sck = port:PA07<2> +smc_sda = port:PA08<2> + +;-------------------------------- +; [usbc0]: Controller 0 configuration. +; usb used: USB enable flag. Set, indicating that the system USB module is available, is set to 0, it means that the system USB is disabled. +; usb_port_type: USB port usage. 0: device only; 1: host only; 2: OTG +; usb_detect_type: USB port of checking. 0: not detected; 1: vbus / id checks; 2: id / dpdm check +; usb_id_gpio: USB ID pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: USB DET_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_drv_vbus_gpio: USB DRY_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: "axp_ctrl", represents axp offer +; usb_restrict_gpio: usb limiting control pin +; usb_restric_flag: usb limiting standard set +;-------------------------------- +;-------------------------------- +; USB0 OTG +;-------------------------------- +[usbc0] +usb_used = 1 +usb_port_type = 2 +usb_detect_type = 0 +usb_id_gpio = port:PG12<0><1> +usb_det_vbus_gpio = port:PG12<0><1> +usb_drv_vbus_gpio = port:PL02<1><0><0> +usb_host_init_state = 1 +usb_restrict_gpio = +usb_restric_flag = 0 +usb_restric_voltage = 3550000 +usb_restric_capacity= 5 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB1 Host +;-------------------------------- +[usbc1] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB2 Host +;-------------------------------- +[usbc2] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB3 Host +;-------------------------------- +[usbc3] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB Device +;-------------------------------- +[usb_feature] +vendor_id = 0x18D1 +mass_storage_id = 0x0001 +adb_id = 0x0002 + +manufacturer_name = "USB Developer" +product_name = "Android" +serial_number = "20080411" + +[msc_feature] +vendor_name = "USB 2.0" +product_name = "USB Flash Driver" +release = 100 +luns = 3 + +[serial_feature] +serial_unique = 0 + +;-------------------------------------------------------------------------------- +;wifi/bt/fm/gps/nfc modules configuration +;module_power0: axp used by module, "axp22_dldo1" - use dldo1, not use keep it empty +;module_power0_vol: power0 voltage, mv; +;chip_en: enable chip io +;lpo_use_apclk: ""- not use, "losc_out"- a23/33/H3, "ac10032k1"、"ac10032k2"、"ac10032k3"- a80 +;-------------------------------------------------------------------------------- +[module_para] +module_power0 = "vcc-wifi-33" +module_power0_vol = 0 +module_power1 = +module_power1_vol = +module_power2 = +module_power2_vol = +module_power3 = +module_power3_vol = +chip_en = +lpo_use_apclk = + +;-------------------------------------------------------------------------------- +;wifi configuration +;wifi_sdc_id: 0- SDC0, 1- SDC1, 2- SDC2, 3- SDC3 +;wifi_usbc_id: 0- USB0, 1- USB1, 2- USB2 +;wifi_usbc_type: 1- EHCI(speed 2.0), 2- OHCI(speed 1.0) +;wl_reg_on: wifi function enable pin +;wl_host_wake: wlan device wake-up host pin +;wl_host_wake_invert: whether wl_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[wifi_para] +wifi_used = 0 +wifi_sdc_id = 1 +wifi_usbc_id = +wifi_usbc_type = +wl_reg_on = port:PL07<1><0> +wl_host_wake = port:PG10<0><0> +wl_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;bluetooth configuration +;bt_used: 0 - no used, 1- used +;bt_uard_id: 0 - uart0, 1- uart1, 2- uart2 +;bt_rst_n: bt function enable io +;bt_wake: host wake-up bluetooth device +;bt_host_wake: bt device wake-up host +;bt_host_wake_invert: whether bt_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[bt_para] +bt_used = 0 +bt_uart_id = 1 +bt_rst_n = +bt_wake = +bt_host_wake = +bt_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;daudio_master:1: SND_SOC_DAIFMT_CBM_CFM(codec clk & FRM master) use +; 2: SND_SOC_DAIFMT_CBS_CFM(codec clk slave & FRM master) not use +; 3: SND_SOC_DAIFMT_CBM_CFS(codec clk master & frame slave) not use +; 4: SND_SOC_DAIFMT_CBS_CFS(codec clk & FRM slave) use +;daudio_select:0 is pcm.1 is i2s +;audio_format: 1:SND_SOC_DAIFMT_I2S(standard i2s format). use +; 2:SND_SOC_DAIFMT_RIGHT_J(right justfied format). +; 3:SND_SOC_DAIFMT_LEFT_J(left justfied format) +; 4:SND_SOC_DAIFMT_DSP_A(pcm. MSB is available on 2nd BCLK rising edge after LRC rising edge). use +; 5:SND_SOC_DAIFMT_DSP_B(pcm. MSB is available on 1nd BCLK rising edge after LRC rising edge) +;signal_inversion:1:SND_SOC_DAIFMT_NB_NF(normal bit clock + frame) use +; 2:SND_SOC_DAIFMT_NB_IF(normal BCLK + inv FRM) +; 3:SND_SOC_DAIFMT_IB_NF(invert BCLK + nor FRM) use +; 4:SND_SOC_DAIFMT_IB_IF(invert BCLK + FRM) +;over_sample_rate: support 128fs/192fs/256fs/384fs/512fs/768fs +;sample_resolution :16bits/20bits/24bits +;word_select_size :16bits/20bits/24bits/32bits +;pcm_sync_period :16/32/64/128/256 +;msb_lsb_first :0: msb first; 1: lsb first +;sign_extend :0: zero pending; 1: sign extend +;slot_index :slot index: 0: the 1st slot - 3: the 4th slot +;slot_width :8 bit width / 16 bit width +;frame_width :0: long frame = 2 clock width; 1: short frame +;tx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;rx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;-------------------------------------------------------------------------------- +[pcm0] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PA18<2><1> +i2s_bclk = port:PA19<2><1> +i2s_dout0 = port:PA20<2><1> +i2s_din = port:PA21<2><1> + +[pcm1] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PG10<2><1> +i2s_bclk = port:PG11<2><1> +i2s_dout0 = port:PG12<2><1> +i2s_din = port:PG13<2><1> + +[audio0] +audio_used = 1 +lineout_vol = 0x1f +cap_vol = 0x5 +audio_hp_ldo = "none" +adcagc_used = 0 +adcdrc_used = 0 +dacdrc_used = 0 +adchpf_used = 0 +dachpf_used = 0 +audio_pa_ctrl = port:PA16<1><0> + +[spdif0] +spdif_used = 0 +spdif_dout = port:PA17<2><1> + +[audiohub] +hub_used = 1 +codec_used = 1 +spdif_used = 0 +hdmi_used = 1 + +;---------------------------------------------------------------------------------- +;ir rx --- infra remote configuration +;---------------------------------------------------------------------------------- +[s_cir0] +ir_used = 1 +ir_rx = port:PL11<2><1> +ir_power_key_code0 = 0x57 +ir_addr_code0 = 0x9f00 +ir_power_key_code1 = 0x1a +ir_addr_code1 = 0xfb04 +ir_power_key_code2 = 0x14 +ir_addr_code2 = 0x7F80 +ir_power_key_code3 = 0x15 +ir_addr_code3 = 0x7F80 +ir_power_key_code4 = 0x0b +ir_addr_code4 = 0xF708 +ir_power_key_code5 = 0x03 +ir_addr_code5 = 0x00EF +ir_power_key_code6 = 0x9f +ir_addr_code6 = 0x4CB3 +ir_power_key_code7 = 0x0a +ir_addr_code7 = 0x7748 +ir_power_key_code8 = 0x45 +ir_addr_code8 = 0xbd02 +ir_power_key_code9 = 0x4d +ir_addr_code9 = 0xde21 +ir_power_key_code10 = 0x18 +ir_addr_code10 = 0xfe01 +ir_power_key_code11 = 0x57 +ir_addr_code11 = 0xff00 +ir_power_key_code12 = 0x4d +ir_addr_code12 = 0xff40 + +;---------------------------------------------------------------------------------- +;ir tx--- infra remote configuration +;---------------------------------------------------------------------------------- +[cir] +ir_used = 1 +ir_tx = port:PH07<2> + +;---------------------------------------------------------------------------------- +; dvfs voltage-frequency table configuration +; +; pmuic_type:0:none, 1:gpio, 2:i2c +; pmu_gpio0: gpio config. +; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low. +; +; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk +; 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator +; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz +; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz +; +; LV_count: count of LV_freq/LV_volt, must be < 16 +; +; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz] +; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz] +; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz] +; LV4: core vdd is 1.20v if cpu frequency is (816Mhz, 1008Mhz] +; LV5: core vdd is 1.10v if cpu frequency is (648Mhz, 816Mhz] +; LV6: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV7: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV8: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; +;---------------------------------------------------------------------------------- +[dvfs_table] +pmuic_type = 2 +pmu_gpio0 = port:PL06<1><1><2><1> +pmu_level0 = 11300 +pmu_level1 = 1100 +extremity_freq = 1296000000 +max_freq = 1200000000 +min_freq = 480000000 +LV_count = 7 +LV1_freq = 1296000000 +LV1_volt = 1320 +LV2_freq = 1200000000 +LV2_volt = 1240 +LV3_freq = 1104000000 +LV3_volt = 1180 +LV4_freq = 1008000000 +LV4_volt = 1140 +LV5_freq = 960000000 +LV5_volt = 1080 +LV6_freq = 816000000 +LV6_volt = 1020 +LV7_freq = 480000000 +LV7_volt = 980 + +[gpu_dvfs_table] +G_LV_count = 3 +G_LV0_freq = 312000000 +G_LV0_volt = 1200000 +G_LV1_freq = 384000000 +G_LV1_volt = 1200000 +G_LV2_freq = 456000000 +G_LV2_volt = 1200000 + +;---------------------------------------------------------------------------------- +;virtual device +;virtual device for pinctrl testing +;device have pin PA1 PA2 +;---------------------------------------------------------------------------------- +[Vdevice] +Vdevice_used = 0 +Vdevice_0 = port:PH10<5><1><2> +Vdevice_1 = port:PH11<5><1><2> + +;---------------------------------------------------------------------------------- +;s_uart0 config parameters +;s_uart_used --s_uart0 whether used for arisc debugging +;---------------------------------------------------------------------------------- +[s_uart0] +s_uart_used = 0 +s_uart_tx = port:PL02<2> +s_uart_rx = port:PL03<2> + +;---------------------------------------------------------------------------------- +;s_rsb0 config parameters +;s_rsb_used --s_rsb0 whether used for arisc +;---------------------------------------------------------------------------------- +[s_rsb0] +s_rsb_used = 1 +s_rsb_sck = port:PL00<2><1><2> +s_rsb_sda = port:PL01<2><1><2> + +;---------------------------------------------------------------------------------- +;s_jtag0 config parameters +;s_jtag0_used --s_jtag0 whether used for arisc +; +;---------------------------------------------------------------------------------- +[s_jtag0] +s_jtag_used = 0 +s_jtag_tms = port:PL04<2><1><2> +s_jtag_tck = port:PL05<2><1><2> +s_jtag_tdo = port:PL06<2><1><2> +s_jtag_tdi = port:PL07<2><1><2> + +;---------------------------------------------------------------------------------- +;s_powchk cpus power check +;s_powchk_used --power check whether used for arisc in super standby +; bit31:enable power updat, bit1:wakeup when power state exception +; bit0:wakeup when power consumption exception +;s_power_reg the expected regs stand for power on/off state +;s_system_power the limit maxmum power consumption when super standby (unit: mw) +; +;---------------------------------------------------------------------------------- +[s_powchk] +s_powchk_used = 0x80000000 +s_power_reg = 0x00000000 +s_system_power = 50 + +;---------------------------------------------------------------------------------- +;scr configuration +;---------------------------------------------------------------------------------- +[sim0] +scr_used = 0 +scr_vccen = port:PA06<2> +scr_slk = port:PA07<2> +scr_sda = port:PA08<2> +scr_rst = port:PA09<2> +scr_det = port:PA10<2> + +;-------------------------------------------------------------------------------- +;tsc configuration +;-------------------------------------------------------------------------------- +[ts0] +tsc_used = 0 +tsc_clk = port:PE00<3> +tsc_err = port:PE01<3> +tsc_sync = port:PE02<3> +tsc_dvld = port:PE03<3> +tsc_d0 = port:PE04<3> +tsc_d1 = port:PE05<3> +tsc_d2 = port:PE06<3> +tsc_d3 = port:PE07<3> +tsc_d4 = port:PE08<3> +tsc_d5 = port:PE09<3> +tsc_d6 = port:PE10<3> +tsc_d7 = port:PE11<3> + +;-------------------------------------------------------------------------------- +;gpio key +;-------------------------------------------------------------------------------- +[gpio_power_key] +key_used = 1 +key_io = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +; key para +; +; key_used --0:not used, 1:used +; key_cnt --how many key button attach to keyadc. +; key*_vol --the threshold of input voltage of key. +; +; For example: if key2_vol < $(keyadc value) < key3_vol, then key3 be reported. +;---------------------------------------------------------------------------------- +[key_para] +key_used = 0 +key_cnt = 5 +key1_vol = 222 +key2_vol = 444 +key3_vol = 666 +key4_vol = 857 +key5_vol = 2000 + +;---------------------------------------------------------------------------------- +;display seven segment para +;---------------------------------------------------------------------------------- +[d7s_para] +d7s_used = 0 +din_gpio = port:PD00<1><1> +clk_gpio = port:PD01<1><1> +stb_gpio = port:PD02<1><1> + +;---------------------------------------------------------------------------------- +;mali parameters +;---------------------------------------------------------------------------------- +[mali_para] +mali_used = 1 +mali_clkdiv = 1 +mali_extreme_freq = 600 +mali_extreme_vol = 1400 + +;---------------------------------------------------------------------------------- +;1wire parameters (default - PA20) +;---------------------------------------------------------------------------------- +[w1_para] +w1_used = 1 +gpio = 20 diff --git a/projects/H3/sys_config/opipcplus.fex b/projects/H3/sys_config/opipcplus.fex new file mode 100755 index 00000000000..62570ee4be7 --- /dev/null +++ b/projects/H3/sys_config/opipcplus.fex @@ -0,0 +1,1074 @@ +[product] +version = "100" +machine = "opipcplus" + +;--------------------------------------------------------------------------------------------------------- +; eraseflag - 1 erase data partition, 0 - do not erase data partition +; next_work - action after burn, 0x0 by config, 0x1, normal, 0x2 reboot 0x3 ,shutdown,0x4 reupdate ,0x5 boot +;--------------------------------------------------------------------------------------------------------- +[platform] +debug_mode = 1 +eraseflag = 1 +next_work = 2 + +;---------------------------------------------------------------------------------- +;[target] system bootup configuration +;boot_clock = CPU boot frequency, Unit: MHz +;storage_type = boot medium, 0-nand, 1-card0, 2-card2, -1(defualt)auto scan +;---------------------------------------------------------------------------------- +[target] +boot_clock = 1008 +storage_type = -1 + +;--------------------------------------------------------------------------------- +; used : 1: used this config, 0: not +; start_type : 1: start system directly when power supply, 0: wait IR/KEY to power on +; irkey_used : 1: ir key used, 0: not +; pmukey_used: 1: physical button used, 0: not +; led_power : 1: light, 0: off +; led_state : 1: light, 0: off +;--------------------------------------------------------------------------------- +[box_start_os] +used = 1 +start_type = 1 +irkey_used = 1 +pmukey_used = 1 +pmukey_num = 3 +led_power = 0 +led_state = 0 + +;--------------------------------------------------------------------------------------------------------- +; if 1 == standby_mode, then support super standby; +; else, support normal standby. +;--------------------------------------------------------------------------------------------------------- +[pm_para] +standby_mode = 1 + +; THIS PARAMETERS SEEMS TO BE USED ONLY FOR TESTING +[card0_boot_para] +card_ctrl = 0 +card_high_speed = 1 +card_line = 4 +sdc_d1 = port:PF00<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_d2 = port:PF05<2><1><2> + +[twi_para] +twi_port = 0 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[uart_para] +uart_debug_port = 0 +uart_debug_tx = port:PA04<2><1> +uart_debug_rx = port:PA05<2><1> + +[force_uart_para] +force_uart_port = 0 +force_uart_tx = port:PF02<3><1> +force_uart_rx = port:PF04<3><1> + +[jtag_para] +jtag_enable = 0 +jtag_ms = port:PA00<3> +jtag_ck = port:PA01<3> +jtag_do = port:PA02<3> +jtag_di = port:PA03<3> + +[clock] +pll_video = 297 +pll_ve = 402 +pll_periph0 = 600 +pll_gpu = 576 +pll_periph1 = 600 +pll_de = 864 + +;***************************************************************************** +;sdram configuration +; +;dram_para2 = 0x00001200 ;Representative enable dram Dual +;dram_para2 = 0x00001100 ;on behalf of a single channel is enabled dram +;***************************************************************************** +[dram_para] +dram_clk = 624 +dram_type = 3 +dram_zq = 0x3b3bfb +dram_odt_en = 0x1 +dram_para1 = 0x10E40000 +dram_para2 = 0x0000 +dram_mr0 = 0x1840 +dram_mr1 = 0x40 +dram_mr2 = 0x18 +dram_mr3 = 0x2 +dram_tpr0 = 0x0048A192 +dram_tpr1 = 0x01C2418D +dram_tpr2 = 0x00076051 +dram_tpr3 = 0 +dram_tpr4 = 0 +dram_tpr5 = 0 +dram_tpr6 = 100 +dram_tpr7 = 0 +dram_tpr8 = 0 +dram_tpr9 = 0 +dram_tpr10 = 0 +dram_tpr11 = 0x6aaa0000 +dram_tpr12 = 0x7979 +dram_tpr13 = 0x800800 + +;--------------------------------------------------------------------------------------------------------- +; wakeup_src_para: +; sometimes, u would like to add more wakeup src in standby mode, these para will be +; help; +; u need to make sure the standby mode support the wakeup src. Also, some hw +; condition must be guaranteed. +; including: +; cpu_en: power on or off. +; 1: mean power on +; 0: mean power off +; cpu_freq: indicating lowest freq. unit is Mhz; +; dram selfresh_en: selfresh or not. +; 1: enable enter selfresh +; 0: disable enter selfresh +; dram_pll: if not enter selfresh, indicating lowest freq. unit is Mhz; +; wakeup_src: to make the scenario work, the wakeup src is needed. +;--------------------------------------------------------------------------------------------------------- +[wakeup_src_para] +cpu_en = 0 +cpu_freq = 48 +pll_ratio = 273 +dram_selfresh_en = 1 +dram_freq = 36 +wakeup_src0 = +wakeup_src_wl = port:PG10<4><0> +wakeup_src_bt = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +;i2c configuration +;---------------------------------------------------------------------------------- +[twi0] +twi_used = 1 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[twi1] +twi_used = 0 +twi_scl = port:PA18<3> +twi_sda = port:PA19<3> + +[twi2] +twi_used = 0 +twi_scl = port:PE12<3> +twi_sda = port:PE13<3> + +;---------------------------------------------------------------------------------- +;uart configuration +;uart_type --- 2 (2 wire), 4 (4 wire), 8 (8 wire, full function) +;---------------------------------------------------------------------------------- +[uart0] +uart_used = 1 +uart_port = 0 +uart_type = 2 +uart_tx = port:PA04<2><1> +uart_rx = port:PA05<2><1> + +[uart1] +uart_used = 0 +uart_port = 1 +uart_type = 2 +uart_tx = port:PG06<2><1> +uart_rx = port:PG07<2><1> +uart_rts = port:PG08<2><1> +uart_cts = port:PG09<2><1> + +[uart2] +uart_used = 0 +uart_port = 2 +uart_type = 4 +uart_tx = port:PA00<2><1> +uart_rx = port:PA01<2><1> +uart_rts = port:PA02<2><1> +uart_cts = port:PA03<2><1> + +[uart3] +uart_used = 0 +uart_port = 3 +uart_type = 2 +uart_tx = port:PA13<3><1> +uart_rx = port:PA14<3><1> +uart_rts = port:PA15<3><1> +uart_cts = port:PA16<3><1> + +;---------------------------------------------------------------------------------- +;SPI controller configuration +;---------------------------------------------------------------------------------- +[spi0] +spi_used = 1 +spi_cs_bitmap = 1 +spi_mosi = port:PC00<3> +spi_miso = port:PC01<3> +spi_sclk = port:PC02<3> +spi_cs0 = port:PC03<3><1> + +[spi1] +spi_used = 0 +spi_cs_bitmap = 1 +spi_cs0 = port:PA13<2><1> +spi_sclk = port:PA14<2> +spi_mosi = port:PA15<2> +spi_miso = port:PA16<2> + +;---------------------------------------------------------------------------------- +;SPI device configuration +;---------------------------------------------------------------------------------- +[spi_devices] +spi_dev_num = 1 + +[spi_board0] +modalias = "spidev" +max_speed_hz = 33000000 +bus_num = 0 +chip_select = 0 +mode = 0 +full_duplex = 1 +manual_cs = 0 + +[leds_para] +leds_used = 1 +green_led = port:PL10<1><0> +green_led_active_low = 1 +red_led = port:PA15<1><0> +red_led_active_low = 0 + +;---------------------------------------------------------------------------------- +;thermal configuration +;ths_trip_count : temperature trigger number +;ths_trip_0 : first temperature trigger +;ths_trip_1 : second temperature trigger +;ths_trip_2 : third temperature trigger, when upto this temperature, system shutdown +;ths_trip_0_min : first temperature trigger's min freq +;ths_trip_0_max : first temperature trigger's max freq +;ths_trip_1_min : second temperature trigger's min freq +;ths_trip_1_max : second temperature trigger's max freq +;---------------------------------------------------------------------------------- +[ths_para] +ths_used = 1 +ths_trip1_count = 6 +ths_trip1_0 = 75 +ths_trip1_1 = 80 +ths_trip1_2 = 85 +ths_trip1_3 = 90 +ths_trip1_4 = 95 +ths_trip1_5 = 105 +ths_trip1_6 = 0 +ths_trip1_7 = 0 +ths_trip1_0_min = 0 +ths_trip1_0_max = 1 +ths_trip1_1_min = 1 +ths_trip1_1_max = 2 +ths_trip1_2_min = 2 +ths_trip1_2_max = 3 +ths_trip1_3_min = 3 +ths_trip1_3_max = 4 +ths_trip1_4_min = 4 +ths_trip1_4_max = 8 +ths_trip1_5_min = 8 +ths_trip1_5_max = 8 +ths_trip1_6_min = 0 +ths_trip1_6_max = 0 +ths_trip2_count = 1 +ths_trip2_0 = 105 + +;---------------------------------------------------------------------------------- +;cooler_table cooler_count <=32 +;---------------------------------------------------------------------------------- +[cooler_table] +cooler_count = 9 +cooler0 = "1296000 4 4294967295 0" +cooler1 = "1200000 4 4294967295 0" +cooler2 = "1008000 4 4294967295 0" +cooler3 = "816000 4 4294967295 0" +cooler4 = "648000 4 4294967295 0" +cooler5 = "480000 4 4294967295 0" +cooler6 = "480000 3 4294967295 0" +cooler7 = "480000 2 4294967295 0" +cooler8 = "480000 1 4294967295 0" + +[nand0_para] +nand_support_2ch = 0 + +nand0_used = 0 +nand0_we = port:PC00<2> +nand0_ale = port:PC01<2> +nand0_cle = port:PC02<2> +nand0_ce1 = port:PC03<2> +nand0_ce0 = port:PC04<2> +nand0_nre = port:PC05<2> +nand0_rb0 = port:PC06<2> +nand0_rb1 = port:PC07<2> +nand0_d0 = port:PC08<2> +nand0_d1 = port:PC09<2> +nand0_d2 = port:PC10<2> +nand0_d3 = port:PC11<2> +nand0_d4 = port:PC12<2> +nand0_d5 = port:PC13<2> +nand0_d6 = port:PC14<2> +nand0_d7 = port:PC15<2> +nand0_ndqs = port:PC16<2> + +;---------------------------------------------------------------------------------- +;disp init configuration +; +;disp_mode (0:screen0; 1:screen1) +;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;) +;screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50) +; (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:PAL 14:NTSC) +;fbx format (0:ARGB 1:ABGR 2:RGBA 3:BGRA 5:RGB565 8:RGB888 12:ARGB4444 16:ARGB1555 18:RGBA5551) +;fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0) +;lcdx_backlight (lcd init backlight,the range:[0,256],default:197 +;---------------------------------------------------------------------------------- +[disp_init] +disp_init_enable = 1 +disp_mode = 0 +screen0_output_type = 3 +screen0_output_mode = 10 +screen1_output_type = 0 +screen1_output_mode = 0 +fb0_format = 0 +fb0_width = 0 +fb0_height = 0 + +fb1_format = 0 +fb1_width = 0 +fb1_height = 0 + +;---------------------------------------------------------------------------------- +;hdmi configuration +;---------------------------------------------------------------------------------- +[hdmi_para] +hdmi_used = 1 +hdmi_power = "vcc-hdmi-18" +hdcp_enable = 0 + +[tv_para] +tv_used = 0 +tv_dac_used = 1 +tv_dac_src0 = 0 + +;---------------------------------------------------------------------------------- +;pwm config +;---------------------------------------------------------------------------------- +[pwm0_para] +pwm_used = 0 +pwm_positive = port:PA05<3><0> + +;------------------------------------------------------------------------------; +; 10/100/100Mbps Ethernet MAC Controller Configure ; +;------------------------------------------------------------------------------; +; Options: ; +; gmac_used --- 0: not used, 1: external phy, 2: internal phy ; +; gmac_powerx -- A[:B] A: axp channel, B: voltage value ; +; If set gamc_phy to use internal PHY, do not config port ; +;------------------------------------------------------------------------------; +; MII RMII MII RMII MII RMII ; +; PD00 * PD06 * * PD12 * * ; +; PD01 * PD07 * PD13 * * ; +; PD02 * * PD08 * PD14 * ; +; PD03 * * PD09 * * PD15 * ; +; PD04 * PD10 * * PD16 * * ; +; PD05 * PD11 * * PD17 * * ; +;------------------------------------------------------------------------------; +[gmac0] +gmac_used = 2 +gmac_power1 = + +;-------------------------------------------------------------------------------- +;vip (video input port) configuration +;vip_used: 0:disable 1:enable +;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer +;vip_dev_qty: The quantity of devices linked to capture bus +; +;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and +; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! +; +;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1, +;vip_dev(x)_pos must be configured! +; +;vip_dev(x)_isp_used 0:not use isp 1:use isp +;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb +;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby +;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable +;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable +;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply +;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply +;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply +;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply +;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply +;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply +;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply +;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply +;x indicates the index of the devices which are linked to the same capture bus +;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 +;fill handle string as below: +;axp22_eldo3 +;axp22_dldo4 +;axp22_eldo2 +;fill handle string "" when not using any pmu power supply +;-------------------------------------------------------------------------------- +[csi0] +vip_used = 0 +vip_mode = 0 +vip_dev_qty = 1 +vip_define_sensor_list = 0 + +vip_csi_pck = port:PE00<2> +vip_csi_mck = port:PE01<2> +vip_csi_hsync = port:PE02<2> +vip_csi_vsync = port:PE03<2> +vip_csi_d0 = port:PE04<2> +vip_csi_d1 = port:PE05<2> +vip_csi_d2 = port:PE06<2> +vip_csi_d3 = port:PE07<2> +vip_csi_d4 = port:PE08<2> +vip_csi_d5 = port:PE09<2> +vip_csi_d6 = port:PE10<2> +vip_csi_d7 = port:PE11<2> +vip_csi_sck = port:PE12<2> +vip_csi_sda = port:PE13<2> + +vip_dev0_mname = "gc2035" +vip_dev0_pos = "front" +vip_dev0_lane = 1 +vip_dev0_twi_id = 2 +vip_dev0_twi_addr = 0x78 +vip_dev0_isp_used = 0 +vip_dev0_fmt = 0 +vip_dev0_stby_mode = 0 +vip_dev0_vflip = 1 +vip_dev0_hflip = 1 +vip_dev0_iovdd = "" +vip_dev0_iovdd_vol = 2800000 +vip_dev0_avdd = "" +vip_dev0_avdd_vol = 2800000 +vip_dev0_dvdd = "" +vip_dev0_dvdd_vol = 1800000 +vip_dev0_afvdd = "" +vip_dev0_afvdd_vol = 2800000 +vip_dev0_power_en = port:PA17<1><1> +vip_dev0_reset = port:PE14<1><1> +vip_dev0_pwdn = port:PE15<1><0> +vip_dev0_flash_en = +vip_dev0_flash_mode = +vip_dev0_af_pwdn = + +vip_dev0_act_used = 0 +vip_dev0_act_name = "ad5820_act" +vip_dev0_act_slave = 0x18 + + +vip_dev1_mname = "" +vip_dev1_pos = "rear" +vip_dev1_lane = 1 +vip_dev1_twi_id = 0 +vip_dev1_twi_addr = +vip_dev1_isp_used = 0 +vip_dev1_fmt = 1 +vip_dev1_stby_mode = 0 +vip_dev1_vflip = 0 +vip_dev1_hflip = 0 +vip_dev1_iovdd = "" +vip_dev1_iovdd_vol = 2800000 +vip_dev1_avdd = "" +vip_dev1_avdd_vol = 2800000 +vip_dev1_dvdd = "" +vip_dev1_dvdd_vol = 1500000 +vip_dev1_afvdd = "" +vip_dev1_afvdd_vol = 2800000 +vip_dev1_power_en = +vip_dev1_reset = +vip_dev1_pwdn = +vip_dev1_flash_en = +vip_dev1_flash_mode = +vip_dev1_af_pwdn = + +;---------------------------------------------------------------------------------- +;Deinterlace configuration +;---------------------------------------------------------------------------------- +[di_para] +di_used = 1 +di_by_pass = 0 + +;-------------------------------------------------------------------------------- +; SDMMC PINS MAPPING | +; ------------------------------------------------------------------------------| +; Config Guide | +; sdc_used: 1-enable card, 0-disable card | +; sdc_detmode: card detect mode | +; 1-detect card by gpio polling | +; 2-detect card by gpio irq(must use IO with irq function) | +; 3-no detect, always in for boot card | +; 4-manually insert and remove by /proc/driver/sunxi-mmc.x/insert| +; sdc_buswidth: card bus width, 1-1bit, 4-4bit, 8-8bit | +; sdc_use_wp: 1-with write protect IO, 0-no write protect IO | +; sdc_isio: for sdio card | +; sdc_regulator: power control.if card supports UHS-I/DDR and HS200 timing for| +; SD3.0 or eMMC4.5, regulator must be configured. the value is | +; the ldo name of AXP221, eg: sdc_regulator = "axp22_eldo2" | +; other: GPIO Mapping configuration | +; ------------------------------------------------------------------------------| +; Note: | +; 1 if detmode=2, sdc_det's config=6 | +; else if detmode=1, sdc_det's config=0 | +; else sdc_det IO is not necessary | +; 2 if the customer wants to support UHS-I and HS200 features, he must provide| +; an independent power supply for the card. This is only used in platforms | +; that supports SD3.0 cards and eMMC4.4+ flashes | +;-------------------------------------------------------------------------------- +[mmc0_para] +sdc_used = 1 +sdc_detmode = 1 +sdc_buswidth = 4 +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_d1 = port:PF00<2><1><2> +sdc_d2 = port:PF05<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_det = port:PF06<0><1><2> +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" + +[mmc1_para] +sdc_used = 1 +sdc_detmode = 4 +sdc_buswidth = 4 +sdc_clk = port:PG00<2><1><3> +sdc_cmd = port:PG01<2><1><3> +sdc_d0 = port:PG02<2><1><3> +sdc_d1 = port:PG03<2><1><3> +sdc_d2 = port:PG04<2><1><3> +sdc_d3 = port:PG05<2><1><3> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 1 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +[mmc2_para] +sdc_used = 1 +sdc_detmode = 1 +sdc_buswidth = 8 +sdc_clk = port:PC05<3><1><2> +sdc_cmd = port:PC06<3><1><2> +sdc_d0 = port:PC08<3><1><2> +sdc_d1 = port:PC09<3><1><2> +sdc_d2 = port:PC10<3><1><2> +sdc_d3 = port:PC11<3><1><2> +sdc_d4 = port:PC12<3><1><2> +sdc_d5 = port:PC13<3><1><2> +sdc_d6 = port:PC14<3><1><2> +sdc_d7 = port:PC15<3><1><2> +emmc_rst = port:PC16<3><1><2> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +; ------------------------------------------------------------------------------| +; sim card configuration +;-------------------------------------------------------------------------------- +[smc_para] +smc_used = 0 +smc_rst = port:PA09<2> +smc_vppen = port:PA20<3> +smc_vppp = port:PA21<3> +smc_det = port:PA10<2> +smc_vccen = port:PA06<2> +smc_sck = port:PA07<2> +smc_sda = port:PA08<2> + +;-------------------------------- +; [usbc0]: Controller 0 configuration. +; usb used: USB enable flag. Set, indicating that the system USB module is available, is set to 0, it means that the system USB is disabled. +; usb_port_type: USB port usage. 0: device only; 1: host only; 2: OTG +; usb_detect_type: USB port of checking. 0: not detected; 1: vbus / id checks; 2: id / dpdm check +; usb_id_gpio: USB ID pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: USB DET_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_drv_vbus_gpio: USB DRY_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: "axp_ctrl", represents axp offer +; usb_restrict_gpio: usb limiting control pin +; usb_restric_flag: usb limiting standard set +;-------------------------------- +;-------------------------------- +; USB0 OTG +;-------------------------------- +[usbc0] +usb_used = 1 +usb_port_type = 2 +usb_detect_type = 0 +usb_id_gpio = port:PG12<0><1> +usb_det_vbus_gpio = port:PG12<0><1> +usb_drv_vbus_gpio = port:PL02<1><0><0> +usb_host_init_state = 1 +usb_restrict_gpio = +usb_restric_flag = 0 +usb_restric_voltage = 3550000 +usb_restric_capacity= 5 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB1 Host +;-------------------------------- +[usbc1] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB2 Host +;-------------------------------- +[usbc2] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB3 Host +;-------------------------------- +[usbc3] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB Device +;-------------------------------- +[usb_feature] +vendor_id = 0x18D1 +mass_storage_id = 0x0001 +adb_id = 0x0002 + +manufacturer_name = "USB Developer" +product_name = "Android" +serial_number = "20080411" + +[msc_feature] +vendor_name = "USB 2.0" +product_name = "USB Flash Driver" +release = 100 +luns = 3 + +[serial_feature] +serial_unique = 0 + +;-------------------------------------------------------------------------------- +;wifi/bt/fm/gps/nfc modules configuration +;module_power0: axp used by module, "axp22_dldo1" - use dldo1, not use keep it empty +;module_power0_vol: power0 voltage, mv; +;chip_en: enable chip io +;lpo_use_apclk: ""- not use, "losc_out"- a23/33/H3, "ac10032k1"、"ac10032k2"、"ac10032k3"- a80 +;-------------------------------------------------------------------------------- +[module_para] +module_power0 = "vcc-wifi-33" +module_power0_vol = 0 +module_power1 = +module_power1_vol = +module_power2 = +module_power2_vol = +module_power3 = +module_power3_vol = +chip_en = +lpo_use_apclk = + +;-------------------------------------------------------------------------------- +;wifi configuration +;wifi_sdc_id: 0- SDC0, 1- SDC1, 2- SDC2, 3- SDC3 +;wifi_usbc_id: 0- USB0, 1- USB1, 2- USB2 +;wifi_usbc_type: 1- EHCI(speed 2.0), 2- OHCI(speed 1.0) +;wl_reg_on: wifi function enable pin +;wl_host_wake: wlan device wake-up host pin +;wl_host_wake_invert: whether wl_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[wifi_para] +wifi_used = 1 +wifi_sdc_id = 1 +wifi_usbc_id = +wifi_usbc_type = +wl_reg_on = port:PL07<1><0> +wl_host_wake = port:PG10<0><0> +wl_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;bluetooth configuration +;bt_used: 0 - no used, 1- used +;bt_uard_id: 0 - uart0, 1- uart1, 2- uart2 +;bt_rst_n: bt function enable io +;bt_wake: host wake-up bluetooth device +;bt_host_wake: bt device wake-up host +;bt_host_wake_invert: whether bt_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[bt_para] +bt_used = 0 +bt_uart_id = 1 +bt_rst_n = +bt_wake = +bt_host_wake = +bt_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;daudio_master:1: SND_SOC_DAIFMT_CBM_CFM(codec clk & FRM master) use +; 2: SND_SOC_DAIFMT_CBS_CFM(codec clk slave & FRM master) not use +; 3: SND_SOC_DAIFMT_CBM_CFS(codec clk master & frame slave) not use +; 4: SND_SOC_DAIFMT_CBS_CFS(codec clk & FRM slave) use +;daudio_select:0 is pcm.1 is i2s +;audio_format: 1:SND_SOC_DAIFMT_I2S(standard i2s format). use +; 2:SND_SOC_DAIFMT_RIGHT_J(right justfied format). +; 3:SND_SOC_DAIFMT_LEFT_J(left justfied format) +; 4:SND_SOC_DAIFMT_DSP_A(pcm. MSB is available on 2nd BCLK rising edge after LRC rising edge). use +; 5:SND_SOC_DAIFMT_DSP_B(pcm. MSB is available on 1nd BCLK rising edge after LRC rising edge) +;signal_inversion:1:SND_SOC_DAIFMT_NB_NF(normal bit clock + frame) use +; 2:SND_SOC_DAIFMT_NB_IF(normal BCLK + inv FRM) +; 3:SND_SOC_DAIFMT_IB_NF(invert BCLK + nor FRM) use +; 4:SND_SOC_DAIFMT_IB_IF(invert BCLK + FRM) +;over_sample_rate: support 128fs/192fs/256fs/384fs/512fs/768fs +;sample_resolution :16bits/20bits/24bits +;word_select_size :16bits/20bits/24bits/32bits +;pcm_sync_period :16/32/64/128/256 +;msb_lsb_first :0: msb first; 1: lsb first +;sign_extend :0: zero pending; 1: sign extend +;slot_index :slot index: 0: the 1st slot - 3: the 4th slot +;slot_width :8 bit width / 16 bit width +;frame_width :0: long frame = 2 clock width; 1: short frame +;tx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;rx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;-------------------------------------------------------------------------------- +[pcm0] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PA18<2><1> +i2s_bclk = port:PA19<2><1> +i2s_dout0 = port:PA20<2><1> +i2s_din = port:PA21<2><1> + +[pcm1] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PG10<2><1> +i2s_bclk = port:PG11<2><1> +i2s_dout0 = port:PG12<2><1> +i2s_din = port:PG13<2><1> + +[audio0] +audio_used = 1 +lineout_vol = 0x1f +cap_vol = 0x5 +audio_hp_ldo = "none" +adcagc_used = 0 +adcdrc_used = 0 +dacdrc_used = 0 +adchpf_used = 0 +dachpf_used = 0 +audio_pa_ctrl = port:PA16<1><0> + +[spdif0] +spdif_used = 0 +spdif_dout = port:PA17<2><1> + +[audiohub] +hub_used = 1 +codec_used = 1 +spdif_used = 0 +hdmi_used = 1 + +;---------------------------------------------------------------------------------- +;ir rx --- infra remote configuration +;---------------------------------------------------------------------------------- +[s_cir0] +ir_used = 1 +ir_rx = port:PL11<2><1> +ir_power_key_code0 = 0x57 +ir_addr_code0 = 0x9f00 +ir_power_key_code1 = 0x1a +ir_addr_code1 = 0xfb04 +ir_power_key_code2 = 0x14 +ir_addr_code2 = 0x7F80 +ir_power_key_code3 = 0x15 +ir_addr_code3 = 0x7F80 +ir_power_key_code4 = 0x0b +ir_addr_code4 = 0xF708 +ir_power_key_code5 = 0x03 +ir_addr_code5 = 0x00EF +ir_power_key_code6 = 0x9f +ir_addr_code6 = 0x4CB3 +ir_power_key_code7 = 0x0a +ir_addr_code7 = 0x7748 +ir_power_key_code8 = 0x45 +ir_addr_code8 = 0xbd02 +ir_power_key_code9 = 0x4d +ir_addr_code9 = 0xde21 +ir_power_key_code10 = 0x18 +ir_addr_code10 = 0xfe01 +ir_power_key_code11 = 0x57 +ir_addr_code11 = 0xff00 +ir_power_key_code12 = 0x4d +ir_addr_code12 = 0xff40 + +;---------------------------------------------------------------------------------- +;ir tx--- infra remote configuration +;---------------------------------------------------------------------------------- +[cir] +ir_used = 1 +ir_tx = port:PH07<2> + +;---------------------------------------------------------------------------------- +; dvfs voltage-frequency table configuration +; +; pmuic_type:0:none, 1:gpio, 2:i2c +; pmu_gpio0: gpio config. +; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low. +; +; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk +; 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator +; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz +; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz +; +; LV_count: count of LV_freq/LV_volt, must be < 16 +; +; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz] +; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz] +; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz] +; LV4: core vdd is 1.20v if cpu frequency is (816Mhz, 1008Mhz] +; LV5: core vdd is 1.10v if cpu frequency is (648Mhz, 816Mhz] +; LV6: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV7: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV8: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; +;---------------------------------------------------------------------------------- +[dvfs_table] +pmuic_type = 2 +pmu_gpio0 = port:PL06<1><1><2><1> +pmu_level0 = 11300 +pmu_level1 = 1100 +extremity_freq = 1296000000 +max_freq = 1200000000 +min_freq = 480000000 +LV_count = 7 +LV1_freq = 1296000000 +LV1_volt = 1320 +LV2_freq = 1200000000 +LV2_volt = 1240 +LV3_freq = 1104000000 +LV3_volt = 1180 +LV4_freq = 1008000000 +LV4_volt = 1140 +LV5_freq = 960000000 +LV5_volt = 1080 +LV6_freq = 816000000 +LV6_volt = 1020 +LV7_freq = 480000000 +LV7_volt = 980 + +[gpu_dvfs_table] +G_LV_count = 3 +G_LV0_freq = 312000000 +G_LV0_volt = 1200000 +G_LV1_freq = 384000000 +G_LV1_volt = 1200000 +G_LV2_freq = 456000000 +G_LV2_volt = 1200000 + +;---------------------------------------------------------------------------------- +;virtual device +;virtual device for pinctrl testing +;device have pin PA1 PA2 +;---------------------------------------------------------------------------------- +[Vdevice] +Vdevice_used = 0 +Vdevice_0 = port:PH10<5><1><2> +Vdevice_1 = port:PH11<5><1><2> + +;---------------------------------------------------------------------------------- +;s_uart0 config parameters +;s_uart_used --s_uart0 whether used for arisc debugging +;---------------------------------------------------------------------------------- +[s_uart0] +s_uart_used = 0 +s_uart_tx = port:PL02<2> +s_uart_rx = port:PL03<2> + +;---------------------------------------------------------------------------------- +;s_rsb0 config parameters +;s_rsb_used --s_rsb0 whether used for arisc +;---------------------------------------------------------------------------------- +[s_rsb0] +s_rsb_used = 1 +s_rsb_sck = port:PL00<2><1><2> +s_rsb_sda = port:PL01<2><1><2> + +;---------------------------------------------------------------------------------- +;s_jtag0 config parameters +;s_jtag0_used --s_jtag0 whether used for arisc +; +;---------------------------------------------------------------------------------- +[s_jtag0] +s_jtag_used = 0 +s_jtag_tms = port:PL04<2><1><2> +s_jtag_tck = port:PL05<2><1><2> +s_jtag_tdo = port:PL06<2><1><2> +s_jtag_tdi = port:PL07<2><1><2> + +;---------------------------------------------------------------------------------- +;s_powchk cpus power check +;s_powchk_used --power check whether used for arisc in super standby +; bit31:enable power updat, bit1:wakeup when power state exception +; bit0:wakeup when power consumption exception +;s_power_reg the expected regs stand for power on/off state +;s_system_power the limit maxmum power consumption when super standby (unit: mw) +; +;---------------------------------------------------------------------------------- +[s_powchk] +s_powchk_used = 0x80000000 +s_power_reg = 0x00000000 +s_system_power = 50 + +;---------------------------------------------------------------------------------- +;scr configuration +;---------------------------------------------------------------------------------- +[sim0] +scr_used = 0 +scr_vccen = port:PA06<2> +scr_slk = port:PA07<2> +scr_sda = port:PA08<2> +scr_rst = port:PA09<2> +scr_det = port:PA10<2> + +;-------------------------------------------------------------------------------- +;tsc configuration +;-------------------------------------------------------------------------------- +[ts0] +tsc_used = 0 +tsc_clk = port:PE00<3> +tsc_err = port:PE01<3> +tsc_sync = port:PE02<3> +tsc_dvld = port:PE03<3> +tsc_d0 = port:PE04<3> +tsc_d1 = port:PE05<3> +tsc_d2 = port:PE06<3> +tsc_d3 = port:PE07<3> +tsc_d4 = port:PE08<3> +tsc_d5 = port:PE09<3> +tsc_d6 = port:PE10<3> +tsc_d7 = port:PE11<3> + +;-------------------------------------------------------------------------------- +;gpio key +;-------------------------------------------------------------------------------- +[gpio_power_key] +key_used = 1 +key_io = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +; key para +; +; key_used --0:not used, 1:used +; key_cnt --how many key button attach to keyadc. +; key*_vol --the threshold of input voltage of key. +; +; For example: if key2_vol < $(keyadc value) < key3_vol, then key3 be reported. +;---------------------------------------------------------------------------------- +[key_para] +key_used = 0 +key_cnt = 5 +key1_vol = 222 +key2_vol = 444 +key3_vol = 666 +key4_vol = 857 +key5_vol = 2000 + +;---------------------------------------------------------------------------------- +;display seven segment para +;---------------------------------------------------------------------------------- +[d7s_para] +d7s_used = 0 +din_gpio = port:PD00<1><1> +clk_gpio = port:PD01<1><1> +stb_gpio = port:PD02<1><1> + +;---------------------------------------------------------------------------------- +;mali parameters +;---------------------------------------------------------------------------------- +[mali_para] +mali_used = 1 +mali_clkdiv = 1 +mali_extreme_freq = 600 +mali_extreme_vol = 1400 + +;---------------------------------------------------------------------------------- +;1wire parameters (default - PA20) +;---------------------------------------------------------------------------------- +[w1_para] +w1_used = 1 +gpio = 20 diff --git a/projects/H3/sys_config/opiplus.fex b/projects/H3/sys_config/opiplus.fex new file mode 100644 index 00000000000..ce60400ee91 --- /dev/null +++ b/projects/H3/sys_config/opiplus.fex @@ -0,0 +1,1097 @@ +[product] +version = "100" +machine = "opiplus" + +;--------------------------------------------------------------------------------------------------------- +; eraseflag - 1 erase data partition, 0 - do not erase data partition +; next_work - action after burn, 0x0 by config, 0x1, normal, 0x2 reboot 0x3 ,shutdown,0x4 reupdate ,0x5 boot +;--------------------------------------------------------------------------------------------------------- +[platform] +debug_mode = 1 +eraseflag = 1 +next_work = 2 + +;---------------------------------------------------------------------------------- +;[target] system bootup configuration +;boot_clock = CPU boot frequency, Unit: MHz +;storage_type = boot medium, 0-nand, 1-card0, 2-card2, -1(defualt)auto scan +;---------------------------------------------------------------------------------- +[target] +boot_clock = 1008 +storage_type = -1 + +;--------------------------------------------------------------------------------- +; used : 1: used this config, 0: not +; start_type : 1: start system directly when power supply, 0: wait IR/KEY to power on +; irkey_used : 1: ir key used, 0: not +; pmukey_used: 1: physical button used, 0: not +; led_power : 1: light, 0: off +; led_state : 1: light, 0: off +;--------------------------------------------------------------------------------- +[box_start_os] +used = 1 +start_type = 1 +irkey_used = 1 +pmukey_used = 1 +pmukey_num = 3 +led_power = 0 +led_state = 0 + +;--------------------------------------------------------------------------------------------------------- +; if 1 == standby_mode, then support super standby; +; else, support normal standby. +;--------------------------------------------------------------------------------------------------------- +[pm_para] +standby_mode = 1 + +; THIS PARAMETERS SEEMS TO BE USED ONLY FOR TESTING +[card0_boot_para] +card_ctrl = 0 +card_high_speed = 1 +card_line = 4 +sdc_d1 = port:PF00<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_d2 = port:PF05<2><1><2> + +[twi_para] +twi_port = 0 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[uart_para] +uart_debug_port = 0 +uart_debug_tx = port:PA04<2><1> +uart_debug_rx = port:PA05<2><1> + +[force_uart_para] +force_uart_port = 0 +force_uart_tx = port:PF02<3><1> +force_uart_rx = port:PF04<3><1> + +[jtag_para] +jtag_enable = 0 +jtag_ms = port:PA00<3> +jtag_ck = port:PA01<3> +jtag_do = port:PA02<3> +jtag_di = port:PA03<3> + +[clock] +pll_video = 297 +pll_ve = 402 +pll_periph0 = 600 +pll_gpu = 576 +pll_periph1 = 600 +pll_de = 864 + +;***************************************************************************** +;sdram configuration +; +;dram_para2 = 0x00001200 ;Representative enable dram Dual +;dram_para2 = 0x00001100 ;on behalf of a single channel is enabled dram +;***************************************************************************** +[dram_para] +dram_clk = 624 +dram_type = 3 +dram_zq = 0x3b3bfb +dram_odt_en = 0x1 +dram_para1 = 0x10E40000 +dram_para2 = 0x0000 +dram_mr0 = 0x1840 +dram_mr1 = 0x40 +dram_mr2 = 0x18 +dram_mr3 = 0x2 +dram_tpr0 = 0x0048A192 +dram_tpr1 = 0x01C2418D +dram_tpr2 = 0x00076051 +dram_tpr3 = 0 +dram_tpr4 = 0 +dram_tpr5 = 0 +dram_tpr6 = 100 +dram_tpr7 = 0 +dram_tpr8 = 0 +dram_tpr9 = 0 +dram_tpr10 = 0 +dram_tpr11 = 0x6aaa0000 +dram_tpr12 = 0x7979 +dram_tpr13 = 0x800800 + +;--------------------------------------------------------------------------------------------------------- +; wakeup_src_para: +; sometimes, u would like to add more wakeup src in standby mode, these para will be +; help; +; u need to make sure the standby mode support the wakeup src. Also, some hw +; condition must be guaranteed. +; including: +; cpu_en: power on or off. +; 1: mean power on +; 0: mean power off +; cpu_freq: indicating lowest freq. unit is Mhz; +; dram selfresh_en: selfresh or not. +; 1: enable enter selfresh +; 0: disable enter selfresh +; dram_pll: if not enter selfresh, indicating lowest freq. unit is Mhz; +; wakeup_src: to make the scenario work, the wakeup src is needed. +;--------------------------------------------------------------------------------------------------------- +[wakeup_src_para] +cpu_en = 0 +cpu_freq = 48 +; (cpu:apb:ahb) +pll_ratio = 273 +dram_selfresh_en = 1 +dram_freq = 36 +wakeup_src0 = +wakeup_src_wl = port:PG10<4><0> +wakeup_src_bt = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +;i2c configuration +;---------------------------------------------------------------------------------- +[twi0] +twi_used = 1 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[twi1] +twi_used = 0 +twi_scl = port:PA18<3> +twi_sda = port:PA19<3> + +[twi2] +twi_used = 0 +twi_scl = port:PE12<3> +twi_sda = port:PE13<3> + +;---------------------------------------------------------------------------------- +;uart configuration +;uart_type --- 2 (2 wire), 4 (4 wire), 8 (8 wire, full function) +;---------------------------------------------------------------------------------- +[uart0] +uart_used = 1 +uart_port = 0 +uart_type = 2 +uart_tx = port:PA04<2><1> +uart_rx = port:PA05<2><1> + +[uart1] +uart_used = 0 +uart_port = 1 +uart_type = 2 +uart_tx = port:PG06<2><1> +uart_rx = port:PG07<2><1> +uart_rts = port:PG08<2><1> +uart_cts = port:PG09<2><1> + +[uart2] +uart_used = 0 +uart_port = 2 +uart_type = 4 +uart_tx = port:PA00<2><1> +uart_rx = port:PA01<2><1> +uart_rts = port:PA02<2><1> +uart_cts = port:PA03<2><1> + +[uart3] +uart_used = 0 +uart_port = 3 +uart_type = 2 +uart_tx = port:PA13<3><1> +uart_rx = port:PA14<3><1> +uart_rts = port:PA15<3><1> +uart_cts = port:PA16<3><1> + +;---------------------------------------------------------------------------------- +;SPI controller configuration +;---------------------------------------------------------------------------------- +[spi0] +spi_used = 1 +spi_cs_bitmap = 1 +spi_mosi = port:PC00<3> +spi_miso = port:PC01<3> +spi_sclk = port:PC02<3> +spi_cs0 = port:PC03<3><1> + +[spi1] +spi_used = 0 +spi_cs_bitmap = 1 +spi_cs0 = port:PA13<2><1> +spi_sclk = port:PA14<2> +spi_mosi = port:PA15<2> +spi_miso = port:PA16<2> + +;---------------------------------------------------------------------------------- +;SPI device configuration +;---------------------------------------------------------------------------------- +[spi_devices] +spi_dev_num = 1 + +[spi_board0] +modalias = "spidev" +max_speed_hz = 33000000 +bus_num = 0 +chip_select = 0 +mode = 0 +full_duplex = 1 +manual_cs = 0 + +[leds_para] +leds_used = 1 +green_led = port:PL10<1><0> +green_led_active_low = 1 +red_led = port:PA15<1><0> +red_led_active_low = 0 + +;---------------------------------------------------------------------------------- +;thermal configuration +;ths_trip_count : temperature trigger number +;ths_trip_0 : first temperature trigger +;ths_trip_1 : second temperature trigger +;ths_trip_2 : third temperature trigger, when upto this temperature, system shutdown +;ths_trip_0_min : first temperature trigger's min freq +;ths_trip_0_max : first temperature trigger's max freq +;ths_trip_1_min : second temperature trigger's min freq +;ths_trip_1_max : second temperature trigger's max freq +;---------------------------------------------------------------------------------- +[ths_para] +ths_used = 1 +ths_trip1_count = 6 +ths_trip1_0 = 75 +ths_trip1_1 = 80 +ths_trip1_2 = 85 +ths_trip1_3 = 90 +ths_trip1_4 = 95 +ths_trip1_5 = 105 +ths_trip1_6 = 0 +ths_trip1_7 = 0 +ths_trip1_0_min = 0 +ths_trip1_0_max = 1 +ths_trip1_1_min = 1 +ths_trip1_1_max = 2 +ths_trip1_2_min = 2 +ths_trip1_2_max = 3 +ths_trip1_3_min = 3 +ths_trip1_3_max = 4 +ths_trip1_4_min = 4 +ths_trip1_4_max = 8 +ths_trip1_5_min = 8 +ths_trip1_5_max = 8 +ths_trip1_6_min = 0 +ths_trip1_6_max = 0 +ths_trip2_count = 1 +ths_trip2_0 = 105 + +;---------------------------------------------------------------------------------- +;cooler_table cooler_count <=32 +;---------------------------------------------------------------------------------- +[cooler_table] +cooler_count = 9 +cooler0 = "1296000 4 4294967295 0" +cooler1 = "1200000 4 4294967295 0" +cooler2 = "1008000 4 4294967295 0" +cooler3 = "816000 4 4294967295 0" +cooler4 = "648000 4 4294967295 0" +cooler5 = "480000 4 4294967295 0" +cooler6 = "480000 3 4294967295 0" +cooler7 = "480000 2 4294967295 0" +cooler8 = "480000 1 4294967295 0" + +[nand0_para] +nand_support_2ch = 0 + +nand0_used = 0 +nand0_we = port:PC00<2> +nand0_ale = port:PC01<2> +nand0_cle = port:PC02<2> +nand0_ce1 = port:PC03<2> +nand0_ce0 = port:PC04<2> +nand0_nre = port:PC05<2> +nand0_rb0 = port:PC06<2> +nand0_rb1 = port:PC07<2> +nand0_d0 = port:PC08<2> +nand0_d1 = port:PC09<2> +nand0_d2 = port:PC10<2> +nand0_d3 = port:PC11<2> +nand0_d4 = port:PC12<2> +nand0_d5 = port:PC13<2> +nand0_d6 = port:PC14<2> +nand0_d7 = port:PC15<2> +nand0_ndqs = port:PC16<2> + +;---------------------------------------------------------------------------------- +;disp init configuration +; +;disp_mode (0:screen0; 1:screen1) +;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;) +;screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50) +; (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:PAL 14:NTSC) +;fbx format (0:ARGB 1:ABGR 2:RGBA 3:BGRA 5:RGB565 8:RGB888 12:ARGB4444 16:ARGB1555 18:RGBA5551) +;fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0) +;lcdx_backlight (lcd init backlight,the range:[0,256],default:197 +;---------------------------------------------------------------------------------- +[disp_init] +disp_init_enable = 1 +disp_mode = 0 +screen0_output_type = 3 +screen0_output_mode = 10 +screen1_output_type = 0 +screen1_output_mode = 0 +fb0_format = 0 +fb0_width = 0 +fb0_height = 0 + +fb1_format = 0 +fb1_width = 0 +fb1_height = 0 + +;---------------------------------------------------------------------------------- +;hdmi configuration +;---------------------------------------------------------------------------------- +[hdmi_para] +hdmi_used = 1 +hdmi_power = "vcc-hdmi-18" +hdcp_enable = 0 + +[tv_para] +tv_used = 0 +tv_dac_used = 1 +tv_dac_src0 = 0 + +;---------------------------------------------------------------------------------- +;pwm config +;---------------------------------------------------------------------------------- +[pwm0_para] +pwm_used = 0 +pwm_positive = port:PA05<3><0> + +;------------------------------------------------------------------------------; +; 10/100/100Mbps Ethernet MAC Controller Configure ; +;------------------------------------------------------------------------------; +; Options: ; +; gmac_used --- 0: not used, 1: external phy, 2: internal phy ; +; gmac_powerx -- A[:B] A: axp channel, B: voltage value ; +; If set gamc_phy to use internal PHY, do not config port ; +;------------------------------------------------------------------------------; +; MII RMII MII RMII MII RMII ; +; PD00 * PD06 * * PD12 * * ; +; PD01 * PD07 * PD13 * * ; +; PD02 * * PD08 * PD14 * ; +; PD03 * * PD09 * * PD15 * ; +; PD04 * PD10 * * PD16 * * ; +; PD05 * PD11 * * PD17 * * ; +;------------------------------------------------------------------------------; +[gmac0] +gmac_used = 1 +gmac_rxd3 = port:PD00<2><3> +gmac_rxd2 = port:PD01<2><3> +gmac_rxd1 = port:PD02<2><3> +gmac_rxd0 = port:PD03<2><3> +gmac_rxclk = port:PD04<2><3> +gmac_rxdv = port:PD05<2><3> +;gmac_rxerr = port:PD06<2><3> +gmac_txd3 = port:PD07<2><3> +gmac_txd2 = port:PD08<2><3> +gmac_txd1 = port:PD09<2><3> +gmac_txd0 = port:PD10<2><3> +;gmac_crs = port:PD11<2><3> +gmac_txclk = port:PD12<2><3> +gmac_txen = port:PD13<2><3> +;gmac_txerr = port:PD14<2><3> +gmac_col = port:PD15<2><3> +gmac_mdc = port:PD16<2><3> +gmac_mdio = port:PD17<2><3> +gmac_power1 = + +[gmac_phy_power] +gmac_phy_power_en = port:PD06<1><0> + +;-------------------------------------------------------------------------------- +;vip (video input port) configuration +;vip_used: 0:disable 1:enable +;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer +;vip_dev_qty: The quantity of devices linked to capture bus +; +;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and +; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! +; +;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1, +;vip_dev(x)_pos must be configured! +; +;vip_dev(x)_isp_used 0:not use isp 1:use isp +;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb +;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby +;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable +;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable +;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply +;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply +;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply +;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply +;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply +;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply +;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply +;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply +;x indicates the index of the devices which are linked to the same capture bus +;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 +;fill handle string as below: +;axp22_eldo3 +;axp22_dldo4 +;axp22_eldo2 +;fill handle string "" when not using any pmu power supply +;-------------------------------------------------------------------------------- +[csi0] +vip_used = 0 +vip_mode = 0 +vip_dev_qty = 1 +vip_define_sensor_list = 0 + +vip_csi_pck = port:PE00<2> +vip_csi_mck = port:PE01<2> +vip_csi_hsync = port:PE02<2> +vip_csi_vsync = port:PE03<2> +vip_csi_d0 = port:PE04<2> +vip_csi_d1 = port:PE05<2> +vip_csi_d2 = port:PE06<2> +vip_csi_d3 = port:PE07<2> +vip_csi_d4 = port:PE08<2> +vip_csi_d5 = port:PE09<2> +vip_csi_d6 = port:PE10<2> +vip_csi_d7 = port:PE11<2> +vip_csi_sck = port:PE12<2> +vip_csi_sda = port:PE13<2> + +vip_dev0_mname = "gc2035" +vip_dev0_pos = "front" +vip_dev0_lane = 1 +vip_dev0_twi_id = 2 +vip_dev0_twi_addr = 0x78 +vip_dev0_isp_used = 0 +vip_dev0_fmt = 0 +vip_dev0_stby_mode = 0 +vip_dev0_vflip = 1 +vip_dev0_hflip = 1 +vip_dev0_iovdd = "" +vip_dev0_iovdd_vol = 2800000 +vip_dev0_avdd = "" +vip_dev0_avdd_vol = 2800000 +vip_dev0_dvdd = "" +vip_dev0_dvdd_vol = 1800000 +vip_dev0_afvdd = "" +vip_dev0_afvdd_vol = 2800000 +vip_dev0_power_en = port:PA17<1><1> +vip_dev0_reset = port:PE14<1><1> +vip_dev0_pwdn = port:PE15<1><0> +vip_dev0_flash_en = +vip_dev0_flash_mode = +vip_dev0_af_pwdn = + +vip_dev0_act_used = 0 +vip_dev0_act_name = "ad5820_act" +vip_dev0_act_slave = 0x18 + + +vip_dev1_mname = "" +vip_dev1_pos = "rear" +vip_dev1_lane = 1 +vip_dev1_twi_id = 0 +vip_dev1_twi_addr = +vip_dev1_isp_used = 0 +vip_dev1_fmt = 1 +vip_dev1_stby_mode = 0 +vip_dev1_vflip = 0 +vip_dev1_hflip = 0 +vip_dev1_iovdd = "" +vip_dev1_iovdd_vol = 2800000 +vip_dev1_avdd = "" +vip_dev1_avdd_vol = 2800000 +vip_dev1_dvdd = "" +vip_dev1_dvdd_vol = 1500000 +vip_dev1_afvdd = "" +vip_dev1_afvdd_vol = 2800000 +vip_dev1_power_en = +vip_dev1_reset = +vip_dev1_pwdn = +vip_dev1_flash_en = +vip_dev1_flash_mode = +vip_dev1_af_pwdn = + +;---------------------------------------------------------------------------------- +;Deinterlace configuration +;---------------------------------------------------------------------------------- +[di_para] +di_used = 1 +di_by_pass = 0 + +;-------------------------------------------------------------------------------- +; SDMMC PINS MAPPING | +; ------------------------------------------------------------------------------| +; Config Guide | +; sdc_used: 1-enable card, 0-disable card | +; sdc_detmode: card detect mode | +; 1-detect card by gpio polling | +; 2-detect card by gpio irq(must use IO with irq function) | +; 3-no detect, always in for boot card | +; 4-manually insert and remove by /proc/driver/sunxi-mmc.x/insert| +; sdc_buswidth: card bus width, 1-1bit, 4-4bit, 8-8bit | +; sdc_use_wp: 1-with write protect IO, 0-no write protect IO | +; sdc_isio: for sdio card | +; sdc_regulator: power control.if card supports UHS-I/DDR and HS200 timing for| +; SD3.0 or eMMC4.5, regulator must be configured. the value is | +; the ldo name of AXP221, eg: sdc_regulator = "axp22_eldo2" | +; other: GPIO Mapping configuration | +; ------------------------------------------------------------------------------| +; Note: | +; 1 if detmode=2, sdc_det's config=6 | +; else if detmode=1, sdc_det's config=0 | +; else sdc_det IO is not necessary | +; 2 if the customer wants to support UHS-I and HS200 features, he must provide| +; an independent power supply for the card. This is only used in platforms | +; that supports SD3.0 cards and eMMC4.4+ flashes | +;-------------------------------------------------------------------------------- +[mmc0_para] +sdc_used = 1 +sdc_detmode = 1 +sdc_buswidth = 4 +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_d1 = port:PF00<2><1><2> +sdc_d2 = port:PF05<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_det = port:PF06<0><1><2> +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" + +[mmc1_para] +sdc_used = 1 +sdc_detmode = 4 +sdc_buswidth = 4 +sdc_clk = port:PG00<2><1><3> +sdc_cmd = port:PG01<2><1><3> +sdc_d0 = port:PG02<2><1><3> +sdc_d1 = port:PG03<2><1><3> +sdc_d2 = port:PG04<2><1><3> +sdc_d3 = port:PG05<2><1><3> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 1 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +[mmc2_para] +sdc_used = 1 +sdc_detmode = 1 +sdc_buswidth = 8 +sdc_clk = port:PC05<3><1><2> +sdc_cmd = port:PC06<3><1><2> +sdc_d0 = port:PC08<3><1><2> +sdc_d1 = port:PC09<3><1><2> +sdc_d2 = port:PC10<3><1><2> +sdc_d3 = port:PC11<3><1><2> +sdc_d4 = port:PC12<3><1><2> +sdc_d5 = port:PC13<3><1><2> +sdc_d6 = port:PC14<3><1><2> +sdc_d7 = port:PC15<3><1><2> +emmc_rst = port:PC16<3><1><2> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +; ------------------------------------------------------------------------------| +; sim card configuration +;-------------------------------------------------------------------------------- +[smc_para] +smc_used = 0 +smc_rst = port:PA09<2> +smc_vppen = port:PA20<3> +smc_vppp = port:PA21<3> +smc_det = port:PA10<2> +smc_vccen = port:PA06<2> +smc_sck = port:PA07<2> +smc_sda = port:PA08<2> + +;-------------------------------- +; [usbc0]: Controller 0 configuration. +; usb used: USB enable flag. Set, indicating that the system USB module is available, is set to 0, it means that the system USB is disabled. +; usb_port_type: USB port usage. 0: device only; 1: host only; 2: OTG +; usb_detect_type: USB port of checking. 0: not detected; 1: vbus / id checks; 2: id / dpdm check +; usb_id_gpio: USB ID pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: USB DET_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_drv_vbus_gpio: USB DRY_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: "axp_ctrl", represents axp offer +; usb_restrict_gpio: usb limiting control pin +; usb_restric_flag: usb limiting standard set +;-------------------------------- +;-------------------------------- +; USB0 OTG +;-------------------------------- +[usbc0] +usb_used = 1 +usb_port_type = 2 +usb_detect_type = 0 +usb_id_gpio = port:PG12<0><1> +usb_det_vbus_gpio = port:PG12<0><1> +usb_drv_vbus_gpio = port:PL02<1><0><0> +usb_host_init_state = 1 +usb_restrict_gpio = +usb_restric_flag = 0 +usb_restric_voltage = 3550000 +usb_restric_capacity= 5 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB1 Host +;-------------------------------- +[usbc1] +usb_used = 1 +usb_drv_vbus_gpio = port:PG13<1><0><0> +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB2 Host +;-------------------------------- +[usbc2] +usb_used = 0 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB3 Host +;-------------------------------- +[usbc3] +usb_used = 1 +;usb_drv_vbus_gpio = port:PG11<1><1> +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB Device +;-------------------------------- +[usb_feature] +vendor_id = 0x18D1 +mass_storage_id = 0x0001 +adb_id = 0x0002 + +manufacturer_name = "USB Developer" +product_name = "Android" +serial_number = "20080411" + +[msc_feature] +vendor_name = "USB 2.0" +product_name = "USB Flash Driver" +release = 100 +luns = 3 + +[serial_feature] +serial_unique = 0 + +;-------------------------------------------------------------------------------- +;wifi/bt/fm/gps/nfc modules configuration +;module_power0: axp used by module, "axp22_dldo1" - use dldo1, not use keep it empty +;module_power0_vol: power0 voltage, mv; +;chip_en: enable chip io +;lpo_use_apclk: ""- not use, "losc_out"- a23/33/H3, "ac10032k1"、"ac10032k2"、"ac10032k3"- a80 +;-------------------------------------------------------------------------------- +[module_para] +module_power0 = "vcc-wifi-33" +module_power0_vol = 0 +module_power1 = +module_power1_vol = +module_power2 = +module_power2_vol = +module_power3 = +module_power3_vol = +chip_en = +lpo_use_apclk = + +;-------------------------------------------------------------------------------- +;wifi configuration +;wifi_sdc_id: 0- SDC0, 1- SDC1, 2- SDC2, 3- SDC3 +;wifi_usbc_id: 0- USB0, 1- USB1, 2- USB2 +;wifi_usbc_type: 1- EHCI(speed 2.0), 2- OHCI(speed 1.0) +;wl_reg_on: wifi function enable pin +;wl_host_wake: wlan device wake-up host pin +;wl_host_wake_invert: whether wl_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[wifi_para] +wifi_used = 1 +wifi_sdc_id = 1 +wifi_usbc_id = +wifi_usbc_type = +wl_reg_on = port:PL07<1><0> +wl_host_wake = port:PG10<0><0> +wl_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;bluetooth configuration +;bt_used: 0 - no used, 1- used +;bt_uard_id: 0 - uart0, 1- uart1, 2- uart2 +;bt_rst_n: bt function enable io +;bt_wake: host wake-up bluetooth device +;bt_host_wake: bt device wake-up host +;bt_host_wake_invert: whether bt_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[bt_para] +bt_used = 0 +bt_uart_id = 1 +bt_rst_n = +bt_wake = +bt_host_wake = +bt_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;daudio_master:1: SND_SOC_DAIFMT_CBM_CFM(codec clk & FRM master) use +; 2: SND_SOC_DAIFMT_CBS_CFM(codec clk slave & FRM master) not use +; 3: SND_SOC_DAIFMT_CBM_CFS(codec clk master & frame slave) not use +; 4: SND_SOC_DAIFMT_CBS_CFS(codec clk & FRM slave) use +;daudio_select:0 is pcm.1 is i2s +;audio_format: 1:SND_SOC_DAIFMT_I2S(standard i2s format). use +; 2:SND_SOC_DAIFMT_RIGHT_J(right justfied format). +; 3:SND_SOC_DAIFMT_LEFT_J(left justfied format) +; 4:SND_SOC_DAIFMT_DSP_A(pcm. MSB is available on 2nd BCLK rising edge after LRC rising edge). use +; 5:SND_SOC_DAIFMT_DSP_B(pcm. MSB is available on 1nd BCLK rising edge after LRC rising edge) +;signal_inversion:1:SND_SOC_DAIFMT_NB_NF(normal bit clock + frame) use +; 2:SND_SOC_DAIFMT_NB_IF(normal BCLK + inv FRM) +; 3:SND_SOC_DAIFMT_IB_NF(invert BCLK + nor FRM) use +; 4:SND_SOC_DAIFMT_IB_IF(invert BCLK + FRM) +;over_sample_rate: support 128fs/192fs/256fs/384fs/512fs/768fs +;sample_resolution :16bits/20bits/24bits +;word_select_size :16bits/20bits/24bits/32bits +;pcm_sync_period :16/32/64/128/256 +;msb_lsb_first :0: msb first; 1: lsb first +;sign_extend :0: zero pending; 1: sign extend +;slot_index :slot index: 0: the 1st slot - 3: the 4th slot +;slot_width :8 bit width / 16 bit width +;frame_width :0: long frame = 2 clock width; 1: short frame +;tx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;rx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;-------------------------------------------------------------------------------- +[pcm0] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PA18<2><1> +i2s_bclk = port:PA19<2><1> +i2s_dout0 = port:PA20<2><1> +i2s_din = port:PA21<2><1> + +[pcm1] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PG10<2><1> +i2s_bclk = port:PG11<2><1> +i2s_dout0 = port:PG12<2><1> +i2s_din = port:PG13<2><1> + +[audio0] +audio_used = 1 +lineout_vol = 0x1f +cap_vol = 0x5 +audio_hp_ldo = "none" +adcagc_used = 0 +adcdrc_used = 0 +dacdrc_used = 0 +adchpf_used = 0 +dachpf_used = 0 +audio_pa_ctrl = port:PA16<1><0> + +[spdif0] +spdif_used = 0 +spdif_dout = port:PA17<2><1> + +[audiohub] +hub_used = 1 +codec_used = 1 +spdif_used = 0 +hdmi_used = 1 + +;---------------------------------------------------------------------------------- +;ir rx --- infra remote configuration +;---------------------------------------------------------------------------------- +[s_cir0] +ir_used = 1 +ir_rx = port:PL11<2><1> +ir_power_key_code0 = 0x57 +ir_addr_code0 = 0x9f00 +ir_power_key_code1 = 0x1a +ir_addr_code1 = 0xfb04 +ir_power_key_code2 = 0x14 +ir_addr_code2 = 0x7F80 +ir_power_key_code3 = 0x15 +ir_addr_code3 = 0x7F80 +ir_power_key_code4 = 0x0b +ir_addr_code4 = 0xF708 +ir_power_key_code5 = 0x03 +ir_addr_code5 = 0x00EF +ir_power_key_code6 = 0x9f +ir_addr_code6 = 0x4CB3 +ir_power_key_code7 = 0x0a +ir_addr_code7 = 0x7748 +ir_power_key_code8 = 0x45 +ir_addr_code8 = 0xbd02 +ir_power_key_code9 = 0x4d +ir_addr_code9 = 0xde21 +ir_power_key_code10 = 0x18 +ir_addr_code10 = 0xfe01 +ir_power_key_code11 = 0x57 +ir_addr_code11 = 0xff00 +ir_power_key_code12 = 0x4d +ir_addr_code12 = 0xff40 + +;---------------------------------------------------------------------------------- +;ir tx--- infra remote configuration +;---------------------------------------------------------------------------------- +[cir] +ir_used = 1 +ir_tx = port:PH07<2> + +;---------------------------------------------------------------------------------- +; dvfs voltage-frequency table configuration +; +; pmuic_type:0:none, 1:gpio, 2:i2c +; pmu_gpio0: gpio config. +; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low. +; +; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk +; 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator +; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz +; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz +; +; LV_count: count of LV_freq/LV_volt, must be < 16 +; +; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz] +; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz] +; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz] +; LV4: core vdd is 1.20v if cpu frequency is (816Mhz, 1008Mhz] +; LV5: core vdd is 1.10v if cpu frequency is (648Mhz, 816Mhz] +; LV6: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV7: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV8: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; +;---------------------------------------------------------------------------------- +[dvfs_table] +pmuic_type = 2 +pmu_gpio0 = port:PL06<1><1><2><1> +pmu_level0 = 11300 +pmu_level1 = 1100 +extremity_freq = 1296000000 +max_freq = 1200000000 +min_freq = 480000000 +LV_count = 7 +LV1_freq = 1296000000 +LV1_volt = 1320 +LV2_freq = 1200000000 +LV2_volt = 1240 +LV3_freq = 1104000000 +LV3_volt = 1180 +LV4_freq = 1008000000 +LV4_volt = 1140 +LV5_freq = 960000000 +LV5_volt = 1080 +LV6_freq = 816000000 +LV6_volt = 1020 +LV7_freq = 480000000 +LV7_volt = 980 + +[gpu_dvfs_table] +G_LV_count = 3 +G_LV0_freq = 312000000 +G_LV0_volt = 1200000 +G_LV1_freq = 384000000 +G_LV1_volt = 1200000 +G_LV2_freq = 456000000 +G_LV2_volt = 1200000 + +;---------------------------------------------------------------------------------- +;virtual device +;virtual device for pinctrl testing +;device have pin PA1 PA2 +;---------------------------------------------------------------------------------- +[Vdevice] +Vdevice_used = 0 +Vdevice_0 = port:PH10<5><1><2> +Vdevice_1 = port:PH11<5><1><2> + +;---------------------------------------------------------------------------------- +;s_uart0 config parameters +;s_uart_used --s_uart0 whether used for arisc debugging +;---------------------------------------------------------------------------------- +[s_uart0] +s_uart_used = 0 +s_uart_tx = port:PL02<2> +s_uart_rx = port:PL03<2> + +;---------------------------------------------------------------------------------- +;s_rsb0 config parameters +;s_rsb_used --s_rsb0 whether used for arisc +;---------------------------------------------------------------------------------- +[s_rsb0] +s_rsb_used = 1 +s_rsb_sck = port:PL00<2><1><2> +s_rsb_sda = port:PL01<2><1><2> + +;---------------------------------------------------------------------------------- +;s_jtag0 config parameters +;s_jtag0_used --s_jtag0 whether used for arisc +; +;---------------------------------------------------------------------------------- +[s_jtag0] +s_jtag_used = 0 +s_jtag_tms = port:PL04<2><1><2> +s_jtag_tck = port:PL05<2><1><2> +s_jtag_tdo = port:PL06<2><1><2> +s_jtag_tdi = port:PL07<2><1><2> + +;---------------------------------------------------------------------------------- +;s_powchk cpus power check +;s_powchk_used --power check whether used for arisc in super standby +; bit31:enable power updat, bit1:wakeup when power state exception +; bit0:wakeup when power consumption exception +;s_power_reg the expected regs stand for power on/off state +;s_system_power the limit maxmum power consumption when super standby (unit: mw) +; +;---------------------------------------------------------------------------------- +[s_powchk] +s_powchk_used = 0x80000000 +s_power_reg = 0x00000000 +s_system_power = 50 + +;---------------------------------------------------------------------------------- +;scr configuration +;---------------------------------------------------------------------------------- +[sim0] +scr_used = 0 +scr_vccen = port:PA06<2> +scr_slk = port:PA07<2> +scr_sda = port:PA08<2> +scr_rst = port:PA09<2> +scr_det = port:PA10<2> + +;-------------------------------------------------------------------------------- +;tsc configuration +;-------------------------------------------------------------------------------- +[ts0] +tsc_used = 0 +tsc_clk = port:PE00<3> +tsc_err = port:PE01<3> +tsc_sync = port:PE02<3> +tsc_dvld = port:PE03<3> +tsc_d0 = port:PE04<3> +tsc_d1 = port:PE05<3> +tsc_d2 = port:PE06<3> +tsc_d3 = port:PE07<3> +tsc_d4 = port:PE08<3> +tsc_d5 = port:PE09<3> +tsc_d6 = port:PE10<3> +tsc_d7 = port:PE11<3> + +;-------------------------------------------------------------------------------- +;gpio key +;-------------------------------------------------------------------------------- +[gpio_power_key] +key_used = 1 +key_io = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +; key para +; +; key_used --0:not used, 1:used +; key_cnt --how many key button attach to keyadc. +; key*_vol --the threshold of input voltage of key. +; +; For example: if key2_vol < $(keyadc value) < key3_vol, then key3 be reported. +;---------------------------------------------------------------------------------- +[key_para] +key_used = 0 +key_cnt = 5 +key1_vol = 222 +key2_vol = 444 +key3_vol = 666 +key4_vol = 857 +key5_vol = 2000 + +;---------------------------------------------------------------------------------- +;display seven segment para +;---------------------------------------------------------------------------------- +[d7s_para] +d7s_used = 0 +din_gpio = port:PD00<1><1> +clk_gpio = port:PD01<1><1> +stb_gpio = port:PD02<1><1> + +;---------------------------------------------------------------------------------- +;mali parameters +;---------------------------------------------------------------------------------- +[mali_para] +mali_used = 1 +mali_clkdiv = 1 +mali_extreme_freq = 600 +mali_extreme_vol = 1400 + +;---------------------------------------------------------------------------------- +;1wire parameters (default - PA20) +;---------------------------------------------------------------------------------- +[w1_para] +w1_used = 1 +gpio = 20 diff --git a/projects/H3/sys_config/opiplus2e.fex b/projects/H3/sys_config/opiplus2e.fex new file mode 100755 index 00000000000..d3ced2fb303 --- /dev/null +++ b/projects/H3/sys_config/opiplus2e.fex @@ -0,0 +1,1095 @@ +[product] +version = "100" +machine = "opiplus2e" + +;--------------------------------------------------------------------------------------------------------- +; eraseflag - 1 erase data partition, 0 - do not erase data partition +; next_work - action after burn, 0x0 by config, 0x1, normal, 0x2 reboot 0x3 ,shutdown,0x4 reupdate ,0x5 boot +;--------------------------------------------------------------------------------------------------------- +[platform] +debug_mode = 1 +eraseflag = 1 +next_work = 2 + +;---------------------------------------------------------------------------------- +;[target] system bootup configuration +;boot_clock = CPU boot frequency, Unit: MHz +;storage_type = boot medium, 0-nand, 1-card0, 2-card2, -1(defualt)auto scan +;---------------------------------------------------------------------------------- +[target] +boot_clock = 1008 +storage_type = -1 + +;--------------------------------------------------------------------------------- +; used : 1: used this config, 0: not +; start_type : 1: start system directly when power supply, 0: wait IR/KEY to power on +; irkey_used : 1: ir key used, 0: not +; pmukey_used: 1: physical button used, 0: not +; led_power : 1: light, 0: off +; led_state : 1: light, 0: off +;--------------------------------------------------------------------------------- +[box_start_os] +used = 1 +start_type = 1 +irkey_used = 1 +pmukey_used = 1 +pmukey_num = 3 +led_power = 0 +led_state = 0 + +;--------------------------------------------------------------------------------------------------------- +; if 1 == standby_mode, then support super standby; +; else, support normal standby. +;--------------------------------------------------------------------------------------------------------- +[pm_para] +standby_mode = 1 + +; THIS PARAMETERS SEEMS TO BE USED ONLY FOR TESTING +[card0_boot_para] +card_ctrl = 0 +card_high_speed = 1 +card_line = 4 +sdc_d1 = port:PF00<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_d2 = port:PF05<2><1><2> + +[twi_para] +twi_port = 0 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[uart_para] +uart_debug_port = 0 +uart_debug_tx = port:PA04<2><1> +uart_debug_rx = port:PA05<2><1> + +[force_uart_para] +force_uart_port = 0 +force_uart_tx = port:PF02<3><1> +force_uart_rx = port:PF04<3><1> + +[jtag_para] +jtag_enable = 0 +jtag_ms = port:PA00<3> +jtag_ck = port:PA01<3> +jtag_do = port:PA02<3> +jtag_di = port:PA03<3> + +[clock] +pll_video = 297 +pll_ve = 402 +pll_periph0 = 600 +pll_gpu = 576 +pll_periph1 = 600 +pll_de = 864 + +;***************************************************************************** +;sdram configuration +; +;dram_para2 = 0x00001200 ;Representative enable dram Dual +;dram_para2 = 0x00001100 ;on behalf of a single channel is enabled dram +;***************************************************************************** +[dram_para] +dram_clk = 624 +dram_type = 3 +dram_zq = 0x3b3bfb +dram_odt_en = 0x1 +dram_para1 = 285476864 +dram_para2 = 0x0000 +dram_mr0 = 7280 +dram_mr1 = 0x40 +dram_mr2 = 0x18 +dram_mr3 = 0 +dram_tpr0 = 0x0048A192 +dram_tpr1 = 0x01C2418D +dram_tpr2 = 0x00076051 +dram_tpr3 = 0 +dram_tpr4 = 0 +dram_tpr5 = 0 +dram_tpr6 = 100 +dram_tpr7 = 0 +dram_tpr8 = 0 +dram_tpr9 = 0 +dram_tpr10 = 0 +dram_tpr11 = 0x6aaa0000 +dram_tpr12 = 0x7979 +dram_tpr13 = 0x1800801 + +;--------------------------------------------------------------------------------------------------------- +; wakeup_src_para: +; sometimes, u would like to add more wakeup src in standby mode, these para will be +; help; +; u need to make sure the standby mode support the wakeup src. Also, some hw +; condition must be guaranteed. +; including: +; cpu_en: power on or off. +; 1: mean power on +; 0: mean power off +; cpu_freq: indicating lowest freq. unit is Mhz; +; dram selfresh_en: selfresh or not. +; 1: enable enter selfresh +; 0: disable enter selfresh +; dram_pll: if not enter selfresh, indicating lowest freq. unit is Mhz; +; wakeup_src: to make the scenario work, the wakeup src is needed. +;--------------------------------------------------------------------------------------------------------- +[wakeup_src_para] +cpu_en = 0 +cpu_freq = 48 +pll_ratio = 273 +dram_selfresh_en = 1 +dram_freq = 36 +wakeup_src0 = +wakeup_src_wl = port:PG10<4><0> +wakeup_src_bt = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +;i2c configuration +;---------------------------------------------------------------------------------- +[twi0] +twi_used = 1 +twi_scl = port:PA11<2> +twi_sda = port:PA12<2> + +[twi1] +twi_used = 0 +twi_scl = port:PA18<3> +twi_sda = port:PA19<3> + +[twi2] +twi_used = 0 +twi_scl = port:PE12<3> +twi_sda = port:PE13<3> + +;---------------------------------------------------------------------------------- +;uart configuration +;uart_type --- 2 (2 wire), 4 (4 wire), 8 (8 wire, full function) +;---------------------------------------------------------------------------------- +[uart0] +uart_used = 1 +uart_port = 0 +uart_type = 2 +uart_tx = port:PA04<2><1> +uart_rx = port:PA05<2><1> + +[uart1] +uart_used = 0 +uart_port = 1 +uart_type = 2 +uart_tx = port:PG06<2><1> +uart_rx = port:PG07<2><1> +uart_rts = port:PG08<2><1> +uart_cts = port:PG09<2><1> + +[uart2] +uart_used = 0 +uart_port = 2 +uart_type = 4 +uart_tx = port:PA00<2><1> +uart_rx = port:PA01<2><1> +uart_rts = port:PA02<2><1> +uart_cts = port:PA03<2><1> + +[uart3] +uart_used = 0 +uart_port = 3 +uart_type = 2 +uart_tx = port:PA13<3><1> +uart_rx = port:PA14<3><1> +uart_rts = port:PA15<3><1> +uart_cts = port:PA16<3><1> + +;---------------------------------------------------------------------------------- +;SPI controller configuration +;---------------------------------------------------------------------------------- +[spi0] +spi_used = 1 +spi_cs_bitmap = 1 +spi_mosi = port:PC00<3> +spi_miso = port:PC01<3> +spi_sclk = port:PC02<3> +spi_cs0 = port:PC03<3><1> + +[spi1] +spi_used = 0 +spi_cs_bitmap = 1 +spi_cs0 = port:PA13<2><1> +spi_sclk = port:PA14<2> +spi_mosi = port:PA15<2> +spi_miso = port:PA16<2> + +;---------------------------------------------------------------------------------- +;SPI device configuration +;---------------------------------------------------------------------------------- +[spi_devices] +spi_dev_num = 1 + +[spi_board0] +modalias = "spidev" +max_speed_hz = 33000000 +bus_num = 0 +chip_select = 0 +mode = 0 +full_duplex = 1 +manual_cs = 0 + +[leds_para] +leds_used = 1 +green_led = port:PL10<1><0> +green_led_active_low = 1 +red_led = port:PA15<1><0> +red_led_active_low = 0 + +;---------------------------------------------------------------------------------- +;thermal configuration +;ths_trip_count : temperature trigger number +;ths_trip_0 : first temperature trigger +;ths_trip_1 : second temperature trigger +;ths_trip_2 : third temperature trigger, when upto this temperature, system shutdown +;ths_trip_0_min : first temperature trigger's min freq +;ths_trip_0_max : first temperature trigger's max freq +;ths_trip_1_min : second temperature trigger's min freq +;ths_trip_1_max : second temperature trigger's max freq +;---------------------------------------------------------------------------------- +[ths_para] +ths_used = 1 +ths_trip1_count = 6 +ths_trip1_0 = 75 +ths_trip1_1 = 80 +ths_trip1_2 = 85 +ths_trip1_3 = 90 +ths_trip1_4 = 95 +ths_trip1_5 = 105 +ths_trip1_6 = 0 +ths_trip1_7 = 0 +ths_trip1_0_min = 0 +ths_trip1_0_max = 1 +ths_trip1_1_min = 1 +ths_trip1_1_max = 2 +ths_trip1_2_min = 2 +ths_trip1_2_max = 3 +ths_trip1_3_min = 3 +ths_trip1_3_max = 4 +ths_trip1_4_min = 4 +ths_trip1_4_max = 8 +ths_trip1_5_min = 8 +ths_trip1_5_max = 8 +ths_trip1_6_min = 0 +ths_trip1_6_max = 0 +ths_trip2_count = 1 +ths_trip2_0 = 105 + +;---------------------------------------------------------------------------------- +;cooler_table cooler_count <=32 +;---------------------------------------------------------------------------------- +[cooler_table] +cooler_count = 9 +cooler0 = "1296000 4 4294967295 0" +cooler1 = "1200000 4 4294967295 0" +cooler2 = "1008000 4 4294967295 0" +cooler3 = "816000 4 4294967295 0" +cooler4 = "648000 4 4294967295 0" +cooler5 = "480000 4 4294967295 0" +cooler6 = "480000 3 4294967295 0" +cooler7 = "480000 2 4294967295 0" +cooler8 = "480000 1 4294967295 0" + +[nand0_para] +nand_support_2ch = 0 + +nand0_used = 0 +nand0_we = port:PC00<2> +nand0_ale = port:PC01<2> +nand0_cle = port:PC02<2> +nand0_ce1 = port:PC03<2> +nand0_ce0 = port:PC04<2> +nand0_nre = port:PC05<2> +nand0_rb0 = port:PC06<2> +nand0_rb1 = port:PC07<2> +nand0_d0 = port:PC08<2> +nand0_d1 = port:PC09<2> +nand0_d2 = port:PC10<2> +nand0_d3 = port:PC11<2> +nand0_d4 = port:PC12<2> +nand0_d5 = port:PC13<2> +nand0_d6 = port:PC14<2> +nand0_d7 = port:PC15<2> +nand0_ndqs = port:PC16<2> + +;---------------------------------------------------------------------------------- +;disp init configuration +; +;disp_mode (0:screen0; 1:screen1) +;screenx_output_type (0:none; 1:lcd; 2:tv; 3:hdmi;) +;screenx_output_mode (used for hdmi output, 0:480i 1:576i 2:480p 3:576p 4:720p50) +; (5:720p60 6:1080i50 7:1080i60 8:1080p24 9:1080p50 10:1080p60 11:PAL 14:NTSC) +;fbx format (0:ARGB 1:ABGR 2:RGBA 3:BGRA 5:RGB565 8:RGB888 12:ARGB4444 16:ARGB1555 18:RGBA5551) +;fbx_width,fbx_height (framebuffer horizontal/vertical pixels, fix to output resolution while equal 0) +;lcdx_backlight (lcd init backlight,the range:[0,256],default:197 +;---------------------------------------------------------------------------------- +[disp_init] +disp_init_enable = 1 +disp_mode = 0 +screen0_output_type = 3 +screen0_output_mode = 10 +screen1_output_type = 0 +screen1_output_mode = 0 +fb0_format = 0 +fb0_width = 0 +fb0_height = 0 + +fb1_format = 0 +fb1_width = 0 +fb1_height = 0 + +;---------------------------------------------------------------------------------- +;hdmi configuration +;---------------------------------------------------------------------------------- +[hdmi_para] +hdmi_used = 1 +hdmi_power = "vcc-hdmi-18" +hdcp_enable = 0 + +[tv_para] +tv_used = 0 +tv_dac_used = 1 +tv_dac_src0 = 0 + +;---------------------------------------------------------------------------------- +;pwm config +;---------------------------------------------------------------------------------- +[pwm0_para] +pwm_used = 0 +pwm_positive = port:PA05<3><0> + +;------------------------------------------------------------------------------; +; 10/100/100Mbps Ethernet MAC Controller Configure ; +;------------------------------------------------------------------------------; +; Options: ; +; gmac_used --- 0: not used, 1: external phy, 2: internal phy ; +; gmac_powerx -- A[:B] A: axp channel, B: voltage value ; +; If set gamc_phy to use internal PHY, do not config port ; +;------------------------------------------------------------------------------; +; MII RMII MII RMII MII RMII ; +; PD00 * PD06 * * PD12 * * ; +; PD01 * PD07 * PD13 * * ; +; PD02 * * PD08 * PD14 * ; +; PD03 * * PD09 * * PD15 * ; +; PD04 * PD10 * * PD16 * * ; +; PD05 * PD11 * * PD17 * * ; +;------------------------------------------------------------------------------; +[gmac0] +gmac_used = 1 +gmac_rxd3 = port:PD00<2><3> +gmac_rxd2 = port:PD01<2><3> +gmac_rxd1 = port:PD02<2><3> +gmac_rxd0 = port:PD03<2><3> +gmac_rxclk = port:PD04<2><3> +gmac_rxdv = port:PD05<2><3> +;gmac_rxerr = port:PD06<2><3> +gmac_txd3 = port:PD07<2><3> +gmac_txd2 = port:PD08<2><3> +gmac_txd1 = port:PD09<2><3> +gmac_txd0 = port:PD10<2><3> +;gmac_crs = port:PD11<2><3> +gmac_txclk = port:PD12<2><3> +gmac_txen = port:PD13<2><3> +;gmac_txerr = port:PD14<2><3> +gmac_col = port:PD15<2><3> +gmac_mdc = port:PD16<2><3> +gmac_mdio = port:PD17<2><3> +gmac_power1 = + +[gmac_phy_power] +gmac_phy_power_en = port:PD06<1><0> + +;-------------------------------------------------------------------------------- +;vip (video input port) configuration +;vip_used: 0:disable 1:enable +;vip_mode: 0:sample one interface to one buffer 1:sample two interface to one buffer +;vip_dev_qty: The quantity of devices linked to capture bus +; +;vip_define_sensor_list: If you want use sensor detect function, please set vip_define_sensor_list = 1, and +; verify that file /system/etc/hawkview/sensor_list_cfg.ini is properly configured! +; +;vip_dev(x)_pos: sensor position, "rear" or "front", if vip_define_sensor_list = 1, +;vip_dev(x)_pos must be configured! +; +;vip_dev(x)_isp_used 0:not use isp 1:use isp +;vip_dev(x)_fmt: 0:yuv 1:bayer raw rgb +;vip_dev(x)_stby_mode: 0:not shut down power at standby 1:shut down power at standby +;vip_dev(x)_vflip: flip in vertical direction 0:disable 1:enable +;vip_dev(x)_hflip: flip in horizontal direction 0:disable 1:enable +;vip_dev(x)_iovdd: camera module io power handle string, pmu power supply +;vip_dev(x)_iovdd_vol: camera module io power voltage, pmu power supply +;vip_dev(x)_avdd: camera module analog power handle string, pmu power supply +;vip_dev(x)_avdd_vol: camera module analog power voltage, pmu power supply +;vip_dev(x)_dvdd: camera module core power handle string, pmu power supply +;vip_dev(x)_dvdd_vol: camera module core power voltage, pmu power supply +;vip_dev(x)_afvdd: camera module vcm power handle string, pmu power supply +;vip_dev(x)_afvdd_vol: camera module vcm power voltage, pmu power supply +;x indicates the index of the devices which are linked to the same capture bus +;fill voltage in uV, e.g. iovdd = 2.8V, vip_devx_iovdd_vol = 2800000 +;fill handle string as below: +;axp22_eldo3 +;axp22_dldo4 +;axp22_eldo2 +;fill handle string "" when not using any pmu power supply +;-------------------------------------------------------------------------------- +[csi0] +vip_used = 0 +vip_mode = 0 +vip_dev_qty = 1 +vip_define_sensor_list = 0 + +vip_csi_pck = port:PE00<2> +vip_csi_mck = port:PE01<2> +vip_csi_hsync = port:PE02<2> +vip_csi_vsync = port:PE03<2> +vip_csi_d0 = port:PE04<2> +vip_csi_d1 = port:PE05<2> +vip_csi_d2 = port:PE06<2> +vip_csi_d3 = port:PE07<2> +vip_csi_d4 = port:PE08<2> +vip_csi_d5 = port:PE09<2> +vip_csi_d6 = port:PE10<2> +vip_csi_d7 = port:PE11<2> +vip_csi_sck = port:PE12<2> +vip_csi_sda = port:PE13<2> + +vip_dev0_mname = "gc2035" +vip_dev0_pos = "front" +vip_dev0_lane = 1 +vip_dev0_twi_id = 2 +vip_dev0_twi_addr = 0x78 +vip_dev0_isp_used = 0 +vip_dev0_fmt = 0 +vip_dev0_stby_mode = 0 +vip_dev0_vflip = 1 +vip_dev0_hflip = 1 +vip_dev0_iovdd = "" +vip_dev0_iovdd_vol = 2800000 +vip_dev0_avdd = "" +vip_dev0_avdd_vol = 2800000 +vip_dev0_dvdd = "" +vip_dev0_dvdd_vol = 1800000 +vip_dev0_afvdd = "" +vip_dev0_afvdd_vol = 2800000 +vip_dev0_power_en = port:PA17<1><1> +vip_dev0_reset = port:PE14<1><1> +vip_dev0_pwdn = port:PE15<1><0> +vip_dev0_flash_en = +vip_dev0_flash_mode = +vip_dev0_af_pwdn = + +vip_dev0_act_used = 0 +vip_dev0_act_name = "ad5820_act" +vip_dev0_act_slave = 0x18 + + +vip_dev1_mname = "" +vip_dev1_pos = "rear" +vip_dev1_lane = 1 +vip_dev1_twi_id = 0 +vip_dev1_twi_addr = +vip_dev1_isp_used = 0 +vip_dev1_fmt = 1 +vip_dev1_stby_mode = 0 +vip_dev1_vflip = 0 +vip_dev1_hflip = 0 +vip_dev1_iovdd = "" +vip_dev1_iovdd_vol = 2800000 +vip_dev1_avdd = "" +vip_dev1_avdd_vol = 2800000 +vip_dev1_dvdd = "" +vip_dev1_dvdd_vol = 1500000 +vip_dev1_afvdd = "" +vip_dev1_afvdd_vol = 2800000 +vip_dev1_power_en = +vip_dev1_reset = +vip_dev1_pwdn = +vip_dev1_flash_en = +vip_dev1_flash_mode = +vip_dev1_af_pwdn = + +;---------------------------------------------------------------------------------- +;Deinterlace configuration +;---------------------------------------------------------------------------------- +[di_para] +di_used = 1 +di_by_pass = 0 + +;-------------------------------------------------------------------------------- +; SDMMC PINS MAPPING | +; ------------------------------------------------------------------------------| +; Config Guide | +; sdc_used: 1-enable card, 0-disable card | +; sdc_detmode: card detect mode | +; 1-detect card by gpio polling | +; 2-detect card by gpio irq(must use IO with irq function) | +; 3-no detect, always in for boot card | +; 4-manually insert and remove by /proc/driver/sunxi-mmc.x/insert| +; sdc_buswidth: card bus width, 1-1bit, 4-4bit, 8-8bit | +; sdc_use_wp: 1-with write protect IO, 0-no write protect IO | +; sdc_isio: for sdio card | +; sdc_regulator: power control.if card supports UHS-I/DDR and HS200 timing for| +; SD3.0 or eMMC4.5, regulator must be configured. the value is | +; the ldo name of AXP221, eg: sdc_regulator = "axp22_eldo2" | +; other: GPIO Mapping configuration | +; ------------------------------------------------------------------------------| +; Note: | +; 1 if detmode=2, sdc_det's config=6 | +; else if detmode=1, sdc_det's config=0 | +; else sdc_det IO is not necessary | +; 2 if the customer wants to support UHS-I and HS200 features, he must provide| +; an independent power supply for the card. This is only used in platforms | +; that supports SD3.0 cards and eMMC4.4+ flashes | +;-------------------------------------------------------------------------------- +[mmc0_para] +sdc_used = 1 +sdc_detmode = 3 +sdc_buswidth = 4 +sdc_clk = port:PF02<2><1><2> +sdc_cmd = port:PF03<2><1><2> +sdc_d0 = port:PF01<2><1><2> +sdc_d1 = port:PF00<2><1><2> +sdc_d2 = port:PF05<2><1><2> +sdc_d3 = port:PF04<2><1><2> +sdc_det = port:PF06<0><1><2> +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" + +[mmc1_para] +sdc_used = 1 +sdc_detmode = 4 +sdc_buswidth = 4 +sdc_clk = port:PG00<2><1><3> +sdc_cmd = port:PG01<2><1><3> +sdc_d0 = port:PG02<2><1><3> +sdc_d1 = port:PG03<2><1><3> +sdc_d2 = port:PG04<2><1><3> +sdc_d3 = port:PG05<2><1><3> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 1 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +[mmc2_para] +sdc_used = 1 +sdc_detmode = 1 +sdc_buswidth = 8 +sdc_clk = port:PC05<3><1><2> +sdc_cmd = port:PC06<3><1><2> +sdc_d0 = port:PC08<3><1><2> +sdc_d1 = port:PC09<3><1><2> +sdc_d2 = port:PC10<3><1><2> +sdc_d3 = port:PC11<3><1><2> +sdc_d4 = port:PC12<3><1><2> +sdc_d5 = port:PC13<3><1><2> +sdc_d6 = port:PC14<3><1><2> +sdc_d7 = port:PC15<3><1><2> +emmc_rst = port:PC16<3><1><2> +sdc_det = +sdc_use_wp = 0 +sdc_wp = +sdc_isio = 0 +sdc_regulator = "none" +sdc_power_supply = "none" +sdc_2xmode = 1 +sdc_ddrmode = 1 + +; ------------------------------------------------------------------------------| +; sim card configuration +;-------------------------------------------------------------------------------- +[smc_para] +smc_used = 0 +smc_rst = port:PA09<2> +smc_vppen = port:PA20<3> +smc_vppp = port:PA21<3> +smc_det = port:PA10<2> +smc_vccen = port:PA06<2> +smc_sck = port:PA07<2> +smc_sda = port:PA08<2> + +;-------------------------------- +; [usbc0]: Controller 0 configuration. +; usb used: USB enable flag. Set, indicating that the system USB module is available, is set to 0, it means that the system USB is disabled. +; usb_port_type: USB port usage. 0: device only; 1: host only; 2: OTG +; usb_detect_type: USB port of checking. 0: not detected; 1: vbus / id checks; 2: id / dpdm check +; usb_id_gpio: USB ID pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: USB DET_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_drv_vbus_gpio: USB DRY_VBUS pin pin configuration. For details, please refer gpio configuration instructions. +; usb_det_vbus_gpio: "axp_ctrl", represents axp offer +; usb_restrict_gpio: usb limiting control pin +; usb_restric_flag: usb limiting standard set +;-------------------------------- +;-------------------------------- +; USB0 OTG +;-------------------------------- +[usbc0] +usb_used = 1 +usb_port_type = 2 +usb_detect_type = 0 +usb_id_gpio = port:PG12<0><1> +usb_det_vbus_gpio = port:PG12<0><1> +usb_drv_vbus_gpio = port:PL02<1><0><0> +usb_host_init_state = 1 +usb_restrict_gpio = +usb_restric_flag = 0 +usb_restric_voltage = 3550000 +usb_restric_capacity= 5 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB1 Host +;-------------------------------- +[usbc1] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB2 Host +;-------------------------------- +[usbc2] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB3 Host +;-------------------------------- +[usbc3] +usb_used = 1 +usb_drv_vbus_gpio = +usb_restrict_gpio = +usb_host_init_state = 1 +usb_restric_flag = 0 +usb_regulator_io = "nocare" +usb_regulator_vol = 0 +usb_not_suspend = 0 + +;-------------------------------- +; USB Device +;-------------------------------- +[usb_feature] +vendor_id = 0x18D1 +mass_storage_id = 0x0001 +adb_id = 0x0002 + +manufacturer_name = "USB Developer" +product_name = "Android" +serial_number = "20080411" + +[msc_feature] +vendor_name = "USB 2.0" +product_name = "USB Flash Driver" +release = 100 +luns = 3 + +[serial_feature] +serial_unique = 0 + +;-------------------------------------------------------------------------------- +;wifi/bt/fm/gps/nfc modules configuration +;module_power0: axp used by module, "axp22_dldo1" - use dldo1, not use keep it empty +;module_power0_vol: power0 voltage, mv; +;chip_en: enable chip io +;lpo_use_apclk: ""- not use, "losc_out"- a23/33/H3, "ac10032k1"、"ac10032k2"、"ac10032k3"- a80 +;-------------------------------------------------------------------------------- +[module_para] +module_power0 = "vcc-wifi-33" +module_power0_vol = 0 +module_power1 = +module_power1_vol = +module_power2 = +module_power2_vol = +module_power3 = +module_power3_vol = +chip_en = +lpo_use_apclk = + +;-------------------------------------------------------------------------------- +;wifi configuration +;wifi_sdc_id: 0- SDC0, 1- SDC1, 2- SDC2, 3- SDC3 +;wifi_usbc_id: 0- USB0, 1- USB1, 2- USB2 +;wifi_usbc_type: 1- EHCI(speed 2.0), 2- OHCI(speed 1.0) +;wl_reg_on: wifi function enable pin +;wl_host_wake: wlan device wake-up host pin +;wl_host_wake_invert: whether wl_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[wifi_para] +wifi_used = 1 +wifi_sdc_id = 1 +wifi_usbc_id = +wifi_usbc_type = +wl_reg_on = port:PL07<1><0> +wl_host_wake = port:PG10<0><0> +wl_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;bluetooth configuration +;bt_used: 0 - no used, 1- used +;bt_uard_id: 0 - uart0, 1- uart1, 2- uart2 +;bt_rst_n: bt function enable io +;bt_wake: host wake-up bluetooth device +;bt_host_wake: bt device wake-up host +;bt_host_wake_invert: whether bt_host_wake use inverter between ap and module +; 0: not used, 1: used +;-------------------------------------------------------------------------------- +[bt_para] +bt_used = 0 +bt_uart_id = 1 +bt_rst_n = +bt_wake = +bt_host_wake = +bt_host_wake_invert = 0 + +;-------------------------------------------------------------------------------- +;daudio_master:1: SND_SOC_DAIFMT_CBM_CFM(codec clk & FRM master) use +; 2: SND_SOC_DAIFMT_CBS_CFM(codec clk slave & FRM master) not use +; 3: SND_SOC_DAIFMT_CBM_CFS(codec clk master & frame slave) not use +; 4: SND_SOC_DAIFMT_CBS_CFS(codec clk & FRM slave) use +;daudio_select:0 is pcm.1 is i2s +;audio_format: 1:SND_SOC_DAIFMT_I2S(standard i2s format). use +; 2:SND_SOC_DAIFMT_RIGHT_J(right justfied format). +; 3:SND_SOC_DAIFMT_LEFT_J(left justfied format) +; 4:SND_SOC_DAIFMT_DSP_A(pcm. MSB is available on 2nd BCLK rising edge after LRC rising edge). use +; 5:SND_SOC_DAIFMT_DSP_B(pcm. MSB is available on 1nd BCLK rising edge after LRC rising edge) +;signal_inversion:1:SND_SOC_DAIFMT_NB_NF(normal bit clock + frame) use +; 2:SND_SOC_DAIFMT_NB_IF(normal BCLK + inv FRM) +; 3:SND_SOC_DAIFMT_IB_NF(invert BCLK + nor FRM) use +; 4:SND_SOC_DAIFMT_IB_IF(invert BCLK + FRM) +;over_sample_rate: support 128fs/192fs/256fs/384fs/512fs/768fs +;sample_resolution :16bits/20bits/24bits +;word_select_size :16bits/20bits/24bits/32bits +;pcm_sync_period :16/32/64/128/256 +;msb_lsb_first :0: msb first; 1: lsb first +;sign_extend :0: zero pending; 1: sign extend +;slot_index :slot index: 0: the 1st slot - 3: the 4th slot +;slot_width :8 bit width / 16 bit width +;frame_width :0: long frame = 2 clock width; 1: short frame +;tx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;rx_data_mode :0: 16bit linear PCM; 1: 8bit linear PCM; 2: 8bit u-law; 3: 8bit a-law +;-------------------------------------------------------------------------------- +[pcm0] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PA18<2><1> +i2s_bclk = port:PA19<2><1> +i2s_dout0 = port:PA20<2><1> +i2s_din = port:PA21<2><1> + +[pcm1] +daudio_used = 0 +daudio_master = 4 +daudio_select = 1 +audio_format = 1 +signal_inversion = 1 +mclk_fs = 128 +sample_resolution = 16 +slot_width_select = 32 +;pcm_sync_period = 256 +pcm_lrck_period = 32 +pcm_lrckr_period = 1 +msb_lsb_first = 0 +sign_extend = 0 +slot_index = 0 +slot_width = 32 +frame_width = 0 +tx_data_mode = 0 +rx_data_mode = 0 +i2s_mclk = port:PG10<2><1> +i2s_bclk = port:PG11<2><1> +i2s_dout0 = port:PG12<2><1> +i2s_din = port:PG13<2><1> + +[audio0] +audio_used = 1 +lineout_vol = 0x1f +cap_vol = 0x5 +audio_hp_ldo = "none" +adcagc_used = 0 +adcdrc_used = 0 +dacdrc_used = 0 +adchpf_used = 0 +dachpf_used = 0 +audio_pa_ctrl = port:PA16<1><0> + +[spdif0] +spdif_used = 0 +spdif_dout = port:PA17<2><1> + +[audiohub] +hub_used = 1 +codec_used = 1 +spdif_used = 0 +hdmi_used = 1 + +;---------------------------------------------------------------------------------- +;ir rx --- infra remote configuration +;---------------------------------------------------------------------------------- +[s_cir0] +ir_used = 1 +ir_rx = port:PL11<2><1> +ir_power_key_code0 = 0x57 +ir_addr_code0 = 0x9f00 +ir_power_key_code1 = 0x1a +ir_addr_code1 = 0xfb04 +ir_power_key_code2 = 0x14 +ir_addr_code2 = 0x7F80 +ir_power_key_code3 = 0x15 +ir_addr_code3 = 0x7F80 +ir_power_key_code4 = 0x0b +ir_addr_code4 = 0xF708 +ir_power_key_code5 = 0x03 +ir_addr_code5 = 0x00EF +ir_power_key_code6 = 0x9f +ir_addr_code6 = 0x4CB3 +ir_power_key_code7 = 0x0a +ir_addr_code7 = 0x7748 +ir_power_key_code8 = 0x45 +ir_addr_code8 = 0xbd02 +ir_power_key_code9 = 0x4d +ir_addr_code9 = 0xde21 +ir_power_key_code10 = 0x18 +ir_addr_code10 = 0xfe01 +ir_power_key_code11 = 0x57 +ir_addr_code11 = 0xff00 +ir_power_key_code12 = 0x4d +ir_addr_code12 = 0xff40 + +;---------------------------------------------------------------------------------- +;ir tx--- infra remote configuration +;---------------------------------------------------------------------------------- +[cir] +ir_used = 1 +ir_tx = port:PH07<2> + +;---------------------------------------------------------------------------------- +; dvfs voltage-frequency table configuration +; +; pmuic_type:0:none, 1:gpio, 2:i2c +; pmu_gpio0: gpio config. +; pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low. +; +; extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk +; 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator +; max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz +; min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz +; +; LV_count: count of LV_freq/LV_volt, must be < 16 +; +; LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz] +; LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz] +; LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz] +; LV4: core vdd is 1.20v if cpu frequency is (816Mhz, 1008Mhz] +; LV5: core vdd is 1.10v if cpu frequency is (648Mhz, 816Mhz] +; LV6: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV7: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; LV8: core vdd is 1.04v if cpu frequency is (0Mhz, 648Mhz] +; +;---------------------------------------------------------------------------------- +[dvfs_table] +pmuic_type = 2 +pmu_gpio0 = port:PL06<1><1><2><1> +pmu_level0 = 11300 +pmu_level1 = 1100 +extremity_freq = 1296000000 +max_freq = 1296000000 +min_freq = 480000000 +LV_count = 7 +LV1_freq = 1296000000 +LV1_volt = 1320 +LV2_freq = 1200000000 +LV2_volt = 1240 +LV3_freq = 1104000000 +LV3_volt = 1180 +LV4_freq = 1008000000 +LV4_volt = 1140 +LV5_freq = 960000000 +LV5_volt = 1080 +LV6_freq = 816000000 +LV6_volt = 1020 +LV7_freq = 480000000 +LV7_volt = 980 + +[gpu_dvfs_table] +G_LV_count = 3 +G_LV0_freq = 312000000 +G_LV0_volt = 1200000 +G_LV1_freq = 384000000 +G_LV1_volt = 1200000 +G_LV2_freq = 456000000 +G_LV2_volt = 1200000 + +;---------------------------------------------------------------------------------- +;virtual device +;virtual device for pinctrl testing +;device have pin PA1 PA2 +;---------------------------------------------------------------------------------- +[Vdevice] +Vdevice_used = 0 +Vdevice_0 = port:PH10<5><1><2> +Vdevice_1 = port:PH11<5><1><2> + +;---------------------------------------------------------------------------------- +;s_uart0 config parameters +;s_uart_used --s_uart0 whether used for arisc debugging +;---------------------------------------------------------------------------------- +[s_uart0] +s_uart_used = 0 +s_uart_tx = port:PL02<2> +s_uart_rx = port:PL03<2> + +;---------------------------------------------------------------------------------- +;s_rsb0 config parameters +;s_rsb_used --s_rsb0 whether used for arisc +;---------------------------------------------------------------------------------- +[s_rsb0] +s_rsb_used = 1 +s_rsb_sck = port:PL00<2><1><2> +s_rsb_sda = port:PL01<2><1><2> + +;---------------------------------------------------------------------------------- +;s_jtag0 config parameters +;s_jtag0_used --s_jtag0 whether used for arisc +; +;---------------------------------------------------------------------------------- +[s_jtag0] +s_jtag_used = 0 +s_jtag_tms = port:PL04<2><1><2> +s_jtag_tck = port:PL05<2><1><2> +s_jtag_tdo = port:PL06<2><1><2> +s_jtag_tdi = port:PL07<2><1><2> + +;---------------------------------------------------------------------------------- +;s_powchk cpus power check +;s_powchk_used --power check whether used for arisc in super standby +; bit31:enable power updat, bit1:wakeup when power state exception +; bit0:wakeup when power consumption exception +;s_power_reg the expected regs stand for power on/off state +;s_system_power the limit maxmum power consumption when super standby (unit: mw) +; +;---------------------------------------------------------------------------------- +[s_powchk] +s_powchk_used = 0x80000000 +s_power_reg = 0x00000000 +s_system_power = 50 + +;---------------------------------------------------------------------------------- +;scr configuration +;---------------------------------------------------------------------------------- +[sim0] +scr_used = 0 +scr_vccen = port:PA06<2> +scr_slk = port:PA07<2> +scr_sda = port:PA08<2> +scr_rst = port:PA09<2> +scr_det = port:PA10<2> + +;-------------------------------------------------------------------------------- +;tsc configuration +;-------------------------------------------------------------------------------- +[ts0] +tsc_used = 0 +tsc_clk = port:PE00<3> +tsc_err = port:PE01<3> +tsc_sync = port:PE02<3> +tsc_dvld = port:PE03<3> +tsc_d0 = port:PE04<3> +tsc_d1 = port:PE05<3> +tsc_d2 = port:PE06<3> +tsc_d3 = port:PE07<3> +tsc_d4 = port:PE08<3> +tsc_d5 = port:PE09<3> +tsc_d6 = port:PE10<3> +tsc_d7 = port:PE11<3> + +;-------------------------------------------------------------------------------- +;gpio key +;-------------------------------------------------------------------------------- +[gpio_power_key] +key_used = 1 +key_io = port:PL03<6><0> + +;---------------------------------------------------------------------------------- +; key para +; +; key_used --0:not used, 1:used +; key_cnt --how many key button attach to keyadc. +; key*_vol --the threshold of input voltage of key. +; +; For example: if key2_vol < $(keyadc value) < key3_vol, then key3 be reported. +;---------------------------------------------------------------------------------- +[key_para] +key_used = 0 +key_cnt = 5 +key1_vol = 222 +key2_vol = 444 +key3_vol = 666 +key4_vol = 857 +key5_vol = 2000 + +;---------------------------------------------------------------------------------- +;display seven segment para +;---------------------------------------------------------------------------------- +[d7s_para] +d7s_used = 0 +din_gpio = port:PD00<1><1> +clk_gpio = port:PD01<1><1> +stb_gpio = port:PD02<1><1> + +;---------------------------------------------------------------------------------- +;mali parameters +;---------------------------------------------------------------------------------- +[mali_para] +mali_used = 1 +mali_clkdiv = 1 +mali_extreme_freq = 600 +mali_extreme_vol = 1400 + +;---------------------------------------------------------------------------------- +;1wire parameters (default - PA20) +;---------------------------------------------------------------------------------- +[w1_para] +w1_used = 1 +gpio = 20 diff --git a/scripts/image b/scripts/image index 5f7aa294f41..65acab4b6de 100755 --- a/scripts/image +++ b/scripts/image @@ -50,7 +50,7 @@ if [ "$DEVEL_VERSION" = "devel" ] ; then IMAGE_NAME="$DISTRONAME-$PROJECT.$TARGET_ARCH-$OS_VERSION-$OPENELEC_VERSION" fi -if [ "$PROJECT" == "imx6" -a -n "$SYSTEM" ]; then +if [ "$PROJECT" == "imx6" -o "$PROJECT" == "H3" -o "$PROJECT" == "A83T" ] && [ -n "$SYSTEM" ]; then IMAGE_NAME="$IMAGE_NAME-$SYSTEM" fi @@ -204,7 +204,7 @@ fi fi done fi - + # run depmod MODVER=$(basename $(ls -d $INSTALL/lib/modules/*)) find $INSTALL/lib/modules/$MODVER/ -name *.ko | \ @@ -343,6 +343,18 @@ fi else UBOOT_SYSTEM="cuboxi" fi + elif [ "$PROJECT" == "H3" ]; then + if [ -n "$SYSTEM" ]; then + UBOOT_SYSTEM="$SYSTEM" + else + UBOOT_SYSTEM="opi2" + fi + elif [ "$PROJECT" == "A83T" ]; then + if [ -n "$SYSTEM" ]; then + UBOOT_SYSTEM="$SYSTEM" + else + UBOOT_SYSTEM="bpim3" + fi fi # variables used in image script must be passed diff --git a/scripts/mkimage b/scripts/mkimage index 53c62f5536b..e8233fdd76f 100755 --- a/scripts/mkimage +++ b/scripts/mkimage @@ -203,6 +203,8 @@ elif [ "$BOOTLOADER" = "u-boot" ]; then dd if="$RELEASE_DIR/3rdparty/bootloader/u-boot-$UBOOT_SYSTEM.imx" of="$DISK" bs=512 seek=2 conv=fsync,notrunc >"$SAVE_ERROR" 2>&1 || show_error elif [ -f "$RELEASE_DIR/3rdparty/bootloader/u-boot.imx" ]; then dd if="$RELEASE_DIR/3rdparty/bootloader/u-boot.imx" of="$DISK" bs=512 seek=2 conv=fsync,notrunc >"$SAVE_ERROR" 2>&1 || show_error + elif [ -n "$UBOOT_SYSTEM" -a -f "$RELEASE_DIR/3rdparty/bootloader/uboot-sunxi-$UBOOT_SYSTEM.bin" ]; then + dd if="$RELEASE_DIR/3rdparty/bootloader/uboot-sunxi-$UBOOT_SYSTEM.bin" of="$DISK" bs=1k seek=8 conv=fsync,notrunc >"$SAVE_ERROR" elif [ -f "$RELEASE_DIR/3rdparty/bootloader/u-boot-fuse" ]; then # allow custom dd script for vendor specific fusing . $RELEASE_DIR/3rdparty/bootloader/u-boot-fuse @@ -216,6 +218,8 @@ elif [ "$BOOTLOADER" = "u-boot" ]; then mcopy "$RELEASE_DIR/3rdparty/bootloader/u-boot-$UBOOT_SYSTEM.img" ::/u-boot.img elif [ -f $RELEASE_DIR/3rdparty/bootloader/u-boot.img ]; then mcopy $RELEASE_DIR/3rdparty/bootloader/u-boot.img :: + elif [ -f "$RELEASE_DIR/3rdparty/bootloader/$UBOOT_SYSTEM.fex" ]; then + mcopy $RELEASE_DIR/3rdparty/bootloader/$UBOOT_SYSTEM.fex ::/script.bin fi for dtb in $RELEASE_DIR/3rdparty/bootloader/*.dtb ; do