diff options
Diffstat (limited to 'xorg-server/hw/xfree86/i2c/fi1236.c')
-rw-r--r-- | xorg-server/hw/xfree86/i2c/fi1236.c | 1210 |
1 files changed, 605 insertions, 605 deletions
diff --git a/xorg-server/hw/xfree86/i2c/fi1236.c b/xorg-server/hw/xfree86/i2c/fi1236.c index 61224eaa5..531b64aed 100644 --- a/xorg-server/hw/xfree86/i2c/fi1236.c +++ b/xorg-server/hw/xfree86/i2c/fi1236.c @@ -1,605 +1,605 @@ - -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> -#endif - -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#include "xf86.h" -#include "xf86i2c.h" -#include "fi1236.h" -#include "tda9885.h" -#include "i2c_def.h" - -#define NUM_TUNERS 8 - -const FI1236_parameters tuner_parms[NUM_TUNERS] = -{ - /* 0 - FI1236 */ - { 733 ,884 ,12820 ,2516 ,7220 ,0xA2 ,0x94, 0x34, 0x8e }, - /* !!!based on documentation - it should be: - {733 ,16*55.25 ,16*801.25 ,16*160 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e},*/ - - /* 1 - FI1216 */ - { 623 ,16*48.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e }, - /* 2 - TEMIC FN5AL */ - { 623 ,16*45.75 ,16*855.25 ,16*169 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e }, - /* 3 - MT2032.. */ - { 733 ,768 ,13760 , 0 , 0 , 0 , 0, 0, 0 }, - /* 4 - FI1246 */ - { 623 ,16*45.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e }, - /* 5 - FI1256 */ - { 623 ,16*49.75 ,16*863.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e }, - /* 6 - FI1236W */ - /*{ 733 ,884 ,12820 ,2516 ,7220 ,0x1 ,0x2, 0x4, 0x8e },*/ - { 732, 16*55.25, 16*801.25, 16*160, 16*442, 0x1, 0x2, 0x4, 0x8e }, - /* 7 - FM1216ME */ - { 623 ,16*48.25 ,16*863.25 ,16*158.00 ,16*442.00 ,0x1 ,0x2, 0x4, 0x8e } -}; - - -FI1236Ptr Detect_FI1236(I2CBusPtr b, I2CSlaveAddr addr) -{ - FI1236Ptr f; - I2CByte a; - - f = xcalloc(1,sizeof(FI1236Rec)); - if(f == NULL) return NULL; - f->d.DevName = strdup("FI12xx Tuner"); - f->d.SlaveAddr = addr; - f->d.pI2CBus = b; - f->d.NextDev = NULL; - f->d.StartTimeout = b->StartTimeout; - f->d.BitTimeout = b->BitTimeout; - f->d.AcknTimeout = b->AcknTimeout; - f->d.ByteTimeout = b->ByteTimeout; - f->type=TUNER_TYPE_FI1236; - f->afc_timer_installed=FALSE; - f->last_afc_hint=TUNER_OFF; - f->video_if=45.7812; - - if(!I2C_WriteRead(&(f->d), NULL, 0, &a, 1)) - { - free(f); - return NULL; - } - FI1236_set_tuner_type(f, TUNER_TYPE_FI1236); - if(!I2CDevInit(&(f->d))) - { - free(f); - return NULL; - } - return f; -} - -static void MT2032_dump_parameters(FI1236Ptr f, MT2032_parameters *m) -{ -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", - m->f_rf, m->f_if1, m->f_if2, m->f_ref, m->f_ifbw, m->f_step); - -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", - m->f_lo1, m->f_lo2, m->LO1I, m->LO2I, m->SEL, m->STEP, m->NUM); -} - - -static void MT2032_getid(FI1236Ptr f) -{ -CARD8 out[4]; -CARD8 in; - -in=0x11; -I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 4); -xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: Company code 0x%02x%02x, part code 0x%02x, revision code 0x%02x\n", - out[0], out[1], out[2], out[3]); - -} - -/* might be buggy */ -#if 0 -static void MT2032_shutdown(FI1236Ptr f) -{ -CARD8 data[10]; - -data[0]=0x00; /* start with register 0x00 */ -data[1]=0x1A; -data[2]=0x44; -data[3]=0x20; - -I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0); - -data[0]=0x05; /* now start with register 0x05 */ -data[1]=0xD7; -data[2]=0x14; -data[3]=0x05; -I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0); - -data[0]=0x0B; /* now start with register 0x05 */ -data[1]=0x8F; -data[2]=0x07; -data[3]=0x43; -I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0); - -usleep(15000); -} -#endif - -static void MT2032_dump_status(FI1236Ptr f); - -static void MT2032_init(FI1236Ptr f) -{ -CARD8 data[10]; -CARD8 value; -CARD8 xogc = 0x00; - -MT2032_getid(f); - -data[0]=0x02; /* start with register 0x02 */ -data[1]=0xFF; -data[2]=0x0F; -data[3]=0x1F; - -I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0); - -data[0]=0x06; /* now start with register 0x06 */ -data[1]=0xE4; -data[2]=0x8F; -data[3]=0xC3; -data[4]=0x4E; -data[5]=0xEC; -I2C_WriteRead(&(f->d), (I2CByte *)data, 6, NULL, 0); - -data[0]=0x0d; /* now start with register 0x0d */ -data[1]=0x32; -I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0); - -while(1) { - usleep(15000); /* wait 15 milliseconds */ - - data[0]=0x0e; /* register number 7, status */ - value=0xFF; - if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1)) - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOK\n"); - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: XOK=%d\n", value & 0x01); - if(value & 1) break; - - data[0]=0x07; - if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1)) - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOGC\n"); - - xogc=value & 0x7; - if(xogc==4){ - break; /* XOGC has reached 4.. stop */ - } - xogc--; - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: try XOGC=%d\n", xogc); - usleep(15000); - data[0]=0x07; /* register number 7, control byte 2 */ - data[1]=0x08 | xogc; - I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0); - } -f->xogc=xogc; -/* wait before continuing */ -usleep(15000); /* wait 50 milliseconds */ -MT2032_dump_status(f); -} - -static int MT2032_no_spur_in_band(MT2032_parameters *m) -{ -int n_max, n1, n2; -double f_test; -n_max=5; -n1=1; -while(1){ - n2=-n1; - f_test=n1*(m->f_lo1-m->f_lo2); - while(1){ - n2--; - f_test=f_test-m->f_lo2; - 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); - xf86DrvMsg(0, X_INFO, "d_f=%g f_ifbw=%g\n",fabs(fabs(f_test)-m->f_if2), m->f_ifbw); - if((fabs(fabs(f_test)-m->f_if2)*2.0)<=m->f_ifbw)return 0; - if(n2<=-n_max)break; - /* this line in the manual is bogus. I say it is faster - and more correct to go over all harmonics.. */ - #if 0 - if(f_test<(m->f_lo2-m->f_if2-m->f_ifbw))break; - #endif - } - n1++; - if(n1>=n_max)return 1; - } - -} - -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) -{ -int n; -m->f_rf=f_rf; -m->f_if1=f_if1; -m->f_if2=f_if2; -m->f_ref=f_ref; -m->f_ifbw=f_ifbw; -m->f_step=f_step; - -m->f_lo1=f_rf+f_if1; -m->LO1I=lrint(m->f_lo1/f_ref); -m->f_lo1=f_ref*m->LO1I; - -m->f_lo2=m->f_lo1-f_rf-f_if2; - -/* check for spurs */ -n=1; -while(n<3){ - if(MT2032_no_spur_in_band(m))break; - if(m->f_lo1<(f_rf+f_if1)){ - m->LO1I+=n; - } else { - m->LO1I-=n; - } - m->f_lo1=m->LO1I*f_ref; - m->f_lo2=m->f_lo1-f_rf-f_if2; - n++; - } -/* xf86DrvMsg(0, X_INFO, "MT2032: n=%d\n", n); */ -/* select VCO */ - -/* m->f_lo1>1100.0 */ -if(m->f_lo1<1370.0)m->SEL=4; - else -if(m->f_lo1<1530.0)m->SEL=3; - else -if(m->f_lo1<1720.0)m->SEL=2; - else -if(m->f_lo1<1890.0)m->SEL=1; - else /* m->f_lo1 < 1958.0 */ - m->SEL=0; - -/* calculate the rest of the registers */ -m->LO2I=floor(m->f_lo2/f_ref); -m->STEP=floor(3780.0*f_step/f_ref); -m->NUM=floor(3780.0*(m->f_lo2/f_ref-m->LO2I)); -m->NUM=m->STEP*lrint((1.0*m->NUM)/(1.0*m->STEP)); -} - -static int MT2032_wait_for_lock(FI1236Ptr f) -{ -int n; -CARD8 data[10]; -CARD8 value; - -n=12; -while(1){ - data[0]=0x0e; /* register number 7, status */ - I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1); -/* xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: LO1LK=%d LO2LK=%d\n", (value & 0x04)>>2, (value & 0x02)>>1); */ - if((value & 6)==6) break; - usleep(1500); - n--; - if(n<0)break; - } -if(n<0){ - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n"); - return 0; - } -return 1; -} - -static void MT2032_implement_settings(FI1236Ptr f, MT2032_parameters *m) -{ -CARD8 data[10]; -CARD8 value; - -data[0]=0x00; /* start with register 0x00 */ -data[1]=(m->LO1I>>3)-1; -data[2]=(m->SEL<<4)|(m->LO1I & 0x7); -data[3]=0x86; -I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0); - -data[0]=0x05; /* start with register 0x05 */ -data[1]=((m->LO2I & 0x7)<<5)|((m->LO2I>>3)-1); -if(m->f_rf<400.0)data[2]=0xe4; - else data[2]=0xf4; -I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0); - -data[0]=0x07; /* register number 7, control byte 2 */ -I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1); -xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: using XOGC=%d\n", (value & 0x07)); -data[1]=8 | (value & 0x7); -I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0); - -data[0]=0x0b; /* start with register 0x0b */ -data[1]=m->NUM & 0xff; -data[2]=(1<<7)|((m->NUM >> 8) & 0x0f); -I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0); - -MT2032_wait_for_lock(f); -} - -static void MT2032_optimize_VCO(FI1236Ptr f, MT2032_parameters *m) -{ -CARD8 data[10]; -CARD8 value; -CARD8 TAD1; - -data[0]=0x0f; /* register number 7, status */ -I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1); -TAD1=value & 0x07; -xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: TAD1=%d SEL=%d\n", TAD1, m->SEL); -if(TAD1 < 2)return; -if(TAD1==2){ - if(m->SEL==0)return; - m->SEL--; - } else { - if(m->SEL>=4)return; - m->SEL++; - } -data[0]=0x01; /* start with register 1 */ -data[1]=(m->SEL<<4)|(m->LO1I & 0x7); -I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0); - -} - -static int FI1236_get_afc_hint(FI1236Ptr f) -{ - CARD8 out; - CARD8 AFC; - - if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W)) - { - TDA9885Ptr t = (TDA9885Ptr)f->afc_source; - if (t == NULL) - return TUNER_OFF; - - tda9885_getstatus(t); - tda9885_dumpstatus(t); - AFC = t->afc_status & 0x0f; - - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC); - if (AFC == 0) return TUNER_TUNED; - else if (AFC <= 0x07)return TUNER_JUST_BELOW; - else if (AFC < 0x0f )return TUNER_JUST_ABOVE; - else if (AFC == 0x0f)return TUNER_TUNED; - } - else - { - I2C_WriteRead(&(f->d), NULL, 0, &out, 1); - AFC=out & 0x7; - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC); - if(AFC==2)return TUNER_TUNED; - if(AFC==3)return TUNER_JUST_BELOW; - if(AFC==1)return TUNER_JUST_ABOVE; - return TUNER_OFF; - } - return TUNER_OFF; -} - -static int MT2032_get_afc_hint(FI1236Ptr f) -{ -CARD8 in; -CARD8 out[2]; -CARD8 AFC; -in=0x0e; -I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2); -AFC=(out[0]>>4) & 0x7; -#if 0 -xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC=%d TAD1=%d TAD2=%d\n", AFC, out[1] & 0x7, (out[1]>>4)& 0x07); -#endif -if(AFC==2)return TUNER_TUNED; -if(AFC==3)return TUNER_JUST_BELOW; -if(AFC==1)return TUNER_JUST_ABOVE; -return TUNER_OFF; -} - -/* this function is for external use only */ -int TUNER_get_afc_hint(FI1236Ptr f) -{ -if(f->afc_timer_installed)return TUNER_STILL_TUNING; -return f->last_afc_hint; -} - -static void MT2032_dump_status(FI1236Ptr f) -{ -CARD8 in; -CARD8 out[2]; -CARD8 AFC; -CARD8 LDONrb; -CARD8 LO1LK, LO2LK, XOK; -CARD8 TAD2, TAD1; - -in=0x0e; -I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2); -XOK=out[0] & 1; -LO1LK=(out[0]>>2) &1; -LO2LK=(out[0]>>1) &1; -LDONrb=(out[0]>>3) &1; - -AFC=(out[0]>>4) & 0x7; - -TAD1=(out[1] & 0x7); -TAD2=(out[1]>>4) & 0x7; - -xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: XOK=%d LO1LK=%d LO2LK=%d LDONrb=%d AFC=%d TAD1=%d TAD2=%d\n", - XOK, LO1LK, LO2LK, LDONrb, AFC, TAD1, TAD2); -xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: OSCILLATOR:%s PLL1:%s PLL2:%s\n", - XOK ? "ok":"off", LO1LK ? "locked" : "off" , LO2LK ? "locked" : "off"); - -} - -static void MT2032_tune(FI1236Ptr f, double freq, double step) -{ -MT2032_parameters m; -CARD8 data[10]; -int i; -/* NTSC IF is 44mhz.. but 733/16=45.8125 and all TDAXXXX docs mention - 45.75, 39, 58.75 and 30. */ -#if 0 -MT2032_calculate_register_settings(&m, freq, 1090.0, 45.125, 5.25, 6.0, step); -MT2032_calculate_register_settings(&m, freq, 1090.0, 45.74, 5.25, 6.0, step); -#endif -MT2032_calculate_register_settings(&m, freq, 1090.0, f->video_if, 5.25, 3.0, step); -MT2032_dump_parameters(f, &m); -MT2032_implement_settings(f, &m); -/* MT2032_dump_parameters(f, &m); */ -for(i=0;i<3;i++){ - MT2032_optimize_VCO(f, &m); - if(MT2032_wait_for_lock(f)){ - data[0]=0x02; /* LO Gain control register 0x02 */ - data[1]=0x20; - I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0); - return; - } - data[0]=0x07; - data[1]=0x88|f->xogc; - I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0); - usleep(15000); - data[1]=0x08|f->xogc; - I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0); - } -xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n"); -} - -void FI1236_set_tuner_type(FI1236Ptr f, int type) -{ -f->type=type; -if(type>=NUM_TUNERS)type = NUM_TUNERS-1; -if(type<0)type = 0; -memcpy(&(f->parm), &(tuner_parms[type]), sizeof(FI1236_parameters)); -f->original_frequency=f->parm.min_freq; -f->afc_delta=0; -if(type==TUNER_TYPE_MT2032){ - MT2032_init(f); - return; - } -} - - -static CARD32 AFC_TimerCallback(OsTimerPtr timer, CARD32 time, pointer data){ -FI1236Ptr f=(FI1236Ptr)data; -if(FI1236_AFC(f))return 150; - else { - f->afc_timer_installed=FALSE; - f->afc_count=0; - return 0; - } -} - -void FI1236_tune(FI1236Ptr f, CARD32 frequency) -{ - CARD16 divider; - CARD8 data; - - if(frequency < f->parm.min_freq) frequency = f->parm.min_freq; - if(frequency > f->parm.max_freq) frequency = f->parm.max_freq; - - divider = (f->parm.fcar+(CARD16)frequency) & 0x7fff; - f->tuner_data.div1 = (CARD8)((divider>>8)&0x7f); - f->tuner_data.div2 = (CARD8)(divider & 0xff); - f->tuner_data.control = f->parm.control; - - if(frequency < f->parm.threshold1) - { - f->tuner_data.band = f->parm.band_low; - } - else if (frequency < f->parm.threshold2) - { - f->tuner_data.band = f->parm.band_mid; - } - else - { - f->tuner_data.band = f->parm.band_high; - } - - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner band to %d\n", f->tuner_data.band); - - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner frequency to %d\n", (int)frequency); - - if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W)) - { - f->tuner_data.aux = 0x20; - I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 5, NULL, 0); - I2C_WriteRead(&(f->d), NULL, 0, &data, 1); - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Tuner status %x\n", data); - - } - else - I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 4, NULL, 0); -} - -void TUNER_set_frequency(FI1236Ptr f, CARD32 frequency) -{ - if(frequency < f->parm.min_freq) frequency = f->parm.min_freq; - if(frequency > f->parm.max_freq) frequency = f->parm.max_freq; - - f->afc_delta=0; - f->original_frequency=frequency; - - if(f->type==TUNER_TYPE_MT2032) - { - MT2032_tune(f, (1.0*frequency)/16.0, 0.0625); - } else - { - FI1236_tune(f, frequency); - } - - if(!f->afc_timer_installed) - { - f->afc_timer_installed=TRUE; -/* RegisterBlockAndWakeupHandlers(FI1236_BlockHandler, AFCWakeup, f); */ - TimerSet(NULL, 0, 300, AFC_TimerCallback, f); - } - -} - - -int FI1236_AFC(FI1236Ptr f) -{ - #if 0 - 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); - #endif - f->afc_count++; - if(f->type==TUNER_TYPE_MT2032) - { - f->last_afc_hint=MT2032_get_afc_hint(f); - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: afc_hint=%d\n", f->last_afc_hint); - if(f->last_afc_hint==TUNER_TUNED)return 0; - if(f->afc_count>3)f->last_afc_hint=TUNER_OFF; - if(f->last_afc_hint==TUNER_OFF) - { - f->afc_delta=0; - } else - f->afc_delta+=f->last_afc_hint; - 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); - MT2032_tune(f, (1.0*f->original_frequency+0.5*f->afc_delta)/16.0, 0.03125); - if(f->last_afc_hint==TUNER_OFF)return 0; - return 1; /* call me again */ - } else - { - f->last_afc_hint=FI1236_get_afc_hint(f); - if(f->last_afc_hint==TUNER_TUNED) - { - xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: TUNER_TUNNED\n"); - return 0; - } - if(f->afc_count>3)f->last_afc_hint=TUNER_OFF; - if(f->last_afc_hint==TUNER_OFF) - { - f->afc_delta=0; - } else - f->afc_delta+=f->last_afc_hint; - 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); - FI1236_tune(f, f->original_frequency+f->afc_delta); - if(f->last_afc_hint==TUNER_OFF)return 0; - return 1; /* call me again */ - } - return 0; /* done */ -} - -void fi1236_dump_status(FI1236Ptr f) -{ -if(f->type==TUNER_TYPE_MT2032){ - MT2032_dump_status(f); - } -} +
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "xf86.h"
+#include "xf86i2c.h"
+#include "fi1236.h"
+#include "tda9885.h"
+#include "i2c_def.h"
+
+#define NUM_TUNERS 8
+
+const FI1236_parameters tuner_parms[NUM_TUNERS] =
+{
+ /* 0 - FI1236 */
+ { 733 ,884 ,12820 ,2516 ,7220 ,0xA2 ,0x94, 0x34, 0x8e },
+ /* !!!based on documentation - it should be:
+ {733 ,16*55.25 ,16*801.25 ,16*160 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e},*/
+
+ /* 1 - FI1216 */
+ { 623 ,16*48.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
+ /* 2 - TEMIC FN5AL */
+ { 623 ,16*45.75 ,16*855.25 ,16*169 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e },
+ /* 3 - MT2032.. */
+ { 733 ,768 ,13760 , 0 , 0 , 0 , 0, 0, 0 },
+ /* 4 - FI1246 */
+ { 623 ,16*45.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
+ /* 5 - FI1256 */
+ { 623 ,16*49.75 ,16*863.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
+ /* 6 - FI1236W */
+ /*{ 733 ,884 ,12820 ,2516 ,7220 ,0x1 ,0x2, 0x4, 0x8e },*/
+ { 732, 16*55.25, 16*801.25, 16*160, 16*442, 0x1, 0x2, 0x4, 0x8e },
+ /* 7 - FM1216ME */
+ { 623 ,16*48.25 ,16*863.25 ,16*158.00 ,16*442.00 ,0x1 ,0x2, 0x4, 0x8e }
+};
+
+
+FI1236Ptr Detect_FI1236(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ FI1236Ptr f;
+ I2CByte a;
+
+ f = calloc(1,sizeof(FI1236Rec));
+ if(f == NULL) return NULL;
+ f->d.DevName = strdup("FI12xx Tuner");
+ f->d.SlaveAddr = addr;
+ f->d.pI2CBus = b;
+ f->d.NextDev = NULL;
+ f->d.StartTimeout = b->StartTimeout;
+ f->d.BitTimeout = b->BitTimeout;
+ f->d.AcknTimeout = b->AcknTimeout;
+ f->d.ByteTimeout = b->ByteTimeout;
+ f->type=TUNER_TYPE_FI1236;
+ f->afc_timer_installed=FALSE;
+ f->last_afc_hint=TUNER_OFF;
+ f->video_if=45.7812;
+
+ if(!I2C_WriteRead(&(f->d), NULL, 0, &a, 1))
+ {
+ free(f);
+ return NULL;
+ }
+ FI1236_set_tuner_type(f, TUNER_TYPE_FI1236);
+ if(!I2CDevInit(&(f->d)))
+ {
+ free(f);
+ return NULL;
+ }
+ return f;
+}
+
+static void MT2032_dump_parameters(FI1236Ptr f, MT2032_parameters *m)
+{
+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",
+ m->f_rf, m->f_if1, m->f_if2, m->f_ref, m->f_ifbw, m->f_step);
+
+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",
+ m->f_lo1, m->f_lo2, m->LO1I, m->LO2I, m->SEL, m->STEP, m->NUM);
+}
+
+
+static void MT2032_getid(FI1236Ptr f)
+{
+CARD8 out[4];
+CARD8 in;
+
+in=0x11;
+I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 4);
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: Company code 0x%02x%02x, part code 0x%02x, revision code 0x%02x\n",
+ out[0], out[1], out[2], out[3]);
+
+}
+
+/* might be buggy */
+#if 0
+static void MT2032_shutdown(FI1236Ptr f)
+{
+CARD8 data[10];
+
+data[0]=0x00; /* start with register 0x00 */
+data[1]=0x1A;
+data[2]=0x44;
+data[3]=0x20;
+
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+data[0]=0x05; /* now start with register 0x05 */
+data[1]=0xD7;
+data[2]=0x14;
+data[3]=0x05;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+data[0]=0x0B; /* now start with register 0x05 */
+data[1]=0x8F;
+data[2]=0x07;
+data[3]=0x43;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+usleep(15000);
+}
+#endif
+
+static void MT2032_dump_status(FI1236Ptr f);
+
+static void MT2032_init(FI1236Ptr f)
+{
+CARD8 data[10];
+CARD8 value;
+CARD8 xogc = 0x00;
+
+MT2032_getid(f);
+
+data[0]=0x02; /* start with register 0x02 */
+data[1]=0xFF;
+data[2]=0x0F;
+data[3]=0x1F;
+
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+data[0]=0x06; /* now start with register 0x06 */
+data[1]=0xE4;
+data[2]=0x8F;
+data[3]=0xC3;
+data[4]=0x4E;
+data[5]=0xEC;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 6, NULL, 0);
+
+data[0]=0x0d; /* now start with register 0x0d */
+data[1]=0x32;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+
+while(1) {
+ usleep(15000); /* wait 15 milliseconds */
+
+ data[0]=0x0e; /* register number 7, status */
+ value=0xFF;
+ if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1))
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOK\n");
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: XOK=%d\n", value & 0x01);
+ if(value & 1) break;
+
+ data[0]=0x07;
+ if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1))
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOGC\n");
+
+ xogc=value & 0x7;
+ if(xogc==4){
+ break; /* XOGC has reached 4.. stop */
+ }
+ xogc--;
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: try XOGC=%d\n", xogc);
+ usleep(15000);
+ data[0]=0x07; /* register number 7, control byte 2 */
+ data[1]=0x08 | xogc;
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+ }
+f->xogc=xogc;
+/* wait before continuing */
+usleep(15000); /* wait 50 milliseconds */
+MT2032_dump_status(f);
+}
+
+static int MT2032_no_spur_in_band(MT2032_parameters *m)
+{
+int n_max, n1, n2;
+double f_test;
+n_max=5;
+n1=1;
+while(1){
+ n2=-n1;
+ f_test=n1*(m->f_lo1-m->f_lo2);
+ while(1){
+ n2--;
+ f_test=f_test-m->f_lo2;
+ 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);
+ xf86DrvMsg(0, X_INFO, "d_f=%g f_ifbw=%g\n",fabs(fabs(f_test)-m->f_if2), m->f_ifbw);
+ if((fabs(fabs(f_test)-m->f_if2)*2.0)<=m->f_ifbw)return 0;
+ if(n2<=-n_max)break;
+ /* this line in the manual is bogus. I say it is faster
+ and more correct to go over all harmonics.. */
+ #if 0
+ if(f_test<(m->f_lo2-m->f_if2-m->f_ifbw))break;
+ #endif
+ }
+ n1++;
+ if(n1>=n_max)return 1;
+ }
+
+}
+
+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)
+{
+int n;
+m->f_rf=f_rf;
+m->f_if1=f_if1;
+m->f_if2=f_if2;
+m->f_ref=f_ref;
+m->f_ifbw=f_ifbw;
+m->f_step=f_step;
+
+m->f_lo1=f_rf+f_if1;
+m->LO1I=lrint(m->f_lo1/f_ref);
+m->f_lo1=f_ref*m->LO1I;
+
+m->f_lo2=m->f_lo1-f_rf-f_if2;
+
+/* check for spurs */
+n=1;
+while(n<3){
+ if(MT2032_no_spur_in_band(m))break;
+ if(m->f_lo1<(f_rf+f_if1)){
+ m->LO1I+=n;
+ } else {
+ m->LO1I-=n;
+ }
+ m->f_lo1=m->LO1I*f_ref;
+ m->f_lo2=m->f_lo1-f_rf-f_if2;
+ n++;
+ }
+/* xf86DrvMsg(0, X_INFO, "MT2032: n=%d\n", n); */
+/* select VCO */
+
+/* m->f_lo1>1100.0 */
+if(m->f_lo1<1370.0)m->SEL=4;
+ else
+if(m->f_lo1<1530.0)m->SEL=3;
+ else
+if(m->f_lo1<1720.0)m->SEL=2;
+ else
+if(m->f_lo1<1890.0)m->SEL=1;
+ else /* m->f_lo1 < 1958.0 */
+ m->SEL=0;
+
+/* calculate the rest of the registers */
+m->LO2I=floor(m->f_lo2/f_ref);
+m->STEP=floor(3780.0*f_step/f_ref);
+m->NUM=floor(3780.0*(m->f_lo2/f_ref-m->LO2I));
+m->NUM=m->STEP*lrint((1.0*m->NUM)/(1.0*m->STEP));
+}
+
+static int MT2032_wait_for_lock(FI1236Ptr f)
+{
+int n;
+CARD8 data[10];
+CARD8 value;
+
+n=12;
+while(1){
+ data[0]=0x0e; /* register number 7, status */
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
+/* xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: LO1LK=%d LO2LK=%d\n", (value & 0x04)>>2, (value & 0x02)>>1); */
+ if((value & 6)==6) break;
+ usleep(1500);
+ n--;
+ if(n<0)break;
+ }
+if(n<0){
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n");
+ return 0;
+ }
+return 1;
+}
+
+static void MT2032_implement_settings(FI1236Ptr f, MT2032_parameters *m)
+{
+CARD8 data[10];
+CARD8 value;
+
+data[0]=0x00; /* start with register 0x00 */
+data[1]=(m->LO1I>>3)-1;
+data[2]=(m->SEL<<4)|(m->LO1I & 0x7);
+data[3]=0x86;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+data[0]=0x05; /* start with register 0x05 */
+data[1]=((m->LO2I & 0x7)<<5)|((m->LO2I>>3)-1);
+if(m->f_rf<400.0)data[2]=0xe4;
+ else data[2]=0xf4;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0);
+
+data[0]=0x07; /* register number 7, control byte 2 */
+I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: using XOGC=%d\n", (value & 0x07));
+data[1]=8 | (value & 0x7);
+I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+
+data[0]=0x0b; /* start with register 0x0b */
+data[1]=m->NUM & 0xff;
+data[2]=(1<<7)|((m->NUM >> 8) & 0x0f);
+I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0);
+
+MT2032_wait_for_lock(f);
+}
+
+static void MT2032_optimize_VCO(FI1236Ptr f, MT2032_parameters *m)
+{
+CARD8 data[10];
+CARD8 value;
+CARD8 TAD1;
+
+data[0]=0x0f; /* register number 7, status */
+I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
+TAD1=value & 0x07;
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: TAD1=%d SEL=%d\n", TAD1, m->SEL);
+if(TAD1 < 2)return;
+if(TAD1==2){
+ if(m->SEL==0)return;
+ m->SEL--;
+ } else {
+ if(m->SEL>=4)return;
+ m->SEL++;
+ }
+data[0]=0x01; /* start with register 1 */
+data[1]=(m->SEL<<4)|(m->LO1I & 0x7);
+I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+
+}
+
+static int FI1236_get_afc_hint(FI1236Ptr f)
+{
+ CARD8 out;
+ CARD8 AFC;
+
+ if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W))
+ {
+ TDA9885Ptr t = (TDA9885Ptr)f->afc_source;
+ if (t == NULL)
+ return TUNER_OFF;
+
+ tda9885_getstatus(t);
+ tda9885_dumpstatus(t);
+ AFC = t->afc_status & 0x0f;
+
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC);
+ if (AFC == 0) return TUNER_TUNED;
+ else if (AFC <= 0x07)return TUNER_JUST_BELOW;
+ else if (AFC < 0x0f )return TUNER_JUST_ABOVE;
+ else if (AFC == 0x0f)return TUNER_TUNED;
+ }
+ else
+ {
+ I2C_WriteRead(&(f->d), NULL, 0, &out, 1);
+ AFC=out & 0x7;
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC);
+ if(AFC==2)return TUNER_TUNED;
+ if(AFC==3)return TUNER_JUST_BELOW;
+ if(AFC==1)return TUNER_JUST_ABOVE;
+ return TUNER_OFF;
+ }
+ return TUNER_OFF;
+}
+
+static int MT2032_get_afc_hint(FI1236Ptr f)
+{
+CARD8 in;
+CARD8 out[2];
+CARD8 AFC;
+in=0x0e;
+I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2);
+AFC=(out[0]>>4) & 0x7;
+#if 0
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC=%d TAD1=%d TAD2=%d\n", AFC, out[1] & 0x7, (out[1]>>4)& 0x07);
+#endif
+if(AFC==2)return TUNER_TUNED;
+if(AFC==3)return TUNER_JUST_BELOW;
+if(AFC==1)return TUNER_JUST_ABOVE;
+return TUNER_OFF;
+}
+
+/* this function is for external use only */
+int TUNER_get_afc_hint(FI1236Ptr f)
+{
+if(f->afc_timer_installed)return TUNER_STILL_TUNING;
+return f->last_afc_hint;
+}
+
+static void MT2032_dump_status(FI1236Ptr f)
+{
+CARD8 in;
+CARD8 out[2];
+CARD8 AFC;
+CARD8 LDONrb;
+CARD8 LO1LK, LO2LK, XOK;
+CARD8 TAD2, TAD1;
+
+in=0x0e;
+I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2);
+XOK=out[0] & 1;
+LO1LK=(out[0]>>2) &1;
+LO2LK=(out[0]>>1) &1;
+LDONrb=(out[0]>>3) &1;
+
+AFC=(out[0]>>4) & 0x7;
+
+TAD1=(out[1] & 0x7);
+TAD2=(out[1]>>4) & 0x7;
+
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: XOK=%d LO1LK=%d LO2LK=%d LDONrb=%d AFC=%d TAD1=%d TAD2=%d\n",
+ XOK, LO1LK, LO2LK, LDONrb, AFC, TAD1, TAD2);
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: OSCILLATOR:%s PLL1:%s PLL2:%s\n",
+ XOK ? "ok":"off", LO1LK ? "locked" : "off" , LO2LK ? "locked" : "off");
+
+}
+
+static void MT2032_tune(FI1236Ptr f, double freq, double step)
+{
+MT2032_parameters m;
+CARD8 data[10];
+int i;
+/* NTSC IF is 44mhz.. but 733/16=45.8125 and all TDAXXXX docs mention
+ 45.75, 39, 58.75 and 30. */
+#if 0
+MT2032_calculate_register_settings(&m, freq, 1090.0, 45.125, 5.25, 6.0, step);
+MT2032_calculate_register_settings(&m, freq, 1090.0, 45.74, 5.25, 6.0, step);
+#endif
+MT2032_calculate_register_settings(&m, freq, 1090.0, f->video_if, 5.25, 3.0, step);
+MT2032_dump_parameters(f, &m);
+MT2032_implement_settings(f, &m);
+/* MT2032_dump_parameters(f, &m); */
+for(i=0;i<3;i++){
+ MT2032_optimize_VCO(f, &m);
+ if(MT2032_wait_for_lock(f)){
+ data[0]=0x02; /* LO Gain control register 0x02 */
+ data[1]=0x20;
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+ return;
+ }
+ data[0]=0x07;
+ data[1]=0x88|f->xogc;
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+ usleep(15000);
+ data[1]=0x08|f->xogc;
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+ }
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n");
+}
+
+void FI1236_set_tuner_type(FI1236Ptr f, int type)
+{
+f->type=type;
+if(type>=NUM_TUNERS)type = NUM_TUNERS-1;
+if(type<0)type = 0;
+memcpy(&(f->parm), &(tuner_parms[type]), sizeof(FI1236_parameters));
+f->original_frequency=f->parm.min_freq;
+f->afc_delta=0;
+if(type==TUNER_TYPE_MT2032){
+ MT2032_init(f);
+ return;
+ }
+}
+
+
+static CARD32 AFC_TimerCallback(OsTimerPtr timer, CARD32 time, pointer data){
+FI1236Ptr f=(FI1236Ptr)data;
+if(FI1236_AFC(f))return 150;
+ else {
+ f->afc_timer_installed=FALSE;
+ f->afc_count=0;
+ return 0;
+ }
+}
+
+void FI1236_tune(FI1236Ptr f, CARD32 frequency)
+{
+ CARD16 divider;
+ CARD8 data;
+
+ if(frequency < f->parm.min_freq) frequency = f->parm.min_freq;
+ if(frequency > f->parm.max_freq) frequency = f->parm.max_freq;
+
+ divider = (f->parm.fcar+(CARD16)frequency) & 0x7fff;
+ f->tuner_data.div1 = (CARD8)((divider>>8)&0x7f);
+ f->tuner_data.div2 = (CARD8)(divider & 0xff);
+ f->tuner_data.control = f->parm.control;
+
+ if(frequency < f->parm.threshold1)
+ {
+ f->tuner_data.band = f->parm.band_low;
+ }
+ else if (frequency < f->parm.threshold2)
+ {
+ f->tuner_data.band = f->parm.band_mid;
+ }
+ else
+ {
+ f->tuner_data.band = f->parm.band_high;
+ }
+
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner band to %d\n", f->tuner_data.band);
+
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner frequency to %d\n", (int)frequency);
+
+ if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W))
+ {
+ f->tuner_data.aux = 0x20;
+ I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 5, NULL, 0);
+ I2C_WriteRead(&(f->d), NULL, 0, &data, 1);
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Tuner status %x\n", data);
+
+ }
+ else
+ I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 4, NULL, 0);
+}
+
+void TUNER_set_frequency(FI1236Ptr f, CARD32 frequency)
+{
+ if(frequency < f->parm.min_freq) frequency = f->parm.min_freq;
+ if(frequency > f->parm.max_freq) frequency = f->parm.max_freq;
+
+ f->afc_delta=0;
+ f->original_frequency=frequency;
+
+ if(f->type==TUNER_TYPE_MT2032)
+ {
+ MT2032_tune(f, (1.0*frequency)/16.0, 0.0625);
+ } else
+ {
+ FI1236_tune(f, frequency);
+ }
+
+ if(!f->afc_timer_installed)
+ {
+ f->afc_timer_installed=TRUE;
+/* RegisterBlockAndWakeupHandlers(FI1236_BlockHandler, AFCWakeup, f); */
+ TimerSet(NULL, 0, 300, AFC_TimerCallback, f);
+ }
+
+}
+
+
+int FI1236_AFC(FI1236Ptr f)
+{
+ #if 0
+ 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);
+ #endif
+ f->afc_count++;
+ if(f->type==TUNER_TYPE_MT2032)
+ {
+ f->last_afc_hint=MT2032_get_afc_hint(f);
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: afc_hint=%d\n", f->last_afc_hint);
+ if(f->last_afc_hint==TUNER_TUNED)return 0;
+ if(f->afc_count>3)f->last_afc_hint=TUNER_OFF;
+ if(f->last_afc_hint==TUNER_OFF)
+ {
+ f->afc_delta=0;
+ } else
+ f->afc_delta+=f->last_afc_hint;
+ 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);
+ MT2032_tune(f, (1.0*f->original_frequency+0.5*f->afc_delta)/16.0, 0.03125);
+ if(f->last_afc_hint==TUNER_OFF)return 0;
+ return 1; /* call me again */
+ } else
+ {
+ f->last_afc_hint=FI1236_get_afc_hint(f);
+ if(f->last_afc_hint==TUNER_TUNED)
+ {
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: TUNER_TUNNED\n");
+ return 0;
+ }
+ if(f->afc_count>3)f->last_afc_hint=TUNER_OFF;
+ if(f->last_afc_hint==TUNER_OFF)
+ {
+ f->afc_delta=0;
+ } else
+ f->afc_delta+=f->last_afc_hint;
+ 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);
+ FI1236_tune(f, f->original_frequency+f->afc_delta);
+ if(f->last_afc_hint==TUNER_OFF)return 0;
+ return 1; /* call me again */
+ }
+ return 0; /* done */
+}
+
+void fi1236_dump_status(FI1236Ptr f)
+{
+if(f->type==TUNER_TYPE_MT2032){
+ MT2032_dump_status(f);
+ }
+}
|