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