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 struct tuner_state status;
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
676static u32 MT2063_gcd(u32 u, u32 v)
677{
678 u32 r;
679
680 while (v != 0) {
681 r = u % v;
682 u = v;
683 v = r;
684 }
685
686 return u;
687}
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
709 u32 *fm, u32 * fp)
710{
711
712
713
714 u32 n, n0;
715 const u32 f_LO1 = pAS_Info->f_LO1;
716 const u32 f_LO2 = pAS_Info->f_LO2;
717 const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
718 const u32 c = d - pAS_Info->f_out_bw;
719 const u32 f = pAS_Info->f_zif_bw / 2;
720 const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
721 s32 f_nsLO1, f_nsLO2;
722 s32 f_Spur;
723 u32 ma, mb, mc, md, me, mf;
724 u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
725
726 dprintk(2, "\n");
727
728 *fm = 0;
729
730
731
732
733
734
735 lo_gcd = MT2063_gcd(f_LO1, f_LO2);
736 gd_Scale = max((u32) MT2063_gcd(lo_gcd, d), f_Scale);
737 hgds = gd_Scale / 2;
738 gc_Scale = max((u32) MT2063_gcd(lo_gcd, c), f_Scale);
739 hgcs = gc_Scale / 2;
740 gf_Scale = max((u32) MT2063_gcd(lo_gcd, f), f_Scale);
741 hgfs = gf_Scale / 2;
742
743 n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
744
745
746 for (n = n0; n <= pAS_Info->maxH1; ++n) {
747 md = (n * ((f_LO1 + hgds) / gd_Scale) -
748 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
749
750
751 if (md >= pAS_Info->maxH1)
752 break;
753
754 ma = (n * ((f_LO1 + hgds) / gd_Scale) +
755 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
756
757
758 if (md == ma)
759 continue;
760
761 mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
762 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
763 if (mc != md) {
764 f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
765 f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
766 f_Spur =
767 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
768 n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
769
770 *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
771 *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
772 return 1;
773 }
774
775
776 me = (n * ((f_LO1 + hgfs) / gf_Scale) +
777 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
778 mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
779 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
780 if (me != mf) {
781 f_nsLO1 = n * (f_LO1 / gf_Scale);
782 f_nsLO2 = me * (f_LO2 / gf_Scale);
783 f_Spur =
784 (gf_Scale * (f_nsLO1 - f_nsLO2)) +
785 n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
786
787 *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
788 *fm = (((s32) f - f_Spur) / (me - n)) + 1;
789 return 1;
790 }
791
792 mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
793 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
794 if (ma != mb) {
795 f_nsLO1 = n * (f_LO1 / gc_Scale);
796 f_nsLO2 = ma * (f_LO2 / gc_Scale);
797 f_Spur =
798 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
799 n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
800
801 *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
802 *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
803 return 1;
804 }
805 }
806
807
808 return 0;
809}
810
811
812
813
814
815
816
817static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
818{
819 int status = 0;
820 u32 fm, fp;
821 pAS_Info->bSpurAvoided = 0;
822 pAS_Info->nSpursFound = 0;
823
824 dprintk(2, "\n");
825
826 if (pAS_Info->maxH1 == 0)
827 return 0;
828
829
830
831
832
833
834
835
836
837
838
839
840 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
841 if (pAS_Info->bSpurPresent) {
842 u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in;
843 u32 zfLO1 = pAS_Info->f_LO1;
844 u32 zfLO2 = pAS_Info->f_LO2;
845 u32 delta_IF1;
846 u32 new_IF1;
847
848
849
850
851 do {
852 pAS_Info->nSpursFound++;
853
854
855 MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
856
857
858 new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
859
860 if (new_IF1 > zfIF1) {
861 pAS_Info->f_LO1 += (new_IF1 - zfIF1);
862 pAS_Info->f_LO2 += (new_IF1 - zfIF1);
863 } else {
864 pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
865 pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
866 }
867 zfIF1 = new_IF1;
868
869 if (zfIF1 > pAS_Info->f_if1_Center)
870 delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
871 else
872 delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
873
874 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
875
876
877
878
879 } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
880
881
882
883
884
885
886 if (pAS_Info->bSpurPresent == 1) {
887 status |= MT2063_SPUR_PRESENT_ERR;
888 pAS_Info->f_LO1 = zfLO1;
889 pAS_Info->f_LO2 = zfLO2;
890 } else
891 pAS_Info->bSpurAvoided = 1;
892 }
893
894 status |=
895 ((pAS_Info->
896 nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
897
898 return status;
899}
900
901
902
903
904#define MT2063_REF_FREQ (16000000UL)
905#define MT2063_IF1_BW (22000000UL)
906#define MT2063_TUNE_STEP_SIZE (50000UL)
907#define MT2063_SPUR_STEP_HZ (250000UL)
908#define MT2063_ZIF_BW (2000000UL)
909#define MT2063_MAX_HARMONICS_1 (15UL)
910#define MT2063_MAX_HARMONICS_2 (5UL)
911#define MT2063_MIN_LO_SEP (1000000UL)
912#define MT2063_LO1_FRACN_AVOID (0UL)
913#define MT2063_LO2_FRACN_AVOID (199999UL)
914#define MT2063_MIN_FIN_FREQ (44000000UL)
915#define MT2063_MAX_FIN_FREQ (1100000000UL)
916#define MT2063_MIN_FOUT_FREQ (36000000UL)
917#define MT2063_MAX_FOUT_FREQ (57000000UL)
918#define MT2063_MIN_DNC_FREQ (1293000000UL)
919#define MT2063_MAX_DNC_FREQ (1614000000UL)
920#define MT2063_MIN_UPC_FREQ (1396000000UL)
921#define MT2063_MAX_UPC_FREQ (2750000000UL)
922
923
924
925
926#define MT2063_B0 (0x9B)
927#define MT2063_B1 (0x9C)
928#define MT2063_B2 (0x9D)
929#define MT2063_B3 (0x9E)
930
931
932
933
934
935
936
937
938static int mt2063_lockStatus(struct mt2063_state *state)
939{
940 const u32 nMaxWait = 100;
941 const u32 nPollRate = 2;
942 const u32 nMaxLoops = nMaxWait / nPollRate;
943 const u8 LO1LK = 0x80;
944 u8 LO2LK = 0x08;
945 int status;
946 u32 nDelays = 0;
947
948 dprintk(2, "\n");
949
950
951 if (state->tuner_id == MT2063_B0)
952 LO2LK = 0x40;
953
954 do {
955 status = mt2063_read(state, MT2063_REG_LO_STATUS,
956 &state->reg[MT2063_REG_LO_STATUS], 1);
957
958 if (status < 0)
959 return status;
960
961 if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
962 (LO1LK | LO2LK)) {
963 return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
964 }
965 msleep(nPollRate);
966 } while (++nDelays < nMaxLoops);
967
968
969
970
971 return 0;
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
1009
1010enum mt2063_delivery_sys {
1011 MT2063_CABLE_QAM = 0,
1012 MT2063_CABLE_ANALOG,
1013 MT2063_OFFAIR_COFDM,
1014 MT2063_OFFAIR_COFDM_SAWLESS,
1015 MT2063_OFFAIR_ANALOG,
1016 MT2063_OFFAIR_8VSB,
1017 MT2063_NUM_RCVR_MODES
1018};
1019
1020static const char *mt2063_mode_name[] = {
1021 [MT2063_CABLE_QAM] = "digital cable",
1022 [MT2063_CABLE_ANALOG] = "analog cable",
1023 [MT2063_OFFAIR_COFDM] = "digital offair",
1024 [MT2063_OFFAIR_COFDM_SAWLESS] = "digital offair without SAW",
1025 [MT2063_OFFAIR_ANALOG] = "analog offair",
1026 [MT2063_OFFAIR_8VSB] = "analog offair 8vsb",
1027};
1028
1029static const u8 RFAGCEN[] = { 0, 0, 0, 0, 0, 0 };
1030static const u8 LNARIN[] = { 0, 0, 3, 3, 3, 3 };
1031static const u8 FIFFQEN[] = { 1, 1, 1, 1, 1, 1 };
1032static const u8 FIFFQ[] = { 0, 0, 0, 0, 0, 0 };
1033static const u8 DNC1GC[] = { 0, 0, 0, 0, 0, 0 };
1034static const u8 DNC2GC[] = { 0, 0, 0, 0, 0, 0 };
1035static const u8 ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 };
1036static const u8 LNATGT[] = { 44, 43, 43, 43, 43, 43 };
1037static const u8 RFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1038static const u8 ACRFMAX[] = { 31, 31, 31, 31, 31, 31 };
1039static const u8 PD1TGT[] = { 36, 36, 38, 38, 36, 38 };
1040static const u8 FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1041static const u8 ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 };
1042static const u8 PD2TGT[] = { 40, 33, 38, 42, 30, 38 };
1043
1044
1045
1046
1047static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
1048 enum MT2063_DNC_Output_Enable *pValue)
1049{
1050 dprintk(2, "\n");
1051
1052 if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) {
1053 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)
1054 *pValue = MT2063_DNC_NONE;
1055 else
1056 *pValue = MT2063_DNC_2;
1057 } else {
1058 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03)
1059 *pValue = MT2063_DNC_1;
1060 else
1061 *pValue = MT2063_DNC_BOTH;
1062 }
1063 return 0;
1064}
1065
1066
1067
1068
1069static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
1070 enum MT2063_DNC_Output_Enable nValue)
1071{
1072 int status = 0;
1073 u8 val = 0;
1074
1075 dprintk(2, "\n");
1076
1077
1078 switch (nValue) {
1079 case MT2063_DNC_NONE:
1080 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;
1081 if (state->reg[MT2063_REG_DNC_GAIN] !=
1082 val)
1083 status |=
1084 mt2063_setreg(state,
1085 MT2063_REG_DNC_GAIN,
1086 val);
1087
1088 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;
1089 if (state->reg[MT2063_REG_VGA_GAIN] !=
1090 val)
1091 status |=
1092 mt2063_setreg(state,
1093 MT2063_REG_VGA_GAIN,
1094 val);
1095
1096 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40);
1097 if (state->reg[MT2063_REG_RSVD_20] !=
1098 val)
1099 status |=
1100 mt2063_setreg(state,
1101 MT2063_REG_RSVD_20,
1102 val);
1103
1104 break;
1105 case MT2063_DNC_1:
1106 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);
1107 if (state->reg[MT2063_REG_DNC_GAIN] !=
1108 val)
1109 status |=
1110 mt2063_setreg(state,
1111 MT2063_REG_DNC_GAIN,
1112 val);
1113
1114 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03;
1115 if (state->reg[MT2063_REG_VGA_GAIN] !=
1116 val)
1117 status |=
1118 mt2063_setreg(state,
1119 MT2063_REG_VGA_GAIN,
1120 val);
1121
1122 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40);
1123 if (state->reg[MT2063_REG_RSVD_20] !=
1124 val)
1125 status |=
1126 mt2063_setreg(state,
1127 MT2063_REG_RSVD_20,
1128 val);
1129
1130 break;
1131 case MT2063_DNC_2:
1132 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03;
1133 if (state->reg[MT2063_REG_DNC_GAIN] !=
1134 val)
1135 status |=
1136 mt2063_setreg(state,
1137 MT2063_REG_DNC_GAIN,
1138 val);
1139
1140 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);
1141 if (state->reg[MT2063_REG_VGA_GAIN] !=
1142 val)
1143 status |=
1144 mt2063_setreg(state,
1145 MT2063_REG_VGA_GAIN,
1146 val);
1147
1148 val = (state->reg[MT2063_REG_RSVD_20] | 0x40);
1149 if (state->reg[MT2063_REG_RSVD_20] !=
1150 val)
1151 status |=
1152 mt2063_setreg(state,
1153 MT2063_REG_RSVD_20,
1154 val);
1155
1156 break;
1157 case MT2063_DNC_BOTH:
1158 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03);
1159 if (state->reg[MT2063_REG_DNC_GAIN] !=
1160 val)
1161 status |=
1162 mt2063_setreg(state,
1163 MT2063_REG_DNC_GAIN,
1164 val);
1165
1166 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03);
1167 if (state->reg[MT2063_REG_VGA_GAIN] !=
1168 val)
1169 status |=
1170 mt2063_setreg(state,
1171 MT2063_REG_VGA_GAIN,
1172 val);
1173
1174 val = (state->reg[MT2063_REG_RSVD_20] | 0x40);
1175 if (state->reg[MT2063_REG_RSVD_20] !=
1176 val)
1177 status |=
1178 mt2063_setreg(state,
1179 MT2063_REG_RSVD_20,
1180 val);
1181
1182 break;
1183 default:
1184 break;
1185 }
1186
1187 return status;
1188}
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
1204 enum mt2063_delivery_sys Mode)
1205{
1206 int status = 0;
1207 u8 val;
1208 u32 longval;
1209
1210 dprintk(2, "\n");
1211
1212 if (Mode >= MT2063_NUM_RCVR_MODES)
1213 status = -ERANGE;
1214
1215
1216 if (status >= 0) {
1217 val =
1218 (state->
1219 reg[MT2063_REG_PD1_TGT] & ~0x40) | (RFAGCEN[Mode]
1220 ? 0x40 :
1221 0x00);
1222 if (state->reg[MT2063_REG_PD1_TGT] != val)
1223 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1224 }
1225
1226
1227 if (status >= 0) {
1228 u8 val = (state->reg[MT2063_REG_CTRL_2C] & ~0x03) |
1229 (LNARIN[Mode] & 0x03);
1230 if (state->reg[MT2063_REG_CTRL_2C] != val)
1231 status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
1232 }
1233
1234
1235 if (status >= 0) {
1236 val =
1237 (state->
1238 reg[MT2063_REG_FIFF_CTRL2] & ~0xF0) |
1239 (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
1240 if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
1241 status |=
1242 mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
1243
1244 val =
1245 (state->reg[MT2063_REG_FIFF_CTRL] | 0x01);
1246 status |=
1247 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1248 val =
1249 (state->
1250 reg[MT2063_REG_FIFF_CTRL] & ~0x01);
1251 status |=
1252 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1253 }
1254 }
1255
1256
1257 status |= mt2063_get_dnc_output_enable(state, &longval);
1258 status |= mt2063_set_dnc_output_enable(state, longval);
1259
1260
1261 if (status >= 0) {
1262 u8 val = (state->reg[MT2063_REG_LNA_OV] & ~0x1F) |
1263 (ACLNAMAX[Mode] & 0x1F);
1264 if (state->reg[MT2063_REG_LNA_OV] != val)
1265 status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
1266 }
1267
1268
1269 if (status >= 0) {
1270 u8 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x3F) |
1271 (LNATGT[Mode] & 0x3F);
1272 if (state->reg[MT2063_REG_LNA_TGT] != val)
1273 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1274 }
1275
1276
1277 if (status >= 0) {
1278 u8 val = (state->reg[MT2063_REG_RF_OV] & ~0x1F) |
1279 (ACRFMAX[Mode] & 0x1F);
1280 if (state->reg[MT2063_REG_RF_OV] != val)
1281 status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
1282 }
1283
1284
1285 if (status >= 0) {
1286 u8 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x3F) |
1287 (PD1TGT[Mode] & 0x3F);
1288 if (state->reg[MT2063_REG_PD1_TGT] != val)
1289 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1290 }
1291
1292
1293 if (status >= 0) {
1294 u8 val = ACFIFMAX[Mode];
1295 if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
1296 val = 5;
1297 val = (state->reg[MT2063_REG_FIF_OV] & ~0x1F) |
1298 (val & 0x1F);
1299 if (state->reg[MT2063_REG_FIF_OV] != val)
1300 status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
1301 }
1302
1303
1304 if (status >= 0) {
1305 u8 val = (state->reg[MT2063_REG_PD2_TGT] & ~0x3F) |
1306 (PD2TGT[Mode] & 0x3F);
1307 if (state->reg[MT2063_REG_PD2_TGT] != val)
1308 status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
1309 }
1310
1311
1312 if (status >= 0) {
1313 val = (state->reg[MT2063_REG_LNA_TGT] & ~0x80) |
1314 (RFOVDIS[Mode] ? 0x80 : 0x00);
1315 if (state->reg[MT2063_REG_LNA_TGT] != val)
1316 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1317 }
1318
1319
1320 if (status >= 0) {
1321 val = (state->reg[MT2063_REG_PD1_TGT] & ~0x80) |
1322 (FIFOVDIS[Mode] ? 0x80 : 0x00);
1323 if (state->reg[MT2063_REG_PD1_TGT] != val)
1324 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1325 }
1326
1327 if (status >= 0) {
1328 state->rcvr_mode = Mode;
1329 dprintk(1, "mt2063 mode changed to %s\n",
1330 mt2063_mode_name[state->rcvr_mode]);
1331 }
1332
1333 return status;
1334}
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
1346 enum MT2063_Mask_Bits Bits)
1347{
1348 int status = 0;
1349
1350 dprintk(2, "\n");
1351 Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD);
1352 if ((Bits & 0xFF00) != 0) {
1353 state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
1354 status |=
1355 mt2063_write(state,
1356 MT2063_REG_PWR_2,
1357 &state->reg[MT2063_REG_PWR_2], 1);
1358 }
1359 if ((Bits & 0xFF) != 0) {
1360 state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
1361 status |=
1362 mt2063_write(state,
1363 MT2063_REG_PWR_1,
1364 &state->reg[MT2063_REG_PWR_1], 1);
1365 }
1366
1367 return status;
1368}
1369
1370
1371
1372
1373
1374
1375static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
1376{
1377 int status;
1378
1379 dprintk(2, "\n");
1380 if (Shutdown == 1)
1381 state->reg[MT2063_REG_PWR_1] |= 0x04;
1382 else
1383 state->reg[MT2063_REG_PWR_1] &= ~0x04;
1384
1385 status = mt2063_write(state,
1386 MT2063_REG_PWR_1,
1387 &state->reg[MT2063_REG_PWR_1], 1);
1388
1389 if (Shutdown != 1) {
1390 state->reg[MT2063_REG_BYP_CTRL] =
1391 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
1392 status |=
1393 mt2063_write(state,
1394 MT2063_REG_BYP_CTRL,
1395 &state->reg[MT2063_REG_BYP_CTRL],
1396 1);
1397 state->reg[MT2063_REG_BYP_CTRL] =
1398 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
1399 status |=
1400 mt2063_write(state,
1401 MT2063_REG_BYP_CTRL,
1402 &state->reg[MT2063_REG_BYP_CTRL],
1403 1);
1404 }
1405
1406 return status;
1407}
1408
1409static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
1410{
1411 return f_ref * (f_LO / f_ref)
1412 + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
1413}
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
1434{
1435 u32 t1 = (f_ref >> 14) * num;
1436 u32 term1 = t1 / denom;
1437 u32 loss = t1 % denom;
1438 u32 term2 =
1439 (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
1440 return (term1 << 14) + term2;
1441}
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460static u32 MT2063_CalcLO1Mult(u32 *Div,
1461 u32 *FracN,
1462 u32 f_LO,
1463 u32 f_LO_Step, u32 f_Ref)
1464{
1465
1466 *Div = f_LO / f_Ref;
1467
1468
1469 *FracN =
1470 (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1471 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1472
1473 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
1474}
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493static u32 MT2063_CalcLO2Mult(u32 *Div,
1494 u32 *FracN,
1495 u32 f_LO,
1496 u32 f_LO_Step, u32 f_Ref)
1497{
1498
1499 *Div = f_LO / f_Ref;
1500
1501
1502 *FracN =
1503 (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1504 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1505
1506 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
1507 8191);
1508}
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
1520{
1521 u32 RFBand;
1522 u32 idx;
1523
1524
1525
1526
1527 RFBand = 31;
1528 for (idx = 0; idx < 31; ++idx) {
1529 if (state->CTFiltMax[idx] >= f_in) {
1530 RFBand = idx;
1531 break;
1532 }
1533 }
1534 return RFBand;
1535}
1536
1537
1538
1539
1540static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
1541{
1542
1543 int status = 0;
1544 u32 LO1;
1545 u32 Num1;
1546 u32 f_IF1;
1547 u32 LO2;
1548 u32 Num2;
1549 u32 ofLO1, ofLO2;
1550 u8 fiffc = 0x80;
1551 u32 fiffof;
1552 const u8 LO1LK = 0x80;
1553 u8 LO2LK = 0x08;
1554 u8 val;
1555 u32 RFBand;
1556
1557 dprintk(2, "\n");
1558
1559 if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
1560 return -EINVAL;
1561
1562 if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
1563 || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
1564 return -EINVAL;
1565
1566
1567
1568
1569 ofLO1 = state->AS_Data.f_LO1;
1570 ofLO2 = state->AS_Data.f_LO2;
1571
1572
1573
1574
1575 if (state->ctfilt_sw == 1) {
1576 val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
1577 if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
1578 status |=
1579 mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
1580 }
1581 val = state->reg[MT2063_REG_CTUNE_OV];
1582 RFBand = FindClearTuneFilter(state, f_in);
1583 state->reg[MT2063_REG_CTUNE_OV] =
1584 (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
1585 | RFBand);
1586 if (state->reg[MT2063_REG_CTUNE_OV] != val) {
1587 status |=
1588 mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
1589 }
1590 }
1591
1592
1593
1594
1595 if (status >= 0) {
1596 status |=
1597 mt2063_read(state,
1598 MT2063_REG_FIFFC,
1599 &state->reg[MT2063_REG_FIFFC], 1);
1600 fiffc = state->reg[MT2063_REG_FIFFC];
1601 }
1602
1603
1604
1605 state->AS_Data.f_in = f_in;
1606
1607 state->AS_Data.f_if1_Request =
1608 MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
1609 state->AS_Data.f_LO1_Step,
1610 state->AS_Data.f_ref) - f_in;
1611
1612
1613
1614
1615
1616 MT2063_ResetExclZones(&state->AS_Data);
1617
1618 f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
1619
1620 state->AS_Data.f_LO1 =
1621 MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
1622 state->AS_Data.f_ref);
1623
1624 state->AS_Data.f_LO2 =
1625 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1626 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1627
1628
1629
1630
1631
1632 status |= MT2063_AvoidSpurs(&state->AS_Data);
1633
1634
1635
1636
1637
1638 state->AS_Data.f_LO1 =
1639 MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
1640 state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
1641 state->AS_Data.f_LO2 =
1642 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1643 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1644 state->AS_Data.f_LO2 =
1645 MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
1646 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1647
1648
1649
1650
1651 if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
1652 || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
1653 status |= MT2063_UPC_RANGE;
1654 if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
1655 || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
1656 status |= MT2063_DNC_RANGE;
1657
1658 if (state->tuner_id == MT2063_B0)
1659 LO2LK = 0x40;
1660
1661
1662
1663
1664
1665 if ((ofLO1 != state->AS_Data.f_LO1)
1666 || (ofLO2 != state->AS_Data.f_LO2)
1667 || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
1668 (LO1LK | LO2LK))) {
1669
1670
1671
1672
1673
1674
1675
1676 fiffof =
1677 (state->AS_Data.f_LO1 -
1678 f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
1679 4992;
1680 if (fiffof > 0xFF)
1681 fiffof = 0xFF;
1682
1683
1684
1685
1686
1687 if (status >= 0) {
1688 state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF);
1689 state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F);
1690 state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1)
1691 |(Num2 >> 12));
1692 state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4);
1693 state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F));
1694
1695
1696
1697
1698
1699
1700 status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5);
1701 if (state->tuner_id == MT2063_B0) {
1702
1703 status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1);
1704 }
1705
1706 if (state->reg[MT2063_REG_FIFF_OFFSET] !=
1707 (u8) fiffof) {
1708 state->reg[MT2063_REG_FIFF_OFFSET] =
1709 (u8) fiffof;
1710 status |=
1711 mt2063_write(state,
1712 MT2063_REG_FIFF_OFFSET,
1713 &state->
1714 reg[MT2063_REG_FIFF_OFFSET],
1715 1);
1716 }
1717 }
1718
1719
1720
1721
1722
1723 if (status < 0)
1724 return status;
1725
1726 status = mt2063_lockStatus(state);
1727 if (status < 0)
1728 return status;
1729 if (!status)
1730 return -EINVAL;
1731
1732
1733
1734
1735 state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
1736 }
1737
1738 return status;
1739}
1740
1741static const u8 MT2063B0_defaults[] = {
1742
1743 0x19, 0x05,
1744 0x1B, 0x1D,
1745 0x1C, 0x1F,
1746 0x1D, 0x0F,
1747 0x1E, 0x3F,
1748 0x1F, 0x0F,
1749 0x20, 0x3F,
1750 0x22, 0x21,
1751 0x23, 0x3F,
1752 0x24, 0x20,
1753 0x25, 0x3F,
1754 0x27, 0xEE,
1755 0x2C, 0x27,
1756 0x30, 0x03,
1757 0x2C, 0x07,
1758 0x2D, 0x87,
1759 0x2E, 0xAA,
1760 0x28, 0xE1,
1761 0x28, 0xE0,
1762 0x00
1763};
1764
1765
1766static const u8 MT2063B1_defaults[] = {
1767
1768 0x05, 0xF0,
1769 0x11, 0x10,
1770 0x19, 0x05,
1771 0x1A, 0x6C,
1772 0x1B, 0x24,
1773 0x1C, 0x28,
1774 0x1D, 0x8F,
1775 0x1E, 0x14,
1776 0x1F, 0x8F,
1777 0x20, 0x57,
1778 0x22, 0x21,
1779 0x23, 0x3C,
1780 0x24, 0x20,
1781 0x2C, 0x24,
1782 0x2D, 0x87,
1783 0x2F, 0xF3,
1784 0x30, 0x0C,
1785 0x31, 0x1B,
1786 0x2C, 0x04,
1787 0x28, 0xE1,
1788 0x28, 0xE0,
1789 0x00
1790};
1791
1792
1793static const u8 MT2063B3_defaults[] = {
1794
1795 0x05, 0xF0,
1796 0x19, 0x3D,
1797 0x2C, 0x24,
1798 0x2C, 0x04,
1799 0x28, 0xE1,
1800 0x28, 0xE0,
1801 0x00
1802};
1803
1804static int mt2063_init(struct dvb_frontend *fe)
1805{
1806 int status;
1807 struct mt2063_state *state = fe->tuner_priv;
1808 u8 all_resets = 0xF0;
1809 const u8 *def = NULL;
1810 char *step;
1811 u32 FCRUN;
1812 s32 maxReads;
1813 u32 fcu_osc;
1814 u32 i;
1815
1816 dprintk(2, "\n");
1817
1818 state->rcvr_mode = MT2063_CABLE_QAM;
1819
1820
1821 status = mt2063_read(state, MT2063_REG_PART_REV,
1822 &state->reg[MT2063_REG_PART_REV], 1);
1823 if (status < 0) {
1824 printk(KERN_ERR "Can't read mt2063 part ID\n");
1825 return status;
1826 }
1827
1828
1829 switch (state->reg[MT2063_REG_PART_REV]) {
1830 case MT2063_B0:
1831 step = "B0";
1832 break;
1833 case MT2063_B1:
1834 step = "B1";
1835 break;
1836 case MT2063_B2:
1837 step = "B2";
1838 break;
1839 case MT2063_B3:
1840 step = "B3";
1841 break;
1842 default:
1843 printk(KERN_ERR "mt2063: Unknown mt2063 device ID (0x%02x)\n",
1844 state->reg[MT2063_REG_PART_REV]);
1845 return -ENODEV;
1846 }
1847
1848
1849 status = mt2063_read(state, MT2063_REG_RSVD_3B,
1850 &state->reg[MT2063_REG_RSVD_3B], 1);
1851
1852
1853 if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) {
1854 printk(KERN_ERR "mt2063: Unknown part ID (0x%02x%02x)\n",
1855 state->reg[MT2063_REG_PART_REV],
1856 state->reg[MT2063_REG_RSVD_3B]);
1857 return -ENODEV;
1858 }
1859
1860 printk(KERN_INFO "mt2063: detected a mt2063 %s\n", step);
1861
1862
1863 status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
1864 if (status < 0)
1865 return status;
1866
1867
1868
1869 switch (state->reg[MT2063_REG_PART_REV]) {
1870 case MT2063_B3:
1871 def = MT2063B3_defaults;
1872 break;
1873
1874 case MT2063_B1:
1875 def = MT2063B1_defaults;
1876 break;
1877
1878 case MT2063_B0:
1879 def = MT2063B0_defaults;
1880 break;
1881
1882 default:
1883 return -ENODEV;
1884 break;
1885 }
1886
1887 while (status >= 0 && *def) {
1888 u8 reg = *def++;
1889 u8 val = *def++;
1890 status = mt2063_write(state, reg, &val, 1);
1891 }
1892 if (status < 0)
1893 return status;
1894
1895
1896 FCRUN = 1;
1897 maxReads = 10;
1898 while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
1899 msleep(2);
1900 status = mt2063_read(state,
1901 MT2063_REG_XO_STATUS,
1902 &state->
1903 reg[MT2063_REG_XO_STATUS], 1);
1904 FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
1905 }
1906
1907 if (FCRUN != 0 || status < 0)
1908 return -ENODEV;
1909
1910 status = mt2063_read(state,
1911 MT2063_REG_FIFFC,
1912 &state->reg[MT2063_REG_FIFFC], 1);
1913 if (status < 0)
1914 return status;
1915
1916
1917 status = mt2063_read(state,
1918 MT2063_REG_PART_REV,
1919 state->reg, MT2063_REG_END_REGS);
1920 if (status < 0)
1921 return status;
1922
1923
1924 state->tuner_id = state->reg[MT2063_REG_PART_REV];
1925 state->AS_Data.f_ref = MT2063_REF_FREQ;
1926 state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
1927 ((u32) state->reg[MT2063_REG_FIFFC] + 640);
1928 state->AS_Data.f_if1_bw = MT2063_IF1_BW;
1929 state->AS_Data.f_out = 43750000UL;
1930 state->AS_Data.f_out_bw = 6750000UL;
1931 state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
1932 state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
1933 state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
1934 state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
1935 state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
1936 state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
1937 state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
1938 state->AS_Data.f_LO1 = 2181000000UL;
1939 state->AS_Data.f_LO2 = 1486249786UL;
1940 state->f_IF1_actual = state->AS_Data.f_if1_Center;
1941 state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
1942 state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
1943 state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
1944 state->num_regs = MT2063_REG_END_REGS;
1945 state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
1946 state->ctfilt_sw = 0;
1947
1948 state->CTFiltMax[0] = 69230000;
1949 state->CTFiltMax[1] = 105770000;
1950 state->CTFiltMax[2] = 140350000;
1951 state->CTFiltMax[3] = 177110000;
1952 state->CTFiltMax[4] = 212860000;
1953 state->CTFiltMax[5] = 241130000;
1954 state->CTFiltMax[6] = 274370000;
1955 state->CTFiltMax[7] = 309820000;
1956 state->CTFiltMax[8] = 342450000;
1957 state->CTFiltMax[9] = 378870000;
1958 state->CTFiltMax[10] = 416210000;
1959 state->CTFiltMax[11] = 456500000;
1960 state->CTFiltMax[12] = 495790000;
1961 state->CTFiltMax[13] = 534530000;
1962 state->CTFiltMax[14] = 572610000;
1963 state->CTFiltMax[15] = 598970000;
1964 state->CTFiltMax[16] = 635910000;
1965 state->CTFiltMax[17] = 672130000;
1966 state->CTFiltMax[18] = 714840000;
1967 state->CTFiltMax[19] = 739660000;
1968 state->CTFiltMax[20] = 770410000;
1969 state->CTFiltMax[21] = 814660000;
1970 state->CTFiltMax[22] = 846950000;
1971 state->CTFiltMax[23] = 867820000;
1972 state->CTFiltMax[24] = 915980000;
1973 state->CTFiltMax[25] = 947450000;
1974 state->CTFiltMax[26] = 983110000;
1975 state->CTFiltMax[27] = 1021630000;
1976 state->CTFiltMax[28] = 1061870000;
1977 state->CTFiltMax[29] = 1098330000;
1978 state->CTFiltMax[30] = 1138990000;
1979
1980
1981
1982
1983
1984
1985 state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
1986 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1987 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1988 if (status < 0)
1989 return status;
1990
1991
1992 status = mt2063_read(state, MT2063_REG_FIFFC,
1993 &state->reg[MT2063_REG_FIFFC], 1);
1994 if (status < 0)
1995 return status;
1996
1997 fcu_osc = state->reg[MT2063_REG_FIFFC];
1998
1999 state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
2000 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
2001 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
2002 if (status < 0)
2003 return status;
2004
2005
2006 for (i = 0; i < 31; i++)
2007 state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
2008
2009 status = MT2063_SoftwareShutdown(state, 1);
2010 if (status < 0)
2011 return status;
2012 status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2013 if (status < 0)
2014 return status;
2015
2016 state->init = true;
2017
2018 return 0;
2019}
2020
2021static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
2022{
2023 struct mt2063_state *state = fe->tuner_priv;
2024 int status;
2025
2026 dprintk(2, "\n");
2027
2028 if (!state->init)
2029 return -ENODEV;
2030
2031 *tuner_status = 0;
2032 status = mt2063_lockStatus(state);
2033 if (status < 0)
2034 return status;
2035 if (status)
2036 *tuner_status = TUNER_STATUS_LOCKED;
2037
2038 dprintk(1, "Tuner status: %d", *tuner_status);
2039
2040 return 0;
2041}
2042
2043static int mt2063_release(struct dvb_frontend *fe)
2044{
2045 struct mt2063_state *state = fe->tuner_priv;
2046
2047 dprintk(2, "\n");
2048
2049 fe->tuner_priv = NULL;
2050 kfree(state);
2051
2052 return 0;
2053}
2054
2055static int mt2063_set_analog_params(struct dvb_frontend *fe,
2056 struct analog_parameters *params)
2057{
2058 struct mt2063_state *state = fe->tuner_priv;
2059 s32 pict_car;
2060 s32 pict2chanb_vsb;
2061 s32 ch_bw;
2062 s32 if_mid;
2063 s32 rcvr_mode;
2064 int status;
2065
2066 dprintk(2, "\n");
2067
2068 if (!state->init) {
2069 status = mt2063_init(fe);
2070 if (status < 0)
2071 return status;
2072 }
2073
2074 switch (params->mode) {
2075 case V4L2_TUNER_RADIO:
2076 pict_car = 38900000;
2077 ch_bw = 8000000;
2078 pict2chanb_vsb = -(ch_bw / 2);
2079 rcvr_mode = MT2063_OFFAIR_ANALOG;
2080 break;
2081 case V4L2_TUNER_ANALOG_TV:
2082 rcvr_mode = MT2063_CABLE_ANALOG;
2083 if (params->std & ~V4L2_STD_MN) {
2084 pict_car = 38900000;
2085 ch_bw = 6000000;
2086 pict2chanb_vsb = -1250000;
2087 } else if (params->std & V4L2_STD_PAL_G) {
2088 pict_car = 38900000;
2089 ch_bw = 7000000;
2090 pict2chanb_vsb = -1250000;
2091 } else {
2092 pict_car = 38900000;
2093 ch_bw = 8000000;
2094 pict2chanb_vsb = -1250000;
2095 }
2096 break;
2097 default:
2098 return -EINVAL;
2099 }
2100 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2101
2102 state->AS_Data.f_LO2_Step = 125000;
2103 state->AS_Data.f_out = if_mid;
2104 state->AS_Data.f_out_bw = ch_bw + 750000;
2105 status = MT2063_SetReceiverMode(state, rcvr_mode);
2106 if (status < 0)
2107 return status;
2108
2109 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2110 params->frequency, ch_bw, pict2chanb_vsb);
2111
2112 status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2113 if (status < 0)
2114 return status;
2115
2116 state->frequency = params->frequency;
2117 return 0;
2118}
2119
2120
2121
2122
2123
2124
2125
2126
2127#define MAX_SYMBOL_RATE_6MHz 5217391
2128
2129static int mt2063_set_params(struct dvb_frontend *fe)
2130{
2131 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
2132 struct mt2063_state *state = fe->tuner_priv;
2133 int status;
2134 s32 pict_car;
2135 s32 pict2chanb_vsb;
2136 s32 ch_bw;
2137 s32 if_mid;
2138 s32 rcvr_mode;
2139
2140 if (!state->init) {
2141 status = mt2063_init(fe);
2142 if (status < 0)
2143 return status;
2144 }
2145
2146 dprintk(2, "\n");
2147
2148 if (c->bandwidth_hz == 0)
2149 return -EINVAL;
2150 if (c->bandwidth_hz <= 6000000)
2151 ch_bw = 6000000;
2152 else if (c->bandwidth_hz <= 7000000)
2153 ch_bw = 7000000;
2154 else
2155 ch_bw = 8000000;
2156
2157 switch (c->delivery_system) {
2158 case SYS_DVBT:
2159 rcvr_mode = MT2063_OFFAIR_COFDM;
2160 pict_car = 36125000;
2161 pict2chanb_vsb = -(ch_bw / 2);
2162 break;
2163 case SYS_DVBC_ANNEX_A:
2164 case SYS_DVBC_ANNEX_C:
2165 rcvr_mode = MT2063_CABLE_QAM;
2166 pict_car = 36125000;
2167 pict2chanb_vsb = -(ch_bw / 2);
2168 break;
2169 default:
2170 return -EINVAL;
2171 }
2172 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2173
2174 state->AS_Data.f_LO2_Step = 125000;
2175 state->AS_Data.f_out = if_mid;
2176 state->AS_Data.f_out_bw = ch_bw + 750000;
2177 status = MT2063_SetReceiverMode(state, rcvr_mode);
2178 if (status < 0)
2179 return status;
2180
2181 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2182 c->frequency, ch_bw, pict2chanb_vsb);
2183
2184 status = MT2063_Tune(state, (c->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2185
2186 if (status < 0)
2187 return status;
2188
2189 state->frequency = c->frequency;
2190 return 0;
2191}
2192
2193static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
2194{
2195 struct mt2063_state *state = fe->tuner_priv;
2196
2197 dprintk(2, "\n");
2198
2199 if (!state->init)
2200 return -ENODEV;
2201
2202 *freq = state->AS_Data.f_out;
2203
2204 dprintk(1, "IF frequency: %d\n", *freq);
2205
2206 return 0;
2207}
2208
2209static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
2210{
2211 struct mt2063_state *state = fe->tuner_priv;
2212
2213 dprintk(2, "\n");
2214
2215 if (!state->init)
2216 return -ENODEV;
2217
2218 *bw = state->AS_Data.f_out_bw - 750000;
2219
2220 dprintk(1, "bandwidth: %d\n", *bw);
2221
2222 return 0;
2223}
2224
2225static struct dvb_tuner_ops mt2063_ops = {
2226 .info = {
2227 .name = "MT2063 Silicon Tuner",
2228 .frequency_min = 45000000,
2229 .frequency_max = 865000000,
2230 .frequency_step = 0,
2231 },
2232
2233 .init = mt2063_init,
2234 .sleep = MT2063_Sleep,
2235 .get_status = mt2063_get_status,
2236 .set_analog_params = mt2063_set_analog_params,
2237 .set_params = mt2063_set_params,
2238 .get_if_frequency = mt2063_get_if_frequency,
2239 .get_bandwidth = mt2063_get_bandwidth,
2240 .release = mt2063_release,
2241};
2242
2243struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
2244 struct mt2063_config *config,
2245 struct i2c_adapter *i2c)
2246{
2247 struct mt2063_state *state = NULL;
2248
2249 dprintk(2, "\n");
2250
2251 state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
2252 if (!state)
2253 return NULL;
2254
2255 state->config = config;
2256 state->i2c = i2c;
2257 state->frontend = fe;
2258 state->reference = config->refclock / 1000;
2259 fe->tuner_priv = state;
2260 fe->ops.tuner_ops = mt2063_ops;
2261
2262 printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
2263 return fe;
2264}
2265EXPORT_SYMBOL_GPL(mt2063_attach);
2266
2267#if 0
2268
2269
2270
2271
2272static int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
2273{
2274 struct mt2063_state *state = fe->tuner_priv;
2275 int err = 0;
2276
2277 dprintk(2, "\n");
2278
2279 err = MT2063_SoftwareShutdown(state, 1);
2280 if (err < 0)
2281 printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
2282
2283 return err;
2284}
2285
2286static int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
2287{
2288 struct mt2063_state *state = fe->tuner_priv;
2289 int err = 0;
2290
2291 dprintk(2, "\n");
2292
2293 err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2294 if (err < 0)
2295 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
2296
2297 return err;
2298}
2299#endif
2300
2301MODULE_AUTHOR("Mauro Carvalho Chehab");
2302MODULE_DESCRIPTION("MT2063 Silicon tuner");
2303MODULE_LICENSE("GPL");
2304