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