Initial commit
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / i2c / fi1236.c
blob110563ed9956524ab5de681728e4429c7ed232cd
2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
4 #endif
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <math.h>
11 #include "xf86.h"
12 #include "xf86i2c.h"
13 #include "fi1236.h"
14 #include "tda9885.h"
15 #include "i2c_def.h"
17 #define NUM_TUNERS 8
19 const FI1236_parameters tuner_parms[NUM_TUNERS] =
21 /* 0 - FI1236 */
22 { 733 ,884 ,12820 ,2516 ,7220 ,0xA2 ,0x94, 0x34, 0x8e },
23 /* !!!based on documentation - it should be:
24 {733 ,16*55.25 ,16*801.25 ,16*160 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e},*/
26 /* 1 - FI1216 */
27 { 623 ,16*48.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
28 /* 2 - TEMIC FN5AL */
29 { 623 ,16*45.75 ,16*855.25 ,16*169 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e },
30 /* 3 - MT2032.. */
31 { 733 ,768 ,13760 , 0 , 0 , 0 , 0, 0, 0 },
32 /* 4 - FI1246 */
33 { 623 ,16*45.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
34 /* 5 - FI1256 */
35 { 623 ,16*49.75 ,16*863.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
36 /* 6 - FI1236W */
37 /*{ 733 ,884 ,12820 ,2516 ,7220 ,0x1 ,0x2, 0x4, 0x8e },*/
38 { 732, 16*55.25, 16*801.25, 16*160, 16*442, 0x1, 0x2, 0x4, 0x8e },
39 /* 7 - FM1216ME */
40 { 623 ,16*48.25 ,16*863.25 ,16*158.00 ,16*442.00 ,0x1 ,0x2, 0x4, 0x8e }
44 FI1236Ptr Detect_FI1236(I2CBusPtr b, I2CSlaveAddr addr)
46 FI1236Ptr f;
47 I2CByte a;
49 f = xcalloc(1,sizeof(FI1236Rec));
50 if(f == NULL) return NULL;
51 f->d.DevName = strdup("FI12xx Tuner");
52 f->d.SlaveAddr = addr;
53 f->d.pI2CBus = b;
54 f->d.NextDev = NULL;
55 f->d.StartTimeout = b->StartTimeout;
56 f->d.BitTimeout = b->BitTimeout;
57 f->d.AcknTimeout = b->AcknTimeout;
58 f->d.ByteTimeout = b->ByteTimeout;
59 f->type=TUNER_TYPE_FI1236;
60 f->afc_timer_installed=FALSE;
61 f->last_afc_hint=TUNER_OFF;
62 f->video_if=45.7812;
64 if(!I2C_WriteRead(&(f->d), NULL, 0, &a, 1))
66 free(f);
67 return NULL;
69 FI1236_set_tuner_type(f, TUNER_TYPE_FI1236);
70 if(!I2CDevInit(&(f->d)))
72 free(f);
73 return NULL;
75 return f;
78 static void MT2032_dump_parameters(FI1236Ptr f, MT2032_parameters *m)
80 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: input f_rf=%g f_if1=%g f_if2=%g f_ref=%g f_ifbw=%g f_step=%g\n",
81 m->f_rf, m->f_if1, m->f_if2, m->f_ref, m->f_ifbw, m->f_step);
83 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "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 static void MT2032_getid(FI1236Ptr f)
90 CARD8 out[4];
91 CARD8 in;
93 in=0x11;
94 I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 4);
95 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: Company code 0x%02x%02x, part code 0x%02x, revision code 0x%02x\n",
96 out[0], out[1], out[2], out[3]);
100 /* might be buggy */
101 #if 0
102 static void MT2032_shutdown(FI1236Ptr f)
104 CARD8 data[10];
106 data[0]=0x00; /* start with register 0x00 */
107 data[1]=0x1A;
108 data[2]=0x44;
109 data[3]=0x20;
111 I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
113 data[0]=0x05; /* now start with register 0x05 */
114 data[1]=0xD7;
115 data[2]=0x14;
116 data[3]=0x05;
117 I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
119 data[0]=0x0B; /* now start with register 0x05 */
120 data[1]=0x8F;
121 data[2]=0x07;
122 data[3]=0x43;
123 I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
125 usleep(15000);
127 #endif
129 static void MT2032_dump_status(FI1236Ptr f);
131 static void MT2032_init(FI1236Ptr f)
133 CARD8 data[10];
134 CARD8 value;
135 CARD8 xogc = 0x00;
137 MT2032_getid(f);
139 data[0]=0x02; /* start with register 0x02 */
140 data[1]=0xFF;
141 data[2]=0x0F;
142 data[3]=0x1F;
144 I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
146 data[0]=0x06; /* now start with register 0x06 */
147 data[1]=0xE4;
148 data[2]=0x8F;
149 data[3]=0xC3;
150 data[4]=0x4E;
151 data[5]=0xEC;
152 I2C_WriteRead(&(f->d), (I2CByte *)data, 6, NULL, 0);
154 data[0]=0x0d; /* now start with register 0x0d */
155 data[1]=0x32;
156 I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
158 while(1) {
159 usleep(15000); /* wait 15 milliseconds */
161 data[0]=0x0e; /* register number 7, status */
162 value=0xFF;
163 if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1))
164 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOK\n");
165 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: XOK=%d\n", value & 0x01);
166 if(value & 1) break;
168 data[0]=0x07;
169 if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1))
170 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOGC\n");
172 xogc=value & 0x7;
173 if(xogc==4){
174 break; /* XOGC has reached 4.. stop */
176 xogc--;
177 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: try XOGC=%d\n", xogc);
178 usleep(15000);
179 data[0]=0x07; /* register number 7, control byte 2 */
180 data[1]=0x08 | xogc;
181 I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
183 f->xogc=xogc;
184 /* wait before continuing */
185 usleep(15000); /* wait 50 milliseconds */
186 MT2032_dump_status(f);
189 static int MT2032_no_spur_in_band(MT2032_parameters *m)
191 int n_max, n1, n2;
192 double f_test;
193 n_max=5;
194 n1=1;
195 while(1){
196 n2=-n1;
197 f_test=n1*(m->f_lo1-m->f_lo2);
198 while(1){
199 n2--;
200 f_test=f_test-m->f_lo2;
201 xf86DrvMsg(0, X_INFO, "testing f_test=%g n1=%d n2=%d f_lo1=%g f_lo2=%g f_if2=%g\n", f_test, n1, n2, m->f_lo1, m->f_lo2, m->f_if2);
202 xf86DrvMsg(0, X_INFO, "d_f=%g f_ifbw=%g\n",fabs(fabs(f_test)-m->f_if2), m->f_ifbw);
203 if((fabs(fabs(f_test)-m->f_if2)*2.0)<=m->f_ifbw)return 0;
204 if(n2<=-n_max)break;
205 /* this line in the manual is bogus. I say it is faster
206 and more correct to go over all harmonics.. */
207 #if 0
208 if(f_test<(m->f_lo2-m->f_if2-m->f_ifbw))break;
209 #endif
211 n1++;
212 if(n1>=n_max)return 1;
217 static void MT2032_calculate_register_settings(MT2032_parameters *m, double f_rf, double f_if1, double f_if2, double f_ref, double f_ifbw, double f_step)
219 int n;
220 m->f_rf=f_rf;
221 m->f_if1=f_if1;
222 m->f_if2=f_if2;
223 m->f_ref=f_ref;
224 m->f_ifbw=f_ifbw;
225 m->f_step=f_step;
227 m->f_lo1=f_rf+f_if1;
228 m->LO1I=(int)floor((m->f_lo1/f_ref)+0.5);
229 m->f_lo1=f_ref*m->LO1I;
231 m->f_lo2=m->f_lo1-f_rf-f_if2;
233 /* check for spurs */
234 n=1;
235 while(n<3){
236 if(MT2032_no_spur_in_band(m))break;
237 if(m->f_lo1<(f_rf+f_if1)){
238 m->LO1I+=n;
239 } else {
240 m->LO1I-=n;
242 m->f_lo1=m->LO1I*f_ref;
243 m->f_lo2=m->f_lo1-f_rf-f_if2;
244 n++;
246 /* xf86DrvMsg(0, X_INFO, "MT2032: n=%d\n", n); */
247 /* select VCO */
249 /* m->f_lo1>1100.0 */
250 if(m->f_lo1<1370.0)m->SEL=4;
251 else
252 if(m->f_lo1<1530.0)m->SEL=3;
253 else
254 if(m->f_lo1<1720.0)m->SEL=2;
255 else
256 if(m->f_lo1<1890.0)m->SEL=1;
257 else /* m->f_lo1 < 1958.0 */
258 m->SEL=0;
260 /* calculate the rest of the registers */
261 m->LO2I=(int)floor(m->f_lo2/f_ref);
262 m->STEP=(int)floor(3780.0*f_step/f_ref);
263 m->NUM=(int)floor(3780.0*(m->f_lo2/f_ref-m->LO2I));
264 m->NUM=m->STEP*(int)floor((1.0*m->NUM)/(1.0*m->STEP)+0.5);
267 static int MT2032_wait_for_lock(FI1236Ptr f)
269 int n;
270 CARD8 data[10];
271 CARD8 value;
273 n=12;
274 while(1){
275 data[0]=0x0e; /* register number 7, status */
276 I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
277 /* xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: LO1LK=%d LO2LK=%d\n", (value & 0x04)>>2, (value & 0x02)>>1); */
278 if((value & 6)==6) break;
279 usleep(1500);
280 n--;
281 if(n<0)break;
283 if(n<0){
284 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n");
285 return 0;
287 return 1;
290 static void MT2032_implement_settings(FI1236Ptr f, MT2032_parameters *m)
292 CARD8 data[10];
293 CARD8 value;
295 data[0]=0x00; /* start with register 0x00 */
296 data[1]=(m->LO1I>>3)-1;
297 data[2]=(m->SEL<<4)|(m->LO1I & 0x7);
298 data[3]=0x86;
299 I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
301 data[0]=0x05; /* start with register 0x05 */
302 data[1]=((m->LO2I & 0x7)<<5)|((m->LO2I>>3)-1);
303 if(m->f_rf<400.0)data[2]=0xe4;
304 else data[2]=0xf4;
305 I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0);
307 data[0]=0x07; /* register number 7, control byte 2 */
308 I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
309 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: using XOGC=%d\n", (value & 0x07));
310 data[1]=8 | (value & 0x7);
311 I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
313 data[0]=0x0b; /* start with register 0x0b */
314 data[1]=m->NUM & 0xff;
315 data[2]=(1<<7)|((m->NUM >> 8) & 0x0f);
316 I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0);
318 MT2032_wait_for_lock(f);
321 static void MT2032_optimize_VCO(FI1236Ptr f, MT2032_parameters *m)
323 CARD8 data[10];
324 CARD8 value;
325 CARD8 TAD1;
327 data[0]=0x0f; /* register number 7, status */
328 I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
329 TAD1=value & 0x07;
330 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: TAD1=%d SEL=%d\n", TAD1, m->SEL);
331 if(TAD1 < 2)return;
332 if(TAD1==2){
333 if(m->SEL==0)return;
334 m->SEL--;
335 } else {
336 if(m->SEL>=4)return;
337 m->SEL++;
339 data[0]=0x01; /* start with register 1 */
340 data[1]=(m->SEL<<4)|(m->LO1I & 0x7);
341 I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
345 static int FI1236_get_afc_hint(FI1236Ptr f)
347 CARD8 out;
348 CARD8 AFC;
350 if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W))
352 TDA9885Ptr t = (TDA9885Ptr)f->afc_source;
353 if (t == NULL)
354 return TUNER_OFF;
356 tda9885_getstatus(t);
357 tda9885_dumpstatus(t);
358 AFC = t->afc_status & 0x0f;
360 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC);
361 if (AFC == 0) return TUNER_TUNED;
362 else if (AFC <= 0x07)return TUNER_JUST_BELOW;
363 else if (AFC < 0x0f )return TUNER_JUST_ABOVE;
364 else if (AFC == 0x0f)return TUNER_TUNED;
366 else
368 I2C_WriteRead(&(f->d), NULL, 0, &out, 1);
369 AFC=out & 0x7;
370 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC);
371 if(AFC==2)return TUNER_TUNED;
372 if(AFC==3)return TUNER_JUST_BELOW;
373 if(AFC==1)return TUNER_JUST_ABOVE;
374 return TUNER_OFF;
376 return TUNER_OFF;
379 static int MT2032_get_afc_hint(FI1236Ptr f)
381 CARD8 in;
382 CARD8 out[2];
383 CARD8 AFC;
384 in=0x0e;
385 I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2);
386 AFC=(out[0]>>4) & 0x7;
387 #if 0
388 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC=%d TAD1=%d TAD2=%d\n", AFC, out[1] & 0x7, (out[1]>>4)& 0x07);
389 #endif
390 if(AFC==2)return TUNER_TUNED;
391 if(AFC==3)return TUNER_JUST_BELOW;
392 if(AFC==1)return TUNER_JUST_ABOVE;
393 return TUNER_OFF;
396 /* this function is for external use only */
397 int TUNER_get_afc_hint(FI1236Ptr f)
399 if(f->afc_timer_installed)return TUNER_STILL_TUNING;
400 return f->last_afc_hint;
401 if(f->type==TUNER_TYPE_MT2032)
402 return MT2032_get_afc_hint(f);
403 else
404 return FI1236_get_afc_hint(f);
407 static void MT2032_dump_status(FI1236Ptr f)
409 CARD8 in;
410 CARD8 out[2];
411 CARD8 AFC;
412 CARD8 LDONrb;
413 CARD8 LO1LK, LO2LK, XOK;
414 CARD8 TAD2, TAD1;
416 in=0x0e;
417 I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2);
418 XOK=out[0] & 1;
419 LO1LK=(out[0]>>2) &1;
420 LO2LK=(out[0]>>1) &1;
421 LDONrb=(out[0]>>3) &1;
423 AFC=(out[0]>>4) & 0x7;
425 TAD1=(out[1] & 0x7);
426 TAD2=(out[1]>>4) & 0x7;
428 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: XOK=%d LO1LK=%d LO2LK=%d LDONrb=%d AFC=%d TAD1=%d TAD2=%d\n",
429 XOK, LO1LK, LO2LK, LDONrb, AFC, TAD1, TAD2);
430 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: OSCILLATOR:%s PLL1:%s PLL2:%s\n",
431 XOK ? "ok":"off", LO1LK ? "locked" : "off" , LO2LK ? "locked" : "off");
435 static void MT2032_tune(FI1236Ptr f, double freq, double step)
437 MT2032_parameters m;
438 CARD8 data[10];
439 int i;
440 /* NTSC IF is 44mhz.. but 733/16=45.8125 and all TDAXXXX docs mention
441 45.75, 39, 58.75 and 30. */
442 #if 0
443 MT2032_calculate_register_settings(&m, freq, 1090.0, 45.125, 5.25, 6.0, step);
444 MT2032_calculate_register_settings(&m, freq, 1090.0, 45.74, 5.25, 6.0, step);
445 #endif
446 MT2032_calculate_register_settings(&m, freq, 1090.0, f->video_if, 5.25, 3.0, step);
447 MT2032_dump_parameters(f, &m);
448 MT2032_implement_settings(f, &m);
449 /* MT2032_dump_parameters(f, &m); */
450 for(i=0;i<3;i++){
451 MT2032_optimize_VCO(f, &m);
452 if(MT2032_wait_for_lock(f)){
453 data[0]=0x02; /* LO Gain control register 0x02 */
454 data[1]=0x20;
455 I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
456 return;
458 data[0]=0x07;
459 data[1]=0x88|f->xogc;
460 I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
461 usleep(15000);
462 data[1]=0x08|f->xogc;
463 I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
465 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n");
468 void FI1236_set_tuner_type(FI1236Ptr f, int type)
470 f->type=type;
471 if(type>=NUM_TUNERS)type = NUM_TUNERS-1;
472 if(type<0)type = 0;
473 memcpy(&(f->parm), &(tuner_parms[type]), sizeof(FI1236_parameters));
474 f->original_frequency=f->parm.min_freq;
475 f->afc_delta=0;
476 if(type==TUNER_TYPE_MT2032){
477 MT2032_init(f);
478 return;
483 static CARD32 AFC_TimerCallback(OsTimerPtr timer, CARD32 time, pointer data){
484 FI1236Ptr f=(FI1236Ptr)data;
485 if(FI1236_AFC(f))return 150;
486 else {
487 f->afc_timer_installed=FALSE;
488 f->afc_count=0;
489 return 0;
493 void FI1236_tune(FI1236Ptr f, CARD32 frequency)
495 CARD16 divider;
496 CARD8 data;
498 if(frequency < f->parm.min_freq) frequency = f->parm.min_freq;
499 if(frequency > f->parm.max_freq) frequency = f->parm.max_freq;
501 divider = (f->parm.fcar+(CARD16)frequency) & 0x7fff;
502 f->tuner_data.div1 = (CARD8)((divider>>8)&0x7f);
503 f->tuner_data.div2 = (CARD8)(divider & 0xff);
504 f->tuner_data.control = f->parm.control;
506 if(frequency < f->parm.threshold1)
508 f->tuner_data.band = f->parm.band_low;
510 else if (frequency < f->parm.threshold2)
512 f->tuner_data.band = f->parm.band_mid;
514 else
516 f->tuner_data.band = f->parm.band_high;
519 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner band to %d\n", f->tuner_data.band);
521 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner frequency to %d\n", (int)frequency);
523 if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W))
525 f->tuner_data.aux = 0x20;
526 I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 5, NULL, 0);
527 I2C_WriteRead(&(f->d), NULL, 0, &data, 1);
528 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Tuner status %x\n", data);
531 else
532 I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 4, NULL, 0);
535 void TUNER_set_frequency(FI1236Ptr f, CARD32 frequency)
537 if(frequency < f->parm.min_freq) frequency = f->parm.min_freq;
538 if(frequency > f->parm.max_freq) frequency = f->parm.max_freq;
540 f->afc_delta=0;
541 f->original_frequency=frequency;
543 if(f->type==TUNER_TYPE_MT2032)
545 MT2032_tune(f, (1.0*frequency)/16.0, 0.0625);
546 } else
548 FI1236_tune(f, frequency);
551 if(!f->afc_timer_installed)
553 f->afc_timer_installed=TRUE;
554 /* RegisterBlockAndWakeupHandlers(FI1236_BlockHandler, AFCWakeup, f); */
555 TimerSet(NULL, 0, 300, AFC_TimerCallback, f);
561 int FI1236_AFC(FI1236Ptr f)
563 #if 0
564 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: f=%p f->count=%d f->original_frequency=%d f->afc_delta=%d\n", f, f->afc_count, f->original_frequency, f->afc_delta);
565 #endif
566 f->afc_count++;
567 if(f->type==TUNER_TYPE_MT2032)
569 f->last_afc_hint=MT2032_get_afc_hint(f);
570 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: afc_hint=%d\n", f->last_afc_hint);
571 if(f->last_afc_hint==TUNER_TUNED)return 0;
572 if(f->afc_count>3)f->last_afc_hint=TUNER_OFF;
573 if(f->last_afc_hint==TUNER_OFF)
575 f->afc_delta=0;
576 } else
577 f->afc_delta+=f->last_afc_hint;
578 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: Setting tuner frequency to %g\n", (0.5*(2*f->original_frequency+f->afc_delta))/16.0);
579 MT2032_tune(f, (1.0*f->original_frequency+0.5*f->afc_delta)/16.0, 0.03125);
580 if(f->last_afc_hint==TUNER_OFF)return 0;
581 return 1; /* call me again */
582 } else
584 f->last_afc_hint=FI1236_get_afc_hint(f);
585 if(f->last_afc_hint==TUNER_TUNED)
587 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: TUNER_TUNNED\n");
588 return 0;
590 if(f->afc_count>3)f->last_afc_hint=TUNER_OFF;
591 if(f->last_afc_hint==TUNER_OFF)
593 f->afc_delta=0;
594 } else
595 f->afc_delta+=f->last_afc_hint;
596 xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: Setting tuner frequency to %g\n", (0.5*(2*f->original_frequency+f->afc_delta))/16.0);
597 FI1236_tune(f, f->original_frequency+f->afc_delta);
598 if(f->last_afc_hint==TUNER_OFF)return 0;
599 return 1; /* call me again */
601 return 0; /* done */
604 void fi1236_dump_status(FI1236Ptr f)
606 if(f->type==TUNER_TYPE_MT2032){
607 MT2032_dump_status(f);