1 #ifdef HAVE_XORG_CONFIG_H
2 #include <xorg-config.h>
18 const FI1236_parameters tuner_parms
[NUM_TUNERS
] = {
20 {733, 884, 12820, 2516, 7220, 0xA2, 0x94, 0x34, 0x8e},
21 /* !!!based on documentation - it should be:
22 {733, 16*55.25, 16*801.25, 16*160, 16*454, 0xA0, 0x90, 0x30, 0x8e}, */
25 {623, 16 * 48.75, 16 * 855.25, 16 * 170, 16 * 450, 0xA0, 0x90, 0x30, 0x8e},
27 {623, 16 * 45.75, 16 * 855.25, 16 * 169, 16 * 454, 0xA0, 0x90, 0x30, 0x8e},
29 {733, 768, 13760, 0, 0, 0, 0, 0, 0},
31 {623, 16 * 45.75, 16 * 855.25, 16 * 170, 16 * 450, 0xA0, 0x90, 0x30, 0x8e},
33 {623, 16 * 49.75, 16 * 863.25, 16 * 170, 16 * 450, 0xA0, 0x90, 0x30, 0x8e},
35 /*{ 733, 884, 12820, 2516, 7220, 0x1, 0x2, 0x4, 0x8e }, */
36 {732, 16 * 55.25, 16 * 801.25, 16 * 160, 16 * 442, 0x1, 0x2, 0x4, 0x8e},
38 {623, 16 * 48.25, 16 * 863.25, 16 * 158.00, 16 * 442.00, 0x1, 0x2, 0x4, 0x8e}
42 Detect_FI1236(I2CBusPtr b
, I2CSlaveAddr addr
)
47 f
= calloc(1, sizeof(FI1236Rec
));
50 f
->d
.DevName
= strdup("FI12xx Tuner");
51 f
->d
.SlaveAddr
= addr
;
54 f
->d
.StartTimeout
= b
->StartTimeout
;
55 f
->d
.BitTimeout
= b
->BitTimeout
;
56 f
->d
.AcknTimeout
= b
->AcknTimeout
;
57 f
->d
.ByteTimeout
= b
->ByteTimeout
;
58 f
->type
= TUNER_TYPE_FI1236
;
59 f
->afc_timer_installed
= FALSE
;
60 f
->last_afc_hint
= TUNER_OFF
;
61 f
->video_if
= 45.7812;
63 if (!I2C_WriteRead(&(f
->d
), NULL
, 0, &a
, 1)) {
67 FI1236_set_tuner_type(f
, TUNER_TYPE_FI1236
);
68 if (!I2CDevInit(&(f
->d
))) {
76 MT2032_dump_parameters(FI1236Ptr f
, MT2032_parameters
* m
)
78 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
79 "MT2032: input f_rf=%g f_if1=%g f_if2=%g f_ref=%g f_ifbw=%g f_step=%g\n",
80 m
->f_rf
, m
->f_if1
, m
->f_if2
, m
->f_ref
, m
->f_ifbw
, m
->f_step
);
82 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
83 "MT2032: computed f_lo1=%g f_lo2=%g LO1I=%d LO2I=%d SEL=%d STEP=%d NUM=%d\n",
84 m
->f_lo1
, m
->f_lo2
, m
->LO1I
, m
->LO2I
, m
->SEL
, m
->STEP
, m
->NUM
);
88 MT2032_getid(FI1236Ptr f
)
94 I2C_WriteRead(&(f
->d
), (I2CByte
*) &in
, 1, out
, 4);
95 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
96 "MT2032: Company code 0x%02x%02x, part code 0x%02x, revision code 0x%02x\n",
97 out
[0], out
[1], out
[2], out
[3]);
104 MT2032_shutdown(FI1236Ptr f
)
108 data
[0] = 0x00; /* start with register 0x00 */
113 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 4, NULL
, 0);
115 data
[0] = 0x05; /* now start with register 0x05 */
119 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 4, NULL
, 0);
121 data
[0] = 0x0B; /* now start with register 0x05 */
125 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 4, NULL
, 0);
131 static void MT2032_dump_status(FI1236Ptr f
);
134 MT2032_init(FI1236Ptr f
)
142 data
[0] = 0x02; /* start with register 0x02 */
147 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 4, NULL
, 0);
149 data
[0] = 0x06; /* now start with register 0x06 */
155 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 6, NULL
, 0);
157 data
[0] = 0x0d; /* now start with register 0x0d */
159 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 2, NULL
, 0);
162 usleep(15000); /* wait 15 milliseconds */
164 data
[0] = 0x0e; /* register number 7, status */
166 if (!I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 1, &value
, 1))
167 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
168 "MT2032: failed to read XOK\n");
169 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
170 "MT2032: XOK=%d\n", value
& 0x01);
175 if (!I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 1, &value
, 1))
176 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
177 "MT2032: failed to read XOGC\n");
181 break; /* XOGC has reached 4.. stop */
183 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
184 "MT2032: try XOGC=%d\n", xogc
);
186 data
[0] = 0x07; /* register number 7, control byte 2 */
187 data
[1] = 0x08 | xogc
;
188 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 2, NULL
, 0);
191 /* wait before continuing */
192 usleep(15000); /* wait 50 milliseconds */
193 MT2032_dump_status(f
);
197 MT2032_no_spur_in_band(MT2032_parameters
* m
)
206 f_test
= n1
* (m
->f_lo1
- m
->f_lo2
);
209 f_test
= f_test
- m
->f_lo2
;
210 xf86DrvMsg(0, X_INFO
,
211 "testing f_test=%g n1=%d n2=%d f_lo1=%g f_lo2=%g f_if2=%g\n",
212 f_test
, n1
, n2
, m
->f_lo1
, m
->f_lo2
, m
->f_if2
);
213 xf86DrvMsg(0, X_INFO
, "d_f=%g f_ifbw=%g\n",
214 fabs(fabs(f_test
) - m
->f_if2
), m
->f_ifbw
);
215 if ((fabs(fabs(f_test
) - m
->f_if2
) * 2.0) <= m
->f_ifbw
)
219 /* this line in the manual is bogus. I say it is faster
220 and more correct to go over all harmonics.. */
222 if (f_test
< (m
->f_lo2
- m
->f_if2
- m
->f_ifbw
))
234 MT2032_calculate_register_settings(MT2032_parameters
* m
, double f_rf
,
235 double f_if1
, double f_if2
, double f_ref
,
236 double f_ifbw
, double f_step
)
247 m
->f_lo1
= f_rf
+ f_if1
;
248 m
->LO1I
= lrint(m
->f_lo1
/ f_ref
);
249 m
->f_lo1
= f_ref
* m
->LO1I
;
251 m
->f_lo2
= m
->f_lo1
- f_rf
- f_if2
;
253 /* check for spurs */
256 if (MT2032_no_spur_in_band(m
))
259 if (m
->f_lo1
< (f_rf
+ f_if1
))
264 m
->f_lo1
= m
->LO1I
* f_ref
;
265 m
->f_lo2
= m
->f_lo1
- f_rf
- f_if2
;
268 /* xf86DrvMsg(0, X_INFO, "MT2032: n=%d\n", n); */
271 /* m->f_lo1>1100.0 */
272 if (m
->f_lo1
< 1370.0)
274 else if (m
->f_lo1
< 1530.0)
276 else if (m
->f_lo1
< 1720.0)
278 else if (m
->f_lo1
< 1890.0)
280 else /* m->f_lo1 < 1958.0 */
283 /* calculate the rest of the registers */
284 m
->LO2I
= floor(m
->f_lo2
/ f_ref
);
285 m
->STEP
= floor(3780.0 * f_step
/ f_ref
);
286 m
->NUM
= floor(3780.0 * (m
->f_lo2
/ f_ref
- m
->LO2I
));
287 m
->NUM
= m
->STEP
* lrint((1.0 * m
->NUM
) / (1.0 * m
->STEP
));
291 MT2032_wait_for_lock(FI1236Ptr f
)
299 data
[0] = 0x0e; /* register number 7, status */
300 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 1, &value
, 1);
301 /* xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO,
302 "MT2032: LO1LK=%d LO2LK=%d\n",
303 (value & 0x04)>>2, (value & 0x02)>>1); */
304 if ((value
& 6) == 6)
312 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
313 "MT2032: failed to set frequency\n");
320 MT2032_implement_settings(FI1236Ptr f
, MT2032_parameters
* m
)
325 data
[0] = 0x00; /* start with register 0x00 */
326 data
[1] = (m
->LO1I
>> 3) - 1;
327 data
[2] = (m
->SEL
<< 4) | (m
->LO1I
& 0x7);
329 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 4, NULL
, 0);
331 data
[0] = 0x05; /* start with register 0x05 */
332 data
[1] = ((m
->LO2I
& 0x7) << 5) | ((m
->LO2I
>> 3) - 1);
337 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 3, NULL
, 0);
339 data
[0] = 0x07; /* register number 7, control byte 2 */
340 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 1, &value
, 1);
341 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
342 "MT2032: using XOGC=%d\n", (value
& 0x07));
343 data
[1] = 8 | (value
& 0x7);
344 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 2, NULL
, 0);
346 data
[0] = 0x0b; /* start with register 0x0b */
347 data
[1] = m
->NUM
& 0xff;
348 data
[2] = (1 << 7) | ((m
->NUM
>> 8) & 0x0f);
349 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 3, NULL
, 0);
351 MT2032_wait_for_lock(f
);
355 MT2032_optimize_VCO(FI1236Ptr f
, MT2032_parameters
* m
)
361 data
[0] = 0x0f; /* register number 7, status */
362 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 1, &value
, 1);
364 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
365 "MT2032: TAD1=%d SEL=%d\n", TAD1
, m
->SEL
);
378 data
[0] = 0x01; /* start with register 1 */
379 data
[1] = (m
->SEL
<< 4) | (m
->LO1I
& 0x7);
380 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 2, NULL
, 0);
385 FI1236_get_afc_hint(FI1236Ptr f
)
390 if ((f
->type
== TUNER_TYPE_FM1216ME
) || (f
->type
== TUNER_TYPE_FI1236W
)) {
391 TDA9885Ptr t
= (TDA9885Ptr
) f
->afc_source
;
396 tda9885_getstatus(t
);
397 tda9885_dumpstatus(t
);
398 AFC
= t
->afc_status
& 0x0f;
400 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
401 "AFC: FI1236_get_afc_hint: %i\n", AFC
);
404 else if (AFC
<= 0x07)
405 return TUNER_JUST_BELOW
;
407 return TUNER_JUST_ABOVE
;
408 else if (AFC
== 0x0f)
412 I2C_WriteRead(&(f
->d
), NULL
, 0, &out
, 1);
414 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
415 "AFC: FI1236_get_afc_hint: %i\n", AFC
);
419 return TUNER_JUST_BELOW
;
421 return TUNER_JUST_ABOVE
;
428 MT2032_get_afc_hint(FI1236Ptr f
)
435 I2C_WriteRead(&(f
->d
), (I2CByte
*) &in
, 1, out
, 2);
436 AFC
= (out
[0] >> 4) & 0x7;
438 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
, "AFC=%d TAD1=%d TAD2=%d\n",
439 AFC
, out
[1] & 0x7, (out
[1] >> 4) & 0x07);
444 return TUNER_JUST_BELOW
;
446 return TUNER_JUST_ABOVE
;
450 /* this function is for external use only */
452 TUNER_get_afc_hint(FI1236Ptr f
)
454 if (f
->afc_timer_installed
)
455 return TUNER_STILL_TUNING
;
456 return f
->last_afc_hint
;
460 MT2032_dump_status(FI1236Ptr f
)
466 CARD8 LO1LK
, LO2LK
, XOK
;
470 I2C_WriteRead(&(f
->d
), (I2CByte
*) &in
, 1, out
, 2);
472 LO1LK
= (out
[0] >> 2) & 1;
473 LO2LK
= (out
[0] >> 1) & 1;
474 LDONrb
= (out
[0] >> 3) & 1;
476 AFC
= (out
[0] >> 4) & 0x7;
478 TAD1
= (out
[1] & 0x7);
479 TAD2
= (out
[1] >> 4) & 0x7;
481 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
482 "MT2032: status: XOK=%d LO1LK=%d LO2LK=%d LDONrb=%d AFC=%d TAD1=%d TAD2=%d\n",
483 XOK
, LO1LK
, LO2LK
, LDONrb
, AFC
, TAD1
, TAD2
);
484 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
485 "MT2032: status: OSCILLATOR:%s PLL1:%s PLL2:%s\n",
487 LO1LK
? "locked" : "off", LO2LK
? "locked" : "off");
492 MT2032_tune(FI1236Ptr f
, double freq
, double step
)
498 /* NTSC IF is 44mhz.. but 733/16=45.8125 and all TDAXXXX docs mention
499 45.75, 39, 58.75 and 30. */
501 MT2032_calculate_register_settings(&m
, freq
, 1090.0, 45.125, 5.25, 6.0,
503 MT2032_calculate_register_settings(&m
, freq
, 1090.0, 45.74, 5.25, 6.0,
506 MT2032_calculate_register_settings(&m
, freq
, 1090.0, f
->video_if
, 5.25, 3.0,
508 MT2032_dump_parameters(f
, &m
);
509 MT2032_implement_settings(f
, &m
);
510 /* MT2032_dump_parameters(f, &m); */
511 for (i
= 0; i
< 3; i
++) {
512 MT2032_optimize_VCO(f
, &m
);
513 if (MT2032_wait_for_lock(f
)) {
514 data
[0] = 0x02; /* LO Gain control register 0x02 */
516 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 2, NULL
, 0);
520 data
[1] = 0x88 | f
->xogc
;
521 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 2, NULL
, 0);
523 data
[1] = 0x08 | f
->xogc
;
524 I2C_WriteRead(&(f
->d
), (I2CByte
*) data
, 2, NULL
, 0);
526 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
527 "MT2032: failed to set frequency\n");
531 FI1236_set_tuner_type(FI1236Ptr f
, int type
)
534 if (type
>= NUM_TUNERS
)
535 type
= NUM_TUNERS
- 1;
538 memcpy(&(f
->parm
), &(tuner_parms
[type
]), sizeof(FI1236_parameters
));
539 f
->original_frequency
= f
->parm
.min_freq
;
541 if (type
== TUNER_TYPE_MT2032
) {
548 AFC_TimerCallback(OsTimerPtr timer
, CARD32 time
, pointer data
)
550 FI1236Ptr f
= (FI1236Ptr
) data
;
555 f
->afc_timer_installed
= FALSE
;
562 FI1236_tune(FI1236Ptr f
, CARD32 frequency
)
567 if (frequency
< f
->parm
.min_freq
)
568 frequency
= f
->parm
.min_freq
;
569 if (frequency
> f
->parm
.max_freq
)
570 frequency
= f
->parm
.max_freq
;
572 divider
= (f
->parm
.fcar
+ (CARD16
) frequency
) & 0x7fff;
573 f
->tuner_data
.div1
= (CARD8
) ((divider
>> 8) & 0x7f);
574 f
->tuner_data
.div2
= (CARD8
) (divider
& 0xff);
575 f
->tuner_data
.control
= f
->parm
.control
;
577 if (frequency
< f
->parm
.threshold1
)
578 f
->tuner_data
.band
= f
->parm
.band_low
;
579 else if (frequency
< f
->parm
.threshold2
)
580 f
->tuner_data
.band
= f
->parm
.band_mid
;
582 f
->tuner_data
.band
= f
->parm
.band_high
;
584 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
585 "Setting tuner band to %d\n", f
->tuner_data
.band
);
587 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
588 "Setting tuner frequency to %d\n", (int) frequency
);
590 if ((f
->type
== TUNER_TYPE_FM1216ME
) || (f
->type
== TUNER_TYPE_FI1236W
)) {
591 f
->tuner_data
.aux
= 0x20;
592 I2C_WriteRead(&(f
->d
), (I2CByte
*) &(f
->tuner_data
), 5, NULL
, 0);
593 I2C_WriteRead(&(f
->d
), NULL
, 0, &data
, 1);
594 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
, "Tuner status %x\n", data
);
597 I2C_WriteRead(&(f
->d
), (I2CByte
*) &(f
->tuner_data
), 4, NULL
, 0);
601 TUNER_set_frequency(FI1236Ptr f
, CARD32 frequency
)
603 if (frequency
< f
->parm
.min_freq
)
604 frequency
= f
->parm
.min_freq
;
605 if (frequency
> f
->parm
.max_freq
)
606 frequency
= f
->parm
.max_freq
;
609 f
->original_frequency
= frequency
;
611 if (f
->type
== TUNER_TYPE_MT2032
)
612 MT2032_tune(f
, (1.0 * frequency
) / 16.0, 0.0625);
614 FI1236_tune(f
, frequency
);
616 if (!f
->afc_timer_installed
) {
617 f
->afc_timer_installed
= TRUE
;
618 /* RegisterBlockAndWakeupHandlers(FI1236_BlockHandler, AFCWakeup, f); */
619 TimerSet(NULL
, 0, 300, AFC_TimerCallback
, f
);
625 FI1236_AFC(FI1236Ptr f
)
628 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
629 "AFC: f=%p f->count=%d f->original_frequency=%d f->afc_delta=%d\n",
630 f
, f
->afc_count
, f
->original_frequency
, f
->afc_delta
);
633 if (f
->type
== TUNER_TYPE_MT2032
) {
634 f
->last_afc_hint
= MT2032_get_afc_hint(f
);
635 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
636 "AFC: afc_hint=%d\n", f
->last_afc_hint
);
637 if (f
->last_afc_hint
== TUNER_TUNED
)
639 if (f
->afc_count
> 3)
640 f
->last_afc_hint
= TUNER_OFF
;
641 if (f
->last_afc_hint
== TUNER_OFF
)
644 f
->afc_delta
+= f
->last_afc_hint
;
646 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
647 "AFC: Setting tuner frequency to %g\n",
648 (0.5 * (2 * f
->original_frequency
+ f
->afc_delta
)) / 16.0);
650 (1.0 * f
->original_frequency
+ 0.5 * f
->afc_delta
) / 16.0,
652 if (f
->last_afc_hint
== TUNER_OFF
)
654 return 1; /* call me again */
657 f
->last_afc_hint
= FI1236_get_afc_hint(f
);
658 if (f
->last_afc_hint
== TUNER_TUNED
) {
659 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
, "AFC: TUNER_TUNNED\n");
662 if (f
->afc_count
> 3)
663 f
->last_afc_hint
= TUNER_OFF
;
665 if (f
->last_afc_hint
== TUNER_OFF
)
668 f
->afc_delta
+= f
->last_afc_hint
;
670 xf86DrvMsg(f
->d
.pI2CBus
->scrnIndex
, X_INFO
,
671 "AFC: Setting tuner frequency to %g\n",
672 (0.5 * (2 * f
->original_frequency
+ f
->afc_delta
)) / 16.0);
673 FI1236_tune(f
, f
->original_frequency
+ f
->afc_delta
);
674 if (f
->last_afc_hint
== TUNER_OFF
)
676 return 1; /* call me again */
682 fi1236_dump_status(FI1236Ptr f
)
684 if (f
->type
== TUNER_TYPE_MT2032
)
685 MT2032_dump_status(f
);