summaryrefslogtreecommitdiffstats
path: root/api/mt2266.c
diff options
context:
space:
mode:
Diffstat (limited to 'api/mt2266.c')
-rw-r--r--api/mt2266.c2368
1 files changed, 2368 insertions, 0 deletions
diff --git a/api/mt2266.c b/api/mt2266.c
new file mode 100644
index 0000000..4cdc225
--- /dev/null
+++ b/api/mt2266.c
@@ -0,0 +1,2368 @@
+/*****************************************************************************
+**
+** 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: MT2266_ReadSub(hUserData, IC_Addr, subAddress, *pData, cnt);
+** - Read byte(s) of data from the two-wire bus.
+**
+** MT2266_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 <stdlib.h> /* for NULL */ // for Linux
+
+/* 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.
+*/
+static 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
+** MT2266_ReadSub() & MT2266_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: MT2266_ReadSub - Read byte(s) of data from the two-wire bus
+** MT2266_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 = NULL;
+
+ /* Check the argument before using */
+ if (hMT2266 == NULL)
+ return MT_ARG_NULL;
+ *hMT2266 = 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 = NULL;
+ MT2266_Info[i].address = MAX_UDATA;
+ MT2266_Info[i].hUserData = 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 == 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 != 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) == 0)
+ return (MT_INV_HANDLE);
+
+ /* Remove the tuner from our list of tuners */
+ pInfo->handle = NULL;
+ pInfo->address = MAX_UDATA;
+ pInfo->hUserData = 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)
+ return (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)
+ return (MT_INV_HANDLE);
+
+ if (pInfo->RC2_Value == 0)
+ return (MT_COMM_ERR);
+
+ /*
+ ** 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: MT2266_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 == NULL)
+ status |= MT_ARG_NULL;
+
+ /* Verify that the handle passed points to a valid tuner */
+ if (IsValidHandle(pInfo) == 0)
+ return (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)
+ return (MT_INV_HANDLE);
+
+ if (val == 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)
+ return (MT_INV_HANDLE);
+
+ if (val == 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)
+ return (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)
+ return (MT_INV_HANDLE);
+
+ if (hUserData == 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: MT2266_ReadSub - Read byte(s) of data from the two-wire bus
+** MT2266_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)
+ return (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);
+ if (MT_NO_ERROR(status))
+ {
+ 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)
+ return (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)
+ return (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)
+ return (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)
+ return (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] = <desired value>
+** ...
+** 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)
+ return (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!
+**
+** MT2266_ReadSub - Read byte(s) of data from the two-wire-bus
+** MT2266_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));
+
+ /* 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 = 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);
+}
+