aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/common/tuners/mt2063.c9048
-rw-r--r--drivers/media/common/tuners/mt2063.h1365
-rw-r--r--drivers/media/common/tuners/mt2063_cfg.h151
3 files changed, 5373 insertions, 5191 deletions
diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c
index 46001916b99..0d64eb83935 100644
--- a/drivers/media/common/tuners/mt2063.c
+++ b/drivers/media/common/tuners/mt2063.c
@@ -1,4471 +1,4704 @@
1 1
2#include <linux/init.h> 2#include <linux/init.h>
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/module.h> 4#include <linux/module.h>
5#include <linux/string.h> 5#include <linux/string.h>
6 6
7#include "drxk_type.h" 7#include "drxk_type.h"
8#include "mt2063.h" 8#include "mt2063.h"
9 9
10/* Version of this module */ 10/* Version of this module */
11#define MT2063_VERSION 10018 /* Version 01.18 */ 11#define MT2063_VERSION 10018 /* Version 01.18 */
12 12
13static unsigned int verbose; 13static unsigned int verbose;
14module_param(verbose, int, 0644); 14module_param(verbose, int, 0644);
15 15
16//i2c operation 16//i2c operation
17static int mt2063_writeregs(struct mt2063_state *state, u8 reg1, 17static int mt2063_writeregs(struct mt2063_state *state, u8 reg1,
18 u8 *data, int len) 18 u8 * data, int len)
19{ 19{
20 int ret; 20 int ret;
21 u8 buf[60];/* = { reg1, data };*/ 21 u8 buf[60]; /* = { reg1, data }; */
22 22
23 struct i2c_msg msg = { 23 struct i2c_msg msg = {
24 .addr = state->config->tuner_address, 24 .addr = state->config->tuner_address,
25 .flags = 0, 25 .flags = 0,
26 .buf = buf, 26 .buf = buf,
27 .len = len + 1 27 .len = len + 1
28 }; 28 };
29 29
30 msg.buf[0] = reg1; 30 msg.buf[0] = reg1;
31 memcpy(msg.buf + 1, data, len); 31 memcpy(msg.buf + 1, data, len);
32 32
33 //printk("mt2063_writeregs state->i2c=%p\n", state->i2c); 33 //printk("mt2063_writeregs state->i2c=%p\n", state->i2c);
34 ret = i2c_transfer(state->i2c, &msg, 1); 34 ret = i2c_transfer(state->i2c, &msg, 1);
35 35
36 if (ret < 0) 36 if (ret < 0)
37 printk("mt2063_writeregs error ret=%d\n", ret); 37 printk("mt2063_writeregs error ret=%d\n", ret);
38
39 return ret;
40}
38 41
39 return ret; 42static int mt2063_read_regs(struct mt2063_state *state, u8 reg1, u8 * b, u8 len)
40}
41
42static int mt2063_read_regs(struct mt2063_state *state, u8 reg1, u8 *b, u8 len)
43{ 43{
44 int ret; 44 int ret;
45 u8 b0[] = { reg1 }; 45 u8 b0[] = { reg1 };
46 struct i2c_msg msg[] = { 46 struct i2c_msg msg[] = {
47 { 47 {
48 .addr = state->config->tuner_address, 48 .addr = state->config->tuner_address,
49 .flags = I2C_M_RD, 49 .flags = I2C_M_RD,
50 .buf = b0, 50 .buf = b0,
51 .len = 1 51 .len = 1}, {
52 }, { 52 .addr = state->config->tuner_address,
53 .addr = state->config->tuner_address, 53 .flags = I2C_M_RD,
54 .flags = I2C_M_RD, 54 .buf = b,
55 .buf = b, 55 .len = len}
56 .len = len 56 };
57
58 //printk("mt2063_read_regs state->i2c=%p\n", state->i2c);
59 ret = i2c_transfer(state->i2c, msg, 2);
60 if (ret < 0)
61 printk("mt2063_readregs error ret=%d\n", ret);
62
63 return ret;
64}
65
66//context of mt2063_userdef.c <Henry> ======================================
67//#################################################################
68//=================================================================
69/*****************************************************************************
70**
71** Name: MT_WriteSub
72**
73** Description: Write values to device using a two-wire serial bus.
74**
75** Parameters: hUserData - User-specific I/O parameter that was
76** passed to tuner's Open function.
77** addr - device serial bus address (value passed
78** as parameter to MTxxxx_Open)
79** subAddress - serial bus sub-address (Register Address)
80** pData - pointer to the Data to be written to the
81** device
82** cnt - number of bytes/registers to be written
83**
84** Returns: status:
85** MT_OK - No errors
86** MT_COMM_ERR - Serial bus communications error
87** user-defined
88**
89** Notes: This is a callback function that is called from the
90** the tuning algorithm. You MUST provide code for this
91** function to write data using the tuner's 2-wire serial
92** bus.
93**
94** The hUserData parameter is a user-specific argument.
95** If additional arguments are needed for the user's
96** serial bus read/write functions, this argument can be
97** used to supply the necessary information.
98** The hUserData parameter is initialized in the tuner's Open
99** function.
100**
101** Revision History:
102**
103** SCR Date Author Description
104** -------------------------------------------------------------------------
105** N/A 03-25-2004 DAD Original
106**
107*****************************************************************************/
108UData_t MT2063_WriteSub(Handle_t hUserData,
109 UData_t addr,
110 U8Data subAddress, U8Data * pData, UData_t cnt)
111{
112 UData_t status = MT2063_OK; /* Status to be returned */
113 struct dvb_frontend *fe = hUserData;
114 struct mt2063_state *state = fe->tuner_priv;
115 /*
116 ** ToDo: Add code here to implement a serial-bus write
117 ** operation to the MTxxxx tuner. If successful,
118 ** return MT_OK.
119 */
120/* return status; */
121
122//#if !TUNER_CONTROL_BY_DRXK_DRIVER
123 fe->ops.i2c_gate_ctrl(fe, 1); //I2C bypass drxk3926 close i2c bridge
124//#endif
125
126 if (mt2063_writeregs(state, subAddress, pData, cnt) < 0) {
127 status = MT2063_ERROR;
128 }
129//#if !TUNER_CONTROL_BY_DRXK_DRIVER
130 fe->ops.i2c_gate_ctrl(fe, 0); //I2C bypass drxk3926 close i2c bridge
131//#endif
132
133 return (status);
134}
135
136/*****************************************************************************
137**
138** Name: MT_ReadSub
139**
140** Description: Read values from device using a two-wire serial bus.
141**
142** Parameters: hUserData - User-specific I/O parameter that was
143** passed to tuner's Open function.
144** addr - device serial bus address (value passed
145** as parameter to MTxxxx_Open)
146** subAddress - serial bus sub-address (Register Address)
147** pData - pointer to the Data to be written to the
148** device
149** cnt - number of bytes/registers to be written
150**
151** Returns: status:
152** MT_OK - No errors
153** MT_COMM_ERR - Serial bus communications error
154** user-defined
155**
156** Notes: This is a callback function that is called from the
157** the tuning algorithm. You MUST provide code for this
158** function to read data using the tuner's 2-wire serial
159** bus.
160**
161** The hUserData parameter is a user-specific argument.
162** If additional arguments are needed for the user's
163** serial bus read/write functions, this argument can be
164** used to supply the necessary information.
165** The hUserData parameter is initialized in the tuner's Open
166** function.
167**
168** Revision History:
169**
170** SCR Date Author Description
171** -------------------------------------------------------------------------
172** N/A 03-25-2004 DAD Original
173**
174*****************************************************************************/
175UData_t MT2063_ReadSub(Handle_t hUserData,
176 UData_t addr,
177 U8Data subAddress, U8Data * pData, UData_t cnt)
178{
179 /*
180 ** ToDo: Add code here to implement a serial-bus read
181 ** operation to the MTxxxx tuner. If successful,
182 ** return MT_OK.
183 */
184/* return status; */
185 UData_t status = MT2063_OK; /* Status to be returned */
186 struct dvb_frontend *fe = hUserData;
187 struct mt2063_state *state = fe->tuner_priv;
188 UData_t i = 0;
189//#if !TUNER_CONTROL_BY_DRXK_DRIVER
190 fe->ops.i2c_gate_ctrl(fe, 1); //I2C bypass drxk3926 close i2c bridge
191//#endif
192
193 for (i = 0; i < cnt; i++) {
194 if (mt2063_read_regs(state, subAddress + i, pData + i, 1) < 0) {
195 status = MT2063_ERROR;
196 break;
197 }
198 }
199
200//#if !TUNER_CONTROL_BY_DRXK_DRIVER
201 fe->ops.i2c_gate_ctrl(fe, 0); //I2C bypass drxk3926 close i2c bridge
202//#endif
203
204 return (status);
205}
206
207/*****************************************************************************
208**
209** Name: MT_Sleep
210**
211** Description: Delay execution for "nMinDelayTime" milliseconds
212**
213** Parameters: hUserData - User-specific I/O parameter that was
214** passed to tuner's Open function.
215** nMinDelayTime - Delay time in milliseconds
216**
217** Returns: None.
218**
219** Notes: This is a callback function that is called from the
220** the tuning algorithm. You MUST provide code that
221** blocks execution for the specified period of time.
222**
223** Revision History:
224**
225** SCR Date Author Description
226** -------------------------------------------------------------------------
227** N/A 03-25-2004 DAD Original
228**
229*****************************************************************************/
230void MT2063_Sleep(Handle_t hUserData, UData_t nMinDelayTime)
231{
232 /*
233 ** ToDo: Add code here to implement a OS blocking
234 ** for a period of "nMinDelayTime" milliseconds.
235 */
236 msleep(nMinDelayTime);
237}
238
239#if defined(MT2060_CNT)
240#if MT2060_CNT > 0
241/*****************************************************************************
242**
243** Name: MT_TunerGain (MT2060 only)
244**
245** Description: Measure the relative tuner gain using the demodulator
246**
247** Parameters: hUserData - User-specific I/O parameter that was
248** passed to tuner's Open function.
249** pMeas - Tuner gain (1/100 of dB scale).
250** ie. 1234 = 12.34 (dB)
251**
252** Returns: status:
253** MT_OK - No errors
254** user-defined errors could be set
255**
256** Notes: This is a callback function that is called from the
257** the 1st IF location routine. You MUST provide
258** code that measures the relative tuner gain in a dB
259** (not linear) scale. The return value is an integer
260** value scaled to 1/100 of a dB.
261**
262** Revision History:
263**
264** SCR Date Author Description
265** -------------------------------------------------------------------------
266** N/A 06-16-2004 DAD Original
267** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name
268** better describes what this function does.
269**
270*****************************************************************************/
271UData_t MT2060_TunerGain(Handle_t hUserData, SData_t * pMeas)
272{
273 UData_t status = MT2063_OK; /* Status to be returned */
274
275 /*
276 ** ToDo: Add code here to return the gain / power level measured
277 ** at the input to the demodulator.
278 */
279
280 return (status);
281}
282#endif
283#endif
284//end of mt2063_userdef.c
285//=================================================================
286//#################################################################
287//=================================================================
288
289//context of mt2063_spuravoid.c <Henry> ======================================
290//#################################################################
291//=================================================================
292
293/*****************************************************************************
294**
295** Name: mt_spuravoid.c
296**
297** Description: Microtune spur avoidance software module.
298** Supports Microtune tuner drivers.
299**
300** CVS ID: $Id: mt_spuravoid.c,v 1.3 2008/06/26 15:39:52 software Exp $
301** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2063/mt_spuravoid.c,v $
302**
303** Revision History:
304**
305** SCR Date Author Description
306** -------------------------------------------------------------------------
307** 082 03-25-2005 JWS Original multi-tuner support - requires
308** MTxxxx_CNT declarations
309** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0.
310** 094 04-06-2005 JWS Ver 1.11 Added uceil and ufloor to get rid
311** of compiler warnings
312** N/A 04-07-2005 DAD Ver 1.13: Merged single- and multi-tuner spur
313** avoidance into a single module.
314** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range
315** (f_min, f_max) < 0, ignore the entry.
316** 115 03-23-2007 DAD Fix declaration of spur due to truncation
317** errors.
318** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from
319** tuner DLL.
320** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for
321** multi-tuners that have
322** (delta IF1) > (f_out-f_outbw/2).
323** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+)
324** Added logic to force f_Center within 1/2 f_Step.
325** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2
326** Type casts added to preserve correct sign.
327** N/A I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT
328** frequencies into MT_ResetExclZones().
329** N/A I 06-20-2008 RSK Ver 1.21: New VERSION number for ver checking.
330**
331*****************************************************************************/
332
333#if !defined(MT2063_TUNER_CNT)
334#error MT2063_TUNER_CNT is not defined (see mt_userdef.h)
335#endif
336
337#if MT2063_TUNER_CNT == 0
338#error MT2063_TUNER_CNT must be updated in mt_userdef.h
339#endif
340
341/* Version of this module */
342#define MT2063_SPUR_VERSION 10201 /* Version 01.21 */
343
344/* Implement ceiling, floor functions. */
345#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
346#define uceil(n, d) ((n)/(d) + ((n)%(d) != 0))
347#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
348#define ufloor(n, d) ((n)/(d))
349
350struct MT2063_FIFZone_t {
351 SData_t min_;
352 SData_t max_;
353};
354
355#if MT2063_TUNER_CNT > 1
356static struct MT2063_AvoidSpursData_t *TunerList[MT2063_TUNER_CNT];
357static UData_t TunerCount = 0;
358#endif
359
360UData_t MT2063_RegisterTuner(struct MT2063_AvoidSpursData_t *pAS_Info)
361{
362#if MT2063_TUNER_CNT == 1
363 pAS_Info->nAS_Algorithm = 1;
364 return MT2063_OK;
365#else
366 UData_t index;
367
368 pAS_Info->nAS_Algorithm = 2;
369
370 /*
371 ** Check to see if tuner is already registered
372 */
373 for (index = 0; index < TunerCount; index++) {
374 if (TunerList[index] == pAS_Info) {
375 return MT2063_OK; /* Already here - no problem */
376 }
377 }
378
379 /*
380 ** Add tuner to list - if there is room.
381 */
382 if (TunerCount < MT2063_TUNER_CNT) {
383 TunerList[TunerCount] = pAS_Info;
384 TunerCount++;
385 return MT2063_OK;
386 } else
387 return MT2063_TUNER_CNT_ERR;
388#endif
389}
390
391void MT2063_UnRegisterTuner(struct MT2063_AvoidSpursData_t *pAS_Info)
392{
393#if MT2063_TUNER_CNT == 1
394 pAS_Info;
395#else
396
397 UData_t index;
398
399 for (index = 0; index < TunerCount; index++) {
400 if (TunerList[index] == pAS_Info) {
401 TunerList[index] = TunerList[--TunerCount];
402 }
403 }
404#endif
405}
406
407/*
408** Reset all exclusion zones.
409** Add zones to protect the PLL FracN regions near zero
410**
411** N/A I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT
412** frequencies into MT_ResetExclZones().
413*/
414void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
415{
416 UData_t center;
417#if MT2063_TUNER_CNT > 1
418 UData_t index;
419 struct MT2063_AvoidSpursData_t *adj;
420#endif
421
422 pAS_Info->nZones = 0; /* this clears the used list */
423 pAS_Info->usedZones = NULL; /* reset ptr */
424 pAS_Info->freeZones = NULL; /* reset ptr */
425
426 center =
427 pAS_Info->f_ref *
428 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
429 pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
430 while (center <
431 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
432 pAS_Info->f_LO1_FracN_Avoid) {
433 /* Exclude LO1 FracN */
434 MT2063_AddExclZone(pAS_Info,
435 center - pAS_Info->f_LO1_FracN_Avoid,
436 center - 1);
437 MT2063_AddExclZone(pAS_Info, center + 1,
438 center + pAS_Info->f_LO1_FracN_Avoid);
439 center += pAS_Info->f_ref;
440 }
441
442 center =
443 pAS_Info->f_ref *
444 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
445 pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
446 while (center <
447 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
448 pAS_Info->f_LO2_FracN_Avoid) {
449 /* Exclude LO2 FracN */
450 MT2063_AddExclZone(pAS_Info,
451 center - pAS_Info->f_LO2_FracN_Avoid,
452 center - 1);
453 MT2063_AddExclZone(pAS_Info, center + 1,
454 center + pAS_Info->f_LO2_FracN_Avoid);
455 center += pAS_Info->f_ref;
456 }
457
458 if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
459 /* Exclude LO1 values that conflict with DECT channels */
460 MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */
461 MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */
462 MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */
463 MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */
464 MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */
465 }
466
467 if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
468 MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */
469 MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */
470 MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */
471 MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16 */
472 MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */
473 MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */
474 MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */
475 MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */
476 MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52 */
477 MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */
478 }
479#if MT2063_TUNER_CNT > 1
480 /*
481 ** Iterate through all adjacent tuners and exclude frequencies related to them
482 */
483 for (index = 0; index < TunerCount; ++index) {
484 adj = TunerList[index];
485 if (pAS_Info == adj) /* skip over our own data, don't process it */
486 continue;
487
488 /*
489 ** Add 1st IF exclusion zone covering adjacent tuner's LO2
490 ** at "adjfLO2 + f_out" +/- m_MinLOSpacing
491 */
492 if (adj->f_LO2 != 0)
493 MT2063_AddExclZone(pAS_Info,
494 (adj->f_LO2 + pAS_Info->f_out) -
495 pAS_Info->f_min_LO_Separation,
496 (adj->f_LO2 + pAS_Info->f_out) +
497 pAS_Info->f_min_LO_Separation);
498
499 /*
500 ** Add 1st IF exclusion zone covering adjacent tuner's LO1
501 ** at "adjfLO1 - f_in" +/- m_MinLOSpacing
502 */
503 if (adj->f_LO1 != 0)
504 MT2063_AddExclZone(pAS_Info,
505 (adj->f_LO1 - pAS_Info->f_in) -
506 pAS_Info->f_min_LO_Separation,
507 (adj->f_LO1 - pAS_Info->f_in) +
508 pAS_Info->f_min_LO_Separation);
509 }
510#endif
511}
512
513static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
514 *pAS_Info,
515 struct MT2063_ExclZone_t *pPrevNode)
516{
517 struct MT2063_ExclZone_t *pNode;
518 /* Check for a node in the free list */
519 if (pAS_Info->freeZones != NULL) {
520 /* Use one from the free list */
521 pNode = pAS_Info->freeZones;
522 pAS_Info->freeZones = pNode->next_;
523 } else {
524 /* Grab a node from the array */
525 pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
526 }
527
528 if (pPrevNode != NULL) {
529 pNode->next_ = pPrevNode->next_;
530 pPrevNode->next_ = pNode;
531 } else { /* insert at the beginning of the list */
532
533 pNode->next_ = pAS_Info->usedZones;
534 pAS_Info->usedZones = pNode;
535 }
536
537 pAS_Info->nZones++;
538 return pNode;
539}
540
541static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
542 *pAS_Info,
543 struct MT2063_ExclZone_t *pPrevNode,
544 struct MT2063_ExclZone_t
545 *pNodeToRemove)
546{
547 struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
548
549 /* Make previous node point to the subsequent node */
550 if (pPrevNode != NULL)
551 pPrevNode->next_ = pNext;
552
553 /* Add pNodeToRemove to the beginning of the freeZones */
554 pNodeToRemove->next_ = pAS_Info->freeZones;
555 pAS_Info->freeZones = pNodeToRemove;
556
557 /* Decrement node count */
558 pAS_Info->nZones--;
559
560 return pNext;
561}
562
563/*****************************************************************************
564**
565** Name: MT_AddExclZone
566**
567** Description: Add (and merge) an exclusion zone into the list.
568** If the range (f_min, f_max) is totally outside the
569** 1st IF BW, ignore the entry.
570** If the range (f_min, f_max) is negative, ignore the entry.
571**
572** Revision History:
573**
574** SCR Date Author Description
575** -------------------------------------------------------------------------
576** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range
577** (f_min, f_max) < 0, ignore the entry.
578**
579*****************************************************************************/
580void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
581 UData_t f_min, UData_t f_max)
582{
583 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
584 struct MT2063_ExclZone_t *pPrev = NULL;
585 struct MT2063_ExclZone_t *pNext = NULL;
586
587 /* Check to see if this overlaps the 1st IF filter */
588 if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
589 && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
590 && (f_min < f_max)) {
591 /*
592 ** 1 2 3 4 5 6
593 **
594 ** New entry: |---| |--| |--| |-| |---| |--|
595 ** or or or or or
596 ** Existing: |--| |--| |--| |---| |-| |--|
597 */
598
599 /* Check for our place in the list */
600 while ((pNode != NULL) && (pNode->max_ < f_min)) {
601 pPrev = pNode;
602 pNode = pNode->next_;
603 }
604
605 if ((pNode != NULL) && (pNode->min_ < f_max)) {
606 /* Combine me with pNode */
607 if (f_min < pNode->min_)
608 pNode->min_ = f_min;
609 if (f_max > pNode->max_)
610 pNode->max_ = f_max;
611 } else {
612 pNode = InsertNode(pAS_Info, pPrev);
613 pNode->min_ = f_min;
614 pNode->max_ = f_max;
615 }
616
617 /* Look for merging possibilities */
618 pNext = pNode->next_;
619 while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
620 if (pNext->max_ > pNode->max_)
621 pNode->max_ = pNext->max_;
622 pNext = RemoveNode(pAS_Info, pNode, pNext); /* Remove pNext, return ptr to pNext->next */
623 }
624 }
625}
626
627/*****************************************************************************
628**
629** Name: MT_ChooseFirstIF
630**
631** Description: Choose the best available 1st IF
632** If f_Desired is not excluded, choose that first.
633** Otherwise, return the value closest to f_Center that is
634** not excluded
635**
636** Revision History:
637**
638** SCR Date Author Description
639** -------------------------------------------------------------------------
640** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from
641** tuner DLL.
642** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+)
643** Added logic to force f_Center within 1/2 f_Step.
644**
645*****************************************************************************/
646UData_t MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
647{
648 /*
649 ** Update "f_Desired" to be the nearest "combinational-multiple" of "f_LO1_Step".
650 ** The resulting number, F_LO1 must be a multiple of f_LO1_Step. And F_LO1 is the arithmetic sum
651 ** of f_in + f_Center. Neither f_in, nor f_Center must be a multiple of f_LO1_Step.
652 ** However, the sum must be.
653 */
654 const UData_t f_Desired =
655 pAS_Info->f_LO1_Step *
656 ((pAS_Info->f_if1_Request + pAS_Info->f_in +
657 pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
658 pAS_Info->f_in;
659 const UData_t f_Step =
660 (pAS_Info->f_LO1_Step >
661 pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
662 f_LO2_Step;
663 UData_t f_Center;
664
665 SData_t i;
666 SData_t j = 0;
667 UData_t bDesiredExcluded = 0;
668 UData_t bZeroExcluded = 0;
669 SData_t tmpMin, tmpMax;
670 SData_t bestDiff;
671 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
672 struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
673
674 if (pAS_Info->nZones == 0)
675 return f_Desired;
676
677 /* f_Center needs to be an integer multiple of f_Step away from f_Desired */
678 if (pAS_Info->f_if1_Center > f_Desired)
679 f_Center =
680 f_Desired +
681 f_Step *
682 ((pAS_Info->f_if1_Center - f_Desired +
683 f_Step / 2) / f_Step);
684 else
685 f_Center =
686 f_Desired -
687 f_Step *
688 ((f_Desired - pAS_Info->f_if1_Center +
689 f_Step / 2) / f_Step);
690
691 //assert;
692 //if (!abs((SData_t) f_Center - (SData_t) pAS_Info->f_if1_Center) <= (SData_t) (f_Step/2))
693 // return 0;
694
695 /* Take MT_ExclZones, center around f_Center and change the resolution to f_Step */
696 while (pNode != NULL) {
697 /* floor function */
698 tmpMin =
699 floor((SData_t) (pNode->min_ - f_Center), (SData_t) f_Step);
700
701 /* ceil function */
702 tmpMax =
703 ceil((SData_t) (pNode->max_ - f_Center), (SData_t) f_Step);
704
705 if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
706 bDesiredExcluded = 1;
707
708 if ((tmpMin < 0) && (tmpMax > 0))
709 bZeroExcluded = 1;
710
711 /* See if this zone overlaps the previous */
712 if ((j > 0) && (tmpMin < zones[j - 1].max_))
713 zones[j - 1].max_ = tmpMax;
714 else {
715 /* Add new zone */
716 //assert(j<MT2063_MAX_ZONES);
717 //if (j>=MT2063_MAX_ZONES)
718 //break;
719
720 zones[j].min_ = tmpMin;
721 zones[j].max_ = tmpMax;
722 j++;
723 }
724 pNode = pNode->next_;
725 }
726
727 /*
728 ** If the desired is okay, return with it
729 */
730 if (bDesiredExcluded == 0)
731 return f_Desired;
732
733 /*
734 ** If the desired is excluded and the center is okay, return with it
735 */
736 if (bZeroExcluded == 0)
737 return f_Center;
738
739 /* Find the value closest to 0 (f_Center) */
740 bestDiff = zones[0].min_;
741 for (i = 0; i < j; i++) {
742 if (abs(zones[i].min_) < abs(bestDiff))
743 bestDiff = zones[i].min_;
744 if (abs(zones[i].max_) < abs(bestDiff))
745 bestDiff = zones[i].max_;
746 }
747
748 if (bestDiff < 0)
749 return f_Center - ((UData_t) (-bestDiff) * f_Step);
750
751 return f_Center + (bestDiff * f_Step);
752}
753
754/****************************************************************************
755**
756** Name: gcd
757**
758** Description: Uses Euclid's algorithm
759**
760** Parameters: u, v - unsigned values whose GCD is desired.
761**
762** Global: None
763**
764** Returns: greatest common divisor of u and v, if either value
765** is 0, the other value is returned as the result.
766**
767** Dependencies: None.
768**
769** Revision History:
770**
771** SCR Date Author Description
772** -------------------------------------------------------------------------
773** N/A 06-01-2004 JWS Original
774** N/A 08-03-2004 DAD Changed to Euclid's since it can handle
775** unsigned numbers.
776**
777****************************************************************************/
778static UData_t MT2063_gcd(UData_t u, UData_t v)
779{
780 UData_t r;
781
782 while (v != 0) {
783 r = u % v;
784 u = v;
785 v = r;
786 }
787
788 return u;
789}
790
791/****************************************************************************
792**
793** Name: umax
794**
795** Description: Implements a simple maximum function for unsigned numbers.
796** Implemented as a function rather than a macro to avoid
797** multiple evaluation of the calling parameters.
798**
799** Parameters: a, b - Values to be compared
800**
801** Global: None
802**
803** Returns: larger of the input values.
804**
805** Dependencies: None.
806**
807** Revision History:
808**
809** SCR Date Author Description
810** -------------------------------------------------------------------------
811** N/A 06-02-2004 JWS Original
812**
813****************************************************************************/
814static UData_t MT2063_umax(UData_t a, UData_t b)
815{
816 return (a >= b) ? a : b;
817}
818
819#if MT2063_TUNER_CNT > 1
820static SData_t RoundAwayFromZero(SData_t n, SData_t d)
821{
822 return (n < 0) ? floor(n, d) : ceil(n, d);
823}
824
825/****************************************************************************
826**
827** Name: IsSpurInAdjTunerBand
828**
829** Description: Checks to see if a spur will be present within the IF's
830** bandwidth or near the zero IF.
831** (fIFOut +/- fIFBW/2, -fIFOut +/- fIFBW/2)
832** and
833** (0 +/- fZIFBW/2)
834**
835** ma mb me mf mc md
836** <--+-+-+-----------------+-+-+-----------------+-+-+-->
837** | ^ 0 ^ |
838** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^
839** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2
840**
841** Note that some equations are doubled to prevent round-off
842** problems when calculating fIFBW/2
843**
844** The spur frequencies are computed as:
845**
846** fSpur = n * f1 - m * f2 - fOffset
847**
848** Parameters: f1 - The 1st local oscillator (LO) frequency
849** of the tuner whose output we are examining
850** f2 - The 1st local oscillator (LO) frequency
851** of the adjacent tuner
852** fOffset - The 2nd local oscillator of the tuner whose
853** output we are examining
854** fIFOut - Output IF center frequency
855** fIFBW - Output IF Bandwidth
856** nMaxH - max # of LO harmonics to search
857** fp - If spur, positive distance to spur-free band edge (returned)
858** fm - If spur, negative distance to spur-free band edge (returned)
859**
860** Returns: 1 if an LO spur would be present, otherwise 0.
861**
862** Dependencies: None.
863**
864** Revision History:
865**
866** SCR Date Author Description
867** -------------------------------------------------------------------------
868** N/A 01-21-2005 JWS Original, adapted from MT_DoubleConversion.
869** 115 03-23-2007 DAD Fix declaration of spur due to truncation
870** errors.
871** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for
872** multi-tuners that have
873** (delta IF1) > (f_out-f_outbw/2).
874** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2
875** Type casts added to preserve correct sign.
876**
877****************************************************************************/
878static UData_t IsSpurInAdjTunerBand(UData_t bIsMyOutput,
879 UData_t f1,
880 UData_t f2,
881 UData_t fOffset,
882 UData_t fIFOut,
883 UData_t fIFBW,
884 UData_t fZIFBW,
885 UData_t nMaxH, UData_t * fp, UData_t * fm)
886{
887 UData_t bSpurFound = 0;
888
889 const UData_t fHalf_IFBW = fIFBW / 2;
890 const UData_t fHalf_ZIFBW = fZIFBW / 2;
891
892 /* Calculate a scale factor for all frequencies, so that our
893 calculations all stay within 31 bits */
894 const UData_t f_Scale =
895 ((f1 +
896 (fOffset + fIFOut +
897 fHalf_IFBW) / nMaxH) / (MAX_UDATA / 2 / nMaxH)) + 1;
898
899 /*
900 ** After this scaling, _f1, _f2, and _f3 are guaranteed to fit into
901 ** signed data types (smaller than MAX_UDATA/2)
902 */
903 const SData_t _f1 = (SData_t) (f1 / f_Scale);
904 const SData_t _f2 = (SData_t) (f2 / f_Scale);
905 const SData_t _f3 = (SData_t) (fOffset / f_Scale);
906
907 const SData_t c = (SData_t) (fIFOut - fHalf_IFBW) / (SData_t) f_Scale;
908 const SData_t d = (SData_t) ((fIFOut + fHalf_IFBW) / f_Scale);
909 const SData_t f = (SData_t) (fHalf_ZIFBW / f_Scale);
910
911 SData_t ma, mb, mc, md, me, mf;
912
913 SData_t fp_ = 0;
914 SData_t fm_ = 0;
915 SData_t n;
916
917 /*
918 ** If the other tuner does not have an LO frequency defined,
919 ** assume that we cannot interfere with it
920 */
921 if (f2 == 0)
922 return 0;
923
924 /* Check out all multiples of f1 from -nMaxH to +nMaxH */
925 for (n = -(SData_t) nMaxH; n <= (SData_t) nMaxH; ++n) {
926 const SData_t nf1 = n * _f1;
927 md = (_f3 + d - nf1) / _f2;
928
929 /* If # f2 harmonics > nMaxH, then no spurs present */
930 if (md <= -(SData_t) nMaxH)
931 break;
932
933 ma = (_f3 - d - nf1) / _f2;
934 if ((ma == md) || (ma >= (SData_t) (nMaxH)))
935 continue;
936
937 mc = (_f3 + c - nf1) / _f2;
938 if (mc != md) {
939 const SData_t m = (n < 0) ? md : mc;
940 const SData_t fspur = (nf1 + m * _f2 - _f3);
941 const SData_t den = (bIsMyOutput ? n - 1 : n);
942 if (den == 0) {
943 fp_ = (d - fspur) * f_Scale;
944 fm_ = (fspur - c) * f_Scale;
945 } else {
946 fp_ =
947 (SData_t) RoundAwayFromZero((d - fspur) *
948 f_Scale, den);
949 fm_ =
950 (SData_t) RoundAwayFromZero((fspur - c) *
951 f_Scale, den);
952 }
953 if (((UData_t) abs(fm_) >= f_Scale)
954 && ((UData_t) abs(fp_) >= f_Scale)) {
955 bSpurFound = 1;
956 break;
957 }
958 }
959
960 /* Location of Zero-IF-spur to be checked */
961 mf = (_f3 + f - nf1) / _f2;
962 me = (_f3 - f - nf1) / _f2;
963 if (me != mf) {
964 const SData_t m = (n < 0) ? mf : me;
965 const SData_t fspur = (nf1 + m * _f2 - _f3);
966 const SData_t den = (bIsMyOutput ? n - 1 : n);
967 if (den == 0) {
968 fp_ = (d - fspur) * f_Scale;
969 fm_ = (fspur - c) * f_Scale;
970 } else {
971 fp_ =
972 (SData_t) RoundAwayFromZero((f - fspur) *
973 f_Scale, den);
974 fm_ =
975 (SData_t) RoundAwayFromZero((fspur + f) *
976 f_Scale, den);
977 }
978 if (((UData_t) abs(fm_) >= f_Scale)
979 && ((UData_t) abs(fp_) >= f_Scale)) {
980 bSpurFound = 1;
981 break;
982 }
983 }
984
985 mb = (_f3 - c - nf1) / _f2;
986 if (ma != mb) {
987 const SData_t m = (n < 0) ? mb : ma;
988 const SData_t fspur = (nf1 + m * _f2 - _f3);
989 const SData_t den = (bIsMyOutput ? n - 1 : n);
990 if (den == 0) {
991 fp_ = (d - fspur) * f_Scale;
992 fm_ = (fspur - c) * f_Scale;
993 } else {
994 fp_ =
995 (SData_t) RoundAwayFromZero((-c - fspur) *
996 f_Scale, den);
997 fm_ =
998 (SData_t) RoundAwayFromZero((fspur + d) *
999 f_Scale, den);
1000 }
1001 if (((UData_t) abs(fm_) >= f_Scale)
1002 && ((UData_t) abs(fp_) >= f_Scale)) {
1003 bSpurFound = 1;
1004 break;
1005 }
1006 }
1007 }
1008
1009 /*
1010 ** Verify that fm & fp are both positive
1011 ** Add one to ensure next 1st IF choice is not right on the edge
1012 */
1013 if (fp_ < 0) {
1014 *fp = -fm_ + 1;
1015 *fm = -fp_ + 1;
1016 } else if (fp_ > 0) {
1017 *fp = fp_ + 1;
1018 *fm = fm_ + 1;
1019 } else {
1020 *fp = 1;
1021 *fm = abs(fm_) + 1;
1022 }
1023
1024 return bSpurFound;
1025}
1026#endif
1027
1028/****************************************************************************
1029**
1030** Name: IsSpurInBand
1031**
1032** Description: Checks to see if a spur will be present within the IF's
1033** bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
1034**
1035** ma mb mc md
1036** <--+-+-+-------------------+-------------------+-+-+-->
1037** | ^ 0 ^ |
1038** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^
1039** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2
1040**
1041** Note that some equations are doubled to prevent round-off
1042** problems when calculating fIFBW/2
1043**
1044** Parameters: pAS_Info - Avoid Spurs information block
1045** fm - If spur, amount f_IF1 has to move negative
1046** fp - If spur, amount f_IF1 has to move positive
1047**
1048** Global: None
1049**
1050** Returns: 1 if an LO spur would be present, otherwise 0.
1051**
1052** Dependencies: None.
1053**
1054** Revision History:
1055**
1056** SCR Date Author Description
1057** -------------------------------------------------------------------------
1058** N/A 11-28-2002 DAD Implemented algorithm from applied patent
1059**
1060****************************************************************************/
1061static UData_t IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
1062 UData_t * fm, UData_t * fp)
1063{
1064 /*
1065 ** Calculate LO frequency settings.
1066 */
1067 UData_t n, n0;
1068 const UData_t f_LO1 = pAS_Info->f_LO1;
1069 const UData_t f_LO2 = pAS_Info->f_LO2;
1070 const UData_t d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
1071 const UData_t c = d - pAS_Info->f_out_bw;
1072 const UData_t f = pAS_Info->f_zif_bw / 2;
1073 const UData_t f_Scale = (f_LO1 / (MAX_UDATA / 2 / pAS_Info->maxH1)) + 1;
1074 SData_t f_nsLO1, f_nsLO2;
1075 SData_t f_Spur;
1076 UData_t ma, mb, mc, md, me, mf;
1077 UData_t lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
1078#if MT2063_TUNER_CNT > 1
1079 UData_t index;
1080
1081 struct MT2063_AvoidSpursData_t *adj;
1082#endif
1083 *fm = 0;
1084
1085 /*
1086 ** For each edge (d, c & f), calculate a scale, based on the gcd
1087 ** of f_LO1, f_LO2 and the edge value. Use the larger of this
1088 ** gcd-based scale factor or f_Scale.
1089 */
1090 lo_gcd = MT2063_gcd(f_LO1, f_LO2);
1091 gd_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, d), f_Scale);
1092 hgds = gd_Scale / 2;
1093 gc_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, c), f_Scale);
1094 hgcs = gc_Scale / 2;
1095 gf_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, f), f_Scale);
1096 hgfs = gf_Scale / 2;
1097
1098 n0 = uceil(f_LO2 - d, f_LO1 - f_LO2);
1099
1100 /* Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic */
1101 for (n = n0; n <= pAS_Info->maxH1; ++n) {
1102 md = (n * ((f_LO1 + hgds) / gd_Scale) -
1103 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
1104
1105 /* If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present */
1106 if (md >= pAS_Info->maxH1)
1107 break;
1108
1109 ma = (n * ((f_LO1 + hgds) / gd_Scale) +
1110 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
1111
1112 /* If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic */
1113 if (md == ma)
1114 continue;
1115
1116 mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
1117 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
1118 if (mc != md) {
1119 f_nsLO1 = (SData_t) (n * (f_LO1 / gc_Scale));
1120 f_nsLO2 = (SData_t) (mc * (f_LO2 / gc_Scale));
1121 f_Spur =
1122 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
1123 n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
1124
1125 *fp = ((f_Spur - (SData_t) c) / (mc - n)) + 1;
1126 *fm = (((SData_t) d - f_Spur) / (mc - n)) + 1;
1127 return 1;
1128 }
1129
1130 /* Location of Zero-IF-spur to be checked */
1131 me = (n * ((f_LO1 + hgfs) / gf_Scale) +
1132 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
1133 mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
1134 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
1135 if (me != mf) {
1136 f_nsLO1 = n * (f_LO1 / gf_Scale);
1137 f_nsLO2 = me * (f_LO2 / gf_Scale);
1138 f_Spur =
1139 (gf_Scale * (f_nsLO1 - f_nsLO2)) +
1140 n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
1141
1142 *fp = ((f_Spur + (SData_t) f) / (me - n)) + 1;
1143 *fm = (((SData_t) f - f_Spur) / (me - n)) + 1;
1144 return 1;
1145 }
1146
1147 mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
1148 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
1149 if (ma != mb) {
1150 f_nsLO1 = n * (f_LO1 / gc_Scale);
1151 f_nsLO2 = ma * (f_LO2 / gc_Scale);
1152 f_Spur =
1153 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
1154 n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
1155
1156 *fp = (((SData_t) d + f_Spur) / (ma - n)) + 1;
1157 *fm = (-(f_Spur + (SData_t) c) / (ma - n)) + 1;
1158 return 1;
1159 }
1160 }
1161
1162#if MT2063_TUNER_CNT > 1
1163 /* If no spur found, see if there are more tuners on the same board */
1164 for (index = 0; index < TunerCount; ++index) {
1165 adj = TunerList[index];
1166 if (pAS_Info == adj) /* skip over our own data, don't process it */
1167 continue;
1168
1169 /* Look for LO-related spurs from the adjacent tuner generated into my IF output */
1170 if (IsSpurInAdjTunerBand(1, /* check my IF output */
1171 pAS_Info->f_LO1, /* my fLO1 */
1172 adj->f_LO1, /* the other tuner's fLO1 */
1173 pAS_Info->f_LO2, /* my fLO2 */
1174 pAS_Info->f_out, /* my fOut */
1175 pAS_Info->f_out_bw, /* my output IF bandwidth */
1176 pAS_Info->f_zif_bw, /* my Zero-IF bandwidth */
1177 pAS_Info->maxH2, fp, /* minimum amount to move LO's positive */
1178 fm)) /* miminum amount to move LO's negative */
1179 return 1;
1180 /* Look for LO-related spurs from my tuner generated into the adjacent tuner's IF output */
1181 if (IsSpurInAdjTunerBand(0, /* check his IF output */
1182 pAS_Info->f_LO1, /* my fLO1 */
1183 adj->f_LO1, /* the other tuner's fLO1 */
1184 adj->f_LO2, /* the other tuner's fLO2 */
1185 adj->f_out, /* the other tuner's fOut */
1186 adj->f_out_bw, /* the other tuner's output IF bandwidth */
1187 pAS_Info->f_zif_bw, /* the other tuner's Zero-IF bandwidth */
1188 adj->maxH2, fp, /* minimum amount to move LO's positive */
1189 fm)) /* miminum amount to move LO's negative */
1190 return 1;
1191 }
1192#endif
1193 /* No spurs found */
1194 return 0;
1195}
1196
1197/*****************************************************************************
1198**
1199** Name: MT_AvoidSpurs
1200**
1201** Description: Main entry point to avoid spurs.
1202** Checks for existing spurs in present LO1, LO2 freqs
1203** and if present, chooses spur-free LO1, LO2 combination
1204** that tunes the same input/output frequencies.
1205**
1206** Revision History:
1207**
1208** SCR Date Author Description
1209** -------------------------------------------------------------------------
1210** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0.
1211**
1212*****************************************************************************/
1213UData_t MT2063_AvoidSpurs(Handle_t h, struct MT2063_AvoidSpursData_t * pAS_Info)
1214{
1215 UData_t status = MT2063_OK;
1216 UData_t fm, fp; /* restricted range on LO's */
1217 pAS_Info->bSpurAvoided = 0;
1218 pAS_Info->nSpursFound = 0;
1219
1220 if (pAS_Info->maxH1 == 0)
1221 return MT2063_OK;
1222
1223 /*
1224 ** Avoid LO Generated Spurs
1225 **
1226 ** Make sure that have no LO-related spurs within the IF output
1227 ** bandwidth.
1228 **
1229 ** If there is an LO spur in this band, start at the current IF1 frequency
1230 ** and work out until we find a spur-free frequency or run up against the
1231 ** 1st IF SAW band edge. Use temporary copies of fLO1 and fLO2 so that they
1232 ** will be unchanged if a spur-free setting is not found.
1233 */
1234 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
1235 if (pAS_Info->bSpurPresent) {
1236 UData_t zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in; /* current attempt at a 1st IF */
1237 UData_t zfLO1 = pAS_Info->f_LO1; /* current attempt at an LO1 freq */
1238 UData_t zfLO2 = pAS_Info->f_LO2; /* current attempt at an LO2 freq */
1239 UData_t delta_IF1;
1240 UData_t new_IF1;
1241
1242 /*
1243 ** Spur was found, attempt to find a spur-free 1st IF
1244 */
1245 do {
1246 pAS_Info->nSpursFound++;
1247
1248 /* Raise f_IF1_upper, if needed */
1249 MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
1250
1251 /* Choose next IF1 that is closest to f_IF1_CENTER */
1252 new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
1253
1254 if (new_IF1 > zfIF1) {
1255 pAS_Info->f_LO1 += (new_IF1 - zfIF1);
1256 pAS_Info->f_LO2 += (new_IF1 - zfIF1);
1257 } else {
1258 pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
1259 pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
1260 }
1261 zfIF1 = new_IF1;
1262
1263 if (zfIF1 > pAS_Info->f_if1_Center)
1264 delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
1265 else
1266 delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
1267 }
1268 /*
1269 ** Continue while the new 1st IF is still within the 1st IF bandwidth
1270 ** and there is a spur in the band (again)
1271 */
1272 while ((2 * delta_IF1 + pAS_Info->f_out_bw <=
1273 pAS_Info->f_if1_bw)
1274 && (pAS_Info->bSpurPresent =
1275 IsSpurInBand(pAS_Info, &fm, &fp)));
1276
1277 /*
1278 ** Use the LO-spur free values found. If the search went all the way to
1279 ** the 1st IF band edge and always found spurs, just leave the original
1280 ** choice. It's as "good" as any other.
1281 */
1282 if (pAS_Info->bSpurPresent == 1) {
1283 status |= MT2063_SPUR_PRESENT_ERR;
1284 pAS_Info->f_LO1 = zfLO1;
1285 pAS_Info->f_LO2 = zfLO2;
1286 } else
1287 pAS_Info->bSpurAvoided = 1;
1288 }
1289
1290 status |=
1291 ((pAS_Info->
1292 nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
1293
1294 return (status);
1295}
1296
1297UData_t MT2063_AvoidSpursVersion(void)
1298{
1299 return (MT2063_SPUR_VERSION);
1300}
1301
1302//end of mt2063_spuravoid.c
1303//=================================================================
1304//#################################################################
1305//=================================================================
1306
1307/*
1308** The expected version of MT_AvoidSpursData_t
1309** If the version is different, an updated file is needed from Microtune
1310*/
1311/* Expecting version 1.21 of the Spur Avoidance API */
1312#define EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION 010201
1313
1314#if MT2063_AVOID_SPURS_INFO_VERSION < EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION
1315#error Contact Microtune for a newer version of MT_SpurAvoid.c
1316#elif MT2063_AVOID_SPURS_INFO_VERSION > EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION
1317#error Contact Microtune for a newer version of mt2063.c
1318#endif
1319
1320#ifndef MT2063_CNT
1321#error You must define MT2063_CNT in the "mt_userdef.h" file
1322#endif
1323
1324typedef enum {
1325 MT2063_SET_ATTEN,
1326 MT2063_INCR_ATTEN,
1327 MT2063_DECR_ATTEN
1328} MT2063_ATTEN_CNTL_MODE;
1329
1330//#define TUNER_MT2063_OPTIMIZATION
1331/*
1332** Constants used by the tuning algorithm
1333*/
1334#define MT2063_REF_FREQ (16000000UL) /* Reference oscillator Frequency (in Hz) */
1335#define MT2063_IF1_BW (22000000UL) /* The IF1 filter bandwidth (in Hz) */
1336#define MT2063_TUNE_STEP_SIZE (50000UL) /* Tune in steps of 50 kHz */
1337#define MT2063_SPUR_STEP_HZ (250000UL) /* Step size (in Hz) to move IF1 when avoiding spurs */
1338#define MT2063_ZIF_BW (2000000UL) /* Zero-IF spur-free bandwidth (in Hz) */
1339#define MT2063_MAX_HARMONICS_1 (15UL) /* Highest intra-tuner LO Spur Harmonic to be avoided */
1340#define MT2063_MAX_HARMONICS_2 (5UL) /* Highest inter-tuner LO Spur Harmonic to be avoided */
1341#define MT2063_MIN_LO_SEP (1000000UL) /* Minimum inter-tuner LO frequency separation */
1342#define MT2063_LO1_FRACN_AVOID (0UL) /* LO1 FracN numerator avoid region (in Hz) */
1343#define MT2063_LO2_FRACN_AVOID (199999UL) /* LO2 FracN numerator avoid region (in Hz) */
1344#define MT2063_MIN_FIN_FREQ (44000000UL) /* Minimum input frequency (in Hz) */
1345#define MT2063_MAX_FIN_FREQ (1100000000UL) /* Maximum input frequency (in Hz) */
1346#define MT2063_MIN_FOUT_FREQ (36000000UL) /* Minimum output frequency (in Hz) */
1347#define MT2063_MAX_FOUT_FREQ (57000000UL) /* Maximum output frequency (in Hz) */
1348#define MT2063_MIN_DNC_FREQ (1293000000UL) /* Minimum LO2 frequency (in Hz) */
1349#define MT2063_MAX_DNC_FREQ (1614000000UL) /* Maximum LO2 frequency (in Hz) */
1350#define MT2063_MIN_UPC_FREQ (1396000000UL) /* Minimum LO1 frequency (in Hz) */
1351#define MT2063_MAX_UPC_FREQ (2750000000UL) /* Maximum LO1 frequency (in Hz) */
1352
1353/*
1354** Define the supported Part/Rev codes for the MT2063
1355*/
1356#define MT2063_B0 (0x9B)
1357#define MT2063_B1 (0x9C)
1358#define MT2063_B2 (0x9D)
1359#define MT2063_B3 (0x9E)
1360
1361/*
1362** The number of Tuner Registers
1363*/
1364static const UData_t MT2063_Num_Registers = MT2063_REG_END_REGS;
1365
1366#define USE_GLOBAL_TUNER 0
1367
1368static UData_t nMT2063MaxTuners = MT2063_CNT;
1369static struct MT2063_Info_t MT2063_Info[MT2063_CNT];
1370static struct MT2063_Info_t *MT2063_Avail[MT2063_CNT];
1371static UData_t nMT2063OpenTuners = 0;
1372
1373/*
1374** Constants for setting receiver modes.
1375** (6 modes defined at this time, enumerated by MT2063_RCVR_MODES)
1376** (DNC1GC & DNC2GC are the values, which are used, when the specific
1377** DNC Output is selected, the other is always off)
1378**
1379** If PAL-L or L' is received, set:
1380** MT2063_SetParam(hMT2063,MT2063_TAGC,1);
1381**
1382** --------------+----------------------------------------------
1383** Mode 0 : | MT2063_CABLE_QAM
1384** Mode 1 : | MT2063_CABLE_ANALOG
1385** Mode 2 : | MT2063_OFFAIR_COFDM
1386** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS
1387** Mode 4 : | MT2063_OFFAIR_ANALOG
1388** Mode 5 : | MT2063_OFFAIR_8VSB
1389** --------------+----+----+----+----+-----+-----+--------------
1390** Mode | 0 | 1 | 2 | 3 | 4 | 5 |
1391** --------------+----+----+----+----+-----+-----+
1392**
1393**
1394*/
1395static const U8Data RFAGCEN[] = { 0, 0, 0, 0, 0, 0 };
1396static const U8Data LNARIN[] = { 0, 0, 3, 3, 3, 3 };
1397static const U8Data FIFFQEN[] = { 1, 1, 1, 1, 1, 1 };
1398static const U8Data FIFFQ[] = { 0, 0, 0, 0, 0, 0 };
1399static const U8Data DNC1GC[] = { 0, 0, 0, 0, 0, 0 };
1400static const U8Data DNC2GC[] = { 0, 0, 0, 0, 0, 0 };
1401static const U8Data ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 };
1402static const U8Data LNATGT[] = { 44, 43, 43, 43, 43, 43 };
1403static const U8Data RFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1404static const U8Data ACRFMAX[] = { 31, 31, 31, 31, 31, 31 };
1405static const U8Data PD1TGT[] = { 36, 36, 38, 38, 36, 38 };
1406static const U8Data FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1407static const U8Data ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 };
1408static const U8Data PD2TGT[] = { 40, 33, 38, 42, 30, 38 };
1409
1410/*
1411** Local Function Prototypes - not available for external access.
1412*/
1413
1414/* Forward declaration(s): */
1415static UData_t MT2063_CalcLO1Mult(UData_t * Div, UData_t * FracN, UData_t f_LO,
1416 UData_t f_LO_Step, UData_t f_Ref);
1417static UData_t MT2063_CalcLO2Mult(UData_t * Div, UData_t * FracN, UData_t f_LO,
1418 UData_t f_LO_Step, UData_t f_Ref);
1419static UData_t MT2063_fLO_FractionalTerm(UData_t f_ref, UData_t num,
1420 UData_t denom);
1421
1422/******************************************************************************
1423**
1424** Name: MT2063_Open
1425**
1426** Description: Initialize the tuner's register values.
1427**
1428** Parameters: MT2063_Addr - Serial bus address of the tuner.
1429** hMT2063 - Tuner handle passed back.
1430** hUserData - User-defined data, if needed for the
1431** MT_ReadSub() & MT_WriteSub functions.
1432**
1433** Returns: status:
1434** MT_OK - No errors
1435** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch
1436** MT_TUNER_INIT_ERR - Tuner initialization failed
1437** MT_COMM_ERR - Serial bus communications error
1438** MT_ARG_NULL - Null pointer argument passed
1439** MT_TUNER_CNT_ERR - Too many tuners open
1440**
1441** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus
1442** MT_WriteSub - Write byte(s) of data to the two-wire bus
1443**
1444** Revision History:
1445**
1446** SCR Date Author Description
1447** -------------------------------------------------------------------------
1448** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1449**
1450******************************************************************************/
1451UData_t MT2063_Open(UData_t MT2063_Addr, Handle_t * hMT2063, Handle_t hUserData)
1452{
1453 UData_t status = MT2063_OK; /* Status to be returned. */
1454 SData_t i;
1455 struct MT2063_Info_t *pInfo = NULL;
1456 struct dvb_frontend *fe = (struct dvb_frontend *)hUserData;
1457 struct mt2063_state *state = fe->tuner_priv;
1458
1459 /* Check the argument before using */
1460 if (hMT2063 == NULL) {
1461 return MT2063_ARG_NULL;
1462 }
1463
1464 /* Default tuner handle to NULL. If successful, it will be reassigned */
1465
1466#if USE_GLOBAL_TUNER
1467 *hMT2063 = NULL;
1468
1469 /*
1470 ** If this is our first tuner, initialize the address fields and
1471 ** the list of available control blocks.
1472 */
1473 if (nMT2063OpenTuners == 0) {
1474 for (i = MT2063_CNT - 1; i >= 0; i--) {
1475 MT2063_Info[i].handle = NULL;
1476 MT2063_Info[i].address = MAX_UDATA;
1477 MT2063_Info[i].rcvr_mode = MT2063_CABLE_QAM;
1478 MT2063_Info[i].hUserData = NULL;
1479 MT2063_Avail[i] = &MT2063_Info[i];
1480 }
1481 }
1482
1483 /*
1484 ** Look for an existing MT2063_State_t entry with this address.
1485 */
1486 for (i = MT2063_CNT - 1; i >= 0; i--) {
1487 /*
1488 ** If an open'ed handle provided, we'll re-initialize that structure.
1489 **
1490 ** We recognize an open tuner because the address and hUserData are
1491 ** the same as one that has already been opened
1492 */
1493 if ((MT2063_Info[i].address == MT2063_Addr) &&
1494 (MT2063_Info[i].hUserData == hUserData)) {
1495 pInfo = &MT2063_Info[i];
1496 break;
1497 }
1498 }
1499
1500 /* If not found, choose an empty spot. */
1501 if (pInfo == NULL) {
1502 /* Check to see that we're not over-allocating */
1503 if (nMT2063OpenTuners == MT2063_CNT) {
1504 return MT2063_TUNER_CNT_ERR;
1505 }
1506 /* Use the next available block from the list */
1507 pInfo = MT2063_Avail[nMT2063OpenTuners];
1508 nMT2063OpenTuners++;
1509 }
1510#else
1511 if (state->MT2063_init == FALSE) {
1512 pInfo = kzalloc(sizeof(struct MT2063_Info_t), GFP_KERNEL);
1513 if (pInfo == NULL) {
1514 return MT2063_TUNER_OPEN_ERR;
1515 }
1516 pInfo->handle = NULL;
1517 pInfo->address = MAX_UDATA;
1518 pInfo->rcvr_mode = MT2063_CABLE_QAM;
1519 pInfo->hUserData = NULL;
1520 } else {
1521 pInfo = *hMT2063;
1522 }
1523#endif
1524
1525 if (MT2063_NO_ERROR(status)) {
1526 status |= MT2063_RegisterTuner(&pInfo->AS_Data);
1527 }
1528
1529 if (MT2063_NO_ERROR(status)) {
1530 pInfo->handle = (Handle_t) pInfo;
1531
1532 pInfo->hUserData = hUserData;
1533 pInfo->address = MT2063_Addr;
1534 pInfo->rcvr_mode = MT2063_CABLE_QAM;
1535 status |= MT2063_ReInit((Handle_t) pInfo);
1536 }
1537
1538 if (MT2063_IS_ERROR(status))
1539 /* MT2063_Close handles the un-registration of the tuner */
1540 MT2063_Close((Handle_t) pInfo);
1541 else {
1542 state->MT2063_init = TRUE;
1543 *hMT2063 = pInfo->handle;
1544
1545 }
1546
1547 return (status);
1548}
1549
1550static UData_t MT2063_IsValidHandle(struct MT2063_Info_t *handle)
1551{
1552 return ((handle != NULL) && (handle->handle == handle)) ? 1 : 0;
1553}
1554
1555/******************************************************************************
1556**
1557** Name: MT2063_Close
1558**
1559** Description: Release the handle to the tuner.
1560**
1561** Parameters: hMT2063 - Handle to the MT2063 tuner
1562**
1563** Returns: status:
1564** MT_OK - No errors
1565** MT_INV_HANDLE - Invalid tuner handle
1566**
1567** Dependencies: mt_errordef.h - definition of error codes
1568**
1569** Revision History:
1570**
1571** SCR Date Author Description
1572** -------------------------------------------------------------------------
1573** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1574**
1575******************************************************************************/
1576UData_t MT2063_Close(Handle_t hMT2063)
1577{
1578 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)hMT2063;
1579
1580 if (!MT2063_IsValidHandle(pInfo))
1581 return MT2063_INV_HANDLE;
1582
1583 /* Unregister tuner with SpurAvoidance routines (if needed) */
1584 MT2063_UnRegisterTuner(&pInfo->AS_Data);
1585 /* Now remove the tuner from our own list of tuners */
1586 pInfo->handle = NULL;
1587 pInfo->address = MAX_UDATA;
1588 pInfo->hUserData = NULL;
1589#if USE_GLOBAL_TUNER
1590 nMT2063OpenTuners--;
1591 MT2063_Avail[nMT2063OpenTuners] = pInfo; /* Return control block to available list */
1592#else
1593 //kfree(pInfo);
1594 //pInfo = NULL;
1595#endif
1596 return MT2063_OK;
1597}
1598
1599/******************************************************************************
1600**
1601** Name: MT2063_GetGPIO
1602**
1603** Description: Get the current MT2063 GPIO value.
1604**
1605** Parameters: h - Open handle to the tuner (from MT2063_Open).
1606** gpio_id - Selects GPIO0, GPIO1 or GPIO2
1607** attr - Selects input readback, I/O direction or
1608** output value
1609** *value - current setting of GPIO pin
1610**
1611** Usage: status = MT2063_GetGPIO(hMT2063, MT2063_GPIO_OUT, &value);
1612**
1613** Returns: status:
1614** MT_OK - No errors
1615** MT_COMM_ERR - Serial bus communications error
1616** MT_INV_HANDLE - Invalid tuner handle
1617** MT_ARG_NULL - Null pointer argument passed
1618**
1619** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus
1620**
1621** Revision History:
1622**
1623** SCR Date Author Description
1624** -------------------------------------------------------------------------
1625** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1626**
1627******************************************************************************/
1628UData_t MT2063_GetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id,
1629 enum MT2063_GPIO_Attr attr, UData_t * value)
1630{
1631 UData_t status = MT2063_OK; /* Status to be returned */
1632 U8Data regno;
1633 SData_t shift;
1634 static U8Data GPIOreg[3] =
1635 { MT2063_REG_RF_STATUS, MT2063_REG_FIF_OV, MT2063_REG_RF_OV };
1636 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1637
1638 if (MT2063_IsValidHandle(pInfo) == 0)
1639 return MT2063_INV_HANDLE;
1640
1641 if (value == NULL)
1642 return MT2063_ARG_NULL;
1643
1644 regno = GPIOreg[attr];
1645
1646 /* We'll read the register just in case the write didn't work last time */
1647 status =
1648 MT2063_ReadSub(pInfo->hUserData, pInfo->address, regno,
1649 &pInfo->reg[regno], 1);
1650
1651 shift = (gpio_id - MT2063_GPIO0 + 5);
1652 *value = (pInfo->reg[regno] >> shift) & 1;
1653
1654 return (status);
1655}
1656
1657/****************************************************************************
1658**
1659** Name: MT2063_GetLocked
1660**
1661** Description: Checks to see if LO1 and LO2 are locked.
1662**
1663** Parameters: h - Open handle to the tuner (from MT2063_Open).
1664**
1665** Returns: status:
1666** MT_OK - No errors
1667** MT_UPC_UNLOCK - Upconverter PLL unlocked
1668** MT_DNC_UNLOCK - Downconverter PLL unlocked
1669** MT_COMM_ERR - Serial bus communications error
1670** MT_INV_HANDLE - Invalid tuner handle
1671**
1672** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus
1673** MT_Sleep - Delay execution for x milliseconds
1674**
1675** Revision History:
1676**
1677** SCR Date Author Description
1678** -------------------------------------------------------------------------
1679** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1680**
1681****************************************************************************/
1682UData_t MT2063_GetLocked(Handle_t h)
1683{
1684 const UData_t nMaxWait = 100; /* wait a maximum of 100 msec */
1685 const UData_t nPollRate = 2; /* poll status bits every 2 ms */
1686 const UData_t nMaxLoops = nMaxWait / nPollRate;
1687 const U8Data LO1LK = 0x80;
1688 U8Data LO2LK = 0x08;
1689 UData_t status = MT2063_OK; /* Status to be returned */
1690 UData_t nDelays = 0;
1691 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1692
1693 if (MT2063_IsValidHandle(pInfo) == 0)
1694 return MT2063_INV_HANDLE;
1695
1696 /* LO2 Lock bit was in a different place for B0 version */
1697 if (pInfo->tuner_id == MT2063_B0)
1698 LO2LK = 0x40;
1699
1700 do {
1701 status |=
1702 MT2063_ReadSub(pInfo->hUserData, pInfo->address,
1703 MT2063_REG_LO_STATUS,
1704 &pInfo->reg[MT2063_REG_LO_STATUS], 1);
1705
1706 if (MT2063_IS_ERROR(status))
1707 return (status);
1708
1709 if ((pInfo->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
1710 (LO1LK | LO2LK)) {
1711 return (status);
1712 }
1713 MT2063_Sleep(pInfo->hUserData, nPollRate); /* Wait between retries */
1714 }
1715 while (++nDelays < nMaxLoops);
1716
1717 if ((pInfo->reg[MT2063_REG_LO_STATUS] & LO1LK) == 0x00)
1718 status |= MT2063_UPC_UNLOCK;
1719 if ((pInfo->reg[MT2063_REG_LO_STATUS] & LO2LK) == 0x00)
1720 status |= MT2063_DNC_UNLOCK;
1721
1722 return (status);
1723}
1724
1725/****************************************************************************
1726**
1727** Name: MT2063_GetParam
1728**
1729** Description: Gets a tuning algorithm parameter.
1730**
1731** This function provides access to the internals of the
1732** tuning algorithm - mostly for testing purposes.
1733**
1734** Parameters: h - Tuner handle (returned by MT2063_Open)
1735** param - Tuning algorithm parameter
1736** (see enum MT2063_Param)
1737** pValue - ptr to returned value
1738**
1739** param Description
1740** ---------------------- --------------------------------
1741** MT2063_IC_ADDR Serial Bus address of this tuner
1742** MT2063_MAX_OPEN Max # of MT2063's allowed open
1743** MT2063_NUM_OPEN # of MT2063's open
1744** MT2063_SRO_FREQ crystal frequency
1745** MT2063_STEPSIZE minimum tuning step size
1746** MT2063_INPUT_FREQ input center frequency
1747** MT2063_LO1_FREQ LO1 Frequency
1748** MT2063_LO1_STEPSIZE LO1 minimum step size
1749** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region
1750** MT2063_IF1_ACTUAL Current 1st IF in use
1751** MT2063_IF1_REQUEST Requested 1st IF
1752** MT2063_IF1_CENTER Center of 1st IF SAW filter
1753** MT2063_IF1_BW Bandwidth of 1st IF SAW filter
1754** MT2063_ZIF_BW zero-IF bandwidth
1755** MT2063_LO2_FREQ LO2 Frequency
1756** MT2063_LO2_STEPSIZE LO2 minimum step size
1757** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region
1758** MT2063_OUTPUT_FREQ output center frequency
1759** MT2063_OUTPUT_BW output bandwidth
1760** MT2063_LO_SEPARATION min inter-tuner LO separation
1761** MT2063_AS_ALG ID of avoid-spurs algorithm in use
1762** MT2063_MAX_HARM1 max # of intra-tuner harmonics
1763** MT2063_MAX_HARM2 max # of inter-tuner harmonics
1764** MT2063_EXCL_ZONES # of 1st IF exclusion zones
1765** MT2063_NUM_SPURS # of spurs found/avoided
1766** MT2063_SPUR_AVOIDED >0 spurs avoided
1767** MT2063_SPUR_PRESENT >0 spurs in output (mathematically)
1768** MT2063_RCVR_MODE Predefined modes.
1769** MT2063_ACLNA LNA attenuator gain code
1770** MT2063_ACRF RF attenuator gain code
1771** MT2063_ACFIF FIF attenuator gain code
1772** MT2063_ACLNA_MAX LNA attenuator limit
1773** MT2063_ACRF_MAX RF attenuator limit
1774** MT2063_ACFIF_MAX FIF attenuator limit
1775** MT2063_PD1 Actual value of PD1
1776** MT2063_PD2 Actual value of PD2
1777** MT2063_DNC_OUTPUT_ENABLE DNC output selection
1778** MT2063_VGAGC VGA gain code
1779** MT2063_VGAOI VGA output current
1780** MT2063_TAGC TAGC setting
1781** MT2063_AMPGC AMP gain code
1782** MT2063_AVOID_DECT Avoid DECT Frequencies
1783** MT2063_CTFILT_SW Cleartune filter selection
1784**
1785** Usage: status |= MT2063_GetParam(hMT2063,
1786** MT2063_IF1_ACTUAL,
1787** &f_IF1_Actual);
1788**
1789** Returns: status:
1790** MT_OK - No errors
1791** MT_INV_HANDLE - Invalid tuner handle
1792** MT_ARG_NULL - Null pointer argument passed
1793** MT_ARG_RANGE - Invalid parameter requested
1794**
1795** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
1796**
1797** See Also: MT2063_SetParam, MT2063_Open
1798**
1799** Revision History:
1800**
1801** SCR Date Author Description
1802** -------------------------------------------------------------------------
1803** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1804** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ
1805** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC
1806** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW
1807** in GetParam.
1808** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT
1809** Split SetParam up to ACLNA / ACLNA_MAX
1810** removed ACLNA_INRC/DECR (+RF & FIF)
1811** removed GCUAUTO / BYPATNDN/UP
1812** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs.
1813** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid.
1814** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW
1815**
1816****************************************************************************/
1817UData_t MT2063_GetParam(Handle_t h, enum MT2063_Param param, UData_t * pValue)
1818{
1819 UData_t status = MT2063_OK; /* Status to be returned */
1820 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1821 UData_t Div;
1822 UData_t Num;
1823
1824 if (pValue == NULL)
1825 status |= MT2063_ARG_NULL;
1826
1827 /* Verify that the handle passed points to a valid tuner */
1828 if (MT2063_IsValidHandle(pInfo) == 0)
1829 status |= MT2063_INV_HANDLE;
1830
1831 if (MT2063_NO_ERROR(status)) {
1832 switch (param) {
1833 /* Serial Bus address of this tuner */
1834 case MT2063_IC_ADDR:
1835 *pValue = pInfo->address;
1836 break;
1837
1838 /* Max # of MT2063's allowed to be open */
1839 case MT2063_MAX_OPEN:
1840 *pValue = nMT2063MaxTuners;
1841 break;
1842
1843 /* # of MT2063's open */
1844 case MT2063_NUM_OPEN:
1845 *pValue = nMT2063OpenTuners;
1846 break;
1847
1848 /* crystal frequency */
1849 case MT2063_SRO_FREQ:
1850 *pValue = pInfo->AS_Data.f_ref;
1851 break;
1852
1853 /* minimum tuning step size */
1854 case MT2063_STEPSIZE:
1855 *pValue = pInfo->AS_Data.f_LO2_Step;
1856 break;
1857
1858 /* input center frequency */
1859 case MT2063_INPUT_FREQ:
1860 *pValue = pInfo->AS_Data.f_in;
1861 break;
1862
1863 /* LO1 Frequency */
1864 case MT2063_LO1_FREQ:
1865 {
1866 /* read the actual tuner register values for LO1C_1 and LO1C_2 */
1867 status |=
1868 MT2063_ReadSub(pInfo->hUserData,
1869 pInfo->address,
1870 MT2063_REG_LO1C_1,
1871 &pInfo->
1872 reg[MT2063_REG_LO1C_1], 2);
1873 Div = pInfo->reg[MT2063_REG_LO1C_1];
1874 Num = pInfo->reg[MT2063_REG_LO1C_2] & 0x3F;
1875 pInfo->AS_Data.f_LO1 =
1876 (pInfo->AS_Data.f_ref * Div) +
1877 MT2063_fLO_FractionalTerm(pInfo->AS_Data.
1878 f_ref, Num, 64);
1879 }
1880 *pValue = pInfo->AS_Data.f_LO1;
1881 break;
1882
1883 /* LO1 minimum step size */
1884 case MT2063_LO1_STEPSIZE:
1885 *pValue = pInfo->AS_Data.f_LO1_Step;
1886 break;
1887
1888 /* LO1 FracN keep-out region */
1889 case MT2063_LO1_FRACN_AVOID_PARAM:
1890 *pValue = pInfo->AS_Data.f_LO1_FracN_Avoid;
1891 break;
1892
1893 /* Current 1st IF in use */
1894 case MT2063_IF1_ACTUAL:
1895 *pValue = pInfo->f_IF1_actual;
1896 break;
1897
1898 /* Requested 1st IF */
1899 case MT2063_IF1_REQUEST:
1900 *pValue = pInfo->AS_Data.f_if1_Request;
1901 break;
1902
1903 /* Center of 1st IF SAW filter */
1904 case MT2063_IF1_CENTER:
1905 *pValue = pInfo->AS_Data.f_if1_Center;
1906 break;
1907
1908 /* Bandwidth of 1st IF SAW filter */
1909 case MT2063_IF1_BW:
1910 *pValue = pInfo->AS_Data.f_if1_bw;
1911 break;
1912
1913 /* zero-IF bandwidth */
1914 case MT2063_ZIF_BW:
1915 *pValue = pInfo->AS_Data.f_zif_bw;
1916 break;
1917
1918 /* LO2 Frequency */
1919 case MT2063_LO2_FREQ:
1920 {
1921 /* Read the actual tuner register values for LO2C_1, LO2C_2 and LO2C_3 */
1922 status |=
1923 MT2063_ReadSub(pInfo->hUserData,
1924 pInfo->address,
1925 MT2063_REG_LO2C_1,
1926 &pInfo->
1927 reg[MT2063_REG_LO2C_1], 3);
1928 Div =
1929 (pInfo->reg[MT2063_REG_LO2C_1] & 0xFE) >> 1;
1930 Num =
1931 ((pInfo->
1932 reg[MT2063_REG_LO2C_1] & 0x01) << 12) |
1933 (pInfo->
1934 reg[MT2063_REG_LO2C_2] << 4) | (pInfo->
1935 reg
1936 [MT2063_REG_LO2C_3]
1937 & 0x00F);
1938 pInfo->AS_Data.f_LO2 =
1939 (pInfo->AS_Data.f_ref * Div) +
1940 MT2063_fLO_FractionalTerm(pInfo->AS_Data.
1941 f_ref, Num, 8191);
1942 }
1943 *pValue = pInfo->AS_Data.f_LO2;
1944 break;
1945
1946 /* LO2 minimum step size */
1947 case MT2063_LO2_STEPSIZE:
1948 *pValue = pInfo->AS_Data.f_LO2_Step;
1949 break;
1950
1951 /* LO2 FracN keep-out region */
1952 case MT2063_LO2_FRACN_AVOID:
1953 *pValue = pInfo->AS_Data.f_LO2_FracN_Avoid;
1954 break;
1955
1956 /* output center frequency */
1957 case MT2063_OUTPUT_FREQ:
1958 *pValue = pInfo->AS_Data.f_out;
1959 break;
1960
1961 /* output bandwidth */
1962 case MT2063_OUTPUT_BW:
1963 *pValue = pInfo->AS_Data.f_out_bw - 750000;
1964 break;
1965
1966 /* min inter-tuner LO separation */
1967 case MT2063_LO_SEPARATION:
1968 *pValue = pInfo->AS_Data.f_min_LO_Separation;
1969 break;
1970
1971 /* ID of avoid-spurs algorithm in use */
1972 case MT2063_AS_ALG:
1973 *pValue = pInfo->AS_Data.nAS_Algorithm;
1974 break;
1975
1976 /* max # of intra-tuner harmonics */
1977 case MT2063_MAX_HARM1:
1978 *pValue = pInfo->AS_Data.maxH1;
1979 break;
1980
1981 /* max # of inter-tuner harmonics */
1982 case MT2063_MAX_HARM2:
1983 *pValue = pInfo->AS_Data.maxH2;
1984 break;
1985
1986 /* # of 1st IF exclusion zones */
1987 case MT2063_EXCL_ZONES:
1988 *pValue = pInfo->AS_Data.nZones;
1989 break;
1990
1991 /* # of spurs found/avoided */
1992 case MT2063_NUM_SPURS:
1993 *pValue = pInfo->AS_Data.nSpursFound;
1994 break;
1995
1996 /* >0 spurs avoided */
1997 case MT2063_SPUR_AVOIDED:
1998 *pValue = pInfo->AS_Data.bSpurAvoided;
1999 break;
2000
2001 /* >0 spurs in output (mathematically) */
2002 case MT2063_SPUR_PRESENT:
2003 *pValue = pInfo->AS_Data.bSpurPresent;
2004 break;
2005
2006 /* Predefined receiver setup combination */
2007 case MT2063_RCVR_MODE:
2008 *pValue = pInfo->rcvr_mode;
2009 break;
2010
2011 case MT2063_PD1:
2012 case MT2063_PD2:
2013 {
2014 U8Data mask = (param == MT2063_PD1 ? 0x01 : 0x03); /* PD1 vs PD2 */
2015 U8Data orig = (pInfo->reg[MT2063_REG_BYP_CTRL]);
2016 U8Data reg = (orig & 0xF1) | mask; /* Only set 3 bits (not 5) */
2017 int i;
2018
2019 *pValue = 0;
2020
2021 /* Initiate ADC output to reg 0x0A */
2022 if (reg != orig)
2023 status |=
2024 MT2063_WriteSub(pInfo->hUserData,
2025 pInfo->address,
2026 MT2063_REG_BYP_CTRL,
2027 &reg, 1);
2028
2029 if (MT2063_IS_ERROR(status))
2030 return (status);
2031
2032 for (i = 0; i < 8; i++) {
2033 status |=
2034 MT2063_ReadSub(pInfo->hUserData,
2035 pInfo->address,
2036 MT2063_REG_ADC_OUT,
2037 &pInfo->
2038 reg
2039 [MT2063_REG_ADC_OUT],
2040 1);
2041
2042 if (MT2063_NO_ERROR(status))
2043 *pValue +=
2044 pInfo->
2045 reg[MT2063_REG_ADC_OUT];
2046 else {
2047 if (i)
2048 *pValue /= i;
2049 return (status);
2050 }
2051 }
2052 *pValue /= 8; /* divide by number of reads */
2053 *pValue >>= 2; /* only want 6 MSB's out of 8 */
2054
2055 /* Restore value of Register BYP_CTRL */
2056 if (reg != orig)
2057 status |=
2058 MT2063_WriteSub(pInfo->hUserData,
2059 pInfo->address,
2060 MT2063_REG_BYP_CTRL,
2061 &orig, 1);
2062 }
2063 break;
2064
2065 /* Get LNA attenuator code */
2066 case MT2063_ACLNA:
2067 {
2068 U8Data val;
2069 status |=
2070 MT2063_GetReg(pInfo, MT2063_REG_XO_STATUS,
2071 &val);
2072 *pValue = val & 0x1f;
2073 }
2074 break;
2075
2076 /* Get RF attenuator code */
2077 case MT2063_ACRF:
2078 {
2079 U8Data val;
2080 status |=
2081 MT2063_GetReg(pInfo, MT2063_REG_RF_STATUS,
2082 &val);
2083 *pValue = val & 0x1f;
2084 }
2085 break;
2086
2087 /* Get FIF attenuator code */
2088 case MT2063_ACFIF:
2089 {
2090 U8Data val;
2091 status |=
2092 MT2063_GetReg(pInfo, MT2063_REG_FIF_STATUS,
2093 &val);
2094 *pValue = val & 0x1f;
2095 }
2096 break;
2097
2098 /* Get LNA attenuator limit */
2099 case MT2063_ACLNA_MAX:
2100 {
2101 U8Data val;
2102 status |=
2103 MT2063_GetReg(pInfo, MT2063_REG_LNA_OV,
2104 &val);
2105 *pValue = val & 0x1f;
2106 }
2107 break;
2108
2109 /* Get RF attenuator limit */
2110 case MT2063_ACRF_MAX:
2111 {
2112 U8Data val;
2113 status |=
2114 MT2063_GetReg(pInfo, MT2063_REG_RF_OV,
2115 &val);
2116 *pValue = val & 0x1f;
2117 }
2118 break;
2119
2120 /* Get FIF attenuator limit */
2121 case MT2063_ACFIF_MAX:
2122 {
2123 U8Data val;
2124 status |=
2125 MT2063_GetReg(pInfo, MT2063_REG_FIF_OV,
2126 &val);
2127 *pValue = val & 0x1f;
2128 }
2129 break;
2130
2131 /* Get current used DNC output */
2132 case MT2063_DNC_OUTPUT_ENABLE:
2133 {
2134 if ((pInfo->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) { /* if DNC1 is off */
2135 if ((pInfo->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
2136 *pValue =
2137 (UData_t) MT2063_DNC_NONE;
2138 else
2139 *pValue =
2140 (UData_t) MT2063_DNC_2;
2141 } else { /* DNC1 is on */
2142
2143 if ((pInfo->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
2144 *pValue =
2145 (UData_t) MT2063_DNC_1;
2146 else
2147 *pValue =
2148 (UData_t) MT2063_DNC_BOTH;
2149 }
2150 }
2151 break;
2152
2153 /* Get VGA Gain Code */
2154 case MT2063_VGAGC:
2155 *pValue =
2156 ((pInfo->reg[MT2063_REG_VGA_GAIN] & 0x0C) >> 2);
2157 break;
2158
2159 /* Get VGA bias current */
2160 case MT2063_VGAOI:
2161 *pValue = (pInfo->reg[MT2063_REG_RSVD_31] & 0x07);
2162 break;
2163
2164 /* Get TAGC setting */
2165 case MT2063_TAGC:
2166 *pValue = (pInfo->reg[MT2063_REG_RSVD_1E] & 0x03);
2167 break;
2168
2169 /* Get AMP Gain Code */
2170 case MT2063_AMPGC:
2171 *pValue = (pInfo->reg[MT2063_REG_TEMP_SEL] & 0x03);
2172 break;
2173
2174 /* Avoid DECT Frequencies */
2175 case MT2063_AVOID_DECT:
2176 *pValue = pInfo->AS_Data.avoidDECT;
2177 break;
2178
2179 /* Cleartune filter selection: 0 - by IC (default), 1 - by software */
2180 case MT2063_CTFILT_SW:
2181 *pValue = pInfo->ctfilt_sw;
2182 break;
2183
2184 case MT2063_EOP:
2185 default:
2186 status |= MT2063_ARG_RANGE;
2187 }
2188 }
2189 return (status);
2190}
2191
2192/****************************************************************************
2193**
2194** Name: MT2063_GetReg
2195**
2196** Description: Gets an MT2063 register.
2197**
2198** Parameters: h - Tuner handle (returned by MT2063_Open)
2199** reg - MT2063 register/subaddress location
2200** *val - MT2063 register/subaddress value
2201**
2202** Returns: status:
2203** MT_OK - No errors
2204** MT_COMM_ERR - Serial bus communications error
2205** MT_INV_HANDLE - Invalid tuner handle
2206** MT_ARG_NULL - Null pointer argument passed
2207** MT_ARG_RANGE - Argument out of range
2208**
2209** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
2210**
2211** Use this function if you need to read a register from
2212** the MT2063.
2213**
2214** Revision History:
2215**
2216** SCR Date Author Description
2217** -------------------------------------------------------------------------
2218** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2219**
2220****************************************************************************/
2221UData_t MT2063_GetReg(Handle_t h, U8Data reg, U8Data * val)
2222{
2223 UData_t status = MT2063_OK; /* Status to be returned */
2224 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
2225
2226 /* Verify that the handle passed points to a valid tuner */
2227 if (MT2063_IsValidHandle(pInfo) == 0)
2228 status |= MT2063_INV_HANDLE;
2229
2230 if (val == NULL)
2231 status |= MT2063_ARG_NULL;
2232
2233 if (reg >= MT2063_REG_END_REGS)
2234 status |= MT2063_ARG_RANGE;
2235
2236 if (MT2063_NO_ERROR(status)) {
2237 status |=
2238 MT2063_ReadSub(pInfo->hUserData, pInfo->address, reg,
2239 &pInfo->reg[reg], 1);
2240 if (MT2063_NO_ERROR(status))
2241 *val = pInfo->reg[reg];
2242 }
2243
2244 return (status);
2245}
2246
2247/******************************************************************************
2248**
2249** Name: MT2063_GetTemp
2250**
2251** Description: Get the MT2063 Temperature register.
2252**
2253** Parameters: h - Open handle to the tuner (from MT2063_Open).
2254** *value - value read from the register
2255**
2256** Binary
2257** Value Returned Value Approx Temp
2258** ---------------------------------------------
2259** MT2063_T_0C 0000 0C
2260** MT2063_T_10C 0001 10C
2261** MT2063_T_20C 0010 20C
2262** MT2063_T_30C 0011 30C
2263** MT2063_T_40C 0100 40C
2264** MT2063_T_50C 0101 50C
2265** MT2063_T_60C 0110 60C
2266** MT2063_T_70C 0111 70C
2267** MT2063_T_80C 1000 80C
2268** MT2063_T_90C 1001 90C
2269** MT2063_T_100C 1010 100C
2270** MT2063_T_110C 1011 110C
2271** MT2063_T_120C 1100 120C
2272** MT2063_T_130C 1101 130C
2273** MT2063_T_140C 1110 140C
2274** MT2063_T_150C 1111 150C
2275**
2276** Returns: status:
2277** MT_OK - No errors
2278** MT_COMM_ERR - Serial bus communications error
2279** MT_INV_HANDLE - Invalid tuner handle
2280** MT_ARG_NULL - Null pointer argument passed
2281** MT_ARG_RANGE - Argument out of range
2282**
2283** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus
2284** MT_WriteSub - Write byte(s) of data to the two-wire bus
2285**
2286** Revision History:
2287**
2288** SCR Date Author Description
2289** -------------------------------------------------------------------------
2290** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2291**
2292******************************************************************************/
2293UData_t MT2063_GetTemp(Handle_t h, enum MT2063_Temperature * value)
2294{
2295 UData_t status = MT2063_OK; /* Status to be returned */
2296 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
2297
2298 if (MT2063_IsValidHandle(pInfo) == 0)
2299 return MT2063_INV_HANDLE;
2300
2301 if (value == NULL)
2302 return MT2063_ARG_NULL;
2303
2304 if ((MT2063_NO_ERROR(status))
2305 && ((pInfo->reg[MT2063_REG_TEMP_SEL] & 0xE0) != 0x00)) {
2306 pInfo->reg[MT2063_REG_TEMP_SEL] &= (0x1F);
2307 status |= MT2063_WriteSub(pInfo->hUserData,
2308 pInfo->address,
2309 MT2063_REG_TEMP_SEL,
2310 &pInfo->reg[MT2063_REG_TEMP_SEL], 1);
2311 }
2312
2313 if (MT2063_NO_ERROR(status))
2314 status |= MT2063_ReadSub(pInfo->hUserData,
2315 pInfo->address,
2316 MT2063_REG_TEMP_STATUS,
2317 &pInfo->reg[MT2063_REG_TEMP_STATUS],
2318 1);
2319
2320 if (MT2063_NO_ERROR(status))
2321 *value =
2322 (enum MT2063_Temperature)(pInfo->
2323 reg[MT2063_REG_TEMP_STATUS] >> 4);
2324
2325 return (status);
2326}
2327
2328/****************************************************************************
2329**
2330** Name: MT2063_GetUserData
2331**
2332** Description: Gets the user-defined data item.
2333**
2334** Parameters: h - Tuner handle (returned by MT2063_Open)
2335**
2336** Returns: status:
2337** MT_OK - No errors
2338** MT_INV_HANDLE - Invalid tuner handle
2339** MT_ARG_NULL - Null pointer argument passed
2340**
2341** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
2342**
2343** The hUserData parameter is a user-specific argument
2344** that is stored internally with the other tuner-
2345** specific information.
2346**
2347** For example, if additional arguments are needed
2348** for the user to identify the device communicating
2349** with the tuner, this argument can be used to supply
2350** the necessary information.
2351**
2352** The hUserData parameter is initialized in the tuner's
2353** Open function to NULL.
2354**
2355** See Also: MT2063_Open
2356**
2357** Revision History:
2358**
2359** SCR Date Author Description
2360** -------------------------------------------------------------------------
2361** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2362**
2363****************************************************************************/
2364UData_t MT2063_GetUserData(Handle_t h, Handle_t * hUserData)
2365{
2366 UData_t status = MT2063_OK; /* Status to be returned */
2367 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
2368
2369 /* Verify that the handle passed points to a valid tuner */
2370 if (MT2063_IsValidHandle(pInfo) == 0)
2371 status = MT2063_INV_HANDLE;
2372
2373 if (hUserData == NULL)
2374 status |= MT2063_ARG_NULL;
2375
2376 if (MT2063_NO_ERROR(status))
2377 *hUserData = pInfo->hUserData;
2378
2379 return (status);
2380}
2381
2382/******************************************************************************
2383**
2384** Name: MT2063_SetReceiverMode
2385**
2386** Description: Set the MT2063 receiver mode
2387**
2388** --------------+----------------------------------------------
2389** Mode 0 : | MT2063_CABLE_QAM
2390** Mode 1 : | MT2063_CABLE_ANALOG
2391** Mode 2 : | MT2063_OFFAIR_COFDM
2392** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS
2393** Mode 4 : | MT2063_OFFAIR_ANALOG
2394** Mode 5 : | MT2063_OFFAIR_8VSB
2395** --------------+----+----+----+----+-----+--------------------
2396** (DNC1GC & DNC2GC are the values, which are used, when the specific
2397** DNC Output is selected, the other is always off)
2398**
2399** |<---------- Mode -------------->|
2400** Reg Field | 0 | 1 | 2 | 3 | 4 | 5 |
2401** ------------+-----+-----+-----+-----+-----+-----+
2402** RFAGCen | OFF | OFF | OFF | OFF | OFF | OFF
2403** LNARin | 0 | 0 | 3 | 3 | 3 | 3
2404** FIFFQen | 1 | 1 | 1 | 1 | 1 | 1
2405** FIFFq | 0 | 0 | 0 | 0 | 0 | 0
2406** DNC1gc | 0 | 0 | 0 | 0 | 0 | 0
2407** DNC2gc | 0 | 0 | 0 | 0 | 0 | 0
2408** GCU Auto | 1 | 1 | 1 | 1 | 1 | 1
2409** LNA max Atn | 31 | 31 | 31 | 31 | 31 | 31
2410** LNA Target | 44 | 43 | 43 | 43 | 43 | 43
2411** ign RF Ovl | 0 | 0 | 0 | 0 | 0 | 0
2412** RF max Atn | 31 | 31 | 31 | 31 | 31 | 31
2413** PD1 Target | 36 | 36 | 38 | 38 | 36 | 38
2414** ign FIF Ovl | 0 | 0 | 0 | 0 | 0 | 0
2415** FIF max Atn | 5 | 5 | 5 | 5 | 5 | 5
2416** PD2 Target | 40 | 33 | 42 | 42 | 33 | 42
2417**
2418**
2419** Parameters: pInfo - ptr to MT2063_Info_t structure
2420** Mode - desired reciever mode
2421**
2422** Usage: status = MT2063_SetReceiverMode(hMT2063, Mode);
2423**
2424** Returns: status:
2425** MT_OK - No errors
2426** MT_COMM_ERR - Serial bus communications error
2427**
2428** Dependencies: MT2063_SetReg - Write a byte of data to a HW register.
2429** Assumes that the tuner cache is valid.
2430**
2431** Revision History:
2432**
2433** SCR Date Author Description
2434** -------------------------------------------------------------------------
2435** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2436** N/A 01-10-2007 PINZ Added additional GCU Settings, FIFF Calib will be triggered
2437** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive
2438** modulation
2439** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE)
2440** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have
2441** the same settings as with MT Launcher
2442** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI
2443** Add SetParam DNC_OUTPUT_ENABLE
2444** Removed VGAGC from receiver mode,
2445** default now 1
2446** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode
2447** Add SetParam AMPGC, removed from rcvr-mode
2448** Corrected names of GCU values
2449** reorganized receiver modes, removed,
2450** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE)
2451** Actualized Receiver-Mode values
2452** N/A 11-12-2007 PINZ Ver 1.09: Actualized Receiver-Mode values
2453** N/A 11-27-2007 PINZ Improved buffered writing
2454** 01-03-2008 PINZ Ver 1.10: Added a trigger of BYPATNUP for
2455** correct wakeup of the LNA after shutdown
2456** Set AFCsd = 1 as default
2457** Changed CAP1sel default
2458** 01-14-2008 PINZ Ver 1.11: Updated gain settings
2459** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT
2460** Split SetParam up to ACLNA / ACLNA_MAX
2461** removed ACLNA_INRC/DECR (+RF & FIF)
2462** removed GCUAUTO / BYPATNDN/UP
2463**
2464******************************************************************************/
2465static UData_t MT2063_SetReceiverMode(struct MT2063_Info_t *pInfo,
2466 enum MT2063_RCVR_MODES Mode)
2467{
2468 UData_t status = MT2063_OK; /* Status to be returned */
2469 U8Data val;
2470 UData_t longval;
2471
2472 if (Mode >= MT2063_NUM_RCVR_MODES)
2473 status = MT2063_ARG_RANGE;
2474
2475 /* RFAGCen */
2476 if (MT2063_NO_ERROR(status)) {
2477 val =
2478 (pInfo->
2479 reg[MT2063_REG_PD1_TGT] & (U8Data) ~ 0x40) | (RFAGCEN[Mode]
2480 ? 0x40 :
2481 0x00);
2482 if (pInfo->reg[MT2063_REG_PD1_TGT] != val) {
2483 status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val);
57 } 2484 }
2485 }
2486
2487 /* LNARin */
2488 if (MT2063_NO_ERROR(status)) {
2489 status |= MT2063_SetParam(pInfo, MT2063_LNA_RIN, LNARIN[Mode]);
2490 }
2491
2492 /* FIFFQEN and FIFFQ */
2493 if (MT2063_NO_ERROR(status)) {
2494 val =
2495 (pInfo->
2496 reg[MT2063_REG_FIFF_CTRL2] & (U8Data) ~ 0xF0) |
2497 (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
2498 if (pInfo->reg[MT2063_REG_FIFF_CTRL2] != val) {
2499 status |=
2500 MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL2, val);
2501 /* trigger FIFF calibration, needed after changing FIFFQ */
2502 val =
2503 (pInfo->reg[MT2063_REG_FIFF_CTRL] | (U8Data) 0x01);
2504 status |=
2505 MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL, val);
2506 val =
2507 (pInfo->
2508 reg[MT2063_REG_FIFF_CTRL] & (U8Data) ~ 0x01);
2509 status |=
2510 MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL, val);
2511 }
2512 }
2513
2514 /* DNC1GC & DNC2GC */
2515 status |= MT2063_GetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, &longval);
2516 status |= MT2063_SetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, longval);
2517
2518 /* acLNAmax */
2519 if (MT2063_NO_ERROR(status)) {
2520 status |=
2521 MT2063_SetParam(pInfo, MT2063_ACLNA_MAX, ACLNAMAX[Mode]);
2522 }
2523
2524 /* LNATGT */
2525 if (MT2063_NO_ERROR(status)) {
2526 status |= MT2063_SetParam(pInfo, MT2063_LNA_TGT, LNATGT[Mode]);
2527 }
2528
2529 /* ACRF */
2530 if (MT2063_NO_ERROR(status)) {
2531 status |=
2532 MT2063_SetParam(pInfo, MT2063_ACRF_MAX, ACRFMAX[Mode]);
2533 }
2534
2535 /* PD1TGT */
2536 if (MT2063_NO_ERROR(status)) {
2537 status |= MT2063_SetParam(pInfo, MT2063_PD1_TGT, PD1TGT[Mode]);
2538 }
2539
2540 /* FIFATN */
2541 if (MT2063_NO_ERROR(status)) {
2542 status |=
2543 MT2063_SetParam(pInfo, MT2063_ACFIF_MAX, ACFIFMAX[Mode]);
2544 }
2545
2546 /* PD2TGT */
2547 if (MT2063_NO_ERROR(status)) {
2548 status |= MT2063_SetParam(pInfo, MT2063_PD2_TGT, PD2TGT[Mode]);
2549 }
2550
2551 /* Ignore ATN Overload */
2552 if (MT2063_NO_ERROR(status)) {
2553 val =
2554 (pInfo->
2555 reg[MT2063_REG_LNA_TGT] & (U8Data) ~ 0x80) | (RFOVDIS[Mode]
2556 ? 0x80 :
2557 0x00);
2558 if (pInfo->reg[MT2063_REG_LNA_TGT] != val) {
2559 status |= MT2063_SetReg(pInfo, MT2063_REG_LNA_TGT, val);
2560 }
2561 }
2562
2563 /* Ignore FIF Overload */
2564 if (MT2063_NO_ERROR(status)) {
2565 val =
2566 (pInfo->
2567 reg[MT2063_REG_PD1_TGT] & (U8Data) ~ 0x80) |
2568 (FIFOVDIS[Mode] ? 0x80 : 0x00);
2569 if (pInfo->reg[MT2063_REG_PD1_TGT] != val) {
2570 status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val);
2571 }
2572 }
2573
2574 if (MT2063_NO_ERROR(status))
2575 pInfo->rcvr_mode = Mode;
2576
2577 return (status);
2578}
2579
2580/******************************************************************************
2581**
2582** Name: MT2063_ReInit
2583**
2584** Description: Initialize the tuner's register values.
2585**
2586** Parameters: h - Tuner handle (returned by MT2063_Open)
2587**
2588** Returns: status:
2589** MT_OK - No errors
2590** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch
2591** MT_INV_HANDLE - Invalid tuner handle
2592** MT_COMM_ERR - Serial bus communications error
2593**
2594** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus
2595** MT_WriteSub - Write byte(s) of data to the two-wire bus
2596**
2597** Revision History:
2598**
2599** SCR Date Author Description
2600** -------------------------------------------------------------------------
2601** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2602** 148 09-04-2007 RSK Ver 1.02: Corrected logic of Reg 3B Reference
2603** 153 09-07-2007 RSK Ver 1.03: Lock Time improvements
2604** N/A 10-31-2007 PINZ Ver 1.08: Changed values suitable to rcvr-mode 0
2605** N/A 11-12-2007 PINZ Ver 1.09: Changed values suitable to rcvr-mode 0
2606** N/A 01-03-2007 PINZ Ver 1.10: Added AFCsd = 1 into defaults
2607** N/A 01-04-2007 PINZ Ver 1.10: Changed CAP1sel default
2608** 01-14-2008 PINZ Ver 1.11: Updated gain settings
2609** 03-18-2008 PINZ Ver 1.13: Added Support for B3
2610** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid.
2611** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW
2612**
2613******************************************************************************/
2614UData_t MT2063_ReInit(Handle_t h)
2615{
2616 U8Data all_resets = 0xF0; /* reset/load bits */
2617 UData_t status = MT2063_OK; /* Status to be returned */
2618 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
2619 U8Data *def;
2620
2621 U8Data MT2063B0_defaults[] = { /* Reg, Value */
2622 0x19, 0x05,
2623 0x1B, 0x1D,
2624 0x1C, 0x1F,
2625 0x1D, 0x0F,
2626 0x1E, 0x3F,
2627 0x1F, 0x0F,
2628 0x20, 0x3F,
2629 0x22, 0x21,
2630 0x23, 0x3F,
2631 0x24, 0x20,
2632 0x25, 0x3F,
2633 0x27, 0xEE,
2634 0x2C, 0x27, /* bit at 0x20 is cleared below */
2635 0x30, 0x03,
2636 0x2C, 0x07, /* bit at 0x20 is cleared here */
2637 0x2D, 0x87,
2638 0x2E, 0xAA,
2639 0x28, 0xE1, /* Set the FIFCrst bit here */
2640 0x28, 0xE0, /* Clear the FIFCrst bit here */
2641 0x00
2642 };
2643
2644 /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
2645 U8Data MT2063B1_defaults[] = { /* Reg, Value */
2646 0x05, 0xF0,
2647 0x11, 0x10, /* New Enable AFCsd */
2648 0x19, 0x05,
2649 0x1A, 0x6C,
2650 0x1B, 0x24,
2651 0x1C, 0x28,
2652 0x1D, 0x8F,
2653 0x1E, 0x14,
2654 0x1F, 0x8F,
2655 0x20, 0x57,
2656 0x22, 0x21, /* New - ver 1.03 */
2657 0x23, 0x3C, /* New - ver 1.10 */
2658 0x24, 0x20, /* New - ver 1.03 */
2659 0x2C, 0x24, /* bit at 0x20 is cleared below */
2660 0x2D, 0x87, /* FIFFQ=0 */
2661 0x2F, 0xF3,
2662 0x30, 0x0C, /* New - ver 1.11 */
2663 0x31, 0x1B, /* New - ver 1.11 */
2664 0x2C, 0x04, /* bit at 0x20 is cleared here */
2665 0x28, 0xE1, /* Set the FIFCrst bit here */
2666 0x28, 0xE0, /* Clear the FIFCrst bit here */
2667 0x00
2668 };
2669
2670 /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
2671 U8Data MT2063B3_defaults[] = { /* Reg, Value */
2672 0x05, 0xF0,
2673 0x19, 0x3D,
2674 0x2C, 0x24, /* bit at 0x20 is cleared below */
2675 0x2C, 0x04, /* bit at 0x20 is cleared here */
2676 0x28, 0xE1, /* Set the FIFCrst bit here */
2677 0x28, 0xE0, /* Clear the FIFCrst bit here */
2678 0x00
58 }; 2679 };
59 2680
60 //printk("mt2063_read_regs state->i2c=%p\n", state->i2c); 2681 /* Verify that the handle passed points to a valid tuner */
61 ret = i2c_transfer(state->i2c, msg, 2); 2682 if (MT2063_IsValidHandle(pInfo) == 0)
62 if (ret < 0) 2683 status |= MT2063_INV_HANDLE;
63 printk("mt2063_readregs error ret=%d\n", ret); 2684
64 2685 /* Read the Part/Rev code from the tuner */
65 return ret; 2686 if (MT2063_NO_ERROR(status)) {
66} 2687 status |=
67 2688 MT2063_ReadSub(pInfo->hUserData, pInfo->address,
68 2689 MT2063_REG_PART_REV, pInfo->reg, 1);
69 2690 }
70 2691
71//context of mt2063_userdef.c <Henry> ====================================== 2692 if (MT2063_NO_ERROR(status) /* Check the part/rev code */
72//################################################################# 2693 &&((pInfo->reg[MT2063_REG_PART_REV] != MT2063_B0) /* MT2063 B0 */
73//================================================================= 2694 &&(pInfo->reg[MT2063_REG_PART_REV] != MT2063_B1) /* MT2063 B1 */
74/***************************************************************************** 2695 &&(pInfo->reg[MT2063_REG_PART_REV] != MT2063_B3))) /* MT2063 B3 */
75** 2696 status |= MT2063_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */
76** Name: MT_WriteSub 2697
77** 2698 /* Read the Part/Rev code (2nd byte) from the tuner */
78** Description: Write values to device using a two-wire serial bus. 2699 if (MT2063_NO_ERROR(status))
79** 2700 status |=
80** Parameters: hUserData - User-specific I/O parameter that was 2701 MT2063_ReadSub(pInfo->hUserData, pInfo->address,
81** passed to tuner's Open function. 2702 MT2063_REG_RSVD_3B,
82** addr - device serial bus address (value passed 2703 &pInfo->reg[MT2063_REG_RSVD_3B], 1);
83** as parameter to MTxxxx_Open) 2704
84** subAddress - serial bus sub-address (Register Address) 2705 if (MT2063_NO_ERROR(status) /* Check the 2nd part/rev code */
85** pData - pointer to the Data to be written to the 2706 &&((pInfo->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) /* b7 != 0 ==> NOT MT2063 */
86** device 2707 status |= MT2063_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */
87** cnt - number of bytes/registers to be written 2708
88** 2709 /* Reset the tuner */
89** Returns: status: 2710 if (MT2063_NO_ERROR(status))
90** MT_OK - No errors 2711 status |= MT2063_WriteSub(pInfo->hUserData,
91** MT_COMM_ERR - Serial bus communications error 2712 pInfo->address,
92** user-defined 2713 MT2063_REG_LO2CQ_3, &all_resets, 1);
93** 2714
94** Notes: This is a callback function that is called from the 2715 /* change all of the default values that vary from the HW reset values */
95** the tuning algorithm. You MUST provide code for this 2716 /* def = (pInfo->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */
96** function to write data using the tuner's 2-wire serial 2717 switch (pInfo->reg[MT2063_REG_PART_REV]) {
97** bus. 2718 case MT2063_B3:
98** 2719 def = MT2063B3_defaults;
99** The hUserData parameter is a user-specific argument. 2720 break;
100** If additional arguments are needed for the user's 2721
101** serial bus read/write functions, this argument can be 2722 case MT2063_B1:
102** used to supply the necessary information. 2723 def = MT2063B1_defaults;
103** The hUserData parameter is initialized in the tuner's Open 2724 break;
104** function. 2725
105** 2726 case MT2063_B0:
106** Revision History: 2727 def = MT2063B0_defaults;
107** 2728 break;
108** SCR Date Author Description 2729
109** ------------------------------------------------------------------------- 2730 default:
110** N/A 03-25-2004 DAD Original 2731 status |= MT2063_TUNER_ID_ERR;
111** 2732 break;
112*****************************************************************************/ 2733 }
113UData_t MT2063_WriteSub(Handle_t hUserData, 2734
114 UData_t addr, 2735 while (MT2063_NO_ERROR(status) && *def) {
115 U8Data subAddress, 2736 U8Data reg = *def++;
116 U8Data *pData, 2737 U8Data val = *def++;
117 UData_t cnt) 2738 status |=
118{ 2739 MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val,
119 UData_t status = MT2063_OK; /* Status to be returned */ 2740 1);
120 struct dvb_frontend *fe = hUserData; 2741 }
121 struct mt2063_state *state = fe->tuner_priv; 2742
122 /* 2743 /* Wait for FIFF location to complete. */
123 ** ToDo: Add code here to implement a serial-bus write 2744 if (MT2063_NO_ERROR(status)) {
124 ** operation to the MTxxxx tuner. If successful, 2745 UData_t FCRUN = 1;
125 ** return MT_OK. 2746 SData_t maxReads = 10;
126 */ 2747 while (MT2063_NO_ERROR(status) && (FCRUN != 0)
127/* return status; */ 2748 && (maxReads-- > 0)) {
128 2749 MT2063_Sleep(pInfo->hUserData, 2);
129//#if !TUNER_CONTROL_BY_DRXK_DRIVER 2750 status |= MT2063_ReadSub(pInfo->hUserData,
130 fe->ops.i2c_gate_ctrl(fe, 1); //I2C bypass drxk3926 close i2c bridge 2751 pInfo->address,
131//#endif 2752 MT2063_REG_XO_STATUS,
132 2753 &pInfo->
133 if (mt2063_writeregs(state, subAddress,pData, cnt)<0) 2754 reg[MT2063_REG_XO_STATUS], 1);
134 { 2755 FCRUN = (pInfo->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
135 status = MT2063_ERROR; 2756 }
136 } 2757
137 2758 if (FCRUN != 0)
138//#if !TUNER_CONTROL_BY_DRXK_DRIVER 2759 status |= MT2063_TUNER_INIT_ERR | MT2063_TUNER_TIMEOUT;
139 fe->ops.i2c_gate_ctrl(fe, 0); //I2C bypass drxk3926 close i2c bridge 2760
140//#endif 2761 if (MT2063_NO_ERROR(status)) /* Re-read FIFFC value */
141 2762 status |=
142 return (status); 2763 MT2063_ReadSub(pInfo->hUserData, pInfo->address,
143} 2764 MT2063_REG_FIFFC,
144 2765 &pInfo->reg[MT2063_REG_FIFFC], 1);
145/***************************************************************************** 2766 }
146** 2767
147** Name: MT_ReadSub 2768 /* Read back all the registers from the tuner */
148** 2769 if (MT2063_NO_ERROR(status))
149** Description: Read values from device using a two-wire serial bus. 2770 status |= MT2063_ReadSub(pInfo->hUserData,
150** 2771 pInfo->address,
151** Parameters: hUserData - User-specific I/O parameter that was 2772 MT2063_REG_PART_REV,
152** passed to tuner's Open function. 2773 pInfo->reg, MT2063_REG_END_REGS);
153** addr - device serial bus address (value passed 2774
154** as parameter to MTxxxx_Open) 2775 if (MT2063_NO_ERROR(status)) {
155** subAddress - serial bus sub-address (Register Address) 2776 /* Initialize the tuner state. */
156** pData - pointer to the Data to be written to the 2777 pInfo->version = MT2063_VERSION;
157** device 2778 pInfo->tuner_id = pInfo->reg[MT2063_REG_PART_REV];
158** cnt - number of bytes/registers to be written 2779 pInfo->AS_Data.f_ref = MT2063_REF_FREQ;
159** 2780 pInfo->AS_Data.f_if1_Center =
160** Returns: status: 2781 (pInfo->AS_Data.f_ref / 8) *
161** MT_OK - No errors 2782 ((UData_t) pInfo->reg[MT2063_REG_FIFFC] + 640);
162** MT_COMM_ERR - Serial bus communications error 2783 pInfo->AS_Data.f_if1_bw = MT2063_IF1_BW;
163** user-defined 2784 pInfo->AS_Data.f_out = 43750000UL;
164** 2785 pInfo->AS_Data.f_out_bw = 6750000UL;
165** Notes: This is a callback function that is called from the 2786 pInfo->AS_Data.f_zif_bw = MT2063_ZIF_BW;
166** the tuning algorithm. You MUST provide code for this 2787 pInfo->AS_Data.f_LO1_Step = pInfo->AS_Data.f_ref / 64;
167** function to read data using the tuner's 2-wire serial 2788 pInfo->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
168** bus. 2789 pInfo->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
169** 2790 pInfo->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
170** The hUserData parameter is a user-specific argument. 2791 pInfo->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
171** If additional arguments are needed for the user's 2792 pInfo->AS_Data.f_if1_Request = pInfo->AS_Data.f_if1_Center;
172** serial bus read/write functions, this argument can be 2793 pInfo->AS_Data.f_LO1 = 2181000000UL;
173** used to supply the necessary information. 2794 pInfo->AS_Data.f_LO2 = 1486249786UL;
174** The hUserData parameter is initialized in the tuner's Open 2795 pInfo->f_IF1_actual = pInfo->AS_Data.f_if1_Center;
175** function. 2796 pInfo->AS_Data.f_in =
176** 2797 pInfo->AS_Data.f_LO1 - pInfo->f_IF1_actual;
177** Revision History: 2798 pInfo->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
178** 2799 pInfo->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
179** SCR Date Author Description 2800 pInfo->num_regs = MT2063_REG_END_REGS;
180** ------------------------------------------------------------------------- 2801 pInfo->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
181** N/A 03-25-2004 DAD Original 2802 pInfo->ctfilt_sw = 0;
182** 2803 }
183*****************************************************************************/ 2804
184UData_t MT2063_ReadSub(Handle_t hUserData, 2805 if (MT2063_NO_ERROR(status)) {
185 UData_t addr, 2806 pInfo->CTFiltMax[0] = 69230000;
186 U8Data subAddress, 2807 pInfo->CTFiltMax[1] = 105770000;
187 U8Data *pData, 2808 pInfo->CTFiltMax[2] = 140350000;
188 UData_t cnt) 2809 pInfo->CTFiltMax[3] = 177110000;
189{ 2810 pInfo->CTFiltMax[4] = 212860000;
190 /* 2811 pInfo->CTFiltMax[5] = 241130000;
191 ** ToDo: Add code here to implement a serial-bus read 2812 pInfo->CTFiltMax[6] = 274370000;
192 ** operation to the MTxxxx tuner. If successful, 2813 pInfo->CTFiltMax[7] = 309820000;
193 ** return MT_OK. 2814 pInfo->CTFiltMax[8] = 342450000;
194 */ 2815 pInfo->CTFiltMax[9] = 378870000;
195/* return status; */ 2816 pInfo->CTFiltMax[10] = 416210000;
196 UData_t status = MT2063_OK; /* Status to be returned */ 2817 pInfo->CTFiltMax[11] = 456500000;
197 struct dvb_frontend *fe = hUserData; 2818 pInfo->CTFiltMax[12] = 495790000;
198 struct mt2063_state *state = fe->tuner_priv; 2819 pInfo->CTFiltMax[13] = 534530000;
199 UData_t i = 0; 2820 pInfo->CTFiltMax[14] = 572610000;
200//#if !TUNER_CONTROL_BY_DRXK_DRIVER 2821 pInfo->CTFiltMax[15] = 598970000;
201 fe->ops.i2c_gate_ctrl(fe, 1); //I2C bypass drxk3926 close i2c bridge 2822 pInfo->CTFiltMax[16] = 635910000;
202//#endif 2823 pInfo->CTFiltMax[17] = 672130000;
203 2824 pInfo->CTFiltMax[18] = 714840000;
204 for (i = 0; i < cnt; i++) 2825 pInfo->CTFiltMax[19] = 739660000;
205 { 2826 pInfo->CTFiltMax[20] = 770410000;
206 if (mt2063_read_regs(state, subAddress+i, pData+i, 1)<0) 2827 pInfo->CTFiltMax[21] = 814660000;
207 { 2828 pInfo->CTFiltMax[22] = 846950000;
208 status = MT2063_ERROR; 2829 pInfo->CTFiltMax[23] = 867820000;
209 break; 2830 pInfo->CTFiltMax[24] = 915980000;
210 } 2831 pInfo->CTFiltMax[25] = 947450000;
211 } 2832 pInfo->CTFiltMax[26] = 983110000;
212 2833 pInfo->CTFiltMax[27] = 1021630000;
213//#if !TUNER_CONTROL_BY_DRXK_DRIVER 2834 pInfo->CTFiltMax[28] = 1061870000;
214 fe->ops.i2c_gate_ctrl(fe, 0); //I2C bypass drxk3926 close i2c bridge 2835 pInfo->CTFiltMax[29] = 1098330000;
215//#endif 2836 pInfo->CTFiltMax[30] = 1138990000;
216 2837 }
217 return(status); 2838
218} 2839 /*
219 2840 ** Fetch the FCU osc value and use it and the fRef value to
220 2841 ** scale all of the Band Max values
221/***************************************************************************** 2842 */
222** 2843 if (MT2063_NO_ERROR(status)) {
223** Name: MT_Sleep 2844 UData_t fcu_osc;
224** 2845 UData_t i;
225** Description: Delay execution for "nMinDelayTime" milliseconds 2846
226** 2847 pInfo->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
227** Parameters: hUserData - User-specific I/O parameter that was 2848 status |=
228** passed to tuner's Open function. 2849 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
229** nMinDelayTime - Delay time in milliseconds 2850 MT2063_REG_CTUNE_CTRL,
230** 2851 &pInfo->reg[MT2063_REG_CTUNE_CTRL], 1);
231** Returns: None. 2852 /* Read the ClearTune filter calibration value */
232** 2853 status |=
233** Notes: This is a callback function that is called from the 2854 MT2063_ReadSub(pInfo->hUserData, pInfo->address,
234** the tuning algorithm. You MUST provide code that 2855 MT2063_REG_FIFFC,
235** blocks execution for the specified period of time. 2856 &pInfo->reg[MT2063_REG_FIFFC], 1);
236** 2857 fcu_osc = pInfo->reg[MT2063_REG_FIFFC];
237** Revision History: 2858
238** 2859 pInfo->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
239** SCR Date Author Description 2860 status |=
240** ------------------------------------------------------------------------- 2861 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
241** N/A 03-25-2004 DAD Original 2862 MT2063_REG_CTUNE_CTRL,
242** 2863 &pInfo->reg[MT2063_REG_CTUNE_CTRL], 1);
243*****************************************************************************/ 2864
244void MT2063_Sleep(Handle_t hUserData, 2865 /* Adjust each of the values in the ClearTune filter cross-over table */
245 UData_t nMinDelayTime) 2866 for (i = 0; i < 31; i++) {
246{ 2867 pInfo->CTFiltMax[i] =
247 /* 2868 (pInfo->CTFiltMax[i] / 768) * (fcu_osc + 640);
248 ** ToDo: Add code here to implement a OS blocking 2869 }
249 ** for a period of "nMinDelayTime" milliseconds. 2870 }
250 */ 2871
251 msleep(nMinDelayTime); 2872 return (status);
252} 2873}
253 2874
254 2875/******************************************************************************
255#if defined(MT2060_CNT) 2876**
256#if MT2060_CNT > 0 2877** Name: MT2063_SetGPIO
257/***************************************************************************** 2878**
258** 2879** Description: Modify the MT2063 GPIO value.
259** Name: MT_TunerGain (MT2060 only) 2880**
260** 2881** Parameters: h - Open handle to the tuner (from MT2063_Open).
261** Description: Measure the relative tuner gain using the demodulator 2882** gpio_id - Selects GPIO0, GPIO1 or GPIO2
262** 2883** attr - Selects input readback, I/O direction or
263** Parameters: hUserData - User-specific I/O parameter that was 2884** output value
264** passed to tuner's Open function. 2885** value - value to set GPIO pin 15, 14 or 19
265** pMeas - Tuner gain (1/100 of dB scale). 2886**
266** ie. 1234 = 12.34 (dB) 2887** Usage: status = MT2063_SetGPIO(hMT2063, MT2063_GPIO1, MT2063_GPIO_OUT, 1);
267** 2888**
268** Returns: status: 2889** Returns: status:
269** MT_OK - No errors 2890** MT_OK - No errors
270** user-defined errors could be set 2891** MT_COMM_ERR - Serial bus communications error
271** 2892** MT_INV_HANDLE - Invalid tuner handle
272** Notes: This is a callback function that is called from the 2893**
273** the 1st IF location routine. You MUST provide 2894** Dependencies: MT_WriteSub - Write byte(s) of data to the two-wire-bus
274** code that measures the relative tuner gain in a dB 2895**
275** (not linear) scale. The return value is an integer 2896** Revision History:
276** value scaled to 1/100 of a dB. 2897**
277** 2898** SCR Date Author Description
278** Revision History: 2899** -------------------------------------------------------------------------
279** 2900** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
280** SCR Date Author Description 2901**
281** ------------------------------------------------------------------------- 2902******************************************************************************/
282** N/A 06-16-2004 DAD Original 2903UData_t MT2063_SetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id,
283** N/A 11-30-2004 DAD Renamed from MT_DemodInputPower. This name 2904 enum MT2063_GPIO_Attr attr, UData_t value)
284** better describes what this function does. 2905{
285** 2906 UData_t status = MT2063_OK; /* Status to be returned */
286*****************************************************************************/ 2907 U8Data regno;
287UData_t MT2060_TunerGain(Handle_t hUserData, 2908 SData_t shift;
288 SData_t* pMeas) 2909 static U8Data GPIOreg[3] = { 0x15, 0x19, 0x18 };
289{ 2910 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
290 UData_t status = MT2063_OK; /* Status to be returned */ 2911
291 2912 if (MT2063_IsValidHandle(pInfo) == 0)
292 /* 2913 return MT2063_INV_HANDLE;
293 ** ToDo: Add code here to return the gain / power level measured 2914
294 ** at the input to the demodulator. 2915 regno = GPIOreg[attr];
295 */ 2916
296 2917 shift = (gpio_id - MT2063_GPIO0 + 5);
297 2918
298 2919 if (value & 0x01)
299 return (status); 2920 pInfo->reg[regno] |= (0x01 << shift);
300} 2921 else
301#endif 2922 pInfo->reg[regno] &= ~(0x01 << shift);
302#endif 2923 status =
303//end of mt2063_userdef.c 2924 MT2063_WriteSub(pInfo->hUserData, pInfo->address, regno,
304//================================================================= 2925 &pInfo->reg[regno], 1);
305//################################################################# 2926
306//================================================================= 2927 return (status);
307 2928}
308 2929
309//context of mt2063_spuravoid.c <Henry> ====================================== 2930/****************************************************************************
310//################################################################# 2931**
311//================================================================= 2932** Name: MT2063_SetParam
312 2933**
313/***************************************************************************** 2934** Description: Sets a tuning algorithm parameter.
314** 2935**
315** Name: mt_spuravoid.c 2936** This function provides access to the internals of the
316** 2937** tuning algorithm. You can override many of the tuning
317** Description: Microtune spur avoidance software module. 2938** algorithm defaults using this function.
318** Supports Microtune tuner drivers. 2939**
319** 2940** Parameters: h - Tuner handle (returned by MT2063_Open)
320** CVS ID: $Id: mt_spuravoid.c,v 1.3 2008/06/26 15:39:52 software Exp $ 2941** param - Tuning algorithm parameter
321** CVS Source: $Source: /export/home/cvsroot/software/tuners/MT2063/mt_spuravoid.c,v $ 2942** (see enum MT2063_Param)
322** 2943** nValue - value to be set
323** Revision History: 2944**
324** 2945** param Description
325** SCR Date Author Description 2946** ---------------------- --------------------------------
326** ------------------------------------------------------------------------- 2947** MT2063_SRO_FREQ crystal frequency
327** 082 03-25-2005 JWS Original multi-tuner support - requires 2948** MT2063_STEPSIZE minimum tuning step size
328** MTxxxx_CNT declarations 2949** MT2063_LO1_FREQ LO1 frequency
329** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. 2950** MT2063_LO1_STEPSIZE LO1 minimum step size
330** 094 04-06-2005 JWS Ver 1.11 Added uceil and ufloor to get rid 2951** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region
331** of compiler warnings 2952** MT2063_IF1_REQUEST Requested 1st IF
332** N/A 04-07-2005 DAD Ver 1.13: Merged single- and multi-tuner spur 2953** MT2063_ZIF_BW zero-IF bandwidth
333** avoidance into a single module. 2954** MT2063_LO2_FREQ LO2 frequency
334** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range 2955** MT2063_LO2_STEPSIZE LO2 minimum step size
335** (f_min, f_max) < 0, ignore the entry. 2956** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region
336** 115 03-23-2007 DAD Fix declaration of spur due to truncation 2957** MT2063_OUTPUT_FREQ output center frequency
337** errors. 2958** MT2063_OUTPUT_BW output bandwidth
338** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from 2959** MT2063_LO_SEPARATION min inter-tuner LO separation
339** tuner DLL. 2960** MT2063_MAX_HARM1 max # of intra-tuner harmonics
340** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for 2961** MT2063_MAX_HARM2 max # of inter-tuner harmonics
341** multi-tuners that have 2962** MT2063_RCVR_MODE Predefined modes
342** (delta IF1) > (f_out-f_outbw/2). 2963** MT2063_LNA_RIN Set LNA Rin (*)
343** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) 2964** MT2063_LNA_TGT Set target power level at LNA (*)
344** Added logic to force f_Center within 1/2 f_Step. 2965** MT2063_PD1_TGT Set target power level at PD1 (*)
345** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 2966** MT2063_PD2_TGT Set target power level at PD2 (*)
346** Type casts added to preserve correct sign. 2967** MT2063_ACLNA_MAX LNA attenuator limit (*)
347** N/A I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT 2968** MT2063_ACRF_MAX RF attenuator limit (*)
348** frequencies into MT_ResetExclZones(). 2969** MT2063_ACFIF_MAX FIF attenuator limit (*)
349** N/A I 06-20-2008 RSK Ver 1.21: New VERSION number for ver checking. 2970** MT2063_DNC_OUTPUT_ENABLE DNC output selection
350** 2971** MT2063_VGAGC VGA gain code
351*****************************************************************************/ 2972** MT2063_VGAOI VGA output current
352 2973** MT2063_TAGC TAGC setting
353#if !defined(MT2063_TUNER_CNT) 2974** MT2063_AMPGC AMP gain code
354#error MT2063_TUNER_CNT is not defined (see mt_userdef.h) 2975** MT2063_AVOID_DECT Avoid DECT Frequencies
355#endif 2976** MT2063_CTFILT_SW Cleartune filter selection
356 2977**
357#if MT2063_TUNER_CNT == 0 2978** (*) This parameter is set by MT2063_RCVR_MODE, do not call
358#error MT2063_TUNER_CNT must be updated in mt_userdef.h 2979** additionally.
359#endif 2980**
360 2981** Usage: status |= MT2063_SetParam(hMT2063,
361/* Version of this module */ 2982** MT2063_STEPSIZE,
362#define MT2063_SPUR_VERSION 10201 /* Version 01.21 */ 2983** 50000);
363 2984**
364 2985** Returns: status:
365/* Implement ceiling, floor functions. */ 2986** MT_OK - No errors
366#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0)) 2987** MT_INV_HANDLE - Invalid tuner handle
367#define uceil(n, d) ((n)/(d) + ((n)%(d) != 0)) 2988** MT_ARG_NULL - Null pointer argument passed
368#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d)) 2989** MT_ARG_RANGE - Invalid parameter requested
369#define ufloor(n, d) ((n)/(d)) 2990** or set value out of range
370 2991** or non-writable parameter
371 2992**
372struct MT2063_FIFZone_t 2993** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
373{ 2994**
374 SData_t min_; 2995** See Also: MT2063_GetParam, MT2063_Open
375 SData_t max_; 2996**
376}; 2997** Revision History:
377 2998**
378#if MT2063_TUNER_CNT > 1 2999** SCR Date Author Description
379static struct MT2063_AvoidSpursData_t* TunerList[MT2063_TUNER_CNT]; 3000** -------------------------------------------------------------------------
380static UData_t TunerCount = 0; 3001** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
381#endif 3002** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ
382 3003** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC
383UData_t MT2063_RegisterTuner(struct MT2063_AvoidSpursData_t* pAS_Info) 3004** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT
384{ 3005** Split SetParam up to ACLNA / ACLNA_MAX
385#if MT2063_TUNER_CNT == 1 3006** removed ACLNA_INRC/DECR (+RF & FIF)
386 pAS_Info->nAS_Algorithm = 1; 3007** removed GCUAUTO / BYPATNDN/UP
387 return MT2063_OK; 3008** 175 I 06-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs.
388#else 3009** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid.
389 UData_t index; 3010** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW
390 3011**
391 pAS_Info->nAS_Algorithm = 2; 3012****************************************************************************/
392 3013UData_t MT2063_SetParam(Handle_t h, enum MT2063_Param param, UData_t nValue)
393 /* 3014{
394 ** Check to see if tuner is already registered 3015 UData_t status = MT2063_OK; /* Status to be returned */
395 */ 3016 U8Data val = 0;
396 for (index = 0; index < TunerCount; index++) 3017 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
397 { 3018
398 if (TunerList[index] == pAS_Info) 3019 /* Verify that the handle passed points to a valid tuner */
399 { 3020 if (MT2063_IsValidHandle(pInfo) == 0)
400 return MT2063_OK; /* Already here - no problem */ 3021 status |= MT2063_INV_HANDLE;
401 } 3022
402 } 3023 if (MT2063_NO_ERROR(status)) {
403 3024 switch (param) {
404 /* 3025 /* crystal frequency */
405 ** Add tuner to list - if there is room. 3026 case MT2063_SRO_FREQ:
406 */ 3027 pInfo->AS_Data.f_ref = nValue;
407 if (TunerCount < MT2063_TUNER_CNT) 3028 pInfo->AS_Data.f_LO1_FracN_Avoid = 0;
408 { 3029 pInfo->AS_Data.f_LO2_FracN_Avoid = nValue / 80 - 1;
409 TunerList[TunerCount] = pAS_Info; 3030 pInfo->AS_Data.f_LO1_Step = nValue / 64;
410 TunerCount++; 3031 pInfo->AS_Data.f_if1_Center =
411 return MT2063_OK; 3032 (pInfo->AS_Data.f_ref / 8) *
412 } 3033 (pInfo->reg[MT2063_REG_FIFFC] + 640);
413 else 3034 break;
414 return MT2063_TUNER_CNT_ERR; 3035
415#endif 3036 /* minimum tuning step size */
416} 3037 case MT2063_STEPSIZE:
417 3038 pInfo->AS_Data.f_LO2_Step = nValue;
418 3039 break;
419void MT2063_UnRegisterTuner(struct MT2063_AvoidSpursData_t* pAS_Info) 3040
420{ 3041 /* LO1 frequency */
421#if MT2063_TUNER_CNT == 1 3042 case MT2063_LO1_FREQ:
422 pAS_Info; 3043 {
423#else 3044 /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */
424 3045 /* Capture the Divider and Numerator portions of other LO */
425 UData_t index; 3046 U8Data tempLO2CQ[3];
426 3047 U8Data tempLO2C[3];
427 for (index = 0; index < TunerCount; index++) 3048 U8Data tmpOneShot;
428 { 3049 UData_t Div, FracN;
429 if (TunerList[index] == pAS_Info) 3050 U8Data restore = 0;
430 { 3051
431 TunerList[index] = TunerList[--TunerCount]; 3052 /* Buffer the queue for restoration later and get actual LO2 values. */
432 } 3053 status |=
433 } 3054 MT2063_ReadSub(pInfo->hUserData,
434#endif 3055 pInfo->address,
435} 3056 MT2063_REG_LO2CQ_1,
436 3057 &(tempLO2CQ[0]), 3);
437 3058 status |=
438/* 3059 MT2063_ReadSub(pInfo->hUserData,
439** Reset all exclusion zones. 3060 pInfo->address,
440** Add zones to protect the PLL FracN regions near zero 3061 MT2063_REG_LO2C_1,
441** 3062 &(tempLO2C[0]), 3);
442** N/A I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT 3063
443** frequencies into MT_ResetExclZones(). 3064 /* clear the one-shot bits */
444*/ 3065 tempLO2CQ[2] = tempLO2CQ[2] & 0x0F;
445void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t* pAS_Info) 3066 tempLO2C[2] = tempLO2C[2] & 0x0F;
446{ 3067
447 UData_t center; 3068 /* only write the queue values if they are different from the actual. */
448#if MT2063_TUNER_CNT > 1 3069 if ((tempLO2CQ[0] != tempLO2C[0]) ||
449 UData_t index; 3070 (tempLO2CQ[1] != tempLO2C[1]) ||
450 struct MT2063_AvoidSpursData_t* adj; 3071 (tempLO2CQ[2] != tempLO2C[2])) {
451#endif 3072 /* put actual LO2 value into queue (with 0 in one-shot bits) */
452 3073 status |=
453 pAS_Info->nZones = 0; /* this clears the used list */ 3074 MT2063_WriteSub(pInfo->hUserData,
454 pAS_Info->usedZones = NULL; /* reset ptr */ 3075 pInfo->address,
455 pAS_Info->freeZones = NULL; /* reset ptr */ 3076 MT2063_REG_LO2CQ_1,
456 3077 &(tempLO2C[0]), 3);
457 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; 3078
458 while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO1_FracN_Avoid) 3079 if (status == MT2063_OK) {
459 { 3080 /* cache the bytes just written. */
460 /* Exclude LO1 FracN */ 3081 pInfo->reg[MT2063_REG_LO2CQ_1] =
461 MT2063_AddExclZone(pAS_Info, center-pAS_Info->f_LO1_FracN_Avoid, center-1); 3082 tempLO2C[0];
462 MT2063_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO1_FracN_Avoid); 3083 pInfo->reg[MT2063_REG_LO2CQ_2] =
463 center += pAS_Info->f_ref; 3084 tempLO2C[1];
464 } 3085 pInfo->reg[MT2063_REG_LO2CQ_3] =
465 3086 tempLO2C[2];
466 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; 3087 }
467 while (center < pAS_Info->f_if1_Center + pAS_Info->f_if1_bw/2 + pAS_Info->f_LO2_FracN_Avoid) 3088 restore = 1;
468 { 3089 }
469 /* Exclude LO2 FracN */ 3090
470 MT2063_AddExclZone(pAS_Info, center-pAS_Info->f_LO2_FracN_Avoid, center-1); 3091 /* Calculate the Divider and Numberator components of LO1 */
471 MT2063_AddExclZone(pAS_Info, center+1, center+pAS_Info->f_LO2_FracN_Avoid); 3092 status =
472 center += pAS_Info->f_ref; 3093 MT2063_CalcLO1Mult(&Div, &FracN, nValue,
473 } 3094 pInfo->AS_Data.f_ref /
474 3095 64,
475 if( MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT) ) 3096 pInfo->AS_Data.f_ref);
476 { 3097 pInfo->reg[MT2063_REG_LO1CQ_1] =
477 /* Exclude LO1 values that conflict with DECT channels */ 3098 (U8Data) (Div & 0x00FF);
478 MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */ 3099 pInfo->reg[MT2063_REG_LO1CQ_2] =
479 MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */ 3100 (U8Data) (FracN);
480 MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */ 3101 status |=
481 MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */ 3102 MT2063_WriteSub(pInfo->hUserData,
482 MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */ 3103 pInfo->address,
483 } 3104 MT2063_REG_LO1CQ_1,
484 3105 &pInfo->
485 if( MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT) ) 3106 reg[MT2063_REG_LO1CQ_1], 2);
486 { 3107
487 MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */ 3108 /* set the one-shot bit to load the pair of LO values */
488 MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */ 3109 tmpOneShot = tempLO2CQ[2] | 0xE0;
489 MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */ 3110 status |=
490 MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16 */ 3111 MT2063_WriteSub(pInfo->hUserData,
491 MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */ 3112 pInfo->address,
492 MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */ 3113 MT2063_REG_LO2CQ_3,
493 MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */ 3114 &tmpOneShot, 1);
494 MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */ 3115
495 MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52 */ 3116 /* only restore the queue values if they were different from the actual. */
496 MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */ 3117 if (restore) {
497 } 3118 /* put actual LO2 value into queue (0 in one-shot bits) */
498 3119 status |=
499#if MT2063_TUNER_CNT > 1 3120 MT2063_WriteSub(pInfo->hUserData,
500 /* 3121 pInfo->address,
501 ** Iterate through all adjacent tuners and exclude frequencies related to them 3122 MT2063_REG_LO2CQ_1,
502 */ 3123 &(tempLO2CQ[0]), 3);
503 for (index = 0; index < TunerCount; ++index) 3124
504 { 3125 /* cache the bytes just written. */
505 adj = TunerList[index]; 3126 pInfo->reg[MT2063_REG_LO2CQ_1] =
506 if (pAS_Info == adj) /* skip over our own data, don't process it */ 3127 tempLO2CQ[0];
507 continue; 3128 pInfo->reg[MT2063_REG_LO2CQ_2] =
508 3129 tempLO2CQ[1];
509 /* 3130 pInfo->reg[MT2063_REG_LO2CQ_3] =
510 ** Add 1st IF exclusion zone covering adjacent tuner's LO2 3131 tempLO2CQ[2];
511 ** at "adjfLO2 + f_out" +/- m_MinLOSpacing 3132 }
512 */ 3133
513 if (adj->f_LO2 != 0) 3134 MT2063_GetParam(pInfo->hUserData,
514 MT2063_AddExclZone(pAS_Info, 3135 MT2063_LO1_FREQ,
515 (adj->f_LO2 + pAS_Info->f_out) - pAS_Info->f_min_LO_Separation, 3136 &pInfo->AS_Data.f_LO1);
516 (adj->f_LO2 + pAS_Info->f_out) + pAS_Info->f_min_LO_Separation ); 3137 }
517 3138 break;
518 /* 3139
519 ** Add 1st IF exclusion zone covering adjacent tuner's LO1 3140 /* LO1 minimum step size */
520 ** at "adjfLO1 - f_in" +/- m_MinLOSpacing 3141 case MT2063_LO1_STEPSIZE:
521 */ 3142 pInfo->AS_Data.f_LO1_Step = nValue;
522 if (adj->f_LO1 != 0) 3143 break;
523 MT2063_AddExclZone(pAS_Info, 3144
524 (adj->f_LO1 - pAS_Info->f_in) - pAS_Info->f_min_LO_Separation, 3145 /* LO1 FracN keep-out region */
525 (adj->f_LO1 - pAS_Info->f_in) + pAS_Info->f_min_LO_Separation ); 3146 case MT2063_LO1_FRACN_AVOID_PARAM:
526 } 3147 pInfo->AS_Data.f_LO1_FracN_Avoid = nValue;
527#endif 3148 break;
528} 3149
529 3150 /* Requested 1st IF */
530 3151 case MT2063_IF1_REQUEST:
531static struct MT2063_ExclZone_t* InsertNode(struct MT2063_AvoidSpursData_t* pAS_Info, 3152 pInfo->AS_Data.f_if1_Request = nValue;
532 struct MT2063_ExclZone_t* pPrevNode) 3153 break;
533{ 3154
534 struct MT2063_ExclZone_t* pNode; 3155 /* zero-IF bandwidth */
535 /* Check for a node in the free list */ 3156 case MT2063_ZIF_BW:
536 if (pAS_Info->freeZones != NULL) 3157 pInfo->AS_Data.f_zif_bw = nValue;
537 { 3158 break;
538 /* Use one from the free list */ 3159
539 pNode = pAS_Info->freeZones; 3160 /* LO2 frequency */
540 pAS_Info->freeZones = pNode->next_; 3161 case MT2063_LO2_FREQ:
541 } 3162 {
542 else 3163 /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */
543 { 3164 /* Capture the Divider and Numerator portions of other LO */
544 /* Grab a node from the array */ 3165 U8Data tempLO1CQ[2];
545 pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones]; 3166 U8Data tempLO1C[2];
546 } 3167 UData_t Div2;
547 3168 UData_t FracN2;
548 if (pPrevNode != NULL) 3169 U8Data tmpOneShot;
549 { 3170 U8Data restore = 0;
550 pNode->next_ = pPrevNode->next_; 3171
551 pPrevNode->next_ = pNode; 3172 /* Buffer the queue for restoration later and get actual LO2 values. */
552 } 3173 status |=
553 else /* insert at the beginning of the list */ 3174 MT2063_ReadSub(pInfo->hUserData,
554 { 3175 pInfo->address,
555 pNode->next_ = pAS_Info->usedZones; 3176 MT2063_REG_LO1CQ_1,
556 pAS_Info->usedZones = pNode; 3177 &(tempLO1CQ[0]), 2);
557 } 3178 status |=
558 3179 MT2063_ReadSub(pInfo->hUserData,
559 pAS_Info->nZones++; 3180 pInfo->address,
560 return pNode; 3181 MT2063_REG_LO1C_1,
561} 3182 &(tempLO1C[0]), 2);
562 3183
563 3184 /* only write the queue values if they are different from the actual. */
564static struct MT2063_ExclZone_t* RemoveNode(struct MT2063_AvoidSpursData_t* pAS_Info, 3185 if ((tempLO1CQ[0] != tempLO1C[0])
565 struct MT2063_ExclZone_t* pPrevNode, 3186 || (tempLO1CQ[1] != tempLO1C[1])) {
566 struct MT2063_ExclZone_t* pNodeToRemove) 3187 /* put actual LO1 value into queue */
567{ 3188 status |=
568 struct MT2063_ExclZone_t* pNext = pNodeToRemove->next_; 3189 MT2063_WriteSub(pInfo->hUserData,
569 3190 pInfo->address,
570 /* Make previous node point to the subsequent node */ 3191 MT2063_REG_LO1CQ_1,
571 if (pPrevNode != NULL) 3192 &(tempLO1C[0]), 2);
572 pPrevNode->next_ = pNext; 3193
573 3194 /* cache the bytes just written. */
574 /* Add pNodeToRemove to the beginning of the freeZones */ 3195 pInfo->reg[MT2063_REG_LO1CQ_1] =
575 pNodeToRemove->next_ = pAS_Info->freeZones; 3196 tempLO1C[0];
576 pAS_Info->freeZones = pNodeToRemove; 3197 pInfo->reg[MT2063_REG_LO1CQ_2] =
577 3198 tempLO1C[1];
578 /* Decrement node count */ 3199 restore = 1;
579 pAS_Info->nZones--; 3200 }
580 3201
581 return pNext; 3202 /* Calculate the Divider and Numberator components of LO2 */
582} 3203 status =
583 3204 MT2063_CalcLO2Mult(&Div2, &FracN2, nValue,
584 3205 pInfo->AS_Data.f_ref /
585/***************************************************************************** 3206 8191,
586** 3207 pInfo->AS_Data.f_ref);
587** Name: MT_AddExclZone 3208 pInfo->reg[MT2063_REG_LO2CQ_1] =
588** 3209 (U8Data) ((Div2 << 1) |
589** Description: Add (and merge) an exclusion zone into the list. 3210 ((FracN2 >> 12) & 0x01)) & 0xFF;
590** If the range (f_min, f_max) is totally outside the 3211 pInfo->reg[MT2063_REG_LO2CQ_2] =
591** 1st IF BW, ignore the entry. 3212 (U8Data) ((FracN2 >> 4) & 0xFF);
592** If the range (f_min, f_max) is negative, ignore the entry. 3213 pInfo->reg[MT2063_REG_LO2CQ_3] =
593** 3214 (U8Data) ((FracN2 & 0x0F));
594** Revision History: 3215 status |=
595** 3216 MT2063_WriteSub(pInfo->hUserData,
596** SCR Date Author Description 3217 pInfo->address,
597** ------------------------------------------------------------------------- 3218 MT2063_REG_LO1CQ_1,
598** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range 3219 &pInfo->
599** (f_min, f_max) < 0, ignore the entry. 3220 reg[MT2063_REG_LO1CQ_1], 3);
600** 3221
601*****************************************************************************/ 3222 /* set the one-shot bit to load the LO values */
602void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t* pAS_Info, 3223 tmpOneShot =
603 UData_t f_min, 3224 pInfo->reg[MT2063_REG_LO2CQ_3] | 0xE0;
604 UData_t f_max) 3225 status |=
605{ 3226 MT2063_WriteSub(pInfo->hUserData,
606 struct MT2063_ExclZone_t* pNode = pAS_Info->usedZones; 3227 pInfo->address,
607 struct MT2063_ExclZone_t* pPrev = NULL; 3228 MT2063_REG_LO2CQ_3,
608 struct MT2063_ExclZone_t* pNext = NULL; 3229 &tmpOneShot, 1);
609 3230
610 /* Check to see if this overlaps the 1st IF filter */ 3231 /* only restore LO1 queue value if they were different from the actual. */
611 if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2))) 3232 if (restore) {
612 && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2))) 3233 /* put previous LO1 queue value back into queue */
613 && (f_min < f_max)) 3234 status |=
614 { 3235 MT2063_WriteSub(pInfo->hUserData,
615 /* 3236 pInfo->address,
616 ** 1 2 3 4 5 6 3237 MT2063_REG_LO1CQ_1,
617 ** 3238 &(tempLO1CQ[0]), 2);
618 ** New entry: |---| |--| |--| |-| |---| |--| 3239
619 ** or or or or or 3240 /* cache the bytes just written. */
620 ** Existing: |--| |--| |--| |---| |-| |--| 3241 pInfo->reg[MT2063_REG_LO1CQ_1] =
621 */ 3242 tempLO1CQ[0];
622 3243 pInfo->reg[MT2063_REG_LO1CQ_2] =
623 /* Check for our place in the list */ 3244 tempLO1CQ[1];
624 while ((pNode != NULL) && (pNode->max_ < f_min)) 3245 }
625 { 3246
626 pPrev = pNode; 3247 MT2063_GetParam(pInfo->hUserData,
627 pNode = pNode->next_; 3248 MT2063_LO2_FREQ,
628 } 3249 &pInfo->AS_Data.f_LO2);
629 3250 }
630 if ((pNode != NULL) && (pNode->min_ < f_max)) 3251 break;
631 { 3252
632 /* Combine me with pNode */ 3253 /* LO2 minimum step size */
633 if (f_min < pNode->min_) 3254 case MT2063_LO2_STEPSIZE:
634 pNode->min_ = f_min; 3255 pInfo->AS_Data.f_LO2_Step = nValue;
635 if (f_max > pNode->max_) 3256 break;
636 pNode->max_ = f_max; 3257
637 } 3258 /* LO2 FracN keep-out region */
638 else 3259 case MT2063_LO2_FRACN_AVOID:
639 { 3260 pInfo->AS_Data.f_LO2_FracN_Avoid = nValue;
640 pNode = InsertNode(pAS_Info, pPrev); 3261 break;
641 pNode->min_ = f_min; 3262
642 pNode->max_ = f_max; 3263 /* output center frequency */
643 } 3264 case MT2063_OUTPUT_FREQ:
644 3265 pInfo->AS_Data.f_out = nValue;
645 /* Look for merging possibilities */ 3266 break;
646 pNext = pNode->next_; 3267
647 while ((pNext != NULL) && (pNext->min_ < pNode->max_)) 3268 /* output bandwidth */
648 { 3269 case MT2063_OUTPUT_BW:
649 if (pNext->max_ > pNode->max_) 3270 pInfo->AS_Data.f_out_bw = nValue + 750000;
650 pNode->max_ = pNext->max_; 3271 break;
651 pNext = RemoveNode(pAS_Info, pNode, pNext); /* Remove pNext, return ptr to pNext->next */ 3272
652 } 3273 /* min inter-tuner LO separation */
653 } 3274 case MT2063_LO_SEPARATION:
654} 3275 pInfo->AS_Data.f_min_LO_Separation = nValue;
655 3276 break;
656 3277
657/***************************************************************************** 3278 /* max # of intra-tuner harmonics */
658** 3279 case MT2063_MAX_HARM1:
659** Name: MT_ChooseFirstIF 3280 pInfo->AS_Data.maxH1 = nValue;
660** 3281 break;
661** Description: Choose the best available 1st IF 3282
662** If f_Desired is not excluded, choose that first. 3283 /* max # of inter-tuner harmonics */
663** Otherwise, return the value closest to f_Center that is 3284 case MT2063_MAX_HARM2:
664** not excluded 3285 pInfo->AS_Data.maxH2 = nValue;
665** 3286 break;
666** Revision History: 3287
667** 3288 case MT2063_RCVR_MODE:
668** SCR Date Author Description 3289 status |=
669** ------------------------------------------------------------------------- 3290 MT2063_SetReceiverMode(pInfo,
670** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from 3291 (enum MT2063_RCVR_MODES)
671** tuner DLL. 3292 nValue);
672** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+) 3293 break;
673** Added logic to force f_Center within 1/2 f_Step. 3294
674** 3295 /* Set LNA Rin -- nValue is desired value */
675*****************************************************************************/ 3296 case MT2063_LNA_RIN:
676UData_t MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t* pAS_Info) 3297 val =
677{ 3298 (pInfo->
678 /* 3299 reg[MT2063_REG_CTRL_2C] & (U8Data) ~ 0x03) |
679 ** Update "f_Desired" to be the nearest "combinational-multiple" of "f_LO1_Step". 3300 (nValue & 0x03);
680 ** The resulting number, F_LO1 must be a multiple of f_LO1_Step. And F_LO1 is the arithmetic sum 3301 if (pInfo->reg[MT2063_REG_CTRL_2C] != val) {
681 ** of f_in + f_Center. Neither f_in, nor f_Center must be a multiple of f_LO1_Step. 3302 status |=
682 ** However, the sum must be. 3303 MT2063_SetReg(pInfo, MT2063_REG_CTRL_2C,
683 */ 3304 val);
684 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; 3305 }
685 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; 3306 break;
686 UData_t f_Center; 3307
687 3308 /* Set target power level at LNA -- nValue is desired value */
688 SData_t i; 3309 case MT2063_LNA_TGT:
689 SData_t j = 0; 3310 val =
690 UData_t bDesiredExcluded = 0; 3311 (pInfo->
691 UData_t bZeroExcluded = 0; 3312 reg[MT2063_REG_LNA_TGT] & (U8Data) ~ 0x3F) |
692 SData_t tmpMin, tmpMax; 3313 (nValue & 0x3F);
693 SData_t bestDiff; 3314 if (pInfo->reg[MT2063_REG_LNA_TGT] != val) {
694 struct MT2063_ExclZone_t* pNode = pAS_Info->usedZones; 3315 status |=
695 struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES]; 3316 MT2063_SetReg(pInfo, MT2063_REG_LNA_TGT,
696 3317 val);
697 if (pAS_Info->nZones == 0) 3318 }
698 return f_Desired; 3319 break;
699 3320
700 /* f_Center needs to be an integer multiple of f_Step away from f_Desired */ 3321 /* Set target power level at PD1 -- nValue is desired value */
701 if (pAS_Info->f_if1_Center > f_Desired) 3322 case MT2063_PD1_TGT:
702 f_Center = f_Desired + f_Step * ((pAS_Info->f_if1_Center - f_Desired + f_Step/2) / f_Step); 3323 val =
703 else 3324 (pInfo->
704 f_Center = f_Desired - f_Step * ((f_Desired - pAS_Info->f_if1_Center + f_Step/2) / f_Step); 3325 reg[MT2063_REG_PD1_TGT] & (U8Data) ~ 0x3F) |
705 3326 (nValue & 0x3F);
706 //assert; 3327 if (pInfo->reg[MT2063_REG_PD1_TGT] != val) {
707 //if (!abs((SData_t) f_Center - (SData_t) pAS_Info->f_if1_Center) <= (SData_t) (f_Step/2)) 3328 status |=
708 // return 0; 3329 MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT,
709 3330 val);
710 /* Take MT_ExclZones, center around f_Center and change the resolution to f_Step */ 3331 }
711 while (pNode != NULL) 3332 break;
712 { 3333
713 /* floor function */ 3334 /* Set target power level at PD2 -- nValue is desired value */
714 tmpMin = floor((SData_t) (pNode->min_ - f_Center), (SData_t) f_Step); 3335 case MT2063_PD2_TGT:
715 3336 val =
716 /* ceil function */ 3337 (pInfo->
717 tmpMax = ceil((SData_t) (pNode->max_ - f_Center), (SData_t) f_Step); 3338 reg[MT2063_REG_PD2_TGT] & (U8Data) ~ 0x3F) |
718 3339 (nValue & 0x3F);
719 if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired)) 3340 if (pInfo->reg[MT2063_REG_PD2_TGT] != val) {
720 bDesiredExcluded = 1; 3341 status |=
721 3342 MT2063_SetReg(pInfo, MT2063_REG_PD2_TGT,
722 if ((tmpMin < 0) && (tmpMax > 0)) 3343 val);
723 bZeroExcluded = 1; 3344 }
724 3345 break;
725 /* See if this zone overlaps the previous */ 3346
726 if ((j>0) && (tmpMin < zones[j-1].max_)) 3347 /* Set LNA atten limit -- nValue is desired value */
727 zones[j-1].max_ = tmpMax; 3348 case MT2063_ACLNA_MAX:
728 else 3349 val =
729 { 3350 (pInfo->
730 /* Add new zone */ 3351 reg[MT2063_REG_LNA_OV] & (U8Data) ~ 0x1F) | (nValue
731 //assert(j<MT2063_MAX_ZONES); 3352 &
732 //if (j>=MT2063_MAX_ZONES) 3353 0x1F);
733 //break; 3354 if (pInfo->reg[MT2063_REG_LNA_OV] != val) {
734 3355 status |=
735 zones[j].min_ = tmpMin; 3356 MT2063_SetReg(pInfo, MT2063_REG_LNA_OV,
736 zones[j].max_ = tmpMax; 3357 val);
737 j++; 3358 }
738 } 3359 break;
739 pNode = pNode->next_; 3360
740 } 3361 /* Set RF atten limit -- nValue is desired value */
741 3362 case MT2063_ACRF_MAX:
742 /* 3363 val =
743 ** If the desired is okay, return with it 3364 (pInfo->
744 */ 3365 reg[MT2063_REG_RF_OV] & (U8Data) ~ 0x1F) | (nValue
745 if (bDesiredExcluded == 0) 3366 &
746 return f_Desired; 3367 0x1F);
747 3368 if (pInfo->reg[MT2063_REG_RF_OV] != val) {
748 /* 3369 status |=
749 ** If the desired is excluded and the center is okay, return with it 3370 MT2063_SetReg(pInfo, MT2063_REG_RF_OV, val);
750 */ 3371 }
751 if (bZeroExcluded == 0) 3372 break;
752 return f_Center; 3373
753 3374 /* Set FIF atten limit -- nValue is desired value, max. 5 if no B3 */
754 /* Find the value closest to 0 (f_Center) */ 3375 case MT2063_ACFIF_MAX:
755 bestDiff = zones[0].min_; 3376 if (pInfo->reg[MT2063_REG_PART_REV] != MT2063_B3
756 for (i=0; i<j; i++) 3377 && nValue > 5)
757 { 3378 nValue = 5;
758 if (abs(zones[i].min_) < abs(bestDiff)) bestDiff = zones[i].min_; 3379 val =
759 if (abs(zones[i].max_) < abs(bestDiff)) bestDiff = zones[i].max_; 3380 (pInfo->
760 } 3381 reg[MT2063_REG_FIF_OV] & (U8Data) ~ 0x1F) | (nValue
761 3382 &
762 3383 0x1F);
763 if (bestDiff < 0) 3384 if (pInfo->reg[MT2063_REG_FIF_OV] != val) {
764 return f_Center - ((UData_t) (-bestDiff) * f_Step); 3385 status |=
765 3386 MT2063_SetReg(pInfo, MT2063_REG_FIF_OV,
766 return f_Center + (bestDiff * f_Step); 3387 val);
767} 3388 }
768 3389 break;
769 3390
770/**************************************************************************** 3391 case MT2063_DNC_OUTPUT_ENABLE:
771** 3392 /* selects, which DNC output is used */
772** Name: gcd 3393 switch ((enum MT2063_DNC_Output_Enable)nValue) {
773** 3394 case MT2063_DNC_NONE:
774** Description: Uses Euclid's algorithm 3395 {
775** 3396 val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */
776** Parameters: u, v - unsigned values whose GCD is desired. 3397 if (pInfo->reg[MT2063_REG_DNC_GAIN] !=
777** 3398 val)
778** Global: None 3399 status |=
779** 3400 MT2063_SetReg(h,
780** Returns: greatest common divisor of u and v, if either value 3401 MT2063_REG_DNC_GAIN,
781** is 0, the other value is returned as the result. 3402 val);
782** 3403
783** Dependencies: None. 3404 val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */
784** 3405 if (pInfo->reg[MT2063_REG_VGA_GAIN] !=
785** Revision History: 3406 val)
786** 3407 status |=
787** SCR Date Author Description 3408 MT2063_SetReg(h,
788** ------------------------------------------------------------------------- 3409 MT2063_REG_VGA_GAIN,
789** N/A 06-01-2004 JWS Original 3410 val);
790** N/A 08-03-2004 DAD Changed to Euclid's since it can handle 3411
791** unsigned numbers. 3412 val = (pInfo->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
792** 3413 if (pInfo->reg[MT2063_REG_RSVD_20] !=
793****************************************************************************/ 3414 val)
794static UData_t MT2063_gcd(UData_t u, UData_t v) 3415 status |=
795{ 3416 MT2063_SetReg(h,
796 UData_t r; 3417 MT2063_REG_RSVD_20,
797 3418 val);
798 while (v != 0) 3419
799 { 3420 break;
800 r = u % v; 3421 }
801 u = v; 3422 case MT2063_DNC_1:
802 v = r; 3423 {
803 } 3424 val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */
804 3425 if (pInfo->reg[MT2063_REG_DNC_GAIN] !=
805 return u; 3426 val)
806} 3427 status |=
807 3428 MT2063_SetReg(h,
808/**************************************************************************** 3429 MT2063_REG_DNC_GAIN,
809** 3430 val);
810** Name: umax 3431
811** 3432 val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */
812** Description: Implements a simple maximum function for unsigned numbers. 3433 if (pInfo->reg[MT2063_REG_VGA_GAIN] !=
813** Implemented as a function rather than a macro to avoid 3434 val)
814** multiple evaluation of the calling parameters. 3435 status |=
815** 3436 MT2063_SetReg(h,
816** Parameters: a, b - Values to be compared 3437 MT2063_REG_VGA_GAIN,
817** 3438 val);
818** Global: None 3439
819** 3440 val = (pInfo->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
820** Returns: larger of the input values. 3441 if (pInfo->reg[MT2063_REG_RSVD_20] !=
821** 3442 val)
822** Dependencies: None. 3443 status |=
823** 3444 MT2063_SetReg(h,
824** Revision History: 3445 MT2063_REG_RSVD_20,
825** 3446 val);
826** SCR Date Author Description 3447
827** ------------------------------------------------------------------------- 3448 break;
828** N/A 06-02-2004 JWS Original 3449 }
829** 3450 case MT2063_DNC_2:
830****************************************************************************/ 3451 {
831static UData_t MT2063_umax(UData_t a, UData_t b) 3452 val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */
832{ 3453 if (pInfo->reg[MT2063_REG_DNC_GAIN] !=
833 return (a >= b) ? a : b; 3454 val)
834} 3455 status |=
835 3456 MT2063_SetReg(h,
836#if MT2063_TUNER_CNT > 1 3457 MT2063_REG_DNC_GAIN,
837static SData_t RoundAwayFromZero(SData_t n, SData_t d) 3458 val);
838{ 3459
839 return (n<0) ? floor(n, d) : ceil(n, d); 3460 val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */
840} 3461 if (pInfo->reg[MT2063_REG_VGA_GAIN] !=
841 3462 val)
842/**************************************************************************** 3463 status |=
843** 3464 MT2063_SetReg(h,
844** Name: IsSpurInAdjTunerBand 3465 MT2063_REG_VGA_GAIN,
845** 3466 val);
846** Description: Checks to see if a spur will be present within the IF's 3467
847** bandwidth or near the zero IF. 3468 val = (pInfo->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
848** (fIFOut +/- fIFBW/2, -fIFOut +/- fIFBW/2) 3469 if (pInfo->reg[MT2063_REG_RSVD_20] !=
849** and 3470 val)
850** (0 +/- fZIFBW/2) 3471 status |=
851** 3472 MT2063_SetReg(h,
852** ma mb me mf mc md 3473 MT2063_REG_RSVD_20,
853** <--+-+-+-----------------+-+-+-----------------+-+-+--> 3474 val);
854** | ^ 0 ^ | 3475
855** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ 3476 break;
856** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 3477 }
857** 3478 case MT2063_DNC_BOTH:
858** Note that some equations are doubled to prevent round-off 3479 {
859** problems when calculating fIFBW/2 3480 val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */
860** 3481 if (pInfo->reg[MT2063_REG_DNC_GAIN] !=
861** The spur frequencies are computed as: 3482 val)
862** 3483 status |=
863** fSpur = n * f1 - m * f2 - fOffset 3484 MT2063_SetReg(h,
864** 3485 MT2063_REG_DNC_GAIN,
865** Parameters: f1 - The 1st local oscillator (LO) frequency 3486 val);
866** of the tuner whose output we are examining 3487
867** f2 - The 1st local oscillator (LO) frequency 3488 val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */
868** of the adjacent tuner 3489 if (pInfo->reg[MT2063_REG_VGA_GAIN] !=
869** fOffset - The 2nd local oscillator of the tuner whose 3490 val)
870** output we are examining 3491 status |=
871** fIFOut - Output IF center frequency 3492 MT2063_SetReg(h,
872** fIFBW - Output IF Bandwidth 3493 MT2063_REG_VGA_GAIN,
873** nMaxH - max # of LO harmonics to search 3494 val);
874** fp - If spur, positive distance to spur-free band edge (returned) 3495
875** fm - If spur, negative distance to spur-free band edge (returned) 3496 val = (pInfo->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
876** 3497 if (pInfo->reg[MT2063_REG_RSVD_20] !=
877** Returns: 1 if an LO spur would be present, otherwise 0. 3498 val)
878** 3499 status |=
879** Dependencies: None. 3500 MT2063_SetReg(h,
880** 3501 MT2063_REG_RSVD_20,
881** Revision History: 3502 val);
882** 3503
883** SCR Date Author Description 3504 break;
884** ------------------------------------------------------------------------- 3505 }
885** N/A 01-21-2005 JWS Original, adapted from MT_DoubleConversion. 3506 default:
886** 115 03-23-2007 DAD Fix declaration of spur due to truncation 3507 break;
887** errors. 3508 }
888** 137 06-18-2007 DAD Ver 1.16: Fix possible divide-by-0 error for 3509 break;
889** multi-tuners that have 3510
890** (delta IF1) > (f_out-f_outbw/2). 3511 case MT2063_VGAGC:
891** 177 S 02-26-2008 RSK Ver 1.18: Corrected calculation using LO1 > MAX/2 3512 /* Set VGA gain code */
892** Type casts added to preserve correct sign. 3513 val =
893** 3514 (pInfo->
894****************************************************************************/ 3515 reg[MT2063_REG_VGA_GAIN] & (U8Data) ~ 0x0C) |
895static UData_t IsSpurInAdjTunerBand(UData_t bIsMyOutput, 3516 ((nValue & 0x03) << 2);
896 UData_t f1, 3517 if (pInfo->reg[MT2063_REG_VGA_GAIN] != val) {
897 UData_t f2, 3518 status |=
898 UData_t fOffset, 3519 MT2063_SetReg(pInfo, MT2063_REG_VGA_GAIN,
899 UData_t fIFOut, 3520 val);
900 UData_t fIFBW, 3521 }
901 UData_t fZIFBW, 3522 break;
902 UData_t nMaxH, 3523
903 UData_t *fp, 3524 case MT2063_VGAOI:
904 UData_t *fm) 3525 /* Set VGA bias current */
905{ 3526 val =
906 UData_t bSpurFound = 0; 3527 (pInfo->
907 3528 reg[MT2063_REG_RSVD_31] & (U8Data) ~ 0x07) |
908 const UData_t fHalf_IFBW = fIFBW / 2; 3529 (nValue & 0x07);
909 const UData_t fHalf_ZIFBW = fZIFBW / 2; 3530 if (pInfo->reg[MT2063_REG_RSVD_31] != val) {
910 3531 status |=
911 /* Calculate a scale factor for all frequencies, so that our 3532 MT2063_SetReg(pInfo, MT2063_REG_RSVD_31,
912 calculations all stay within 31 bits */ 3533 val);
913 const UData_t f_Scale = ((f1 + (fOffset + fIFOut + fHalf_IFBW) / nMaxH) / (MAX_UDATA/2 / nMaxH)) + 1; 3534 }
914 3535 break;
915 /* 3536
916 ** After this scaling, _f1, _f2, and _f3 are guaranteed to fit into 3537 case MT2063_TAGC:
917 ** signed data types (smaller than MAX_UDATA/2) 3538 /* Set TAGC */
918 */ 3539 val =
919 const SData_t _f1 = (SData_t) ( f1 / f_Scale); 3540 (pInfo->
920 const SData_t _f2 = (SData_t) ( f2 / f_Scale); 3541 reg[MT2063_REG_RSVD_1E] & (U8Data) ~ 0x03) |
921 const SData_t _f3 = (SData_t) (fOffset / f_Scale); 3542 (nValue & 0x03);
922 3543 if (pInfo->reg[MT2063_REG_RSVD_1E] != val) {
923 const SData_t c = (SData_t) (fIFOut - fHalf_IFBW) / (SData_t) f_Scale; 3544 status |=
924 const SData_t d = (SData_t) ((fIFOut + fHalf_IFBW) / f_Scale); 3545 MT2063_SetReg(pInfo, MT2063_REG_RSVD_1E,
925 const SData_t f = (SData_t) (fHalf_ZIFBW / f_Scale); 3546 val);
926 3547 }
927 SData_t ma, mb, mc, md, me, mf; 3548 break;
928 3549
929 SData_t fp_ = 0; 3550 case MT2063_AMPGC:
930 SData_t fm_ = 0; 3551 /* Set Amp gain code */
931 SData_t n; 3552 val =
932 3553 (pInfo->
933 3554 reg[MT2063_REG_TEMP_SEL] & (U8Data) ~ 0x03) |
934 /* 3555 (nValue & 0x03);
935 ** If the other tuner does not have an LO frequency defined, 3556 if (pInfo->reg[MT2063_REG_TEMP_SEL] != val) {
936 ** assume that we cannot interfere with it 3557 status |=
937 */ 3558 MT2063_SetReg(pInfo, MT2063_REG_TEMP_SEL,
938 if (f2 == 0) 3559 val);
939 return 0; 3560 }
940 3561 break;
941 3562
942 /* Check out all multiples of f1 from -nMaxH to +nMaxH */ 3563 /* Avoid DECT Frequencies */
943 for (n = -(SData_t)nMaxH; n <= (SData_t)nMaxH; ++n) 3564 case MT2063_AVOID_DECT:
944 { 3565 {
945 const SData_t nf1 = n*_f1; 3566 enum MT2063_DECT_Avoid_Type newAvoidSetting =
946 md = (_f3 + d - nf1) / _f2; 3567 (enum MT2063_DECT_Avoid_Type)nValue;
947 3568 if ((newAvoidSetting >=
948 /* If # f2 harmonics > nMaxH, then no spurs present */ 3569 MT2063_NO_DECT_AVOIDANCE)
949 if (md <= -(SData_t) nMaxH ) 3570 && (newAvoidSetting <= MT2063_AVOID_BOTH)) {
950 break; 3571 pInfo->AS_Data.avoidDECT =
951 3572 newAvoidSetting;
952 ma = (_f3 - d - nf1) / _f2; 3573 }
953 if ((ma == md) || (ma >= (SData_t) (nMaxH))) 3574 }
954 continue; 3575 break;
955 3576
956 mc = (_f3 + c - nf1) / _f2; 3577 /* Cleartune filter selection: 0 - by IC (default), 1 - by software */
957 if (mc != md) 3578 case MT2063_CTFILT_SW:
958 { 3579 pInfo->ctfilt_sw = (nValue & 0x01);
959 const SData_t m = (n<0) ? md : mc; 3580 break;
960 const SData_t fspur = (nf1 + m*_f2 - _f3); 3581
961 const SData_t den = (bIsMyOutput ? n - 1 : n); 3582 /* These parameters are read-only */
962 if (den == 0) 3583 case MT2063_IC_ADDR:
963 { 3584 case MT2063_MAX_OPEN:
964 fp_ = (d - fspur)* f_Scale; 3585 case MT2063_NUM_OPEN:
965 fm_ = (fspur - c)* f_Scale; 3586 case MT2063_INPUT_FREQ:
966 } 3587 case MT2063_IF1_ACTUAL:
967 else 3588 case MT2063_IF1_CENTER:
968 { 3589 case MT2063_IF1_BW:
969 fp_ = (SData_t) RoundAwayFromZero((d - fspur)* f_Scale, den); 3590 case MT2063_AS_ALG:
970 fm_ = (SData_t) RoundAwayFromZero((fspur - c)* f_Scale, den); 3591 case MT2063_EXCL_ZONES:
971 } 3592 case MT2063_SPUR_AVOIDED:
972 if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) 3593 case MT2063_NUM_SPURS:
973 { 3594 case MT2063_SPUR_PRESENT:
974 bSpurFound = 1; 3595 case MT2063_ACLNA:
975 break; 3596 case MT2063_ACRF:
976 } 3597 case MT2063_ACFIF:
977 } 3598 case MT2063_EOP:
978 3599 default:
979 /* Location of Zero-IF-spur to be checked */ 3600 status |= MT2063_ARG_RANGE;
980 mf = (_f3 + f - nf1) / _f2; 3601 }
981 me = (_f3 - f - nf1) / _f2; 3602 }
982 if (me != mf) 3603 return (status);
983 { 3604}
984 const SData_t m = (n<0) ? mf : me; 3605
985 const SData_t fspur = (nf1 + m*_f2 - _f3); 3606/****************************************************************************
986 const SData_t den = (bIsMyOutput ? n - 1 : n); 3607**
987 if (den == 0) 3608** Name: MT2063_SetPowerMaskBits
988 { 3609**
989 fp_ = (d - fspur)* f_Scale; 3610** Description: Sets the power-down mask bits for various sections of
990 fm_ = (fspur - c)* f_Scale; 3611** the MT2063
991 } 3612**
992 else 3613** Parameters: h - Tuner handle (returned by MT2063_Open)
993 { 3614** Bits - Mask bits to be set.
994 fp_ = (SData_t) RoundAwayFromZero((f - fspur)* f_Scale, den); 3615**
995 fm_ = (SData_t) RoundAwayFromZero((fspur + f)* f_Scale, den); 3616** See definition of MT2063_Mask_Bits type for description
996 } 3617** of each of the power bits.
997 if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) 3618**
998 { 3619** Returns: status:
999 bSpurFound = 1; 3620** MT_OK - No errors
1000 break; 3621** MT_INV_HANDLE - Invalid tuner handle
1001 } 3622** MT_COMM_ERR - Serial bus communications error
1002 } 3623**
1003 3624** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
1004 mb = (_f3 - c - nf1) / _f2; 3625**
1005 if (ma != mb) 3626** Revision History:
1006 { 3627**
1007 const SData_t m = (n<0) ? mb : ma; 3628** SCR Date Author Description
1008 const SData_t fspur = (nf1 + m*_f2 - _f3); 3629** -------------------------------------------------------------------------
1009 const SData_t den = (bIsMyOutput ? n - 1 : n); 3630** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1010 if (den == 0) 3631**
1011 { 3632****************************************************************************/
1012 fp_ = (d - fspur)* f_Scale; 3633UData_t MT2063_SetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits)
1013 fm_ = (fspur - c)* f_Scale; 3634{
1014 } 3635 UData_t status = MT2063_OK; /* Status to be returned */
1015 else 3636 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1016 { 3637
1017 fp_ = (SData_t) RoundAwayFromZero((-c - fspur)* f_Scale, den); 3638 /* Verify that the handle passed points to a valid tuner */
1018 fm_ = (SData_t) RoundAwayFromZero((fspur +d)* f_Scale, den); 3639 if (MT2063_IsValidHandle(pInfo) == 0)
1019 } 3640 status = MT2063_INV_HANDLE;
1020 if (((UData_t)abs(fm_) >= f_Scale) && ((UData_t)abs(fp_) >= f_Scale)) 3641 else {
1021 { 3642 Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
1022 bSpurFound = 1; 3643 if ((Bits & 0xFF00) != 0) {
1023 break; 3644 pInfo->reg[MT2063_REG_PWR_2] |=
1024 } 3645 (U8Data) ((Bits & 0xFF00) >> 8);
1025 } 3646 status |=
1026 } 3647 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
1027 3648 MT2063_REG_PWR_2,
1028 /* 3649 &pInfo->reg[MT2063_REG_PWR_2], 1);
1029 ** Verify that fm & fp are both positive 3650 }
1030 ** Add one to ensure next 1st IF choice is not right on the edge 3651 if ((Bits & 0xFF) != 0) {
1031 */ 3652 pInfo->reg[MT2063_REG_PWR_1] |= ((U8Data) Bits & 0xFF);
1032 if (fp_ < 0) 3653 status |=
1033 { 3654 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
1034 *fp = -fm_ + 1; 3655 MT2063_REG_PWR_1,
1035 *fm = -fp_ + 1; 3656 &pInfo->reg[MT2063_REG_PWR_1], 1);
1036 } 3657 }
1037 else if (fp_ > 0) 3658 }
1038 { 3659
1039 *fp = fp_ + 1; 3660 return (status);
1040 *fm = fm_ + 1; 3661}
1041 } 3662
1042 else 3663/****************************************************************************
1043 { 3664**
1044 *fp = 1; 3665** Name: MT2063_ClearPowerMaskBits
1045 *fm = abs(fm_) + 1; 3666**
1046 } 3667** Description: Clears the power-down mask bits for various sections of
1047 3668** the MT2063
1048 return bSpurFound; 3669**
1049} 3670** Parameters: h - Tuner handle (returned by MT2063_Open)
1050#endif 3671** Bits - Mask bits to be cleared.
1051 3672**
1052/**************************************************************************** 3673** See definition of MT2063_Mask_Bits type for description
1053** 3674** of each of the power bits.
1054** Name: IsSpurInBand 3675**
1055** 3676** Returns: status:
1056** Description: Checks to see if a spur will be present within the IF's 3677** MT_OK - No errors
1057** bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW) 3678** MT_INV_HANDLE - Invalid tuner handle
1058** 3679** MT_COMM_ERR - Serial bus communications error
1059** ma mb mc md 3680**
1060** <--+-+-+-------------------+-------------------+-+-+--> 3681** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
1061** | ^ 0 ^ | 3682**
1062** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^ 3683** Revision History:
1063** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2 3684**
1064** 3685** SCR Date Author Description
1065** Note that some equations are doubled to prevent round-off 3686** -------------------------------------------------------------------------
1066** problems when calculating fIFBW/2 3687** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1067** 3688**
1068** Parameters: pAS_Info - Avoid Spurs information block 3689****************************************************************************/
1069** fm - If spur, amount f_IF1 has to move negative 3690UData_t MT2063_ClearPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits)
1070** fp - If spur, amount f_IF1 has to move positive 3691{
1071** 3692 UData_t status = MT2063_OK; /* Status to be returned */
1072** Global: None 3693 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1073** 3694
1074** Returns: 1 if an LO spur would be present, otherwise 0. 3695 /* Verify that the handle passed points to a valid tuner */
1075** 3696 if (MT2063_IsValidHandle(pInfo) == 0)
1076** Dependencies: None. 3697 status = MT2063_INV_HANDLE;
1077** 3698 else {
1078** Revision History: 3699 Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
1079** 3700 if ((Bits & 0xFF00) != 0) {
1080** SCR Date Author Description 3701 pInfo->reg[MT2063_REG_PWR_2] &= ~(U8Data) (Bits >> 8);
1081** ------------------------------------------------------------------------- 3702 status |=
1082** N/A 11-28-2002 DAD Implemented algorithm from applied patent 3703 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
1083** 3704 MT2063_REG_PWR_2,
1084****************************************************************************/ 3705 &pInfo->reg[MT2063_REG_PWR_2], 1);
1085static UData_t IsSpurInBand(struct MT2063_AvoidSpursData_t* pAS_Info, 3706 }
1086 UData_t* fm, 3707 if ((Bits & 0xFF) != 0) {
1087 UData_t* fp) 3708 pInfo->reg[MT2063_REG_PWR_1] &= ~(U8Data) (Bits & 0xFF);
1088{ 3709 status |=
1089 /* 3710 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
1090 ** Calculate LO frequency settings. 3711 MT2063_REG_PWR_1,
1091 */ 3712 &pInfo->reg[MT2063_REG_PWR_1], 1);
1092 UData_t n, n0; 3713 }
1093 const UData_t f_LO1 = pAS_Info->f_LO1; 3714 }
1094 const UData_t f_LO2 = pAS_Info->f_LO2; 3715
1095 const UData_t d = pAS_Info->f_out + pAS_Info->f_out_bw/2; 3716 return (status);
1096 const UData_t c = d - pAS_Info->f_out_bw; 3717}
1097 const UData_t f = pAS_Info->f_zif_bw/2; 3718
1098 const UData_t f_Scale = (f_LO1 / (MAX_UDATA/2 / pAS_Info->maxH1)) + 1; 3719/****************************************************************************
1099 SData_t f_nsLO1, f_nsLO2; 3720**
1100 SData_t f_Spur; 3721** Name: MT2063_GetPowerMaskBits
1101 UData_t ma, mb, mc, md, me, mf; 3722**
1102 UData_t lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs; 3723** Description: Returns a mask of the enabled power shutdown bits
1103#if MT2063_TUNER_CNT > 1 3724**
1104 UData_t index; 3725** Parameters: h - Tuner handle (returned by MT2063_Open)
1105 3726** Bits - Mask bits to currently set.
1106 struct MT2063_AvoidSpursData_t *adj; 3727**
1107#endif 3728** See definition of MT2063_Mask_Bits type for description
1108 *fm = 0; 3729** of each of the power bits.
1109 3730**
1110 /* 3731** Returns: status:
1111 ** For each edge (d, c & f), calculate a scale, based on the gcd 3732** MT_OK - No errors
1112 ** of f_LO1, f_LO2 and the edge value. Use the larger of this 3733** MT_INV_HANDLE - Invalid tuner handle
1113 ** gcd-based scale factor or f_Scale. 3734** MT_ARG_NULL - Output argument is NULL
1114 */ 3735** MT_COMM_ERR - Serial bus communications error
1115 lo_gcd = MT2063_gcd(f_LO1, f_LO2); 3736**
1116 gd_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, d), f_Scale); 3737** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
1117 hgds = gd_Scale/2; 3738**
1118 gc_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, c), f_Scale); 3739** Revision History:
1119 hgcs = gc_Scale/2; 3740**
1120 gf_Scale = MT2063_umax((UData_t) MT2063_gcd(lo_gcd, f), f_Scale); 3741** SCR Date Author Description
1121 hgfs = gf_Scale/2; 3742** -------------------------------------------------------------------------
1122 3743** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1123 n0 = uceil(f_LO2 - d, f_LO1 - f_LO2); 3744**
1124 3745****************************************************************************/
1125 /* Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic */ 3746UData_t MT2063_GetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits * Bits)
1126 for (n=n0; n<=pAS_Info->maxH1; ++n) 3747{
1127 { 3748 UData_t status = MT2063_OK; /* Status to be returned */
1128 md = (n*((f_LO1+hgds)/gd_Scale) - ((d+hgds)/gd_Scale)) / ((f_LO2+hgds)/gd_Scale); 3749 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1129 3750
1130 /* If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present */ 3751 /* Verify that the handle passed points to a valid tuner */
1131 if (md >= pAS_Info->maxH1) 3752 if (MT2063_IsValidHandle(pInfo) == 0)
1132 break; 3753 status = MT2063_INV_HANDLE;
1133 3754 else {
1134 ma = (n*((f_LO1+hgds)/gd_Scale) + ((d+hgds)/gd_Scale)) / ((f_LO2+hgds)/gd_Scale); 3755 if (Bits == NULL)
1135 3756 status |= MT2063_ARG_NULL;
1136 /* If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic */ 3757
1137 if (md == ma) 3758 if (MT2063_NO_ERROR(status))
1138 continue; 3759 status |=
1139 3760 MT2063_ReadSub(pInfo->hUserData, pInfo->address,
1140 mc = (n*((f_LO1+hgcs)/gc_Scale) - ((c+hgcs)/gc_Scale)) / ((f_LO2+hgcs)/gc_Scale); 3761 MT2063_REG_PWR_1,
1141 if (mc != md) 3762 &pInfo->reg[MT2063_REG_PWR_1], 2);
1142 { 3763
1143 f_nsLO1 = (SData_t) (n*(f_LO1/gc_Scale)); 3764 if (MT2063_NO_ERROR(status)) {
1144 f_nsLO2 = (SData_t) (mc*(f_LO2/gc_Scale)); 3765 *Bits =
1145 f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - mc*(f_LO2 % gc_Scale); 3766 (enum
1146 3767 MT2063_Mask_Bits)(((SData_t) pInfo->
1147 *fp = ((f_Spur - (SData_t) c) / (mc - n)) + 1; 3768 reg[MT2063_REG_PWR_2] << 8) +
1148 *fm = (((SData_t) d - f_Spur) / (mc - n)) + 1; 3769 pInfo->reg[MT2063_REG_PWR_1]);
1149 return 1; 3770 *Bits = (enum MT2063_Mask_Bits)(*Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
1150 } 3771 }
1151 3772 }
1152 /* Location of Zero-IF-spur to be checked */ 3773
1153 me = (n*((f_LO1+hgfs)/gf_Scale) + ((f+hgfs)/gf_Scale)) / ((f_LO2+hgfs)/gf_Scale); 3774 return (status);
1154 mf = (n*((f_LO1+hgfs)/gf_Scale) - ((f+hgfs)/gf_Scale)) / ((f_LO2+hgfs)/gf_Scale); 3775}
1155 if (me != mf) 3776
1156 { 3777/****************************************************************************
1157 f_nsLO1 = n*(f_LO1/gf_Scale); 3778**
1158 f_nsLO2 = me*(f_LO2/gf_Scale); 3779** Name: MT2063_EnableExternalShutdown
1159 f_Spur = (gf_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gf_Scale) - me*(f_LO2 % gf_Scale); 3780**
1160 3781** Description: Enables or disables the operation of the external
1161 *fp = ((f_Spur + (SData_t) f) / (me - n)) + 1; 3782** shutdown pin
1162 *fm = (((SData_t) f - f_Spur) / (me - n)) + 1; 3783**
1163 return 1; 3784** Parameters: h - Tuner handle (returned by MT2063_Open)
1164 } 3785** Enabled - 0 = disable the pin, otherwise enable it
1165 3786**
1166 mb = (n*((f_LO1+hgcs)/gc_Scale) + ((c+hgcs)/gc_Scale)) / ((f_LO2+hgcs)/gc_Scale); 3787** Returns: status:
1167 if (ma != mb) 3788** MT_OK - No errors
1168 { 3789** MT_INV_HANDLE - Invalid tuner handle
1169 f_nsLO1 = n*(f_LO1/gc_Scale); 3790** MT_COMM_ERR - Serial bus communications error
1170 f_nsLO2 = ma*(f_LO2/gc_Scale); 3791**
1171 f_Spur = (gc_Scale * (f_nsLO1 - f_nsLO2)) + n*(f_LO1 % gc_Scale) - ma*(f_LO2 % gc_Scale); 3792** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
1172 3793**
1173 *fp = (((SData_t) d + f_Spur) / (ma - n)) + 1; 3794** Revision History:
1174 *fm = (-(f_Spur + (SData_t) c) / (ma - n)) + 1; 3795**
1175 return 1; 3796** SCR Date Author Description
1176 } 3797** -------------------------------------------------------------------------
1177 } 3798** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1178 3799**
1179#if MT2063_TUNER_CNT > 1 3800****************************************************************************/
1180 /* If no spur found, see if there are more tuners on the same board */ 3801UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled)
1181 for (index = 0; index < TunerCount; ++index) 3802{
1182 { 3803 UData_t status = MT2063_OK; /* Status to be returned */
1183 adj = TunerList[index]; 3804 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1184 if (pAS_Info == adj) /* skip over our own data, don't process it */ 3805
1185 continue; 3806 /* Verify that the handle passed points to a valid tuner */
1186 3807 if (MT2063_IsValidHandle(pInfo) == 0)
1187 /* Look for LO-related spurs from the adjacent tuner generated into my IF output */ 3808 status = MT2063_INV_HANDLE;
1188 if (IsSpurInAdjTunerBand(1, /* check my IF output */ 3809 else {
1189 pAS_Info->f_LO1, /* my fLO1 */ 3810 if (Enabled == 0)
1190 adj->f_LO1, /* the other tuner's fLO1 */ 3811 pInfo->reg[MT2063_REG_PWR_1] &= ~0x08; /* Turn off the bit */
1191 pAS_Info->f_LO2, /* my fLO2 */ 3812 else
1192 pAS_Info->f_out, /* my fOut */ 3813 pInfo->reg[MT2063_REG_PWR_1] |= 0x08; /* Turn the bit on */
1193 pAS_Info->f_out_bw, /* my output IF bandwidth */ 3814
1194 pAS_Info->f_zif_bw, /* my Zero-IF bandwidth */ 3815 status |=
1195 pAS_Info->maxH2, 3816 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
1196 fp, /* minimum amount to move LO's positive */ 3817 MT2063_REG_PWR_1,
1197 fm)) /* miminum amount to move LO's negative */ 3818 &pInfo->reg[MT2063_REG_PWR_1], 1);
1198 return 1; 3819 }
1199 /* Look for LO-related spurs from my tuner generated into the adjacent tuner's IF output */ 3820
1200 if (IsSpurInAdjTunerBand(0, /* check his IF output */ 3821 return (status);
1201 pAS_Info->f_LO1, /* my fLO1 */ 3822}
1202 adj->f_LO1, /* the other tuner's fLO1 */ 3823
1203 adj->f_LO2, /* the other tuner's fLO2 */ 3824/****************************************************************************
1204 adj->f_out, /* the other tuner's fOut */ 3825**
1205 adj->f_out_bw, /* the other tuner's output IF bandwidth */ 3826** Name: MT2063_SoftwareShutdown
1206 pAS_Info->f_zif_bw, /* the other tuner's Zero-IF bandwidth */ 3827**
1207 adj->maxH2, 3828** Description: Enables or disables software shutdown function. When
1208 fp, /* minimum amount to move LO's positive */ 3829** Shutdown==1, any section whose power mask is set will be
1209 fm)) /* miminum amount to move LO's negative */ 3830** shutdown.
1210 return 1; 3831**
1211 } 3832** Parameters: h - Tuner handle (returned by MT2063_Open)
1212#endif 3833** Shutdown - 1 = shutdown the masked sections, otherwise
1213 /* No spurs found */ 3834** power all sections on
1214 return 0; 3835**
1215} 3836** Returns: status:
1216 3837** MT_OK - No errors
1217 3838** MT_INV_HANDLE - Invalid tuner handle
1218/***************************************************************************** 3839** MT_COMM_ERR - Serial bus communications error
1219** 3840**
1220** Name: MT_AvoidSpurs 3841** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
1221** 3842**
1222** Description: Main entry point to avoid spurs. 3843** Revision History:
1223** Checks for existing spurs in present LO1, LO2 freqs 3844**
1224** and if present, chooses spur-free LO1, LO2 combination 3845** SCR Date Author Description
1225** that tunes the same input/output frequencies. 3846** -------------------------------------------------------------------------
1226** 3847** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1227** Revision History: 3848** 01-03-2008 PINZ Ver 1.xx: Added a trigger of BYPATNUP for
1228** 3849** correct wakeup of the LNA
1229** SCR Date Author Description 3850**
1230** ------------------------------------------------------------------------- 3851****************************************************************************/
1231** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0. 3852UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown)
1232** 3853{
1233*****************************************************************************/ 3854 UData_t status = MT2063_OK; /* Status to be returned */
1234UData_t MT2063_AvoidSpurs(Handle_t h, 3855 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1235 struct MT2063_AvoidSpursData_t* pAS_Info) 3856
1236{ 3857 /* Verify that the handle passed points to a valid tuner */
1237 UData_t status = MT2063_OK; 3858 if (MT2063_IsValidHandle(pInfo) == 0) {
1238 UData_t fm, fp; /* restricted range on LO's */ 3859 status = MT2063_INV_HANDLE;
1239 pAS_Info->bSpurAvoided = 0; 3860 } else {
1240 pAS_Info->nSpursFound = 0; 3861 if (Shutdown == 1)
1241 3862 pInfo->reg[MT2063_REG_PWR_1] |= 0x04; /* Turn the bit on */
1242 if (pAS_Info->maxH1 == 0) 3863 else
1243 return MT2063_OK; 3864 pInfo->reg[MT2063_REG_PWR_1] &= ~0x04; /* Turn off the bit */
1244 3865
1245 /* 3866 status |=
1246 ** Avoid LO Generated Spurs 3867 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
1247 ** 3868 MT2063_REG_PWR_1,
1248 ** Make sure that have no LO-related spurs within the IF output 3869 &pInfo->reg[MT2063_REG_PWR_1], 1);
1249 ** bandwidth. 3870
1250 ** 3871 if (Shutdown != 1) {
1251 ** If there is an LO spur in this band, start at the current IF1 frequency 3872 pInfo->reg[MT2063_REG_BYP_CTRL] =
1252 ** and work out until we find a spur-free frequency or run up against the 3873 (pInfo->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
1253 ** 1st IF SAW band edge. Use temporary copies of fLO1 and fLO2 so that they 3874 status |=
1254 ** will be unchanged if a spur-free setting is not found. 3875 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
1255 */ 3876 MT2063_REG_BYP_CTRL,
1256 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp); 3877 &pInfo->reg[MT2063_REG_BYP_CTRL],
1257 if (pAS_Info->bSpurPresent) 3878 1);
1258 { 3879 pInfo->reg[MT2063_REG_BYP_CTRL] =
1259 UData_t zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in; /* current attempt at a 1st IF */ 3880 (pInfo->reg[MT2063_REG_BYP_CTRL] & 0x9F);
1260 UData_t zfLO1 = pAS_Info->f_LO1; /* current attempt at an LO1 freq */ 3881 status |=
1261 UData_t zfLO2 = pAS_Info->f_LO2; /* current attempt at an LO2 freq */ 3882 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
1262 UData_t delta_IF1; 3883 MT2063_REG_BYP_CTRL,
1263 UData_t new_IF1; 3884 &pInfo->reg[MT2063_REG_BYP_CTRL],
1264 3885 1);
1265 /* 3886 }
1266 ** Spur was found, attempt to find a spur-free 1st IF 3887 }
1267 */ 3888
1268 do 3889 return (status);
1269 { 3890}
1270 pAS_Info->nSpursFound++; 3891
1271 3892/****************************************************************************
1272 /* Raise f_IF1_upper, if needed */ 3893**
1273 MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp); 3894** Name: MT2063_SetExtSRO
1274 3895**
1275 /* Choose next IF1 that is closest to f_IF1_CENTER */ 3896** Description: Sets the external SRO driver.
1276 new_IF1 = MT2063_ChooseFirstIF(pAS_Info); 3897**
1277 3898** Parameters: h - Tuner handle (returned by MT2063_Open)
1278 if (new_IF1 > zfIF1) 3899** Ext_SRO_Setting - external SRO drive setting
1279 { 3900**
1280 pAS_Info->f_LO1 += (new_IF1 - zfIF1); 3901** (default) MT2063_EXT_SRO_OFF - ext driver off
1281 pAS_Info->f_LO2 += (new_IF1 - zfIF1); 3902** MT2063_EXT_SRO_BY_1 - ext driver = SRO frequency
1282 } 3903** MT2063_EXT_SRO_BY_2 - ext driver = SRO/2 frequency
1283 else 3904** MT2063_EXT_SRO_BY_4 - ext driver = SRO/4 frequency
1284 { 3905**
1285 pAS_Info->f_LO1 -= (zfIF1 - new_IF1); 3906** Returns: status:
1286 pAS_Info->f_LO2 -= (zfIF1 - new_IF1); 3907** MT_OK - No errors
1287 } 3908** MT_COMM_ERR - Serial bus communications error
1288 zfIF1 = new_IF1; 3909** MT_INV_HANDLE - Invalid tuner handle
1289 3910**
1290 if (zfIF1 > pAS_Info->f_if1_Center) 3911** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
1291 delta_IF1 = zfIF1 - pAS_Info->f_if1_Center; 3912**
1292 else 3913** The Ext_SRO_Setting settings default to OFF
1293 delta_IF1 = pAS_Info->f_if1_Center - zfIF1; 3914** Use this function if you need to override the default
1294 } 3915**
1295 /* 3916** Revision History:
1296 ** Continue while the new 1st IF is still within the 1st IF bandwidth 3917**
1297 ** and there is a spur in the band (again) 3918** SCR Date Author Description
1298 */ 3919** -------------------------------------------------------------------------
1299 while ((2*delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && 3920** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1300 (pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp))); 3921** 189 S 05-13-2008 RSK Ver 1.16: Correct location for ExtSRO control.
1301 3922**
1302 /* 3923****************************************************************************/
1303 ** Use the LO-spur free values found. If the search went all the way to 3924UData_t MT2063_SetExtSRO(Handle_t h, enum MT2063_Ext_SRO Ext_SRO_Setting)
1304 ** the 1st IF band edge and always found spurs, just leave the original 3925{
1305 ** choice. It's as "good" as any other. 3926 UData_t status = MT2063_OK; /* Status to be returned */
1306 */ 3927 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1307 if (pAS_Info->bSpurPresent == 1) 3928
1308 { 3929 /* Verify that the handle passed points to a valid tuner */
1309 status |= MT2063_SPUR_PRESENT_ERR; 3930 if (MT2063_IsValidHandle(pInfo) == 0)
1310 pAS_Info->f_LO1 = zfLO1; 3931 status = MT2063_INV_HANDLE;
1311 pAS_Info->f_LO2 = zfLO2; 3932 else {
1312 } 3933 pInfo->reg[MT2063_REG_CTRL_2C] =
1313 else 3934 (pInfo->
1314 pAS_Info->bSpurAvoided = 1; 3935 reg[MT2063_REG_CTRL_2C] & 0x3F) | ((U8Data) Ext_SRO_Setting
1315 } 3936 << 6);
1316 3937 status =
1317 status |= ((pAS_Info->nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK); 3938 MT2063_WriteSub(pInfo->hUserData, pInfo->address,
1318 3939 MT2063_REG_CTRL_2C,
1319 return (status); 3940 &pInfo->reg[MT2063_REG_CTRL_2C], 1);
1320} 3941 }
1321 3942
1322 3943 return (status);
1323UData_t MT2063_AvoidSpursVersion(void) 3944}
1324{ 3945
1325 return (MT2063_SPUR_VERSION); 3946/****************************************************************************
1326} 3947**
1327//end of mt2063_spuravoid.c 3948** Name: MT2063_SetReg
1328//================================================================= 3949**
1329//################################################################# 3950** Description: Sets an MT2063 register.
1330//================================================================= 3951**
1331 3952** Parameters: h - Tuner handle (returned by MT2063_Open)
1332 3953** reg - MT2063 register/subaddress location
1333/* 3954** val - MT2063 register/subaddress value
1334** The expected version of MT_AvoidSpursData_t 3955**
1335** If the version is different, an updated file is needed from Microtune 3956** Returns: status:
1336*/ 3957** MT_OK - No errors
1337/* Expecting version 1.21 of the Spur Avoidance API */ 3958** MT_COMM_ERR - Serial bus communications error
1338#define EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION 010201 3959** MT_INV_HANDLE - Invalid tuner handle
1339 3960** MT_ARG_RANGE - Argument out of range
1340#if MT2063_AVOID_SPURS_INFO_VERSION < EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION 3961**
1341#error Contact Microtune for a newer version of MT_SpurAvoid.c 3962** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
1342#elif MT2063_AVOID_SPURS_INFO_VERSION > EXPECTED_MT2063_AVOID_SPURS_INFO_VERSION 3963**
1343#error Contact Microtune for a newer version of mt2063.c 3964** Use this function if you need to override a default
1344#endif 3965** register value
1345 3966**
1346#ifndef MT2063_CNT 3967** Revision History:
1347#error You must define MT2063_CNT in the "mt_userdef.h" file 3968**
1348#endif 3969** SCR Date Author Description
1349 3970** -------------------------------------------------------------------------
1350 3971** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1351typedef enum 3972**
1352{ 3973****************************************************************************/
1353 MT2063_SET_ATTEN, 3974UData_t MT2063_SetReg(Handle_t h, U8Data reg, U8Data val)
1354 MT2063_INCR_ATTEN, 3975{
1355 MT2063_DECR_ATTEN 3976 UData_t status = MT2063_OK; /* Status to be returned */
1356} MT2063_ATTEN_CNTL_MODE; 3977 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1357 3978
1358 3979 /* Verify that the handle passed points to a valid tuner */
1359//#define TUNER_MT2063_OPTIMIZATION 3980 if (MT2063_IsValidHandle(pInfo) == 0)
1360/* 3981 status |= MT2063_INV_HANDLE;
1361** Constants used by the tuning algorithm 3982
1362*/ 3983 if (reg >= MT2063_REG_END_REGS)
1363#define MT2063_REF_FREQ (16000000UL) /* Reference oscillator Frequency (in Hz) */ 3984 status |= MT2063_ARG_RANGE;
1364#define MT2063_IF1_BW (22000000UL) /* The IF1 filter bandwidth (in Hz) */ 3985
1365#define MT2063_TUNE_STEP_SIZE (50000UL) /* Tune in steps of 50 kHz */ 3986 if (MT2063_NO_ERROR(status)) {
1366#define MT2063_SPUR_STEP_HZ (250000UL) /* Step size (in Hz) to move IF1 when avoiding spurs */ 3987 status |=
1367#define MT2063_ZIF_BW (2000000UL) /* Zero-IF spur-free bandwidth (in Hz) */ 3988 MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val,
1368#define MT2063_MAX_HARMONICS_1 (15UL) /* Highest intra-tuner LO Spur Harmonic to be avoided */ 3989 1);
1369#define MT2063_MAX_HARMONICS_2 (5UL) /* Highest inter-tuner LO Spur Harmonic to be avoided */ 3990 if (MT2063_NO_ERROR(status))
1370#define MT2063_MIN_LO_SEP (1000000UL) /* Minimum inter-tuner LO frequency separation */ 3991 pInfo->reg[reg] = val;
1371#define MT2063_LO1_FRACN_AVOID (0UL) /* LO1 FracN numerator avoid region (in Hz) */ 3992 }
1372#define MT2063_LO2_FRACN_AVOID (199999UL) /* LO2 FracN numerator avoid region (in Hz) */ 3993
1373#define MT2063_MIN_FIN_FREQ (44000000UL) /* Minimum input frequency (in Hz) */ 3994 return (status);
1374#define MT2063_MAX_FIN_FREQ (1100000000UL) /* Maximum input frequency (in Hz) */ 3995}
1375#define MT2063_MIN_FOUT_FREQ (36000000UL) /* Minimum output frequency (in Hz) */ 3996
1376#define MT2063_MAX_FOUT_FREQ (57000000UL) /* Maximum output frequency (in Hz) */ 3997static UData_t MT2063_Round_fLO(UData_t f_LO, UData_t f_LO_Step, UData_t f_ref)
1377#define MT2063_MIN_DNC_FREQ (1293000000UL) /* Minimum LO2 frequency (in Hz) */ 3998{
1378#define MT2063_MAX_DNC_FREQ (1614000000UL) /* Maximum LO2 frequency (in Hz) */ 3999 return f_ref * (f_LO / f_ref)
1379#define MT2063_MIN_UPC_FREQ (1396000000UL) /* Minimum LO1 frequency (in Hz) */ 4000 + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
1380#define MT2063_MAX_UPC_FREQ (2750000000UL) /* Maximum LO1 frequency (in Hz) */ 4001}
1381 4002
1382 4003/****************************************************************************
1383/* 4004**
1384** Define the supported Part/Rev codes for the MT2063 4005** Name: fLO_FractionalTerm
1385*/ 4006**
1386#define MT2063_B0 (0x9B) 4007** Description: Calculates the portion contributed by FracN / denom.
1387#define MT2063_B1 (0x9C) 4008**
1388#define MT2063_B2 (0x9D) 4009** This function preserves maximum precision without
1389#define MT2063_B3 (0x9E) 4010** risk of overflow. It accurately calculates
1390 4011** f_ref * num / denom to within 1 HZ with fixed math.
1391/* 4012**
1392** The number of Tuner Registers 4013** Parameters: num - Fractional portion of the multiplier
1393*/ 4014** denom - denominator portion of the ratio
1394static const UData_t MT2063_Num_Registers = MT2063_REG_END_REGS; 4015** This routine successfully handles denom values
1395 4016** up to and including 2^18.
1396 4017** f_Ref - SRO frequency. This calculation handles
1397#define USE_GLOBAL_TUNER 0 4018** f_ref as two separate 14-bit fields.
1398 4019** Therefore, a maximum value of 2^28-1
1399static UData_t nMT2063MaxTuners = MT2063_CNT; 4020** may safely be used for f_ref. This is
1400static struct MT2063_Info_t MT2063_Info[MT2063_CNT]; 4021** the genesis of the magic number "14" and the
1401static struct MT2063_Info_t *MT2063_Avail[MT2063_CNT]; 4022** magic mask value of 0x03FFF.
1402static UData_t nMT2063OpenTuners = 0; 4023**
1403 4024** Returns: f_ref * num / denom
1404 4025**
1405/* 4026** Revision History:
1406** Constants for setting receiver modes. 4027**
1407** (6 modes defined at this time, enumerated by MT2063_RCVR_MODES) 4028** SCR Date Author Description
1408** (DNC1GC & DNC2GC are the values, which are used, when the specific 4029** -------------------------------------------------------------------------
1409** DNC Output is selected, the other is always off) 4030** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1410** 4031**
1411** If PAL-L or L' is received, set: 4032****************************************************************************/
1412** MT2063_SetParam(hMT2063,MT2063_TAGC,1); 4033static UData_t MT2063_fLO_FractionalTerm(UData_t f_ref,
1413** 4034 UData_t num, UData_t denom)
1414** --------------+---------------------------------------------- 4035{
1415** Mode 0 : | MT2063_CABLE_QAM 4036 UData_t t1 = (f_ref >> 14) * num;
1416** Mode 1 : | MT2063_CABLE_ANALOG 4037 UData_t term1 = t1 / denom;
1417** Mode 2 : | MT2063_OFFAIR_COFDM 4038 UData_t loss = t1 % denom;
1418** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS 4039 UData_t term2 =
1419** Mode 4 : | MT2063_OFFAIR_ANALOG 4040 (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
1420** Mode 5 : | MT2063_OFFAIR_8VSB 4041 return ((term1 << 14) + term2);
1421** --------------+----+----+----+----+-----+-----+-------------- 4042}
1422** Mode | 0 | 1 | 2 | 3 | 4 | 5 | 4043
1423** --------------+----+----+----+----+-----+-----+ 4044/****************************************************************************
1424** 4045**
1425** 4046** Name: CalcLO1Mult
1426*/ 4047**
1427static const U8Data RFAGCEN[] = { 0, 0, 0, 0, 0, 0 }; 4048** Description: Calculates Integer divider value and the numerator
1428static const U8Data LNARIN[] = { 0, 0, 3, 3, 3, 3 }; 4049** value for a FracN PLL.
1429static const U8Data FIFFQEN[] = { 1, 1, 1, 1, 1, 1 }; 4050**
1430static const U8Data FIFFQ[] = { 0, 0, 0, 0, 0, 0 }; 4051** This function assumes that the f_LO and f_Ref are
1431static const U8Data DNC1GC[] = { 0, 0, 0, 0, 0, 0 }; 4052** evenly divisible by f_LO_Step.
1432static const U8Data DNC2GC[] = { 0, 0, 0, 0, 0, 0 }; 4053**
1433static const U8Data ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 }; 4054** Parameters: Div - OUTPUT: Whole number portion of the multiplier
1434static const U8Data LNATGT[] = { 44, 43, 43, 43, 43, 43 }; 4055** FracN - OUTPUT: Fractional portion of the multiplier
1435static const U8Data RFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; 4056** f_LO - desired LO frequency.
1436static const U8Data ACRFMAX[] = { 31, 31, 31, 31, 31, 31 }; 4057** f_LO_Step - Minimum step size for the LO (in Hz).
1437static const U8Data PD1TGT[] = { 36, 36, 38, 38, 36, 38 }; 4058** f_Ref - SRO frequency.
1438static const U8Data FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 }; 4059** f_Avoid - Range of PLL frequencies to avoid near
1439static const U8Data ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 }; 4060** integer multiples of f_Ref (in Hz).
1440static const U8Data PD2TGT[] = { 40, 33, 38, 42, 30, 38 }; 4061**
1441 4062** Returns: Recalculated LO frequency.
1442/* 4063**
1443** Local Function Prototypes - not available for external access. 4064** Revision History:
1444*/ 4065**
1445 4066** SCR Date Author Description
1446/* Forward declaration(s): */ 4067** -------------------------------------------------------------------------
1447static UData_t MT2063_CalcLO1Mult(UData_t *Div, UData_t *FracN, UData_t f_LO, UData_t f_LO_Step, UData_t f_Ref); 4068** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1448static UData_t MT2063_CalcLO2Mult(UData_t *Div, UData_t *FracN, UData_t f_LO, UData_t f_LO_Step, UData_t f_Ref); 4069**
1449static UData_t MT2063_fLO_FractionalTerm(UData_t f_ref, UData_t num, UData_t denom); 4070****************************************************************************/
1450 4071static UData_t MT2063_CalcLO1Mult(UData_t * Div,
1451 4072 UData_t * FracN,
1452/****************************************************************************** 4073 UData_t f_LO,
1453** 4074 UData_t f_LO_Step, UData_t f_Ref)
1454** Name: MT2063_Open 4075{
1455** 4076 /* Calculate the whole number portion of the divider */
1456** Description: Initialize the tuner's register values. 4077 *Div = f_LO / f_Ref;
1457** 4078
1458** Parameters: MT2063_Addr - Serial bus address of the tuner. 4079 /* Calculate the numerator value (round to nearest f_LO_Step) */
1459** hMT2063 - Tuner handle passed back. 4080 *FracN =
1460** hUserData - User-defined data, if needed for the 4081 (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1461** MT_ReadSub() & MT_WriteSub functions. 4082 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1462** 4083
1463** Returns: status: 4084 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
1464** MT_OK - No errors 4085}
1465** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch 4086
1466** MT_TUNER_INIT_ERR - Tuner initialization failed 4087/****************************************************************************
1467** MT_COMM_ERR - Serial bus communications error 4088**
1468** MT_ARG_NULL - Null pointer argument passed 4089** Name: CalcLO2Mult
1469** MT_TUNER_CNT_ERR - Too many tuners open 4090**
1470** 4091** Description: Calculates Integer divider value and the numerator
1471** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus 4092** value for a FracN PLL.
1472** MT_WriteSub - Write byte(s) of data to the two-wire bus 4093**
1473** 4094** This function assumes that the f_LO and f_Ref are
1474** Revision History: 4095** evenly divisible by f_LO_Step.
1475** 4096**
1476** SCR Date Author Description 4097** Parameters: Div - OUTPUT: Whole number portion of the multiplier
1477** ------------------------------------------------------------------------- 4098** FracN - OUTPUT: Fractional portion of the multiplier
1478** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. 4099** f_LO - desired LO frequency.
1479** 4100** f_LO_Step - Minimum step size for the LO (in Hz).
1480******************************************************************************/ 4101** f_Ref - SRO frequency.
1481UData_t MT2063_Open(UData_t MT2063_Addr, 4102** f_Avoid - Range of PLL frequencies to avoid near
1482 Handle_t* hMT2063, 4103** integer multiples of f_Ref (in Hz).
1483 Handle_t hUserData) 4104**
1484{ 4105** Returns: Recalculated LO frequency.
1485 UData_t status = MT2063_OK; /* Status to be returned. */ 4106**
1486 SData_t i; 4107** Revision History:
1487 struct MT2063_Info_t* pInfo = NULL; 4108**
1488 struct dvb_frontend *fe= (struct dvb_frontend *)hUserData; 4109** SCR Date Author Description
1489 struct mt2063_state *state = fe->tuner_priv; 4110** -------------------------------------------------------------------------
1490 4111** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1491 /* Check the argument before using */ 4112**
1492 if (hMT2063 == NULL) 4113****************************************************************************/
1493 { 4114static UData_t MT2063_CalcLO2Mult(UData_t * Div,
1494 return MT2063_ARG_NULL; 4115 UData_t * FracN,
1495 } 4116 UData_t f_LO,
1496 4117 UData_t f_LO_Step, UData_t f_Ref)
1497 /* Default tuner handle to NULL. If successful, it will be reassigned */ 4118{
1498 4119 /* Calculate the whole number portion of the divider */
1499#if USE_GLOBAL_TUNER 4120 *Div = f_LO / f_Ref;
1500 *hMT2063 = NULL; 4121
1501 4122 /* Calculate the numerator value (round to nearest f_LO_Step) */
1502 /* 4123 *FracN =
1503 ** If this is our first tuner, initialize the address fields and 4124 (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1504 ** the list of available control blocks. 4125 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1505 */ 4126
1506 if (nMT2063OpenTuners == 0) 4127 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
1507 { 4128 8191);
1508 for (i=MT2063_CNT-1; i>=0; i--) 4129}
1509 { 4130
1510 MT2063_Info[i].handle = NULL; 4131/****************************************************************************
1511 MT2063_Info[i].address = MAX_UDATA; 4132**
1512 MT2063_Info[i].rcvr_mode = MT2063_CABLE_QAM; 4133** Name: FindClearTuneFilter
1513 MT2063_Info[i].hUserData = NULL; 4134**
1514 MT2063_Avail[i] = &MT2063_Info[i]; 4135** Description: Calculate the corrrect ClearTune filter to be used for
1515 } 4136** a given input frequency.
1516 } 4137**
1517 4138** Parameters: pInfo - ptr to tuner data structure
1518 /* 4139** f_in - RF input center frequency (in Hz).
1519 ** Look for an existing MT2063_State_t entry with this address. 4140**
1520 */ 4141** Returns: ClearTune filter number (0-31)
1521 for (i=MT2063_CNT-1; i>=0; i--) 4142**
1522 { 4143** Dependencies: MUST CALL MT2064_Open BEFORE FindClearTuneFilter!
1523 /* 4144**
1524 ** If an open'ed handle provided, we'll re-initialize that structure. 4145** Revision History:
1525 ** 4146**
1526 ** We recognize an open tuner because the address and hUserData are 4147** SCR Date Author Description
1527 ** the same as one that has already been opened 4148** -------------------------------------------------------------------------
1528 */ 4149** 04-10-2008 PINZ Ver 1.14: Use software-controlled ClearTune
1529 if ((MT2063_Info[i].address == MT2063_Addr) && 4150** cross-over frequency values.
1530 (MT2063_Info[i].hUserData == hUserData)) 4151**
1531 { 4152****************************************************************************/
1532 pInfo = &MT2063_Info[i]; 4153static UData_t FindClearTuneFilter(struct MT2063_Info_t *pInfo, UData_t f_in)
1533 break; 4154{
1534 } 4155 UData_t RFBand;
1535 } 4156 UData_t idx; /* index loop */
1536 4157
1537 /* If not found, choose an empty spot. */ 4158 /*
1538 if (pInfo == NULL) 4159 ** Find RF Band setting
1539 { 4160 */
1540 /* Check to see that we're not over-allocating */ 4161 RFBand = 31; /* def when f_in > all */
1541 if (nMT2063OpenTuners == MT2063_CNT) 4162 for (idx = 0; idx < 31; ++idx) {
1542 { 4163 if (pInfo->CTFiltMax[idx] >= f_in) {
1543 return MT2063_TUNER_CNT_ERR; 4164 RFBand = idx;
1544 } 4165 break;
1545 /* Use the next available block from the list */ 4166 }
1546 pInfo = MT2063_Avail[nMT2063OpenTuners]; 4167 }
1547 nMT2063OpenTuners++; 4168 return (RFBand);
1548 } 4169}
1549#else 4170
1550 if (state->MT2063_init==FALSE) 4171/****************************************************************************
1551 { 4172**
1552 pInfo = kzalloc(sizeof (struct MT2063_Info_t), GFP_KERNEL); 4173** Name: MT2063_Tune
1553 if (pInfo == NULL) 4174**
1554 { 4175** Description: Change the tuner's tuned frequency to RFin.
1555 return MT2063_TUNER_OPEN_ERR; 4176**
1556 } 4177** Parameters: h - Open handle to the tuner (from MT2063_Open).
1557 pInfo->handle = NULL; 4178** f_in - RF input center frequency (in Hz).
1558 pInfo->address = MAX_UDATA; 4179**
1559 pInfo->rcvr_mode = MT2063_CABLE_QAM; 4180** Returns: status:
1560 pInfo->hUserData = NULL; 4181** MT_OK - No errors
1561 } 4182** MT_INV_HANDLE - Invalid tuner handle
1562 else 4183** MT_UPC_UNLOCK - Upconverter PLL unlocked
1563 { 4184** MT_DNC_UNLOCK - Downconverter PLL unlocked
1564 pInfo = *hMT2063; 4185** MT_COMM_ERR - Serial bus communications error
1565 } 4186** MT_SPUR_CNT_MASK - Count of avoided LO spurs
1566#endif 4187** MT_SPUR_PRESENT - LO spur possible in output
1567 4188** MT_FIN_RANGE - Input freq out of range
1568 if (MT2063_NO_ERROR(status)) 4189** MT_FOUT_RANGE - Output freq out of range
1569 { 4190** MT_UPC_RANGE - Upconverter freq out of range
1570 status |= MT2063_RegisterTuner(&pInfo->AS_Data); 4191** MT_DNC_RANGE - Downconverter freq out of range
1571 } 4192**
1572 4193** Dependencies: MUST CALL MT2063_Open BEFORE MT2063_Tune!
1573 if (MT2063_NO_ERROR(status)) 4194**
1574 { 4195** MT_ReadSub - Read data from the two-wire serial bus
1575 pInfo->handle = (Handle_t) pInfo; 4196** MT_WriteSub - Write data to the two-wire serial bus
1576 4197** MT_Sleep - Delay execution for x milliseconds
1577 pInfo->hUserData = hUserData; 4198** MT2063_GetLocked - Checks to see if LO1 and LO2 are locked
1578 pInfo->address = MT2063_Addr; 4199**
1579 pInfo->rcvr_mode = MT2063_CABLE_QAM; 4200** Revision History:
1580 status |= MT2063_ReInit((Handle_t) pInfo); 4201**
1581 } 4202** SCR Date Author Description
1582 4203** -------------------------------------------------------------------------
1583 if (MT2063_IS_ERROR(status)) 4204** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1584 /* MT2063_Close handles the un-registration of the tuner */ 4205** 04-10-2008 PINZ Ver 1.05: Use software-controlled ClearTune
1585 MT2063_Close((Handle_t) pInfo); 4206** cross-over frequency values.
1586 else 4207** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs.
1587 { 4208** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid.
1588 state->MT2063_init = TRUE; 4209** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW
1589 *hMT2063 = pInfo->handle; 4210**
1590 4211****************************************************************************/
1591 } 4212UData_t MT2063_Tune(Handle_t h, UData_t f_in)
1592 4213{ /* RF input center frequency */
1593 return (status); 4214 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
1594} 4215
1595 4216 UData_t status = MT2063_OK; /* status of operation */
1596 4217 UData_t LO1; /* 1st LO register value */
1597static UData_t MT2063_IsValidHandle(struct MT2063_Info_t* handle) 4218 UData_t Num1; /* Numerator for LO1 reg. value */
1598{ 4219 UData_t f_IF1; /* 1st IF requested */
1599 return ((handle != NULL) && (handle->handle == handle)) ? 1 : 0; 4220 UData_t LO2; /* 2nd LO register value */
1600} 4221 UData_t Num2; /* Numerator for LO2 reg. value */
1601 4222 UData_t ofLO1, ofLO2; /* last time's LO frequencies */
1602 4223 UData_t ofin, ofout; /* last time's I/O frequencies */
1603/****************************************************************************** 4224 U8Data fiffc = 0x80; /* FIFF center freq from tuner */
1604** 4225 UData_t fiffof; /* Offset from FIFF center freq */
1605** Name: MT2063_Close 4226 const U8Data LO1LK = 0x80; /* Mask for LO1 Lock bit */
1606** 4227 U8Data LO2LK = 0x08; /* Mask for LO2 Lock bit */
1607** Description: Release the handle to the tuner. 4228 U8Data val;
1608** 4229 UData_t RFBand;
1609** Parameters: hMT2063 - Handle to the MT2063 tuner 4230
1610** 4231 /* Verify that the handle passed points to a valid tuner */
1611** Returns: status: 4232 if (MT2063_IsValidHandle(pInfo) == 0)
1612** MT_OK - No errors 4233 return MT2063_INV_HANDLE;
1613** MT_INV_HANDLE - Invalid tuner handle 4234
1614** 4235 /* Check the input and output frequency ranges */
1615** Dependencies: mt_errordef.h - definition of error codes 4236 if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
1616** 4237 status |= MT2063_FIN_RANGE;
1617** Revision History: 4238
1618** 4239 if ((pInfo->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
1619** SCR Date Author Description 4240 || (pInfo->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
1620** ------------------------------------------------------------------------- 4241 status |= MT2063_FOUT_RANGE;
1621** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. 4242
1622** 4243 /*
1623******************************************************************************/ 4244 ** Save original LO1 and LO2 register values
1624UData_t MT2063_Close(Handle_t hMT2063) 4245 */
1625{ 4246 ofLO1 = pInfo->AS_Data.f_LO1;
1626 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) hMT2063; 4247 ofLO2 = pInfo->AS_Data.f_LO2;
1627 4248 ofin = pInfo->AS_Data.f_in;
1628 if (!MT2063_IsValidHandle(pInfo)) 4249 ofout = pInfo->AS_Data.f_out;
1629 return MT2063_INV_HANDLE; 4250
1630 4251 /*
1631 /* Unregister tuner with SpurAvoidance routines (if needed) */ 4252 ** Find and set RF Band setting
1632 MT2063_UnRegisterTuner(&pInfo->AS_Data); 4253 */
1633 /* Now remove the tuner from our own list of tuners */ 4254 if (pInfo->ctfilt_sw == 1) {
1634 pInfo->handle = NULL; 4255 val = (pInfo->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
1635 pInfo->address = MAX_UDATA; 4256 if (pInfo->reg[MT2063_REG_CTUNE_CTRL] != val) {
1636 pInfo->hUserData = NULL; 4257 status |=
1637 #if USE_GLOBAL_TUNER 4258 MT2063_SetReg(pInfo, MT2063_REG_CTUNE_CTRL, val);
1638 nMT2063OpenTuners--; 4259 }
1639 MT2063_Avail[nMT2063OpenTuners] = pInfo; /* Return control block to available list */ 4260 val = pInfo->reg[MT2063_REG_CTUNE_OV];
1640 #else 4261 RFBand = FindClearTuneFilter(pInfo, f_in);
1641 //kfree(pInfo); 4262 pInfo->reg[MT2063_REG_CTUNE_OV] =
1642 //pInfo = NULL; 4263 (U8Data) ((pInfo->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
1643 #endif 4264 | RFBand);
1644 return MT2063_OK; 4265 if (pInfo->reg[MT2063_REG_CTUNE_OV] != val) {
1645} 4266 status |=
1646 4267 MT2063_SetReg(pInfo, MT2063_REG_CTUNE_OV, val);
1647 4268 }
1648/****************************************************************************** 4269 }
1649** 4270
1650** Name: MT2063_GetGPIO 4271 /*
1651** 4272 ** Read the FIFF Center Frequency from the tuner
1652** Description: Get the current MT2063 GPIO value. 4273 */
1653** 4274 if (MT2063_NO_ERROR(status)) {
1654** Parameters: h - Open handle to the tuner (from MT2063_Open). 4275 status |=
1655** gpio_id - Selects GPIO0, GPIO1 or GPIO2 4276 MT2063_ReadSub(pInfo->hUserData, pInfo->address,
1656** attr - Selects input readback, I/O direction or 4277 MT2063_REG_FIFFC,
1657** output value 4278 &pInfo->reg[MT2063_REG_FIFFC], 1);
1658** *value - current setting of GPIO pin 4279 fiffc = pInfo->reg[MT2063_REG_FIFFC];
1659** 4280 }
1660** Usage: status = MT2063_GetGPIO(hMT2063, MT2063_GPIO_OUT, &value); 4281 /*
1661** 4282 ** Assign in the requested values
1662** Returns: status: 4283 */
1663** MT_OK - No errors 4284 pInfo->AS_Data.f_in = f_in;
1664** MT_COMM_ERR - Serial bus communications error 4285 /* Request a 1st IF such that LO1 is on a step size */
1665** MT_INV_HANDLE - Invalid tuner handle 4286 pInfo->AS_Data.f_if1_Request =
1666** MT_ARG_NULL - Null pointer argument passed 4287 MT2063_Round_fLO(pInfo->AS_Data.f_if1_Request + f_in,
1667** 4288 pInfo->AS_Data.f_LO1_Step,
1668** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus 4289 pInfo->AS_Data.f_ref) - f_in;
1669** 4290
1670** Revision History: 4291 /*
1671** 4292 ** Calculate frequency settings. f_IF1_FREQ + f_in is the
1672** SCR Date Author Description 4293 ** desired LO1 frequency
1673** ------------------------------------------------------------------------- 4294 */
1674** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. 4295 MT2063_ResetExclZones(&pInfo->AS_Data);
1675** 4296
1676******************************************************************************/ 4297 f_IF1 = MT2063_ChooseFirstIF(&pInfo->AS_Data);
1677UData_t MT2063_GetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, 4298
1678 enum MT2063_GPIO_Attr attr, 4299 pInfo->AS_Data.f_LO1 =
1679 UData_t* value) 4300 MT2063_Round_fLO(f_IF1 + f_in, pInfo->AS_Data.f_LO1_Step,
1680{ 4301 pInfo->AS_Data.f_ref);
1681 UData_t status = MT2063_OK; /* Status to be returned */ 4302
1682 U8Data regno; 4303 pInfo->AS_Data.f_LO2 =
1683 SData_t shift; 4304 MT2063_Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in,
1684 static U8Data GPIOreg[3] = {MT2063_REG_RF_STATUS, MT2063_REG_FIF_OV, MT2063_REG_RF_OV}; 4305 pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref);
1685 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; 4306
1686 4307 /*
1687 if (MT2063_IsValidHandle(pInfo) == 0) 4308 ** Check for any LO spurs in the output bandwidth and adjust
1688 return MT2063_INV_HANDLE; 4309 ** the LO settings to avoid them if needed
1689 4310 */
1690 if (value == NULL) 4311 status |= MT2063_AvoidSpurs(h, &pInfo->AS_Data);
1691 return MT2063_ARG_NULL; 4312 /*
1692 4313 ** MT_AvoidSpurs spurs may have changed the LO1 & LO2 values.
1693 regno = GPIOreg[attr]; 4314 ** Recalculate the LO frequencies and the values to be placed
1694 4315 ** in the tuning registers.
1695 /* We'll read the register just in case the write didn't work last time */ 4316 */
1696 status = MT2063_ReadSub(pInfo->hUserData, pInfo->address, regno, &pInfo->reg[regno], 1); 4317 pInfo->AS_Data.f_LO1 =
1697 4318 MT2063_CalcLO1Mult(&LO1, &Num1, pInfo->AS_Data.f_LO1,
1698 shift = (gpio_id - MT2063_GPIO0 + 5); 4319 pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref);
1699 *value = (pInfo->reg[regno] >> shift) & 1; 4320 pInfo->AS_Data.f_LO2 =
1700 4321 MT2063_Round_fLO(pInfo->AS_Data.f_LO1 - pInfo->AS_Data.f_out - f_in,
1701 return (status); 4322 pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref);
1702} 4323 pInfo->AS_Data.f_LO2 =
1703 4324 MT2063_CalcLO2Mult(&LO2, &Num2, pInfo->AS_Data.f_LO2,
1704 4325 pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref);
1705/**************************************************************************** 4326
1706** 4327 /*
1707** Name: MT2063_GetLocked 4328 ** Check the upconverter and downconverter frequency ranges
1708** 4329 */
1709** Description: Checks to see if LO1 and LO2 are locked. 4330 if ((pInfo->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
1710** 4331 || (pInfo->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
1711** Parameters: h - Open handle to the tuner (from MT2063_Open). 4332 status |= MT2063_UPC_RANGE;
1712** 4333 if ((pInfo->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
1713** Returns: status: 4334 || (pInfo->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
1714** MT_OK - No errors 4335 status |= MT2063_DNC_RANGE;
1715** MT_UPC_UNLOCK - Upconverter PLL unlocked 4336 /* LO2 Lock bit was in a different place for B0 version */
1716** MT_DNC_UNLOCK - Downconverter PLL unlocked 4337 if (pInfo->tuner_id == MT2063_B0)
1717** MT_COMM_ERR - Serial bus communications error 4338 LO2LK = 0x40;
1718** MT_INV_HANDLE - Invalid tuner handle 4339
1719** 4340 /*
1720** Dependencies: MT_ReadSub - Read byte(s) of data from the serial bus 4341 ** If we have the same LO frequencies and we're already locked,
1721** MT_Sleep - Delay execution for x milliseconds 4342 ** then skip re-programming the LO registers.
1722** 4343 */
1723** Revision History: 4344 if ((ofLO1 != pInfo->AS_Data.f_LO1)
1724** 4345 || (ofLO2 != pInfo->AS_Data.f_LO2)
1725** SCR Date Author Description 4346 || ((pInfo->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
1726** ------------------------------------------------------------------------- 4347 (LO1LK | LO2LK))) {
1727** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b. 4348 /*
1728** 4349 ** Calculate the FIFFOF register value
1729****************************************************************************/ 4350 **
1730UData_t MT2063_GetLocked(Handle_t h) 4351 ** IF1_Actual
1731{ 4352 ** FIFFOF = ------------ - 8 * FIFFC - 4992
1732 const UData_t nMaxWait = 100; /* wait a maximum of 100 msec */ 4353 ** f_ref/64
1733 const UData_t nPollRate = 2; /* poll status bits every 2 ms */ 4354 */
1734 const UData_t nMaxLoops = nMaxWait / nPollRate; 4355 fiffof =
1735 const U8Data LO1LK = 0x80; 4356 (pInfo->AS_Data.f_LO1 -
1736 U8Data LO2LK = 0x08; 4357 f_in) / (pInfo->AS_Data.f_ref / 64) - 8 * (UData_t) fiffc -
1737 UData_t status = MT2063_OK; /* Status to be returned */ 4358 4992;
1738 UData_t nDelays = 0; 4359 if (fiffof > 0xFF)
1739 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h; 4360 fiffof = 0xFF;
1740 4361
1741 if (MT2063_IsValidHandle(pInfo) == 0) 4362 /*
1742 return MT2063_INV_HANDLE; 4363 ** Place all of the calculated values into the local tuner
1743 4364 ** register fields.
1744 /* LO2 Lock bit was in a different place for B0 version */ 4365 */
1745 if (pInfo->tuner_id == MT2063_B0) 4366 if (MT2063_NO_ERROR(status)) {
1746 LO2LK = 0x40; 4367 pInfo->reg[MT2063_REG_LO1CQ_1] = (U8Data) (LO1 & 0xFF); /* DIV1q */
1747 4368 pInfo->reg[MT2063_REG_LO1CQ_2] = (U8Data) (Num1 & 0x3F); /* NUM1q */
1748 do 4369 pInfo->reg[MT2063_REG_LO2CQ_1] = (U8Data) (((LO2 & 0x7F) << 1) /* DIV2q */
1749 { 4370 |(Num2 >> 12)); /* NUM2q (hi) */
1750 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO_STATUS, &pInfo->reg[MT2063_REG_LO_STATUS], 1); 4371 pInfo->reg[MT2063_REG_LO2CQ_2] = (U8Data) ((Num2 & 0x0FF0) >> 4); /* NUM2q (mid) */
1751 4372 pInfo->reg[MT2063_REG_LO2CQ_3] = (U8Data) (0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */
1752 if (MT2063_IS_ERROR(status)) 4373
1753 return (status); 4374 /*
1754 4375 ** Now write out the computed register values
1755 if ((pInfo->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) == (LO1LK | LO2LK)) 4376 ** IMPORTANT: There is a required order for writing
1756 { 4377 ** (0x05 must follow all the others).
1757 return (status); 4378 */
1758 } 4379 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &pInfo->reg[MT2063_REG_LO1CQ_1], 5); /* 0x01 - 0x05 */
1759 MT2063_Sleep(pInfo->hUserData, nPollRate); /* Wait between retries */ 4380 if (pInfo->tuner_id == MT2063_B0) {
1760 } 4381 /* Re-write the one-shot bits to trigger the tune operation */
1761 while (++nDelays < nMaxLoops); 4382 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_3, &pInfo->reg[MT2063_REG_LO2CQ_3], 1); /* 0x05 */
1762 4383 }
1763 if ((pInfo->reg[MT2063_REG_LO_STATUS] & LO1LK) == 0x00) 4384 /* Write out the FIFF offset only if it's changing */
1764 status |= MT2063_UPC_UNLOCK; 4385 if (pInfo->reg[MT2063_REG_FIFF_OFFSET] !=
1765 if ((pInfo->reg[MT2063_REG_LO_STATUS] & LO2LK) == 0x00) 4386 (U8Data) fiffof) {
1766 status |= MT2063_DNC_UNLOCK; 4387 pInfo->reg[MT2063_REG_FIFF_OFFSET] =
1767 4388 (U8Data) fiffof;
1768 return (status); 4389 status |=
1769} 4390 MT2063_WriteSub(pInfo->hUserData,
1770 4391 pInfo->address,
1771 4392 MT2063_REG_FIFF_OFFSET,
1772/**************************************************************************** 4393 &pInfo->
1773** 4394 reg[MT2063_REG_FIFF_OFFSET],
1774** Name: MT2063_GetParam 4395 1);
1775** 4396 }
1776** Description: Gets a tuning algorithm parameter. 4397 }
1777** 4398
1778** This function provides access to the internals of the 4399 /*
1779** tuning algorithm - mostly for testing purposes. 4400 ** Check for LO's locking
1780** 4401 */
1781** Parameters: h - Tuner handle (returned by MT2063_Open) 4402
1782** param - Tuning algorithm parameter 4403 if (MT2063_NO_ERROR(status)) {
1783** (see enum MT2063_Param) 4404 status |= MT2063_GetLocked(h);
1784** pValue - ptr to returned value 4405 }
1785** 4406 /*
1786** param Description 4407 ** If we locked OK, assign calculated data to MT2063_Info_t structure
1787** ---------------------- -------------------------------- 4408 */
1788** MT2063_IC_ADDR Serial Bus address of this tuner 4409 if (MT2063_NO_ERROR(status)) {
1789** MT2063_MAX_OPEN Max # of MT2063's allowed open 4410 pInfo->f_IF1_actual = pInfo->AS_Data.f_LO1 - f_in;
1790** MT2063_NUM_OPEN # of MT2063's open 4411 }
1791** MT2063_SRO_FREQ crystal frequency 4412 }
1792** MT2063_STEPSIZE minimum tuning step size 4413
1793** MT2063_INPUT_FREQ input center frequency 4414 return (status);
1794** MT2063_LO1_FREQ LO1 Frequency 4415}
1795** MT2063_LO1_STEPSIZE LO1 minimum step size 4416
1796** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region 4417UData_t MT_Tune_atv(Handle_t h, UData_t f_in, UData_t bw_in,
1797** MT2063_IF1_ACTUAL Current 1st IF in use 4418 enum MTTune_atv_standard tv_type)
1798** MT2063_IF1_REQUEST Requested 1st IF
1799** MT2063_IF1_CENTER Center of 1st IF SAW filter
1800** MT2063_IF1_BW Bandwidth of 1st IF SAW filter
1801** MT2063_ZIF_BW zero-IF bandwidth
1802** MT2063_LO2_FREQ LO2 Frequency
1803** MT2063_LO2_STEPSIZE LO2 minimum step size
1804** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region
1805** MT2063_OUTPUT_FREQ output center frequency
1806** MT2063_OUTPUT_BW output bandwidth
1807** MT2063_LO_SEPARATION min inter-tuner LO separation
1808** MT2063_AS_ALG ID of avoid-spurs algorithm in use
1809** MT2063_MAX_HARM1 max # of intra-tuner harmonics
1810** MT2063_MAX_HARM2 max # of inter-tuner harmonics
1811** MT2063_EXCL_ZONES # of 1st IF exclusion zones
1812** MT2063_NUM_SPURS # of spurs found/avoided
1813** MT2063_SPUR_AVOIDED >0 spurs avoided
1814** MT2063_SPUR_PRESENT >0 spurs in output (mathematically)
1815** MT2063_RCVR_MODE Predefined modes.
1816** MT2063_ACLNA LNA attenuator gain code
1817** MT2063_ACRF RF attenuator gain code
1818** MT2063_ACFIF FIF attenuator gain code
1819** MT2063_ACLNA_MAX LNA attenuator limit
1820** MT2063_ACRF_MAX RF attenuator limit
1821** MT2063_ACFIF_MAX FIF attenuator limit
1822** MT2063_PD1 Actual value of PD1
1823** MT2063_PD2 Actual value of PD2
1824** MT2063_DNC_OUTPUT_ENABLE DNC output selection
1825** MT2063_VGAGC VGA gain code
1826** MT2063_VGAOI VGA output current
1827** MT2063_TAGC TAGC setting
1828** MT2063_AMPGC AMP gain code
1829** MT2063_AVOID_DECT Avoid DECT Frequencies
1830** MT2063_CTFILT_SW Cleartune filter selection
1831**
1832** Usage: status |= MT2063_GetParam(hMT2063,
1833** MT2063_IF1_ACTUAL,
1834** &f_IF1_Actual);
1835**
1836** Returns: status:
1837** MT_OK - No errors
1838** MT_INV_HANDLE - Invalid tuner handle
1839** MT_ARG_NULL - Null pointer argument passed
1840** MT_ARG_RANGE - Invalid parameter requested
1841**
1842** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
1843**
1844** See Also: MT2063_SetParam, MT2063_Open
1845**
1846** Revision History:
1847**
1848** SCR Date Author Description
1849** -------------------------------------------------------------------------
1850** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
1851** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ
1852** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC
1853** 173 M 01-23-2008 RSK Ver 1.12: Read LO1C and LO2C registers from HW
1854** in GetParam.
1855** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT
1856** Split SetParam up to ACLNA / ACLNA_MAX
1857** removed ACLNA_INRC/DECR (+RF & FIF)
1858** removed GCUAUTO / BYPATNDN/UP
1859** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs.
1860** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid.
1861** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW
1862**
1863****************************************************************************/
1864UData_t MT2063_GetParam(Handle_t h,
1865 enum MT2063_Param param,
1866 UData_t* pValue)
1867{
1868 UData_t status = MT2063_OK; /* Status to be returned */
1869 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
1870 UData_t Div;
1871 UData_t Num;
1872
1873 if (pValue == NULL)
1874 status |= MT2063_ARG_NULL;
1875
1876 /* Verify that the handle passed points to a valid tuner */
1877 if (MT2063_IsValidHandle(pInfo) == 0)
1878 status |= MT2063_INV_HANDLE;
1879
1880 if (MT2063_NO_ERROR(status))
1881 {
1882 switch (param)
1883 {
1884 /* Serial Bus address of this tuner */
1885 case MT2063_IC_ADDR:
1886 *pValue = pInfo->address;
1887 break;
1888
1889 /* Max # of MT2063's allowed to be open */
1890 case MT2063_MAX_OPEN:
1891 *pValue = nMT2063MaxTuners;
1892 break;
1893
1894 /* # of MT2063's open */
1895 case MT2063_NUM_OPEN:
1896 *pValue = nMT2063OpenTuners;
1897 break;
1898
1899 /* crystal frequency */
1900 case MT2063_SRO_FREQ:
1901 *pValue = pInfo->AS_Data.f_ref;
1902 break;
1903
1904 /* minimum tuning step size */
1905 case MT2063_STEPSIZE:
1906 *pValue = pInfo->AS_Data.f_LO2_Step;
1907 break;
1908
1909 /* input center frequency */
1910 case MT2063_INPUT_FREQ:
1911 *pValue = pInfo->AS_Data.f_in;
1912 break;
1913
1914 /* LO1 Frequency */
1915 case MT2063_LO1_FREQ:
1916 {
1917 /* read the actual tuner register values for LO1C_1 and LO1C_2 */
1918 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1C_1, &pInfo->reg[MT2063_REG_LO1C_1], 2);
1919 Div = pInfo->reg[MT2063_REG_LO1C_1];
1920 Num = pInfo->reg[MT2063_REG_LO1C_2] & 0x3F;
1921 pInfo->AS_Data.f_LO1 = (pInfo->AS_Data.f_ref * Div) + MT2063_fLO_FractionalTerm(pInfo->AS_Data.f_ref, Num, 64);
1922 }
1923 *pValue = pInfo->AS_Data.f_LO1;
1924 break;
1925
1926 /* LO1 minimum step size */
1927 case MT2063_LO1_STEPSIZE:
1928 *pValue = pInfo->AS_Data.f_LO1_Step;
1929 break;
1930
1931 /* LO1 FracN keep-out region */
1932 case MT2063_LO1_FRACN_AVOID_PARAM:
1933 *pValue = pInfo->AS_Data.f_LO1_FracN_Avoid;
1934 break;
1935
1936 /* Current 1st IF in use */
1937 case MT2063_IF1_ACTUAL:
1938 *pValue = pInfo->f_IF1_actual;
1939 break;
1940
1941 /* Requested 1st IF */
1942 case MT2063_IF1_REQUEST:
1943 *pValue = pInfo->AS_Data.f_if1_Request;
1944 break;
1945
1946 /* Center of 1st IF SAW filter */
1947 case MT2063_IF1_CENTER:
1948 *pValue = pInfo->AS_Data.f_if1_Center;
1949 break;
1950
1951 /* Bandwidth of 1st IF SAW filter */
1952 case MT2063_IF1_BW:
1953 *pValue = pInfo->AS_Data.f_if1_bw;
1954 break;
1955
1956 /* zero-IF bandwidth */
1957 case MT2063_ZIF_BW:
1958 *pValue = pInfo->AS_Data.f_zif_bw;
1959 break;
1960
1961 /* LO2 Frequency */
1962 case MT2063_LO2_FREQ:
1963 {
1964 /* Read the actual tuner register values for LO2C_1, LO2C_2 and LO2C_3 */
1965 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2C_1, &pInfo->reg[MT2063_REG_LO2C_1], 3);
1966 Div = (pInfo->reg[MT2063_REG_LO2C_1] & 0xFE ) >> 1;
1967 Num = ((pInfo->reg[MT2063_REG_LO2C_1] & 0x01 ) << 12) | (pInfo->reg[MT2063_REG_LO2C_2] << 4) | (pInfo->reg[MT2063_REG_LO2C_3] & 0x00F);
1968 pInfo->AS_Data.f_LO2 = (pInfo->AS_Data.f_ref * Div) + MT2063_fLO_FractionalTerm(pInfo->AS_Data.f_ref, Num, 8191);
1969 }
1970 *pValue = pInfo->AS_Data.f_LO2;
1971 break;
1972
1973 /* LO2 minimum step size */
1974 case MT2063_LO2_STEPSIZE:
1975 *pValue = pInfo->AS_Data.f_LO2_Step;
1976 break;
1977
1978 /* LO2 FracN keep-out region */
1979 case MT2063_LO2_FRACN_AVOID:
1980 *pValue = pInfo->AS_Data.f_LO2_FracN_Avoid;
1981 break;
1982
1983 /* output center frequency */
1984 case MT2063_OUTPUT_FREQ:
1985 *pValue = pInfo->AS_Data.f_out;
1986 break;
1987
1988 /* output bandwidth */
1989 case MT2063_OUTPUT_BW:
1990 *pValue = pInfo->AS_Data.f_out_bw - 750000;
1991 break;
1992
1993 /* min inter-tuner LO separation */
1994 case MT2063_LO_SEPARATION:
1995 *pValue = pInfo->AS_Data.f_min_LO_Separation;
1996 break;
1997
1998 /* ID of avoid-spurs algorithm in use */
1999 case MT2063_AS_ALG:
2000 *pValue = pInfo->AS_Data.nAS_Algorithm;
2001 break;
2002
2003 /* max # of intra-tuner harmonics */
2004 case MT2063_MAX_HARM1:
2005 *pValue = pInfo->AS_Data.maxH1;
2006 break;
2007
2008 /* max # of inter-tuner harmonics */
2009 case MT2063_MAX_HARM2:
2010 *pValue = pInfo->AS_Data.maxH2;
2011 break;
2012
2013 /* # of 1st IF exclusion zones */
2014 case MT2063_EXCL_ZONES:
2015 *pValue = pInfo->AS_Data.nZones;
2016 break;
2017
2018 /* # of spurs found/avoided */
2019 case MT2063_NUM_SPURS:
2020 *pValue = pInfo->AS_Data.nSpursFound;
2021 break;
2022
2023 /* >0 spurs avoided */
2024 case MT2063_SPUR_AVOIDED:
2025 *pValue = pInfo->AS_Data.bSpurAvoided;
2026 break;
2027
2028 /* >0 spurs in output (mathematically) */
2029 case MT2063_SPUR_PRESENT:
2030 *pValue = pInfo->AS_Data.bSpurPresent;
2031 break;
2032
2033 /* Predefined receiver setup combination */
2034 case MT2063_RCVR_MODE:
2035 *pValue = pInfo->rcvr_mode;
2036 break;
2037
2038 case MT2063_PD1:
2039 case MT2063_PD2:
2040 {
2041 U8Data mask = (param == MT2063_PD1 ? 0x01 : 0x03); /* PD1 vs PD2 */
2042 U8Data orig = (pInfo->reg[MT2063_REG_BYP_CTRL]);
2043 U8Data reg = (orig & 0xF1) | mask; /* Only set 3 bits (not 5) */
2044 int i;
2045
2046 *pValue = 0;
2047
2048 /* Initiate ADC output to reg 0x0A */
2049 if (reg != orig)
2050 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_BYP_CTRL, &reg, 1);
2051
2052 if (MT2063_IS_ERROR(status))
2053 return (status);
2054
2055 for (i=0; i<8; i++) {
2056 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_ADC_OUT, &pInfo->reg[MT2063_REG_ADC_OUT], 1);
2057
2058 if (MT2063_NO_ERROR(status))
2059 *pValue += pInfo->reg[MT2063_REG_ADC_OUT];
2060 else
2061 {
2062 if( i ) *pValue /= i;
2063 return (status);
2064 }
2065 }
2066 *pValue /= 8; /* divide by number of reads */
2067 *pValue >>=2; /* only want 6 MSB's out of 8 */
2068
2069 /* Restore value of Register BYP_CTRL */
2070 if (reg != orig)
2071 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_BYP_CTRL, &orig, 1);
2072 }
2073 break;
2074
2075 /* Get LNA attenuator code */
2076 case MT2063_ACLNA:
2077 {
2078 U8Data val;
2079 status |= MT2063_GetReg(pInfo, MT2063_REG_XO_STATUS, &val);
2080 *pValue = val & 0x1f;
2081 }
2082 break;
2083
2084 /* Get RF attenuator code */
2085 case MT2063_ACRF:
2086 {
2087 U8Data val;
2088 status |= MT2063_GetReg(pInfo, MT2063_REG_RF_STATUS, &val);
2089 *pValue = val & 0x1f;
2090 }
2091 break;
2092
2093 /* Get FIF attenuator code */
2094 case MT2063_ACFIF:
2095 {
2096 U8Data val;
2097 status |= MT2063_GetReg(pInfo, MT2063_REG_FIF_STATUS, &val);
2098 *pValue = val & 0x1f;
2099 }
2100 break;
2101
2102 /* Get LNA attenuator limit */
2103 case MT2063_ACLNA_MAX:
2104 {
2105 U8Data val;
2106 status |= MT2063_GetReg(pInfo, MT2063_REG_LNA_OV, &val);
2107 *pValue = val & 0x1f;
2108 }
2109 break;
2110
2111 /* Get RF attenuator limit */
2112 case MT2063_ACRF_MAX:
2113 {
2114 U8Data val;
2115 status |= MT2063_GetReg(pInfo, MT2063_REG_RF_OV, &val);
2116 *pValue = val & 0x1f;
2117 }
2118 break;
2119
2120 /* Get FIF attenuator limit */
2121 case MT2063_ACFIF_MAX:
2122 {
2123 U8Data val;
2124 status |= MT2063_GetReg(pInfo, MT2063_REG_FIF_OV, &val);
2125 *pValue = val & 0x1f;
2126 }
2127 break;
2128
2129 /* Get current used DNC output */
2130 case MT2063_DNC_OUTPUT_ENABLE:
2131 {
2132 if ( (pInfo->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) /* if DNC1 is off */
2133 {
2134 if ( (pInfo->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
2135 *pValue = (UData_t)MT2063_DNC_NONE;
2136 else
2137 *pValue = (UData_t)MT2063_DNC_2;
2138 }
2139 else /* DNC1 is on */
2140 {
2141 if ( (pInfo->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
2142 *pValue = (UData_t)MT2063_DNC_1;
2143 else
2144 *pValue = (UData_t)MT2063_DNC_BOTH;
2145 }
2146 }
2147 break;
2148
2149 /* Get VGA Gain Code */
2150 case MT2063_VGAGC:
2151 *pValue = ( (pInfo->reg[MT2063_REG_VGA_GAIN] & 0x0C) >> 2 );
2152 break;
2153
2154 /* Get VGA bias current */
2155 case MT2063_VGAOI:
2156 *pValue = (pInfo->reg[MT2063_REG_RSVD_31] & 0x07);
2157 break;
2158
2159 /* Get TAGC setting */
2160 case MT2063_TAGC:
2161 *pValue = (pInfo->reg[MT2063_REG_RSVD_1E] & 0x03);
2162 break;
2163
2164 /* Get AMP Gain Code */
2165 case MT2063_AMPGC:
2166 *pValue = (pInfo->reg[MT2063_REG_TEMP_SEL] & 0x03);
2167 break;
2168
2169 /* Avoid DECT Frequencies */
2170 case MT2063_AVOID_DECT:
2171 *pValue = pInfo->AS_Data.avoidDECT;
2172 break;
2173
2174 /* Cleartune filter selection: 0 - by IC (default), 1 - by software */
2175 case MT2063_CTFILT_SW:
2176 *pValue = pInfo->ctfilt_sw;
2177 break;
2178
2179 case MT2063_EOP:
2180 default:
2181 status |= MT2063_ARG_RANGE;
2182 }
2183 }
2184 return (status);
2185}
2186
2187
2188/****************************************************************************
2189**
2190** Name: MT2063_GetReg
2191**
2192** Description: Gets an MT2063 register.
2193**
2194** Parameters: h - Tuner handle (returned by MT2063_Open)
2195** reg - MT2063 register/subaddress location
2196** *val - MT2063 register/subaddress value
2197**
2198** Returns: status:
2199** MT_OK - No errors
2200** MT_COMM_ERR - Serial bus communications error
2201** MT_INV_HANDLE - Invalid tuner handle
2202** MT_ARG_NULL - Null pointer argument passed
2203** MT_ARG_RANGE - Argument out of range
2204**
2205** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
2206**
2207** Use this function if you need to read a register from
2208** the MT2063.
2209**
2210** Revision History:
2211**
2212** SCR Date Author Description
2213** -------------------------------------------------------------------------
2214** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2215**
2216****************************************************************************/
2217UData_t MT2063_GetReg(Handle_t h,
2218 U8Data reg,
2219 U8Data* val)
2220{
2221 UData_t status = MT2063_OK; /* Status to be returned */
2222 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
2223
2224 /* Verify that the handle passed points to a valid tuner */
2225 if (MT2063_IsValidHandle(pInfo) == 0)
2226 status |= MT2063_INV_HANDLE;
2227
2228 if (val == NULL)
2229 status |= MT2063_ARG_NULL;
2230
2231 if (reg >= MT2063_REG_END_REGS)
2232 status |= MT2063_ARG_RANGE;
2233
2234 if (MT2063_NO_ERROR(status))
2235 {
2236 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, reg, &pInfo->reg[reg], 1);
2237 if (MT2063_NO_ERROR(status))
2238 *val = pInfo->reg[reg];
2239 }
2240
2241 return (status);
2242}
2243
2244
2245/******************************************************************************
2246**
2247** Name: MT2063_GetTemp
2248**
2249** Description: Get the MT2063 Temperature register.
2250**
2251** Parameters: h - Open handle to the tuner (from MT2063_Open).
2252** *value - value read from the register
2253**
2254** Binary
2255** Value Returned Value Approx Temp
2256** ---------------------------------------------
2257** MT2063_T_0C 0000 0C
2258** MT2063_T_10C 0001 10C
2259** MT2063_T_20C 0010 20C
2260** MT2063_T_30C 0011 30C
2261** MT2063_T_40C 0100 40C
2262** MT2063_T_50C 0101 50C
2263** MT2063_T_60C 0110 60C
2264** MT2063_T_70C 0111 70C
2265** MT2063_T_80C 1000 80C
2266** MT2063_T_90C 1001 90C
2267** MT2063_T_100C 1010 100C
2268** MT2063_T_110C 1011 110C
2269** MT2063_T_120C 1100 120C
2270** MT2063_T_130C 1101 130C
2271** MT2063_T_140C 1110 140C
2272** MT2063_T_150C 1111 150C
2273**
2274** Returns: status:
2275** MT_OK - No errors
2276** MT_COMM_ERR - Serial bus communications error
2277** MT_INV_HANDLE - Invalid tuner handle
2278** MT_ARG_NULL - Null pointer argument passed
2279** MT_ARG_RANGE - Argument out of range
2280**
2281** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus
2282** MT_WriteSub - Write byte(s) of data to the two-wire bus
2283**
2284** Revision History:
2285**
2286** SCR Date Author Description
2287** -------------------------------------------------------------------------
2288** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2289**
2290******************************************************************************/
2291UData_t MT2063_GetTemp(Handle_t h, enum MT2063_Temperature* value)
2292{
2293 UData_t status = MT2063_OK; /* Status to be returned */
2294 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
2295
2296 if (MT2063_IsValidHandle(pInfo) == 0)
2297 return MT2063_INV_HANDLE;
2298
2299 if (value == NULL)
2300 return MT2063_ARG_NULL;
2301
2302 if ((MT2063_NO_ERROR(status)) && ((pInfo->reg[MT2063_REG_TEMP_SEL] & 0xE0) != 0x00))
2303 {
2304 pInfo->reg[MT2063_REG_TEMP_SEL] &= (0x1F);
2305 status |= MT2063_WriteSub(pInfo->hUserData,
2306 pInfo->address,
2307 MT2063_REG_TEMP_SEL,
2308 &pInfo->reg[MT2063_REG_TEMP_SEL],
2309 1);
2310 }
2311
2312 if (MT2063_NO_ERROR(status))
2313 status |= MT2063_ReadSub(pInfo->hUserData,
2314 pInfo->address,
2315 MT2063_REG_TEMP_STATUS,
2316 &pInfo->reg[MT2063_REG_TEMP_STATUS],
2317 1);
2318
2319 if (MT2063_NO_ERROR(status))
2320 *value = (enum MT2063_Temperature) (pInfo->reg[MT2063_REG_TEMP_STATUS] >> 4);
2321
2322 return (status);
2323}
2324
2325
2326/****************************************************************************
2327**
2328** Name: MT2063_GetUserData
2329**
2330** Description: Gets the user-defined data item.
2331**
2332** Parameters: h - Tuner handle (returned by MT2063_Open)
2333**
2334** Returns: status:
2335** MT_OK - No errors
2336** MT_INV_HANDLE - Invalid tuner handle
2337** MT_ARG_NULL - Null pointer argument passed
2338**
2339** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
2340**
2341** The hUserData parameter is a user-specific argument
2342** that is stored internally with the other tuner-
2343** specific information.
2344**
2345** For example, if additional arguments are needed
2346** for the user to identify the device communicating
2347** with the tuner, this argument can be used to supply
2348** the necessary information.
2349**
2350** The hUserData parameter is initialized in the tuner's
2351** Open function to NULL.
2352**
2353** See Also: MT2063_Open
2354**
2355** Revision History:
2356**
2357** SCR Date Author Description
2358** -------------------------------------------------------------------------
2359** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2360**
2361****************************************************************************/
2362UData_t MT2063_GetUserData(Handle_t h,
2363 Handle_t* hUserData)
2364{
2365 UData_t status = MT2063_OK; /* Status to be returned */
2366 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
2367
2368 /* Verify that the handle passed points to a valid tuner */
2369 if (MT2063_IsValidHandle(pInfo) == 0)
2370 status = MT2063_INV_HANDLE;
2371
2372 if (hUserData == NULL)
2373 status |= MT2063_ARG_NULL;
2374
2375 if (MT2063_NO_ERROR(status))
2376 *hUserData = pInfo->hUserData;
2377
2378 return (status);
2379}
2380
2381
2382
2383/******************************************************************************
2384**
2385** Name: MT2063_SetReceiverMode
2386**
2387** Description: Set the MT2063 receiver mode
2388**
2389** --------------+----------------------------------------------
2390** Mode 0 : | MT2063_CABLE_QAM
2391** Mode 1 : | MT2063_CABLE_ANALOG
2392** Mode 2 : | MT2063_OFFAIR_COFDM
2393** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS
2394** Mode 4 : | MT2063_OFFAIR_ANALOG
2395** Mode 5 : | MT2063_OFFAIR_8VSB
2396** --------------+----+----+----+----+-----+--------------------
2397** (DNC1GC & DNC2GC are the values, which are used, when the specific
2398** DNC Output is selected, the other is always off)
2399**
2400** |<---------- Mode -------------->|
2401** Reg Field | 0 | 1 | 2 | 3 | 4 | 5 |
2402** ------------+-----+-----+-----+-----+-----+-----+
2403** RFAGCen | OFF | OFF | OFF | OFF | OFF | OFF
2404** LNARin | 0 | 0 | 3 | 3 | 3 | 3
2405** FIFFQen | 1 | 1 | 1 | 1 | 1 | 1
2406** FIFFq | 0 | 0 | 0 | 0 | 0 | 0
2407** DNC1gc | 0 | 0 | 0 | 0 | 0 | 0
2408** DNC2gc | 0 | 0 | 0 | 0 | 0 | 0
2409** GCU Auto | 1 | 1 | 1 | 1 | 1 | 1
2410** LNA max Atn | 31 | 31 | 31 | 31 | 31 | 31
2411** LNA Target | 44 | 43 | 43 | 43 | 43 | 43
2412** ign RF Ovl | 0 | 0 | 0 | 0 | 0 | 0
2413** RF max Atn | 31 | 31 | 31 | 31 | 31 | 31
2414** PD1 Target | 36 | 36 | 38 | 38 | 36 | 38
2415** ign FIF Ovl | 0 | 0 | 0 | 0 | 0 | 0
2416** FIF max Atn | 5 | 5 | 5 | 5 | 5 | 5
2417** PD2 Target | 40 | 33 | 42 | 42 | 33 | 42
2418**
2419**
2420** Parameters: pInfo - ptr to MT2063_Info_t structure
2421** Mode - desired reciever mode
2422**
2423** Usage: status = MT2063_SetReceiverMode(hMT2063, Mode);
2424**
2425** Returns: status:
2426** MT_OK - No errors
2427** MT_COMM_ERR - Serial bus communications error
2428**
2429** Dependencies: MT2063_SetReg - Write a byte of data to a HW register.
2430** Assumes that the tuner cache is valid.
2431**
2432** Revision History:
2433**
2434** SCR Date Author Description
2435** -------------------------------------------------------------------------
2436** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2437** N/A 01-10-2007 PINZ Added additional GCU Settings, FIFF Calib will be triggered
2438** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive
2439** modulation
2440** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE)
2441** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have
2442** the same settings as with MT Launcher
2443** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI
2444** Add SetParam DNC_OUTPUT_ENABLE
2445** Removed VGAGC from receiver mode,
2446** default now 1
2447** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode
2448** Add SetParam AMPGC, removed from rcvr-mode
2449** Corrected names of GCU values
2450** reorganized receiver modes, removed,
2451** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE)
2452** Actualized Receiver-Mode values
2453** N/A 11-12-2007 PINZ Ver 1.09: Actualized Receiver-Mode values
2454** N/A 11-27-2007 PINZ Improved buffered writing
2455** 01-03-2008 PINZ Ver 1.10: Added a trigger of BYPATNUP for
2456** correct wakeup of the LNA after shutdown
2457** Set AFCsd = 1 as default
2458** Changed CAP1sel default
2459** 01-14-2008 PINZ Ver 1.11: Updated gain settings
2460** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT
2461** Split SetParam up to ACLNA / ACLNA_MAX
2462** removed ACLNA_INRC/DECR (+RF & FIF)
2463** removed GCUAUTO / BYPATNDN/UP
2464**
2465******************************************************************************/
2466static UData_t MT2063_SetReceiverMode(struct MT2063_Info_t* pInfo, enum MT2063_RCVR_MODES Mode)
2467{
2468 UData_t status = MT2063_OK; /* Status to be returned */
2469 U8Data val;
2470 UData_t longval;
2471
2472
2473 if (Mode >= MT2063_NUM_RCVR_MODES)
2474 status = MT2063_ARG_RANGE;
2475
2476 /* RFAGCen */
2477 if (MT2063_NO_ERROR(status))
2478 {
2479 val = (pInfo->reg[MT2063_REG_PD1_TGT] & (U8Data)~0x40) | (RFAGCEN[Mode] ? 0x40 : 0x00);
2480 if( pInfo->reg[MT2063_REG_PD1_TGT] != val )
2481 {
2482 status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val);
2483 }
2484 }
2485
2486 /* LNARin */
2487 if (MT2063_NO_ERROR(status))
2488 {
2489 status |= MT2063_SetParam(pInfo, MT2063_LNA_RIN, LNARIN[Mode]);
2490 }
2491
2492 /* FIFFQEN and FIFFQ */
2493 if (MT2063_NO_ERROR(status))
2494 {
2495 val = (pInfo->reg[MT2063_REG_FIFF_CTRL2] & (U8Data)~0xF0) | (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
2496 if( pInfo->reg[MT2063_REG_FIFF_CTRL2] != val )
2497 {
2498 status |= MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL2, val);
2499 /* trigger FIFF calibration, needed after changing FIFFQ */
2500 val = (pInfo->reg[MT2063_REG_FIFF_CTRL] | (U8Data)0x01);
2501 status |= MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL, val);
2502 val = (pInfo->reg[MT2063_REG_FIFF_CTRL] & (U8Data)~0x01);
2503 status |= MT2063_SetReg(pInfo, MT2063_REG_FIFF_CTRL, val);
2504 }
2505 }
2506
2507 /* DNC1GC & DNC2GC */
2508 status |= MT2063_GetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, &longval);
2509 status |= MT2063_SetParam(pInfo, MT2063_DNC_OUTPUT_ENABLE, longval);
2510
2511 /* acLNAmax */
2512 if (MT2063_NO_ERROR(status))
2513 {
2514 status |= MT2063_SetParam(pInfo, MT2063_ACLNA_MAX, ACLNAMAX[Mode]);
2515 }
2516
2517 /* LNATGT */
2518 if (MT2063_NO_ERROR(status))
2519 {
2520 status |= MT2063_SetParam(pInfo, MT2063_LNA_TGT, LNATGT[Mode]);
2521 }
2522
2523 /* ACRF */
2524 if (MT2063_NO_ERROR(status))
2525 {
2526 status |= MT2063_SetParam(pInfo, MT2063_ACRF_MAX, ACRFMAX[Mode]);
2527 }
2528
2529 /* PD1TGT */
2530 if (MT2063_NO_ERROR(status))
2531 {
2532 status |= MT2063_SetParam(pInfo, MT2063_PD1_TGT, PD1TGT[Mode]);
2533 }
2534
2535 /* FIFATN */
2536 if (MT2063_NO_ERROR(status))
2537 {
2538 status |= MT2063_SetParam(pInfo, MT2063_ACFIF_MAX, ACFIFMAX[Mode]);
2539 }
2540
2541 /* PD2TGT */
2542 if (MT2063_NO_ERROR(status))
2543 {
2544 status |= MT2063_SetParam(pInfo, MT2063_PD2_TGT, PD2TGT[Mode]);
2545 }
2546
2547 /* Ignore ATN Overload */
2548 if (MT2063_NO_ERROR(status))
2549 {
2550 val = (pInfo->reg[MT2063_REG_LNA_TGT] & (U8Data)~0x80) | (RFOVDIS[Mode] ? 0x80 : 0x00);
2551 if( pInfo->reg[MT2063_REG_LNA_TGT] != val )
2552 {
2553 status |= MT2063_SetReg(pInfo, MT2063_REG_LNA_TGT, val);
2554 }
2555 }
2556
2557 /* Ignore FIF Overload */
2558 if (MT2063_NO_ERROR(status))
2559 {
2560 val = (pInfo->reg[MT2063_REG_PD1_TGT] & (U8Data)~0x80) | (FIFOVDIS[Mode] ? 0x80 : 0x00);
2561 if( pInfo->reg[MT2063_REG_PD1_TGT] != val )
2562 {
2563 status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val);
2564 }
2565 }
2566
2567 if (MT2063_NO_ERROR(status))
2568 pInfo->rcvr_mode = Mode;
2569
2570 return (status);
2571}
2572
2573
2574/******************************************************************************
2575**
2576** Name: MT2063_ReInit
2577**
2578** Description: Initialize the tuner's register values.
2579**
2580** Parameters: h - Tuner handle (returned by MT2063_Open)
2581**
2582** Returns: status:
2583** MT_OK - No errors
2584** MT_TUNER_ID_ERR - Tuner Part/Rev code mismatch
2585** MT_INV_HANDLE - Invalid tuner handle
2586** MT_COMM_ERR - Serial bus communications error
2587**
2588** Dependencies: MT_ReadSub - Read byte(s) of data from the two-wire bus
2589** MT_WriteSub - Write byte(s) of data to the two-wire bus
2590**
2591** Revision History:
2592**
2593** SCR Date Author Description
2594** -------------------------------------------------------------------------
2595** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2596** 148 09-04-2007 RSK Ver 1.02: Corrected logic of Reg 3B Reference
2597** 153 09-07-2007 RSK Ver 1.03: Lock Time improvements
2598** N/A 10-31-2007 PINZ Ver 1.08: Changed values suitable to rcvr-mode 0
2599** N/A 11-12-2007 PINZ Ver 1.09: Changed values suitable to rcvr-mode 0
2600** N/A 01-03-2007 PINZ Ver 1.10: Added AFCsd = 1 into defaults
2601** N/A 01-04-2007 PINZ Ver 1.10: Changed CAP1sel default
2602** 01-14-2008 PINZ Ver 1.11: Updated gain settings
2603** 03-18-2008 PINZ Ver 1.13: Added Support for B3
2604** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid.
2605** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW
2606**
2607******************************************************************************/
2608UData_t MT2063_ReInit(Handle_t h)
2609{
2610 U8Data all_resets = 0xF0; /* reset/load bits */
2611 UData_t status = MT2063_OK; /* Status to be returned */
2612 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
2613 U8Data *def;
2614
2615 U8Data MT2063B0_defaults[] = { /* Reg, Value */
2616 0x19, 0x05,
2617 0x1B, 0x1D,
2618 0x1C, 0x1F,
2619 0x1D, 0x0F,
2620 0x1E, 0x3F,
2621 0x1F, 0x0F,
2622 0x20, 0x3F,
2623 0x22, 0x21,
2624 0x23, 0x3F,
2625 0x24, 0x20,
2626 0x25, 0x3F,
2627 0x27, 0xEE,
2628 0x2C, 0x27, /* bit at 0x20 is cleared below */
2629 0x30, 0x03,
2630 0x2C, 0x07, /* bit at 0x20 is cleared here */
2631 0x2D, 0x87,
2632 0x2E, 0xAA,
2633 0x28, 0xE1, /* Set the FIFCrst bit here */
2634 0x28, 0xE0, /* Clear the FIFCrst bit here */
2635 0x00 };
2636
2637 /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
2638 U8Data MT2063B1_defaults[] = { /* Reg, Value */
2639 0x05, 0xF0,
2640 0x11, 0x10, /* New Enable AFCsd */
2641 0x19, 0x05,
2642 0x1A, 0x6C,
2643 0x1B, 0x24,
2644 0x1C, 0x28,
2645 0x1D, 0x8F,
2646 0x1E, 0x14,
2647 0x1F, 0x8F,
2648 0x20, 0x57,
2649 0x22, 0x21, /* New - ver 1.03 */
2650 0x23, 0x3C, /* New - ver 1.10 */
2651 0x24, 0x20, /* New - ver 1.03 */
2652 0x2C, 0x24, /* bit at 0x20 is cleared below */
2653 0x2D, 0x87, /* FIFFQ=0 */
2654 0x2F, 0xF3,
2655 0x30, 0x0C, /* New - ver 1.11 */
2656 0x31, 0x1B, /* New - ver 1.11 */
2657 0x2C, 0x04, /* bit at 0x20 is cleared here */
2658 0x28, 0xE1, /* Set the FIFCrst bit here */
2659 0x28, 0xE0, /* Clear the FIFCrst bit here */
2660 0x00 };
2661
2662 /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
2663 U8Data MT2063B3_defaults[] = { /* Reg, Value */
2664 0x05, 0xF0,
2665 0x19, 0x3D,
2666 0x2C, 0x24, /* bit at 0x20 is cleared below */
2667 0x2C, 0x04, /* bit at 0x20 is cleared here */
2668 0x28, 0xE1, /* Set the FIFCrst bit here */
2669 0x28, 0xE0, /* Clear the FIFCrst bit here */
2670 0x00 };
2671
2672 /* Verify that the handle passed points to a valid tuner */
2673 if (MT2063_IsValidHandle(pInfo) == 0)
2674 status |= MT2063_INV_HANDLE;
2675
2676 /* Read the Part/Rev code from the tuner */
2677 if (MT2063_NO_ERROR(status))
2678 {
2679 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_PART_REV, pInfo->reg, 1);
2680 }
2681
2682 if (MT2063_NO_ERROR(status) /* Check the part/rev code */
2683 && ( (pInfo->reg[MT2063_REG_PART_REV] != MT2063_B0) /* MT2063 B0 */
2684 && (pInfo->reg[MT2063_REG_PART_REV] != MT2063_B1) /* MT2063 B1 */
2685 && (pInfo->reg[MT2063_REG_PART_REV] != MT2063_B3))) /* MT2063 B3 */
2686 status |= MT2063_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */
2687
2688 /* Read the Part/Rev code (2nd byte) from the tuner */
2689 if (MT2063_NO_ERROR(status))
2690 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_RSVD_3B, &pInfo->reg[MT2063_REG_RSVD_3B], 1);
2691
2692 if (MT2063_NO_ERROR(status) /* Check the 2nd part/rev code */
2693 && ((pInfo->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) /* b7 != 0 ==> NOT MT2063 */
2694 status |= MT2063_TUNER_ID_ERR; /* Wrong tuner Part/Rev code */
2695
2696 /* Reset the tuner */
2697 if (MT2063_NO_ERROR(status))
2698 status |= MT2063_WriteSub(pInfo->hUserData,
2699 pInfo->address,
2700 MT2063_REG_LO2CQ_3,
2701 &all_resets,
2702 1);
2703
2704 /* change all of the default values that vary from the HW reset values */
2705 /* def = (pInfo->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */
2706 switch (pInfo->reg[MT2063_REG_PART_REV])
2707 {
2708 case MT2063_B3 :
2709 def = MT2063B3_defaults;
2710 break;
2711
2712 case MT2063_B1 :
2713 def = MT2063B1_defaults;
2714 break;
2715
2716 case MT2063_B0 :
2717 def = MT2063B0_defaults;
2718 break;
2719
2720 default :
2721 status |= MT2063_TUNER_ID_ERR;
2722 break;
2723 }
2724
2725 while (MT2063_NO_ERROR(status) && *def)
2726 {
2727 U8Data reg = *def++;
2728 U8Data val = *def++;
2729 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1);
2730 }
2731
2732 /* Wait for FIFF location to complete. */
2733 if (MT2063_NO_ERROR(status))
2734 {
2735 UData_t FCRUN = 1;
2736 SData_t maxReads = 10;
2737 while (MT2063_NO_ERROR(status) && (FCRUN != 0) && (maxReads-- > 0))
2738 {
2739 MT2063_Sleep(pInfo->hUserData, 2);
2740 status |= MT2063_ReadSub(pInfo->hUserData,
2741 pInfo->address,
2742 MT2063_REG_XO_STATUS,
2743 &pInfo->reg[MT2063_REG_XO_STATUS],
2744 1);
2745 FCRUN = (pInfo->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
2746 }
2747
2748 if (FCRUN != 0)
2749 status |= MT2063_TUNER_INIT_ERR | MT2063_TUNER_TIMEOUT;
2750
2751 if (MT2063_NO_ERROR(status)) /* Re-read FIFFC value */
2752 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_FIFFC, &pInfo->reg[MT2063_REG_FIFFC], 1);
2753 }
2754
2755 /* Read back all the registers from the tuner */
2756 if (MT2063_NO_ERROR(status))
2757 status |= MT2063_ReadSub(pInfo->hUserData,
2758 pInfo->address,
2759 MT2063_REG_PART_REV,
2760 pInfo->reg,
2761 MT2063_REG_END_REGS);
2762
2763 if (MT2063_NO_ERROR(status))
2764 {
2765 /* Initialize the tuner state. */
2766 pInfo->version = MT2063_VERSION;
2767 pInfo->tuner_id = pInfo->reg[MT2063_REG_PART_REV];
2768 pInfo->AS_Data.f_ref = MT2063_REF_FREQ;
2769 pInfo->AS_Data.f_if1_Center = (pInfo->AS_Data.f_ref / 8) * ((UData_t) pInfo->reg[MT2063_REG_FIFFC] + 640);
2770 pInfo->AS_Data.f_if1_bw = MT2063_IF1_BW;
2771 pInfo->AS_Data.f_out = 43750000UL;
2772 pInfo->AS_Data.f_out_bw = 6750000UL;
2773 pInfo->AS_Data.f_zif_bw = MT2063_ZIF_BW;
2774 pInfo->AS_Data.f_LO1_Step = pInfo->AS_Data.f_ref / 64;
2775 pInfo->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
2776 pInfo->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
2777 pInfo->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
2778 pInfo->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
2779 pInfo->AS_Data.f_if1_Request = pInfo->AS_Data.f_if1_Center;
2780 pInfo->AS_Data.f_LO1 = 2181000000UL;
2781 pInfo->AS_Data.f_LO2 = 1486249786UL;
2782 pInfo->f_IF1_actual = pInfo->AS_Data.f_if1_Center;
2783 pInfo->AS_Data.f_in = pInfo->AS_Data.f_LO1 - pInfo->f_IF1_actual;
2784 pInfo->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
2785 pInfo->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
2786 pInfo->num_regs = MT2063_REG_END_REGS;
2787 pInfo->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
2788 pInfo->ctfilt_sw = 0;
2789 }
2790
2791 if (MT2063_NO_ERROR(status))
2792 {
2793 pInfo->CTFiltMax[ 0] = 69230000;
2794 pInfo->CTFiltMax[ 1] = 105770000;
2795 pInfo->CTFiltMax[ 2] = 140350000;
2796 pInfo->CTFiltMax[ 3] = 177110000;
2797 pInfo->CTFiltMax[ 4] = 212860000;
2798 pInfo->CTFiltMax[ 5] = 241130000;
2799 pInfo->CTFiltMax[ 6] = 274370000;
2800 pInfo->CTFiltMax[ 7] = 309820000;
2801 pInfo->CTFiltMax[ 8] = 342450000;
2802 pInfo->CTFiltMax[ 9] = 378870000;
2803 pInfo->CTFiltMax[10] = 416210000;
2804 pInfo->CTFiltMax[11] = 456500000;
2805 pInfo->CTFiltMax[12] = 495790000;
2806 pInfo->CTFiltMax[13] = 534530000;
2807 pInfo->CTFiltMax[14] = 572610000;
2808 pInfo->CTFiltMax[15] = 598970000;
2809 pInfo->CTFiltMax[16] = 635910000;
2810 pInfo->CTFiltMax[17] = 672130000;
2811 pInfo->CTFiltMax[18] = 714840000;
2812 pInfo->CTFiltMax[19] = 739660000;
2813 pInfo->CTFiltMax[20] = 770410000;
2814 pInfo->CTFiltMax[21] = 814660000;
2815 pInfo->CTFiltMax[22] = 846950000;
2816 pInfo->CTFiltMax[23] = 867820000;
2817 pInfo->CTFiltMax[24] = 915980000;
2818 pInfo->CTFiltMax[25] = 947450000;
2819 pInfo->CTFiltMax[26] = 983110000;
2820 pInfo->CTFiltMax[27] = 1021630000;
2821 pInfo->CTFiltMax[28] = 1061870000;
2822 pInfo->CTFiltMax[29] = 1098330000;
2823 pInfo->CTFiltMax[30] = 1138990000;
2824 }
2825
2826 /*
2827 ** Fetch the FCU osc value and use it and the fRef value to
2828 ** scale all of the Band Max values
2829 */
2830 if (MT2063_NO_ERROR(status))
2831 {
2832 UData_t fcu_osc;
2833 UData_t i;
2834
2835 pInfo->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
2836 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_CTUNE_CTRL, &pInfo->reg[MT2063_REG_CTUNE_CTRL], 1);
2837 /* Read the ClearTune filter calibration value */
2838 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_FIFFC, &pInfo->reg[MT2063_REG_FIFFC], 1);
2839 fcu_osc = pInfo->reg[MT2063_REG_FIFFC];
2840
2841 pInfo->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
2842 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_CTUNE_CTRL, &pInfo->reg[MT2063_REG_CTUNE_CTRL], 1);
2843
2844 /* Adjust each of the values in the ClearTune filter cross-over table */
2845 for (i = 0; i < 31; i++)
2846 {
2847 pInfo->CTFiltMax[i] = (pInfo->CTFiltMax[i]/768) * (fcu_osc + 640);
2848 }
2849 }
2850
2851 return (status);
2852}
2853
2854
2855/******************************************************************************
2856**
2857** Name: MT2063_SetGPIO
2858**
2859** Description: Modify the MT2063 GPIO value.
2860**
2861** Parameters: h - Open handle to the tuner (from MT2063_Open).
2862** gpio_id - Selects GPIO0, GPIO1 or GPIO2
2863** attr - Selects input readback, I/O direction or
2864** output value
2865** value - value to set GPIO pin 15, 14 or 19
2866**
2867** Usage: status = MT2063_SetGPIO(hMT2063, MT2063_GPIO1, MT2063_GPIO_OUT, 1);
2868**
2869** Returns: status:
2870** MT_OK - No errors
2871** MT_COMM_ERR - Serial bus communications error
2872** MT_INV_HANDLE - Invalid tuner handle
2873**
2874** Dependencies: MT_WriteSub - Write byte(s) of data to the two-wire-bus
2875**
2876** Revision History:
2877**
2878** SCR Date Author Description
2879** -------------------------------------------------------------------------
2880** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2881**
2882******************************************************************************/
2883UData_t MT2063_SetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id,
2884 enum MT2063_GPIO_Attr attr,
2885 UData_t value)
2886{
2887 UData_t status = MT2063_OK; /* Status to be returned */
2888 U8Data regno;
2889 SData_t shift;
2890 static U8Data GPIOreg[3] = {0x15, 0x19, 0x18};
2891 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
2892
2893 if (MT2063_IsValidHandle(pInfo) == 0)
2894 return MT2063_INV_HANDLE;
2895
2896 regno = GPIOreg[attr];
2897
2898 shift = (gpio_id - MT2063_GPIO0 + 5);
2899
2900 if (value & 0x01)
2901 pInfo->reg[regno] |= (0x01 << shift);
2902 else
2903 pInfo->reg[regno] &= ~(0x01 << shift);
2904 status = MT2063_WriteSub(pInfo->hUserData, pInfo->address, regno, &pInfo->reg[regno], 1);
2905
2906 return (status);
2907}
2908
2909
2910/****************************************************************************
2911**
2912** Name: MT2063_SetParam
2913**
2914** Description: Sets a tuning algorithm parameter.
2915**
2916** This function provides access to the internals of the
2917** tuning algorithm. You can override many of the tuning
2918** algorithm defaults using this function.
2919**
2920** Parameters: h - Tuner handle (returned by MT2063_Open)
2921** param - Tuning algorithm parameter
2922** (see enum MT2063_Param)
2923** nValue - value to be set
2924**
2925** param Description
2926** ---------------------- --------------------------------
2927** MT2063_SRO_FREQ crystal frequency
2928** MT2063_STEPSIZE minimum tuning step size
2929** MT2063_LO1_FREQ LO1 frequency
2930** MT2063_LO1_STEPSIZE LO1 minimum step size
2931** MT2063_LO1_FRACN_AVOID LO1 FracN keep-out region
2932** MT2063_IF1_REQUEST Requested 1st IF
2933** MT2063_ZIF_BW zero-IF bandwidth
2934** MT2063_LO2_FREQ LO2 frequency
2935** MT2063_LO2_STEPSIZE LO2 minimum step size
2936** MT2063_LO2_FRACN_AVOID LO2 FracN keep-out region
2937** MT2063_OUTPUT_FREQ output center frequency
2938** MT2063_OUTPUT_BW output bandwidth
2939** MT2063_LO_SEPARATION min inter-tuner LO separation
2940** MT2063_MAX_HARM1 max # of intra-tuner harmonics
2941** MT2063_MAX_HARM2 max # of inter-tuner harmonics
2942** MT2063_RCVR_MODE Predefined modes
2943** MT2063_LNA_RIN Set LNA Rin (*)
2944** MT2063_LNA_TGT Set target power level at LNA (*)
2945** MT2063_PD1_TGT Set target power level at PD1 (*)
2946** MT2063_PD2_TGT Set target power level at PD2 (*)
2947** MT2063_ACLNA_MAX LNA attenuator limit (*)
2948** MT2063_ACRF_MAX RF attenuator limit (*)
2949** MT2063_ACFIF_MAX FIF attenuator limit (*)
2950** MT2063_DNC_OUTPUT_ENABLE DNC output selection
2951** MT2063_VGAGC VGA gain code
2952** MT2063_VGAOI VGA output current
2953** MT2063_TAGC TAGC setting
2954** MT2063_AMPGC AMP gain code
2955** MT2063_AVOID_DECT Avoid DECT Frequencies
2956** MT2063_CTFILT_SW Cleartune filter selection
2957**
2958** (*) This parameter is set by MT2063_RCVR_MODE, do not call
2959** additionally.
2960**
2961** Usage: status |= MT2063_SetParam(hMT2063,
2962** MT2063_STEPSIZE,
2963** 50000);
2964**
2965** Returns: status:
2966** MT_OK - No errors
2967** MT_INV_HANDLE - Invalid tuner handle
2968** MT_ARG_NULL - Null pointer argument passed
2969** MT_ARG_RANGE - Invalid parameter requested
2970** or set value out of range
2971** or non-writable parameter
2972**
2973** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
2974**
2975** See Also: MT2063_GetParam, MT2063_Open
2976**
2977** Revision History:
2978**
2979** SCR Date Author Description
2980** -------------------------------------------------------------------------
2981** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
2982** 154 09-13-2007 RSK Ver 1.05: Get/SetParam changes for LOx_FREQ
2983** 10-31-2007 PINZ Ver 1.08: Get/SetParam add VGAGC, VGAOI, AMPGC, TAGC
2984** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT
2985** Split SetParam up to ACLNA / ACLNA_MAX
2986** removed ACLNA_INRC/DECR (+RF & FIF)
2987** removed GCUAUTO / BYPATNDN/UP
2988** 175 I 06-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs.
2989** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid.
2990** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW
2991**
2992****************************************************************************/
2993UData_t MT2063_SetParam(Handle_t h,
2994 enum MT2063_Param param,
2995 UData_t nValue)
2996{
2997 UData_t status = MT2063_OK; /* Status to be returned */
2998 U8Data val=0;
2999 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
3000
3001 /* Verify that the handle passed points to a valid tuner */
3002 if (MT2063_IsValidHandle(pInfo) == 0)
3003 status |= MT2063_INV_HANDLE;
3004
3005 if (MT2063_NO_ERROR(status))
3006 {
3007 switch (param)
3008 {
3009 /* crystal frequency */
3010 case MT2063_SRO_FREQ:
3011 pInfo->AS_Data.f_ref = nValue;
3012 pInfo->AS_Data.f_LO1_FracN_Avoid = 0;
3013 pInfo->AS_Data.f_LO2_FracN_Avoid = nValue / 80 - 1;
3014 pInfo->AS_Data.f_LO1_Step = nValue / 64;
3015 pInfo->AS_Data.f_if1_Center = (pInfo->AS_Data.f_ref / 8) * (pInfo->reg[MT2063_REG_FIFFC] + 640);
3016 break;
3017
3018 /* minimum tuning step size */
3019 case MT2063_STEPSIZE:
3020 pInfo->AS_Data.f_LO2_Step = nValue;
3021 break;
3022
3023
3024 /* LO1 frequency */
3025 case MT2063_LO1_FREQ:
3026 {
3027 /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */
3028 /* Capture the Divider and Numerator portions of other LO */
3029 U8Data tempLO2CQ[3];
3030 U8Data tempLO2C[3];
3031 U8Data tmpOneShot;
3032 UData_t Div, FracN;
3033 U8Data restore = 0;
3034
3035 /* Buffer the queue for restoration later and get actual LO2 values. */
3036 status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_1, &(tempLO2CQ[0]), 3);
3037 status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, MT2063_REG_LO2C_1, &(tempLO2C[0]), 3);
3038
3039 /* clear the one-shot bits */
3040 tempLO2CQ[2] = tempLO2CQ[2] & 0x0F;
3041 tempLO2C[2] = tempLO2C[2] & 0x0F;
3042
3043 /* only write the queue values if they are different from the actual. */
3044 if( ( tempLO2CQ[0] != tempLO2C[0] ) ||
3045 ( tempLO2CQ[1] != tempLO2C[1] ) ||
3046 ( tempLO2CQ[2] != tempLO2C[2] ) )
3047 {
3048 /* put actual LO2 value into queue (with 0 in one-shot bits) */
3049 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_1, &(tempLO2C[0]), 3);
3050
3051 if( status == MT2063_OK )
3052 {
3053 /* cache the bytes just written. */
3054 pInfo->reg[MT2063_REG_LO2CQ_1] = tempLO2C[0];
3055 pInfo->reg[MT2063_REG_LO2CQ_2] = tempLO2C[1];
3056 pInfo->reg[MT2063_REG_LO2CQ_3] = tempLO2C[2];
3057 }
3058 restore = 1;
3059 }
3060
3061 /* Calculate the Divider and Numberator components of LO1 */
3062 status = MT2063_CalcLO1Mult(&Div, &FracN, nValue, pInfo->AS_Data.f_ref/64, pInfo->AS_Data.f_ref);
3063 pInfo->reg[MT2063_REG_LO1CQ_1] = (U8Data)(Div & 0x00FF);
3064 pInfo->reg[MT2063_REG_LO1CQ_2] = (U8Data)(FracN);
3065 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &pInfo->reg[MT2063_REG_LO1CQ_1], 2);
3066
3067 /* set the one-shot bit to load the pair of LO values */
3068 tmpOneShot = tempLO2CQ[2] | 0xE0;
3069 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_3, &tmpOneShot, 1);
3070
3071 /* only restore the queue values if they were different from the actual. */
3072 if( restore )
3073 {
3074 /* put actual LO2 value into queue (0 in one-shot bits) */
3075 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_1, &(tempLO2CQ[0]), 3);
3076
3077 /* cache the bytes just written. */
3078 pInfo->reg[MT2063_REG_LO2CQ_1] = tempLO2CQ[0];
3079 pInfo->reg[MT2063_REG_LO2CQ_2] = tempLO2CQ[1];
3080 pInfo->reg[MT2063_REG_LO2CQ_3] = tempLO2CQ[2];
3081 }
3082
3083 MT2063_GetParam( pInfo->hUserData, MT2063_LO1_FREQ, &pInfo->AS_Data.f_LO1 );
3084 }
3085 break;
3086
3087 /* LO1 minimum step size */
3088 case MT2063_LO1_STEPSIZE:
3089 pInfo->AS_Data.f_LO1_Step = nValue;
3090 break;
3091
3092 /* LO1 FracN keep-out region */
3093 case MT2063_LO1_FRACN_AVOID_PARAM:
3094 pInfo->AS_Data.f_LO1_FracN_Avoid = nValue;
3095 break;
3096
3097 /* Requested 1st IF */
3098 case MT2063_IF1_REQUEST:
3099 pInfo->AS_Data.f_if1_Request = nValue;
3100 break;
3101
3102 /* zero-IF bandwidth */
3103 case MT2063_ZIF_BW:
3104 pInfo->AS_Data.f_zif_bw = nValue;
3105 break;
3106
3107 /* LO2 frequency */
3108 case MT2063_LO2_FREQ:
3109 {
3110 /* Note: LO1 and LO2 are BOTH written at toggle of LDLOos */
3111 /* Capture the Divider and Numerator portions of other LO */
3112 U8Data tempLO1CQ[2];
3113 U8Data tempLO1C[2];
3114 UData_t Div2;
3115 UData_t FracN2;
3116 U8Data tmpOneShot;
3117 U8Data restore = 0;
3118
3119 /* Buffer the queue for restoration later and get actual LO2 values. */
3120 status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &(tempLO1CQ[0]), 2);
3121 status |= MT2063_ReadSub (pInfo->hUserData, pInfo->address, MT2063_REG_LO1C_1, &(tempLO1C[0]), 2);
3122
3123 /* only write the queue values if they are different from the actual. */
3124 if( (tempLO1CQ[0] != tempLO1C[0]) || (tempLO1CQ[1] != tempLO1C[1]) )
3125 {
3126 /* put actual LO1 value into queue */
3127 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &(tempLO1C[0]), 2);
3128
3129 /* cache the bytes just written. */
3130 pInfo->reg[MT2063_REG_LO1CQ_1] = tempLO1C[0];
3131 pInfo->reg[MT2063_REG_LO1CQ_2] = tempLO1C[1];
3132 restore = 1;
3133 }
3134
3135 /* Calculate the Divider and Numberator components of LO2 */
3136 status = MT2063_CalcLO2Mult(&Div2, &FracN2, nValue, pInfo->AS_Data.f_ref/8191, pInfo->AS_Data.f_ref);
3137 pInfo->reg[MT2063_REG_LO2CQ_1] = (U8Data)((Div2 << 1) | ((FracN2 >> 12) & 0x01) ) & 0xFF;
3138 pInfo->reg[MT2063_REG_LO2CQ_2] = (U8Data)((FracN2 >> 4) & 0xFF);
3139 pInfo->reg[MT2063_REG_LO2CQ_3] = (U8Data)((FracN2 & 0x0F) );
3140 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &pInfo->reg[MT2063_REG_LO1CQ_1], 3);
3141
3142 /* set the one-shot bit to load the LO values */
3143 tmpOneShot = pInfo->reg[MT2063_REG_LO2CQ_3] | 0xE0;
3144 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_3, &tmpOneShot, 1);
3145
3146 /* only restore LO1 queue value if they were different from the actual. */
3147 if( restore )
3148 {
3149 /* put previous LO1 queue value back into queue */
3150 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &(tempLO1CQ[0]), 2);
3151
3152 /* cache the bytes just written. */
3153 pInfo->reg[MT2063_REG_LO1CQ_1] = tempLO1CQ[0];
3154 pInfo->reg[MT2063_REG_LO1CQ_2] = tempLO1CQ[1];
3155 }
3156
3157 MT2063_GetParam( pInfo->hUserData, MT2063_LO2_FREQ, &pInfo->AS_Data.f_LO2 );
3158 }
3159 break;
3160
3161 /* LO2 minimum step size */
3162 case MT2063_LO2_STEPSIZE:
3163 pInfo->AS_Data.f_LO2_Step = nValue;
3164 break;
3165
3166 /* LO2 FracN keep-out region */
3167 case MT2063_LO2_FRACN_AVOID:
3168 pInfo->AS_Data.f_LO2_FracN_Avoid = nValue;
3169 break;
3170
3171 /* output center frequency */
3172 case MT2063_OUTPUT_FREQ:
3173 pInfo->AS_Data.f_out = nValue;
3174 break;
3175
3176 /* output bandwidth */
3177 case MT2063_OUTPUT_BW:
3178 pInfo->AS_Data.f_out_bw = nValue + 750000;
3179 break;
3180
3181 /* min inter-tuner LO separation */
3182 case MT2063_LO_SEPARATION:
3183 pInfo->AS_Data.f_min_LO_Separation = nValue;
3184 break;
3185
3186 /* max # of intra-tuner harmonics */
3187 case MT2063_MAX_HARM1:
3188 pInfo->AS_Data.maxH1 = nValue;
3189 break;
3190
3191 /* max # of inter-tuner harmonics */
3192 case MT2063_MAX_HARM2:
3193 pInfo->AS_Data.maxH2 = nValue;
3194 break;
3195
3196 case MT2063_RCVR_MODE:
3197 status |= MT2063_SetReceiverMode(pInfo, (enum MT2063_RCVR_MODES)nValue);
3198 break;
3199
3200 /* Set LNA Rin -- nValue is desired value */
3201 case MT2063_LNA_RIN:
3202 val = ( pInfo->reg[MT2063_REG_CTRL_2C] & (U8Data)~0x03) | (nValue & 0x03);
3203 if( pInfo->reg[MT2063_REG_CTRL_2C] != val )
3204 {
3205 status |= MT2063_SetReg(pInfo, MT2063_REG_CTRL_2C, val);
3206 }
3207 break;
3208
3209 /* Set target power level at LNA -- nValue is desired value */
3210 case MT2063_LNA_TGT:
3211 val = ( pInfo->reg[MT2063_REG_LNA_TGT] & (U8Data)~0x3F) | (nValue & 0x3F);
3212 if( pInfo->reg[MT2063_REG_LNA_TGT] != val )
3213 {
3214 status |= MT2063_SetReg(pInfo, MT2063_REG_LNA_TGT, val);
3215 }
3216 break;
3217
3218 /* Set target power level at PD1 -- nValue is desired value */
3219 case MT2063_PD1_TGT:
3220 val = ( pInfo->reg[MT2063_REG_PD1_TGT] & (U8Data)~0x3F) | (nValue & 0x3F);
3221 if( pInfo->reg[MT2063_REG_PD1_TGT] != val )
3222 {
3223 status |= MT2063_SetReg(pInfo, MT2063_REG_PD1_TGT, val);
3224 }
3225 break;
3226
3227 /* Set target power level at PD2 -- nValue is desired value */
3228 case MT2063_PD2_TGT:
3229 val = ( pInfo->reg[MT2063_REG_PD2_TGT] & (U8Data)~0x3F) | (nValue & 0x3F);
3230 if( pInfo->reg[MT2063_REG_PD2_TGT] != val )
3231 {
3232 status |= MT2063_SetReg(pInfo, MT2063_REG_PD2_TGT, val);
3233 }
3234 break;
3235
3236 /* Set LNA atten limit -- nValue is desired value */
3237 case MT2063_ACLNA_MAX:
3238 val = ( pInfo->reg[MT2063_REG_LNA_OV] & (U8Data)~0x1F) | (nValue & 0x1F);
3239 if( pInfo->reg[MT2063_REG_LNA_OV] != val )
3240 {
3241 status |= MT2063_SetReg(pInfo, MT2063_REG_LNA_OV, val);
3242 }
3243 break;
3244
3245 /* Set RF atten limit -- nValue is desired value */
3246 case MT2063_ACRF_MAX:
3247 val = ( pInfo->reg[MT2063_REG_RF_OV] & (U8Data)~0x1F) | (nValue & 0x1F);
3248 if( pInfo->reg[MT2063_REG_RF_OV] != val )
3249 {
3250 status |= MT2063_SetReg(pInfo, MT2063_REG_RF_OV, val);
3251 }
3252 break;
3253
3254 /* Set FIF atten limit -- nValue is desired value, max. 5 if no B3 */
3255 case MT2063_ACFIF_MAX:
3256 if ( pInfo->reg[MT2063_REG_PART_REV] != MT2063_B3 && nValue > 5)
3257 nValue = 5;
3258 val = ( pInfo->reg[MT2063_REG_FIF_OV] & (U8Data)~0x1F) | (nValue & 0x1F);
3259 if( pInfo->reg[MT2063_REG_FIF_OV] != val )
3260 {
3261 status |= MT2063_SetReg(pInfo, MT2063_REG_FIF_OV, val);
3262 }
3263 break;
3264
3265 case MT2063_DNC_OUTPUT_ENABLE:
3266 /* selects, which DNC output is used */
3267 switch ((enum MT2063_DNC_Output_Enable)nValue)
3268 {
3269 case MT2063_DNC_NONE :
3270 {
3271 val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC ) | 0x03; /* Set DNC1GC=3 */
3272 if (pInfo->reg[MT2063_REG_DNC_GAIN] != val)
3273 status |= MT2063_SetReg(h, MT2063_REG_DNC_GAIN, val);
3274
3275 val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC ) | 0x03; /* Set DNC2GC=3 */
3276 if (pInfo->reg[MT2063_REG_VGA_GAIN] != val)
3277 status |= MT2063_SetReg(h, MT2063_REG_VGA_GAIN, val);
3278
3279 val = (pInfo->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
3280 if (pInfo->reg[MT2063_REG_RSVD_20] != val)
3281 status |= MT2063_SetReg(h, MT2063_REG_RSVD_20, val);
3282
3283 break;
3284 }
3285 case MT2063_DNC_1 :
3286 {
3287 val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC ) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */
3288 if (pInfo->reg[MT2063_REG_DNC_GAIN] != val)
3289 status |= MT2063_SetReg(h, MT2063_REG_DNC_GAIN, val);
3290
3291 val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC ) | 0x03; /* Set DNC2GC=3 */
3292 if (pInfo->reg[MT2063_REG_VGA_GAIN] != val)
3293 status |= MT2063_SetReg(h, MT2063_REG_VGA_GAIN, val);
3294
3295 val = (pInfo->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
3296 if (pInfo->reg[MT2063_REG_RSVD_20] != val)
3297 status |= MT2063_SetReg(h, MT2063_REG_RSVD_20, val);
3298
3299 break;
3300 }
3301 case MT2063_DNC_2 :
3302 {
3303 val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC ) | 0x03; /* Set DNC1GC=3 */
3304 if (pInfo->reg[MT2063_REG_DNC_GAIN] != val)
3305 status |= MT2063_SetReg(h, MT2063_REG_DNC_GAIN, val);
3306
3307 val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC ) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */
3308 if (pInfo->reg[MT2063_REG_VGA_GAIN] != val)
3309 status |= MT2063_SetReg(h, MT2063_REG_VGA_GAIN, val);
3310
3311 val = (pInfo->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
3312 if (pInfo->reg[MT2063_REG_RSVD_20] != val)
3313 status |= MT2063_SetReg(h, MT2063_REG_RSVD_20, val);
3314
3315 break;
3316 }
3317 case MT2063_DNC_BOTH :
3318 {
3319 val = (pInfo->reg[MT2063_REG_DNC_GAIN] & 0xFC ) | (DNC1GC[pInfo->rcvr_mode] & 0x03); /* Set DNC1GC=x */
3320 if (pInfo->reg[MT2063_REG_DNC_GAIN] != val)
3321 status |= MT2063_SetReg(h, MT2063_REG_DNC_GAIN, val);
3322
3323 val = (pInfo->reg[MT2063_REG_VGA_GAIN] & 0xFC ) | (DNC2GC[pInfo->rcvr_mode] & 0x03); /* Set DNC2GC=x */
3324 if (pInfo->reg[MT2063_REG_VGA_GAIN] != val)
3325 status |= MT2063_SetReg(h, MT2063_REG_VGA_GAIN, val);
3326
3327 val = (pInfo->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
3328 if (pInfo->reg[MT2063_REG_RSVD_20] != val)
3329 status |= MT2063_SetReg(h, MT2063_REG_RSVD_20, val);
3330
3331 break;
3332 }
3333 default : break;
3334 }
3335 break;
3336
3337 case MT2063_VGAGC:
3338 /* Set VGA gain code */
3339 val = (pInfo->reg[MT2063_REG_VGA_GAIN] & (U8Data)~0x0C) | ( (nValue & 0x03) << 2);
3340 if( pInfo->reg[MT2063_REG_VGA_GAIN] != val )
3341 {
3342 status |= MT2063_SetReg(pInfo, MT2063_REG_VGA_GAIN, val);
3343 }
3344 break;
3345
3346 case MT2063_VGAOI:
3347 /* Set VGA bias current */
3348 val = (pInfo->reg[MT2063_REG_RSVD_31] & (U8Data)~0x07) | (nValue & 0x07);
3349 if( pInfo->reg[MT2063_REG_RSVD_31] != val )
3350 {
3351 status |= MT2063_SetReg(pInfo, MT2063_REG_RSVD_31, val);
3352 }
3353 break;
3354
3355 case MT2063_TAGC:
3356 /* Set TAGC */
3357 val = (pInfo->reg[MT2063_REG_RSVD_1E] & (U8Data)~0x03) | (nValue & 0x03);
3358 if( pInfo->reg[MT2063_REG_RSVD_1E] != val )
3359 {
3360 status |= MT2063_SetReg(pInfo, MT2063_REG_RSVD_1E, val);
3361 }
3362 break;
3363
3364 case MT2063_AMPGC:
3365 /* Set Amp gain code */
3366 val = (pInfo->reg[MT2063_REG_TEMP_SEL] & (U8Data)~0x03) | (nValue & 0x03);
3367 if( pInfo->reg[MT2063_REG_TEMP_SEL] != val )
3368 {
3369 status |= MT2063_SetReg(pInfo, MT2063_REG_TEMP_SEL, val);
3370 }
3371 break;
3372
3373 /* Avoid DECT Frequencies */
3374 case MT2063_AVOID_DECT:
3375 {
3376 enum MT2063_DECT_Avoid_Type newAvoidSetting = (enum MT2063_DECT_Avoid_Type) nValue;
3377 if( (newAvoidSetting >= MT2063_NO_DECT_AVOIDANCE) && (newAvoidSetting <= MT2063_AVOID_BOTH) )
3378 {
3379 pInfo->AS_Data.avoidDECT = newAvoidSetting;
3380 }
3381 }
3382 break;
3383
3384 /* Cleartune filter selection: 0 - by IC (default), 1 - by software */
3385 case MT2063_CTFILT_SW:
3386 pInfo->ctfilt_sw = (nValue & 0x01);
3387 break;
3388
3389 /* These parameters are read-only */
3390 case MT2063_IC_ADDR:
3391 case MT2063_MAX_OPEN:
3392 case MT2063_NUM_OPEN:
3393 case MT2063_INPUT_FREQ:
3394 case MT2063_IF1_ACTUAL:
3395 case MT2063_IF1_CENTER:
3396 case MT2063_IF1_BW:
3397 case MT2063_AS_ALG:
3398 case MT2063_EXCL_ZONES:
3399 case MT2063_SPUR_AVOIDED:
3400 case MT2063_NUM_SPURS:
3401 case MT2063_SPUR_PRESENT:
3402 case MT2063_ACLNA:
3403 case MT2063_ACRF:
3404 case MT2063_ACFIF:
3405 case MT2063_EOP:
3406 default:
3407 status |= MT2063_ARG_RANGE;
3408 }
3409 }
3410 return (status);
3411}
3412
3413
3414/****************************************************************************
3415**
3416** Name: MT2063_SetPowerMaskBits
3417**
3418** Description: Sets the power-down mask bits for various sections of
3419** the MT2063
3420**
3421** Parameters: h - Tuner handle (returned by MT2063_Open)
3422** Bits - Mask bits to be set.
3423**
3424** See definition of MT2063_Mask_Bits type for description
3425** of each of the power bits.
3426**
3427** Returns: status:
3428** MT_OK - No errors
3429** MT_INV_HANDLE - Invalid tuner handle
3430** MT_COMM_ERR - Serial bus communications error
3431**
3432** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
3433**
3434** Revision History:
3435**
3436** SCR Date Author Description
3437** -------------------------------------------------------------------------
3438** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3439**
3440****************************************************************************/
3441UData_t MT2063_SetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits)
3442{
3443 UData_t status = MT2063_OK; /* Status to be returned */
3444 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
3445
3446 /* Verify that the handle passed points to a valid tuner */
3447 if (MT2063_IsValidHandle(pInfo) == 0)
3448 status = MT2063_INV_HANDLE;
3449 else
3450 {
3451 Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
3452 if ((Bits & 0xFF00) != 0)
3453 {
3454 pInfo->reg[MT2063_REG_PWR_2] |= (U8Data)((Bits & 0xFF00) >> 8);
3455 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_2, &pInfo->reg[MT2063_REG_PWR_2], 1);
3456 }
3457 if ((Bits & 0xFF) != 0)
3458 {
3459 pInfo->reg[MT2063_REG_PWR_1] |= ((U8Data)Bits & 0xFF);
3460 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 1);
3461 }
3462 }
3463
3464 return (status);
3465}
3466
3467
3468/****************************************************************************
3469**
3470** Name: MT2063_ClearPowerMaskBits
3471**
3472** Description: Clears the power-down mask bits for various sections of
3473** the MT2063
3474**
3475** Parameters: h - Tuner handle (returned by MT2063_Open)
3476** Bits - Mask bits to be cleared.
3477**
3478** See definition of MT2063_Mask_Bits type for description
3479** of each of the power bits.
3480**
3481** Returns: status:
3482** MT_OK - No errors
3483** MT_INV_HANDLE - Invalid tuner handle
3484** MT_COMM_ERR - Serial bus communications error
3485**
3486** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
3487**
3488** Revision History:
3489**
3490** SCR Date Author Description
3491** -------------------------------------------------------------------------
3492** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3493**
3494****************************************************************************/
3495UData_t MT2063_ClearPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits)
3496{
3497 UData_t status = MT2063_OK; /* Status to be returned */
3498 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
3499
3500 /* Verify that the handle passed points to a valid tuner */
3501 if (MT2063_IsValidHandle(pInfo) == 0)
3502 status = MT2063_INV_HANDLE;
3503 else
3504 {
3505 Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
3506 if ((Bits & 0xFF00) != 0)
3507 {
3508 pInfo->reg[MT2063_REG_PWR_2] &= ~(U8Data)(Bits >> 8);
3509 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_2, &pInfo->reg[MT2063_REG_PWR_2], 1);
3510 }
3511 if ((Bits & 0xFF) != 0)
3512 {
3513 pInfo->reg[MT2063_REG_PWR_1] &= ~(U8Data)(Bits & 0xFF);
3514 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 1);
3515 }
3516 }
3517
3518 return (status);
3519}
3520
3521
3522/****************************************************************************
3523**
3524** Name: MT2063_GetPowerMaskBits
3525**
3526** Description: Returns a mask of the enabled power shutdown bits
3527**
3528** Parameters: h - Tuner handle (returned by MT2063_Open)
3529** Bits - Mask bits to currently set.
3530**
3531** See definition of MT2063_Mask_Bits type for description
3532** of each of the power bits.
3533**
3534** Returns: status:
3535** MT_OK - No errors
3536** MT_INV_HANDLE - Invalid tuner handle
3537** MT_ARG_NULL - Output argument is NULL
3538** MT_COMM_ERR - Serial bus communications error
3539**
3540** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
3541**
3542** Revision History:
3543**
3544** SCR Date Author Description
3545** -------------------------------------------------------------------------
3546** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3547**
3548****************************************************************************/
3549UData_t MT2063_GetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits *Bits)
3550{
3551 UData_t status = MT2063_OK; /* Status to be returned */
3552 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
3553
3554 /* Verify that the handle passed points to a valid tuner */
3555 if (MT2063_IsValidHandle(pInfo) == 0)
3556 status = MT2063_INV_HANDLE;
3557 else
3558 {
3559 if (Bits == NULL)
3560 status |= MT2063_ARG_NULL;
3561
3562 if (MT2063_NO_ERROR(status))
3563 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 2);
3564
3565 if (MT2063_NO_ERROR(status))
3566 {
3567 *Bits = (enum MT2063_Mask_Bits)(((SData_t)pInfo->reg[MT2063_REG_PWR_2] << 8) + pInfo->reg[MT2063_REG_PWR_1]);
3568 *Bits = (enum MT2063_Mask_Bits)(*Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
3569 }
3570 }
3571
3572 return (status);
3573}
3574
3575
3576/****************************************************************************
3577**
3578** Name: MT2063_EnableExternalShutdown
3579**
3580** Description: Enables or disables the operation of the external
3581** shutdown pin
3582**
3583** Parameters: h - Tuner handle (returned by MT2063_Open)
3584** Enabled - 0 = disable the pin, otherwise enable it
3585**
3586** Returns: status:
3587** MT_OK - No errors
3588** MT_INV_HANDLE - Invalid tuner handle
3589** MT_COMM_ERR - Serial bus communications error
3590**
3591** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
3592**
3593** Revision History:
3594**
3595** SCR Date Author Description
3596** -------------------------------------------------------------------------
3597** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3598**
3599****************************************************************************/
3600UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled)
3601{
3602 UData_t status = MT2063_OK; /* Status to be returned */
3603 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
3604
3605 /* Verify that the handle passed points to a valid tuner */
3606 if (MT2063_IsValidHandle(pInfo) == 0)
3607 status = MT2063_INV_HANDLE;
3608 else
3609 {
3610 if (Enabled == 0)
3611 pInfo->reg[MT2063_REG_PWR_1] &= ~0x08; /* Turn off the bit */
3612 else
3613 pInfo->reg[MT2063_REG_PWR_1] |= 0x08; /* Turn the bit on */
3614
3615 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 1);
3616 }
3617
3618 return (status);
3619}
3620
3621
3622/****************************************************************************
3623**
3624** Name: MT2063_SoftwareShutdown
3625**
3626** Description: Enables or disables software shutdown function. When
3627** Shutdown==1, any section whose power mask is set will be
3628** shutdown.
3629**
3630** Parameters: h - Tuner handle (returned by MT2063_Open)
3631** Shutdown - 1 = shutdown the masked sections, otherwise
3632** power all sections on
3633**
3634** Returns: status:
3635** MT_OK - No errors
3636** MT_INV_HANDLE - Invalid tuner handle
3637** MT_COMM_ERR - Serial bus communications error
3638**
3639** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
3640**
3641** Revision History:
3642**
3643** SCR Date Author Description
3644** -------------------------------------------------------------------------
3645** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3646** 01-03-2008 PINZ Ver 1.xx: Added a trigger of BYPATNUP for
3647** correct wakeup of the LNA
3648**
3649****************************************************************************/
3650UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown)
3651{
3652 UData_t status = MT2063_OK; /* Status to be returned */
3653 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
3654
3655 /* Verify that the handle passed points to a valid tuner */
3656 if (MT2063_IsValidHandle(pInfo) == 0)
3657 {
3658 status = MT2063_INV_HANDLE;
3659 }
3660 else
3661 {
3662 if (Shutdown == 1)
3663 pInfo->reg[MT2063_REG_PWR_1] |= 0x04; /* Turn the bit on */
3664 else
3665 pInfo->reg[MT2063_REG_PWR_1] &= ~0x04; /* Turn off the bit */
3666
3667 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_PWR_1, &pInfo->reg[MT2063_REG_PWR_1], 1);
3668
3669 if (Shutdown != 1)
3670 {
3671 pInfo->reg[MT2063_REG_BYP_CTRL] = (pInfo->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
3672 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_BYP_CTRL, &pInfo->reg[MT2063_REG_BYP_CTRL], 1);
3673 pInfo->reg[MT2063_REG_BYP_CTRL] = (pInfo->reg[MT2063_REG_BYP_CTRL] & 0x9F);
3674 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_BYP_CTRL, &pInfo->reg[MT2063_REG_BYP_CTRL], 1);
3675 }
3676 }
3677
3678 return (status);
3679}
3680
3681
3682/****************************************************************************
3683**
3684** Name: MT2063_SetExtSRO
3685**
3686** Description: Sets the external SRO driver.
3687**
3688** Parameters: h - Tuner handle (returned by MT2063_Open)
3689** Ext_SRO_Setting - external SRO drive setting
3690**
3691** (default) MT2063_EXT_SRO_OFF - ext driver off
3692** MT2063_EXT_SRO_BY_1 - ext driver = SRO frequency
3693** MT2063_EXT_SRO_BY_2 - ext driver = SRO/2 frequency
3694** MT2063_EXT_SRO_BY_4 - ext driver = SRO/4 frequency
3695**
3696** Returns: status:
3697** MT_OK - No errors
3698** MT_COMM_ERR - Serial bus communications error
3699** MT_INV_HANDLE - Invalid tuner handle
3700**
3701** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
3702**
3703** The Ext_SRO_Setting settings default to OFF
3704** Use this function if you need to override the default
3705**
3706** Revision History:
3707**
3708** SCR Date Author Description
3709** -------------------------------------------------------------------------
3710** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3711** 189 S 05-13-2008 RSK Ver 1.16: Correct location for ExtSRO control.
3712**
3713****************************************************************************/
3714UData_t MT2063_SetExtSRO(Handle_t h,
3715 enum MT2063_Ext_SRO Ext_SRO_Setting)
3716{
3717 UData_t status = MT2063_OK; /* Status to be returned */
3718 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
3719
3720 /* Verify that the handle passed points to a valid tuner */
3721 if (MT2063_IsValidHandle(pInfo) == 0)
3722 status = MT2063_INV_HANDLE;
3723 else
3724 {
3725 pInfo->reg[MT2063_REG_CTRL_2C] = (pInfo->reg[MT2063_REG_CTRL_2C] & 0x3F) | ((U8Data)Ext_SRO_Setting << 6);
3726 status = MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_CTRL_2C, &pInfo->reg[MT2063_REG_CTRL_2C], 1);
3727 }
3728
3729 return (status);
3730}
3731
3732
3733/****************************************************************************
3734**
3735** Name: MT2063_SetReg
3736**
3737** Description: Sets an MT2063 register.
3738**
3739** Parameters: h - Tuner handle (returned by MT2063_Open)
3740** reg - MT2063 register/subaddress location
3741** val - MT2063 register/subaddress value
3742**
3743** Returns: status:
3744** MT_OK - No errors
3745** MT_COMM_ERR - Serial bus communications error
3746** MT_INV_HANDLE - Invalid tuner handle
3747** MT_ARG_RANGE - Argument out of range
3748**
3749** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
3750**
3751** Use this function if you need to override a default
3752** register value
3753**
3754** Revision History:
3755**
3756** SCR Date Author Description
3757** -------------------------------------------------------------------------
3758** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3759**
3760****************************************************************************/
3761UData_t MT2063_SetReg(Handle_t h,
3762 U8Data reg,
3763 U8Data val)
3764{
3765 UData_t status = MT2063_OK; /* Status to be returned */
3766 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
3767
3768 /* Verify that the handle passed points to a valid tuner */
3769 if (MT2063_IsValidHandle(pInfo) == 0)
3770 status |= MT2063_INV_HANDLE;
3771
3772 if (reg >= MT2063_REG_END_REGS)
3773 status |= MT2063_ARG_RANGE;
3774
3775 if (MT2063_NO_ERROR(status))
3776 {
3777 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, reg, &val, 1);
3778 if (MT2063_NO_ERROR(status))
3779 pInfo->reg[reg] = val;
3780 }
3781
3782 return (status);
3783}
3784
3785
3786static UData_t MT2063_Round_fLO(UData_t f_LO, UData_t f_LO_Step, UData_t f_ref)
3787{
3788 return f_ref * (f_LO / f_ref)
3789 + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
3790}
3791
3792
3793/****************************************************************************
3794**
3795** Name: fLO_FractionalTerm
3796**
3797** Description: Calculates the portion contributed by FracN / denom.
3798**
3799** This function preserves maximum precision without
3800** risk of overflow. It accurately calculates
3801** f_ref * num / denom to within 1 HZ with fixed math.
3802**
3803** Parameters: num - Fractional portion of the multiplier
3804** denom - denominator portion of the ratio
3805** This routine successfully handles denom values
3806** up to and including 2^18.
3807** f_Ref - SRO frequency. This calculation handles
3808** f_ref as two separate 14-bit fields.
3809** Therefore, a maximum value of 2^28-1
3810** may safely be used for f_ref. This is
3811** the genesis of the magic number "14" and the
3812** magic mask value of 0x03FFF.
3813**
3814** Returns: f_ref * num / denom
3815**
3816** Revision History:
3817**
3818** SCR Date Author Description
3819** -------------------------------------------------------------------------
3820** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3821**
3822****************************************************************************/
3823static UData_t MT2063_fLO_FractionalTerm( UData_t f_ref,
3824 UData_t num,
3825 UData_t denom )
3826{
3827 UData_t t1 = (f_ref >> 14) * num;
3828 UData_t term1 = t1 / denom;
3829 UData_t loss = t1 % denom;
3830 UData_t term2 = ( ((f_ref & 0x00003FFF) * num + (loss<<14)) + (denom/2) ) / denom;
3831 return ((term1 << 14) + term2);
3832}
3833
3834
3835/****************************************************************************
3836**
3837** Name: CalcLO1Mult
3838**
3839** Description: Calculates Integer divider value and the numerator
3840** value for a FracN PLL.
3841**
3842** This function assumes that the f_LO and f_Ref are
3843** evenly divisible by f_LO_Step.
3844**
3845** Parameters: Div - OUTPUT: Whole number portion of the multiplier
3846** FracN - OUTPUT: Fractional portion of the multiplier
3847** f_LO - desired LO frequency.
3848** f_LO_Step - Minimum step size for the LO (in Hz).
3849** f_Ref - SRO frequency.
3850** f_Avoid - Range of PLL frequencies to avoid near
3851** integer multiples of f_Ref (in Hz).
3852**
3853** Returns: Recalculated LO frequency.
3854**
3855** Revision History:
3856**
3857** SCR Date Author Description
3858** -------------------------------------------------------------------------
3859** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3860**
3861****************************************************************************/
3862static UData_t MT2063_CalcLO1Mult(UData_t *Div,
3863 UData_t *FracN,
3864 UData_t f_LO,
3865 UData_t f_LO_Step,
3866 UData_t f_Ref)
3867{
3868 /* Calculate the whole number portion of the divider */
3869 *Div = f_LO / f_Ref;
3870
3871 /* Calculate the numerator value (round to nearest f_LO_Step) */
3872 *FracN = (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
3873
3874 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm( f_Ref, *FracN, 64 );
3875}
3876
3877
3878/****************************************************************************
3879**
3880** Name: CalcLO2Mult
3881**
3882** Description: Calculates Integer divider value and the numerator
3883** value for a FracN PLL.
3884**
3885** This function assumes that the f_LO and f_Ref are
3886** evenly divisible by f_LO_Step.
3887**
3888** Parameters: Div - OUTPUT: Whole number portion of the multiplier
3889** FracN - OUTPUT: Fractional portion of the multiplier
3890** f_LO - desired LO frequency.
3891** f_LO_Step - Minimum step size for the LO (in Hz).
3892** f_Ref - SRO frequency.
3893** f_Avoid - Range of PLL frequencies to avoid near
3894** integer multiples of f_Ref (in Hz).
3895**
3896** Returns: Recalculated LO frequency.
3897**
3898** Revision History:
3899**
3900** SCR Date Author Description
3901** -------------------------------------------------------------------------
3902** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3903**
3904****************************************************************************/
3905static UData_t MT2063_CalcLO2Mult(UData_t *Div,
3906 UData_t *FracN,
3907 UData_t f_LO,
3908 UData_t f_LO_Step,
3909 UData_t f_Ref)
3910{
3911 /* Calculate the whole number portion of the divider */
3912 *Div = f_LO / f_Ref;
3913
3914 /* Calculate the numerator value (round to nearest f_LO_Step) */
3915 *FracN = (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) + (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
3916
3917 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm( f_Ref, *FracN, 8191 );
3918}
3919
3920/****************************************************************************
3921**
3922** Name: FindClearTuneFilter
3923**
3924** Description: Calculate the corrrect ClearTune filter to be used for
3925** a given input frequency.
3926**
3927** Parameters: pInfo - ptr to tuner data structure
3928** f_in - RF input center frequency (in Hz).
3929**
3930** Returns: ClearTune filter number (0-31)
3931**
3932** Dependencies: MUST CALL MT2064_Open BEFORE FindClearTuneFilter!
3933**
3934** Revision History:
3935**
3936** SCR Date Author Description
3937** -------------------------------------------------------------------------
3938** 04-10-2008 PINZ Ver 1.14: Use software-controlled ClearTune
3939** cross-over frequency values.
3940**
3941****************************************************************************/
3942static UData_t FindClearTuneFilter(struct MT2063_Info_t* pInfo, UData_t f_in)
3943{
3944 UData_t RFBand;
3945 UData_t idx; /* index loop */
3946
3947 /*
3948 ** Find RF Band setting
3949 */
3950 RFBand = 31; /* def when f_in > all */
3951 for (idx=0; idx<31; ++idx)
3952 {
3953 if (pInfo->CTFiltMax[idx] >= f_in)
3954 {
3955 RFBand = idx;
3956 break;
3957 }
3958 }
3959 return (RFBand);
3960}
3961
3962
3963
3964/****************************************************************************
3965**
3966** Name: MT2063_Tune
3967**
3968** Description: Change the tuner's tuned frequency to RFin.
3969**
3970** Parameters: h - Open handle to the tuner (from MT2063_Open).
3971** f_in - RF input center frequency (in Hz).
3972**
3973** Returns: status:
3974** MT_OK - No errors
3975** MT_INV_HANDLE - Invalid tuner handle
3976** MT_UPC_UNLOCK - Upconverter PLL unlocked
3977** MT_DNC_UNLOCK - Downconverter PLL unlocked
3978** MT_COMM_ERR - Serial bus communications error
3979** MT_SPUR_CNT_MASK - Count of avoided LO spurs
3980** MT_SPUR_PRESENT - LO spur possible in output
3981** MT_FIN_RANGE - Input freq out of range
3982** MT_FOUT_RANGE - Output freq out of range
3983** MT_UPC_RANGE - Upconverter freq out of range
3984** MT_DNC_RANGE - Downconverter freq out of range
3985**
3986** Dependencies: MUST CALL MT2063_Open BEFORE MT2063_Tune!
3987**
3988** MT_ReadSub - Read data from the two-wire serial bus
3989** MT_WriteSub - Write data to the two-wire serial bus
3990** MT_Sleep - Delay execution for x milliseconds
3991** MT2063_GetLocked - Checks to see if LO1 and LO2 are locked
3992**
3993** Revision History:
3994**
3995** SCR Date Author Description
3996** -------------------------------------------------------------------------
3997** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
3998** 04-10-2008 PINZ Ver 1.05: Use software-controlled ClearTune
3999** cross-over frequency values.
4000** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs.
4001** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid.
4002** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW
4003**
4004****************************************************************************/
4005UData_t MT2063_Tune(Handle_t h,
4006 UData_t f_in) /* RF input center frequency */
4007{
4008 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
4009
4010 UData_t status = MT2063_OK; /* status of operation */
4011 UData_t LO1; /* 1st LO register value */
4012 UData_t Num1; /* Numerator for LO1 reg. value */
4013 UData_t f_IF1; /* 1st IF requested */
4014 UData_t LO2; /* 2nd LO register value */
4015 UData_t Num2; /* Numerator for LO2 reg. value */
4016 UData_t ofLO1, ofLO2; /* last time's LO frequencies */
4017 UData_t ofin, ofout; /* last time's I/O frequencies */
4018 U8Data fiffc = 0x80; /* FIFF center freq from tuner */
4019 UData_t fiffof; /* Offset from FIFF center freq */
4020 const U8Data LO1LK = 0x80; /* Mask for LO1 Lock bit */
4021 U8Data LO2LK = 0x08; /* Mask for LO2 Lock bit */
4022 U8Data val;
4023 UData_t RFBand;
4024
4025 /* Verify that the handle passed points to a valid tuner */
4026 if (MT2063_IsValidHandle(pInfo) == 0)
4027 return MT2063_INV_HANDLE;
4028
4029 /* Check the input and output frequency ranges */
4030 if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
4031 status |= MT2063_FIN_RANGE;
4032
4033 if ((pInfo->AS_Data.f_out < MT2063_MIN_FOUT_FREQ) || (pInfo->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
4034 status |= MT2063_FOUT_RANGE;
4035
4036 /*
4037 ** Save original LO1 and LO2 register values
4038 */
4039 ofLO1 = pInfo->AS_Data.f_LO1;
4040 ofLO2 = pInfo->AS_Data.f_LO2;
4041 ofin = pInfo->AS_Data.f_in;
4042 ofout = pInfo->AS_Data.f_out;
4043
4044 /*
4045 ** Find and set RF Band setting
4046 */
4047 if (pInfo->ctfilt_sw == 1)
4048 {
4049 val = ( pInfo->reg[MT2063_REG_CTUNE_CTRL] | 0x08 );
4050 if( pInfo->reg[MT2063_REG_CTUNE_CTRL] != val )
4051 {
4052 status |= MT2063_SetReg(pInfo, MT2063_REG_CTUNE_CTRL, val);
4053 }
4054 val = pInfo->reg[MT2063_REG_CTUNE_OV];
4055 RFBand = FindClearTuneFilter(pInfo, f_in);
4056 pInfo->reg[MT2063_REG_CTUNE_OV] = (U8Data)((pInfo->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
4057 | RFBand);
4058 if (pInfo->reg[MT2063_REG_CTUNE_OV] != val)
4059 {
4060 status |= MT2063_SetReg(pInfo, MT2063_REG_CTUNE_OV, val);
4061 }
4062 }
4063
4064 /*
4065 ** Read the FIFF Center Frequency from the tuner
4066 */
4067 if (MT2063_NO_ERROR(status))
4068 {
4069 status |= MT2063_ReadSub(pInfo->hUserData, pInfo->address, MT2063_REG_FIFFC, &pInfo->reg[MT2063_REG_FIFFC], 1);
4070 fiffc = pInfo->reg[MT2063_REG_FIFFC];
4071 }
4072 /*
4073 ** Assign in the requested values
4074 */
4075 pInfo->AS_Data.f_in = f_in;
4076 /* Request a 1st IF such that LO1 is on a step size */
4077 pInfo->AS_Data.f_if1_Request = MT2063_Round_fLO(pInfo->AS_Data.f_if1_Request + f_in, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref) - f_in;
4078
4079 /*
4080 ** Calculate frequency settings. f_IF1_FREQ + f_in is the
4081 ** desired LO1 frequency
4082 */
4083 MT2063_ResetExclZones(&pInfo->AS_Data);
4084
4085 f_IF1 = MT2063_ChooseFirstIF(&pInfo->AS_Data);
4086
4087 pInfo->AS_Data.f_LO1 = MT2063_Round_fLO(f_IF1 + f_in, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref);
4088
4089 pInfo->AS_Data.f_LO2 = MT2063_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);
4090
4091 /*
4092 ** Check for any LO spurs in the output bandwidth and adjust
4093 ** the LO settings to avoid them if needed
4094 */
4095 status |= MT2063_AvoidSpurs(h, &pInfo->AS_Data);
4096 /*
4097 ** MT_AvoidSpurs spurs may have changed the LO1 & LO2 values.
4098 ** Recalculate the LO frequencies and the values to be placed
4099 ** in the tuning registers.
4100 */
4101 pInfo->AS_Data.f_LO1 = MT2063_CalcLO1Mult(&LO1, &Num1, pInfo->AS_Data.f_LO1, pInfo->AS_Data.f_LO1_Step, pInfo->AS_Data.f_ref);
4102 pInfo->AS_Data.f_LO2 = MT2063_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);
4103 pInfo->AS_Data.f_LO2 = MT2063_CalcLO2Mult(&LO2, &Num2, pInfo->AS_Data.f_LO2, pInfo->AS_Data.f_LO2_Step, pInfo->AS_Data.f_ref);
4104
4105
4106 /*
4107 ** Check the upconverter and downconverter frequency ranges
4108 */
4109 if ((pInfo->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ) || (pInfo->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
4110 status |= MT2063_UPC_RANGE;
4111 if ((pInfo->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ) || (pInfo->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
4112 status |= MT2063_DNC_RANGE;
4113 /* LO2 Lock bit was in a different place for B0 version */
4114 if (pInfo->tuner_id == MT2063_B0)
4115 LO2LK = 0x40;
4116
4117 /*
4118 ** If we have the same LO frequencies and we're already locked,
4119 ** then skip re-programming the LO registers.
4120 */
4121 if ((ofLO1 != pInfo->AS_Data.f_LO1)
4122 || (ofLO2 != pInfo->AS_Data.f_LO2)
4123 || ((pInfo->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) != (LO1LK | LO2LK)))
4124 {
4125 /*
4126 ** Calculate the FIFFOF register value
4127 **
4128 ** IF1_Actual
4129 ** FIFFOF = ------------ - 8 * FIFFC - 4992
4130 ** f_ref/64
4131 */
4132 fiffof = (pInfo->AS_Data.f_LO1 - f_in) / (pInfo->AS_Data.f_ref / 64) - 8 * (UData_t)fiffc - 4992;
4133 if (fiffof > 0xFF)
4134 fiffof = 0xFF;
4135
4136 /*
4137 ** Place all of the calculated values into the local tuner
4138 ** register fields.
4139 */
4140 if (MT2063_NO_ERROR(status))
4141 {
4142 pInfo->reg[MT2063_REG_LO1CQ_1] = (U8Data)(LO1 & 0xFF); /* DIV1q */
4143 pInfo->reg[MT2063_REG_LO1CQ_2] = (U8Data)(Num1 & 0x3F); /* NUM1q */
4144 pInfo->reg[MT2063_REG_LO2CQ_1] = (U8Data)(((LO2 & 0x7F) << 1) /* DIV2q */
4145 | (Num2 >> 12)); /* NUM2q (hi) */
4146 pInfo->reg[MT2063_REG_LO2CQ_2] = (U8Data)((Num2 & 0x0FF0) >> 4); /* NUM2q (mid) */
4147 pInfo->reg[MT2063_REG_LO2CQ_3] = (U8Data)(0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */
4148
4149 /*
4150 ** Now write out the computed register values
4151 ** IMPORTANT: There is a required order for writing
4152 ** (0x05 must follow all the others).
4153 */
4154 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO1CQ_1, &pInfo->reg[MT2063_REG_LO1CQ_1], 5); /* 0x01 - 0x05 */
4155 if (pInfo->tuner_id == MT2063_B0)
4156 {
4157 /* Re-write the one-shot bits to trigger the tune operation */
4158 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_LO2CQ_3, &pInfo->reg[MT2063_REG_LO2CQ_3], 1); /* 0x05 */
4159 }
4160 /* Write out the FIFF offset only if it's changing */
4161 if (pInfo->reg[MT2063_REG_FIFF_OFFSET] != (U8Data)fiffof)
4162 {
4163 pInfo->reg[MT2063_REG_FIFF_OFFSET] = (U8Data)fiffof;
4164 status |= MT2063_WriteSub(pInfo->hUserData, pInfo->address, MT2063_REG_FIFF_OFFSET, &pInfo->reg[MT2063_REG_FIFF_OFFSET], 1);
4165 }
4166 }
4167
4168 /*
4169 ** Check for LO's locking
4170 */
4171
4172
4173 if (MT2063_NO_ERROR(status))
4174 {
4175 status |= MT2063_GetLocked(h);
4176 }
4177 /*
4178 ** If we locked OK, assign calculated data to MT2063_Info_t structure
4179 */
4180 if (MT2063_NO_ERROR(status))
4181 {
4182 pInfo->f_IF1_actual = pInfo->AS_Data.f_LO1 - f_in;
4183 }
4184 }
4185
4186 return (status);
4187}
4188
4189UData_t MT_Tune_atv(Handle_t h, UData_t f_in, UData_t bw_in, enum MTTune_atv_standard tv_type)
4190{
4191
4192 UData_t status = MT2063_OK;
4193 struct MT2063_Info_t* pInfo = (struct MT2063_Info_t*) h;
4194 struct dvb_frontend *fe = (struct dvb_frontend *)pInfo->hUserData;
4195 struct mt2063_state *state = fe->tuner_priv;
4196
4197 SData_t pict_car = 0;
4198 SData_t pict2chanb_vsb = 0;
4199 SData_t pict2chanb_snd = 0;
4200 SData_t pict2snd1 = 0;
4201 SData_t pict2snd2 = 0;
4202 SData_t ch_bw = 0;
4203
4204 SData_t if_mid = 0;
4205 SData_t rcvr_mode =0;
4206 UData_t mode_get =0;
4207
4208
4209 switch (tv_type) {
4210 case MTTUNEA_PAL_B : {
4211 pict_car = 38900000;
4212 ch_bw = 8000000;
4213 pict2chanb_vsb = -1250000;
4214 pict2snd1 = 5500000;
4215 pict2snd2 = 5742000;
4216 rcvr_mode =1;
4217 break;
4218 }
4219 case MTTUNEA_PAL_G : {
4220 pict_car = 38900000;
4221 ch_bw = 7000000;
4222 pict2chanb_vsb = -1250000;
4223 pict2snd1 = 5500000;
4224 pict2snd2 = 0;
4225 rcvr_mode =1;
4226 break;
4227 }
4228 case MTTUNEA_PAL_I : {
4229 pict_car = 38900000;
4230 ch_bw = 8000000;
4231 pict2chanb_vsb = -1250000;
4232 pict2snd1 = 6000000;
4233 pict2snd2 = 0;
4234 rcvr_mode =1;
4235 break;
4236 }
4237 case MTTUNEA_PAL_L : {
4238 pict_car = 38900000;
4239 ch_bw = 8000000;
4240 pict2chanb_vsb = -1250000;
4241 pict2snd1 = 6500000;
4242 pict2snd2 = 0;
4243 rcvr_mode =1;
4244 break;
4245 }
4246 case MTTUNEA_PAL_MN : {
4247 pict_car = 38900000;
4248 ch_bw = 6000000;
4249 pict2chanb_vsb = -1250000;
4250 pict2snd1 = 4500000;
4251 pict2snd2 = 0;
4252 rcvr_mode =1;
4253 break;
4254 }
4255 case MTTUNEA_PAL_DK : {
4256 pict_car = 38900000;
4257 ch_bw = 8000000;
4258 pict2chanb_vsb = -1250000;
4259 pict2snd1 = 6500000;
4260 pict2snd2 = 0;
4261 rcvr_mode =1;
4262 break;
4263 }
4264 case MTTUNEA_DIGITAL : {
4265 pict_car = 36125000;
4266 ch_bw = 8000000;
4267 pict2chanb_vsb = -(ch_bw/2);
4268 pict2snd1 = 0;
4269 pict2snd2 = 0;
4270 rcvr_mode = 2;
4271 break;
4272 }
4273 case MTTUNEA_FMRADIO : {
4274 pict_car = 38900000;
4275 ch_bw = 8000000;
4276 pict2chanb_vsb = -(ch_bw/2);
4277 pict2snd1 = 0;
4278 pict2snd2 = 0;
4279 rcvr_mode =4;
4280 //f_in -= 2900000;
4281 break;
4282 }
4283 case MTTUNEA_DVBC : {
4284 pict_car = 36125000;
4285 ch_bw = 8000000;
4286 pict2chanb_vsb = -(ch_bw/2);
4287 pict2snd1 = 0;
4288 pict2snd2 = 0;
4289 rcvr_mode = MT2063_CABLE_QAM;
4290 break;
4291 }
4292 case MTTUNEA_DVBT : {
4293 pict_car = 36125000;
4294 ch_bw = bw_in;//8000000
4295 pict2chanb_vsb = -(ch_bw/2);
4296 pict2snd1 = 0;
4297 pict2snd2 = 0;
4298 rcvr_mode = MT2063_OFFAIR_COFDM;
4299 break;
4300 }
4301 case MTTUNEA_UNKNOWN : break;
4302 default : break;
4303 }
4304
4305 pict2chanb_snd = pict2chanb_vsb - ch_bw;
4306 if_mid = pict_car - (pict2chanb_vsb + (ch_bw/2) );
4307
4308 status |= MT2063_SetParam(h,MT2063_STEPSIZE,125000);
4309 status |= MT2063_SetParam(h,MT2063_OUTPUT_FREQ,if_mid);
4310 status |= MT2063_SetParam(h,MT2063_OUTPUT_BW,ch_bw);
4311 status |=MT2063_GetParam(h,MT2063_RCVR_MODE,&mode_get);
4312
4313 status |= MT2063_SetParam(h,MT2063_RCVR_MODE,rcvr_mode);
4314 status |= MT2063_Tune(h,( f_in + (pict2chanb_vsb + (ch_bw/2) ) ) );
4315 status |=MT2063_GetParam(h,MT2063_RCVR_MODE,&mode_get);
4316
4317 return (UData_t)status;
4318}
4319
4320
4321static int mt2063_init(struct dvb_frontend *fe)
4322{
4323 UData_t status = MT2063_ERROR;
4324 struct mt2063_state *state = fe->tuner_priv;
4325
4326 status = MT2063_Open(0xC0, &(state->MT2063_ht), fe);
4327 status |= MT2063_SoftwareShutdown(state->MT2063_ht, 1);
4328 status |= MT2063_ClearPowerMaskBits(state->MT2063_ht, MT2063_ALL_SD);
4329
4330 if(MT2063_OK != status)
4331 {
4332 printk("%s %d error status = 0x%x!!\n", __func__, __LINE__, status);
4333 return -1;
4334 }
4335
4336 return 0;
4337}
4338
4339static int mt2063_sleep(struct dvb_frontend *fe)
4340{ 4419{
4341 /* TODO: power down */ 4420
4421 UData_t status = MT2063_OK;
4422 struct MT2063_Info_t *pInfo = (struct MT2063_Info_t *)h;
4423 struct dvb_frontend *fe = (struct dvb_frontend *)pInfo->hUserData;
4424 struct mt2063_state *state = fe->tuner_priv;
4425
4426 SData_t pict_car = 0;
4427 SData_t pict2chanb_vsb = 0;
4428 SData_t pict2chanb_snd = 0;
4429 SData_t pict2snd1 = 0;
4430 SData_t pict2snd2 = 0;
4431 SData_t ch_bw = 0;
4432
4433 SData_t if_mid = 0;
4434 SData_t rcvr_mode = 0;
4435 UData_t mode_get = 0;
4436
4437 switch (tv_type) {
4438 case MTTUNEA_PAL_B:{
4439 pict_car = 38900000;
4440 ch_bw = 8000000;
4441 pict2chanb_vsb = -1250000;
4442 pict2snd1 = 5500000;
4443 pict2snd2 = 5742000;
4444 rcvr_mode = 1;
4445 break;
4446 }
4447 case MTTUNEA_PAL_G:{
4448 pict_car = 38900000;
4449 ch_bw = 7000000;
4450 pict2chanb_vsb = -1250000;
4451 pict2snd1 = 5500000;
4452 pict2snd2 = 0;
4453 rcvr_mode = 1;
4454 break;
4455 }
4456 case MTTUNEA_PAL_I:{
4457 pict_car = 38900000;
4458 ch_bw = 8000000;
4459 pict2chanb_vsb = -1250000;
4460 pict2snd1 = 6000000;
4461 pict2snd2 = 0;
4462 rcvr_mode = 1;
4463 break;
4464 }
4465 case MTTUNEA_PAL_L:{
4466 pict_car = 38900000;
4467 ch_bw = 8000000;
4468 pict2chanb_vsb = -1250000;
4469 pict2snd1 = 6500000;
4470 pict2snd2 = 0;
4471 rcvr_mode = 1;
4472 break;
4473 }
4474 case MTTUNEA_PAL_MN:{
4475 pict_car = 38900000;
4476 ch_bw = 6000000;
4477 pict2chanb_vsb = -1250000;
4478 pict2snd1 = 4500000;
4479 pict2snd2 = 0;
4480 rcvr_mode = 1;
4481 break;
4482 }
4483 case MTTUNEA_PAL_DK:{
4484 pict_car = 38900000;
4485 ch_bw = 8000000;
4486 pict2chanb_vsb = -1250000;
4487 pict2snd1 = 6500000;
4488 pict2snd2 = 0;
4489 rcvr_mode = 1;
4490 break;
4491 }
4492 case MTTUNEA_DIGITAL:{
4493 pict_car = 36125000;
4494 ch_bw = 8000000;
4495 pict2chanb_vsb = -(ch_bw / 2);
4496 pict2snd1 = 0;
4497 pict2snd2 = 0;
4498 rcvr_mode = 2;
4499 break;
4500 }
4501 case MTTUNEA_FMRADIO:{
4502 pict_car = 38900000;
4503 ch_bw = 8000000;
4504 pict2chanb_vsb = -(ch_bw / 2);
4505 pict2snd1 = 0;
4506 pict2snd2 = 0;
4507 rcvr_mode = 4;
4508 //f_in -= 2900000;
4509 break;
4510 }
4511 case MTTUNEA_DVBC:{
4512 pict_car = 36125000;
4513 ch_bw = 8000000;
4514 pict2chanb_vsb = -(ch_bw / 2);
4515 pict2snd1 = 0;
4516 pict2snd2 = 0;
4517 rcvr_mode = MT2063_CABLE_QAM;
4518 break;
4519 }
4520 case MTTUNEA_DVBT:{
4521 pict_car = 36125000;
4522 ch_bw = bw_in; //8000000
4523 pict2chanb_vsb = -(ch_bw / 2);
4524 pict2snd1 = 0;
4525 pict2snd2 = 0;
4526 rcvr_mode = MT2063_OFFAIR_COFDM;
4527 break;
4528 }
4529 case MTTUNEA_UNKNOWN:
4530 break;
4531 default:
4532 break;
4533 }
4534
4535 pict2chanb_snd = pict2chanb_vsb - ch_bw;
4536 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
4537
4538 status |= MT2063_SetParam(h, MT2063_STEPSIZE, 125000);
4539 status |= MT2063_SetParam(h, MT2063_OUTPUT_FREQ, if_mid);
4540 status |= MT2063_SetParam(h, MT2063_OUTPUT_BW, ch_bw);
4541 status |= MT2063_GetParam(h, MT2063_RCVR_MODE, &mode_get);
4542
4543 status |= MT2063_SetParam(h, MT2063_RCVR_MODE, rcvr_mode);
4544 status |= MT2063_Tune(h, (f_in + (pict2chanb_vsb + (ch_bw / 2))));
4545 status |= MT2063_GetParam(h, MT2063_RCVR_MODE, &mode_get);
4546
4547 return (UData_t) status;
4548}
4549
4550static int mt2063_init(struct dvb_frontend *fe)
4551{
4552 UData_t status = MT2063_ERROR;
4553 struct mt2063_state *state = fe->tuner_priv;
4554
4555 status = MT2063_Open(0xC0, &(state->MT2063_ht), fe);
4556 status |= MT2063_SoftwareShutdown(state->MT2063_ht, 1);
4557 status |= MT2063_ClearPowerMaskBits(state->MT2063_ht, MT2063_ALL_SD);
4558
4559 if (MT2063_OK != status) {
4560 printk("%s %d error status = 0x%x!!\n", __func__, __LINE__,
4561 status);
4562 return -1;
4563 }
4564
4342 return 0; 4565 return 0;
4343} 4566}
4344 4567
4345static int mt2063_get_status(struct dvb_frontend *fe, u32 *status) 4568static int mt2063_sleep(struct dvb_frontend *fe)
4346{ 4569{
4347 int rc = 0; 4570 /* TODO: power down */
4348 4571 return 0;
4349 //get tuner lock status
4350
4351 return rc;
4352} 4572}
4353 4573
4354 4574static int mt2063_get_status(struct dvb_frontend *fe, u32 * status)
4355static int mt2063_get_state(struct dvb_frontend *fe, 4575{
4356 enum tuner_param param, 4576 int rc = 0;
4357 struct tuner_state *state) 4577
4358{ 4578 //get tuner lock status
4359 struct mt2063_state *mt2063State = fe->tuner_priv; 4579
4360 4580 return rc;
4581}
4582
4583static int mt2063_get_state(struct dvb_frontend *fe,
4584 enum tuner_param param, struct tuner_state *state)
4585{
4586 struct mt2063_state *mt2063State = fe->tuner_priv;
4587
4361 switch (param) { 4588 switch (param) {
4362 case DVBFE_TUNER_FREQUENCY: 4589 case DVBFE_TUNER_FREQUENCY:
4363 //get frequency 4590 //get frequency
4364 break; 4591 break;
4365 case DVBFE_TUNER_TUNERSTEP: 4592 case DVBFE_TUNER_TUNERSTEP:
4366 break; 4593 break;
4367 case DVBFE_TUNER_IFFREQ: 4594 case DVBFE_TUNER_IFFREQ:
4368 break; 4595 break;
4369 case DVBFE_TUNER_BANDWIDTH: 4596 case DVBFE_TUNER_BANDWIDTH:
4370 //get bandwidth 4597 //get bandwidth
4371 break; 4598 break;
4372 case DVBFE_TUNER_REFCLOCK: 4599 case DVBFE_TUNER_REFCLOCK:
4373 state->refclock = (u32_t)MT2063_GetLocked((Handle_t)(mt2063State->MT2063_ht)); 4600 state->refclock =
4601 (u32_t)
4602 MT2063_GetLocked((Handle_t) (mt2063State->MT2063_ht));
4374 break; 4603 break;
4375 default: 4604 default:
4376 break; 4605 break;
4377 } 4606 }
4378 4607
4379 return (int)state->refclock; 4608 return (int)state->refclock;
4380} 4609}
4381 4610
4382static int mt2063_set_state(struct dvb_frontend *fe, 4611static int mt2063_set_state(struct dvb_frontend *fe,
4383 enum tuner_param param, 4612 enum tuner_param param, struct tuner_state *state)
4384 struct tuner_state *state)
4385{ 4613{
4386 struct mt2063_state *mt2063State = fe->tuner_priv; 4614 struct mt2063_state *mt2063State = fe->tuner_priv;
4387 UData_t status = MT2063_OK; 4615 UData_t status = MT2063_OK;
4388 4616
4389 switch (param) { 4617 switch (param) {
4390 case DVBFE_TUNER_FREQUENCY: 4618 case DVBFE_TUNER_FREQUENCY:
4391 //set frequency 4619 //set frequency
4392 4620
4393 status = MT_Tune_atv((Handle_t)(mt2063State->MT2063_ht), state->frequency, state->bandwidth, mt2063State->tv_type); 4621 status =
4394 4622 MT_Tune_atv((Handle_t) (mt2063State->MT2063_ht),
4395 mt2063State->frequency = state->frequency; 4623 state->frequency, state->bandwidth,
4624 mt2063State->tv_type);
4625
4626 mt2063State->frequency = state->frequency;
4396 break; 4627 break;
4397 case DVBFE_TUNER_TUNERSTEP: 4628 case DVBFE_TUNER_TUNERSTEP:
4398 break; 4629 break;
4399 case DVBFE_TUNER_IFFREQ: 4630 case DVBFE_TUNER_IFFREQ:
4400 break; 4631 break;
4401 case DVBFE_TUNER_BANDWIDTH: 4632 case DVBFE_TUNER_BANDWIDTH:
4402 //set bandwidth 4633 //set bandwidth
4403 mt2063State->bandwidth = state->bandwidth; 4634 mt2063State->bandwidth = state->bandwidth;
4635 break;
4636 case DVBFE_TUNER_REFCLOCK:
4637
4638 break;
4639 case DVBFE_TUNER_OPEN:
4640 status = MT2063_Open(MT2063_I2C, &(mt2063State->MT2063_ht), fe);
4641 break;
4642 case DVBFE_TUNER_SOFTWARE_SHUTDOWN:
4643 status = MT2063_SoftwareShutdown(mt2063State->MT2063_ht, 1);
4644 break;
4645 case DVBFE_TUNER_CLEAR_POWER_MASKBITS:
4646 status =
4647 MT2063_ClearPowerMaskBits(mt2063State->MT2063_ht,
4648 MT2063_ALL_SD);
4404 break; 4649 break;
4405 case DVBFE_TUNER_REFCLOCK:
4406
4407 break;
4408 case DVBFE_TUNER_OPEN:
4409 status = MT2063_Open(MT2063_I2C, &(mt2063State->MT2063_ht), fe);
4410 break;
4411 case DVBFE_TUNER_SOFTWARE_SHUTDOWN:
4412 status = MT2063_SoftwareShutdown(mt2063State->MT2063_ht, 1);
4413 break;
4414 case DVBFE_TUNER_CLEAR_POWER_MASKBITS:
4415 status = MT2063_ClearPowerMaskBits(mt2063State->MT2063_ht, MT2063_ALL_SD);
4416 break;
4417 default: 4650 default:
4418 break; 4651 break;
4419 } 4652 }
4420 4653
4421 return (int)status; 4654 return (int)status;
4422} 4655}
4423 4656
4424static int mt2063_release(struct dvb_frontend *fe) 4657static int mt2063_release(struct dvb_frontend *fe)
4425{ 4658{
4426 struct mt2063_state *state = fe->tuner_priv; 4659 struct mt2063_state *state = fe->tuner_priv;
4427 4660
4428 fe->tuner_priv = NULL; 4661 fe->tuner_priv = NULL;
4429 kfree(state); 4662 kfree(state);
4430 4663
4431 return 0; 4664 return 0;
4432} 4665}
4433 4666
4434static struct dvb_tuner_ops mt2063_ops = { 4667static struct dvb_tuner_ops mt2063_ops = {
4435 .info = { 4668 .info = {
4436 .name = "MT2063 Silicon Tuner", 4669 .name = "MT2063 Silicon Tuner",
4437 .frequency_min = 45000000, 4670 .frequency_min = 45000000,
4438 .frequency_max = 850000000, 4671 .frequency_max = 850000000,
4439 .frequency_step = 0, 4672 .frequency_step = 0,
4440 }, 4673 },
4441 4674
4442 .init = mt2063_init, 4675 .init = mt2063_init,
4443 .sleep = mt2063_sleep, 4676 .sleep = mt2063_sleep,
4444 .get_status = mt2063_get_status, 4677 .get_status = mt2063_get_status,
4445 .get_state = mt2063_get_state, 4678 .get_state = mt2063_get_state,
4446 .set_state = mt2063_set_state, 4679 .set_state = mt2063_set_state,
4447 .release = mt2063_release 4680 .release = mt2063_release
4448}; 4681};
4449 4682
4450struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, 4683struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
4451 struct mt2063_config *config, 4684 struct mt2063_config *config,
4452 struct i2c_adapter *i2c) 4685 struct i2c_adapter *i2c)
4453{ 4686{
4454 struct mt2063_state *state = NULL; 4687 struct mt2063_state *state = NULL;
4455 4688
4456 state = kzalloc(sizeof (struct mt2063_state), GFP_KERNEL); 4689 state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
4457 if (state == NULL) 4690 if (state == NULL)
4458 goto error; 4691 goto error;
4459 4692
4460 state->config = config; 4693 state->config = config;
4461 state->i2c = i2c; 4694 state->i2c = i2c;
4462 state->frontend = fe; 4695 state->frontend = fe;
4463 state->reference = config->refclock / 1000; /* kHz */ 4696 state->reference = config->refclock / 1000; /* kHz */
4464 state->MT2063_init = FALSE; 4697 state->MT2063_init = FALSE;
4465 fe->tuner_priv = state; 4698 fe->tuner_priv = state;
4466 fe->ops.tuner_ops = mt2063_ops; 4699 fe->ops.tuner_ops = mt2063_ops;
4467 4700
4468 printk("%s: Attaching MT2063 \n", __func__); 4701 printk("%s: Attaching MT2063 \n", __func__);
4469 return fe; 4702 return fe;
4470 4703
4471error: 4704error:
@@ -4473,14 +4706,9 @@ error:
4473 return NULL; 4706 return NULL;
4474} 4707}
4475 4708
4476 4709EXPORT_SYMBOL(mt2063_attach);
4477
4478EXPORT_SYMBOL(mt2063_attach);
4479MODULE_PARM_DESC(verbose, "Set Verbosity level"); 4710MODULE_PARM_DESC(verbose, "Set Verbosity level");
4480 4711
4481MODULE_AUTHOR("Henry"); 4712MODULE_AUTHOR("Henry");
4482MODULE_DESCRIPTION("MT2063 Silicon tuner"); 4713MODULE_DESCRIPTION("MT2063 Silicon tuner");
4483MODULE_LICENSE("GPL"); 4714MODULE_LICENSE("GPL");
4484
4485
4486
diff --git a/drivers/media/common/tuners/mt2063.h b/drivers/media/common/tuners/mt2063.h
index 423d1a79b96..4912f8902aa 100644
--- a/drivers/media/common/tuners/mt2063.h
+++ b/drivers/media/common/tuners/mt2063.h
@@ -1,729 +1,672 @@
1#ifndef __MT2063_H__ 1#ifndef __MT2063_H__
2#define __MT2063_H__ 2#define __MT2063_H__
3 3
4#include <linux/dvb/frontend.h> 4#include <linux/dvb/frontend.h>
5#include "dvb_frontend.h" 5#include "dvb_frontend.h"
6 6
7//context of mt2063_errordef.h <Henry> ====================================== 7//context of mt2063_errordef.h <Henry> ======================================
8//################################################################# 8//#################################################################
9//================================================================= 9//=================================================================
10 10
11/* 11/*
12** Note to users: DO NOT EDIT THIS FILE 12** Note to users: DO NOT EDIT THIS FILE
13** 13**
14** If you wish to rename any of the "user defined" bits, 14** If you wish to rename any of the "user defined" bits,
15** it should be done in the user file that includes this 15** it should be done in the user file that includes this
16** source file (e.g. mt_userdef.h) 16** source file (e.g. mt_userdef.h)
17** 17**
18*/ 18*/
19 19
20 20#define MT2063_ERROR (1 << 31)
21 21#define MT2063_USER_ERROR (1 << 30)
22#define MT2063_ERROR (1 << 31) 22
23#define MT2063_USER_ERROR (1 << 30) 23/* Macro to be used to check for errors */
24 24#define MT2063_IS_ERROR(s) (((s) >> 30) != 0)
25/* Macro to be used to check for errors */ 25#define MT2063_NO_ERROR(s) (((s) >> 30) == 0)
26#define MT2063_IS_ERROR(s) (((s) >> 30) != 0) 26
27#define MT2063_NO_ERROR(s) (((s) >> 30) == 0) 27#define MT2063_OK (0x00000000)
28 28
29 29/* Unknown error */
30#define MT2063_OK (0x00000000) 30#define MT2063_UNKNOWN (0x80000001)
31 31
32/* Unknown error */ 32/* Error: Upconverter PLL is not locked */
33#define MT2063_UNKNOWN (0x80000001) 33#define MT2063_UPC_UNLOCK (0x80000002)
34 34
35/* Error: Upconverter PLL is not locked */ 35/* Error: Downconverter PLL is not locked */
36#define MT2063_UPC_UNLOCK (0x80000002) 36#define MT2063_DNC_UNLOCK (0x80000004)
37 37
38/* Error: Downconverter PLL is not locked */ 38/* Error: Two-wire serial bus communications error */
39#define MT2063_DNC_UNLOCK (0x80000004) 39#define MT2063_COMM_ERR (0x80000008)
40 40
41/* Error: Two-wire serial bus communications error */ 41/* Error: Tuner handle passed to function was invalid */
42#define MT2063_COMM_ERR (0x80000008) 42#define MT2063_INV_HANDLE (0x80000010)
43 43
44/* Error: Tuner handle passed to function was invalid */ 44/* Error: Function argument is invalid (out of range) */
45#define MT2063_INV_HANDLE (0x80000010) 45#define MT2063_ARG_RANGE (0x80000020)
46 46
47/* Error: Function argument is invalid (out of range) */ 47/* Error: Function argument (ptr to return value) was NULL */
48#define MT2063_ARG_RANGE (0x80000020) 48#define MT2063_ARG_NULL (0x80000040)
49 49
50/* Error: Function argument (ptr to return value) was NULL */ 50/* Error: Attempt to open more than MT_TUNER_CNT tuners */
51#define MT2063_ARG_NULL (0x80000040) 51#define MT2063_TUNER_CNT_ERR (0x80000080)
52 52
53/* Error: Attempt to open more than MT_TUNER_CNT tuners */ 53/* Error: Tuner Part Code / Rev Code mismatches expected value */
54#define MT2063_TUNER_CNT_ERR (0x80000080) 54#define MT2063_TUNER_ID_ERR (0x80000100)
55 55
56/* Error: Tuner Part Code / Rev Code mismatches expected value */ 56/* Error: Tuner Initialization failure */
57#define MT2063_TUNER_ID_ERR (0x80000100) 57#define MT2063_TUNER_INIT_ERR (0x80000200)
58 58
59/* Error: Tuner Initialization failure */ 59#define MT2063_TUNER_OPEN_ERR (0x80000400)
60#define MT2063_TUNER_INIT_ERR (0x80000200) 60
61 61/* User-definable fields (see mt_userdef.h) */
62#define MT2063_TUNER_OPEN_ERR (0x80000400) 62#define MT2063_USER_DEFINED1 (0x00001000)
63 63#define MT2063_USER_DEFINED2 (0x00002000)
64/* User-definable fields (see mt_userdef.h) */ 64#define MT2063_USER_DEFINED3 (0x00004000)
65#define MT2063_USER_DEFINED1 (0x00001000) 65#define MT2063_USER_DEFINED4 (0x00008000)
66#define MT2063_USER_DEFINED2 (0x00002000) 66#define MT2063_USER_MASK (0x4000f000)
67#define MT2063_USER_DEFINED3 (0x00004000) 67#define MT2063_USER_SHIFT (12)
68#define MT2063_USER_DEFINED4 (0x00008000) 68
69#define MT2063_USER_MASK (0x4000f000) 69/* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */
70#define MT2063_USER_SHIFT (12) 70#define MT2063_SPUR_CNT_MASK (0x001f0000)
71 71#define MT2063_SPUR_SHIFT (16)
72/* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */ 72
73#define MT2063_SPUR_CNT_MASK (0x001f0000) 73/* Info: Tuner timeout waiting for condition */
74#define MT2063_SPUR_SHIFT (16) 74#define MT2063_TUNER_TIMEOUT (0x00400000)
75 75
76/* Info: Tuner timeout waiting for condition */ 76/* Info: Unavoidable LO-related spur may be present in the output */
77#define MT2063_TUNER_TIMEOUT (0x00400000) 77#define MT2063_SPUR_PRESENT_ERR (0x00800000)
78 78
79/* Info: Unavoidable LO-related spur may be present in the output */ 79/* Info: Tuner input frequency is out of range */
80#define MT2063_SPUR_PRESENT_ERR (0x00800000) 80#define MT2063_FIN_RANGE (0x01000000)
81 81
82/* Info: Tuner input frequency is out of range */ 82/* Info: Tuner output frequency is out of range */
83#define MT2063_FIN_RANGE (0x01000000) 83#define MT2063_FOUT_RANGE (0x02000000)
84 84
85/* Info: Tuner output frequency is out of range */ 85/* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
86#define MT2063_FOUT_RANGE (0x02000000) 86#define MT2063_UPC_RANGE (0x04000000)
87 87
88/* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */ 88/* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
89#define MT2063_UPC_RANGE (0x04000000) 89#define MT2063_DNC_RANGE (0x08000000)
90 90
91/* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */ 91//end of mt2063_errordef.h
92#define MT2063_DNC_RANGE (0x08000000) 92//=================================================================
93 93//#################################################################
94//end of mt2063_errordef.h 94//=================================================================
95//================================================================= 95
96//################################################################# 96//context of mt2063_userdef.h <Henry> ======================================
97//================================================================= 97//#################################################################
98 98//=================================================================
99//context of mt2063_userdef.h <Henry> ====================================== 99/*
100//################################################################# 100** Data Types
101//================================================================= 101*/
102/* 102#define MT2060_CNT 10
103** Data Types 103
104*/ 104typedef unsigned char U8Data; /* type corresponds to 8 bits */
105#define MT2060_CNT 10 105typedef unsigned int UData_t; /* type must be at least 32 bits */
106 106typedef int SData_t; /* type must be at least 32 bits */
107typedef unsigned char U8Data; /* type corresponds to 8 bits */ 107typedef void *Handle_t; /* memory pointer type */
108typedef unsigned int UData_t; /* type must be at least 32 bits */ 108//typedef double FData_t; /* floating point data type */
109typedef int SData_t; /* type must be at least 32 bits */ 109
110typedef void * Handle_t; /* memory pointer type */ 110#define MAX_UDATA (4294967295) /* max value storable in UData_t */
111//typedef double FData_t; /* floating point data type */ 111
112 112/*
113#define MAX_UDATA (4294967295) /* max value storable in UData_t */ 113** Define an MTxxxx_CNT macro for each type of tuner that will be built
114 114** into your application (e.g., MT2121, MT2060). MT_TUNER_CNT
115/* 115** must be set to the SUM of all of the MTxxxx_CNT macros.
116** Define an MTxxxx_CNT macro for each type of tuner that will be built 116**
117** into your application (e.g., MT2121, MT2060). MT_TUNER_CNT 117** #define MT2050_CNT (1)
118** must be set to the SUM of all of the MTxxxx_CNT macros. 118** #define MT2060_CNT (1)
119** 119** #define MT2111_CNT (1)
120** #define MT2050_CNT (1) 120** #define MT2121_CNT (3)
121** #define MT2060_CNT (1) 121*/
122** #define MT2111_CNT (1) 122
123** #define MT2121_CNT (3) 123#define MT2063_CNT (1)
124*/ 124
125 125#if !defined( MT2063_TUNER_CNT )
126#define MT2063_CNT (1) 126#define MT2063_TUNER_CNT (1) /* total num of MicroTuner tuners */
127 127#endif
128#if !defined( MT2063_TUNER_CNT ) 128#define MT2063_I2C (0xC0)
129#define MT2063_TUNER_CNT (1) /* total num of MicroTuner tuners */ 129
130#endif 130UData_t MT2063_WriteSub(Handle_t hUserData,
131#define MT2063_I2C (0xC0) 131 UData_t addr,
132 132 U8Data subAddress, U8Data * pData, UData_t cnt);
133UData_t MT2063_WriteSub(Handle_t hUserData, 133
134 UData_t addr, 134UData_t MT2063_ReadSub(Handle_t hUserData,
135 U8Data subAddress, 135 UData_t addr,
136 U8Data *pData, 136 U8Data subAddress, U8Data * pData, UData_t cnt);
137 UData_t cnt); 137
138 138void MT2063_Sleep(Handle_t hUserData, UData_t nMinDelayTime);
139 139
140UData_t MT2063_ReadSub(Handle_t hUserData, 140#if defined(MT2060_CNT)
141 UData_t addr, 141#if MT2060_CNT > 0
142 U8Data subAddress, 142UData_t MT2060_TunerGain(Handle_t hUserData, SData_t * pMeas);
143 U8Data *pData, 143#endif
144 UData_t cnt); 144#endif
145 145//end of mt2063_userdef.h
146 146//=================================================================
147void MT2063_Sleep(Handle_t hUserData, 147//#################################################################
148 UData_t nMinDelayTime); 148//=================================================================
149 149
150 150//context of mt2063_spruavoid.h <Henry> ======================================
151#if defined(MT2060_CNT) 151//#################################################################
152#if MT2060_CNT > 0 152//=================================================================
153UData_t MT2060_TunerGain(Handle_t hUserData, 153/*
154 SData_t* pMeas); 154** Constant defining the version of the following structure
155#endif 155** and therefore the API for this code.
156#endif 156**
157//end of mt2063_userdef.h 157** When compiling the tuner driver, the preprocessor will
158//================================================================= 158** check against this version number to make sure that
159//################################################################# 159** it matches the version that the tuner driver knows about.
160//================================================================= 160*/
161 161/* Version 010201 => 1.21 */
162 162#define MT2063_AVOID_SPURS_INFO_VERSION 010201
163//context of mt2063_spruavoid.h <Henry> ====================================== 163
164//################################################################# 164/* DECT Frequency Avoidance */
165//================================================================= 165#define MT2063_DECT_AVOID_US_FREQS 0x00000001
166/* 166
167** Constant defining the version of the following structure 167#define MT2063_DECT_AVOID_EURO_FREQS 0x00000002
168** and therefore the API for this code. 168
169** 169#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
170** When compiling the tuner driver, the preprocessor will 170
171** check against this version number to make sure that 171#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
172** it matches the version that the tuner driver knows about. 172
173*/ 173enum MT2063_DECT_Avoid_Type {
174/* Version 010201 => 1.21 */ 174 MT2063_NO_DECT_AVOIDANCE = 0, /* Do not create DECT exclusion zones. */
175#define MT2063_AVOID_SPURS_INFO_VERSION 010201 175 MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS, /* Avoid US DECT frequencies. */
176 176 MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS, /* Avoid European DECT frequencies. */
177 177 MT2063_AVOID_BOTH /* Avoid both regions. Not typically used. */
178/* DECT Frequency Avoidance */ 178};
179#define MT2063_DECT_AVOID_US_FREQS 0x00000001 179
180 180#define MT2063_MAX_ZONES 48
181#define MT2063_DECT_AVOID_EURO_FREQS 0x00000002 181
182 182struct MT2063_ExclZone_t;
183#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0) 183
184 184struct MT2063_ExclZone_t {
185#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0) 185 UData_t min_;
186 186 UData_t max_;
187 187 struct MT2063_ExclZone_t *next_;
188enum MT2063_DECT_Avoid_Type 188};
189{ 189
190 MT2063_NO_DECT_AVOIDANCE = 0, /* Do not create DECT exclusion zones. */ 190/*
191 MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS, /* Avoid US DECT frequencies. */ 191** Structure of data needed for Spur Avoidance
192 MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS, /* Avoid European DECT frequencies. */ 192*/
193 MT2063_AVOID_BOTH /* Avoid both regions. Not typically used. */ 193struct MT2063_AvoidSpursData_t {
194 194 UData_t nAS_Algorithm;
195} ; 195 UData_t f_ref;
196 196 UData_t f_in;
197 197 UData_t f_LO1;
198#define MT2063_MAX_ZONES 48 198 UData_t f_if1_Center;
199 199 UData_t f_if1_Request;
200struct MT2063_ExclZone_t; 200 UData_t f_if1_bw;
201 201 UData_t f_LO2;
202struct MT2063_ExclZone_t 202 UData_t f_out;
203{ 203 UData_t f_out_bw;
204 UData_t min_; 204 UData_t f_LO1_Step;
205 UData_t max_; 205 UData_t f_LO2_Step;
206 struct MT2063_ExclZone_t* next_; 206 UData_t f_LO1_FracN_Avoid;
207}; 207 UData_t f_LO2_FracN_Avoid;
208 208 UData_t f_zif_bw;
209/* 209 UData_t f_min_LO_Separation;
210** Structure of data needed for Spur Avoidance 210 UData_t maxH1;
211*/ 211 UData_t maxH2;
212struct MT2063_AvoidSpursData_t 212 enum MT2063_DECT_Avoid_Type avoidDECT;
213{ 213 UData_t bSpurPresent;
214 UData_t nAS_Algorithm; 214 UData_t bSpurAvoided;
215 UData_t f_ref; 215 UData_t nSpursFound;
216 UData_t f_in; 216 UData_t nZones;
217 UData_t f_LO1; 217 struct MT2063_ExclZone_t *freeZones;
218 UData_t f_if1_Center; 218 struct MT2063_ExclZone_t *usedZones;
219 UData_t f_if1_Request; 219 struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
220 UData_t f_if1_bw; 220};
221 UData_t f_LO2; 221
222 UData_t f_out; 222UData_t MT2063_RegisterTuner(struct MT2063_AvoidSpursData_t *pAS_Info);
223 UData_t f_out_bw; 223
224 UData_t f_LO1_Step; 224void MT2063_UnRegisterTuner(struct MT2063_AvoidSpursData_t *pAS_Info);
225 UData_t f_LO2_Step; 225
226 UData_t f_LO1_FracN_Avoid; 226void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info);
227 UData_t f_LO2_FracN_Avoid; 227
228 UData_t f_zif_bw; 228void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
229 UData_t f_min_LO_Separation; 229 UData_t f_min, UData_t f_max);
230 UData_t maxH1; 230
231 UData_t maxH2; 231UData_t MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info);
232 enum MT2063_DECT_Avoid_Type avoidDECT; 232
233 UData_t bSpurPresent; 233UData_t MT2063_AvoidSpurs(Handle_t h, struct MT2063_AvoidSpursData_t *pAS_Info);
234 UData_t bSpurAvoided; 234
235 UData_t nSpursFound; 235UData_t MT2063_AvoidSpursVersion(void);
236 UData_t nZones; 236
237 struct MT2063_ExclZone_t* freeZones; 237//end of mt2063_spuravoid.h
238 struct MT2063_ExclZone_t* usedZones; 238//=================================================================
239 struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES]; 239//#################################################################
240}; 240//=================================================================
241 241
242UData_t MT2063_RegisterTuner(struct MT2063_AvoidSpursData_t* pAS_Info); 242/*
243 243** Values returned by the MT2063's on-chip temperature sensor
244void MT2063_UnRegisterTuner(struct MT2063_AvoidSpursData_t* pAS_Info); 244** to be read/written.
245 245*/
246void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t* pAS_Info); 246enum MT2063_Temperature {
247 247 MT2063_T_0C = 0, /* Temperature approx 0C */
248void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t* pAS_Info, 248 MT2063_T_10C, /* Temperature approx 10C */
249 UData_t f_min, 249 MT2063_T_20C, /* Temperature approx 20C */
250 UData_t f_max); 250 MT2063_T_30C, /* Temperature approx 30C */
251 251 MT2063_T_40C, /* Temperature approx 40C */
252UData_t MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t* pAS_Info); 252 MT2063_T_50C, /* Temperature approx 50C */
253 253 MT2063_T_60C, /* Temperature approx 60C */
254UData_t MT2063_AvoidSpurs(Handle_t h, 254 MT2063_T_70C, /* Temperature approx 70C */
255 struct MT2063_AvoidSpursData_t* pAS_Info); 255 MT2063_T_80C, /* Temperature approx 80C */
256 256 MT2063_T_90C, /* Temperature approx 90C */
257UData_t MT2063_AvoidSpursVersion(void); 257 MT2063_T_100C, /* Temperature approx 100C */
258 258 MT2063_T_110C, /* Temperature approx 110C */
259//end of mt2063_spuravoid.h 259 MT2063_T_120C, /* Temperature approx 120C */
260//================================================================= 260 MT2063_T_130C, /* Temperature approx 130C */
261//################################################################# 261 MT2063_T_140C, /* Temperature approx 140C */
262//================================================================= 262 MT2063_T_150C, /* Temperature approx 150C */
263 263};
264 264
265/* 265/*
266** Values returned by the MT2063's on-chip temperature sensor 266** Parameters for selecting GPIO bits
267** to be read/written. 267*/
268*/ 268enum MT2063_GPIO_Attr {
269enum MT2063_Temperature 269 MT2063_GPIO_IN,
270{ 270 MT2063_GPIO_DIR,
271 MT2063_T_0C = 0, /* Temperature approx 0C */ 271 MT2063_GPIO_OUT,
272 MT2063_T_10C, /* Temperature approx 10C */ 272};
273 MT2063_T_20C, /* Temperature approx 20C */ 273
274 MT2063_T_30C, /* Temperature approx 30C */ 274enum MT2063_GPIO_ID {
275 MT2063_T_40C, /* Temperature approx 40C */ 275 MT2063_GPIO0,
276 MT2063_T_50C, /* Temperature approx 50C */ 276 MT2063_GPIO1,
277 MT2063_T_60C, /* Temperature approx 60C */ 277 MT2063_GPIO2,
278 MT2063_T_70C, /* Temperature approx 70C */ 278};
279 MT2063_T_80C, /* Temperature approx 80C */ 279
280 MT2063_T_90C, /* Temperature approx 90C */ 280/*
281 MT2063_T_100C, /* Temperature approx 100C */ 281** Parameter for function MT2063_SetExtSRO that specifies the external
282 MT2063_T_110C, /* Temperature approx 110C */ 282** SRO drive frequency.
283 MT2063_T_120C, /* Temperature approx 120C */ 283**
284 MT2063_T_130C, /* Temperature approx 130C */ 284** MT2063_EXT_SRO_OFF is the power-up default value.
285 MT2063_T_140C, /* Temperature approx 140C */ 285*/
286 MT2063_T_150C, /* Temperature approx 150C */ 286enum MT2063_Ext_SRO {
287}; 287 MT2063_EXT_SRO_OFF, /* External SRO drive off */
288 288 MT2063_EXT_SRO_BY_4, /* External SRO drive divide by 4 */
289 289 MT2063_EXT_SRO_BY_2, /* External SRO drive divide by 2 */
290/* 290 MT2063_EXT_SRO_BY_1 /* External SRO drive divide by 1 */
291** Parameters for selecting GPIO bits 291};
292*/ 292
293enum MT2063_GPIO_Attr 293/*
294{ 294** Parameter for function MT2063_SetPowerMask that specifies the power down
295 MT2063_GPIO_IN, 295** of various sections of the MT2063.
296 MT2063_GPIO_DIR, 296*/
297 MT2063_GPIO_OUT, 297enum MT2063_Mask_Bits {
298}; 298 MT2063_REG_SD = 0x0040, /* Shutdown regulator */
299 299 MT2063_SRO_SD = 0x0020, /* Shutdown SRO */
300enum MT2063_GPIO_ID 300 MT2063_AFC_SD = 0x0010, /* Shutdown AFC A/D */
301{ 301 MT2063_PD_SD = 0x0002, /* Enable power detector shutdown */
302 MT2063_GPIO0, 302 MT2063_PDADC_SD = 0x0001, /* Enable power detector A/D shutdown */
303 MT2063_GPIO1, 303 MT2063_VCO_SD = 0x8000, /* Enable VCO shutdown */
304 MT2063_GPIO2, 304 MT2063_LTX_SD = 0x4000, /* Enable LTX shutdown */
305}; 305 MT2063_LT1_SD = 0x2000, /* Enable LT1 shutdown */
306 306 MT2063_LNA_SD = 0x1000, /* Enable LNA shutdown */
307 307 MT2063_UPC_SD = 0x0800, /* Enable upconverter shutdown */
308/* 308 MT2063_DNC_SD = 0x0400, /* Enable downconverter shutdown */
309** Parameter for function MT2063_SetExtSRO that specifies the external 309 MT2063_VGA_SD = 0x0200, /* Enable VGA shutdown */
310** SRO drive frequency. 310 MT2063_AMP_SD = 0x0100, /* Enable AMP shutdown */
311** 311 MT2063_ALL_SD = 0xFF73, /* All shutdown bits for this tuner */
312** MT2063_EXT_SRO_OFF is the power-up default value. 312 MT2063_NONE_SD = 0x0000 /* No shutdown bits */
313*/ 313};
314enum MT2063_Ext_SRO 314
315{ 315/*
316 MT2063_EXT_SRO_OFF, /* External SRO drive off */ 316** Parameter for function MT2063_GetParam & MT2063_SetParam that
317 MT2063_EXT_SRO_BY_4, /* External SRO drive divide by 4 */ 317** specifies the tuning algorithm parameter to be read/written.
318 MT2063_EXT_SRO_BY_2, /* External SRO drive divide by 2 */ 318*/
319 MT2063_EXT_SRO_BY_1 /* External SRO drive divide by 1 */ 319enum MT2063_Param {
320}; 320 /* tuner address set by MT2063_Open() */
321 321 MT2063_IC_ADDR,
322 322
323/* 323 /* max number of MT2063 tuners set by MT_TUNER_CNT in mt_userdef.h */
324** Parameter for function MT2063_SetPowerMask that specifies the power down 324 MT2063_MAX_OPEN,
325** of various sections of the MT2063. 325
326*/ 326 /* current number of open MT2063 tuners set by MT2063_Open() */
327enum MT2063_Mask_Bits 327 MT2063_NUM_OPEN,
328{ 328
329 MT2063_REG_SD = 0x0040, /* Shutdown regulator */ 329 /* crystal frequency (default: 16000000 Hz) */
330 MT2063_SRO_SD = 0x0020, /* Shutdown SRO */ 330 MT2063_SRO_FREQ,
331 MT2063_AFC_SD = 0x0010, /* Shutdown AFC A/D */ 331
332 MT2063_PD_SD = 0x0002, /* Enable power detector shutdown */ 332 /* min tuning step size (default: 50000 Hz) */
333 MT2063_PDADC_SD = 0x0001, /* Enable power detector A/D shutdown */ 333 MT2063_STEPSIZE,
334 MT2063_VCO_SD = 0x8000, /* Enable VCO shutdown */ 334
335 MT2063_LTX_SD = 0x4000, /* Enable LTX shutdown */ 335 /* input center frequency set by MT2063_Tune() */
336 MT2063_LT1_SD = 0x2000, /* Enable LT1 shutdown */ 336 MT2063_INPUT_FREQ,
337 MT2063_LNA_SD = 0x1000, /* Enable LNA shutdown */ 337
338 MT2063_UPC_SD = 0x0800, /* Enable upconverter shutdown */ 338 /* LO1 Frequency set by MT2063_Tune() */
339 MT2063_DNC_SD = 0x0400, /* Enable downconverter shutdown */ 339 MT2063_LO1_FREQ,
340 MT2063_VGA_SD = 0x0200, /* Enable VGA shutdown */ 340
341 MT2063_AMP_SD = 0x0100, /* Enable AMP shutdown */ 341 /* LO1 minimum step size (default: 250000 Hz) */
342 MT2063_ALL_SD = 0xFF73, /* All shutdown bits for this tuner */ 342 MT2063_LO1_STEPSIZE,
343 MT2063_NONE_SD = 0x0000 /* No shutdown bits */ 343
344}; 344 /* LO1 FracN keep-out region (default: 999999 Hz) */
345 345 MT2063_LO1_FRACN_AVOID_PARAM,
346 346
347/* 347 /* Current 1st IF in use set by MT2063_Tune() */
348** Parameter for function MT2063_GetParam & MT2063_SetParam that 348 MT2063_IF1_ACTUAL,
349** specifies the tuning algorithm parameter to be read/written. 349
350*/ 350 /* Requested 1st IF set by MT2063_Tune() */
351enum MT2063_Param 351 MT2063_IF1_REQUEST,
352{ 352
353 /* tuner address set by MT2063_Open() */ 353 /* Center of 1st IF SAW filter (default: 1218000000 Hz) */
354 MT2063_IC_ADDR, 354 MT2063_IF1_CENTER,
355 355
356 /* max number of MT2063 tuners set by MT_TUNER_CNT in mt_userdef.h */ 356 /* Bandwidth of 1st IF SAW filter (default: 20000000 Hz) */
357 MT2063_MAX_OPEN, 357 MT2063_IF1_BW,
358 358
359 /* current number of open MT2063 tuners set by MT2063_Open() */ 359 /* zero-IF bandwidth (default: 2000000 Hz) */
360 MT2063_NUM_OPEN, 360 MT2063_ZIF_BW,
361 361
362 /* crystal frequency (default: 16000000 Hz) */ 362 /* LO2 Frequency set by MT2063_Tune() */
363 MT2063_SRO_FREQ, 363 MT2063_LO2_FREQ,
364 364
365 /* min tuning step size (default: 50000 Hz) */ 365 /* LO2 minimum step size (default: 50000 Hz) */
366 MT2063_STEPSIZE, 366 MT2063_LO2_STEPSIZE,
367 367
368 /* input center frequency set by MT2063_Tune() */ 368 /* LO2 FracN keep-out region (default: 374999 Hz) */
369 MT2063_INPUT_FREQ, 369 MT2063_LO2_FRACN_AVOID,
370 370
371 /* LO1 Frequency set by MT2063_Tune() */ 371 /* output center frequency set by MT2063_Tune() */
372 MT2063_LO1_FREQ, 372 MT2063_OUTPUT_FREQ,
373 373
374 /* LO1 minimum step size (default: 250000 Hz) */ 374 /* output bandwidth set by MT2063_Tune() */
375 MT2063_LO1_STEPSIZE, 375 MT2063_OUTPUT_BW,
376 376
377 /* LO1 FracN keep-out region (default: 999999 Hz) */ 377 /* min inter-tuner LO separation (default: 1000000 Hz) */
378 MT2063_LO1_FRACN_AVOID_PARAM, 378 MT2063_LO_SEPARATION,
379 379
380 /* Current 1st IF in use set by MT2063_Tune() */ 380 /* ID of avoid-spurs algorithm in use compile-time constant */
381 MT2063_IF1_ACTUAL, 381 MT2063_AS_ALG,
382 382
383 /* Requested 1st IF set by MT2063_Tune() */ 383 /* max # of intra-tuner harmonics (default: 15) */
384 MT2063_IF1_REQUEST, 384 MT2063_MAX_HARM1,
385 385
386 /* Center of 1st IF SAW filter (default: 1218000000 Hz) */ 386 /* max # of inter-tuner harmonics (default: 7) */
387 MT2063_IF1_CENTER, 387 MT2063_MAX_HARM2,
388 388
389 /* Bandwidth of 1st IF SAW filter (default: 20000000 Hz) */ 389 /* # of 1st IF exclusion zones used set by MT2063_Tune() */
390 MT2063_IF1_BW, 390 MT2063_EXCL_ZONES,
391 391
392 /* zero-IF bandwidth (default: 2000000 Hz) */ 392 /* # of spurs found/avoided set by MT2063_Tune() */
393 MT2063_ZIF_BW, 393 MT2063_NUM_SPURS,
394 394
395 /* LO2 Frequency set by MT2063_Tune() */ 395 /* >0 spurs avoided set by MT2063_Tune() */
396 MT2063_LO2_FREQ, 396 MT2063_SPUR_AVOIDED,
397 397
398 /* LO2 minimum step size (default: 50000 Hz) */ 398 /* >0 spurs in output (mathematically) set by MT2063_Tune() */
399 MT2063_LO2_STEPSIZE, 399 MT2063_SPUR_PRESENT,
400 400
401 /* LO2 FracN keep-out region (default: 374999 Hz) */ 401 /* Receiver Mode for some parameters. 1 is DVB-T */
402 MT2063_LO2_FRACN_AVOID, 402 MT2063_RCVR_MODE,
403 403
404 /* output center frequency set by MT2063_Tune() */ 404 /* directly set LNA attenuation, parameter is value to set */
405 MT2063_OUTPUT_FREQ, 405 MT2063_ACLNA,
406 406
407 /* output bandwidth set by MT2063_Tune() */ 407 /* maximum LNA attenuation, parameter is value to set */
408 MT2063_OUTPUT_BW, 408 MT2063_ACLNA_MAX,
409 409
410 /* min inter-tuner LO separation (default: 1000000 Hz) */ 410 /* directly set ATN attenuation. Paremeter is value to set. */
411 MT2063_LO_SEPARATION, 411 MT2063_ACRF,
412 412
413 /* ID of avoid-spurs algorithm in use compile-time constant */ 413 /* maxium ATN attenuation. Paremeter is value to set. */
414 MT2063_AS_ALG, 414 MT2063_ACRF_MAX,
415 415
416 /* max # of intra-tuner harmonics (default: 15) */ 416 /* directly set FIF attenuation. Paremeter is value to set. */
417 MT2063_MAX_HARM1, 417 MT2063_ACFIF,
418 418
419 /* max # of inter-tuner harmonics (default: 7) */ 419 /* maxium FIF attenuation. Paremeter is value to set. */
420 MT2063_MAX_HARM2, 420 MT2063_ACFIF_MAX,
421 421
422 /* # of 1st IF exclusion zones used set by MT2063_Tune() */ 422 /* LNA Rin */
423 MT2063_EXCL_ZONES, 423 MT2063_LNA_RIN,
424 424
425 /* # of spurs found/avoided set by MT2063_Tune() */ 425 /* Power Detector LNA level target */
426 MT2063_NUM_SPURS, 426 MT2063_LNA_TGT,
427 427
428 /* >0 spurs avoided set by MT2063_Tune() */ 428 /* Power Detector 1 level */
429 MT2063_SPUR_AVOIDED, 429 MT2063_PD1,
430 430
431 /* >0 spurs in output (mathematically) set by MT2063_Tune() */ 431 /* Power Detector 1 level target */
432 MT2063_SPUR_PRESENT, 432 MT2063_PD1_TGT,
433 433
434 /* Receiver Mode for some parameters. 1 is DVB-T */ 434 /* Power Detector 2 level */
435 MT2063_RCVR_MODE, 435 MT2063_PD2,
436 436
437 /* directly set LNA attenuation, parameter is value to set */ 437 /* Power Detector 2 level target */
438 MT2063_ACLNA, 438 MT2063_PD2_TGT,
439 439
440 /* maximum LNA attenuation, parameter is value to set */ 440 /* Selects, which DNC is activ */
441 MT2063_ACLNA_MAX, 441 MT2063_DNC_OUTPUT_ENABLE,
442 442
443 /* directly set ATN attenuation. Paremeter is value to set. */ 443 /* VGA gain code */
444 MT2063_ACRF, 444 MT2063_VGAGC,
445 445
446 /* maxium ATN attenuation. Paremeter is value to set. */ 446 /* VGA bias current */
447 MT2063_ACRF_MAX, 447 MT2063_VGAOI,
448 448
449 /* directly set FIF attenuation. Paremeter is value to set. */ 449 /* TAGC, determins the speed of the AGC */
450 MT2063_ACFIF, 450 MT2063_TAGC,
451 451
452 /* maxium FIF attenuation. Paremeter is value to set. */ 452 /* AMP gain code */
453 MT2063_ACFIF_MAX, 453 MT2063_AMPGC,
454 454
455 /* LNA Rin */ 455 /* Control setting to avoid DECT freqs (default: MT_AVOID_BOTH) */
456 MT2063_LNA_RIN, 456 MT2063_AVOID_DECT,
457 457
458 /* Power Detector LNA level target */ 458 /* Cleartune filter selection: 0 - by IC (default), 1 - by software */
459 MT2063_LNA_TGT, 459 MT2063_CTFILT_SW,
460 460
461 /* Power Detector 1 level */ 461 MT2063_EOP /* last entry in enumerated list */
462 MT2063_PD1, 462};
463 463
464 /* Power Detector 1 level target */ 464/*
465 MT2063_PD1_TGT, 465** Parameter for selecting tuner mode
466 466*/
467 /* Power Detector 2 level */ 467enum MT2063_RCVR_MODES {
468 MT2063_PD2, 468 MT2063_CABLE_QAM = 0, /* Digital cable */
469 469 MT2063_CABLE_ANALOG, /* Analog cable */
470 /* Power Detector 2 level target */ 470 MT2063_OFFAIR_COFDM, /* Digital offair */
471 MT2063_PD2_TGT, 471 MT2063_OFFAIR_COFDM_SAWLESS, /* Digital offair without SAW */
472 472 MT2063_OFFAIR_ANALOG, /* Analog offair */
473 /* Selects, which DNC is activ */ 473 MT2063_OFFAIR_8VSB, /* Analog offair */
474 MT2063_DNC_OUTPUT_ENABLE, 474 MT2063_NUM_RCVR_MODES
475 475};
476 /* VGA gain code */ 476
477 MT2063_VGAGC, 477/*
478 478** Possible values for MT2063_DNC_OUTPUT
479 /* VGA bias current */ 479*/
480 MT2063_VGAOI, 480enum MT2063_DNC_Output_Enable {
481 481 MT2063_DNC_NONE = 0,
482 /* TAGC, determins the speed of the AGC */ 482 MT2063_DNC_1,
483 MT2063_TAGC, 483 MT2063_DNC_2,
484 484 MT2063_DNC_BOTH
485 /* AMP gain code */ 485};
486 MT2063_AMPGC, 486
487 487/*
488 /* Control setting to avoid DECT freqs (default: MT_AVOID_BOTH) */ 488** Two-wire serial bus subaddresses of the tuner registers.
489 MT2063_AVOID_DECT, 489** Also known as the tuner's register addresses.
490 490*/
491 /* Cleartune filter selection: 0 - by IC (default), 1 - by software */ 491enum MT2063_Register_Offsets {
492 MT2063_CTFILT_SW, 492 MT2063_REG_PART_REV = 0, /* 0x00: Part/Rev Code */
493 493 MT2063_REG_LO1CQ_1, /* 0x01: LO1C Queued Byte 1 */
494 MT2063_EOP /* last entry in enumerated list */ 494 MT2063_REG_LO1CQ_2, /* 0x02: LO1C Queued Byte 2 */
495 495 MT2063_REG_LO2CQ_1, /* 0x03: LO2C Queued Byte 1 */
496}; 496 MT2063_REG_LO2CQ_2, /* 0x04: LO2C Queued Byte 2 */
497 497 MT2063_REG_LO2CQ_3, /* 0x05: LO2C Queued Byte 3 */
498 498 MT2063_REG_RSVD_06, /* 0x06: Reserved */
499/* 499 MT2063_REG_LO_STATUS, /* 0x07: LO Status */
500** Parameter for selecting tuner mode 500 MT2063_REG_FIFFC, /* 0x08: FIFF Center */
501*/ 501 MT2063_REG_CLEARTUNE, /* 0x09: ClearTune Filter */
502enum MT2063_RCVR_MODES 502 MT2063_REG_ADC_OUT, /* 0x0A: ADC_OUT */
503{ 503 MT2063_REG_LO1C_1, /* 0x0B: LO1C Byte 1 */
504 MT2063_CABLE_QAM = 0, /* Digital cable */ 504 MT2063_REG_LO1C_2, /* 0x0C: LO1C Byte 2 */
505 MT2063_CABLE_ANALOG, /* Analog cable */ 505 MT2063_REG_LO2C_1, /* 0x0D: LO2C Byte 1 */
506 MT2063_OFFAIR_COFDM, /* Digital offair */ 506 MT2063_REG_LO2C_2, /* 0x0E: LO2C Byte 2 */
507 MT2063_OFFAIR_COFDM_SAWLESS, /* Digital offair without SAW */ 507 MT2063_REG_LO2C_3, /* 0x0F: LO2C Byte 3 */
508 MT2063_OFFAIR_ANALOG, /* Analog offair */ 508 MT2063_REG_RSVD_10, /* 0x10: Reserved */
509 MT2063_OFFAIR_8VSB, /* Analog offair */ 509 MT2063_REG_PWR_1, /* 0x11: PWR Byte 1 */
510 MT2063_NUM_RCVR_MODES 510 MT2063_REG_PWR_2, /* 0x12: PWR Byte 2 */
511}; 511 MT2063_REG_TEMP_STATUS, /* 0x13: Temp Status */
512 512 MT2063_REG_XO_STATUS, /* 0x14: Crystal Status */
513 513 MT2063_REG_RF_STATUS, /* 0x15: RF Attn Status */
514/* 514 MT2063_REG_FIF_STATUS, /* 0x16: FIF Attn Status */
515** Possible values for MT2063_DNC_OUTPUT 515 MT2063_REG_LNA_OV, /* 0x17: LNA Attn Override */
516*/ 516 MT2063_REG_RF_OV, /* 0x18: RF Attn Override */
517enum MT2063_DNC_Output_Enable{ 517 MT2063_REG_FIF_OV, /* 0x19: FIF Attn Override */
518 MT2063_DNC_NONE = 0, 518 MT2063_REG_LNA_TGT, /* 0x1A: Reserved */
519 MT2063_DNC_1, 519 MT2063_REG_PD1_TGT, /* 0x1B: Pwr Det 1 Target */
520 MT2063_DNC_2, 520 MT2063_REG_PD2_TGT, /* 0x1C: Pwr Det 2 Target */
521 MT2063_DNC_BOTH 521 MT2063_REG_RSVD_1D, /* 0x1D: Reserved */
522}; 522 MT2063_REG_RSVD_1E, /* 0x1E: Reserved */
523 523 MT2063_REG_RSVD_1F, /* 0x1F: Reserved */
524/* 524 MT2063_REG_RSVD_20, /* 0x20: Reserved */
525** Two-wire serial bus subaddresses of the tuner registers. 525 MT2063_REG_BYP_CTRL, /* 0x21: Bypass Control */
526** Also known as the tuner's register addresses. 526 MT2063_REG_RSVD_22, /* 0x22: Reserved */
527*/ 527 MT2063_REG_RSVD_23, /* 0x23: Reserved */
528enum MT2063_Register_Offsets 528 MT2063_REG_RSVD_24, /* 0x24: Reserved */
529{ 529 MT2063_REG_RSVD_25, /* 0x25: Reserved */
530 MT2063_REG_PART_REV = 0, /* 0x00: Part/Rev Code */ 530 MT2063_REG_RSVD_26, /* 0x26: Reserved */
531 MT2063_REG_LO1CQ_1, /* 0x01: LO1C Queued Byte 1 */ 531 MT2063_REG_RSVD_27, /* 0x27: Reserved */
532 MT2063_REG_LO1CQ_2, /* 0x02: LO1C Queued Byte 2 */ 532 MT2063_REG_FIFF_CTRL, /* 0x28: FIFF Control */
533 MT2063_REG_LO2CQ_1, /* 0x03: LO2C Queued Byte 1 */ 533 MT2063_REG_FIFF_OFFSET, /* 0x29: FIFF Offset */
534 MT2063_REG_LO2CQ_2, /* 0x04: LO2C Queued Byte 2 */ 534 MT2063_REG_CTUNE_CTRL, /* 0x2A: Reserved */
535 MT2063_REG_LO2CQ_3, /* 0x05: LO2C Queued Byte 3 */ 535 MT2063_REG_CTUNE_OV, /* 0x2B: Reserved */
536 MT2063_REG_RSVD_06, /* 0x06: Reserved */ 536 MT2063_REG_CTRL_2C, /* 0x2C: Reserved */
537 MT2063_REG_LO_STATUS, /* 0x07: LO Status */ 537 MT2063_REG_FIFF_CTRL2, /* 0x2D: Fiff Control */
538 MT2063_REG_FIFFC, /* 0x08: FIFF Center */ 538 MT2063_REG_RSVD_2E, /* 0x2E: Reserved */
539 MT2063_REG_CLEARTUNE, /* 0x09: ClearTune Filter */ 539 MT2063_REG_DNC_GAIN, /* 0x2F: DNC Control */
540 MT2063_REG_ADC_OUT, /* 0x0A: ADC_OUT */ 540 MT2063_REG_VGA_GAIN, /* 0x30: VGA Gain Ctrl */
541 MT2063_REG_LO1C_1, /* 0x0B: LO1C Byte 1 */ 541 MT2063_REG_RSVD_31, /* 0x31: Reserved */
542 MT2063_REG_LO1C_2, /* 0x0C: LO1C Byte 2 */ 542 MT2063_REG_TEMP_SEL, /* 0x32: Temperature Selection */
543 MT2063_REG_LO2C_1, /* 0x0D: LO2C Byte 1 */ 543 MT2063_REG_RSVD_33, /* 0x33: Reserved */
544 MT2063_REG_LO2C_2, /* 0x0E: LO2C Byte 2 */ 544 MT2063_REG_RSVD_34, /* 0x34: Reserved */
545 MT2063_REG_LO2C_3, /* 0x0F: LO2C Byte 3 */ 545 MT2063_REG_RSVD_35, /* 0x35: Reserved */
546 MT2063_REG_RSVD_10, /* 0x10: Reserved */ 546 MT2063_REG_RSVD_36, /* 0x36: Reserved */
547 MT2063_REG_PWR_1, /* 0x11: PWR Byte 1 */ 547 MT2063_REG_RSVD_37, /* 0x37: Reserved */
548 MT2063_REG_PWR_2, /* 0x12: PWR Byte 2 */ 548 MT2063_REG_RSVD_38, /* 0x38: Reserved */
549 MT2063_REG_TEMP_STATUS, /* 0x13: Temp Status */ 549 MT2063_REG_RSVD_39, /* 0x39: Reserved */
550 MT2063_REG_XO_STATUS, /* 0x14: Crystal Status */ 550 MT2063_REG_RSVD_3A, /* 0x3A: Reserved */
551 MT2063_REG_RF_STATUS, /* 0x15: RF Attn Status */ 551 MT2063_REG_RSVD_3B, /* 0x3B: Reserved */
552 MT2063_REG_FIF_STATUS, /* 0x16: FIF Attn Status */ 552 MT2063_REG_RSVD_3C, /* 0x3C: Reserved */
553 MT2063_REG_LNA_OV, /* 0x17: LNA Attn Override */ 553 MT2063_REG_END_REGS
554 MT2063_REG_RF_OV, /* 0x18: RF Attn Override */ 554};
555 MT2063_REG_FIF_OV, /* 0x19: FIF Attn Override */ 555
556 MT2063_REG_LNA_TGT, /* 0x1A: Reserved */ 556struct MT2063_Info_t {
557 MT2063_REG_PD1_TGT, /* 0x1B: Pwr Det 1 Target */ 557 Handle_t handle;
558 MT2063_REG_PD2_TGT, /* 0x1C: Pwr Det 2 Target */ 558 Handle_t hUserData;
559 MT2063_REG_RSVD_1D, /* 0x1D: Reserved */ 559 UData_t address;
560 MT2063_REG_RSVD_1E, /* 0x1E: Reserved */ 560 UData_t version;
561 MT2063_REG_RSVD_1F, /* 0x1F: Reserved */ 561 UData_t tuner_id;
562 MT2063_REG_RSVD_20, /* 0x20: Reserved */ 562 struct MT2063_AvoidSpursData_t AS_Data;
563 MT2063_REG_BYP_CTRL, /* 0x21: Bypass Control */ 563 UData_t f_IF1_actual;
564 MT2063_REG_RSVD_22, /* 0x22: Reserved */ 564 UData_t rcvr_mode;
565 MT2063_REG_RSVD_23, /* 0x23: Reserved */ 565 UData_t ctfilt_sw;
566 MT2063_REG_RSVD_24, /* 0x24: Reserved */ 566 UData_t CTFiltMax[31];
567 MT2063_REG_RSVD_25, /* 0x25: Reserved */ 567 UData_t num_regs;
568 MT2063_REG_RSVD_26, /* 0x26: Reserved */ 568 U8Data reg[MT2063_REG_END_REGS];
569 MT2063_REG_RSVD_27, /* 0x27: Reserved */ 569};
570 MT2063_REG_FIFF_CTRL, /* 0x28: FIFF Control */ 570typedef struct MT2063_Info_t *pMT2063_Info_t;
571 MT2063_REG_FIFF_OFFSET, /* 0x29: FIFF Offset */ 571
572 MT2063_REG_CTUNE_CTRL, /* 0x2A: Reserved */ 572enum MTTune_atv_standard {
573 MT2063_REG_CTUNE_OV, /* 0x2B: Reserved */ 573 MTTUNEA_UNKNOWN = 0,
574 MT2063_REG_CTRL_2C, /* 0x2C: Reserved */ 574 MTTUNEA_PAL_B,
575 MT2063_REG_FIFF_CTRL2, /* 0x2D: Fiff Control */ 575 MTTUNEA_PAL_G,
576 MT2063_REG_RSVD_2E, /* 0x2E: Reserved */ 576 MTTUNEA_PAL_I,
577 MT2063_REG_DNC_GAIN, /* 0x2F: DNC Control */ 577 MTTUNEA_PAL_L,
578 MT2063_REG_VGA_GAIN, /* 0x30: VGA Gain Ctrl */ 578 MTTUNEA_PAL_MN,
579 MT2063_REG_RSVD_31, /* 0x31: Reserved */ 579 MTTUNEA_PAL_DK,
580 MT2063_REG_TEMP_SEL, /* 0x32: Temperature Selection */ 580 MTTUNEA_DIGITAL,
581 MT2063_REG_RSVD_33, /* 0x33: Reserved */ 581 MTTUNEA_FMRADIO,
582 MT2063_REG_RSVD_34, /* 0x34: Reserved */ 582 MTTUNEA_DVBC,
583 MT2063_REG_RSVD_35, /* 0x35: Reserved */ 583 MTTUNEA_DVBT
584 MT2063_REG_RSVD_36, /* 0x36: Reserved */ 584};
585 MT2063_REG_RSVD_37, /* 0x37: Reserved */ 585
586 MT2063_REG_RSVD_38, /* 0x38: Reserved */ 586/* ====== Functions which are declared in MT2063.c File ======= */
587 MT2063_REG_RSVD_39, /* 0x39: Reserved */ 587
588 MT2063_REG_RSVD_3A, /* 0x3A: Reserved */ 588UData_t MT2063_Open(UData_t MT2063_Addr,
589 MT2063_REG_RSVD_3B, /* 0x3B: Reserved */ 589 Handle_t * hMT2063, Handle_t hUserData);
590 MT2063_REG_RSVD_3C, /* 0x3C: Reserved */ 590
591 MT2063_REG_END_REGS 591UData_t MT2063_Close(Handle_t hMT2063);
592}; 592
593 593UData_t MT2063_Tune(Handle_t h, UData_t f_in); /* RF input center frequency */
594struct MT2063_Info_t 594
595{ 595UData_t MT2063_GetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id,
596 Handle_t handle; 596 enum MT2063_GPIO_Attr attr, UData_t * value);
597 Handle_t hUserData; 597
598 UData_t address; 598UData_t MT2063_GetLocked(Handle_t h);
599 UData_t version; 599
600 UData_t tuner_id; 600UData_t MT2063_GetParam(Handle_t h, enum MT2063_Param param, UData_t * pValue);
601 struct MT2063_AvoidSpursData_t AS_Data; 601
602 UData_t f_IF1_actual; 602UData_t MT2063_GetReg(Handle_t h, U8Data reg, U8Data * val);
603 UData_t rcvr_mode; 603
604 UData_t ctfilt_sw; 604UData_t MT2063_GetTemp(Handle_t h, enum MT2063_Temperature *value);
605 UData_t CTFiltMax[31]; 605
606 UData_t num_regs; 606UData_t MT2063_GetUserData(Handle_t h, Handle_t * hUserData);
607 U8Data reg[MT2063_REG_END_REGS]; 607
608} ; 608UData_t MT2063_ReInit(Handle_t h);
609typedef struct MT2063_Info_t* pMT2063_Info_t; 609
610 610UData_t MT2063_SetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id,
611enum MTTune_atv_standard{ 611 enum MT2063_GPIO_Attr attr, UData_t value);
612 MTTUNEA_UNKNOWN = 0, 612
613 MTTUNEA_PAL_B, 613UData_t MT2063_SetParam(Handle_t h, enum MT2063_Param param, UData_t nValue);
614 MTTUNEA_PAL_G, 614
615 MTTUNEA_PAL_I, 615UData_t MT2063_SetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits);
616 MTTUNEA_PAL_L, 616
617 MTTUNEA_PAL_MN, 617UData_t MT2063_ClearPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits);
618 MTTUNEA_PAL_DK, 618
619 MTTUNEA_DIGITAL, 619UData_t MT2063_GetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits *Bits);
620 MTTUNEA_FMRADIO, 620
621 MTTUNEA_DVBC, 621UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled);
622 MTTUNEA_DVBT 622
623}; 623UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown);
624 624
625/* ====== Functions which are declared in MT2063.c File ======= */ 625UData_t MT2063_SetExtSRO(Handle_t h, enum MT2063_Ext_SRO Ext_SRO_Setting);
626 626
627UData_t MT2063_Open(UData_t MT2063_Addr, 627UData_t MT2063_SetReg(Handle_t h, U8Data reg, U8Data val);
628 Handle_t* hMT2063, 628
629 Handle_t hUserData); 629UData_t MT_Tune_atv(Handle_t h, UData_t f_in, UData_t bw_in,
630 630 enum MTTune_atv_standard tv_type);
631 631
632UData_t MT2063_Close(Handle_t hMT2063); 632struct mt2063_config {
633 633 u8 tuner_address;
634UData_t MT2063_Tune(Handle_t h, 634 u32 refclock;
635 UData_t f_in); /* RF input center frequency */
636
637UData_t MT2063_GetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, enum MT2063_GPIO_Attr attr, UData_t* value);
638
639
640UData_t MT2063_GetLocked(Handle_t h);
641
642
643UData_t MT2063_GetParam(Handle_t h,
644 enum MT2063_Param param,
645 UData_t* pValue);
646
647
648UData_t MT2063_GetReg(Handle_t h,
649 U8Data reg,
650 U8Data* val);
651
652
653UData_t MT2063_GetTemp(Handle_t h, enum MT2063_Temperature* value);
654
655
656UData_t MT2063_GetUserData(Handle_t h,
657 Handle_t* hUserData);
658
659UData_t MT2063_ReInit(Handle_t h);
660
661
662UData_t MT2063_SetGPIO(Handle_t h, enum MT2063_GPIO_ID gpio_id, enum MT2063_GPIO_Attr attr, UData_t value);
663
664UData_t MT2063_SetParam(Handle_t h,
665 enum MT2063_Param param,
666 UData_t nValue);
667
668
669UData_t MT2063_SetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits);
670
671UData_t MT2063_ClearPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits Bits);
672
673UData_t MT2063_GetPowerMaskBits(Handle_t h, enum MT2063_Mask_Bits *Bits);
674
675UData_t MT2063_EnableExternalShutdown(Handle_t h, U8Data Enabled);
676
677UData_t MT2063_SoftwareShutdown(Handle_t h, U8Data Shutdown);
678
679UData_t MT2063_SetExtSRO(Handle_t h, enum MT2063_Ext_SRO Ext_SRO_Setting);
680
681UData_t MT2063_SetReg(Handle_t h,
682 U8Data reg,
683 U8Data val);
684
685UData_t MT_Tune_atv(Handle_t h, UData_t f_in,UData_t bw_in, enum MTTune_atv_standard tv_type);
686
687
688
689struct mt2063_config {
690 u8 tuner_address;
691 u32 refclock;
692}; 635};
693 636
694struct mt2063_state { 637struct mt2063_state {
695 struct i2c_adapter *i2c; 638 struct i2c_adapter *i2c;
696 639
697 const struct mt2063_config *config; 640 const struct mt2063_config *config;
698 struct dvb_tuner_ops ops; 641 struct dvb_tuner_ops ops;
699 struct dvb_frontend *frontend; 642 struct dvb_frontend *frontend;
700 struct tuner_state status; 643 struct tuner_state status;
701 const struct MT2063_Info_t *MT2063_ht; 644 const struct MT2063_Info_t *MT2063_ht;
702 enum Bool_t MT2063_init; 645 enum Bool_t MT2063_init;
703 646
704 enum MTTune_atv_standard tv_type; 647 enum MTTune_atv_standard tv_type;
705 u32 frequency; 648 u32 frequency;
706 u32 srate; 649 u32 srate;
707 u32 bandwidth; 650 u32 bandwidth;
708 u32 reference; 651 u32 reference;
709}; 652};
710
711#if defined(CONFIG_DVB_MT2063) || (defined(CONFIG_DVB_MT2063_MODULE) && defined(MODULE))
712 653
713extern struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, 654#if defined(CONFIG_DVB_MT2063) || (defined(CONFIG_DVB_MT2063_MODULE) && defined(MODULE))
714 struct mt2063_config *config, 655
715 struct i2c_adapter *i2c); 656extern struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
657 struct mt2063_config *config,
658 struct i2c_adapter *i2c);
716 659
717#else 660#else
718 661
719static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, 662static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
720 struct mt2063_config *config, 663 struct mt2063_config *config,
721 struct i2c_adapter *i2c) 664 struct i2c_adapter *i2c)
722{ 665{
723 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); 666 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
724 return NULL; 667 return NULL;
725} 668}
726 669
727#endif //CONFIG_DVB_MT2063 670#endif //CONFIG_DVB_MT2063
728 671
729#endif //__MT2063_H__ 672#endif //__MT2063_H__
diff --git a/drivers/media/common/tuners/mt2063_cfg.h b/drivers/media/common/tuners/mt2063_cfg.h
index 2b6bd50eddd..5f80f02ed09 100644
--- a/drivers/media/common/tuners/mt2063_cfg.h
+++ b/drivers/media/common/tuners/mt2063_cfg.h
@@ -1,37 +1,40 @@
1 1
2 2static unsigned int mt2063_setTune(struct dvb_frontend *fe, UData_t f_in,
3static unsigned int mt2063_setTune(struct dvb_frontend *fe, UData_t f_in,UData_t bw_in, enum MTTune_atv_standard tv_type) 3 UData_t bw_in,
4 enum MTTune_atv_standard tv_type)
4{ 5{
5 //return (int)MT_Tune_atv(h, f_in, bw_in, tv_type); 6 //return (int)MT_Tune_atv(h, f_in, bw_in, tv_type);
6 7
7 struct dvb_frontend_ops *frontend_ops = NULL; 8 struct dvb_frontend_ops *frontend_ops = NULL;
8 struct dvb_tuner_ops *tuner_ops = NULL; 9 struct dvb_tuner_ops *tuner_ops = NULL;
9 struct tuner_state t_state; 10 struct tuner_state t_state;
10 struct mt2063_state *mt2063State = fe->tuner_priv; 11 struct mt2063_state *mt2063State = fe->tuner_priv;
11 int err = 0; 12 int err = 0;
12 13
13 t_state.frequency = f_in; 14 t_state.frequency = f_in;
14 t_state.bandwidth = bw_in; 15 t_state.bandwidth = bw_in;
15 mt2063State->tv_type = tv_type; 16 mt2063State->tv_type = tv_type;
16 if (&fe->ops) 17 if (&fe->ops)
17 frontend_ops = &fe->ops; 18 frontend_ops = &fe->ops;
18 if (&frontend_ops->tuner_ops) 19 if (&frontend_ops->tuner_ops)
19 tuner_ops = &frontend_ops->tuner_ops; 20 tuner_ops = &frontend_ops->tuner_ops;
20 if (tuner_ops->set_state) { 21 if (tuner_ops->set_state) {
21 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { 22 if ((err =
23 tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY,
24 &t_state)) < 0) {
22 printk("%s: Invalid parameter\n", __func__); 25 printk("%s: Invalid parameter\n", __func__);
23 return err; 26 return err;
24 } 27 }
25 } 28 }
26 29
27 return err; 30 return err;
28} 31}
29 32
30static unsigned int mt2063_lockStatus(struct dvb_frontend *fe) 33static unsigned int mt2063_lockStatus(struct dvb_frontend *fe)
31{ 34{
32 struct dvb_frontend_ops *frontend_ops = &fe->ops; 35 struct dvb_frontend_ops *frontend_ops = &fe->ops;
33 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; 36 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
34 struct tuner_state t_state; 37 struct tuner_state t_state;
35 int err = 0; 38 int err = 0;
36 39
37 if (&fe->ops) 40 if (&fe->ops)
@@ -39,73 +42,81 @@ static unsigned int mt2063_lockStatus(struct dvb_frontend *fe)
39 if (&frontend_ops->tuner_ops) 42 if (&frontend_ops->tuner_ops)
40 tuner_ops = &frontend_ops->tuner_ops; 43 tuner_ops = &frontend_ops->tuner_ops;
41 if (tuner_ops->get_state) { 44 if (tuner_ops->get_state) {
42 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_REFCLOCK, &t_state)) < 0) { 45 if ((err =
46 tuner_ops->get_state(fe, DVBFE_TUNER_REFCLOCK,
47 &t_state)) < 0) {
43 printk("%s: Invalid parameter\n", __func__); 48 printk("%s: Invalid parameter\n", __func__);
44 return err; 49 return err;
45 } 50 }
46 } 51 }
47 return err; 52 return err;
48} 53}
49 54
50static unsigned int tuner_MT2063_Open(struct dvb_frontend *fe) 55static unsigned int tuner_MT2063_Open(struct dvb_frontend *fe)
51{ 56{
52 struct dvb_frontend_ops *frontend_ops = &fe->ops; 57 struct dvb_frontend_ops *frontend_ops = &fe->ops;
53 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; 58 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
54 struct tuner_state t_state; 59 struct tuner_state t_state;
55 int err = 0; 60 int err = 0;
56 61
57 if (&fe->ops) 62 if (&fe->ops)
58 frontend_ops = &fe->ops; 63 frontend_ops = &fe->ops;
59 if (&frontend_ops->tuner_ops) 64 if (&frontend_ops->tuner_ops)
60 tuner_ops = &frontend_ops->tuner_ops; 65 tuner_ops = &frontend_ops->tuner_ops;
61 if (tuner_ops->set_state) { 66 if (tuner_ops->set_state) {
62 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_OPEN, &t_state)) < 0) { 67 if ((err =
68 tuner_ops->set_state(fe, DVBFE_TUNER_OPEN,
69 &t_state)) < 0) {
63 printk("%s: Invalid parameter\n", __func__); 70 printk("%s: Invalid parameter\n", __func__);
64 return err; 71 return err;
65 } 72 }
66 } 73 }
67 74
68 return err; 75 return err;
69} 76}
70 77
71static unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe) 78static unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
72{ 79{
73 struct dvb_frontend_ops *frontend_ops = &fe->ops; 80 struct dvb_frontend_ops *frontend_ops = &fe->ops;
74 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; 81 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
75 struct tuner_state t_state; 82 struct tuner_state t_state;
76 int err = 0; 83 int err = 0;
77 84
78 if (&fe->ops) 85 if (&fe->ops)
79 frontend_ops = &fe->ops; 86 frontend_ops = &fe->ops;
80 if (&frontend_ops->tuner_ops) 87 if (&frontend_ops->tuner_ops)
81 tuner_ops = &frontend_ops->tuner_ops; 88 tuner_ops = &frontend_ops->tuner_ops;
82 if (tuner_ops->set_state) { 89 if (tuner_ops->set_state) {
83 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_SOFTWARE_SHUTDOWN, &t_state)) < 0) { 90 if ((err =
91 tuner_ops->set_state(fe, DVBFE_TUNER_SOFTWARE_SHUTDOWN,
92 &t_state)) < 0) {
84 printk("%s: Invalid parameter\n", __func__); 93 printk("%s: Invalid parameter\n", __func__);
85 return err; 94 return err;
86 } 95 }
87 } 96 }
88 97
89 return err; 98 return err;
90} 99}
91 100
92static unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe) 101static unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
93{ 102{
94 struct dvb_frontend_ops *frontend_ops = &fe->ops; 103 struct dvb_frontend_ops *frontend_ops = &fe->ops;
95 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; 104 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
96 struct tuner_state t_state; 105 struct tuner_state t_state;
97 int err = 0; 106 int err = 0;
98 107
99 if (&fe->ops) 108 if (&fe->ops)
100 frontend_ops = &fe->ops; 109 frontend_ops = &fe->ops;
101 if (&frontend_ops->tuner_ops) 110 if (&frontend_ops->tuner_ops)
102 tuner_ops = &frontend_ops->tuner_ops; 111 tuner_ops = &frontend_ops->tuner_ops;
103 if (tuner_ops->set_state) { 112 if (tuner_ops->set_state) {
104 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_CLEAR_POWER_MASKBITS, &t_state)) < 0) { 113 if ((err =
114 tuner_ops->set_state(fe, DVBFE_TUNER_CLEAR_POWER_MASKBITS,
115 &t_state)) < 0) {
105 printk("%s: Invalid parameter\n", __func__); 116 printk("%s: Invalid parameter\n", __func__);
106 return err; 117 return err;
107 } 118 }
108 } 119 }
109 120
110 return err; 121 return err;
111} 122}