1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/videodev2.h>
27#include <linux/gcd.h>
28
29#include "mt2063.h"
30
31static unsigned int debug;
32module_param(debug, int, 0644);
33MODULE_PARM_DESC(debug, "Set Verbosity level");
34
35#define dprintk(level, fmt, arg...) do { \
36if (debug >= level) \
37 printk(KERN_DEBUG "mt2063 %s: " fmt, __func__, ## arg); \
38} while (0)
39
40
41
42
43
44#define MT2063_SPUR_PRESENT_ERR (0x00800000)
45
46
47#define MT2063_SPUR_CNT_MASK (0x001f0000)
48#define MT2063_SPUR_SHIFT (16)
49
50
51#define MT2063_UPC_RANGE (0x04000000)
52
53
54#define MT2063_DNC_RANGE (0x08000000)
55
56
57
58
59
60
61
62
63
64
65
66#define MT2063_DECT_AVOID_US_FREQS 0x00000001
67
68#define MT2063_DECT_AVOID_EURO_FREQS 0x00000002
69
70#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
71
72#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
73
74enum MT2063_DECT_Avoid_Type {
75 MT2063_NO_DECT_AVOIDANCE = 0,
76 MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS,
77 MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS,
78 MT2063_AVOID_BOTH
79};
80
81#define MT2063_MAX_ZONES 48
82
83struct MT2063_ExclZone_t {
84 u32 min_;
85 u32 max_;
86 struct MT2063_ExclZone_t *next_;
87};
88
89
90
91
92struct MT2063_AvoidSpursData_t {
93 u32 f_ref;
94 u32 f_in;
95 u32 f_LO1;
96 u32 f_if1_Center;
97 u32 f_if1_Request;
98 u32 f_if1_bw;
99 u32 f_LO2;
100 u32 f_out;
101 u32 f_out_bw;
102 u32 f_LO1_Step;
103 u32 f_LO2_Step;
104 u32 f_LO1_FracN_Avoid;
105 u32 f_LO2_FracN_Avoid;
106 u32 f_zif_bw;
107 u32 f_min_LO_Separation;
108 u32 maxH1;
109 u32 maxH2;
110 enum MT2063_DECT_Avoid_Type avoidDECT;
111 u32 bSpurPresent;
112 u32 bSpurAvoided;
113 u32 nSpursFound;
114 u32 nZones;
115 struct MT2063_ExclZone_t *freeZones;
116 struct MT2063_ExclZone_t *usedZones;
117 struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
118};
119
120
121
122
123
124enum MT2063_Mask_Bits {
125 MT2063_REG_SD = 0x0040,
126 MT2063_SRO_SD = 0x0020,
127 MT2063_AFC_SD = 0x0010,
128 MT2063_PD_SD = 0x0002,
129 MT2063_PDADC_SD = 0x0001,
130 MT2063_VCO_SD = 0x8000,
131 MT2063_LTX_SD = 0x4000,
132 MT2063_LT1_SD = 0x2000,
133 MT2063_LNA_SD = 0x1000,
134 MT2063_UPC_SD = 0x0800,
135 MT2063_DNC_SD = 0x0400,
136 MT2063_VGA_SD = 0x0200,
137 MT2063_AMP_SD = 0x0100,
138 MT2063_ALL_SD = 0xFF73,
139 MT2063_NONE_SD = 0x0000
140};
141
142
143
144
145enum MT2063_DNC_Output_Enable {
146 MT2063_DNC_NONE = 0,
147 MT2063_DNC_1,
148 MT2063_DNC_2,
149 MT2063_DNC_BOTH
150};
151
152
153
154
155
156enum MT2063_Register_Offsets {
157 MT2063_REG_PART_REV = 0,
158 MT2063_REG_LO1CQ_1,
159 MT2063_REG_LO1CQ_2,
160 MT2063_REG_LO2CQ_1,
161 MT2063_REG_LO2CQ_2,
162 MT2063_REG_LO2CQ_3,
163 MT2063_REG_RSVD_06,
164 MT2063_REG_LO_STATUS,
165 MT2063_REG_FIFFC,
166 MT2063_REG_CLEARTUNE,
167 MT2063_REG_ADC_OUT,
168 MT2063_REG_LO1C_1,
169 MT2063_REG_LO1C_2,
170 MT2063_REG_LO2C_1,
171 MT2063_REG_LO2C_2,
172 MT2063_REG_LO2C_3,
173 MT2063_REG_RSVD_10,
174 MT2063_REG_PWR_1,
175 MT2063_REG_PWR_2,
176 MT2063_REG_TEMP_STATUS,
177 MT2063_REG_XO_STATUS,
178 MT2063_REG_RF_STATUS,
179 MT2063_REG_FIF_STATUS,
180 MT2063_REG_LNA_OV,
181 MT2063_REG_RF_OV,
182 MT2063_REG_FIF_OV,
183 MT2063_REG_LNA_TGT,
184 MT2063_REG_PD1_TGT,
185 MT2063_REG_PD2_TGT,
186 MT2063_REG_RSVD_1D,
187 MT2063_REG_RSVD_1E,
188 MT2063_REG_RSVD_1F,
189 MT2063_REG_RSVD_20,
190 MT2063_REG_BYP_CTRL,
191 MT2063_REG_RSVD_22,
192 MT2063_REG_RSVD_23,
193 MT2063_REG_RSVD_24,
194 MT2063_REG_RSVD_25,
195 MT2063_REG_RSVD_26,
196 MT2063_REG_RSVD_27,
197 MT2063_REG_FIFF_CTRL,
198 MT2063_REG_FIFF_OFFSET,
199 MT2063_REG_CTUNE_CTRL,
200 MT2063_REG_CTUNE_OV,
201 MT2063_REG_CTRL_2C,
202 MT2063_REG_FIFF_CTRL2,
203 MT2063_REG_RSVD_2E,
204 MT2063_REG_DNC_GAIN,
205 MT2063_REG_VGA_GAIN,
206 MT2063_REG_RSVD_31,
207 MT2063_REG_TEMP_SEL,
208 MT2063_REG_RSVD_33,
209 MT2063_REG_RSVD_34,
210 MT2063_REG_RSVD_35,
211 MT2063_REG_RSVD_36,
212 MT2063_REG_RSVD_37,
213 MT2063_REG_RSVD_38,
214 MT2063_REG_RSVD_39,
215 MT2063_REG_RSVD_3A,
216 MT2063_REG_RSVD_3B,
217 MT2063_REG_RSVD_3C,
218 MT2063_REG_END_REGS
219};
220
221struct mt2063_state {
222 struct i2c_adapter *i2c;
223
224 bool init;
225
226 const struct mt2063_config *config;
227 struct dvb_tuner_ops ops;
228 struct dvb_frontend *frontend;
229
230 u32 frequency;
231 u32 srate;
232 u32 bandwidth;
233 u32 reference;
234
235 u32 tuner_id;
236 struct MT2063_AvoidSpursData_t AS_Data;
237 u32 f_IF1_actual;
238 u32 rcvr_mode;
239 u32 ctfilt_sw;
240 u32 CTFiltMax[31];
241 u32 num_regs;
242 u8 reg[MT2063_REG_END_REGS];
243};
244
245
246
247
248static int mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
249{
250 struct dvb_frontend *fe = state->frontend;
251 int ret;
252 u8 buf[60];
253 struct i2c_msg msg = {
254 .addr = state->config->tuner_address,
255 .flags = 0,
256 .buf = buf,
257 .len = len + 1
258 };
259
260 dprintk(2, "\n");
261
262 msg.buf[0] = reg;
263 memcpy(msg.buf + 1, data, len);
264
265 if (fe->ops.i2c_gate_ctrl)
266 fe->ops.i2c_gate_ctrl(fe, 1);
267 ret = i2c_transfer(state->i2c, &msg, 1);
268 if (fe->ops.i2c_gate_ctrl)
269 fe->ops.i2c_gate_ctrl(fe, 0);
270
271 if (ret < 0)
272 printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
273
274 return ret;
275}
276
277
278
279
280static int mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
281{
282 int status;
283
284 dprintk(2, "\n");
285
286 if (reg >= MT2063_REG_END_REGS)
287 return -ERANGE;
288
289 status = mt2063_write(state, reg, &val, 1);
290 if (status < 0)
291 return status;
292
293 state->reg[reg] = val;
294
295 return 0;
296}
297
298
299
300
301static int mt2063_read(struct mt2063_state *state,
302 u8 subAddress, u8 *pData, u32 cnt)
303{
304 int status = 0;
305 struct dvb_frontend *fe = state->frontend;
306 u32 i = 0;
307
308 dprintk(2, "addr 0x%02x, cnt %d\n", subAddress, cnt);
309
310 if (fe->ops.i2c_gate_ctrl)
311 fe->ops.i2c_gate_ctrl(fe, 1);
312
313 for (i = 0; i < cnt; i++) {
314 u8 b0[] = { subAddress + i };
315 struct i2c_msg msg[] = {
316 {
317 .addr = state->config->tuner_address,
318 .flags = 0,
319 .buf = b0,
320 .len = 1
321 }, {
322 .addr = state->config->tuner_address,
323 .flags = I2C_M_RD,
324 .buf = pData + i,
325 .len = 1
326 }
327 };
328
329 status = i2c_transfer(state->i2c, msg, 2);
330 dprintk(2, "addr 0x%02x, ret = %d, val = 0x%02x\n",
331 subAddress + i, status, *(pData + i));
332 if (status < 0)
333 break;
334 }
335 if (fe->ops.i2c_gate_ctrl)
336 fe->ops.i2c_gate_ctrl(fe, 0);
337
338 if (status < 0)
339 printk(KERN_ERR "Can't read from address 0x%02x,\n",
340 subAddress + i);
341
342 return status;
343}
344
345
346
347
348static int MT2063_Sleep(struct dvb_frontend *fe)
349{
350
351
352
353 msleep(100);
354
355 return 0;
356}
357
358
359
360
361
362
363#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
364#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
365
366struct MT2063_FIFZone_t {
367 s32 min_;
368 s32 max_;
369};
370
371static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
372 *pAS_Info,
373 struct MT2063_ExclZone_t *pPrevNode)
374{
375 struct MT2063_ExclZone_t *pNode;
376
377 dprintk(2, "\n");
378
379
380 if (pAS_Info->freeZones != NULL) {
381
382 pNode = pAS_Info->freeZones;
383 pAS_Info->freeZones = pNode->next_;
384 } else {
385
386 pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
387 }
388
389 if (pPrevNode != NULL) {
390 pNode->next_ = pPrevNode->next_;
391 pPrevNode->next_ = pNode;
392 } else {
393
394 pNode->next_ = pAS_Info->usedZones;
395 pAS_Info->usedZones = pNode;
396 }
397
398 pAS_Info->nZones++;
399 return pNode;
400}
401
402static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
403 *pAS_Info,
404 struct MT2063_ExclZone_t *pPrevNode,
405 struct MT2063_ExclZone_t
406 *pNodeToRemove)
407{
408 struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
409
410 dprintk(2, "\n");
411
412
413 if (pPrevNode != NULL)
414 pPrevNode->next_ = pNext;
415
416
417 pNodeToRemove->next_ = pAS_Info->freeZones;
418 pAS_Info->freeZones = pNodeToRemove;
419
420
421 pAS_Info->nZones--;
422
423 return pNext;
424}
425
426
427
428
429
430
431
432
433
434static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
435 u32 f_min, u32 f_max)
436{
437 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
438 struct MT2063_ExclZone_t *pPrev = NULL;
439 struct MT2063_ExclZone_t *pNext = NULL;
440
441 dprintk(2, "\n");
442
443
444 if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
445 && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
446 && (f_min < f_max)) {
447
448
449
450
451
452
453
454
455
456 while ((pNode != NULL) && (pNode->max_ < f_min)) {
457 pPrev = pNode;
458 pNode = pNode->next_;
459 }
460
461 if ((pNode != NULL) && (pNode->min_ < f_max)) {
462
463 if (f_min < pNode->min_)
464 pNode->min_ = f_min;
465 if (f_max > pNode->max_)
466 pNode->max_ = f_max;
467 } else {
468 pNode = InsertNode(pAS_Info, pPrev);
469 pNode->min_ = f_min;
470 pNode->max_ = f_max;
471 }
472
473
474 pNext = pNode->next_;
475 while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
476 if (pNext->max_ > pNode->max_)
477 pNode->max_ = pNext->max_;
478
479 pNext = RemoveNode(pAS_Info, pNode, pNext);
480 }
481 }
482}
483
484
485
486
487
488static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
489{
490 u32 center;
491
492 dprintk(2, "\n");
493
494 pAS_Info->nZones = 0;
495 pAS_Info->usedZones = NULL;
496 pAS_Info->freeZones = NULL;
497
498 center =
499 pAS_Info->f_ref *
500 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
501 pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
502 while (center <
503 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
504 pAS_Info->f_LO1_FracN_Avoid) {
505
506 MT2063_AddExclZone(pAS_Info,
507 center - pAS_Info->f_LO1_FracN_Avoid,
508 center - 1);
509 MT2063_AddExclZone(pAS_Info, center + 1,
510 center + pAS_Info->f_LO1_FracN_Avoid);
511 center += pAS_Info->f_ref;
512 }
513
514 center =
515 pAS_Info->f_ref *
516 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
517 pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
518 while (center <
519 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
520 pAS_Info->f_LO2_FracN_Avoid) {
521
522 MT2063_AddExclZone(pAS_Info,
523 center - pAS_Info->f_LO2_FracN_Avoid,
524 center - 1);
525 MT2063_AddExclZone(pAS_Info, center + 1,
526 center + pAS_Info->f_LO2_FracN_Avoid);
527 center += pAS_Info->f_ref;
528 }
529
530 if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
531
532 MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in);
533 MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in);
534 MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in);
535 MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in);
536 MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in);
537 }
538
539 if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
540 MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in);
541 MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in);
542 MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in);
543 MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in);
544 MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in);
545 MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in);
546 MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in);
547 MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in);
548 MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in);
549 MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in);
550 }
551}
552
553
554
555
556
557
558
559static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
560{
561
562
563
564
565
566
567
568
569 const u32 f_Desired =
570 pAS_Info->f_LO1_Step *
571 ((pAS_Info->f_if1_Request + pAS_Info->f_in +
572 pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
573 pAS_Info->f_in;
574 const u32 f_Step =
575 (pAS_Info->f_LO1_Step >
576 pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
577 f_LO2_Step;
578 u32 f_Center;
579 s32 i;
580 s32 j = 0;
581 u32 bDesiredExcluded = 0;
582 u32 bZeroExcluded = 0;
583 s32 tmpMin, tmpMax;
584 s32 bestDiff;
585 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
586 struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
587
588 dprintk(2, "\n");
589
590 if (pAS_Info->nZones == 0)
591 return f_Desired;
592
593
594
595
596
597 if (pAS_Info->f_if1_Center > f_Desired)
598 f_Center =
599 f_Desired +
600 f_Step *
601 ((pAS_Info->f_if1_Center - f_Desired +
602 f_Step / 2) / f_Step);
603 else
604 f_Center =
605 f_Desired -
606 f_Step *
607 ((f_Desired - pAS_Info->f_if1_Center +
608 f_Step / 2) / f_Step);
609
610
611
612
613
614 while (pNode != NULL) {
615
616 tmpMin =
617 floor((s32) (pNode->min_ - f_Center), (s32) f_Step);
618
619
620 tmpMax =
621 ceil((s32) (pNode->max_ - f_Center), (s32) f_Step);
622
623 if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
624 bDesiredExcluded = 1;
625
626 if ((tmpMin < 0) && (tmpMax > 0))
627 bZeroExcluded = 1;
628
629
630 if ((j > 0) && (tmpMin < zones[j - 1].max_))
631 zones[j - 1].max_ = tmpMax;
632 else {
633
634 zones[j].min_ = tmpMin;
635 zones[j].max_ = tmpMax;
636 j++;
637 }
638 pNode = pNode->next_;
639 }
640
641
642
643
644 if (bDesiredExcluded == 0)
645 return f_Desired;
646
647
648
649
650 if (bZeroExcluded == 0)
651 return f_Center;
652
653
654 bestDiff = zones[0].min_;
655 for (i = 0; i < j; i++) {
656 if (abs(zones[i].min_) < abs(bestDiff))
657 bestDiff = zones[i].min_;
658 if (abs(zones[i].max_) < abs(bestDiff))
659 bestDiff = zones[i].max_;
660 }
661
662 if (bestDiff < 0)
663 return f_Center - ((u32) (-bestDiff) * f_Step);
664
665 return f_Center + (bestDiff * f_Step);
666}
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
688 u32 *fm, u32 * fp)
689{
690
691
692
693 u32 n, n0;
694 const u32 f_LO1 = pAS_Info->f_LO1;
695 const u32 f_LO2 = pAS_Info->f_LO2;
696 const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
697 const u32 c = d - pAS_Info->f_out_bw;
698 const u32 f = pAS_Info->f_zif_bw / 2;
699 const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
700 s32 f_nsLO1, f_nsLO2;
701 s32 f_Spur;
702 u32 ma, mb, mc, md, me, mf;
703 u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
704
705 dprintk(2, "\n");
706
707 *fm = 0;
708
709
710
711
712
713
714 lo_gcd = gcd(f_LO1, f_LO2);
715 gd_Scale = max((u32) gcd(lo_gcd, d), f_Scale);
716 hgds = gd_Scale / 2;
717 gc_Scale = max((u32) gcd(lo_gcd, c), f_Scale);
718 hgcs = gc_Scale / 2;
719 gf_Scale = max((u32) gcd(lo_gcd, f), f_Scale);
720 hgfs = gf_Scale / 2;
721
722 n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
723
724
725 for (n = n0; n <= pAS_Info->maxH1; ++n) {
726 md = (n * ((f_LO1 + hgds) / gd_Scale) -
727 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
728
729
730 if (md >= pAS_Info->maxH1)
731 break;
732
733 ma = (n * ((f_LO1 + hgds) / gd_Scale) +
734 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
735
736
737 if (md == ma)
738 continue;
739
740 mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
741 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
742 if (mc != md) {
743 f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
744 f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
745 f_Spur =
746 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
747 n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
748
749 *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
750 *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
751 return 1;
752 }
753
754
755 me = (n * ((f_LO1 + hgfs) / gf_Scale) +
756 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
757 mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
758 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
759 if (me != mf) {
760 f_nsLO1 = n * (f_LO1 / gf_Scale);
761 f_nsLO2 = me * (f_LO2 / gf_Scale);
762 f_Spur =
763 (gf_Scale * (f_nsLO1 - f_nsLO2)) +
764 n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
765
766 *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
767 *fm = (((s32) f - f_Spur) / (me - n)) + 1;
768 return 1;
769 }
770
771 mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
772 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
773 if (ma != mb) {
774 f_nsLO1 = n * (f_LO1 / gc_Scale);
775 f_nsLO2 = ma * (f_LO2 / gc_Scale);
776 f_Spur =
777 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
778 n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
779
780 *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
781 *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
782 return 1;
783 }
784 }
785
786
787 return 0;
788}
789
790
791
792
793
794
795
796static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
797{
798 int status = 0;
799 u32 fm, fp;
800 pAS_Info->bSpurAvoided = 0;
801 pAS_Info->nSpursFound = 0;
802
803 dprintk(2, "\n");
804
805 if (pAS_Info->maxH1 == 0)
806 return 0;
807
808
809
810
811
812
813
814
815
816
817
818
819 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
820 if (pAS_Info->bSpurPresent) {
821 u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in;
822 u32 zfLO1 = pAS_Info->f_LO1;
823 u32 zfLO2 = pAS_Info->f_LO2;
824 u32 delta_IF1;
825 u32 new_IF1;
826
827
828
829
830 do {
831 pAS_Info->nSpursFound++;
832
833
834 MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
835
836
837 new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
838
839 if (new_IF1 > zfIF1) {
840 pAS_Info->f_LO1 += (new_IF1 - zfIF1);
841 pAS_Info->f_LO2 += (new_IF1 - zfIF1);
842 } else {
843 pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
844 pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
845 }
846 zfIF1 = new_IF1;
847
848 if (zfIF1 > pAS_Info->f_if1_Center)
849 delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
850 else
851 delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
852
853 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
854
855
856
857
858 } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
859
860
861
862
863
864
865 if (pAS_Info->bSpurPresent == 1) {
866 status |= MT2063_SPUR_PRESENT_ERR;
867 pAS_Info->f_LO1 = zfLO1;
868 pAS_Info->f_LO2 = zfLO2;
869 } else
870 pAS_Info->bSpurAvoided = 1;
871 }
872
873 status |=
874 ((pAS_Info->
875 nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
876
877 return status;
878}
879
880
881
882
883#define MT2063_REF_FREQ (16000000UL)
884#define MT2063_IF1_BW (22000000UL)
885#define MT2063_TUNE_STEP_SIZE (50000UL)
886#define MT2063_SPUR_STEP_HZ (250000UL)
887#define MT2063_ZIF_BW (2000000UL)
888#define MT2063_MAX_HARMONICS_1 (15UL)
889#define MT2063_MAX_HARMONICS_2 (5UL)
890#define MT2063_MIN_LO_SEP (1000000UL)
891#define MT2063_LO1_FRACN_AVOID (0UL)
892#define MT2063_LO2_FRACN_AVOID (199999UL)
893#define MT2063_MIN_FIN_FREQ (44000000UL)
894#define MT2063_MAX_FIN_FREQ (1100000000UL)
895#define MT2063_MIN_FOUT_FREQ (36000000UL)
896#define MT2063_MAX_FOUT_FREQ (57000000UL)
897#define MT2063_MIN_DNC_FREQ (1293000000UL)
898#define MT2063_MAX_DNC_FREQ (1614000000UL)
899#define MT2063_MIN_UPC_FREQ (1396000000UL)
900#define MT2063_MAX_UPC_FREQ (2750000000UL)
901
902
903
904
905#define MT2063_B0 (0x9B)
906#define MT2063_B1 (0x9C)
907#define MT2063_B2 (0x9D)
908#define MT2063_B3 (0x9E)
909
910
911
912
913
914
915
916
917static int mt2063_lockStatus(struct mt2063_state *state)
918{
919 const u32 nMaxWait = 100;
920 const u32 nPollRate = 2;
921 const u32 nMaxLoops = nMaxWait / nPollRate;
922 const u8 LO1LK = 0x80;
923 u8 LO2LK = 0x08;
924 int status;
925 u32 nDelays = 0;
926
927 dprintk(2, "\n");
928
929
930 if (state->tuner_id == MT2063_B0)
931 LO2LK = 0x40;
932
933 do {
934 status = mt2063_read(state, MT2063_REG_LO_STATUS,
935 &state->reg[MT2063_REG_LO_STATUS], 1);
936
937 if (status < 0)
938 return status;
939
940 if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
941 (LO1LK | LO2LK)) {
942 return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
943 }
944 msleep(nPollRate);
945 } while (++nDelays < nMaxLoops);
946
947
948
949
950 return 0;
951}
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989enum mt2063_delivery_sys {
990 MT2063_CABLE_QAM = 0,
991 MT2063_CABLE_ANALOG,
992 MT2063_OFFAIR_COFDM,
993 MT2063_OFFAIR_COFDM_SAWLESS,
994 MT2063_OFFAIR_ANALOG,
995 MT2063_OFFAIR_8VSB,
996 MT2063_NUM_RCVR_MODES
997};
998
999static const char *mt2063_mode_name[] = {
1000 [MT2063_CABLE_QAM] = "digital cable",
1001 [MT2063_CABLE_ANALOG] = "analog cable",
1002 [MT2063_OFFAIR_COFDM] = "digital offair",
1003 [MT2063_OFFAIR_COFDM_SAWLESS] = "digital offair without SAW",
1004 [MT2063_OFFAIR_ANALOG] = "analog offair",
1005 [MT2063_OFFAIR_8VSB] = "analog offair 8vsb",
1006};
1007
1008static const u8 RFAGCEN[] = { 0, 0, 0, 0, 0, 0 };
1009static const u8 LNARIN[] = { 0, 0, 3, 3, 3, 3 };
1010static const u8 FIFFQEN[] = { 1, 1, 1, 1, 1, 1 };
1011static const u8 FIFFQ[] = { 0, 0, 0, 0, 0, 0 };
1012static const u8 DNC1GC[] = { 0, 0, 0, 0, 0, 0 };
1013static const u8 DNC2GC[] = { 0, 0, 0, 0, 0, 0 };
1014static const u8 ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 };
1015static const u8 LNATGT[] = { 44, 43, 43, 43, 43, 43 };
1016static const u8 RFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1017static const u8 ACRFMAX[] = { 31, 31, 31, 31, 31, 31 };
1018static const u8 PD1TGT[] = { 36, 36, 38, 38, 36, 38 };
1019static const u8 FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1020static const u8 ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 };
1021static const u8 PD2TGT[] = { 40, 33, 38, 42, 30, 38 };
1022
1023
1024
1025
1026static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
1027 enum MT2063_DNC_Output_Enable *pValue)
1028{
1029 dprintk(2, "\n");
1030
1031 if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) {
1032 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)
1033 *pValue = MT2063_DNC_NONE;
1034 else
1035 *pValue = MT2063_DNC_2;
1036 } else {
1037 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)
1038 *pValue = MT2063_DNC_1;
1039 else
1040 *pValue = MT2063_DNC_BOTH;
1041 }
1042 return 0;
1043}
1044
1045
1046
1047
1048static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
1049 enum MT2063_DNC_Output_Enable nValue)
1050{
1051 int status = 0;
1052 u8 val = 0;
1053
1054 dprintk(2, "\n");
1055
1056
1057 switch (nValue) {
1058 case MT2063_DNC_NONE:
1059 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;
1060 if (state->reg[MT2063_REG_DNC_GAIN] !=
1061 val)
1062 status |=
1063 mt2063_setreg(state,
1064 MT2063_REG_DNC_GAIN,
1065 val);
1066
1067 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;
1068 if (state->reg[MT2063_REG_VGA_GAIN] !=
1069 val)
1070 status |=
1071 mt2063_setreg(state,
1072 MT2063_REG_VGA_GAIN,
1073 val);
1074
1075 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40);
1076 if (state->reg[MT2063_REG_RSVD_20] !=
1077 val)
1078 status |=
1079 mt2063_setreg(state,
1080 MT2063_REG_RSVD_20,
1081 val);
1082
1083 break;
1084 case MT2063_DNC_1:
1085 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);
1086 if (state->reg[MT2063_REG_DNC_GAIN] !=
1087 val)
1088 status |=
1089 mt2063_setreg(state,
1090 MT2063_REG_DNC_GAIN,
1091 val);
1092
1093 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;
1094 if (state->reg[MT2063_REG_VGA_GAIN] !=
1095 val)
1096 status |=
1097 mt2063_setreg(state,
1098 MT2063_REG_VGA_GAIN,
1099 val);
1100
1101 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40);
1102 if (state->reg[MT2063_REG_RSVD_20] !=
1103 val)
1104 status |=
1105 mt2063_setreg(state,
1106 MT2063_REG_RSVD_20,
1107 val);
1108
1109 break;
1110 case MT2063_DNC_2:
1111 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;
1112 if (state->reg[MT2063_REG_DNC_GAIN] !=
1113 val)
1114 status |=
1115 mt2063_setreg(state,
1116 MT2063_REG_DNC_GAIN,
1117 val);
1118
1119 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);
1120 if (state->reg[MT2063_REG_VGA_GAIN] !=
1121 val)
1122 status |=
1123 mt2063_setreg(state,
1124 MT2063_REG_VGA_GAIN,
1125 val);
1126
1127 val = (state->reg[MT2063_REG_RSVD_20] | 0x40);
1128 if (state->reg[MT2063_REG_RSVD_20] !=
1129 val)
1130 status |=
1131 mt2063_setreg(state,
1132 MT2063_REG_RSVD_20,
1133 val);
1134
1135 break;
1136 case MT2063_DNC_BOTH:
1137 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);
1138 if (state->reg[MT2063_REG_DNC_GAIN] !=
1139 val)
1140 status |=
1141 mt2063_setreg(state,
1142 MT2063_REG_DNC_GAIN,
1143 val);
1144
1145 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);
1146 if (state->reg[MT2063_REG_VGA_GAIN] !=
1147 val)
1148 status |=
1149 mt2063_setreg(state,
1150 MT2063_REG_VGA_GAIN,
1151 val);
1152
1153 val = (state->reg[MT2063_REG_RSVD_20] | 0x40);
1154 if (state->reg[MT2063_REG_RSVD_20] !=
1155 val)
1156 status |=
1157 mt2063_setreg(state,
1158 MT2063_REG_RSVD_20,
1159 val);
1160
1161 break;
1162 default:
1163 break;
1164 }
1165
1166 return status;
1167}
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
1183 enum mt2063_delivery_sys Mode)
1184{
1185 int status = 0;
1186 u8 val;
1187 u32 longval;
1188
1189 dprintk(2, "\n");
1190
1191 if (Mode >= MT2063_NUM_RCVR_MODES)
1192 status = -ERANGE;
1193
1194
1195 if (status >= 0) {
1196 val =
1197 (state->
1198 reg[MT2063_REG_PD1_TGT] & ~0x40) | (RFAGCEN[Mode]
1199 ? 0x40 :
1200 0x00);
1201 if (state->reg[MT2063_REG_PD1_TGT] != val)
1202 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1203 }
1204
1205
1206 if (status >= 0) {
1207 u8 val = (state->reg[MT2063_REG_CTRL_2C] & ~0x03) |
1208 (LNARIN[Mode] & 0x03);
1209 if (state->reg[MT2063_REG_CTRL_2C] != val)
1210 status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
1211 }
1212
1213
1214 if (status >= 0) {
1215 val =
1216 (state->
1217 reg[MT2063_REG_FIFF_CTRL2] & ~0xF0) |
1218 (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
1219 if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
1220 status |=
1221 mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
1222
1223 val =
1224 (state->reg[MT2063_REG_FIFF_CTRL] | 0x01);
1225 status |=
1226 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1227 val =
1228 (state->
1229 reg[MT2063_REG_FIFF_CTRL] & ~0x01);
1230 status |=
1231 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1232 }
1233 }
1234
1235
1236 status |= mt2063_get_dnc_output_enable(state, &longval);
1237 status |= mt2063_set_dnc_output_enable(state, longval);
1238
1239
1240 if (status >= 0) {
1241 u8 val = (state->reg[MT2063_REG_LNA_OV] & ~0x1F) |
1242 (ACLNAMAX[Mode] & 0x1F);
1243 if (state->reg[MT2063_REG_LNA_OV] != val)
1244 status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
1245 }
1246
1247
1248 if (status >= 0) {
1249 u8 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x3F) |
1250 (LNATGT[Mode] & 0x3F);
1251 if (state->reg[MT2063_REG_LNA_TGT] != val)
1252 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1253 }
1254
1255
1256 if (status >= 0) {
1257 u8 val = (state->reg[MT2063_REG_RF_OV] & ~0x1F) |
1258 (ACRFMAX[Mode] & 0x1F);
1259 if (state->reg[MT2063_REG_RF_OV] != val)
1260 status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
1261 }
1262
1263
1264 if (status >= 0) {
1265 u8 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x3F) |
1266 (PD1TGT[Mode] & 0x3F);
1267 if (state->reg[MT2063_REG_PD1_TGT] != val)
1268 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1269 }
1270
1271
1272 if (status >= 0) {
1273 u8 val = ACFIFMAX[Mode];
1274 if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
1275 val = 5;
1276 val = (state->reg[MT2063_REG_FIF_OV] & ~0x1F) |
1277 (val & 0x1F);
1278 if (state->reg[MT2063_REG_FIF_OV] != val)
1279 status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
1280 }
1281
1282
1283 if (status >= 0) {
1284 u8 val = (state->reg[MT2063_REG_PD2_TGT] & ~0x3F) |
1285 (PD2TGT[Mode] & 0x3F);
1286 if (state->reg[MT2063_REG_PD2_TGT] != val)
1287 status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
1288 }
1289
1290
1291 if (status >= 0) {
1292 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x80) |
1293 (RFOVDIS[Mode] ? 0x80 : 0x00);
1294 if (state->reg[MT2063_REG_LNA_TGT] != val)
1295 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1296 }
1297
1298
1299 if (status >= 0) {
1300 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x80) |
1301 (FIFOVDIS[Mode] ? 0x80 : 0x00);
1302 if (state->reg[MT2063_REG_PD1_TGT] != val)
1303 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1304 }
1305
1306 if (status >= 0) {
1307 state->rcvr_mode = Mode;
1308 dprintk(1, "mt2063 mode changed to %s\n",
1309 mt2063_mode_name[state->rcvr_mode]);
1310 }
1311
1312 return status;
1313}
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
1325 enum MT2063_Mask_Bits Bits)
1326{
1327 int status = 0;
1328
1329 dprintk(2, "\n");
1330 Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD);
1331 if ((Bits & 0xFF00) != 0) {
1332 state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
1333 status |=
1334 mt2063_write(state,
1335 MT2063_REG_PWR_2,
1336 &state->reg[MT2063_REG_PWR_2], 1);
1337 }
1338 if ((Bits & 0xFF) != 0) {
1339 state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
1340 status |=
1341 mt2063_write(state,
1342 MT2063_REG_PWR_1,
1343 &state->reg[MT2063_REG_PWR_1], 1);
1344 }
1345
1346 return status;
1347}
1348
1349
1350
1351
1352
1353
1354static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
1355{
1356 int status;
1357
1358 dprintk(2, "\n");
1359 if (Shutdown == 1)
1360 state->reg[MT2063_REG_PWR_1] |= 0x04;
1361 else
1362 state->reg[MT2063_REG_PWR_1] &= ~0x04;
1363
1364 status = mt2063_write(state,
1365 MT2063_REG_PWR_1,
1366 &state->reg[MT2063_REG_PWR_1], 1);
1367
1368 if (Shutdown != 1) {
1369 state->reg[MT2063_REG_BYP_CTRL] =
1370 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
1371 status |=
1372 mt2063_write(state,
1373 MT2063_REG_BYP_CTRL,
1374 &state->reg[MT2063_REG_BYP_CTRL],
1375 1);
1376 state->reg[MT2063_REG_BYP_CTRL] =
1377 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
1378 status |=
1379 mt2063_write(state,
1380 MT2063_REG_BYP_CTRL,
1381 &state->reg[MT2063_REG_BYP_CTRL],
1382 1);
1383 }
1384
1385 return status;
1386}
1387
1388static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
1389{
1390 return f_ref * (f_LO / f_ref)
1391 + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
1392}
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
1413{
1414 u32 t1 = (f_ref >> 14) * num;
1415 u32 term1 = t1 / denom;
1416 u32 loss = t1 % denom;
1417 u32 term2 =
1418 (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
1419 return (term1 << 14) + term2;
1420}
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439static u32 MT2063_CalcLO1Mult(u32 *Div,
1440 u32 *FracN,
1441 u32 f_LO,
1442 u32 f_LO_Step, u32 f_Ref)
1443{
1444
1445 *Div = f_LO / f_Ref;
1446
1447
1448 *FracN =
1449 (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1450 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1451
1452 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
1453}
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470static u32 MT2063_CalcLO2Mult(u32 *Div,
1471 u32 *FracN,
1472 u32 f_LO,
1473 u32 f_LO_Step, u32 f_Ref)
1474{
1475
1476 *Div = f_LO / f_Ref;
1477
1478
1479 *FracN =
1480 (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1481 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1482
1483 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
1484 8191);
1485}
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
1497{
1498 u32 RFBand;
1499 u32 idx;
1500
1501
1502
1503
1504 RFBand = 31;
1505 for (idx = 0; idx < 31; ++idx) {
1506 if (state->CTFiltMax[idx] >= f_in) {
1507 RFBand = idx;
1508 break;
1509 }
1510 }
1511 return RFBand;
1512}
1513
1514
1515
1516
1517static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
1518{
1519
1520 int status = 0;
1521 u32 LO1;
1522 u32 Num1;
1523 u32 f_IF1;
1524 u32 LO2;
1525 u32 Num2;
1526 u32 ofLO1, ofLO2;
1527 u8 fiffc = 0x80;
1528 u32 fiffof;
1529 const u8 LO1LK = 0x80;
1530 u8 LO2LK = 0x08;
1531 u8 val;
1532 u32 RFBand;
1533
1534 dprintk(2, "\n");
1535
1536 if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
1537 return -EINVAL;
1538
1539 if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
1540 || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
1541 return -EINVAL;
1542
1543
1544
1545
1546 ofLO1 = state->AS_Data.f_LO1;
1547 ofLO2 = state->AS_Data.f_LO2;
1548
1549
1550
1551
1552 if (state->ctfilt_sw == 1) {
1553 val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
1554 if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
1555 status |=
1556 mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
1557 }
1558 val = state->reg[MT2063_REG_CTUNE_OV];
1559 RFBand = FindClearTuneFilter(state, f_in);
1560 state->reg[MT2063_REG_CTUNE_OV] =
1561 (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
1562 | RFBand);
1563 if (state->reg[MT2063_REG_CTUNE_OV] != val) {
1564 status |=
1565 mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
1566 }
1567 }
1568
1569
1570
1571
1572 if (status >= 0) {
1573 status |=
1574 mt2063_read(state,
1575 MT2063_REG_FIFFC,
1576 &state->reg[MT2063_REG_FIFFC], 1);
1577 fiffc = state->reg[MT2063_REG_FIFFC];
1578 }
1579
1580
1581
1582 state->AS_Data.f_in = f_in;
1583
1584 state->AS_Data.f_if1_Request =
1585 MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
1586 state->AS_Data.f_LO1_Step,
1587 state->AS_Data.f_ref) - f_in;
1588
1589
1590
1591
1592
1593 MT2063_ResetExclZones(&state->AS_Data);
1594
1595 f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
1596
1597 state->AS_Data.f_LO1 =
1598 MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
1599 state->AS_Data.f_ref);
1600
1601 state->AS_Data.f_LO2 =
1602 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1603 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1604
1605
1606
1607
1608
1609 status |= MT2063_AvoidSpurs(&state->AS_Data);
1610
1611
1612
1613
1614
1615 state->AS_Data.f_LO1 =
1616 MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
1617 state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
1618 state->AS_Data.f_LO2 =
1619 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1620 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1621 state->AS_Data.f_LO2 =
1622 MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
1623 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1624
1625
1626
1627
1628 if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
1629 || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
1630 status |= MT2063_UPC_RANGE;
1631 if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
1632 || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
1633 status |= MT2063_DNC_RANGE;
1634
1635 if (state->tuner_id == MT2063_B0)
1636 LO2LK = 0x40;
1637
1638
1639
1640
1641
1642 if ((ofLO1 != state->AS_Data.f_LO1)
1643 || (ofLO2 != state->AS_Data.f_LO2)
1644 || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
1645 (LO1LK | LO2LK))) {
1646
1647
1648
1649
1650
1651
1652
1653 fiffof =
1654 (state->AS_Data.f_LO1 -
1655 f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
1656 4992;
1657 if (fiffof > 0xFF)
1658 fiffof = 0xFF;
1659
1660
1661
1662
1663
1664 if (status >= 0) {
1665 state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF);
1666 state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F);
1667 state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1)
1668 |(Num2 >> 12));
1669 state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4);
1670 state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F));
1671
1672
1673
1674
1675
1676
1677 status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5);
1678 if (state->tuner_id == MT2063_B0) {
1679
1680 status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1);
1681 }
1682
1683 if (state->reg[MT2063_REG_FIFF_OFFSET] !=
1684 (u8) fiffof) {
1685 state->reg[MT2063_REG_FIFF_OFFSET] =
1686 (u8) fiffof;
1687 status |=
1688 mt2063_write(state,
1689 MT2063_REG_FIFF_OFFSET,
1690 &state->
1691 reg[MT2063_REG_FIFF_OFFSET],
1692 1);
1693 }
1694 }
1695
1696
1697
1698
1699
1700 if (status < 0)
1701 return status;
1702
1703 status = mt2063_lockStatus(state);
1704 if (status < 0)
1705 return status;
1706 if (!status)
1707 return -EINVAL;
1708
1709
1710
1711
1712 state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
1713 }
1714
1715 return status;
1716}
1717
1718static const u8 MT2063B0_defaults[] = {
1719
1720 0x19, 0x05,
1721 0x1B, 0x1D,
1722 0x1C, 0x1F,
1723 0x1D, 0x0F,
1724 0x1E, 0x3F,
1725 0x1F, 0x0F,
1726 0x20, 0x3F,
1727 0x22, 0x21,
1728 0x23, 0x3F,
1729 0x24, 0x20,
1730 0x25, 0x3F,
1731 0x27, 0xEE,
1732 0x2C, 0x27,
1733 0x30, 0x03,
1734 0x2C, 0x07,
1735 0x2D, 0x87,
1736 0x2E, 0xAA,
1737 0x28, 0xE1,
1738 0x28, 0xE0,
1739 0x00
1740};
1741
1742
1743static const u8 MT2063B1_defaults[] = {
1744
1745 0x05, 0xF0,
1746 0x11, 0x10,
1747 0x19, 0x05,
1748 0x1A, 0x6C,
1749 0x1B, 0x24,
1750 0x1C, 0x28,
1751 0x1D, 0x8F,
1752 0x1E, 0x14,
1753 0x1F, 0x8F,
1754 0x20, 0x57,
1755 0x22, 0x21,
1756 0x23, 0x3C,
1757 0x24, 0x20,
1758 0x2C, 0x24,
1759 0x2D, 0x87,
1760 0x2F, 0xF3,
1761 0x30, 0x0C,
1762 0x31, 0x1B,
1763 0x2C, 0x04,
1764 0x28, 0xE1,
1765 0x28, 0xE0,
1766 0x00
1767};
1768
1769
1770static const u8 MT2063B3_defaults[] = {
1771
1772 0x05, 0xF0,
1773 0x19, 0x3D,
1774 0x2C, 0x24,
1775 0x2C, 0x04,
1776 0x28, 0xE1,
1777 0x28, 0xE0,
1778 0x00
1779};
1780
1781static int mt2063_init(struct dvb_frontend *fe)
1782{
1783 int status;
1784 struct mt2063_state *state = fe->tuner_priv;
1785 u8 all_resets = 0xF0;
1786 const u8 *def = NULL;
1787 char *step;
1788 u32 FCRUN;
1789 s32 maxReads;
1790 u32 fcu_osc;
1791 u32 i;
1792
1793 dprintk(2, "\n");
1794
1795 state->rcvr_mode = MT2063_CABLE_QAM;
1796
1797
1798 status = mt2063_read(state, MT2063_REG_PART_REV,
1799 &state->reg[MT2063_REG_PART_REV], 1);
1800 if (status < 0) {
1801 printk(KERN_ERR "Can't read mt2063 part ID\n");
1802 return status;
1803 }
1804
1805
1806 switch (state->reg[MT2063_REG_PART_REV]) {
1807 case MT2063_B0:
1808 step = "B0";
1809 break;
1810 case MT2063_B1:
1811 step = "B1";
1812 break;
1813 case MT2063_B2:
1814 step = "B2";
1815 break;
1816 case MT2063_B3:
1817 step = "B3";
1818 break;
1819 default:
1820 printk(KERN_ERR "mt2063: Unknown mt2063 device ID (0x%02x)\n",
1821 state->reg[MT2063_REG_PART_REV]);
1822 return -ENODEV;
1823 }
1824
1825
1826 status = mt2063_read(state, MT2063_REG_RSVD_3B,
1827 &state->reg[MT2063_REG_RSVD_3B], 1);
1828
1829
1830 if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) {
1831 printk(KERN_ERR "mt2063: Unknown part ID (0x%02x%02x)\n",
1832 state->reg[MT2063_REG_PART_REV],
1833 state->reg[MT2063_REG_RSVD_3B]);
1834 return -ENODEV;
1835 }
1836
1837 printk(KERN_INFO "mt2063: detected a mt2063 %s\n", step);
1838
1839
1840 status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
1841 if (status < 0)
1842 return status;
1843
1844
1845
1846 switch (state->reg[MT2063_REG_PART_REV]) {
1847 case MT2063_B3:
1848 def = MT2063B3_defaults;
1849 break;
1850
1851 case MT2063_B1:
1852 def = MT2063B1_defaults;
1853 break;
1854
1855 case MT2063_B0:
1856 def = MT2063B0_defaults;
1857 break;
1858
1859 default:
1860 return -ENODEV;
1861 break;
1862 }
1863
1864 while (status >= 0 && *def) {
1865 u8 reg = *def++;
1866 u8 val = *def++;
1867 status = mt2063_write(state, reg, &val, 1);
1868 }
1869 if (status < 0)
1870 return status;
1871
1872
1873 FCRUN = 1;
1874 maxReads = 10;
1875 while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
1876 msleep(2);
1877 status = mt2063_read(state,
1878 MT2063_REG_XO_STATUS,
1879 &state->
1880 reg[MT2063_REG_XO_STATUS], 1);
1881 FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
1882 }
1883
1884 if (FCRUN != 0 || status < 0)
1885 return -ENODEV;
1886
1887 status = mt2063_read(state,
1888 MT2063_REG_FIFFC,
1889 &state->reg[MT2063_REG_FIFFC], 1);
1890 if (status < 0)
1891 return status;
1892
1893
1894 status = mt2063_read(state,
1895 MT2063_REG_PART_REV,
1896 state->reg, MT2063_REG_END_REGS);
1897 if (status < 0)
1898 return status;
1899
1900
1901 state->tuner_id = state->reg[MT2063_REG_PART_REV];
1902 state->AS_Data.f_ref = MT2063_REF_FREQ;
1903 state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
1904 ((u32) state->reg[MT2063_REG_FIFFC] + 640);
1905 state->AS_Data.f_if1_bw = MT2063_IF1_BW;
1906 state->AS_Data.f_out = 43750000UL;
1907 state->AS_Data.f_out_bw = 6750000UL;
1908 state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
1909 state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
1910 state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
1911 state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
1912 state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
1913 state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
1914 state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
1915 state->AS_Data.f_LO1 = 2181000000UL;
1916 state->AS_Data.f_LO2 = 1486249786UL;
1917 state->f_IF1_actual = state->AS_Data.f_if1_Center;
1918 state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
1919 state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
1920 state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
1921 state->num_regs = MT2063_REG_END_REGS;
1922 state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
1923 state->ctfilt_sw = 0;
1924
1925 state->CTFiltMax[0] = 69230000;
1926 state->CTFiltMax[1] = 105770000;
1927 state->CTFiltMax[2] = 140350000;
1928 state->CTFiltMax[3] = 177110000;
1929 state->CTFiltMax[4] = 212860000;
1930 state->CTFiltMax[5] = 241130000;
1931 state->CTFiltMax[6] = 274370000;
1932 state->CTFiltMax[7] = 309820000;
1933 state->CTFiltMax[8] = 342450000;
1934 state->CTFiltMax[9] = 378870000;
1935 state->CTFiltMax[10] = 416210000;
1936 state->CTFiltMax[11] = 456500000;
1937 state->CTFiltMax[12] = 495790000;
1938 state->CTFiltMax[13] = 534530000;
1939 state->CTFiltMax[14] = 572610000;
1940 state->CTFiltMax[15] = 598970000;
1941 state->CTFiltMax[16] = 635910000;
1942 state->CTFiltMax[17] = 672130000;
1943 state->CTFiltMax[18] = 714840000;
1944 state->CTFiltMax[19] = 739660000;
1945 state->CTFiltMax[20] = 770410000;
1946 state->CTFiltMax[21] = 814660000;
1947 state->CTFiltMax[22] = 846950000;
1948 state->CTFiltMax[23] = 867820000;
1949 state->CTFiltMax[24] = 915980000;
1950 state->CTFiltMax[25] = 947450000;
1951 state->CTFiltMax[26] = 983110000;
1952 state->CTFiltMax[27] = 1021630000;
1953 state->CTFiltMax[28] = 1061870000;
1954 state->CTFiltMax[29] = 1098330000;
1955 state->CTFiltMax[30] = 1138990000;
1956
1957
1958
1959
1960
1961
1962 state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
1963 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1964 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1965 if (status < 0)
1966 return status;
1967
1968
1969 status = mt2063_read(state, MT2063_REG_FIFFC,
1970 &state->reg[MT2063_REG_FIFFC], 1);
1971 if (status < 0)
1972 return status;
1973
1974 fcu_osc = state->reg[MT2063_REG_FIFFC];
1975
1976 state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
1977 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1978 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1979 if (status < 0)
1980 return status;
1981
1982
1983 for (i = 0; i < 31; i++)
1984 state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
1985
1986 status = MT2063_SoftwareShutdown(state, 1);
1987 if (status < 0)
1988 return status;
1989 status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
1990 if (status < 0)
1991 return status;
1992
1993 state->init = true;
1994
1995 return 0;
1996}
1997
1998static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
1999{
2000 struct mt2063_state *state = fe->tuner_priv;
2001 int status;
2002
2003 dprintk(2, "\n");
2004
2005 if (!state->init)
2006 return -ENODEV;
2007
2008 *tuner_status = 0;
2009 status = mt2063_lockStatus(state);
2010 if (status < 0)
2011 return status;
2012 if (status)
2013 *tuner_status = TUNER_STATUS_LOCKED;
2014
2015 dprintk(1, "Tuner status: %d", *tuner_status);
2016
2017 return 0;
2018}
2019
2020static void mt2063_release(struct dvb_frontend *fe)
2021{
2022 struct mt2063_state *state = fe->tuner_priv;
2023
2024 dprintk(2, "\n");
2025
2026 fe->tuner_priv = NULL;
2027 kfree(state);
2028}
2029
2030static int mt2063_set_analog_params(struct dvb_frontend *fe,
2031 struct analog_parameters *params)
2032{
2033 struct mt2063_state *state = fe->tuner_priv;
2034 s32 pict_car;
2035 s32 pict2chanb_vsb;
2036 s32 ch_bw;
2037 s32 if_mid;
2038 s32 rcvr_mode;
2039 int status;
2040
2041 dprintk(2, "\n");
2042
2043 if (!state->init) {
2044 status = mt2063_init(fe);
2045 if (status < 0)
2046 return status;
2047 }
2048
2049 switch (params->mode) {
2050 case V4L2_TUNER_RADIO:
2051 pict_car = 38900000;
2052 ch_bw = 8000000;
2053 pict2chanb_vsb = -(ch_bw / 2);
2054 rcvr_mode = MT2063_OFFAIR_ANALOG;
2055 break;
2056 case V4L2_TUNER_ANALOG_TV:
2057 rcvr_mode = MT2063_CABLE_ANALOG;
2058 if (params->std & ~V4L2_STD_MN) {
2059 pict_car = 38900000;
2060 ch_bw = 6000000;
2061 pict2chanb_vsb = -1250000;
2062 } else if (params->std & V4L2_STD_PAL_G) {
2063 pict_car = 38900000;
2064 ch_bw = 7000000;
2065 pict2chanb_vsb = -1250000;
2066 } else {
2067 pict_car = 38900000;
2068 ch_bw = 8000000;
2069 pict2chanb_vsb = -1250000;
2070 }
2071 break;
2072 default:
2073 return -EINVAL;
2074 }
2075 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2076
2077 state->AS_Data.f_LO2_Step = 125000;
2078 state->AS_Data.f_out = if_mid;
2079 state->AS_Data.f_out_bw = ch_bw + 750000;
2080 status = MT2063_SetReceiverMode(state, rcvr_mode);
2081 if (status < 0)
2082 return status;
2083
2084 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2085 params->frequency, ch_bw, pict2chanb_vsb);
2086
2087 status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2088 if (status < 0)
2089 return status;
2090
2091 state->frequency = params->frequency;
2092 return 0;
2093}
2094
2095
2096
2097
2098
2099
2100
2101
2102#define MAX_SYMBOL_RATE_6MHz 5217391
2103
2104static int mt2063_set_params(struct dvb_frontend *fe)
2105{
2106 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
2107 struct mt2063_state *state = fe->tuner_priv;
2108 int status;
2109 s32 pict_car;
2110 s32 pict2chanb_vsb;
2111 s32 ch_bw;
2112 s32 if_mid;
2113 s32 rcvr_mode;
2114
2115 if (!state->init) {
2116 status = mt2063_init(fe);
2117 if (status < 0)
2118 return status;
2119 }
2120
2121 dprintk(2, "\n");
2122
2123 if (c->bandwidth_hz == 0)
2124 return -EINVAL;
2125 if (c->bandwidth_hz <= 6000000)
2126 ch_bw = 6000000;
2127 else if (c->bandwidth_hz <= 7000000)
2128 ch_bw = 7000000;
2129 else
2130 ch_bw = 8000000;
2131
2132 switch (c->delivery_system) {
2133 case SYS_DVBT:
2134 rcvr_mode = MT2063_OFFAIR_COFDM;
2135 pict_car = 36125000;
2136 pict2chanb_vsb = -(ch_bw / 2);
2137 break;
2138 case SYS_DVBC_ANNEX_A:
2139 case SYS_DVBC_ANNEX_C:
2140 rcvr_mode = MT2063_CABLE_QAM;
2141 pict_car = 36125000;
2142 pict2chanb_vsb = -(ch_bw / 2);
2143 break;
2144 default:
2145 return -EINVAL;
2146 }
2147 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2148
2149 state->AS_Data.f_LO2_Step = 125000;
2150 state->AS_Data.f_out = if_mid;
2151 state->AS_Data.f_out_bw = ch_bw + 750000;
2152 status = MT2063_SetReceiverMode(state, rcvr_mode);
2153 if (status < 0)
2154 return status;
2155
2156 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2157 c->frequency, ch_bw, pict2chanb_vsb);
2158
2159 status = MT2063_Tune(state, (c->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2160
2161 if (status < 0)
2162 return status;
2163
2164 state->frequency = c->frequency;
2165 return 0;
2166}
2167
2168static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
2169{
2170 struct mt2063_state *state = fe->tuner_priv;
2171
2172 dprintk(2, "\n");
2173
2174 if (!state->init)
2175 return -ENODEV;
2176
2177 *freq = state->AS_Data.f_out;
2178
2179 dprintk(1, "IF frequency: %d\n", *freq);
2180
2181 return 0;
2182}
2183
2184static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
2185{
2186 struct mt2063_state *state = fe->tuner_priv;
2187
2188 dprintk(2, "\n");
2189
2190 if (!state->init)
2191 return -ENODEV;
2192
2193 *bw = state->AS_Data.f_out_bw - 750000;
2194
2195 dprintk(1, "bandwidth: %d\n", *bw);
2196
2197 return 0;
2198}
2199
2200static const struct dvb_tuner_ops mt2063_ops = {
2201 .info = {
2202 .name = "MT2063 Silicon Tuner",
2203 .frequency_min = 45000000,
2204 .frequency_max = 865000000,
2205 .frequency_step = 0,
2206 },
2207
2208 .init = mt2063_init,
2209 .sleep = MT2063_Sleep,
2210 .get_status = mt2063_get_status,
2211 .set_analog_params = mt2063_set_analog_params,
2212 .set_params = mt2063_set_params,
2213 .get_if_frequency = mt2063_get_if_frequency,
2214 .get_bandwidth = mt2063_get_bandwidth,
2215 .release = mt2063_release,
2216};
2217
2218struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
2219 struct mt2063_config *config,
2220 struct i2c_adapter *i2c)
2221{
2222 struct mt2063_state *state = NULL;
2223
2224 dprintk(2, "\n");
2225
2226 state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
2227 if (!state)
2228 return NULL;
2229
2230 state->config = config;
2231 state->i2c = i2c;
2232 state->frontend = fe;
2233 state->reference = config->refclock / 1000;
2234 fe->tuner_priv = state;
2235 fe->ops.tuner_ops = mt2063_ops;
2236
2237 printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
2238 return fe;
2239}
2240EXPORT_SYMBOL_GPL(mt2063_attach);
2241
2242#if 0
2243
2244
2245
2246
2247static int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
2248{
2249 struct mt2063_state *state = fe->tuner_priv;
2250 int err = 0;
2251
2252 dprintk(2, "\n");
2253
2254 err = MT2063_SoftwareShutdown(state, 1);
2255 if (err < 0)
2256 printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
2257
2258 return err;
2259}
2260
2261static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
2262{
2263 struct mt2063_state *state = fe->tuner_priv;
2264 int err = 0;
2265
2266 dprintk(2, "\n");
2267
2268 err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2269 if (err < 0)
2270 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
2271
2272 return err;
2273}
2274#endif
2275
2276MODULE_AUTHOR("Mauro Carvalho Chehab");
2277MODULE_DESCRIPTION("MT2063 Silicon tuner");
2278MODULE_LICENSE("GPL");
2279