diff --git a/drivers/media/tuners/r850.c b/drivers/media/tuners/r850.c index 5898a4b82587..d502e3ceb0d1 100644 --- a/drivers/media/tuners/r850.c +++ b/drivers/media/tuners/r850.c @@ -1,3261 +1,3261 @@ -#include -#include "r850.h" -#include "r850_priv.h" - -static int r850_rd(struct r850_priv *priv,u8 reg, u8 *buf,u8 len) -{ - int ret,i; - - struct i2c_msg msg[2]={ - { - .addr = priv->cfg->i2c_address, - .flags = 0, .buf = ®, .len = 1 - },{ - .addr = priv->cfg->i2c_address, - .flags = I2C_M_RD, .buf = buf, .len = len - } - }; - ret = i2c_transfer(priv->i2c, msg, 2); - if (ret == 2) { - for (i = 0; i < len; i++) - buf[i] = bitrev8(buf[i]); - ret = 0; - } else { - dev_warn(&priv->i2c->dev, "%s: i2c tuner rd failed=%d " \ - "len=%d\n", KBUILD_MODNAME, ret, len); - ret = -EREMOTEIO; - } - return ret; - -} -static int r850_wrm(struct r850_priv *priv,u8 reg, u8 *val,u8 len) -{ - int ret; - u8 buf[len + 1]; - - memcpy(&buf[1], val, len); - buf[0] = reg; - - struct i2c_msg msg = { - .addr = priv->cfg->i2c_address, - .flags = 0, .buf = buf, .len = len + 1 }; - - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret == 1) { - ret = 0; - } else { - dev_warn(&priv->i2c->dev, "%s: i2c tuner wr failed=%d " \ - "len=%d\n", KBUILD_MODNAME, ret, len); - ret = -EREMOTEIO; - } - return ret; - -} -static int r850_wr(struct r850_priv *priv,u8 reg, u8 val) -{ - return r850_wrm(priv,reg,&val,1); -} -struct R850_Freq_Info_Type R850_Freq_Sel(u32 LO_freq, u32 RF_freq, enum R850_Standard_Type R850_Standard) -{ - struct R850_Freq_Info_Type R850_Freq_Info; - - - //----- LO dependent parameter -------- - - //IMR point - if((LO_freq>0) && (LO_freq<170000)) - { - R850_Freq_Info.IMR_MEM_NOR = 0; - R850_Freq_Info.IMR_MEM_REV = 5; - } - else if((LO_freq>=170000) && (LO_freq<240000)) - { - R850_Freq_Info.IMR_MEM_NOR = 4; - R850_Freq_Info.IMR_MEM_REV = 9; - } - else if((LO_freq>=240000) && (LO_freq<400000)) - { - R850_Freq_Info.IMR_MEM_NOR = 1; - R850_Freq_Info.IMR_MEM_REV = 6; - } - else if((LO_freq>=400000) && (LO_freq<760000)) - { - R850_Freq_Info.IMR_MEM_NOR = 2; - R850_Freq_Info.IMR_MEM_REV = 7; - } - else - { - R850_Freq_Info.IMR_MEM_NOR = 3; - R850_Freq_Info.IMR_MEM_REV = 8; - } - - //TF_HPF_BPF R16[2:0] - /* 7-lowest:111 ; 6:011 ; 5:101 ; 4:001 ; 3:110 ; 2:010 ; 1:100 ; 0-noBPF:000 */ - if(LO_freq<580000) - R850_Freq_Info.TF_HPF_BPF = 0x07; //7 => 111:lowset BPF R16[2:0] - else if(LO_freq>=580000 && LO_freq<660000) - R850_Freq_Info.TF_HPF_BPF = 0x01; //4 => 001 - else if(LO_freq>=660000 && LO_freq<780000) - R850_Freq_Info.TF_HPF_BPF = 0x06; //3 => 110 - else if(LO_freq>=780000 && LO_freq<900000) - R850_Freq_Info.TF_HPF_BPF = 0x04; //1 => 100 - else - R850_Freq_Info.TF_HPF_BPF = 0x00; //0 => 000 - - /* -00: highest band -01: med band -10: low band -11: Ultrawide band -*/ - //RF polyfilter band - if((LO_freq>0) && (LO_freq<133000)) - R850_Freq_Info.RF_POLY = 2; //R17[6:5]=2; low => R18[1:0] - else if((LO_freq>=133000) && (LO_freq<221000)) - R850_Freq_Info.RF_POLY = 1; //R17[6:5]=1; mid => R18[1:0] - else if((LO_freq>=221000) && (LO_freq<760000)) - R850_Freq_Info.RF_POLY = 0; //R17[6:5]=0; highest => R18[1:0] - else - R850_Freq_Info.RF_POLY = 3; //R17[6:5]=3; ultra high => R18[1:0] - - - /* -00: highest -01: high -10: low -11: lowest -*/ - //TF_HPF_Corner - if((LO_freq>0) && (LO_freq<480000)) - R850_Freq_Info.TF_HPF_CNR = 3; //lowest => R16[4:3] - else if((LO_freq>=480000) && (LO_freq<550000)) - R850_Freq_Info.TF_HPF_CNR = 2; // low => R16[4:3] - else if((LO_freq>=550000) && (LO_freq<700000)) - R850_Freq_Info.TF_HPF_CNR = 1; // high => R16[4:3] - else - R850_Freq_Info.TF_HPF_CNR = 0; //highest => R16[4:3] - - - //LPF Cap, Notch - switch(R850_Standard) - { - case R850_DVB_C_8M: //Cable - case R850_DVB_C_6M: - case R850_J83B: - case R850_DVB_C_8M_IF_5M: - case R850_DVB_C_6M_IF_5M: - case R850_J83B_IF_5M: - if(LO_freq<77000) - { - R850_Freq_Info.LPF_CAP = 15; - R850_Freq_Info.LPF_NOTCH = 10; - } - else if((LO_freq>=77000) && (LO_freq<85000)) - { - R850_Freq_Info.LPF_CAP = 15; - R850_Freq_Info.LPF_NOTCH = 4; - } - else if((LO_freq>=85000) && (LO_freq<115000)) - { - R850_Freq_Info.LPF_CAP = 13; - R850_Freq_Info.LPF_NOTCH = 3; - } - else if((LO_freq>=115000) && (LO_freq<125000)) - { - R850_Freq_Info.LPF_CAP = 11; - R850_Freq_Info.LPF_NOTCH = 1; - } - else if((LO_freq>=125000) && (LO_freq<141000)) - { - R850_Freq_Info.LPF_CAP = 9; - R850_Freq_Info.LPF_NOTCH = 0; - } - else if((LO_freq>=141000) && (LO_freq<157000)) - { - R850_Freq_Info.LPF_CAP = 8; - R850_Freq_Info.LPF_NOTCH = 0; - } - else if((LO_freq>=157000) && (LO_freq<181000)) - { - R850_Freq_Info.LPF_CAP = 6; - R850_Freq_Info.LPF_NOTCH = 0; - } - else if((LO_freq>=181000) && (LO_freq<205000)) - { - R850_Freq_Info.LPF_CAP = 3; - R850_Freq_Info.LPF_NOTCH = 0; - } - else //LO>=201M - { - R850_Freq_Info.LPF_CAP = 0; - R850_Freq_Info.LPF_NOTCH = 0; - } - //Diplexer Select R14[3:2] - if(LO_freq<330000) - R850_Freq_Info.TF_DIPLEXER = 2; //LPF R14[3:2] - else - R850_Freq_Info.TF_DIPLEXER = 0; //HPF - - - break; - - default: //Air, DTMB (for 180nH) - if((LO_freq>0) && (LO_freq<73000)) - { - R850_Freq_Info.LPF_CAP = 8; - R850_Freq_Info.LPF_NOTCH = 10; - } - else if((LO_freq>=73000) && (LO_freq<81000)) - { - R850_Freq_Info.LPF_CAP = 8; - R850_Freq_Info.LPF_NOTCH = 4; - } - else if((LO_freq>=81000) && (LO_freq<89000)) - { - R850_Freq_Info.LPF_CAP = 8; - R850_Freq_Info.LPF_NOTCH = 3; - } - else if((LO_freq>=89000) && (LO_freq<121000)) - { - R850_Freq_Info.LPF_CAP = 6; - R850_Freq_Info.LPF_NOTCH = 1; - } - else if((LO_freq>=121000) && (LO_freq<145000)) - { - R850_Freq_Info.LPF_CAP = 4; - R850_Freq_Info.LPF_NOTCH = 0; - } - else if((LO_freq>=145000) && (LO_freq<153000)) - { - R850_Freq_Info.LPF_CAP = 3; - R850_Freq_Info.LPF_NOTCH = 0; - } - else if((LO_freq>=153000) && (LO_freq<177000)) - { - R850_Freq_Info.LPF_CAP = 2; - R850_Freq_Info.LPF_NOTCH = 0; - } - else if((LO_freq>=177000) && (LO_freq<201000)) - { - R850_Freq_Info.LPF_CAP = 1; - R850_Freq_Info.LPF_NOTCH = 0; - } - else //LO>=201M - { - R850_Freq_Info.LPF_CAP = 0; - R850_Freq_Info.LPF_NOTCH = 0; - } - //Diplexer Select R14[3:2] - if(LO_freq<340000) - R850_Freq_Info.TF_DIPLEXER = 2; //LPF R14[3:2] - else - R850_Freq_Info.TF_DIPLEXER = 0; //HPF - break; - - }//end switch(standard) - - - return R850_Freq_Info; - -} - -struct R850_SysFreq_Info_Type R850_SysFreq_NrbDetOn_Sel(enum R850_Standard_Type R850_Standard,u32 RF_freq) -{ - - struct R850_SysFreq_Info_Type R850_SysFreq_Info; - - switch(R850_Standard) - { - case R850_DTMB_8M_4570: - case R850_DTMB_6M_4500: - case R850_DTMB_8M_IF_5M: - case R850_DTMB_6M_IF_5M: - if(RF_freq<=100000) - { - //LNA - R850_SysFreq_Info.LNA_VTL_H=0x6B; //R39[7:0] LNA VTL/H = 0.94(6) / 1.44(B) - - //NRB - R850_SysFreq_Info.NRB_TOP=10; //R40[7:4] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] - R850_SysFreq_Info.NRB_BW_LPF=3; //R26[7:6] [widest (0), wide (1), low (2), lowest (3)] - R850_SysFreq_Info.NRB_BW_HPF=3; //R26[3:2] [lowest (0), low (1), high (2), highest (3)] - R850_SysFreq_Info.IMG_NRB_ADDER=1; //R46[3:2] ["original" (0), "top+6" (1), "top+9" (2), "top+11" (3)] - - //Filter - R850_SysFreq_Info.FILT_3TH_LPF_GAIN=0; //R24[1:0] [normal (0), +1.5dB (1), +3dB (2), +4.5dB (3)] - } - else if(RF_freq<=340000) - { - //LNA - R850_SysFreq_Info.LNA_VTL_H=0x6B; //R39[7:0] LNA VTL/H = 0.94(6) / 1.44(B) - - //NRB - R850_SysFreq_Info.NRB_TOP=10; //R40[7:4] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] - R850_SysFreq_Info.NRB_BW_LPF=2; //R26[7:6] [widest (0), wide (1), low (2), lowest (3)] - R850_SysFreq_Info.NRB_BW_HPF=3; //R26[3:2] [lowest (0), low (1), high (2), highest (3)] - R850_SysFreq_Info.IMG_NRB_ADDER=1; //R46[3:2] ["original" (0), "top+6" (1), "top+9" (2), "top+11" (3)] - - //Filter - R850_SysFreq_Info.FILT_3TH_LPF_GAIN=0; //R24[1:0] [normal (0), +1.5dB (1), +3dB (2), +4.5dB (3)] - } - else - { - //LNA - R850_SysFreq_Info.LNA_VTL_H=0x5A; //R39[7:0] LNA VTL/H = 0.84(5) / 1.34(A) - - //NRB - R850_SysFreq_Info.NRB_TOP=6; //R40[7:4] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] - R850_SysFreq_Info.NRB_BW_LPF=2; //R26[7:6] [widest (0), wide (1), low (2), lowest (3)] - R850_SysFreq_Info.NRB_BW_HPF=2; //R26[3:2] [lowest (0), low (1), high (2), highest (3)] - R850_SysFreq_Info.IMG_NRB_ADDER=0; //R46[3:2] ["original" (0), "top+6" (1), "top+9" (2), "top+11" (3)] - - //Filter - R850_SysFreq_Info.FILT_3TH_LPF_GAIN=3; //R24[1:0] [normal (0), +1.5dB (1), +3dB (2), +4.5dB (3)] - } - - //PW - R850_SysFreq_Info.NA_PWR_DET = 0; //R10[6] ["off" (0), "on" (1)] - R850_SysFreq_Info.LNA_NRB_DET=0; //R11[7] ["on" (0), "off" (1)] - - //LNA - R850_SysFreq_Info.LNA_TOP=4; //R38[2:0] ["7~0" (0~7) ; input: "7~0"] - R850_SysFreq_Info.RF_LTE_PSG=1; //R17[4] ["no psg" (0), "7.5dB(5~8)" (1)] - - - //RFBuf - R850_SysFreq_Info.RF_TOP=4; //R38[6:4] ["7~0" (0~7) ; input: "7~0"] - R850_SysFreq_Info.RF_VTL_H=0x4A; //R42[7:0] RF VTL/H = 0.74(4) / 1.34(A) - R850_SysFreq_Info.RF_GAIN_LIMIT=0; //MSB R18[2], LSB R16[6] ["max =15" (0), "max =11" (1), "max =13" (2), "max =9" (3)] - - //Mixer and Mixamp - R850_SysFreq_Info.MIXER_AMP_LPF = 4; //R19[2:0] ["normal (widest)" (0), "1" (1), "2" (2), "3" (3), "4" (4), "5" (5), "6" (6), "narrowest" (7)] - R850_SysFreq_Info.MIXER_TOP=9; //R40[3:0] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] - R850_SysFreq_Info.MIXER_VTH=0x09; //R41[3:0] 1.24 (9) - R850_SysFreq_Info.MIXER_VTL=0x04; //R43[3:0] 0.74 (4) - R850_SysFreq_Info.MIXER_GAIN_LIMIT=1; //R22[7:6] ["max=6" (0), "max=8" (1), "max=10" (2), "max=12" (3)] - R850_SysFreq_Info.MIXER_DETBW_LPF =0; //R46[7] ["normal" (0), "enhance amp det LPF" (1)] - - //Filter - R850_SysFreq_Info.FILTER_TOP=4; //R44[3:0] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] - R850_SysFreq_Info.FILTER_VTH=0x90; //R41[7:4] 1.24 (9) - R850_SysFreq_Info.FILTER_VTL=0x40; //R43[7:4] 0.74 (4) - R850_SysFreq_Info.FILT_3TH_LPF_CUR=0; //R10[4] [high (0), low (1)] - - - //Discharge - R850_SysFreq_Info.LNA_RF_DIS_MODE=1; //Both (fast+slow) (R45[1:0]=0'b00; R31[0]=1 ;R32[5]=1) : 1111 Both (fast+slow) case 1 - R850_SysFreq_Info.LNA_RF_CHARGE_CUR=1; //R31[1] ["6x chargeI" (0), "4x chargeI" (1)] - R850_SysFreq_Info.LNA_RF_DIS_CURR=1; //R13[5] ["1/3 dis current" (0), "normal" (1)] - R850_SysFreq_Info.RF_DIS_SLOW_FAST=5; //R45[7:4] 0.3u (1) / 0.9u (4) - R850_SysFreq_Info.LNA_DIS_SLOW_FAST=9; //R44[7:4] 0.3u (1) / 1.5u (8) => 1 + 8 = 9 - R850_SysFreq_Info.BB_DIS_CURR=0; //R25[6] ["x1" (0) , "x1/2" (1)] - R850_SysFreq_Info.MIXER_FILTER_DIS=2; //R37[7:6] ["highest" (0), "high" (1), "low" (2), "lowest" (3)] - R850_SysFreq_Info.BB_DET_MODE=0; //R37[2] ["peak" (0), "average" (1)] - - //Polyphase - R850_SysFreq_Info.ENB_POLY_GAIN=0; //R25[1]=0 original ["original" (0), "ctrl by mixamp (>10)" (1)] - - //VGA - R850_SysFreq_Info.HPF_COMP=0; //R13[2:1] ["normal" (0) , "+1.5dB" (1), "+3dB" (2), "+4dB" (3)] - R850_SysFreq_Info.FB_RES_1ST=0; //R21[4] ["2K" (0) , "8K" (1)] - - break; - - default: //DVB-T - //PW - R850_SysFreq_Info.NA_PWR_DET = 0; //R10[6] ["off" (0), "on" (1)] - R850_SysFreq_Info.LNA_NRB_DET=0; //R11[7] ["on" (0), "off" (1)] - - //LNA - R850_SysFreq_Info.LNA_TOP=4; //R38[2:0] ["7~0" (0~7) ; input: "7~0"] - R850_SysFreq_Info.LNA_VTL_H=0x5A; //R39[7:0] LNA VTL/H = 0.84(5) / 1.34(A) - R850_SysFreq_Info.RF_LTE_PSG=1; //R17[4] ["no psg" (0), "7.5dB(5~8)" (1)] - - - //RFBuf - R850_SysFreq_Info.RF_TOP=4; //R38[6:4] ["7~0" (0~7) ; input: "7~0"] - R850_SysFreq_Info.RF_VTL_H=0x4A; //R42[7:0] RF VTL/H = 0.74(4) / 1.34(A) - R850_SysFreq_Info.RF_GAIN_LIMIT=0; //MSB R18[2], LSB R16[6] ["max =15" (0), "max =11" (1), "max =13" (2), "max =9" (3)] - - //Mixer and Mixamp - R850_SysFreq_Info.MIXER_AMP_LPF = 4; //R19[2:0] ["normal (widest)" (0), "1" (1), "2" (2), "3" (3), "4" (4), "5" (5), "6" (6), "narrowest" (7)] - R850_SysFreq_Info.MIXER_TOP=9; //R40[3:0] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] - R850_SysFreq_Info.MIXER_VTH=0x09; //R41[3:0] 1.24 (9) - R850_SysFreq_Info.MIXER_VTL=0x04; //R43[3:0] 0.74 (4) - R850_SysFreq_Info.MIXER_GAIN_LIMIT=3; //R22[7:6] ["max=6" (0), "max=8" (1), "max=10" (2), "max=12" (3)] - R850_SysFreq_Info.MIXER_DETBW_LPF =0; //R46[7] ["normal" (0), "enhance amp det LPF" (1)] - - - //Filter - R850_SysFreq_Info.FILTER_TOP=4; //R44[3:0] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] - R850_SysFreq_Info.FILTER_VTH=0x90; //R41[7:4] 1.24 (9) - R850_SysFreq_Info.FILTER_VTL=0x40; //R43[7:4] 0.74 (4) - R850_SysFreq_Info.FILT_3TH_LPF_CUR=1; //R10[4] [high (0), low (1)] - R850_SysFreq_Info.FILT_3TH_LPF_GAIN=3; //R24[1:0] [normal (0), +1.5dB (1), +3dB (2), +4.5dB (3)] - - //Discharge - R850_SysFreq_Info.LNA_RF_DIS_MODE=1; //Both (fast+slow) (R45[1:0]=0'b00; R31[0]=1 ;R32[5]=1) : 1111 Both (fast+slow) case 1 - R850_SysFreq_Info.LNA_RF_CHARGE_CUR=1; //R31[1] ["6x chargeI" (0), "4x chargeI" (1)] - R850_SysFreq_Info.LNA_RF_DIS_CURR=1; //R13[5] ["1/3 dis current" (0), "normal" (1)] - R850_SysFreq_Info.RF_DIS_SLOW_FAST=5; //R45[7:4] 0.3u (1) / 0.9u (4) - R850_SysFreq_Info.LNA_DIS_SLOW_FAST=9; //R44[7:4] 0.3u (1) / 1.5u (8) => 1 + 8 = 9 - R850_SysFreq_Info.BB_DIS_CURR=0; //R25[6] ["x1" (0) , "x1/2" (1)] - R850_SysFreq_Info.MIXER_FILTER_DIS=2; //R37[7:6] ["highest" (0), "high" (1), "low" (2), "lowest" (3)] - R850_SysFreq_Info.BB_DET_MODE=0; //R37[2] ["peak" (0), "average" (1)] - - //Polyphase - R850_SysFreq_Info.ENB_POLY_GAIN=0; //R25[1]=0 original ["original" (0), "ctrl by mixamp (>10)" (1)] - - //NRB - R850_SysFreq_Info.NRB_TOP=4; //R40[7:4] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] - R850_SysFreq_Info.NRB_BW_HPF=0; //R26[3:2] [lowest (0), low (1), high (2), highest (3)] - R850_SysFreq_Info.NRB_BW_LPF=2; //R26[7:6] [widest (0), wide (1), low (2), lowest (3)] - R850_SysFreq_Info.IMG_NRB_ADDER=2; //R46[3:2] ["original" (0), "top+6" (1), "top+9" (2), "top+11" (3)] - - //VGA - R850_SysFreq_Info.HPF_COMP=1; //R13[2:1] ["normal" (0) , "+1.5dB" (1), "+3dB" (2), "+4dB" (3)] - R850_SysFreq_Info.FB_RES_1ST=1; //R21[4] ["2K" (0) , "8K" (1)] - break; - - } //end switch - - - R850_SysFreq_Info.DEGLITCH_CLK = 1; //R38[3] ["500Hz"(0), "1KHz"(1)] - //R850_SysFreq_Info.LNA_RF_DIS_MODE =1; //Both (fast+slow) (R45[1:0]=0'b00; R31[0]=1 ;R32[5]=1) : 1111 Both (fast+slow) case 1 - //R850_SysFreq_Info.LNA_DIS_SLOW_FAST &= 0x03; - //R850_SysFreq_Info.LNA_DIS_SLOW_FAST += 8; //R44[7:6] R45[7:6] ["0.6u" (0), "0.9u" (4), "1.5u" (8), "2.4u" (12)] - R850_SysFreq_Info.NAT_HYS = 1; //R35[6] ["no hys"(0) , "-6.5dB hys"(1)] - R850_SysFreq_Info.NAT_CAIN = 2; //R31[4:5] ["max-17dB"(0) , "max-11dB"(1), "max-6dB"(2), "max"(3)] - R850_SysFreq_Info.PULSE_HYS = 1; //R26[1:0] ["1.0V"(0), "0.8V"(1), "0.6V"(2), "0.4V"(3)] - R850_SysFreq_Info.FAST_DEGLITCH = 1; //R36[3:2] ["70ms"(0), "45ms"(1), "20ms"(2), "10ms"(3)] - R850_SysFreq_Info.PUL_RANGE_SEL = 0; //R31[2] ["0"(0), "1"(1)] - R850_SysFreq_Info.PUL_FLAG_RANGE = 3; //R35[1:0] ["0~14"(0), "1~14"(1), "2~14"(2), "3~14"(3)] - R850_SysFreq_Info.PULG_CNT_THRE = 1; //R17[1] ["threshold =14"(0), "threshold =15"(1)] - R850_SysFreq_Info.FORCE_PULSE = 1; //R46[5] ["pul_flag=0"(0), "auto"(1)] - R850_SysFreq_Info.FLG_CNT_CLK = 1; //R47[7:6] ["0.25Sec"(0), "0.5Sec"(1), "1Sec"(2), "2Sec"(3)] - R850_SysFreq_Info.NATG_OFFSET = 0; //R36[5:4] ["-6dB"(0), "-3dB"(1), "Normal"(2), "3dB"(3)] - - - return R850_SysFreq_Info; - -} -//-----------------------------------------------------------------------------------/ -// Purpose: read multiple IMR results for stability -// input: IMR_Reg: IMR result address -// IMR_Result_Data: result -// output: TRUE or FALSE -//-----------------------------------------------------------------------------------/ -R850_ErrCode R850_Muti_Read( struct r850_priv*priv, u8* IMR_Result_Data) //ok -{ - int ret = 0; - u8 buf[2]; - - - msleep(2);//2 //R850_ADC_READ_DELAY = 2; - - ret = r850_rd(priv,0x00,buf,2); - if(ret!=0){ - *IMR_Result_Data = 0; - return R850_Fail; - } - *IMR_Result_Data = buf[1] & 0x3F; - - return R850_Success; -} -R850_ErrCode R850_SetXtalCap(struct r850_priv *priv,u8 u8XtalCap) -{ - u8 XtalCap; - u8 Capx; - u8 Capx_3_0, Capxx; - - if(u8XtalCap>31) - { - XtalCap = 1; //10 - Capx = u8XtalCap-10; - } - else - { - XtalCap = 0; //0 - Capx = u8XtalCap; - } - - Capxx = Capx & 0x01; - Capx_3_0 = Capx >> 1; - - // Set Xtal Cap R33[6:3], R34[3] XtalCap => R33[7] - - priv->regs[33] = (priv->regs[33 ] & 0x07) | (Capx_3_0 << 3) | ( XtalCap << 7); - if(r850_wr(priv,33,priv->regs[33])!=0) - return R850_Fail; - - - priv->regs[34] = (priv->regs[34] & 0xF7) | (Capxx << 3); - if(r850_wr(priv,34,priv->regs[34])!=0) - return R850_Fail; - - return R850_Success; -} - -R850_ErrCode R850_SetXtalCap_No_Write(struct r850_priv *priv,u8 u8XtalCap) -{ - u8 XtalCap; - u8 Capx; - u8 Capx_3_0, Capxx; - - if(u8XtalCap>31) - { - XtalCap = 1; //10 - Capx = u8XtalCap-10; - } - else - { - XtalCap = 0; //0 - Capx = u8XtalCap; - } - - Capxx = Capx & 0x01; - Capx_3_0 = Capx >> 1; - - // Set Xtal Cap R33[6:3], R34[3] XtalCap => R33[7] - - priv->regs[33] = (priv->regs[33] & 0x07) | (Capx_3_0 << 3) | ( XtalCap << 7); - - priv->regs[34] = (priv->regs[34] & 0xF7) | (Capxx << 3); - - return R850_Success; -} - -/*parameter 2: xtal_gm -0:24MHz (strong) -1:24MHz -2:gm (16MHz) -3:off -*/ -R850_ErrCode R850_Set_XTAL_GM(struct r850_priv *priv,u8 xtal_gm) -{ - // Set Xtal gm R34[7:6] - - priv->regs[34] = (priv->regs[34] & 0x3F) | (xtal_gm << 6); - if(r850_wr(priv,34,priv->regs[34])!=0) - return R850_Fail; - - return R850_Success; -} - -/* - XTAL_PWR_VALUE -{ - XTAL_LOWEST = 0, - XTAL_LOW, - XTAL_HIGH, - XTAL_HIGHEST, - XTAL_CHECK_SIZE -}; -*/ -R850_ErrCode R850_SetXtalPW( struct r850_priv *priv,u8 u8Xtalpw) -{ - u8 Xtal_power; - - Xtal_power = (3 - u8Xtalpw); - - priv->regs[34] = (priv->regs[34] & 0xCF) | (Xtal_power<<4); //R34[5:4] - - if(r850_wr(priv,34,priv->regs[34])!=0) - return R850_Fail; - - return R850_Success; -} - -R850_ErrCode R850_PLL(struct r850_priv*priv, u32 LO_Freq, enum R850_Standard_Type R850_Standard)//ok -{ - u8 MixDiv = 2; - u8 DivBuf = 0; - u8 Ni = 0; - u8 Si = 0; - u8 DivNum = 0; - u16 Nint = 0; - u32 VCO_Min = 2200000; - u32 VCO_Max = 4400000; - u32 VCO_Freq = 0; - u32 PLL_Ref = priv->cfg->R850_Xtal; - u32 VCO_Fra = 0; - u16 Nsdm = 2; - u16 SDM = 0; - u16 SDM16to9 = 0; - u16 SDM8to1 = 0; - u8 XTAL_POW = 0; - u16 u2XalDivJudge; - u8 u1XtalDivRemain; - u8 CP_CUR = 0x00; - u8 CP_OFFSET = 0x00; - u8 SDM_RES = 0x00; - u8 NS_RES = 0x00; - u8 IQGen_Cur = 0; //DminDmin - u8 IQBias = 1; //BiasI - u8 IQLoad = 0; //3.2k/2 - u8 OutBuf_Bias = 0; //max - u8 BiasHf = 0; //135u - u8 PllArrayCunt = 0; - int ret = 0; - -// if(R850_Chip == R850_MP) -// VCO_Min=2270000; -// else - VCO_Min=2200000; - - VCO_Max = VCO_Min*2; - - // VCO current = 0 (max) - priv->regs[32] = (priv->regs[32] & 0xFC) | 0x00; // R31[1:0] = 0 => R32[3:2] = 0 - - // VCO power = auto - priv->regs[46] = (priv->regs[46] & 0xBF) | 0x40; // R26[7] = 1 => R46[6] = 1 - - // HfDiv Buf = 6dB buffer - priv->regs[37] = (priv->regs[37] & 0xEF) | 0x00; // R17[7]=0 => R37[4]=0 - - // Divider HfDiv current = 135u - priv->regs[12] = (priv->regs[12] & 0xFC) | 0x00; // R10[1:0]=00 => R12[3:2]=00 - - // PLL LDOA=2.2V - priv->regs[11] = (priv->regs[11] & 0xF3) | 0x00; // R11[3:2]=00 => R11[3:2]=00 - - // PFD DLDO=4mA - priv->regs[12] = (priv->regs[12] & 0x3F) | 0x00; // R8[5:4]=00 => R12[7:6]=00 - - // DLDO2=3mA - priv->regs[11] = (priv->regs[11] & 0xCF) | 0x10; // R11[5:4]=01 => R11[5:4]=01 - - // HF Fiv LDO=7mA (new bonding set this off) - priv->regs[9] = (priv->regs[9] & 0xF9) | 0x00; // R12[2:1]=00 => R9[2:1]=00 - - //------ Xtal freq depend setting: Xtal Gm & AGC ref clk --------// - if(priv->cfg->R850_Xtal==24000) - { - priv->regs[34] = (priv->regs[34] & 0x3F) | 0x00; //gm*2(24) R32[4:3]:00 => R34[7:6]:00 - priv->regs[37] = (priv->regs[37] & 0xDF) | 0x20; //clk /3 (24) => R37[5]=1 - } - else if(priv->cfg->R850_Xtal==16000) - { - priv->regs[34] = (priv->regs[34] & 0x3F) | 0x80; //gm(16) R32[4:3]:10 => R34[7:6]:10 - priv->regs[37] = (priv->regs[37] & 0xDF) | 0x00; //clk /2 (16) => R37[5]=0 - } - else if(priv->cfg->R850_Xtal==27000) - { - priv->regs[34] = (priv->regs[34] & 0x3F) | 0x00; //gm*2(24) R32[4:3]:00 => R34[7:6]:00 - priv->regs[37] = (priv->regs[37] & 0xDF) | 0x20; //clk /3 (24) => R37[5]=1 - } - else //not support Xtal freq - return R850_Fail; - - - if(priv->R850_clock_out == 1) - { - XTAL_POW = 0; //highest, R32[2:1]=0 - //Set X'tal Cap - R850_SetXtalCap(priv, priv->R850_Xtal_cap); - } - else if(priv->R850_clock_out == 0) - { - XTAL_POW = 3; //lowest, R32[2:1]=3 - //Set X'tal Cap - R850_SetXtalCap(priv, 0); - //gm off - R850_Set_XTAL_GM(priv, 1); //3:xtal gm off - } - else - { - if(LO_Freq<100000) //Xtal PW : Low - { - if(priv->R850_Xtal_Pwr <= R850_XTAL_LOW ) - { - XTAL_POW = 2; - } - else - { - XTAL_POW = 3 - priv->R850_Xtal_Pwr; - } - } - else if((110000<=LO_Freq) && (LO_Freq<130000)) //Xtal PW: High - { - if(priv->R850_Xtal_Pwr <= R850_XTAL_HIGH ) - { - XTAL_POW = 1; - } - else - { - XTAL_POW = 3 - priv->R850_Xtal_Pwr; - } - } - else //Xtal PW : Highest - { - XTAL_POW = 0; - } - //Set X'tal Cap - R850_SetXtalCap(priv, priv->R850_Xtal_cap); - } - - - priv->regs[34] = (priv->regs[34] & 0xCF) | (XTAL_POW<<4); //R32[2:1] => R34[5:4] - - - CP_CUR = 0x00; //0.7m, R30[7:5]=000 - CP_OFFSET = 0x00; //0u, R37[1]=0 - if(priv->cfg->R850_Xtal == 24000) - { - u2XalDivJudge = (u16) ((LO_Freq+priv->R850_IF_GOLOBAL)/1000/12); - // 48, 120 ,264 ,288, 336 - if((u2XalDivJudge==4)||(u2XalDivJudge==10)||(u2XalDivJudge==22)||(u2XalDivJudge==24)||(u2XalDivJudge==28)) - { - CP_OFFSET = 0x02; //30u, R37[1]=1 - } - else - { - CP_OFFSET = 0x00; //0u, R37[1]=0 - } - } - else if(priv->cfg->R850_Xtal == 16000) - { - u2XalDivJudge = (u16) ((LO_Freq+priv->R850_IF_GOLOBAL)/1000/8); - // - if((u2XalDivJudge==6)||(u2XalDivJudge==10)||(u2XalDivJudge==12)||(u2XalDivJudge==48)) - { - CP_OFFSET = 0x02; //30u, R37[1]=1 - } - else - { - CP_OFFSET = 0x00; //0u, R37[1]=0 - } - } - else if(priv->cfg->R850_Xtal == 27000) - { - u2XalDivJudge = (u16) ((LO_Freq+priv->R850_IF_GOLOBAL)*10/1000/135); - // 48, 120 ,264 ,288, 336 - if((u2XalDivJudge==4)||(u2XalDivJudge==10)||(u2XalDivJudge==22)||(u2XalDivJudge==24)||(u2XalDivJudge==28)) - { - CP_OFFSET = 0x02; //30u, R37[1]=1 - } - else - { - CP_OFFSET = 0x00; //0u, R37[1]=0 - } - } - - - priv->regs[30] = (priv->regs[30] & 0x1F) | (CP_CUR); // => R30[7:5] - - priv->regs[37] = (priv->regs[37] & 0xFD) | (CP_OFFSET); // => R37[1] - - //set pll autotune = 64kHz (fast) R47[1:0](MP) , R47[0](MT1) - - priv->regs[47] = priv->regs[47] & 0xFD; - - //Divider - while(MixDiv <= 64) - { - if(((LO_Freq * MixDiv) >= VCO_Min) && ((LO_Freq * MixDiv) < VCO_Max)) - { - DivBuf = MixDiv; - while(DivBuf > 2) - { - DivBuf = DivBuf >> 1; - DivNum ++; - } - break; - } - MixDiv = MixDiv << 1; - } - - //IQ Gen block & BiasHF & NS_RES & SDM_Res - if(MixDiv <= 4) //Div=2,4 - { - IQGen_Cur = 0; //DminDmin - IQBias = 1; //BiasI - IQLoad = 0; //3.2k/2 - OutBuf_Bias = 0; //0 (max) - BiasHf = 0; //135u - SDM_RES = 0; //short - NS_RES = 0; //0R - } - else if(MixDiv == 8) - { - IQGen_Cur = 0; //DminDmin - IQBias = 0; //BiasI/2 - IQLoad = 1; //3.2k - OutBuf_Bias = 1; //1 - BiasHf = 1; //110u - SDM_RES = 0; //short - NS_RES = 1; //800R - } - else if(MixDiv == 16) - { - IQGen_Cur = 0; //DminDmin - IQBias = 0; //BiasI/2 - IQLoad = 1; //3.2k - OutBuf_Bias = 2; //2 - BiasHf = 1; //110u - SDM_RES = 0; //short - NS_RES = 0; //0R - } - else if(MixDiv >= 32) //32, 64 - { - IQGen_Cur = 0; //DminDmin - IQBias = 0; //BiasI/2 - IQLoad = 1; //3.2k - OutBuf_Bias = 3; //3 (min) - BiasHf = 1; //110u - SDM_RES = 0; //short - NS_RES = 0; //0R - } - else - { - return R850_Fail; - } - - { - - { - if(priv->cfg->R850_Xtal==24000) - u2XalDivJudge = (u16) ((LO_Freq + priv->R850_IF_GOLOBAL)/1000/12); - else if(priv->cfg->R850_Xtal==16000) - u2XalDivJudge = (u16) ((LO_Freq + priv->R850_IF_GOLOBAL)/1000/8); - else if(priv->cfg->R850_Xtal==27000) - u2XalDivJudge = (u16) ((LO_Freq + priv->R850_IF_GOLOBAL)*10/1000/135); - else - return R850_Fail; - - u1XtalDivRemain = (u8) (u2XalDivJudge % 2); - - if(LO_Freq < (372000+8500)) - { - if(u1XtalDivRemain==1) //odd - { - priv->R850_XtalDiv = R850_XTAL_DIV1; - } - else //even, spur area - { - priv->R850_XtalDiv = R850_XTAL_DIV1_2; - } - } - else if(((LO_Freq + priv->R850_IF_GOLOBAL) >= 478000) && ((LO_Freq + priv->R850_IF_GOLOBAL) < 482000) && (R850_Standard == R850_ISDB_T_4063)) - { - priv->R850_XtalDiv = R850_XTAL_DIV4; - } - else - { - priv->R850_XtalDiv = R850_XTAL_DIV1; - } - } - } - - - //Xtal divider setting - //R850_XtalDiv = XTAL_DIV2; //div 1, 2, 4 - if(priv->R850_XtalDiv==R850_XTAL_DIV1) - { - PLL_Ref = priv->cfg->R850_Xtal; - priv->regs[34] = (priv->regs[34] & 0xFC) | 0x00; //b7:2nd_div2=0, b6:1st_div2=0 R32[7:6] => R34[1:0] - } - else if(priv->R850_XtalDiv==R850_XTAL_DIV1_2) - { - PLL_Ref = priv->cfg->R850_Xtal/2; - priv->regs[34] = (priv->regs[34] & 0xFC) | 0x02; //1st_div2=0(R34[0]), 2nd_div2=1(R34[1]) - } - else if(priv->R850_XtalDiv==R850_XTAL_DIV2_1) - { - PLL_Ref = priv->cfg->R850_Xtal/2; - priv->regs[34] = (priv->regs[34] & 0xFC) | 0x01; //1st_div2=1(R34[0]), 2nd_div2=0(R34[1]) - } - else if(priv->R850_XtalDiv==R850_XTAL_DIV4) //24MHz - { - PLL_Ref = priv->cfg->R850_Xtal/4; - priv->regs[34] = (priv->regs[34] & 0xFC) | 0x03; //b7:2nd_div2=1, b6:1st_div2=1 R32[7:6] => R34[1:0] - } - - - //IQ gen current R10[7] => R11[0] - priv->regs[11] = (priv->regs[11] & 0xFE) | (IQGen_Cur); - - //Out Buf Bias R10[6:5] => R45[3:2] - priv->regs[45] = (priv->regs[45] & 0xF3) | (OutBuf_Bias<<2); - - //BiasI R29[2] => R46[0] - priv->regs[46] = (priv->regs[46] & 0xFE) | (IQBias); - - //IQLoad R36[5] => R46[1] - priv->regs[46] = (priv->regs[46] & 0xFD) | (IQLoad<<1); - - //BiasHF R29[7:6] => R32[1:0] - priv->regs[32] = (priv->regs[32] & 0xFC) | (BiasHf); - - //SDM_RES R30[7] => R32[4] - priv->regs[32] = (priv->regs[32] & 0xEF) | (SDM_RES<<4); - - //NS_RES R36[0] => R17[7] - priv->regs[17] = (priv->regs[17] & 0x7F) | (NS_RES<<7); - - //Divider num R35[5:3] => R30[4:2] - priv->regs[30] = (priv->regs[30] & 0xE3) | (DivNum << 2); - - VCO_Freq = LO_Freq * MixDiv; - Nint = (u16) (VCO_Freq / 2 / PLL_Ref); - VCO_Fra = (u16) (VCO_Freq - 2 * PLL_Ref * Nint); - - //Boundary spur prevention - if (VCO_Fra < PLL_Ref/64) //2*PLL_Ref/128 - VCO_Fra = 0; - else if (VCO_Fra > PLL_Ref*127/64) //2*PLL_Ref*127/128 - { - VCO_Fra = 0; - Nint ++; - } - else if((VCO_Fra > PLL_Ref*127/128) && (VCO_Fra < PLL_Ref)) //> 2*PLL_Ref*127/256, < 2*PLL_Ref*128/256 - VCO_Fra = PLL_Ref*127/128; // VCO_Fra = 2*PLL_Ref*127/256 - else if((VCO_Fra > PLL_Ref) && (VCO_Fra < PLL_Ref*129/128)) //> 2*PLL_Ref*128/256, < 2*PLL_Ref*129/256 - VCO_Fra = PLL_Ref*129/128; // VCO_Fra = 2*PLL_Ref*129/256 - else - VCO_Fra = VCO_Fra; - - //Ni & Si - Ni = (u8) ((Nint - 13) / 4); - Si = (u8) (Nint - 4 *Ni - 13); - - - priv->regs[27] = (priv->regs[27] & 0x80) | Ni; //R26[6:0] => R27[6:0] - priv->regs[30] = (priv->regs[30] & 0xFC) | Si; //R35[7:6] => R30[1:0] - - //pw_sdm & pw_dither - priv->regs[32] &= 0x3F; //R29[1:0] => R32[7:6] - if(VCO_Fra == 0) - { - priv->regs[32] |= 0xC0; - } - - //SDM calculator - while(VCO_Fra > 1) - { - if (VCO_Fra > (2*PLL_Ref / Nsdm)) - { - SDM = SDM + 32768 / (Nsdm/2); - VCO_Fra = VCO_Fra - 2*PLL_Ref / Nsdm; - if (Nsdm >= 0x8000) - break; - } - Nsdm = Nsdm << 1; - } - - SDM16to9 = SDM >> 8; - SDM8to1 = SDM - (SDM16to9 << 8); - - - priv->regs[29] = (u8) SDM16to9; //R28 => R29 - priv->regs[28] = (u8) SDM8to1; //R27 => R28 - - - ret = r850_wrm(priv,8,&priv->regs[8],40); - if(ret!=0) - return R850_Fail; - - - - if(priv->R850_XtalDiv == R850_XTAL_DIV1) - msleep( R850_PLL_LOCK_DELAY); //correct gx_msleep ecos, don't modify delay function! - else if((priv->R850_XtalDiv == R850_XTAL_DIV1_2) || (priv->R850_XtalDiv == R850_XTAL_DIV2_1)) - msleep( R850_PLL_LOCK_DELAY*2); - else - msleep( R850_PLL_LOCK_DELAY*4); - - //set pll autotune = 1khz (2'b10) - - priv->regs[47] = (priv->regs[47] & 0xFD) | 0x02; - if(r850_wr(priv,47,priv->regs[47])!=0) - return R850_Fail; - - - return R850_Success; - -} - - -R850_ErrCode R850_MUX( struct r850_priv *priv ,u32 LO_KHz, u32 RF_KHz, enum R850_Standard_Type R850_Standard) -{ - u8 Reg_IMR_Gain = 0; - u8 Reg_IMR_Phase = 0; - u8 Reg_IMR_Iqcap = 0; - struct R850_Freq_Info_Type Freq_Info1; - - //Freq_Info_Type Freq_Info1; - Freq_Info1 = R850_Freq_Sel(LO_KHz, RF_KHz, R850_Standard); - - - // TF_DIPLEXER - priv->regs[14] = (priv->regs[14] & 0xF3) | (Freq_Info1.TF_DIPLEXER<<2); //LPF => R14[3:2] - if(r850_wr(priv,14,priv->regs[14])!=0) - return R850_Fail; - - - - //TF_HPF_BPF => R16[2:0] TF_HPF_CNR => R16[4:3] - priv->regs[16] = (priv->regs[16] & 0xE0) | (Freq_Info1.TF_HPF_BPF) | (Freq_Info1.TF_HPF_CNR << 3); // R16[2:0], R16[4:3] - if(r850_wr(priv,16,priv->regs[16])!=0) - return R850_Fail; - - - // RF Polyfilter - priv->regs[18] = (priv->regs[18] & 0xFC) | (Freq_Info1.RF_POLY); //R17[6:5] => R18[1:0] - if(r850_wr(priv,18,priv->regs[18])!=0) - return R850_Fail; - - - // LNA Cap - priv->regs[14] = (priv->regs[14] & 0x0F) | (Freq_Info1.LPF_CAP<<4); //R16[3:0] => R14[7:4] - if(r850_wr(priv,14,priv->regs[14])!=0) - return R850_Fail; - - - // LNA Notch - priv->regs[15] = (priv->regs[15] & 0xF0) | (Freq_Info1.LPF_NOTCH); //R16[7:4] => R15[3:0] - if(r850_wr(priv,15,priv->regs[15])!=0) - return R850_Fail; - - - - - //Set_IMR - if( (priv->R850_IMR_done_flag == TRUE) && (priv->R850_IMR_Cal_Result==0)) - { - - Reg_IMR_Gain = priv->imr_data[Freq_Info1.IMR_MEM_NOR].Gain_X & 0x2F; //R20[4:0] => R20[3:0] - Reg_IMR_Phase = priv->imr_data[Freq_Info1.IMR_MEM_NOR].Phase_Y & 0x2F; //R21[4:0] => R21[3:0] - Reg_IMR_Iqcap = priv->imr_data[Freq_Info1.IMR_MEM_NOR].Iqcap; //0,1,2 - - - } - else - { - Reg_IMR_Gain = 0; - Reg_IMR_Phase = 0; - Reg_IMR_Iqcap = 0; - } - - //Gain, R20[4:0] - priv->regs[R850_IMR_GAIN_REG] = (priv->regs[R850_IMR_GAIN_REG] & 0xD0) | (Reg_IMR_Gain & 0x2F); - if(r850_wr(priv,R850_IMR_GAIN_REG,priv->regs[R850_IMR_GAIN_REG])!=0) - return R850_Fail; - - //Phase, R21[4:0] - priv->regs[R850_IMR_PHASE_REG] = (priv->regs[R850_IMR_PHASE_REG] & 0xD0) | (Reg_IMR_Phase & 0x2F); - if(r850_wr(priv,R850_IMR_PHASE_REG,priv->regs[R850_IMR_PHASE_REG])!=0) - return R850_Fail; - - - //Iqcap, R21[7:6] - priv->regs[R850_IMR_IQCAP_REG] = (priv->regs[R850_IMR_IQCAP_REG] & 0x3F) | (Reg_IMR_Iqcap<<6); - if(r850_wr(priv,R850_IMR_IQCAP_REG,priv->regs[R850_IMR_IQCAP_REG])!=0) - return R850_Fail; - - - return R850_Success; -} - -//-----------------------------------------------------------------------------------/ -// Purpose: compare IMR result aray [0][1][2], find min value and store to CorArry[0] -// input: CorArry: three IMR data array -// output: TRUE or FALSE -//-----------------------------------------------------------------------------------/ -R850_ErrCode R850_CompreCor(struct R850_SectType* CorArry) -{ - u8 CompCunt = 0; - struct R850_SectType CorTemp; - - for(CompCunt=3; CompCunt > 0; CompCunt --) - { - if(CorArry[0].Value > CorArry[CompCunt - 1].Value) //compare IMR result [0][1][2], find min value - { - CorTemp = CorArry[0]; - CorArry[0] = CorArry[CompCunt - 1]; - CorArry[CompCunt - 1] = CorTemp; - } - } - - return R850_Success; -} - - -//-------------------------------------------------------------------------------------// -// Purpose: if (Gain<9 or Phase<9), Gain+1 or Phase+1 and compare with min value -// new < min => update to min and continue -// new > min => Exit -// input: StepArry: three IMR data array -// Pace: gain or phase register -// output: TRUE or FALSE -//-------------------------------------------------------------------------------------// -R850_ErrCode R850_CompreStep(struct r850_priv*priv, struct R850_SectType* StepArry, u8 Pace) -{ - struct R850_SectType StepTemp; - - //min value already saved in StepArry[0] - StepTemp.Phase_Y = StepArry[0].Phase_Y; //whole byte data - StepTemp.Gain_X = StepArry[0].Gain_X; - //StepTemp.Iqcap = StepArry[0].Iqcap; - - while(((StepTemp.Gain_X & 0x0F) < R850_IMR_TRIAL) && ((StepTemp.Phase_Y & 0x0F) < R850_IMR_TRIAL)) - { - if(Pace == R850_IMR_GAIN_REG) - StepTemp.Gain_X ++; - else - StepTemp.Phase_Y ++; - - if(r850_wr(priv,R850_IMR_GAIN_REG,StepTemp.Gain_X)!=0) - return R850_Fail; - - if(r850_wr(priv,R850_IMR_PHASE_REG,StepTemp.Phase_Y)!=0) - return R850_Fail; - - if(R850_Muti_Read(priv, &StepTemp.Value) != R850_Success) - return R850_Fail; - - if(StepTemp.Value <= StepArry[0].Value) - { - StepArry[0].Gain_X = StepTemp.Gain_X; - StepArry[0].Phase_Y = StepTemp.Phase_Y; - //StepArry[0].Iqcap = StepTemp.Iqcap; - StepArry[0].Value = StepTemp.Value; - } - else if((StepTemp.Value - 2*R850_ADC_READ_COUNT) > StepArry[0].Value) - { - break; - } - - } //end of while() - - return R850_Success; -} - -//-------------------------------------------------------------------------------------------- -// Purpose: record IMR results by input gain/phase location -// then adjust gain or phase positive 1 step and negtive 1 step, both record results -// input: FixPot: phase or gain -// FlucPot phase or gain -// PotReg: Reg20 or Reg21 -// CompareTree: 3 IMR trace and results -// output: TREU or FALSE -//-------------------------------------------------------------------------------------------- -R850_ErrCode R850_IQ_Tree( struct r850_priv *priv,u8 FixPot, u8 FlucPot, u8 PotReg, struct R850_SectType* CompareTree) -{ - u8 TreeCunt = 0; - u8 PntReg = 0; - - //PntReg is reg to change; FlucPot is change value - if(PotReg == R850_IMR_GAIN_REG) - PntReg = R850_IMR_PHASE_REG; //phase control - else - PntReg = R850_IMR_GAIN_REG; //gain control - - for(TreeCunt = 0; TreeCunt<3; TreeCunt ++) - { - - if(r850_wr(priv,PotReg,FixPot)!=0) - return R850_Fail; - if(r850_wr(priv,PntReg,FlucPot)!=0) - return R850_Fail; - - if(R850_Muti_Read(priv, &CompareTree[TreeCunt].Value) != R850_Success) - return R850_Fail; - - if(PotReg == R850_IMR_GAIN_REG) - { - CompareTree[TreeCunt].Gain_X = FixPot; - CompareTree[TreeCunt].Phase_Y = FlucPot; - } - else - { - CompareTree[TreeCunt].Phase_Y = FixPot; - CompareTree[TreeCunt].Gain_X = FlucPot; - } - - if(TreeCunt == 0) //try right-side point - { - FlucPot ++; - } - else if(TreeCunt == 1) //try left-side point - { - if((FlucPot & 0x0F) == 1) //if absolute location is 1, change I/Q direction - { - if(FlucPot & 0x20) //b[5]:I/Q selection. 0:Q-path, 1:I-path - { - //FlucPot = (FlucPot & 0xE0) | 0x01; - FlucPot = (FlucPot & 0xD0) | 0x01; - } - else - { - //FlucPot = (FlucPot & 0xE0) | 0x11; - FlucPot = (FlucPot & 0xD0) | 0x21; - } - } - else - { - FlucPot = FlucPot - 2; - } - } - } - - return R850_Success; -} - -R850_ErrCode R850_IQ_Tree5(struct r850_priv*priv, u8 FixPot, u8 FlucPot, u8 PotReg, struct R850_SectType* CompareTree) -{ - u8 TreeCunt = 0; - u8 TreeTimes = 5; - u8 TempPot = 0; - u8 PntReg = 0; - u8 CompCunt = 0; - struct R850_SectType CorTemp[5]; - struct R850_SectType Compare_Temp; - u8 CuntTemp = 0; - - memset(&Compare_Temp,0, sizeof(struct R850_SectType)); - Compare_Temp.Value = 255; - - for(CompCunt=0; CompCunt<3; CompCunt++) - { - CorTemp[CompCunt].Gain_X = CompareTree[CompCunt].Gain_X; - CorTemp[CompCunt].Phase_Y = CompareTree[CompCunt].Phase_Y; - CorTemp[CompCunt].Value = CompareTree[CompCunt].Value; - } - - /* - if(PotReg == 0x08) - PntReg = 0x09; //phase control - else - PntReg = 0x08; //gain control - */ - - //PntReg is reg to change; FlucPot is change value - if(PotReg == R850_IMR_GAIN_REG) - PntReg = R850_IMR_PHASE_REG; //phase control - else - PntReg = R850_IMR_GAIN_REG; //gain control - - - - - for(TreeCunt = 0;TreeCunt < TreeTimes;TreeCunt++) - { - if(r850_wr(priv,PotReg,FixPot) != 0) - return R850_Fail; - if(r850_wr(priv,PntReg,FlucPot) != 0) - return R850_Fail; - - if(R850_Muti_Read( priv,&CorTemp[TreeCunt].Value) != R850_Success) - return R850_Fail; - - if(PotReg == R850_IMR_GAIN_REG) - { - CorTemp[TreeCunt].Gain_X = FixPot; - CorTemp[TreeCunt].Phase_Y = FlucPot; - } - else - { - CorTemp[TreeCunt].Phase_Y = FixPot; - CorTemp[TreeCunt].Gain_X = FlucPot; - } - - if(TreeCunt == 0) //next try right-side 1 point - { - FlucPot ++; //+1 - } - else if(TreeCunt == 1) //next try right-side 2 point - { - FlucPot ++; //1+1=2 - } - else if(TreeCunt == 2) //next try left-side 1 point - { - if((FlucPot & 0x0F) == 0x02) //if absolute location is 2, change I/Q direction and set to 1 - { - TempPot = 1; - if((FlucPot & 0x20)==0x20) //b[5]:I/Q selection. 0:Q-path, 1:I-path - { - FlucPot = (FlucPot & 0xD0) | 0x01; //Q1 - } - else - { - FlucPot = (FlucPot & 0xD0) | 0x21; //I1 - } - } - else - { - FlucPot -= 3; //+2-3=-1 - } - } - else if(TreeCunt == 3) //next try left-side 2 point - { - if(TempPot==1) //been chnaged I/Q - { - FlucPot += 1; - } - else if((FlucPot & 0x0F) == 0x00) //if absolute location is 0, change I/Q direction - { - TempPot = 1; - if((FlucPot & 0x20)==0x20) //b[5]:I/Q selection. 0:Q-path, 1:I-path - { - FlucPot = (FlucPot & 0xD0) | 0x01; //Q1 - } - else - { - FlucPot = (FlucPot & 0xD0) | 0x21; //I1 - } - } - else - { - FlucPot -= 1; //-1-1=-2 - } - } - - if(CorTemp[TreeCunt].Value < Compare_Temp.Value) - { - Compare_Temp.Value = CorTemp[TreeCunt].Value; - Compare_Temp.Gain_X = CorTemp[TreeCunt].Gain_X; - Compare_Temp.Phase_Y = CorTemp[TreeCunt].Phase_Y; - CuntTemp = TreeCunt; - } - } - - - //CompareTree[0].Gain_X = CorTemp[CuntTemp].Gain_X; - //CompareTree[0].Phase_Y = CorTemp[CuntTemp].Phase_Y; - //CompareTree[0].Value = CorTemp[CuntTemp].Value; - - for(CompCunt=0; CompCunt<3; CompCunt++) - { - if(CuntTemp==3 || CuntTemp==4) - { - CompareTree[CompCunt].Gain_X = CorTemp[2+CompCunt].Gain_X; //2,3,4 - CompareTree[CompCunt].Phase_Y = CorTemp[2+CompCunt].Phase_Y; - CompareTree[CompCunt].Value = CorTemp[2+CompCunt].Value; - } - else - { - CompareTree[CompCunt].Gain_X = CorTemp[CompCunt].Gain_X; //0,1,2 - CompareTree[CompCunt].Phase_Y = CorTemp[CompCunt].Phase_Y; - CompareTree[CompCunt].Value = CorTemp[CompCunt].Value; - } - - } - - return R850_Success; -} - -R850_ErrCode R850_Section(struct r850_priv*priv, struct R850_SectType* IQ_Pont) -{ - struct R850_SectType Compare_IQ[3]; - struct R850_SectType Compare_Bet[3]; - - //Try X-1 column and save min result to Compare_Bet[0] - if((IQ_Pont->Gain_X & 0x0F) == 0x00) - { - Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) & 0xDF) + 1; //Q-path, Gain=1 - } - else - { - Compare_IQ[0].Gain_X = IQ_Pont->Gain_X - 1; //left point - } - Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; - - if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) // y-direction - return R850_Fail; - - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - Compare_Bet[0].Gain_X = Compare_IQ[0].Gain_X; - Compare_Bet[0].Phase_Y = Compare_IQ[0].Phase_Y; - Compare_Bet[0].Value = Compare_IQ[0].Value; - - //Try X column and save min result to Compare_Bet[1] - Compare_IQ[0].Gain_X = IQ_Pont->Gain_X; - Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; - - if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) - return R850_Fail; - - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - Compare_Bet[1].Gain_X = Compare_IQ[0].Gain_X; - Compare_Bet[1].Phase_Y = Compare_IQ[0].Phase_Y; - Compare_Bet[1].Value = Compare_IQ[0].Value; - - //Try X+1 column and save min result to Compare_Bet[2] - if((IQ_Pont->Gain_X & 0x0F) == 0x00) - Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) | 0x20) + 1; //I-path, Gain=1 - else - Compare_IQ[0].Gain_X = IQ_Pont->Gain_X + 1; - Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; - - if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) - return R850_Fail; - - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - Compare_Bet[2].Gain_X = Compare_IQ[0].Gain_X; - Compare_Bet[2].Phase_Y = Compare_IQ[0].Phase_Y; - Compare_Bet[2].Value = Compare_IQ[0].Value; - - if(R850_CompreCor(&Compare_Bet[0]) != R850_Success) - return R850_Fail; - - *IQ_Pont = Compare_Bet[0]; - - return R850_Success; -} -R850_ErrCode R850_IMR_Iqcap(struct r850_priv*priv, struct R850_SectType* IQ_Point) -{ - struct R850_SectType Compare_Temp; - int i = 0; - - //Set Gain/Phase to right setting - if(r850_wr( priv,R850_IMR_GAIN_REG,IQ_Point->Gain_X) != 0) - return R850_Fail; - - if(r850_wr( priv,R850_IMR_PHASE_REG,IQ_Point->Phase_Y) != 0) - return R850_Fail; - - //try iqcap - for(i=0; i<3; i++) - { - Compare_Temp.Iqcap = (u8) i; - priv->regs[R850_IMR_IQCAP_REG] = (priv->regs[R850_IMR_IQCAP_REG] & 0x3F) | (Compare_Temp.Iqcap<<6); - if(r850_wr( priv,R850_IMR_IQCAP_REG,priv->regs[R850_IMR_IQCAP_REG]) != 0) - return R850_Fail; - - - - if(R850_Muti_Read(priv, &(Compare_Temp.Value)) != R850_Success) - return R850_Fail; - - if(Compare_Temp.Value < IQ_Point->Value) - { - IQ_Point->Value = Compare_Temp.Value; - IQ_Point->Iqcap = Compare_Temp.Iqcap; //0, 1, 2 - } - else if(Compare_Temp.Value == IQ_Point->Value) - { - IQ_Point->Value = Compare_Temp.Value; - IQ_Point->Iqcap = Compare_Temp.Iqcap; //0, 1, 2 - } - } - - return R850_Success; -} - -R850_ErrCode R850_IMR_Cross( struct r850_priv*priv,struct R850_SectType* IQ_Pont, u8* X_Direct) -{ - - struct R850_SectType Compare_Cross[9]; //(0,0)(0,Q-1)(0,I-1)(Q-1,0)(I-1,0)+(0,Q-2)(0,I-2)(Q-2,0)(I-2,0) - struct R850_SectType Compare_Temp; - u8 CrossCount = 0; - u8 RegGain = priv->regs[R850_IMR_GAIN_REG] & 0xD0; - u8 RegPhase = priv->regs[R850_IMR_PHASE_REG] & 0xD0; - - //memset(&Compare_Temp,0, sizeof(R850_SectType)); - Compare_Temp.Gain_X = 0; - Compare_Temp.Phase_Y = 0; - Compare_Temp.Iqcap = 0; - Compare_Temp.Value = 255; - - for(CrossCount=0; CrossCount<9; CrossCount++) - { - - if(CrossCount==0) - { - Compare_Cross[CrossCount].Gain_X = RegGain; - Compare_Cross[CrossCount].Phase_Y = RegPhase; - } - else if(CrossCount==1) - { - Compare_Cross[CrossCount].Gain_X = RegGain; //0 - Compare_Cross[CrossCount].Phase_Y = RegPhase + 1; //Q-1 - } - else if(CrossCount==2) - { - Compare_Cross[CrossCount].Gain_X = RegGain; //0 - Compare_Cross[CrossCount].Phase_Y = (RegPhase | 0x20) + 1; //I-1 - } - else if(CrossCount==3) - { - Compare_Cross[CrossCount].Gain_X = RegGain + 1; //Q-1 - Compare_Cross[CrossCount].Phase_Y = RegPhase; - } - else if(CrossCount==4) - { - //Compare_Cross[CrossCount].Gain_X = (RegGain | 0x10) + 1; //I-1 - Compare_Cross[CrossCount].Gain_X = (RegGain | 0x20) + 1; //I-1 - Compare_Cross[CrossCount].Phase_Y = RegPhase; - } - else if(CrossCount==5) - { - Compare_Cross[CrossCount].Gain_X = RegGain; //0 - Compare_Cross[CrossCount].Phase_Y = RegPhase + 2; //Q-2 - } - else if(CrossCount==6) - { - Compare_Cross[CrossCount].Gain_X = RegGain; //0 - Compare_Cross[CrossCount].Phase_Y = (RegPhase | 0x20) + 2; //I-2 - } - else if(CrossCount==7) - { - Compare_Cross[CrossCount].Gain_X = RegGain + 2; //Q-2 - Compare_Cross[CrossCount].Phase_Y = RegPhase; - } - else if(CrossCount==8) - { - Compare_Cross[CrossCount].Gain_X = (RegGain | 0x20) + 2; //I-2 - Compare_Cross[CrossCount].Phase_Y = RegPhase; - } - - // R850_I2C.RegAddr = R850_IMR_GAIN_REG; - // R850_I2C.Data = Compare_Cross[CrossCount].Gain_X; - if(r850_wr(priv,R850_IMR_GAIN_REG,Compare_Cross[CrossCount].Gain_X)!=0) - return R850_Fail; - - -// R850_I2C.RegAddr = R850_IMR_PHASE_REG; -// R850_I2C.Data = Compare_Cross[CrossCount].Phase_Y; - if(r850_wr(priv,R850_IMR_PHASE_REG,Compare_Cross[CrossCount].Phase_Y)!=0) - return R850_Fail; - - - if(R850_Muti_Read(priv, &Compare_Cross[CrossCount].Value) != R850_Success) - return R850_Fail; - - if( Compare_Cross[CrossCount].Value < Compare_Temp.Value) - { - Compare_Temp.Value = Compare_Cross[CrossCount].Value; - Compare_Temp.Gain_X = Compare_Cross[CrossCount].Gain_X; - Compare_Temp.Phase_Y = Compare_Cross[CrossCount].Phase_Y; - } - } //end for loop - - - if(((Compare_Temp.Phase_Y & 0x2F)==0x01) || (Compare_Temp.Phase_Y & 0x2F)==0x02) //phase Q1 or Q2 - { - *X_Direct = (u8) 0; - IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; //0 - IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; //0 - IQ_Pont[0].Value = Compare_Cross[0].Value; - - IQ_Pont[1].Gain_X = Compare_Cross[1].Gain_X; //0 - IQ_Pont[1].Phase_Y = Compare_Cross[1].Phase_Y; //Q1 - IQ_Pont[1].Value = Compare_Cross[1].Value; - - IQ_Pont[2].Gain_X = Compare_Cross[5].Gain_X; //0 - IQ_Pont[2].Phase_Y = Compare_Cross[5].Phase_Y;//Q2 - IQ_Pont[2].Value = Compare_Cross[5].Value; - } - else if(((Compare_Temp.Phase_Y & 0x2F)==0x21) || (Compare_Temp.Phase_Y & 0x2F)==0x22) //phase I1 or I2 - { - *X_Direct = (u8) 0; - IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; //0 - IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; //0 - IQ_Pont[0].Value = Compare_Cross[0].Value; - - IQ_Pont[1].Gain_X = Compare_Cross[2].Gain_X; //0 - IQ_Pont[1].Phase_Y = Compare_Cross[2].Phase_Y; //Q1 - IQ_Pont[1].Value = Compare_Cross[2].Value; - - IQ_Pont[2].Gain_X = Compare_Cross[6].Gain_X; //0 - IQ_Pont[2].Phase_Y = Compare_Cross[6].Phase_Y;//Q2 - IQ_Pont[2].Value = Compare_Cross[6].Value; - } - else if(((Compare_Temp.Gain_X & 0x2F)==0x01) || (Compare_Temp.Gain_X & 0x2F)==0x02) //gain Q1 or Q2 - { - *X_Direct = (u8) 1; - IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; //0 - IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; //0 - IQ_Pont[0].Value = Compare_Cross[0].Value; - - IQ_Pont[1].Gain_X = Compare_Cross[3].Gain_X; //Q1 - IQ_Pont[1].Phase_Y = Compare_Cross[3].Phase_Y; //0 - IQ_Pont[1].Value = Compare_Cross[3].Value; - - IQ_Pont[2].Gain_X = Compare_Cross[7].Gain_X; //Q2 - IQ_Pont[2].Phase_Y = Compare_Cross[7].Phase_Y;//0 - IQ_Pont[2].Value = Compare_Cross[7].Value; - } - else if(((Compare_Temp.Gain_X & 0x2F)==0x21) || (Compare_Temp.Gain_X & 0x2F)==0x22) //gain I1 or I2 - { - *X_Direct = (u8) 1; - IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; //0 - IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; //0 - IQ_Pont[0].Value = Compare_Cross[0].Value; - - IQ_Pont[1].Gain_X = Compare_Cross[4].Gain_X; //I1 - IQ_Pont[1].Phase_Y = Compare_Cross[4].Phase_Y; //0 - IQ_Pont[1].Value = Compare_Cross[4].Value; - - IQ_Pont[2].Gain_X = Compare_Cross[8].Gain_X; //I2 - IQ_Pont[2].Phase_Y = Compare_Cross[8].Phase_Y;//0 - IQ_Pont[2].Value = Compare_Cross[8].Value; - } - else //(0,0) - { - *X_Direct = (u8) 1; - IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; - IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; - IQ_Pont[0].Value = Compare_Cross[0].Value; - - IQ_Pont[1].Gain_X = Compare_Cross[3].Gain_X; //Q1 - IQ_Pont[1].Phase_Y = Compare_Cross[3].Phase_Y; //0 - IQ_Pont[1].Value = Compare_Cross[3].Value; - - IQ_Pont[2].Gain_X = Compare_Cross[4].Gain_X; //I1 - IQ_Pont[2].Phase_Y = Compare_Cross[4].Phase_Y; //0 - IQ_Pont[2].Value = Compare_Cross[4].Value; - } - return R850_Success; -} - - -R850_ErrCode R850_IQ( struct r850_priv*priv, struct R850_SectType* IQ_Pont) -{ - struct R850_SectType Compare_IQ[3]; - u8 X_Direction; // 1:X, 0:Y - - //------- increase Filter gain max to let ADC read value significant ---------// - - priv->regs[41] = (priv->regs[41] | 0xF0); - if(r850_wr(priv,41,priv->regs[41])!=0) - return R850_Fail; - - - - //give a initial value, no useful - Compare_IQ[0].Gain_X = priv->regs[R850_IMR_GAIN_REG] & 0xD0; - Compare_IQ[0].Phase_Y = priv->regs[R850_IMR_PHASE_REG] & 0xD0; - - - // Determine X or Y - if(R850_IMR_Cross( priv,&Compare_IQ[0], &X_Direction) != R850_Success) - return R850_Fail; - - if(X_Direction==1) - { - //compare and find min of 3 points. determine I/Q direction - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - //increase step to find min value of this direction - if(R850_CompreStep(priv, &Compare_IQ[0], R850_IMR_GAIN_REG) != R850_Success) //X - return R850_Fail; - } - else - { - //compare and find min of 3 points. determine I/Q direction - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - //increase step to find min value of this direction - if(R850_CompreStep(priv, &Compare_IQ[0], R850_IMR_PHASE_REG) != R850_Success) //Y - return R850_Fail; - } - - //Another direction - if(X_Direction==1) //Y-direct - { - // if(R850_IQ_Tree( Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) //Y - if(R850_IQ_Tree5( priv,Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) //Y - - return R850_Fail; - - //compare and find min of 3 points. determine I/Q direction - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - //increase step to find min value of this direction - if(R850_CompreStep(priv, &Compare_IQ[0], R850_IMR_PHASE_REG) != R850_Success) //Y - return R850_Fail; - } - else //X-direct - { - // if(R850_IQ_Tree( Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, R850_IMR_PHASE_REG, &Compare_IQ[0]) != R850_Success) //X - if(R850_IQ_Tree5(priv,Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, R850_IMR_PHASE_REG, &Compare_IQ[0]) != R850_Success) //X - return R850_Fail; - - //compare and find min of 3 points. determine I/Q direction - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - //increase step to find min value of this direction - if(R850_CompreStep(priv, &Compare_IQ[0], R850_IMR_GAIN_REG) != R850_Success) //X - return R850_Fail; - } - - - //--- Check 3 points again---// - if(X_Direction==1) //X-direct - { - if(R850_IQ_Tree(priv, Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, R850_IMR_PHASE_REG, &Compare_IQ[0]) != R850_Success) //X - return R850_Fail; - } - else //Y-direct - { - if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) //Y - return R850_Fail; - } - - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - //Section-9 check - if(R850_Section(priv, &Compare_IQ[0]) != R850_Success) - return R850_Fail; - - //clear IQ_Cap = 0 - //Compare_IQ[0].Iqcap = priv->regs[R850_IMR_IQCAP_REG] & 0x3F; - Compare_IQ[0].Iqcap = 0; - - if(R850_IMR_Iqcap(priv, &Compare_IQ[0]) != R850_Success) - return R850_Fail; - - *IQ_Pont = Compare_IQ[0]; - - //reset gain/phase/iqcap control setting - //R850_I2C.RegAddr = R850_IMR_GAIN_REG; - priv->regs[R850_IMR_GAIN_REG] = priv->regs[R850_IMR_GAIN_REG] & 0xD0; - if(r850_wr(priv,R850_IMR_GAIN_REG,priv->regs[R850_IMR_GAIN_REG])!=0) - return R850_Fail; - - - priv->regs[R850_IMR_PHASE_REG] = priv->regs[R850_IMR_PHASE_REG] & 0xD0; - if(r850_wr(priv,R850_IMR_PHASE_REG,priv->regs[R850_IMR_PHASE_REG])!=0) - return R850_Fail; - - - priv->regs[R850_IMR_IQCAP_REG] = priv->regs[R850_IMR_IQCAP_REG] & 0x3F; - if(r850_wr(priv,R850_IMR_IQCAP_REG,priv->regs[R850_IMR_IQCAP_REG])!=0) - return R850_Fail; - - - return R850_Success; -} - - - - - - -//----------------------------------------------------------------------------------------// -// purpose: search surrounding points from previous point -// try (x-1), (x), (x+1) columns, and find min IMR result point -// input: IQ_Pont: previous point data(IMR Gain, Phase, ADC Result, RefRreq) -// will be updated to final best point -// output: TRUE or FALSE -//----------------------------------------------------------------------------------------// -R850_ErrCode R850_F_IMR(struct r850_priv *priv, struct R850_SectType* IQ_Pont) -{ - struct R850_SectType Compare_IQ[3]; - struct R850_SectType Compare_Bet[3]; - - //------- increase Filter gain max to let ADC read value significant ---------// - priv->regs[41] = (priv->regs[41] | 0xF0); - if(r850_wr(priv,41,priv->regs[41]) != 0) - return R850_Fail; - - //Try X-1 column and save min result to Compare_Bet[0] - if((IQ_Pont->Gain_X & 0x0F) == 0x00) - { - Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) & 0xDF) + 1; //Q-path, Gain=1 - } - else - { - Compare_IQ[0].Gain_X = IQ_Pont->Gain_X - 1; //left point - } - Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; - - if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) // y-direction - return R850_Fail; - - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - Compare_Bet[0].Gain_X = Compare_IQ[0].Gain_X; - Compare_Bet[0].Phase_Y = Compare_IQ[0].Phase_Y; - Compare_Bet[0].Value = Compare_IQ[0].Value; - - //Try X column and save min result to Compare_Bet[1] - Compare_IQ[0].Gain_X = IQ_Pont->Gain_X; - Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; - - if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) - return R850_Fail; - - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - Compare_Bet[1].Gain_X = Compare_IQ[0].Gain_X; - Compare_Bet[1].Phase_Y = Compare_IQ[0].Phase_Y; - Compare_Bet[1].Value = Compare_IQ[0].Value; - - //Try X+1 column and save min result to Compare_Bet[2] - if((IQ_Pont->Gain_X & 0x0F) == 0x00) - Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) | 0x20) + 1; //I-path, Gain=1 - else - Compare_IQ[0].Gain_X = IQ_Pont->Gain_X + 1; - Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; - - if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) - return R850_Fail; - - if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) - return R850_Fail; - - Compare_Bet[2].Gain_X = Compare_IQ[0].Gain_X; - Compare_Bet[2].Phase_Y = Compare_IQ[0].Phase_Y; - Compare_Bet[2].Value = Compare_IQ[0].Value; - - if(R850_CompreCor(&Compare_Bet[0]) != R850_Success) - return R850_Fail; - - //clear IQ_Cap = 0 - //Compare_Bet[0].Iqcap = priv->regs[3] & 0xFC; - Compare_Bet[0].Iqcap = 0; - - if(R850_IMR_Iqcap(priv, &Compare_Bet[0]) != R850_Success) - return R850_Fail; - - *IQ_Pont = Compare_Bet[0]; - - return R850_Success; -} - - - -R850_ErrCode R850_InitReg(struct r850_priv *priv)//ok -{ - u8 InitArrayCunt = 0; - - - //Write Full Table, Set Xtal Power = highest at initial - //R850_I2C_Len.RegAddr = 0; - //R850_I2C_Len.Len = R850_REG_NUM; - u8 XtalCap; - u8 Capx; - u8 Capx_3_0, Capxx; - int ret=0; - - if(priv->R850_clock_out==1) - { - if(priv->R850_Xtal_cap>31) - { - XtalCap = 1; //10 - Capx = priv->R850_Xtal_cap-10; - } - else - { - XtalCap = 0; //0 - Capx = priv->R850_Xtal_cap; - } - - Capxx = Capx & 0x01; - Capx_3_0 = Capx >> 1; - - // Set Xtal Cap R33[6:3], R34[3] XtalCap => R33[7] - R850_iniArray[0][33] = 0x01 | (Capx_3_0 << 3) | ( XtalCap << 7); - R850_iniArray[1][33] = 0x01 | (Capx_3_0 << 3) | ( XtalCap << 7); - R850_iniArray[2][33] = 0x01 | (Capx_3_0 << 3) | ( XtalCap << 7); - // Set GM=strong - R850_iniArray[0][34] = 0x04 | (Capxx << 3); - R850_iniArray[1][34] = 0x04 | (Capxx << 3); - R850_iniArray[2][34] = 0x04 | (Capxx << 3); - } - else - { - R850_iniArray[0][33]= 0x01; - R850_iniArray[1][33]= 0x01; - R850_iniArray[2][33]= 0x01; - - R850_iniArray[0][34]= 0x74; - R850_iniArray[1][34]= 0x74; - R850_iniArray[2][34]= 0x74; - - } - - - - if(priv->cfg->R850_Xtal == 24000) - { - for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_iniArray[0][InitArrayCunt]; - } - } - else if(priv->cfg->R850_Xtal == 16000) - { - for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_iniArray[1][InitArrayCunt]; - } - } - else if(priv->cfg->R850_Xtal == 27000) - { - for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_iniArray[2][InitArrayCunt]; - } - } - else - { - //no support now - return R850_Fail; - } - - -//Xtal cap - - if(priv->R850_clock_out == 1) - { - R850_SetXtalPW( priv, R850_XTAL_HIGHEST); - R850_SetXtalCap_No_Write(priv, priv->R850_Xtal_cap); - } - else if(priv->R850_clock_out == 0) - { - R850_SetXtalPW(priv, R850_XTAL_LOWEST); - R850_SetXtalCap_No_Write(priv, 0); - //gm off - R850_Set_XTAL_GM(priv, 1); //3:xtal gm off - } - else - { - R850_SetXtalCap_No_Write(priv, priv->R850_Xtal_cap); - } - - ret = r850_wrm(priv,8,&priv->regs[8],40); - if(ret!=0) - return R850_Fail; - - return R850_Success; -} - -R850_ErrCode R850_Cal_Prepare(struct r850_priv *priv,u8 u1CalFlag) -{ - //R850_Cal_Info_Type Cal_Info; - u8 InitArrayCunt = 0; - - //Write Full Table, include PLL & RingPLL all settings - //R850_I2C_Len.RegAddr = 0; - //R850_I2C_Len.Len = R850_REG_NUM; - - int ret = 0; - - switch(u1CalFlag) - { - case R850_IMR_CAL: - if(priv->cfg->R850_Xtal == 24000) - { - //542MHz - for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_IMR_CAL_Array[0][InitArrayCunt]; - } - } - else if(priv->cfg->R850_Xtal == 16000) - { - //542MHz - for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_IMR_CAL_Array[1][InitArrayCunt]; - } - } - else if(priv->cfg->R850_Xtal == 27000) - { - //542MHz - for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_IMR_CAL_Array[2][InitArrayCunt]; - } - } - else - { - //no support now - return R850_Fail; - } - break; - - case R850_IMR_LNA_CAL: - - break; - - case R850_LPF_CAL: - - if(priv->cfg->R850_Xtal == 24000) - { - for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_LPF_CAL_Array[0][InitArrayCunt]; - } - } - else if(priv->cfg->R850_Xtal == 16000) - { - for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_LPF_CAL_Array[1][InitArrayCunt]; - } - } - else if(priv->cfg->R850_Xtal == 27000) - { - for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_LPF_CAL_Array[2][InitArrayCunt]; - } - } - else - { - //no support 27MHz now - return R850_Fail; - } - break; - - default: - break; - - } - - -//Xtal cap - if(priv->R850_clock_out == 1) - { - R850_SetXtalPW(priv, R850_XTAL_HIGHEST); - R850_SetXtalCap_No_Write( priv, priv->R850_Xtal_cap); - } - else if(priv->R850_clock_out == 0) - { - R850_SetXtalPW(priv, R850_XTAL_LOWEST); - R850_SetXtalCap_No_Write(priv, 0); - //gm off - R850_Set_XTAL_GM(priv, 1); //3:xtal gm off - } - else - { - R850_SetXtalCap_No_Write(priv, priv->R850_Xtal_cap); - } - - ret = r850_wrm(priv,8,&priv->regs[8],40); - if(ret) - return R850_Fail; - - return R850_Success; -} - - -R850_ErrCode R850_IMR(struct r850_priv* priv, u8 IMR_MEM, u8 IM_Flag) -{ - - //------------------------------------------------------------------- - //to do - u32 RingVCO = 0; - u32 RingFreq = 0; - u32 RingRef = priv->cfg->R850_Xtal; - u8 divnum_ring = 0; - //u8 u1MixerGain = 6; //fix at initial test - - u8 IMR_Gain = 0; - u8 IMR_Phase = 0; - struct R850_SectType IMR_POINT; - - //priv->regs[24] &= 0x3F; //clear ring_div1, R24[7:6] - //priv->regs[25] &= 0xFC; //clear ring_div2, R25[1:0] - - if(priv->cfg->R850_Xtal==24000) //24M - { - divnum_ring = 17; - } - else if(priv->cfg->R850_Xtal==16000) //16M - { - divnum_ring = 25; //3200/8/16. 32>divnum>7 - } - else if(priv->cfg->R850_Xtal==27000) //27M - { - divnum_ring = 15; //3200/8/16. 32>divnum>7 - } - else //not support - { - return R850_Fail; - } - - RingVCO = (divnum_ring)* 8 * RingRef; - RingFreq = RingVCO/48; - - switch(IMR_MEM) - { - case 0: // RingFreq = 136.0M (16M, 24M) ; RingFreq = 135.0M (27M) ; - RingFreq = RingVCO/24; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x08; // ring_div2 /4 (2) R35[1:0] => R36[3:2] - break; - case 1: // RingFreq = 326M (16M, 24M) ; RingFreq = 324.0M (27M) ; - RingFreq = RingVCO/10; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x01; // ring_div1 /5 (1) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x04; // ring_div2 /2 (1) R35[1:0] => R36[3:2] - break; - case 2: // RingFreq = 544M (16M, 24M) ; RingFreq = 540.0M (27M) ; - RingFreq = RingVCO/6; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] - break; - case 3: // RingFreq = 816M (16M, 24M) ; RingFreq = 810.0M (27M) ; - RingFreq = RingVCO/4; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x00; // ring_div1 /4 (0) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] - break; - case 4: // RingFreq = 200M (16M, 24M) ; RingFreq = 202M (27M) ; - RingFreq = RingVCO/16; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x00; // ring_div1 /4 (0) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x08; // ring_div2 /4 (2) R35[1:0] => R36[3:2] - break; - case 5: // RingFreq = 136M (16M, 24M) ; RingFreq = 135.0M (27M) ; - RingFreq = RingVCO/24; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x08; // ring_div2 /4 (2) R35[1:0] => R36[3:2] - break; - case 6: // RingFreq = 326M (16M, 24M) ; RingFreq = 324.0M (27M) ; - RingFreq = RingVCO/10; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x01; // ring_div1 /5 (1) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x04; // ring_div2 /2 (1) R35[1:0] => R36[3:2] - break; - case 7: // RingFreq = 544M (16M, 24M) ; RingFreq = 540.0M (27M) ; - RingFreq = RingVCO/6; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] - break; - case 8: // RingFreq = 816M (16M, 24M) ; RingFreq = 810.0M (27M) ; - RingFreq = RingVCO/4; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x00; // ring_div1 /4 (0) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] - break; - case 9: // RingFreq = 200M (16M, 24M) ; RingFreq = 202M (27M) ; - RingFreq = RingVCO/16; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x00; // ring_div1 /4 (0) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x08; // ring_div2 /4 (2) R35[1:0] => R36[3:2] - break; - default: // RingFreq = 544M (16M, 24M) ; RingFreq = 540.0M (27M) ; - RingFreq = RingVCO/6; - priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] - priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] - break; - } - - //write RingPLL setting, R34[4:0] => R35[4:0] - priv->regs[35] = (priv->regs[35] & 0xE0) | divnum_ring; //ring_div_num, R34[4:0] - - if(RingVCO>=3200000) - priv->regs[35] = (priv->regs[35] & 0xBF); //vco_band=high, R34[7]=0 => R35[6] - else - priv->regs[35] = (priv->regs[35] | 0x40); //vco_band=low, R34[7]=1 => R35[6] - - //write RingPLL setting, R35 - if(r850_wr(priv,35,priv->regs[35])!=0) - return R850_Fail; - - //write RingPLL setting, R36 - if(r850_wr(priv,36,priv->regs[36])!=0) - return R850_Fail; - - //Ring PLL power initial at "min_lp" - /* - //Ring PLL power, R25[2:1] - if((RingFreq>0) && (RingFreqregs[25] = (priv->regs[25] & 0xF9) | 0x04; //R25[2:1]=2'b10; min_lp - else - priv->regs[25] = (priv->regs[25] & 0xF9) | 0x00; //R25[2:1]=2'b00; min - - R850_I2C.RegAddr = 0x19; - R850_I2C.Data = priv->regs[25]; - if(I2C_Write( &R850_I2C) != R850_Success) - return R850_Fail; - */ - - { - //Must do MUX before PLL() - if(R850_MUX( priv,RingFreq - R850_IMR_IF, RingFreq, R850_STD_SIZE) != R850_Success) //IMR MUX (LO, RF) - return R850_Fail; - - priv->R850_IF_GOLOBAL = R850_IMR_IF; - if(R850_PLL(priv, (RingFreq - R850_IMR_IF), R850_STD_SIZE) != R850_Success) //IMR PLL - return R850_Fail; - - //Img_R = normal - priv->regs[19] = (priv->regs[19] & 0xEF); //R20[7]=0 => R19[4]=0 - // Mixer Amp LPF=7 (0 is widest) - priv->regs[19] = (priv->regs[19] & 0xF8) | (7); - if(r850_wr(priv,19,priv->regs[19])!=0) - return R850_Fail; - - - if(IMR_MEM==4) - { - //output atten - priv->regs[36] = (priv->regs[36] & 0xCF) | (0x10); // R41[3:0]=0 - } - else - { - //output atten - priv->regs[36] = (priv->regs[36] & 0xCF) | (0x30); // R41[3:0]=0 - - } - if(r850_wr(priv,36,priv->regs[36])!=0) - return R850_Fail; - - //Mixer Gain = 8 - priv->regs[41] = (priv->regs[41] & 0xF0) | (8); //R41[3:0]=0 - if(r850_wr(priv,41,priv->regs[41])!=0) - return R850_Fail; - - - //clear IQ_cap - //IMR_POINT.Iqcap = priv->regs[19] & 0x3F; - IMR_POINT.Iqcap = 0; - - if(IM_Flag == TRUE) - { - if(R850_IQ( priv, &IMR_POINT) != R850_Success) - return R850_Fail; - } - else //IMR_MEM 1, 0, 3, 4 - { - if((IMR_MEM==1) || (IMR_MEM==3)) - { - IMR_POINT.Gain_X = priv->imr_data[2].Gain_X; //node 3 - IMR_POINT.Phase_Y = priv->imr_data[2].Phase_Y; - IMR_POINT.Value = priv->imr_data[2].Value; - } - else if((IMR_MEM==0) || (IMR_MEM==4)) - { - IMR_POINT.Gain_X = priv->imr_data[1].Gain_X; - IMR_POINT.Phase_Y = priv->imr_data[1].Phase_Y; - IMR_POINT.Value = priv->imr_data[1].Value; - } - - if(R850_F_IMR(priv,&IMR_POINT) != R850_Success) - return R850_Fail; - } - } - - //Save IMR Value - priv->imr_data[IMR_MEM].Gain_X = IMR_POINT.Gain_X; - priv->imr_data[IMR_MEM].Phase_Y = IMR_POINT.Phase_Y; - priv->imr_data[IMR_MEM].Value = IMR_POINT.Value; - priv->imr_data[IMR_MEM].Iqcap = IMR_POINT.Iqcap; - - IMR_Gain = priv->imr_data[IMR_MEM].Gain_X & 0x2F; //R20[3:0] - IMR_Phase = priv->imr_data[IMR_MEM].Phase_Y & 0x2F; //R21[3:0] - - - if(((IMR_Gain & 0x0F)>6) || ((IMR_Phase & 0x0F)>6)) - { - priv->R850_IMR_Cal_Result = 1; //fail - } - - return R850_Success; -} - -//----------------------------------------------------------------------// -// R850_GetRfRssi( ): Get RF RSSI // -// 1st parameter: input RF Freq (KHz) // -// 2nd parameter: input Standard // -// 3rd parameter: output signal level (dBm*1000) // -// 4th parameter: output RF max gain indicator (1:max gain) // -//-----------------------------------------------------------------------// -R850_ErrCode R850_GetRfRssi( struct r850_priv*priv,u32 RF_Freq_Khz, enum R850_Standard_Type RT_Standard, s32 *RfLevelDbm, u8 *fgRfMaxGain) -{ - //u8 bPulseFlag; - struct R850_RF_Gain_Info rf_gain_info; - u16 acc_lna_gain; - u16 acc_rfbuf_gain; - u16 acc_mixer_gain; - u16 rf_total_gain; - u8 u1FreqIndex; - s16 u2FreqFactor=0; - u8 u1LnaGainqFactorIdx; - s32 rf_rssi; - s32 fine_tune = 0; //for find tune - u8 rf_limit; - u8 mixer_limit; - u8 mixer_1315_gain = 0; - u8 filter_limit; - //{50~135, 135~215, 215~265, 265~315, 315~325, 325~345, 345~950} - s8 R850_Start_Gain_Cal_By_Freq[7] = {10, -10, -30, -10, 20, 20, 20}; - u8 buf[6]; - - - r850_rd(priv,0,buf,6); - - //bPulseFlag = ((R850_I2C_Len.Data[1] & 0x40) >> 6); - - rf_gain_info.RF_gain1 = (buf[3] & 0x1F); //lna - rf_gain_info.RF_gain2 = (buf[4] & 0x0F); //rf - rf_gain_info.RF_gain3 = (buf[4] & 0xF0)>>4; //mixer - rf_gain_info.RF_gain4 = (buf[5] & 0x0F); //filter - - - //max gain indicator - if((rf_gain_info.RF_gain1==31) && (rf_gain_info.RF_gain2==15) && (rf_gain_info.RF_gain3==15) && (rf_gain_info.RF_gain4==15)) - *fgRfMaxGain = 1; - else - *fgRfMaxGain = 0; - rf_limit = (((priv->regs[18]&0x04)>>1) + ((priv->regs[16]&0x40)>>6)); - - if(rf_limit==0) - rf_limit = 15; - else if(rf_limit==1) - rf_limit = 11; - else if(rf_limit==2) - rf_limit = 13; - else - rf_limit = 9; - - mixer_limit = (((priv->regs[22]&0xC0)>>6)*2)+6; //0=6, 1=8, 2=10, 3=12 - mixer_1315_gain = ((priv->regs[25]&0x02)>>1); //0:original, 1:ctrl by mixamp (>10) - - if( rf_gain_info.RF_gain2 > rf_limit) - rf_gain_info.RF_gain2 = rf_limit; - - if((rf_gain_info.RF_gain3 > 12)&&(mixer_1315_gain==1)) - mixer_1315_gain = rf_gain_info.RF_gain3; //save 0 or 13 or 14 or 15 - - if( rf_gain_info.RF_gain3 > mixer_limit) - rf_gain_info.RF_gain3 = mixer_limit; - - - filter_limit = (priv->regs[22]&0x01); - if(filter_limit==1) - filter_limit = 15; - else - filter_limit = 13; - - if( rf_gain_info.RF_gain4 > filter_limit) - rf_gain_info.RF_gain4 = filter_limit; - - - //coarse adjustment - if(RF_Freq_Khz<135000) //<135M - { - u1FreqIndex = 0; - u2FreqFactor = R850_Start_Gain_Cal_By_Freq[0]; - } - else if((RF_Freq_Khz>=135000)&&(RF_Freq_Khz<215000)) //135~215M - { - u1FreqIndex = 0; - u2FreqFactor = R850_Start_Gain_Cal_By_Freq[1]; - } - else if((RF_Freq_Khz>=215000)&&(RF_Freq_Khz<265000)) //215~265M - { - u1FreqIndex = 1; - u2FreqFactor = R850_Start_Gain_Cal_By_Freq[2]; - } - else if((RF_Freq_Khz>=265000)&&(RF_Freq_Khz<315000)) //265~315M - { - u1FreqIndex = 1; - u2FreqFactor = R850_Start_Gain_Cal_By_Freq[3]; - } - else if((RF_Freq_Khz>=315000)&&(RF_Freq_Khz<325000)) //315~325M - { - u1FreqIndex = 1; - u2FreqFactor = R850_Start_Gain_Cal_By_Freq[4]; - } - else if((RF_Freq_Khz>=325000)&&(RF_Freq_Khz<345000)) //325~345M - { - u1FreqIndex = 1; - u2FreqFactor = R850_Start_Gain_Cal_By_Freq[5]; - } - else if((RF_Freq_Khz>=345000)&&(RF_Freq_Khz<420000)) //345~420M - { - u1FreqIndex = 1; - u2FreqFactor = R850_Start_Gain_Cal_By_Freq[6]; - } - else if((RF_Freq_Khz>=420000)&&(RF_Freq_Khz<710000)) //420~710M - { - u1FreqIndex = 2; - u2FreqFactor = R850_Start_Gain_Cal_By_Freq[6]; - - } - else // >=710 - { - u1FreqIndex = 3; - u2FreqFactor = R850_Start_Gain_Cal_By_Freq[6]; - } - - - //LNA Gain - acc_lna_gain = R850_Lna_Acc_Gain[u1FreqIndex][rf_gain_info.RF_gain1]; - - - - //fine adjustment - //Cal LNA Gain by Freq - - //Method 2 : All frequencies are finely adjusted.. - - - if(rf_gain_info.RF_gain1 >= 10) - { - u1LnaGainqFactorIdx = (u8) ((RF_Freq_Khz-50000) / 10000); - - if( ((RF_Freq_Khz-50000) - (u1LnaGainqFactorIdx * 10000))>=5000) - u1LnaGainqFactorIdx +=1; - acc_lna_gain += (u16)(Lna_Acc_Gain_offset[u1LnaGainqFactorIdx]); - - } - - //RF buf - acc_rfbuf_gain = R850_Rf_Acc_Gain[rf_gain_info.RF_gain2]; - if(RF_Freq_Khz<=300000) - acc_rfbuf_gain += (rf_gain_info.RF_gain2 * 1); - else if (RF_Freq_Khz>=600000) - acc_rfbuf_gain -= (rf_gain_info.RF_gain2 * 1); - - //Mixer - acc_mixer_gain = R850_Mixer_Acc_Gain [rf_gain_info.RF_gain3] ; - - if((mixer_1315_gain!=0) && (mixer_1315_gain!=1)) //Gain 13 or 14 or 15 - acc_mixer_gain = acc_mixer_gain + (R850_Mixer_Acc_Gain[mixer_1315_gain] - R850_Mixer_Acc_Gain[12]); - - - - //Add Rf Buf and Mixer Gain - rf_total_gain = acc_lna_gain + acc_rfbuf_gain + acc_mixer_gain + rf_gain_info.RF_gain4*153/10; - - rf_rssi = fine_tune - (s32) (rf_total_gain - u2FreqFactor); - - - *RfLevelDbm = rf_rssi*100; - - return R850_Success; -} - - -//-----------------------------------------------------------------------// -// R850_GetIfRssi( ): Get IF VGA GAIN // -// 1st parameter: return IF VGA Gain (dB*100) // -//-----------------------------------------------------------------------// -R850_ErrCode R850_GetIfRssi(struct r850_priv*priv,s32 *VgaGain) -{ - u8 adc_read; - u8 buf[2]; - //Optimize value - u16 vga_table[64] = { //*100 - 0, 0, 20, 20, 30, 50, 60, 80, 110, 130, 130, 160, //0~11 - 200, 240, 280, 330, 380, 410, 430, 480, 530, 590, //12~21 - 640, 690, 730, 760, 780, 810, 840, 890, 930, 950, //22~31 - 980, 1010, 1010, 1030, 1060, 1100, 1120, 1140, 1170, 1180, //32~41 - 1190, 1210, 1220, 1260, 1270, 1300, 1320, 1320, 1340, 1340, //42~51 - 1360, 1390, 1400, 1420, 1440, 1450, 1460, 1480, 1490, 1510, //52~61 - 1550, 1600 //62~63 - }; - - //ADC sel : vagc, R22[3:2]=2 - priv->regs[22] = (priv->regs[22] & 0xF3) | 0x08; - if(r850_wr(priv,22,priv->regs[22]) != 0) - return R850_Fail; - - //IF_AGC read, R18[5]=1 - priv->regs[18] = priv->regs[18] | 0x20; - if(r850_wr(priv,18,priv->regs[18]) != 0) - return R850_Fail; - - //ADC power on, R11[1]=0 - priv->regs[11] = priv->regs[11] & 0xFD; - if(r850_wr(priv,11,priv->regs[11]) != 0) - return R850_Fail; - - //read adc value - r850_rd(priv,0x00,buf,2); - adc_read = (buf[1] & 0x3F); - - *VgaGain = vga_table[adc_read]; - - return R850_Success; -} - - -// R850_GetRfRssi( ): Get RF RSSI // -// 1st parameter: input RF Freq (KHz) // -// 2nd parameter: input Standard // -// 3rd parameter: return signal level indicator (dBm) // -//-----------------------------------------------------------------------// -R850_ErrCode R850_GetTotalRssi( struct r850_priv*priv, u32 RF_Freq_Khz, enum R850_Standard_Type RT_Standard, s32 *RssiDbm) -{ - s32 rf_rssi; - s32 if_rssi; - s32 rem, total_rssi; - s32 ssi_offset = 0; //need to fine tune by platform - s32 total_rssi_dbm; - u8 rf_max_gain_flag; - - R850_GetRfRssi(priv, RF_Freq_Khz, RT_Standard, &rf_rssi, &rf_max_gain_flag); - - R850_GetIfRssi(priv, &if_rssi); //vga gain - - total_rssi = rf_rssi - (if_rssi*10); - rem = total_rssi - (total_rssi/1000)*1000; //for rounding - if((rem>-500) && (rem<500)) - total_rssi_dbm = (total_rssi/1000); - else if(rem<=-500) - total_rssi_dbm = (total_rssi/1000)-1; - else - total_rssi_dbm = (total_rssi/1000)+1; - - //for different platform, need to fine tune offset value - *RssiDbm = total_rssi_dbm + ssi_offset+8; - - return R850_Success; -} - -u8 R850_Filt_Cal_ADC(struct r850_priv *priv, u32 IF_Freq, u8 R850_BW, u8 FilCal_Gap) -{ - u8 u1FilterCodeResult = 0; - u8 u1FilterCode = 0; - u8 u1FilterCalValue = 0; - u8 u1FilterCalValuePre = 0; - u8 initial_cnt = 0; - u8 i = 0; - //u32 RingVCO = 0; - u32 RingFreq = 72000; - u8 ADC_Read_Value = 0; - u8 ADC_Read_Value_8M5Hz = 0; - u8 LPF_Count = 0; - //u32 RingRef = R850_Xtal; - //u8 divnum_ring = 0; - //u8 VGA_Count = 0; - - - if(R850_Cal_Prepare(priv, R850_LPF_CAL) != R850_Success) - return R850_Fail; - - priv->R850_IF_GOLOBAL = IF_Freq; - //Set PLL (TBD, normal) - if(R850_PLL(priv, (RingFreq - IF_Freq), R850_STD_SIZE) != R850_Success) //FilCal PLL - return R850_Fail; - - //------- increase Filter gain to let ADC read value significant ---------// - for(LPF_Count=5; LPF_Count < 16; LPF_Count ++) - { - - priv->regs[41] = (priv->regs[41] & 0x0F) | (LPF_Count<<4); - if(r850_wr(priv,41,priv->regs[41]) != 0) - return R850_Fail; - - msleep( R850_FILTER_GAIN_DELAY); // - - if(R850_Muti_Read(priv, &ADC_Read_Value) != R850_Success) - return R850_Fail; - - if(ADC_Read_Value > 40*R850_ADC_READ_COUNT) - { - break; - } - } - - - //If IF_Freq>10MHz, need to compare 8.5MHz ADC Value, - //If the ADC values greater than 8 in the same gain,the filter corner select 8M / 0 - if(IF_Freq>=10000) - { - priv->R850_IF_GOLOBAL = 8500; - //Set PLL (TBD, normal) - if(R850_PLL( priv,(RingFreq - 8500), R850_STD_SIZE) != R850_Success) //FilCal PLL - return R850_Fail; - - msleep( R850_FILTER_GAIN_DELAY); // - - if(R850_Muti_Read( priv,&ADC_Read_Value_8M5Hz) != R850_Success) - return R850_Fail; - - if(ADC_Read_Value_8M5Hz > (ADC_Read_Value + 8) ) - { - //priv->bw = 0; //8M - u1FilterCodeResult = 0; - return u1FilterCodeResult; - } - else - { - priv->R850_IF_GOLOBAL = IF_Freq; - //Set PLL (TBD, normal) - if(R850_PLL(priv, (RingFreq - IF_Freq), R850_STD_SIZE) != R850_Success) //FilCal PLL - return R850_Fail; - } - } - - - - //------- Try suitable BW --------// - if(R850_BW==2) //6M - initial_cnt = 1; //try 7M first - else - initial_cnt = 0; //try 8M first - - for(i=initial_cnt; i<3; i++) - { - - //Set BW R22[5:4] => R23[6:5] - priv->regs[23] = (priv->regs[23] & 0xCF); - if(r850_wr(priv,23,priv->regs[23]) != 0) - return R850_Fail; - - // read code 0 R22[4:1] => R23[4:1] - priv->regs[23] = (priv->regs[23] & 0xE1); //code 0 - if(r850_wr(priv,23,priv->regs[23]) != 0) - return R850_Fail; - - msleep( R850_FILTER_CODE_DELAY); //delay ms - - if(R850_Muti_Read(priv, &u1FilterCalValuePre) != R850_Success) - return R850_Fail; - - //read code 26 R22[4:1] => R23[4:1] - priv->regs[23] = (priv->regs[23] & 0xE1) | (13<<1); //code 26 - if(r850_wr(priv,23,priv->regs[23]) != 0) - return R850_Fail; - - msleep( R850_FILTER_CODE_DELAY); //delay ms - - if(R850_Muti_Read(priv, &u1FilterCalValue) != R850_Success) - return R850_Fail; - - if(u1FilterCalValuePre > (u1FilterCalValue+16)) //suitable BW found - break; - } - - //-------- Try LPF filter code ---------// - u1FilterCalValuePre = 0; - for(u1FilterCode=0; u1FilterCode<16; u1FilterCode++) - { - priv->regs[23] = (priv->regs[23] & 0xE1) | (u1FilterCode<<1); - if(r850_wr(priv,23,priv->regs[23]) != 0) - - return R850_Fail; - - msleep( R850_FILTER_CODE_DELAY); //delay ms - - if(R850_Muti_Read(priv, &u1FilterCalValue) != R850_Success) - return R850_Fail; - - if((IF_Freq>=10000)&&(u1FilterCode==0)) - { - u1FilterCalValuePre = ADC_Read_Value_8M5Hz; - } - else if(u1FilterCode==0) - { - u1FilterCalValuePre = u1FilterCalValue; - } - - if((u1FilterCalValue+FilCal_Gap*R850_ADC_READ_COUNT) < u1FilterCalValuePre) - { - u1FilterCodeResult = u1FilterCode; - break; - } - } - - //Try LSB bit - if(u1FilterCodeResult>0) //try code-1 & lsb=1 - { - - priv->regs[23] = (priv->regs[23] & 0xE0) | ((u1FilterCodeResult-1)<<1) | 0x01; - if(r850_wr(priv,23,priv->regs[23]) != 0) - return R850_Fail; - - msleep( R850_FILTER_GAIN_DELAY); //delay ms - - if(R850_Muti_Read( priv,&u1FilterCalValue) != R850_Success) - return R850_Fail; - - if((u1FilterCalValue+FilCal_Gap*R850_ADC_READ_COUNT) < u1FilterCalValuePre) - { - u1FilterCodeResult = u1FilterCodeResult - 1; - } - - } - - if(u1FilterCode==16) - u1FilterCodeResult = 15; - - return u1FilterCodeResult; - -} - -R850_ErrCode R850_SetStandard(struct r850_priv *priv, enum R850_Standard_Type RT_Standard) -{ - u8 u1FilCalGap = 16; - - //HPF ext protection - if(priv->fc.flag== 0) - { - priv->fc.code = R850_Filt_Cal_ADC(priv, priv->R850_Sys_Info.FILT_CAL_IF, priv->R850_Sys_Info.BW, u1FilCalGap); - priv->fc.bw = 0; - priv->fc.flag = 1; - priv->fc.lpflsb = 0; - - //Reset register and Array - if(R850_InitReg(priv) != R850_Success) - return R850_Fail; - } - // Set LPF Lsb bit - priv->regs[23] = (priv->regs[23] & 0xFE) ; //R23[0] - // Set LPF fine code - priv->regs[23] = (priv->regs[23] & 0xE1) | (priv->fc.code<<1); //R23[4:1] - // Set LPF coarse BW - priv->regs[23] = (priv->regs[23] & 0x9F) | (priv->fc.bw<<5); //R23[6:5] - //Set HPF notch R23[7] - priv->regs[23] = (priv->regs[23] & 0x7F) | (priv->R850_Sys_Info.HPF_NOTCH<<7); - if(r850_wr(priv,23,priv->regs[23]) != 0) - return R850_Fail; - - - // Set HPF corner - priv->regs[24] = (priv->regs[24] & 0x0F) | (priv->R850_Sys_Info.HPF_COR<<4); //R24[3:0] => R24[7:4] - if(r850_wr(priv,24,priv->regs[24]) != 0) - return R850_Fail; - - - // Set Filter Auto Ext - priv->regs[18] = (priv->regs[18] & 0xBF) | (priv->R850_Sys_Info.FILT_EXT_ENA<<6); // =>R18[6] - if(r850_wr(priv,18,priv->regs[18]) != 0) - return R850_Fail; - - //set Filter Comp //R24[3:2] - priv->regs[24] = (priv->regs[24] & 0xF3) | (priv->R850_Sys_Info.FILT_COMP<<2); - if(r850_wr(priv,24,priv->regs[24]) != 0) - return R850_Fail; - - // Set AGC clk R47[3:2] - priv->regs[47] = (priv->regs[47] & 0xF3) | (priv->R850_Sys_Info.AGC_CLK<<2); - if(r850_wr(priv,47,priv->regs[47]) != 0) - return R850_Fail; - - priv->regs[44] = (priv->regs[44] & 0xFE) | ((priv->R850_Sys_Info.IMG_GAIN & 0x02)>>1); - if(r850_wr(priv,44,priv->regs[44]) != 0) - return R850_Fail; - - priv->regs[46] = (priv->regs[46] & 0xEF) | ((priv->R850_Sys_Info.IMG_GAIN & 0x01)<<4); - if(r850_wr(priv,46,priv->regs[46]) != 0) - return R850_Fail; - - return R850_Success; -} - - - -R850_ErrCode R850_SetFrequency(struct r850_priv *priv, struct R850_Set_Info R850_INFO) //Write Multi byte -{ - - u32 LO_KHz; - u8 Img_R; - u8 SetFreqArrayCunt; - int ret = 0; - - struct R850_SysFreq_Info_Type SysFreq_Info1; - - //Get Sys-Freq parameter - - SysFreq_Info1 = R850_SysFreq_NrbDetOn_Sel( R850_INFO.R850_Standard, R850_INFO.RF_KHz); - - //R850_IMR_point_num = Freq_Info1.IMR_MEM_NOR; - - // Check Input Frequency Range - if((R850_INFO.RF_KHz<40000) || (R850_INFO.RF_KHz>1002000)) - { - return R850_Fail; - } - - - - LO_KHz = R850_INFO.RF_KHz + priv->R850_Sys_Info.IF_KHz; - Img_R = 0; - - priv->regs[19] = (priv->regs[19] & 0xEF) | (Img_R<<4); //R20[7] => R19[4] - if(r850_wr(priv,19,priv->regs[19])) - return R850_Fail; - - - //Set MUX dependent var. Must do before PLL() - if(R850_MUX( priv,LO_KHz, R850_INFO.RF_KHz, R850_INFO.R850_Standard) != R850_Success) //normal MUX - return R850_Fail; - - priv->R850_IF_GOLOBAL = priv->R850_Sys_Info.IF_KHz; - //Set PLL - if(R850_PLL(priv, LO_KHz, R850_INFO.R850_Standard) != R850_Success) //noraml PLL - return R850_Fail; - - // PW - // Set NA det power R10[6] - //if(R850_External_LNA == 0) //External LNA Disable => depend on setting - priv->regs[10] = (priv->regs[10] & 0xBF) | (SysFreq_Info1.NA_PWR_DET<<6); -// else //External LNA Enable => fixed - // priv->regs[R850_I2C.RegAddr] = (priv->regs[R850_I2C.RegAddr] & 0xBF); - - //Set Man Buf Cur R16[5] -// if(R850_External_LNA == 0) //External LNA Disable => depend on initial value - priv->regs[16] = (priv->regs[16] & 0xDF) | (R850_iniArray[0][16] & 0x20); -// else //External LNA Enable => fixed -// priv->regs[R850_I2C.RegAddr] = (priv->regs[R850_I2C.RegAddr] | 0x20); - - - //LNA_NRB_DET R11[7] - priv->regs[11] = (priv->regs[11] & 0x7F) | (SysFreq_Info1.LNA_NRB_DET<<7); - - //LNA - // LNA_TOP R38[2:0] - priv->regs[38] = (priv->regs[38] & 0xF8) | (7 - SysFreq_Info1.LNA_TOP); - - // LNA VTL/H R39[7:0] - priv->regs[39] = (priv->regs[39 ] & 0x00) | SysFreq_Info1.LNA_VTL_H; - - // RF_LTE_PSG R17[4] - priv->regs[17] = (priv->regs[17 ] & 0xEF) | (SysFreq_Info1.RF_LTE_PSG<<4); - - //RF - // RF TOP R38[6:4] - priv->regs[38] = (priv->regs[38] & 0x8F) | ((7 - SysFreq_Info1.RF_TOP)<<4); - - // RF VTL/H R42[7:0] - priv->regs[42] = (priv->regs[42] & 0x00) | SysFreq_Info1.RF_VTL_H; - - // RF Gain Limt (MSB:R18[2] & LSB:R16[6]) - switch(SysFreq_Info1.RF_GAIN_LIMIT) - { - case 0://'b00 - priv->regs[18] = (priv->regs[18] & 0xFB); - priv->regs[16] = (priv->regs[16] & 0xBF); - break; - case 1://'b01 - priv->regs[18] = (priv->regs[18] & 0xFB); - priv->regs[16] = (priv->regs[16] | 0x40); - break; - case 2://'b10 - priv->regs[18] = (priv->regs[18] | 0x02); - priv->regs[16] = (priv->regs[16] & 0xBF); - break; - case 3://'b11 - priv->regs[18] = (priv->regs[18] | 0x02); - priv->regs[16] = (priv->regs[16] | 0x40); - break; - } - - //MIXER & FILTER - //MIXER_AMP_LPF R19[2:0] - priv->regs[19] = (priv->regs[19] & 0xF8) | SysFreq_Info1.MIXER_AMP_LPF; - - // MIXER TOP R40[3:0] - priv->regs[40] = (priv->regs[40] & 0xF0) | (15 - SysFreq_Info1.MIXER_TOP); - - // Filter TOP R44[3:0] for MP, R44[3:1] for MT1 - priv->regs[44] = (priv->regs[44] & 0xF1) | ((7-SysFreq_Info1.FILTER_TOP)<<1); - - //FILT_3TH_LPF_CUR=0; //R10[4] [high (0), low (1)] - priv->regs[10] = (priv->regs[10] & 0xEF) | (SysFreq_Info1.FILT_3TH_LPF_CUR<<4); - - // 3th_LPF_Gain R24[1:0] - priv->regs[24] = (priv->regs[24] & 0xFC) | SysFreq_Info1.FILT_3TH_LPF_GAIN; - - priv->regs[19] = (priv->regs[19] & 0x7F) | 0x80; - // MIXER VTH & Filter VTH R41[7:0] - priv->regs[41] = ((priv->regs[41] & 0x00) | SysFreq_Info1.MIXER_VTH | SysFreq_Info1.FILTER_VTH); - - // MIXER VTL & Filter VTL R43[7:0] - priv->regs[43] = ((priv->regs[43] & 0x00) | SysFreq_Info1.MIXER_VTL | SysFreq_Info1.FILTER_VTL); - - // Mixer Gain Limt R22[7:6] - priv->regs[22] = (priv->regs[22] & 0x3F) | (SysFreq_Info1.MIXER_GAIN_LIMIT << 6); - - // MIXER_DETBW_LPF R46[7] - priv->regs[46] = (priv->regs[46] & 0x7F) | (SysFreq_Info1.MIXER_DETBW_LPF << 7); - - //Discharge - //LNA_RF Discharge Mode (R45[1:0]=2'b01; R9[6]=1) => (R45[1:0]=0'b00; R31[0]=1 ;R32[5]=1) - if(SysFreq_Info1.LNA_RF_DIS_MODE==0) //auto (normal) - { - priv->regs[45] = (priv->regs[45] & 0xFC) | 0x00; //00 - priv->regs[31] = (priv->regs[31] & 0xFE) | 0x01; //1 - priv->regs[32] = (priv->regs[32] & 0xDF) | 0x20; //1 - } - else if(SysFreq_Info1.LNA_RF_DIS_MODE==1) //both(fast+slow) - { - priv->regs[45] = (priv->regs[45] & 0xFC) | 0x03; //11 - priv->regs[31] = (priv->regs[31] & 0xFE) | 0x01; //1 - priv->regs[32] = (priv->regs[32] & 0xDF) | 0x20; //1 - } - else if(SysFreq_Info1.LNA_RF_DIS_MODE==2) //both(slow) - { - priv->regs[45] = (priv->regs[45] & 0xFC) | 0x03; //11 - priv->regs[31] = (priv->regs[31] & 0xFE) | 0x00; //0 - priv->regs[32] = (priv->regs[32] & 0xDF) | 0x00; //0 - } - else if(SysFreq_Info1.LNA_RF_DIS_MODE==3) //LNA(slow) - { - priv->regs[45] = (priv->regs[45] & 0xFC) | 0x03; //11 - priv->regs[31] = (priv->regs[31] & 0xFE) | 0x01; //1 - priv->regs[32] = (priv->regs[32] & 0xDF) | 0x00; //0 - } - else if(SysFreq_Info1.LNA_RF_DIS_MODE==4) //RF(slow) - { - priv->regs[45] = (priv->regs[45] & 0xFC) | 0x03; //11 - priv->regs[31] = (priv->regs[31] & 0xFE) | 0x00; //0 - priv->regs[32] = (priv->regs[32] & 0xDF) | 0x20; //1 - } - else - { - priv->regs[45] = (priv->regs[45] & 0xFC) | 0x00; //00 - priv->regs[31] = (priv->regs[31] & 0xFE) | 0x01; //1 - priv->regs[32] = (priv->regs[32] & 0xDF) | 0x20; //1 - } - - //LNA_RF_CHARGE_CUR R31[1] - priv->regs[31] = (priv->regs[31] & 0xFD) | (SysFreq_Info1.LNA_RF_CHARGE_CUR<<1); - - //LNA_RF_dis current R13[5] - priv->regs[13] = (priv->regs[13] & 0xDF) | (SysFreq_Info1.LNA_RF_DIS_CURR<<5); - - //RF_slow disch(5:4) / fast disch(7:6) //(R45[7:4]) - priv->regs[45] = (priv->regs[45] & 0x0F) | (SysFreq_Info1.RF_DIS_SLOW_FAST<<4); - - //LNA slow disch(5:4) / fast disch(7:6) => R44[7:4] - priv->regs[44] = (priv->regs[44] & 0x0F) | (SysFreq_Info1.LNA_DIS_SLOW_FAST<<4); - - //BB disch current R25[6] - priv->regs[25] = (priv->regs[25] & 0xBF) | (SysFreq_Info1.BB_DIS_CURR<<6); - - //Mixer/Filter disch R37[7:6] - priv->regs[37] = (priv->regs[37] & 0x3F) | (SysFreq_Info1.MIXER_FILTER_DIS<<6); - - //BB Det Mode R37[2] - priv->regs[37] = (priv->regs[37] & 0xFB) | (SysFreq_Info1.BB_DET_MODE<<2); - - //Polyphase - //ENB_POLY_GAIN R25[1] - priv->regs[25] = (priv->regs[25] & 0xFD) | (SysFreq_Info1.ENB_POLY_GAIN<<1); - - //NRB - // NRB TOP R40[7:4] - priv->regs[40] = (priv->regs[40] & 0x0F) | ((15 - SysFreq_Info1.NRB_TOP)<<4); - - //NRB LPF & HPF BW R26[7:6 & 3:2] - priv->regs[26] = (priv->regs[26] & 0x33) | (SysFreq_Info1.NRB_BW_HPF<<2) | (SysFreq_Info1.NRB_BW_LPF<<6); - - //NBR Image TOP adder R46[3:2] - priv->regs[46] = (priv->regs[46] & 0xF3) | (SysFreq_Info1.IMG_NRB_ADDER<<2); - - //VGA - //HPF_COMP R13[2:1] - priv->regs[13] = (priv->regs[13] & 0xF9) | (SysFreq_Info1.HPF_COMP<<1); - - //FB_RES_1ST //R21[4] - priv->regs[21] = (priv->regs[21] & 0xEF) | (SysFreq_Info1.FB_RES_1ST<<4); - - //DEGLITCH_CLK; R38[3] - priv->regs[38] = (priv->regs[38] & 0xF7) | (SysFreq_Info1.DEGLITCH_CLK<<3); - - //NAT_HYS; R35[6] - priv->regs[35] = (priv->regs[35] & 0xBF) | (SysFreq_Info1.NAT_HYS<<6); - - //NAT_CAIN; R31[4:5] - priv->regs[31] = (priv->regs[31] & 0xCF) | (SysFreq_Info1.NAT_CAIN<<4); - - //PULSE_HYS; R26[1:0] - priv->regs[26] = (priv->regs[26] & 0xFC) | (SysFreq_Info1.PULSE_HYS); - - //FAST_DEGLITCH; R36[3:2] - priv->regs[36] = (priv->regs[36] & 0xF3) | (SysFreq_Info1.FAST_DEGLITCH<<2); - - //PUL_RANGE_SEL; R31[2] - priv->regs[31] = (priv->regs[31] & 0xFB) | (SysFreq_Info1.PUL_RANGE_SEL<<2); - - //PUL_FLAG_RANGE; R35[1:0] - priv->regs[35] = (priv->regs[35] & 0xFC) | (SysFreq_Info1.PUL_FLAG_RANGE); - - //PULG_CNT_THRE; R17[1] - priv->regs[17] = (priv->regs[17] & 0xFD) | (SysFreq_Info1.PULG_CNT_THRE<<1); - - //FORCE_PULSE; R46[5] - priv->regs[46] = (priv->regs[46] & 0xDF) | (SysFreq_Info1.FORCE_PULSE<<5); - - //FLG_CNT_CLK; R47[7:6] - priv->regs[47] = (priv->regs[47] & 0x3F) | (SysFreq_Info1.FLG_CNT_CLK<<6); - - //NATG_OFFSET; R36[5:4] - priv->regs[36] = (priv->regs[36] & 0xCF) | (SysFreq_Info1.NATG_OFFSET<<4); - //other setting - - // Set AGC clk R47[3:2] only for isdbt 4.063 (set 1Khz because Div/4, original agc clk is 512Hz) - if( (R850_INFO.RF_KHz >= 478000) && (R850_INFO.RF_KHz < 482000) && (R850_INFO.R850_Standard == R850_ISDB_T_4063) ) - { - priv->regs[47] = (priv->regs[47] & 0xF3); - } - - - //IF AGC1 - priv->regs[25] = priv->regs[25] & 0xDF; - - - //Set LT - if(R850_INFO.R850_LT==R850_LT_ON) - { - //LT Sel: active LT(after LNA) R8[6]=1 ; acLT PW: ON R8[7]=1 - priv->regs[8] = (priv->regs[8] | 0xC0 ); - //Pulse LT on R10[1]=1 - priv->regs[10] = (priv->regs[10] | 0x02); - } - else - { - //LT Sel: active LT(after LNA) R8[6]=1 ; acLT PW: OFF R8[7]=0 - priv->regs[8] = ((priv->regs[8] | 0x40) & 0x7F); - //Pulse LT on R10[1]=0 - priv->regs[10] = (priv->regs[10] & 0xFD); - } - - - //Set Clk Out - if(R850_INFO.R850_ClkOutMode==R850_CLK_OUT_OFF) - { - priv->regs[34] = (priv->regs[34] | 0x04); //no clk out R34[2] = 1 - } - else - { - priv->regs[34] = (priv->regs[34] & 0xFB); //clk out R34[2] = 0 - } - - ret = r850_wrm(priv,8,&priv->regs[8],40); - if(ret!=0) - return R850_Fail; - - - return R850_Success; -} - - -static int r850_init(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct r850_priv *priv = fe->tuner_priv; - - int ret = 0; - - if(priv->inited) - return ret; - - priv->fc.bw = 0x00; - priv->fc.code = 0; - priv->fc.lpflsb = 0; - priv->fc.flag =0; - - priv->R850_Sys_Info.IF_KHz=5000; - priv->R850_Sys_Info.BW=0; //BW=8M R23[6:5] [8M(0), 7M(1), 6M(2)] - priv->R850_Sys_Info.FILT_CAL_IF=8800; //CAL IF - priv->R850_Sys_Info.HPF_COR=11; //R24[7:4] [0~15 ; input: "0~15"] - priv->R850_Sys_Info.FILT_EXT_ENA=0; //R18[6] filter ext disable [off(0), on(1)] - priv->R850_Sys_Info.FILT_COMP=2; //R24[3:2] [0~3 ; input: "0~3"] - priv->R850_Sys_Info.AGC_CLK = 1; //R47[3:2] 1k [1kHz(0), 512Hz(1), 4kHz(2), 64Hz(3)] - priv->R850_Sys_Info.IMG_GAIN = 2; ////MSB:R44[0] , LSB:R46[4] highest [lowest(0), high(1), low(2), highest(3)] - - priv->R850_clock_out = 0; - priv->R850_IMR_Cal_Result = 0; - - priv->R850_Xtal_cap = 29; - priv->R850_IF_GOLOBAL = 6000; - priv->R850_XtalDiv = R850_XTAL_DIV1; - - priv->R850_IMR_done_flag = 0; - priv->R850_IMR_Cal_Result = 0; - - - if(R850_Cal_Prepare(priv, R850_IMR_CAL) != R850_Success) - ret=-1; - - - if(R850_IMR(priv,2, TRUE) != R850_Success) //Full K node 2 - ret=-1; - - if(R850_IMR(priv, 1, FALSE) != R850_Success) - ret=-1; - - if(R850_IMR(priv, 0, FALSE) != R850_Success) - ret=-1; - - if(R850_IMR(priv, 3, FALSE) != R850_Success) - ret=-1; - - if(R850_IMR(priv, 4, FALSE) != R850_Success) - ret=-1; - - priv->R850_IMR_done_flag = 1; - - //do Xtal check - - if(priv->R850_clock_out == 1) - { - priv->R850_Xtal_Pwr = R850_XTAL_HIGHEST; - } - else //==0 - { - priv->R850_Xtal_Pwr = R850_XTAL_LOWEST; - } - - //write initial reg - if(R850_InitReg(priv) != R850_Success) - ret=-1; - - priv->inited = 1; - - /* init statistics in order signal app which are supported */ - c->strength.len = 1; - c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - - return ret; - -} - -static int r850_set_params(struct dvb_frontend *fe) -{ - struct r850_priv *priv = fe->tuner_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct R850_Set_Info tuner_parameters; - - int ret = 0; - - if(!priv->inited) - r850_init(fe); - - tuner_parameters.RF_KHz = c->frequency /1000; - - tuner_parameters.R850_LT=R850_LT_ON; - tuner_parameters.R850_ClkOutMode=R850_CLK_OUT_OFF; - tuner_parameters.R850_Standard = R850_DTMB_8M_IF_5M; - - - - if(R850_SetStandard(priv,R850_DTMB_8M_IF_5M) != R850_Success) - ret=-1; - - if(R850_SetFrequency(priv, tuner_parameters) != R850_Success) - ret=-1; - - return ret; -} -static int r850_get_rf_strength(struct dvb_frontend *fe, u16 *rssi) -{ - struct r850_priv *priv = fe->tuner_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - s32 RSSI_Value = 0; - int strength; - - R850_GetTotalRssi(priv,c->frequency/1000,R850_DTMB_8M_IF_5M,&RSSI_Value); - - if(RSSI_Value>-70) - RSSI_Value+=8; - - c->strength.len = 2; - c->strength.stat[0].scale = FE_SCALE_DECIBEL; - c->strength.stat[0].svalue = (s8)RSSI_Value * 1000; - - if(RSSI_Value<-85) - RSSI_Value = -80; - if(RSSI_Value> -50) - RSSI_Value = -20; - - strength = (85+RSSI_Value)*100/65+20; - - if(strength>100) - strength=100; - - c->strength.stat[1].scale = FE_SCALE_RELATIVE; - c->strength.stat[1].uvalue = strength*655; - - *rssi =(u16)(strength*655); - - return 0; -} -static void r850_release(struct dvb_frontend *fe) -{ - struct r850_priv *priv = fe->tuner_priv; - dev_dbg(&priv->i2c->dev, "%s()\n", __func__); - - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; -} - -static int r850_sleep(struct dvb_frontend *fe) -{ - struct r850_priv *priv = fe->tuner_priv; - int ret = 0; - dev_dbg(&priv->i2c->dev, "%s()\n", __func__); - - //if (ret) - // dev_dbg(&priv->i2c->dev, "%s() failed\n", __func__); - return ret; -} - -static const struct dvb_tuner_ops r850_tuner_ops = { - .info = { - .name = "Rafael R850", -// .frequency_min_hz = 250 * MHz, -// .frequency_max_hz = 2300 * MHz, - }, - - .release = r850_release, - - .init = r850_init, - .sleep = r850_sleep, - .set_params = r850_set_params, - .get_rf_strength = r850_get_rf_strength, -}; - -struct dvb_frontend *r850_attach(struct dvb_frontend *fe, - struct r850_config *cfg, struct i2c_adapter *i2c) -{ - struct r850_priv *priv = NULL; - u8 chip_id; - u8 buf[50]; - int ret = 0; - - priv = kzalloc(sizeof(struct r850_priv), GFP_KERNEL); - if (priv == NULL) { - dev_dbg(&i2c->dev, "%s() attach failed\n", __func__); - return NULL; - } - - priv->cfg = cfg; - priv->i2c = i2c; - - priv->inited = 0; - - ret = r850_rd(priv,0x00,buf,48); - if(ret!=0) - return NULL; - - dev_info(&priv->i2c->dev, - "%s: Rafael R850 successfully attached,id is 0x%x\n", - KBUILD_MODNAME,buf[0]); - - memcpy(&fe->ops.tuner_ops, &r850_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = priv; - return fe; -} - -EXPORT_SYMBOL_GPL(r850_attach); - -MODULE_DESCRIPTION("Rafael R850 tuner driver"); -MODULE_AUTHOR("Davin"); -MODULE_LICENSE("GPL"); - +#include +#include "r850.h" +#include "r850_priv.h" + +static int r850_rd(struct r850_priv *priv,u8 reg, u8 *buf,u8 len) +{ + int ret,i; + + struct i2c_msg msg[2]={ + { + .addr = priv->cfg->i2c_address, + .flags = 0, .buf = ®, .len = 1 + },{ + .addr = priv->cfg->i2c_address, + .flags = I2C_M_RD, .buf = buf, .len = len + } + }; + ret = i2c_transfer(priv->i2c, msg, 2); + if (ret == 2) { + for (i = 0; i < len; i++) + buf[i] = bitrev8(buf[i]); + ret = 0; + } else { + dev_warn(&priv->i2c->dev, "%s: i2c tuner rd failed=%d " \ + "len=%d\n", KBUILD_MODNAME, ret, len); + ret = -EREMOTEIO; + } + return ret; + +} +static int r850_wrm(struct r850_priv *priv,u8 reg, u8 *val,u8 len) +{ + int ret; + u8 buf[len + 1]; + + memcpy(&buf[1], val, len); + buf[0] = reg; + + struct i2c_msg msg = { + .addr = priv->cfg->i2c_address, + .flags = 0, .buf = buf, .len = len + 1 }; + + + ret = i2c_transfer(priv->i2c, &msg, 1); + if (ret == 1) { + ret = 0; + } else { + dev_warn(&priv->i2c->dev, "%s: i2c tuner wr failed=%d " \ + "len=%d\n", KBUILD_MODNAME, ret, len); + ret = -EREMOTEIO; + } + return ret; + +} +static int r850_wr(struct r850_priv *priv,u8 reg, u8 val) +{ + return r850_wrm(priv,reg,&val,1); +} +struct R850_Freq_Info_Type R850_Freq_Sel(u32 LO_freq, u32 RF_freq, enum R850_Standard_Type R850_Standard) +{ + struct R850_Freq_Info_Type R850_Freq_Info; + + + //----- LO dependent parameter -------- + + //IMR point + if((LO_freq>0) && (LO_freq<170000)) + { + R850_Freq_Info.IMR_MEM_NOR = 0; + R850_Freq_Info.IMR_MEM_REV = 5; + } + else if((LO_freq>=170000) && (LO_freq<240000)) + { + R850_Freq_Info.IMR_MEM_NOR = 4; + R850_Freq_Info.IMR_MEM_REV = 9; + } + else if((LO_freq>=240000) && (LO_freq<400000)) + { + R850_Freq_Info.IMR_MEM_NOR = 1; + R850_Freq_Info.IMR_MEM_REV = 6; + } + else if((LO_freq>=400000) && (LO_freq<760000)) + { + R850_Freq_Info.IMR_MEM_NOR = 2; + R850_Freq_Info.IMR_MEM_REV = 7; + } + else + { + R850_Freq_Info.IMR_MEM_NOR = 3; + R850_Freq_Info.IMR_MEM_REV = 8; + } + + //TF_HPF_BPF R16[2:0] + /* 7-lowest:111 ; 6:011 ; 5:101 ; 4:001 ; 3:110 ; 2:010 ; 1:100 ; 0-noBPF:000 */ + if(LO_freq<580000) + R850_Freq_Info.TF_HPF_BPF = 0x07; //7 => 111:lowset BPF R16[2:0] + else if(LO_freq>=580000 && LO_freq<660000) + R850_Freq_Info.TF_HPF_BPF = 0x01; //4 => 001 + else if(LO_freq>=660000 && LO_freq<780000) + R850_Freq_Info.TF_HPF_BPF = 0x06; //3 => 110 + else if(LO_freq>=780000 && LO_freq<900000) + R850_Freq_Info.TF_HPF_BPF = 0x04; //1 => 100 + else + R850_Freq_Info.TF_HPF_BPF = 0x00; //0 => 000 + + /* +00: highest band +01: med band +10: low band +11: Ultrawide band +*/ + //RF polyfilter band + if((LO_freq>0) && (LO_freq<133000)) + R850_Freq_Info.RF_POLY = 2; //R17[6:5]=2; low => R18[1:0] + else if((LO_freq>=133000) && (LO_freq<221000)) + R850_Freq_Info.RF_POLY = 1; //R17[6:5]=1; mid => R18[1:0] + else if((LO_freq>=221000) && (LO_freq<760000)) + R850_Freq_Info.RF_POLY = 0; //R17[6:5]=0; highest => R18[1:0] + else + R850_Freq_Info.RF_POLY = 3; //R17[6:5]=3; ultra high => R18[1:0] + + + /* +00: highest +01: high +10: low +11: lowest +*/ + //TF_HPF_Corner + if((LO_freq>0) && (LO_freq<480000)) + R850_Freq_Info.TF_HPF_CNR = 3; //lowest => R16[4:3] + else if((LO_freq>=480000) && (LO_freq<550000)) + R850_Freq_Info.TF_HPF_CNR = 2; // low => R16[4:3] + else if((LO_freq>=550000) && (LO_freq<700000)) + R850_Freq_Info.TF_HPF_CNR = 1; // high => R16[4:3] + else + R850_Freq_Info.TF_HPF_CNR = 0; //highest => R16[4:3] + + + //LPF Cap, Notch + switch(R850_Standard) + { + case R850_DVB_C_8M: //Cable + case R850_DVB_C_6M: + case R850_J83B: + case R850_DVB_C_8M_IF_5M: + case R850_DVB_C_6M_IF_5M: + case R850_J83B_IF_5M: + if(LO_freq<77000) + { + R850_Freq_Info.LPF_CAP = 15; + R850_Freq_Info.LPF_NOTCH = 10; + } + else if((LO_freq>=77000) && (LO_freq<85000)) + { + R850_Freq_Info.LPF_CAP = 15; + R850_Freq_Info.LPF_NOTCH = 4; + } + else if((LO_freq>=85000) && (LO_freq<115000)) + { + R850_Freq_Info.LPF_CAP = 13; + R850_Freq_Info.LPF_NOTCH = 3; + } + else if((LO_freq>=115000) && (LO_freq<125000)) + { + R850_Freq_Info.LPF_CAP = 11; + R850_Freq_Info.LPF_NOTCH = 1; + } + else if((LO_freq>=125000) && (LO_freq<141000)) + { + R850_Freq_Info.LPF_CAP = 9; + R850_Freq_Info.LPF_NOTCH = 0; + } + else if((LO_freq>=141000) && (LO_freq<157000)) + { + R850_Freq_Info.LPF_CAP = 8; + R850_Freq_Info.LPF_NOTCH = 0; + } + else if((LO_freq>=157000) && (LO_freq<181000)) + { + R850_Freq_Info.LPF_CAP = 6; + R850_Freq_Info.LPF_NOTCH = 0; + } + else if((LO_freq>=181000) && (LO_freq<205000)) + { + R850_Freq_Info.LPF_CAP = 3; + R850_Freq_Info.LPF_NOTCH = 0; + } + else //LO>=201M + { + R850_Freq_Info.LPF_CAP = 0; + R850_Freq_Info.LPF_NOTCH = 0; + } + //Diplexer Select R14[3:2] + if(LO_freq<330000) + R850_Freq_Info.TF_DIPLEXER = 2; //LPF R14[3:2] + else + R850_Freq_Info.TF_DIPLEXER = 0; //HPF + + + break; + + default: //Air, DTMB (for 180nH) + if((LO_freq>0) && (LO_freq<73000)) + { + R850_Freq_Info.LPF_CAP = 8; + R850_Freq_Info.LPF_NOTCH = 10; + } + else if((LO_freq>=73000) && (LO_freq<81000)) + { + R850_Freq_Info.LPF_CAP = 8; + R850_Freq_Info.LPF_NOTCH = 4; + } + else if((LO_freq>=81000) && (LO_freq<89000)) + { + R850_Freq_Info.LPF_CAP = 8; + R850_Freq_Info.LPF_NOTCH = 3; + } + else if((LO_freq>=89000) && (LO_freq<121000)) + { + R850_Freq_Info.LPF_CAP = 6; + R850_Freq_Info.LPF_NOTCH = 1; + } + else if((LO_freq>=121000) && (LO_freq<145000)) + { + R850_Freq_Info.LPF_CAP = 4; + R850_Freq_Info.LPF_NOTCH = 0; + } + else if((LO_freq>=145000) && (LO_freq<153000)) + { + R850_Freq_Info.LPF_CAP = 3; + R850_Freq_Info.LPF_NOTCH = 0; + } + else if((LO_freq>=153000) && (LO_freq<177000)) + { + R850_Freq_Info.LPF_CAP = 2; + R850_Freq_Info.LPF_NOTCH = 0; + } + else if((LO_freq>=177000) && (LO_freq<201000)) + { + R850_Freq_Info.LPF_CAP = 1; + R850_Freq_Info.LPF_NOTCH = 0; + } + else //LO>=201M + { + R850_Freq_Info.LPF_CAP = 0; + R850_Freq_Info.LPF_NOTCH = 0; + } + //Diplexer Select R14[3:2] + if(LO_freq<340000) + R850_Freq_Info.TF_DIPLEXER = 2; //LPF R14[3:2] + else + R850_Freq_Info.TF_DIPLEXER = 0; //HPF + break; + + }//end switch(standard) + + + return R850_Freq_Info; + +} + +struct R850_SysFreq_Info_Type R850_SysFreq_NrbDetOn_Sel(enum R850_Standard_Type R850_Standard,u32 RF_freq) +{ + + struct R850_SysFreq_Info_Type R850_SysFreq_Info; + + switch(R850_Standard) + { + case R850_DTMB_8M_4570: + case R850_DTMB_6M_4500: + case R850_DTMB_8M_IF_5M: + case R850_DTMB_6M_IF_5M: + if(RF_freq<=100000) + { + //LNA + R850_SysFreq_Info.LNA_VTL_H=0x6B; //R39[7:0] LNA VTL/H = 0.94(6) / 1.44(B) + + //NRB + R850_SysFreq_Info.NRB_TOP=10; //R40[7:4] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] + R850_SysFreq_Info.NRB_BW_LPF=3; //R26[7:6] [widest (0), wide (1), low (2), lowest (3)] + R850_SysFreq_Info.NRB_BW_HPF=3; //R26[3:2] [lowest (0), low (1), high (2), highest (3)] + R850_SysFreq_Info.IMG_NRB_ADDER=1; //R46[3:2] ["original" (0), "top+6" (1), "top+9" (2), "top+11" (3)] + + //Filter + R850_SysFreq_Info.FILT_3TH_LPF_GAIN=0; //R24[1:0] [normal (0), +1.5dB (1), +3dB (2), +4.5dB (3)] + } + else if(RF_freq<=340000) + { + //LNA + R850_SysFreq_Info.LNA_VTL_H=0x6B; //R39[7:0] LNA VTL/H = 0.94(6) / 1.44(B) + + //NRB + R850_SysFreq_Info.NRB_TOP=10; //R40[7:4] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] + R850_SysFreq_Info.NRB_BW_LPF=2; //R26[7:6] [widest (0), wide (1), low (2), lowest (3)] + R850_SysFreq_Info.NRB_BW_HPF=3; //R26[3:2] [lowest (0), low (1), high (2), highest (3)] + R850_SysFreq_Info.IMG_NRB_ADDER=1; //R46[3:2] ["original" (0), "top+6" (1), "top+9" (2), "top+11" (3)] + + //Filter + R850_SysFreq_Info.FILT_3TH_LPF_GAIN=0; //R24[1:0] [normal (0), +1.5dB (1), +3dB (2), +4.5dB (3)] + } + else + { + //LNA + R850_SysFreq_Info.LNA_VTL_H=0x5A; //R39[7:0] LNA VTL/H = 0.84(5) / 1.34(A) + + //NRB + R850_SysFreq_Info.NRB_TOP=6; //R40[7:4] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] + R850_SysFreq_Info.NRB_BW_LPF=2; //R26[7:6] [widest (0), wide (1), low (2), lowest (3)] + R850_SysFreq_Info.NRB_BW_HPF=2; //R26[3:2] [lowest (0), low (1), high (2), highest (3)] + R850_SysFreq_Info.IMG_NRB_ADDER=0; //R46[3:2] ["original" (0), "top+6" (1), "top+9" (2), "top+11" (3)] + + //Filter + R850_SysFreq_Info.FILT_3TH_LPF_GAIN=3; //R24[1:0] [normal (0), +1.5dB (1), +3dB (2), +4.5dB (3)] + } + + //PW + R850_SysFreq_Info.NA_PWR_DET = 0; //R10[6] ["off" (0), "on" (1)] + R850_SysFreq_Info.LNA_NRB_DET=0; //R11[7] ["on" (0), "off" (1)] + + //LNA + R850_SysFreq_Info.LNA_TOP=4; //R38[2:0] ["7~0" (0~7) ; input: "7~0"] + R850_SysFreq_Info.RF_LTE_PSG=1; //R17[4] ["no psg" (0), "7.5dB(5~8)" (1)] + + + //RFBuf + R850_SysFreq_Info.RF_TOP=4; //R38[6:4] ["7~0" (0~7) ; input: "7~0"] + R850_SysFreq_Info.RF_VTL_H=0x4A; //R42[7:0] RF VTL/H = 0.74(4) / 1.34(A) + R850_SysFreq_Info.RF_GAIN_LIMIT=0; //MSB R18[2], LSB R16[6] ["max =15" (0), "max =11" (1), "max =13" (2), "max =9" (3)] + + //Mixer and Mixamp + R850_SysFreq_Info.MIXER_AMP_LPF = 4; //R19[2:0] ["normal (widest)" (0), "1" (1), "2" (2), "3" (3), "4" (4), "5" (5), "6" (6), "narrowest" (7)] + R850_SysFreq_Info.MIXER_TOP=9; //R40[3:0] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] + R850_SysFreq_Info.MIXER_VTH=0x09; //R41[3:0] 1.24 (9) + R850_SysFreq_Info.MIXER_VTL=0x04; //R43[3:0] 0.74 (4) + R850_SysFreq_Info.MIXER_GAIN_LIMIT=1; //R22[7:6] ["max=6" (0), "max=8" (1), "max=10" (2), "max=12" (3)] + R850_SysFreq_Info.MIXER_DETBW_LPF =0; //R46[7] ["normal" (0), "enhance amp det LPF" (1)] + + //Filter + R850_SysFreq_Info.FILTER_TOP=4; //R44[3:0] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] + R850_SysFreq_Info.FILTER_VTH=0x90; //R41[7:4] 1.24 (9) + R850_SysFreq_Info.FILTER_VTL=0x40; //R43[7:4] 0.74 (4) + R850_SysFreq_Info.FILT_3TH_LPF_CUR=0; //R10[4] [high (0), low (1)] + + + //Discharge + R850_SysFreq_Info.LNA_RF_DIS_MODE=1; //Both (fast+slow) (R45[1:0]=0'b00; R31[0]=1 ;R32[5]=1) : 1111 Both (fast+slow) case 1 + R850_SysFreq_Info.LNA_RF_CHARGE_CUR=1; //R31[1] ["6x chargeI" (0), "4x chargeI" (1)] + R850_SysFreq_Info.LNA_RF_DIS_CURR=1; //R13[5] ["1/3 dis current" (0), "normal" (1)] + R850_SysFreq_Info.RF_DIS_SLOW_FAST=5; //R45[7:4] 0.3u (1) / 0.9u (4) + R850_SysFreq_Info.LNA_DIS_SLOW_FAST=9; //R44[7:4] 0.3u (1) / 1.5u (8) => 1 + 8 = 9 + R850_SysFreq_Info.BB_DIS_CURR=0; //R25[6] ["x1" (0) , "x1/2" (1)] + R850_SysFreq_Info.MIXER_FILTER_DIS=2; //R37[7:6] ["highest" (0), "high" (1), "low" (2), "lowest" (3)] + R850_SysFreq_Info.BB_DET_MODE=0; //R37[2] ["peak" (0), "average" (1)] + + //Polyphase + R850_SysFreq_Info.ENB_POLY_GAIN=0; //R25[1]=0 original ["original" (0), "ctrl by mixamp (>10)" (1)] + + //VGA + R850_SysFreq_Info.HPF_COMP=0; //R13[2:1] ["normal" (0) , "+1.5dB" (1), "+3dB" (2), "+4dB" (3)] + R850_SysFreq_Info.FB_RES_1ST=0; //R21[4] ["2K" (0) , "8K" (1)] + + break; + + default: //DVB-T + //PW + R850_SysFreq_Info.NA_PWR_DET = 0; //R10[6] ["off" (0), "on" (1)] + R850_SysFreq_Info.LNA_NRB_DET=0; //R11[7] ["on" (0), "off" (1)] + + //LNA + R850_SysFreq_Info.LNA_TOP=4; //R38[2:0] ["7~0" (0~7) ; input: "7~0"] + R850_SysFreq_Info.LNA_VTL_H=0x5A; //R39[7:0] LNA VTL/H = 0.84(5) / 1.34(A) + R850_SysFreq_Info.RF_LTE_PSG=1; //R17[4] ["no psg" (0), "7.5dB(5~8)" (1)] + + + //RFBuf + R850_SysFreq_Info.RF_TOP=4; //R38[6:4] ["7~0" (0~7) ; input: "7~0"] + R850_SysFreq_Info.RF_VTL_H=0x4A; //R42[7:0] RF VTL/H = 0.74(4) / 1.34(A) + R850_SysFreq_Info.RF_GAIN_LIMIT=0; //MSB R18[2], LSB R16[6] ["max =15" (0), "max =11" (1), "max =13" (2), "max =9" (3)] + + //Mixer and Mixamp + R850_SysFreq_Info.MIXER_AMP_LPF = 4; //R19[2:0] ["normal (widest)" (0), "1" (1), "2" (2), "3" (3), "4" (4), "5" (5), "6" (6), "narrowest" (7)] + R850_SysFreq_Info.MIXER_TOP=9; //R40[3:0] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] + R850_SysFreq_Info.MIXER_VTH=0x09; //R41[3:0] 1.24 (9) + R850_SysFreq_Info.MIXER_VTL=0x04; //R43[3:0] 0.74 (4) + R850_SysFreq_Info.MIXER_GAIN_LIMIT=3; //R22[7:6] ["max=6" (0), "max=8" (1), "max=10" (2), "max=12" (3)] + R850_SysFreq_Info.MIXER_DETBW_LPF =0; //R46[7] ["normal" (0), "enhance amp det LPF" (1)] + + + //Filter + R850_SysFreq_Info.FILTER_TOP=4; //R44[3:0] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] + R850_SysFreq_Info.FILTER_VTH=0x90; //R41[7:4] 1.24 (9) + R850_SysFreq_Info.FILTER_VTL=0x40; //R43[7:4] 0.74 (4) + R850_SysFreq_Info.FILT_3TH_LPF_CUR=1; //R10[4] [high (0), low (1)] + R850_SysFreq_Info.FILT_3TH_LPF_GAIN=3; //R24[1:0] [normal (0), +1.5dB (1), +3dB (2), +4.5dB (3)] + + //Discharge + R850_SysFreq_Info.LNA_RF_DIS_MODE=1; //Both (fast+slow) (R45[1:0]=0'b00; R31[0]=1 ;R32[5]=1) : 1111 Both (fast+slow) case 1 + R850_SysFreq_Info.LNA_RF_CHARGE_CUR=1; //R31[1] ["6x chargeI" (0), "4x chargeI" (1)] + R850_SysFreq_Info.LNA_RF_DIS_CURR=1; //R13[5] ["1/3 dis current" (0), "normal" (1)] + R850_SysFreq_Info.RF_DIS_SLOW_FAST=5; //R45[7:4] 0.3u (1) / 0.9u (4) + R850_SysFreq_Info.LNA_DIS_SLOW_FAST=9; //R44[7:4] 0.3u (1) / 1.5u (8) => 1 + 8 = 9 + R850_SysFreq_Info.BB_DIS_CURR=0; //R25[6] ["x1" (0) , "x1/2" (1)] + R850_SysFreq_Info.MIXER_FILTER_DIS=2; //R37[7:6] ["highest" (0), "high" (1), "low" (2), "lowest" (3)] + R850_SysFreq_Info.BB_DET_MODE=0; //R37[2] ["peak" (0), "average" (1)] + + //Polyphase + R850_SysFreq_Info.ENB_POLY_GAIN=0; //R25[1]=0 original ["original" (0), "ctrl by mixamp (>10)" (1)] + + //NRB + R850_SysFreq_Info.NRB_TOP=4; //R40[7:4] ["15-highest ~ 0-lowest" (0~15) ; input: "15~0"] + R850_SysFreq_Info.NRB_BW_HPF=0; //R26[3:2] [lowest (0), low (1), high (2), highest (3)] + R850_SysFreq_Info.NRB_BW_LPF=2; //R26[7:6] [widest (0), wide (1), low (2), lowest (3)] + R850_SysFreq_Info.IMG_NRB_ADDER=2; //R46[3:2] ["original" (0), "top+6" (1), "top+9" (2), "top+11" (3)] + + //VGA + R850_SysFreq_Info.HPF_COMP=1; //R13[2:1] ["normal" (0) , "+1.5dB" (1), "+3dB" (2), "+4dB" (3)] + R850_SysFreq_Info.FB_RES_1ST=1; //R21[4] ["2K" (0) , "8K" (1)] + break; + + } //end switch + + + R850_SysFreq_Info.DEGLITCH_CLK = 1; //R38[3] ["500Hz"(0), "1KHz"(1)] + //R850_SysFreq_Info.LNA_RF_DIS_MODE =1; //Both (fast+slow) (R45[1:0]=0'b00; R31[0]=1 ;R32[5]=1) : 1111 Both (fast+slow) case 1 + //R850_SysFreq_Info.LNA_DIS_SLOW_FAST &= 0x03; + //R850_SysFreq_Info.LNA_DIS_SLOW_FAST += 8; //R44[7:6] R45[7:6] ["0.6u" (0), "0.9u" (4), "1.5u" (8), "2.4u" (12)] + R850_SysFreq_Info.NAT_HYS = 1; //R35[6] ["no hys"(0) , "-6.5dB hys"(1)] + R850_SysFreq_Info.NAT_CAIN = 2; //R31[4:5] ["max-17dB"(0) , "max-11dB"(1), "max-6dB"(2), "max"(3)] + R850_SysFreq_Info.PULSE_HYS = 1; //R26[1:0] ["1.0V"(0), "0.8V"(1), "0.6V"(2), "0.4V"(3)] + R850_SysFreq_Info.FAST_DEGLITCH = 1; //R36[3:2] ["70ms"(0), "45ms"(1), "20ms"(2), "10ms"(3)] + R850_SysFreq_Info.PUL_RANGE_SEL = 0; //R31[2] ["0"(0), "1"(1)] + R850_SysFreq_Info.PUL_FLAG_RANGE = 3; //R35[1:0] ["0~14"(0), "1~14"(1), "2~14"(2), "3~14"(3)] + R850_SysFreq_Info.PULG_CNT_THRE = 1; //R17[1] ["threshold =14"(0), "threshold =15"(1)] + R850_SysFreq_Info.FORCE_PULSE = 1; //R46[5] ["pul_flag=0"(0), "auto"(1)] + R850_SysFreq_Info.FLG_CNT_CLK = 1; //R47[7:6] ["0.25Sec"(0), "0.5Sec"(1), "1Sec"(2), "2Sec"(3)] + R850_SysFreq_Info.NATG_OFFSET = 0; //R36[5:4] ["-6dB"(0), "-3dB"(1), "Normal"(2), "3dB"(3)] + + + return R850_SysFreq_Info; + +} +//-----------------------------------------------------------------------------------/ +// Purpose: read multiple IMR results for stability +// input: IMR_Reg: IMR result address +// IMR_Result_Data: result +// output: TRUE or FALSE +//-----------------------------------------------------------------------------------/ +R850_ErrCode R850_Muti_Read( struct r850_priv*priv, u8* IMR_Result_Data) //ok +{ + int ret = 0; + u8 buf[2]; + + + msleep(2);//2 //R850_ADC_READ_DELAY = 2; + + ret = r850_rd(priv,0x00,buf,2); + if(ret!=0){ + *IMR_Result_Data = 0; + return R850_Fail; + } + *IMR_Result_Data = buf[1] & 0x3F; + + return R850_Success; +} +R850_ErrCode R850_SetXtalCap(struct r850_priv *priv,u8 u8XtalCap) +{ + u8 XtalCap; + u8 Capx; + u8 Capx_3_0, Capxx; + + if(u8XtalCap>31) + { + XtalCap = 1; //10 + Capx = u8XtalCap-10; + } + else + { + XtalCap = 0; //0 + Capx = u8XtalCap; + } + + Capxx = Capx & 0x01; + Capx_3_0 = Capx >> 1; + + // Set Xtal Cap R33[6:3], R34[3] XtalCap => R33[7] + + priv->regs[33] = (priv->regs[33 ] & 0x07) | (Capx_3_0 << 3) | ( XtalCap << 7); + if(r850_wr(priv,33,priv->regs[33])!=0) + return R850_Fail; + + + priv->regs[34] = (priv->regs[34] & 0xF7) | (Capxx << 3); + if(r850_wr(priv,34,priv->regs[34])!=0) + return R850_Fail; + + return R850_Success; +} + +R850_ErrCode R850_SetXtalCap_No_Write(struct r850_priv *priv,u8 u8XtalCap) +{ + u8 XtalCap; + u8 Capx; + u8 Capx_3_0, Capxx; + + if(u8XtalCap>31) + { + XtalCap = 1; //10 + Capx = u8XtalCap-10; + } + else + { + XtalCap = 0; //0 + Capx = u8XtalCap; + } + + Capxx = Capx & 0x01; + Capx_3_0 = Capx >> 1; + + // Set Xtal Cap R33[6:3], R34[3] XtalCap => R33[7] + + priv->regs[33] = (priv->regs[33] & 0x07) | (Capx_3_0 << 3) | ( XtalCap << 7); + + priv->regs[34] = (priv->regs[34] & 0xF7) | (Capxx << 3); + + return R850_Success; +} + +/*parameter 2: xtal_gm +0:24MHz (strong) +1:24MHz +2:gm (16MHz) +3:off +*/ +R850_ErrCode R850_Set_XTAL_GM(struct r850_priv *priv,u8 xtal_gm) +{ + // Set Xtal gm R34[7:6] + + priv->regs[34] = (priv->regs[34] & 0x3F) | (xtal_gm << 6); + if(r850_wr(priv,34,priv->regs[34])!=0) + return R850_Fail; + + return R850_Success; +} + +/* + XTAL_PWR_VALUE +{ + XTAL_LOWEST = 0, + XTAL_LOW, + XTAL_HIGH, + XTAL_HIGHEST, + XTAL_CHECK_SIZE +}; +*/ +R850_ErrCode R850_SetXtalPW( struct r850_priv *priv,u8 u8Xtalpw) +{ + u8 Xtal_power; + + Xtal_power = (3 - u8Xtalpw); + + priv->regs[34] = (priv->regs[34] & 0xCF) | (Xtal_power<<4); //R34[5:4] + + if(r850_wr(priv,34,priv->regs[34])!=0) + return R850_Fail; + + return R850_Success; +} + +R850_ErrCode R850_PLL(struct r850_priv*priv, u32 LO_Freq, enum R850_Standard_Type R850_Standard)//ok +{ + u8 MixDiv = 2; + u8 DivBuf = 0; + u8 Ni = 0; + u8 Si = 0; + u8 DivNum = 0; + u16 Nint = 0; + u32 VCO_Min = 2200000; + u32 VCO_Max = 4400000; + u32 VCO_Freq = 0; + u32 PLL_Ref = priv->cfg->R850_Xtal; + u32 VCO_Fra = 0; + u16 Nsdm = 2; + u16 SDM = 0; + u16 SDM16to9 = 0; + u16 SDM8to1 = 0; + u8 XTAL_POW = 0; + u16 u2XalDivJudge; + u8 u1XtalDivRemain; + u8 CP_CUR = 0x00; + u8 CP_OFFSET = 0x00; + u8 SDM_RES = 0x00; + u8 NS_RES = 0x00; + u8 IQGen_Cur = 0; //DminDmin + u8 IQBias = 1; //BiasI + u8 IQLoad = 0; //3.2k/2 + u8 OutBuf_Bias = 0; //max + u8 BiasHf = 0; //135u + u8 PllArrayCunt = 0; + int ret = 0; + +// if(R850_Chip == R850_MP) +// VCO_Min=2270000; +// else + VCO_Min=2200000; + + VCO_Max = VCO_Min*2; + + // VCO current = 0 (max) + priv->regs[32] = (priv->regs[32] & 0xFC) | 0x00; // R31[1:0] = 0 => R32[3:2] = 0 + + // VCO power = auto + priv->regs[46] = (priv->regs[46] & 0xBF) | 0x40; // R26[7] = 1 => R46[6] = 1 + + // HfDiv Buf = 6dB buffer + priv->regs[37] = (priv->regs[37] & 0xEF) | 0x00; // R17[7]=0 => R37[4]=0 + + // Divider HfDiv current = 135u + priv->regs[12] = (priv->regs[12] & 0xFC) | 0x00; // R10[1:0]=00 => R12[3:2]=00 + + // PLL LDOA=2.2V + priv->regs[11] = (priv->regs[11] & 0xF3) | 0x00; // R11[3:2]=00 => R11[3:2]=00 + + // PFD DLDO=4mA + priv->regs[12] = (priv->regs[12] & 0x3F) | 0x00; // R8[5:4]=00 => R12[7:6]=00 + + // DLDO2=3mA + priv->regs[11] = (priv->regs[11] & 0xCF) | 0x10; // R11[5:4]=01 => R11[5:4]=01 + + // HF Fiv LDO=7mA (new bonding set this off) + priv->regs[9] = (priv->regs[9] & 0xF9) | 0x00; // R12[2:1]=00 => R9[2:1]=00 + + //------ Xtal freq depend setting: Xtal Gm & AGC ref clk --------// + if(priv->cfg->R850_Xtal==24000) + { + priv->regs[34] = (priv->regs[34] & 0x3F) | 0x00; //gm*2(24) R32[4:3]:00 => R34[7:6]:00 + priv->regs[37] = (priv->regs[37] & 0xDF) | 0x20; //clk /3 (24) => R37[5]=1 + } + else if(priv->cfg->R850_Xtal==16000) + { + priv->regs[34] = (priv->regs[34] & 0x3F) | 0x80; //gm(16) R32[4:3]:10 => R34[7:6]:10 + priv->regs[37] = (priv->regs[37] & 0xDF) | 0x00; //clk /2 (16) => R37[5]=0 + } + else if(priv->cfg->R850_Xtal==27000) + { + priv->regs[34] = (priv->regs[34] & 0x3F) | 0x00; //gm*2(24) R32[4:3]:00 => R34[7:6]:00 + priv->regs[37] = (priv->regs[37] & 0xDF) | 0x20; //clk /3 (24) => R37[5]=1 + } + else //not support Xtal freq + return R850_Fail; + + + if(priv->R850_clock_out == 1) + { + XTAL_POW = 0; //highest, R32[2:1]=0 + //Set X'tal Cap + R850_SetXtalCap(priv, priv->R850_Xtal_cap); + } + else if(priv->R850_clock_out == 0) + { + XTAL_POW = 3; //lowest, R32[2:1]=3 + //Set X'tal Cap + R850_SetXtalCap(priv, 0); + //gm off + R850_Set_XTAL_GM(priv, 1); //3:xtal gm off + } + else + { + if(LO_Freq<100000) //Xtal PW : Low + { + if(priv->R850_Xtal_Pwr <= R850_XTAL_LOW ) + { + XTAL_POW = 2; + } + else + { + XTAL_POW = 3 - priv->R850_Xtal_Pwr; + } + } + else if((110000<=LO_Freq) && (LO_Freq<130000)) //Xtal PW: High + { + if(priv->R850_Xtal_Pwr <= R850_XTAL_HIGH ) + { + XTAL_POW = 1; + } + else + { + XTAL_POW = 3 - priv->R850_Xtal_Pwr; + } + } + else //Xtal PW : Highest + { + XTAL_POW = 0; + } + //Set X'tal Cap + R850_SetXtalCap(priv, priv->R850_Xtal_cap); + } + + + priv->regs[34] = (priv->regs[34] & 0xCF) | (XTAL_POW<<4); //R32[2:1] => R34[5:4] + + + CP_CUR = 0x00; //0.7m, R30[7:5]=000 + CP_OFFSET = 0x00; //0u, R37[1]=0 + if(priv->cfg->R850_Xtal == 24000) + { + u2XalDivJudge = (u16) ((LO_Freq+priv->R850_IF_GOLOBAL)/1000/12); + // 48, 120 ,264 ,288, 336 + if((u2XalDivJudge==4)||(u2XalDivJudge==10)||(u2XalDivJudge==22)||(u2XalDivJudge==24)||(u2XalDivJudge==28)) + { + CP_OFFSET = 0x02; //30u, R37[1]=1 + } + else + { + CP_OFFSET = 0x00; //0u, R37[1]=0 + } + } + else if(priv->cfg->R850_Xtal == 16000) + { + u2XalDivJudge = (u16) ((LO_Freq+priv->R850_IF_GOLOBAL)/1000/8); + // + if((u2XalDivJudge==6)||(u2XalDivJudge==10)||(u2XalDivJudge==12)||(u2XalDivJudge==48)) + { + CP_OFFSET = 0x02; //30u, R37[1]=1 + } + else + { + CP_OFFSET = 0x00; //0u, R37[1]=0 + } + } + else if(priv->cfg->R850_Xtal == 27000) + { + u2XalDivJudge = (u16) ((LO_Freq+priv->R850_IF_GOLOBAL)*10/1000/135); + // 48, 120 ,264 ,288, 336 + if((u2XalDivJudge==4)||(u2XalDivJudge==10)||(u2XalDivJudge==22)||(u2XalDivJudge==24)||(u2XalDivJudge==28)) + { + CP_OFFSET = 0x02; //30u, R37[1]=1 + } + else + { + CP_OFFSET = 0x00; //0u, R37[1]=0 + } + } + + + priv->regs[30] = (priv->regs[30] & 0x1F) | (CP_CUR); // => R30[7:5] + + priv->regs[37] = (priv->regs[37] & 0xFD) | (CP_OFFSET); // => R37[1] + + //set pll autotune = 64kHz (fast) R47[1:0](MP) , R47[0](MT1) + + priv->regs[47] = priv->regs[47] & 0xFD; + + //Divider + while(MixDiv <= 64) + { + if(((LO_Freq * MixDiv) >= VCO_Min) && ((LO_Freq * MixDiv) < VCO_Max)) + { + DivBuf = MixDiv; + while(DivBuf > 2) + { + DivBuf = DivBuf >> 1; + DivNum ++; + } + break; + } + MixDiv = MixDiv << 1; + } + + //IQ Gen block & BiasHF & NS_RES & SDM_Res + if(MixDiv <= 4) //Div=2,4 + { + IQGen_Cur = 0; //DminDmin + IQBias = 1; //BiasI + IQLoad = 0; //3.2k/2 + OutBuf_Bias = 0; //0 (max) + BiasHf = 0; //135u + SDM_RES = 0; //short + NS_RES = 0; //0R + } + else if(MixDiv == 8) + { + IQGen_Cur = 0; //DminDmin + IQBias = 0; //BiasI/2 + IQLoad = 1; //3.2k + OutBuf_Bias = 1; //1 + BiasHf = 1; //110u + SDM_RES = 0; //short + NS_RES = 1; //800R + } + else if(MixDiv == 16) + { + IQGen_Cur = 0; //DminDmin + IQBias = 0; //BiasI/2 + IQLoad = 1; //3.2k + OutBuf_Bias = 2; //2 + BiasHf = 1; //110u + SDM_RES = 0; //short + NS_RES = 0; //0R + } + else if(MixDiv >= 32) //32, 64 + { + IQGen_Cur = 0; //DminDmin + IQBias = 0; //BiasI/2 + IQLoad = 1; //3.2k + OutBuf_Bias = 3; //3 (min) + BiasHf = 1; //110u + SDM_RES = 0; //short + NS_RES = 0; //0R + } + else + { + return R850_Fail; + } + + { + + { + if(priv->cfg->R850_Xtal==24000) + u2XalDivJudge = (u16) ((LO_Freq + priv->R850_IF_GOLOBAL)/1000/12); + else if(priv->cfg->R850_Xtal==16000) + u2XalDivJudge = (u16) ((LO_Freq + priv->R850_IF_GOLOBAL)/1000/8); + else if(priv->cfg->R850_Xtal==27000) + u2XalDivJudge = (u16) ((LO_Freq + priv->R850_IF_GOLOBAL)*10/1000/135); + else + return R850_Fail; + + u1XtalDivRemain = (u8) (u2XalDivJudge % 2); + + if(LO_Freq < (372000+8500)) + { + if(u1XtalDivRemain==1) //odd + { + priv->R850_XtalDiv = R850_XTAL_DIV1; + } + else //even, spur area + { + priv->R850_XtalDiv = R850_XTAL_DIV1_2; + } + } + else if(((LO_Freq + priv->R850_IF_GOLOBAL) >= 478000) && ((LO_Freq + priv->R850_IF_GOLOBAL) < 482000) && (R850_Standard == R850_ISDB_T_4063)) + { + priv->R850_XtalDiv = R850_XTAL_DIV4; + } + else + { + priv->R850_XtalDiv = R850_XTAL_DIV1; + } + } + } + + + //Xtal divider setting + //R850_XtalDiv = XTAL_DIV2; //div 1, 2, 4 + if(priv->R850_XtalDiv==R850_XTAL_DIV1) + { + PLL_Ref = priv->cfg->R850_Xtal; + priv->regs[34] = (priv->regs[34] & 0xFC) | 0x00; //b7:2nd_div2=0, b6:1st_div2=0 R32[7:6] => R34[1:0] + } + else if(priv->R850_XtalDiv==R850_XTAL_DIV1_2) + { + PLL_Ref = priv->cfg->R850_Xtal/2; + priv->regs[34] = (priv->regs[34] & 0xFC) | 0x02; //1st_div2=0(R34[0]), 2nd_div2=1(R34[1]) + } + else if(priv->R850_XtalDiv==R850_XTAL_DIV2_1) + { + PLL_Ref = priv->cfg->R850_Xtal/2; + priv->regs[34] = (priv->regs[34] & 0xFC) | 0x01; //1st_div2=1(R34[0]), 2nd_div2=0(R34[1]) + } + else if(priv->R850_XtalDiv==R850_XTAL_DIV4) //24MHz + { + PLL_Ref = priv->cfg->R850_Xtal/4; + priv->regs[34] = (priv->regs[34] & 0xFC) | 0x03; //b7:2nd_div2=1, b6:1st_div2=1 R32[7:6] => R34[1:0] + } + + + //IQ gen current R10[7] => R11[0] + priv->regs[11] = (priv->regs[11] & 0xFE) | (IQGen_Cur); + + //Out Buf Bias R10[6:5] => R45[3:2] + priv->regs[45] = (priv->regs[45] & 0xF3) | (OutBuf_Bias<<2); + + //BiasI R29[2] => R46[0] + priv->regs[46] = (priv->regs[46] & 0xFE) | (IQBias); + + //IQLoad R36[5] => R46[1] + priv->regs[46] = (priv->regs[46] & 0xFD) | (IQLoad<<1); + + //BiasHF R29[7:6] => R32[1:0] + priv->regs[32] = (priv->regs[32] & 0xFC) | (BiasHf); + + //SDM_RES R30[7] => R32[4] + priv->regs[32] = (priv->regs[32] & 0xEF) | (SDM_RES<<4); + + //NS_RES R36[0] => R17[7] + priv->regs[17] = (priv->regs[17] & 0x7F) | (NS_RES<<7); + + //Divider num R35[5:3] => R30[4:2] + priv->regs[30] = (priv->regs[30] & 0xE3) | (DivNum << 2); + + VCO_Freq = LO_Freq * MixDiv; + Nint = (u16) (VCO_Freq / 2 / PLL_Ref); + VCO_Fra = (u16) (VCO_Freq - 2 * PLL_Ref * Nint); + + //Boundary spur prevention + if (VCO_Fra < PLL_Ref/64) //2*PLL_Ref/128 + VCO_Fra = 0; + else if (VCO_Fra > PLL_Ref*127/64) //2*PLL_Ref*127/128 + { + VCO_Fra = 0; + Nint ++; + } + else if((VCO_Fra > PLL_Ref*127/128) && (VCO_Fra < PLL_Ref)) //> 2*PLL_Ref*127/256, < 2*PLL_Ref*128/256 + VCO_Fra = PLL_Ref*127/128; // VCO_Fra = 2*PLL_Ref*127/256 + else if((VCO_Fra > PLL_Ref) && (VCO_Fra < PLL_Ref*129/128)) //> 2*PLL_Ref*128/256, < 2*PLL_Ref*129/256 + VCO_Fra = PLL_Ref*129/128; // VCO_Fra = 2*PLL_Ref*129/256 + else + VCO_Fra = VCO_Fra; + + //Ni & Si + Ni = (u8) ((Nint - 13) / 4); + Si = (u8) (Nint - 4 *Ni - 13); + + + priv->regs[27] = (priv->regs[27] & 0x80) | Ni; //R26[6:0] => R27[6:0] + priv->regs[30] = (priv->regs[30] & 0xFC) | Si; //R35[7:6] => R30[1:0] + + //pw_sdm & pw_dither + priv->regs[32] &= 0x3F; //R29[1:0] => R32[7:6] + if(VCO_Fra == 0) + { + priv->regs[32] |= 0xC0; + } + + //SDM calculator + while(VCO_Fra > 1) + { + if (VCO_Fra > (2*PLL_Ref / Nsdm)) + { + SDM = SDM + 32768 / (Nsdm/2); + VCO_Fra = VCO_Fra - 2*PLL_Ref / Nsdm; + if (Nsdm >= 0x8000) + break; + } + Nsdm = Nsdm << 1; + } + + SDM16to9 = SDM >> 8; + SDM8to1 = SDM - (SDM16to9 << 8); + + + priv->regs[29] = (u8) SDM16to9; //R28 => R29 + priv->regs[28] = (u8) SDM8to1; //R27 => R28 + + + ret = r850_wrm(priv,8,&priv->regs[8],40); + if(ret!=0) + return R850_Fail; + + + + if(priv->R850_XtalDiv == R850_XTAL_DIV1) + msleep( R850_PLL_LOCK_DELAY); //correct gx_msleep ecos, don't modify delay function! + else if((priv->R850_XtalDiv == R850_XTAL_DIV1_2) || (priv->R850_XtalDiv == R850_XTAL_DIV2_1)) + msleep( R850_PLL_LOCK_DELAY*2); + else + msleep( R850_PLL_LOCK_DELAY*4); + + //set pll autotune = 1khz (2'b10) + + priv->regs[47] = (priv->regs[47] & 0xFD) | 0x02; + if(r850_wr(priv,47,priv->regs[47])!=0) + return R850_Fail; + + + return R850_Success; + +} + + +R850_ErrCode R850_MUX( struct r850_priv *priv ,u32 LO_KHz, u32 RF_KHz, enum R850_Standard_Type R850_Standard) +{ + u8 Reg_IMR_Gain = 0; + u8 Reg_IMR_Phase = 0; + u8 Reg_IMR_Iqcap = 0; + struct R850_Freq_Info_Type Freq_Info1; + + //Freq_Info_Type Freq_Info1; + Freq_Info1 = R850_Freq_Sel(LO_KHz, RF_KHz, R850_Standard); + + + // TF_DIPLEXER + priv->regs[14] = (priv->regs[14] & 0xF3) | (Freq_Info1.TF_DIPLEXER<<2); //LPF => R14[3:2] + if(r850_wr(priv,14,priv->regs[14])!=0) + return R850_Fail; + + + + //TF_HPF_BPF => R16[2:0] TF_HPF_CNR => R16[4:3] + priv->regs[16] = (priv->regs[16] & 0xE0) | (Freq_Info1.TF_HPF_BPF) | (Freq_Info1.TF_HPF_CNR << 3); // R16[2:0], R16[4:3] + if(r850_wr(priv,16,priv->regs[16])!=0) + return R850_Fail; + + + // RF Polyfilter + priv->regs[18] = (priv->regs[18] & 0xFC) | (Freq_Info1.RF_POLY); //R17[6:5] => R18[1:0] + if(r850_wr(priv,18,priv->regs[18])!=0) + return R850_Fail; + + + // LNA Cap + priv->regs[14] = (priv->regs[14] & 0x0F) | (Freq_Info1.LPF_CAP<<4); //R16[3:0] => R14[7:4] + if(r850_wr(priv,14,priv->regs[14])!=0) + return R850_Fail; + + + // LNA Notch + priv->regs[15] = (priv->regs[15] & 0xF0) | (Freq_Info1.LPF_NOTCH); //R16[7:4] => R15[3:0] + if(r850_wr(priv,15,priv->regs[15])!=0) + return R850_Fail; + + + + + //Set_IMR + if( (priv->R850_IMR_done_flag == TRUE) && (priv->R850_IMR_Cal_Result==0)) + { + + Reg_IMR_Gain = priv->imr_data[Freq_Info1.IMR_MEM_NOR].Gain_X & 0x2F; //R20[4:0] => R20[3:0] + Reg_IMR_Phase = priv->imr_data[Freq_Info1.IMR_MEM_NOR].Phase_Y & 0x2F; //R21[4:0] => R21[3:0] + Reg_IMR_Iqcap = priv->imr_data[Freq_Info1.IMR_MEM_NOR].Iqcap; //0,1,2 + + + } + else + { + Reg_IMR_Gain = 0; + Reg_IMR_Phase = 0; + Reg_IMR_Iqcap = 0; + } + + //Gain, R20[4:0] + priv->regs[R850_IMR_GAIN_REG] = (priv->regs[R850_IMR_GAIN_REG] & 0xD0) | (Reg_IMR_Gain & 0x2F); + if(r850_wr(priv,R850_IMR_GAIN_REG,priv->regs[R850_IMR_GAIN_REG])!=0) + return R850_Fail; + + //Phase, R21[4:0] + priv->regs[R850_IMR_PHASE_REG] = (priv->regs[R850_IMR_PHASE_REG] & 0xD0) | (Reg_IMR_Phase & 0x2F); + if(r850_wr(priv,R850_IMR_PHASE_REG,priv->regs[R850_IMR_PHASE_REG])!=0) + return R850_Fail; + + + //Iqcap, R21[7:6] + priv->regs[R850_IMR_IQCAP_REG] = (priv->regs[R850_IMR_IQCAP_REG] & 0x3F) | (Reg_IMR_Iqcap<<6); + if(r850_wr(priv,R850_IMR_IQCAP_REG,priv->regs[R850_IMR_IQCAP_REG])!=0) + return R850_Fail; + + + return R850_Success; +} + +//-----------------------------------------------------------------------------------/ +// Purpose: compare IMR result aray [0][1][2], find min value and store to CorArry[0] +// input: CorArry: three IMR data array +// output: TRUE or FALSE +//-----------------------------------------------------------------------------------/ +R850_ErrCode R850_CompreCor(struct R850_SectType* CorArry) +{ + u8 CompCunt = 0; + struct R850_SectType CorTemp; + + for(CompCunt=3; CompCunt > 0; CompCunt --) + { + if(CorArry[0].Value > CorArry[CompCunt - 1].Value) //compare IMR result [0][1][2], find min value + { + CorTemp = CorArry[0]; + CorArry[0] = CorArry[CompCunt - 1]; + CorArry[CompCunt - 1] = CorTemp; + } + } + + return R850_Success; +} + + +//-------------------------------------------------------------------------------------// +// Purpose: if (Gain<9 or Phase<9), Gain+1 or Phase+1 and compare with min value +// new < min => update to min and continue +// new > min => Exit +// input: StepArry: three IMR data array +// Pace: gain or phase register +// output: TRUE or FALSE +//-------------------------------------------------------------------------------------// +R850_ErrCode R850_CompreStep(struct r850_priv*priv, struct R850_SectType* StepArry, u8 Pace) +{ + struct R850_SectType StepTemp; + + //min value already saved in StepArry[0] + StepTemp.Phase_Y = StepArry[0].Phase_Y; //whole byte data + StepTemp.Gain_X = StepArry[0].Gain_X; + //StepTemp.Iqcap = StepArry[0].Iqcap; + + while(((StepTemp.Gain_X & 0x0F) < R850_IMR_TRIAL) && ((StepTemp.Phase_Y & 0x0F) < R850_IMR_TRIAL)) + { + if(Pace == R850_IMR_GAIN_REG) + StepTemp.Gain_X ++; + else + StepTemp.Phase_Y ++; + + if(r850_wr(priv,R850_IMR_GAIN_REG,StepTemp.Gain_X)!=0) + return R850_Fail; + + if(r850_wr(priv,R850_IMR_PHASE_REG,StepTemp.Phase_Y)!=0) + return R850_Fail; + + if(R850_Muti_Read(priv, &StepTemp.Value) != R850_Success) + return R850_Fail; + + if(StepTemp.Value <= StepArry[0].Value) + { + StepArry[0].Gain_X = StepTemp.Gain_X; + StepArry[0].Phase_Y = StepTemp.Phase_Y; + //StepArry[0].Iqcap = StepTemp.Iqcap; + StepArry[0].Value = StepTemp.Value; + } + else if((StepTemp.Value - 2*R850_ADC_READ_COUNT) > StepArry[0].Value) + { + break; + } + + } //end of while() + + return R850_Success; +} + +//-------------------------------------------------------------------------------------------- +// Purpose: record IMR results by input gain/phase location +// then adjust gain or phase positive 1 step and negtive 1 step, both record results +// input: FixPot: phase or gain +// FlucPot phase or gain +// PotReg: Reg20 or Reg21 +// CompareTree: 3 IMR trace and results +// output: TREU or FALSE +//-------------------------------------------------------------------------------------------- +R850_ErrCode R850_IQ_Tree( struct r850_priv *priv,u8 FixPot, u8 FlucPot, u8 PotReg, struct R850_SectType* CompareTree) +{ + u8 TreeCunt = 0; + u8 PntReg = 0; + + //PntReg is reg to change; FlucPot is change value + if(PotReg == R850_IMR_GAIN_REG) + PntReg = R850_IMR_PHASE_REG; //phase control + else + PntReg = R850_IMR_GAIN_REG; //gain control + + for(TreeCunt = 0; TreeCunt<3; TreeCunt ++) + { + + if(r850_wr(priv,PotReg,FixPot)!=0) + return R850_Fail; + if(r850_wr(priv,PntReg,FlucPot)!=0) + return R850_Fail; + + if(R850_Muti_Read(priv, &CompareTree[TreeCunt].Value) != R850_Success) + return R850_Fail; + + if(PotReg == R850_IMR_GAIN_REG) + { + CompareTree[TreeCunt].Gain_X = FixPot; + CompareTree[TreeCunt].Phase_Y = FlucPot; + } + else + { + CompareTree[TreeCunt].Phase_Y = FixPot; + CompareTree[TreeCunt].Gain_X = FlucPot; + } + + if(TreeCunt == 0) //try right-side point + { + FlucPot ++; + } + else if(TreeCunt == 1) //try left-side point + { + if((FlucPot & 0x0F) == 1) //if absolute location is 1, change I/Q direction + { + if(FlucPot & 0x20) //b[5]:I/Q selection. 0:Q-path, 1:I-path + { + //FlucPot = (FlucPot & 0xE0) | 0x01; + FlucPot = (FlucPot & 0xD0) | 0x01; + } + else + { + //FlucPot = (FlucPot & 0xE0) | 0x11; + FlucPot = (FlucPot & 0xD0) | 0x21; + } + } + else + { + FlucPot = FlucPot - 2; + } + } + } + + return R850_Success; +} + +R850_ErrCode R850_IQ_Tree5(struct r850_priv*priv, u8 FixPot, u8 FlucPot, u8 PotReg, struct R850_SectType* CompareTree) +{ + u8 TreeCunt = 0; + u8 TreeTimes = 5; + u8 TempPot = 0; + u8 PntReg = 0; + u8 CompCunt = 0; + struct R850_SectType CorTemp[5]; + struct R850_SectType Compare_Temp; + u8 CuntTemp = 0; + + memset(&Compare_Temp,0, sizeof(struct R850_SectType)); + Compare_Temp.Value = 255; + + for(CompCunt=0; CompCunt<3; CompCunt++) + { + CorTemp[CompCunt].Gain_X = CompareTree[CompCunt].Gain_X; + CorTemp[CompCunt].Phase_Y = CompareTree[CompCunt].Phase_Y; + CorTemp[CompCunt].Value = CompareTree[CompCunt].Value; + } + + /* + if(PotReg == 0x08) + PntReg = 0x09; //phase control + else + PntReg = 0x08; //gain control + */ + + //PntReg is reg to change; FlucPot is change value + if(PotReg == R850_IMR_GAIN_REG) + PntReg = R850_IMR_PHASE_REG; //phase control + else + PntReg = R850_IMR_GAIN_REG; //gain control + + + + + for(TreeCunt = 0;TreeCunt < TreeTimes;TreeCunt++) + { + if(r850_wr(priv,PotReg,FixPot) != 0) + return R850_Fail; + if(r850_wr(priv,PntReg,FlucPot) != 0) + return R850_Fail; + + if(R850_Muti_Read( priv,&CorTemp[TreeCunt].Value) != R850_Success) + return R850_Fail; + + if(PotReg == R850_IMR_GAIN_REG) + { + CorTemp[TreeCunt].Gain_X = FixPot; + CorTemp[TreeCunt].Phase_Y = FlucPot; + } + else + { + CorTemp[TreeCunt].Phase_Y = FixPot; + CorTemp[TreeCunt].Gain_X = FlucPot; + } + + if(TreeCunt == 0) //next try right-side 1 point + { + FlucPot ++; //+1 + } + else if(TreeCunt == 1) //next try right-side 2 point + { + FlucPot ++; //1+1=2 + } + else if(TreeCunt == 2) //next try left-side 1 point + { + if((FlucPot & 0x0F) == 0x02) //if absolute location is 2, change I/Q direction and set to 1 + { + TempPot = 1; + if((FlucPot & 0x20)==0x20) //b[5]:I/Q selection. 0:Q-path, 1:I-path + { + FlucPot = (FlucPot & 0xD0) | 0x01; //Q1 + } + else + { + FlucPot = (FlucPot & 0xD0) | 0x21; //I1 + } + } + else + { + FlucPot -= 3; //+2-3=-1 + } + } + else if(TreeCunt == 3) //next try left-side 2 point + { + if(TempPot==1) //been chnaged I/Q + { + FlucPot += 1; + } + else if((FlucPot & 0x0F) == 0x00) //if absolute location is 0, change I/Q direction + { + TempPot = 1; + if((FlucPot & 0x20)==0x20) //b[5]:I/Q selection. 0:Q-path, 1:I-path + { + FlucPot = (FlucPot & 0xD0) | 0x01; //Q1 + } + else + { + FlucPot = (FlucPot & 0xD0) | 0x21; //I1 + } + } + else + { + FlucPot -= 1; //-1-1=-2 + } + } + + if(CorTemp[TreeCunt].Value < Compare_Temp.Value) + { + Compare_Temp.Value = CorTemp[TreeCunt].Value; + Compare_Temp.Gain_X = CorTemp[TreeCunt].Gain_X; + Compare_Temp.Phase_Y = CorTemp[TreeCunt].Phase_Y; + CuntTemp = TreeCunt; + } + } + + + //CompareTree[0].Gain_X = CorTemp[CuntTemp].Gain_X; + //CompareTree[0].Phase_Y = CorTemp[CuntTemp].Phase_Y; + //CompareTree[0].Value = CorTemp[CuntTemp].Value; + + for(CompCunt=0; CompCunt<3; CompCunt++) + { + if(CuntTemp==3 || CuntTemp==4) + { + CompareTree[CompCunt].Gain_X = CorTemp[2+CompCunt].Gain_X; //2,3,4 + CompareTree[CompCunt].Phase_Y = CorTemp[2+CompCunt].Phase_Y; + CompareTree[CompCunt].Value = CorTemp[2+CompCunt].Value; + } + else + { + CompareTree[CompCunt].Gain_X = CorTemp[CompCunt].Gain_X; //0,1,2 + CompareTree[CompCunt].Phase_Y = CorTemp[CompCunt].Phase_Y; + CompareTree[CompCunt].Value = CorTemp[CompCunt].Value; + } + + } + + return R850_Success; +} + +R850_ErrCode R850_Section(struct r850_priv*priv, struct R850_SectType* IQ_Pont) +{ + struct R850_SectType Compare_IQ[3]; + struct R850_SectType Compare_Bet[3]; + + //Try X-1 column and save min result to Compare_Bet[0] + if((IQ_Pont->Gain_X & 0x0F) == 0x00) + { + Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) & 0xDF) + 1; //Q-path, Gain=1 + } + else + { + Compare_IQ[0].Gain_X = IQ_Pont->Gain_X - 1; //left point + } + Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; + + if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) // y-direction + return R850_Fail; + + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + Compare_Bet[0].Gain_X = Compare_IQ[0].Gain_X; + Compare_Bet[0].Phase_Y = Compare_IQ[0].Phase_Y; + Compare_Bet[0].Value = Compare_IQ[0].Value; + + //Try X column and save min result to Compare_Bet[1] + Compare_IQ[0].Gain_X = IQ_Pont->Gain_X; + Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; + + if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) + return R850_Fail; + + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + Compare_Bet[1].Gain_X = Compare_IQ[0].Gain_X; + Compare_Bet[1].Phase_Y = Compare_IQ[0].Phase_Y; + Compare_Bet[1].Value = Compare_IQ[0].Value; + + //Try X+1 column and save min result to Compare_Bet[2] + if((IQ_Pont->Gain_X & 0x0F) == 0x00) + Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) | 0x20) + 1; //I-path, Gain=1 + else + Compare_IQ[0].Gain_X = IQ_Pont->Gain_X + 1; + Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; + + if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) + return R850_Fail; + + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + Compare_Bet[2].Gain_X = Compare_IQ[0].Gain_X; + Compare_Bet[2].Phase_Y = Compare_IQ[0].Phase_Y; + Compare_Bet[2].Value = Compare_IQ[0].Value; + + if(R850_CompreCor(&Compare_Bet[0]) != R850_Success) + return R850_Fail; + + *IQ_Pont = Compare_Bet[0]; + + return R850_Success; +} +R850_ErrCode R850_IMR_Iqcap(struct r850_priv*priv, struct R850_SectType* IQ_Point) +{ + struct R850_SectType Compare_Temp; + int i = 0; + + //Set Gain/Phase to right setting + if(r850_wr( priv,R850_IMR_GAIN_REG,IQ_Point->Gain_X) != 0) + return R850_Fail; + + if(r850_wr( priv,R850_IMR_PHASE_REG,IQ_Point->Phase_Y) != 0) + return R850_Fail; + + //try iqcap + for(i=0; i<3; i++) + { + Compare_Temp.Iqcap = (u8) i; + priv->regs[R850_IMR_IQCAP_REG] = (priv->regs[R850_IMR_IQCAP_REG] & 0x3F) | (Compare_Temp.Iqcap<<6); + if(r850_wr( priv,R850_IMR_IQCAP_REG,priv->regs[R850_IMR_IQCAP_REG]) != 0) + return R850_Fail; + + + + if(R850_Muti_Read(priv, &(Compare_Temp.Value)) != R850_Success) + return R850_Fail; + + if(Compare_Temp.Value < IQ_Point->Value) + { + IQ_Point->Value = Compare_Temp.Value; + IQ_Point->Iqcap = Compare_Temp.Iqcap; //0, 1, 2 + } + else if(Compare_Temp.Value == IQ_Point->Value) + { + IQ_Point->Value = Compare_Temp.Value; + IQ_Point->Iqcap = Compare_Temp.Iqcap; //0, 1, 2 + } + } + + return R850_Success; +} + +R850_ErrCode R850_IMR_Cross( struct r850_priv*priv,struct R850_SectType* IQ_Pont, u8* X_Direct) +{ + + struct R850_SectType Compare_Cross[9]; //(0,0)(0,Q-1)(0,I-1)(Q-1,0)(I-1,0)+(0,Q-2)(0,I-2)(Q-2,0)(I-2,0) + struct R850_SectType Compare_Temp; + u8 CrossCount = 0; + u8 RegGain = priv->regs[R850_IMR_GAIN_REG] & 0xD0; + u8 RegPhase = priv->regs[R850_IMR_PHASE_REG] & 0xD0; + + //memset(&Compare_Temp,0, sizeof(R850_SectType)); + Compare_Temp.Gain_X = 0; + Compare_Temp.Phase_Y = 0; + Compare_Temp.Iqcap = 0; + Compare_Temp.Value = 255; + + for(CrossCount=0; CrossCount<9; CrossCount++) + { + + if(CrossCount==0) + { + Compare_Cross[CrossCount].Gain_X = RegGain; + Compare_Cross[CrossCount].Phase_Y = RegPhase; + } + else if(CrossCount==1) + { + Compare_Cross[CrossCount].Gain_X = RegGain; //0 + Compare_Cross[CrossCount].Phase_Y = RegPhase + 1; //Q-1 + } + else if(CrossCount==2) + { + Compare_Cross[CrossCount].Gain_X = RegGain; //0 + Compare_Cross[CrossCount].Phase_Y = (RegPhase | 0x20) + 1; //I-1 + } + else if(CrossCount==3) + { + Compare_Cross[CrossCount].Gain_X = RegGain + 1; //Q-1 + Compare_Cross[CrossCount].Phase_Y = RegPhase; + } + else if(CrossCount==4) + { + //Compare_Cross[CrossCount].Gain_X = (RegGain | 0x10) + 1; //I-1 + Compare_Cross[CrossCount].Gain_X = (RegGain | 0x20) + 1; //I-1 + Compare_Cross[CrossCount].Phase_Y = RegPhase; + } + else if(CrossCount==5) + { + Compare_Cross[CrossCount].Gain_X = RegGain; //0 + Compare_Cross[CrossCount].Phase_Y = RegPhase + 2; //Q-2 + } + else if(CrossCount==6) + { + Compare_Cross[CrossCount].Gain_X = RegGain; //0 + Compare_Cross[CrossCount].Phase_Y = (RegPhase | 0x20) + 2; //I-2 + } + else if(CrossCount==7) + { + Compare_Cross[CrossCount].Gain_X = RegGain + 2; //Q-2 + Compare_Cross[CrossCount].Phase_Y = RegPhase; + } + else if(CrossCount==8) + { + Compare_Cross[CrossCount].Gain_X = (RegGain | 0x20) + 2; //I-2 + Compare_Cross[CrossCount].Phase_Y = RegPhase; + } + + // R850_I2C.RegAddr = R850_IMR_GAIN_REG; + // R850_I2C.Data = Compare_Cross[CrossCount].Gain_X; + if(r850_wr(priv,R850_IMR_GAIN_REG,Compare_Cross[CrossCount].Gain_X)!=0) + return R850_Fail; + + +// R850_I2C.RegAddr = R850_IMR_PHASE_REG; +// R850_I2C.Data = Compare_Cross[CrossCount].Phase_Y; + if(r850_wr(priv,R850_IMR_PHASE_REG,Compare_Cross[CrossCount].Phase_Y)!=0) + return R850_Fail; + + + if(R850_Muti_Read(priv, &Compare_Cross[CrossCount].Value) != R850_Success) + return R850_Fail; + + if( Compare_Cross[CrossCount].Value < Compare_Temp.Value) + { + Compare_Temp.Value = Compare_Cross[CrossCount].Value; + Compare_Temp.Gain_X = Compare_Cross[CrossCount].Gain_X; + Compare_Temp.Phase_Y = Compare_Cross[CrossCount].Phase_Y; + } + } //end for loop + + + if(((Compare_Temp.Phase_Y & 0x2F)==0x01) || (Compare_Temp.Phase_Y & 0x2F)==0x02) //phase Q1 or Q2 + { + *X_Direct = (u8) 0; + IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; //0 + IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; //0 + IQ_Pont[0].Value = Compare_Cross[0].Value; + + IQ_Pont[1].Gain_X = Compare_Cross[1].Gain_X; //0 + IQ_Pont[1].Phase_Y = Compare_Cross[1].Phase_Y; //Q1 + IQ_Pont[1].Value = Compare_Cross[1].Value; + + IQ_Pont[2].Gain_X = Compare_Cross[5].Gain_X; //0 + IQ_Pont[2].Phase_Y = Compare_Cross[5].Phase_Y;//Q2 + IQ_Pont[2].Value = Compare_Cross[5].Value; + } + else if(((Compare_Temp.Phase_Y & 0x2F)==0x21) || (Compare_Temp.Phase_Y & 0x2F)==0x22) //phase I1 or I2 + { + *X_Direct = (u8) 0; + IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; //0 + IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; //0 + IQ_Pont[0].Value = Compare_Cross[0].Value; + + IQ_Pont[1].Gain_X = Compare_Cross[2].Gain_X; //0 + IQ_Pont[1].Phase_Y = Compare_Cross[2].Phase_Y; //Q1 + IQ_Pont[1].Value = Compare_Cross[2].Value; + + IQ_Pont[2].Gain_X = Compare_Cross[6].Gain_X; //0 + IQ_Pont[2].Phase_Y = Compare_Cross[6].Phase_Y;//Q2 + IQ_Pont[2].Value = Compare_Cross[6].Value; + } + else if(((Compare_Temp.Gain_X & 0x2F)==0x01) || (Compare_Temp.Gain_X & 0x2F)==0x02) //gain Q1 or Q2 + { + *X_Direct = (u8) 1; + IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; //0 + IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; //0 + IQ_Pont[0].Value = Compare_Cross[0].Value; + + IQ_Pont[1].Gain_X = Compare_Cross[3].Gain_X; //Q1 + IQ_Pont[1].Phase_Y = Compare_Cross[3].Phase_Y; //0 + IQ_Pont[1].Value = Compare_Cross[3].Value; + + IQ_Pont[2].Gain_X = Compare_Cross[7].Gain_X; //Q2 + IQ_Pont[2].Phase_Y = Compare_Cross[7].Phase_Y;//0 + IQ_Pont[2].Value = Compare_Cross[7].Value; + } + else if(((Compare_Temp.Gain_X & 0x2F)==0x21) || (Compare_Temp.Gain_X & 0x2F)==0x22) //gain I1 or I2 + { + *X_Direct = (u8) 1; + IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; //0 + IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; //0 + IQ_Pont[0].Value = Compare_Cross[0].Value; + + IQ_Pont[1].Gain_X = Compare_Cross[4].Gain_X; //I1 + IQ_Pont[1].Phase_Y = Compare_Cross[4].Phase_Y; //0 + IQ_Pont[1].Value = Compare_Cross[4].Value; + + IQ_Pont[2].Gain_X = Compare_Cross[8].Gain_X; //I2 + IQ_Pont[2].Phase_Y = Compare_Cross[8].Phase_Y;//0 + IQ_Pont[2].Value = Compare_Cross[8].Value; + } + else //(0,0) + { + *X_Direct = (u8) 1; + IQ_Pont[0].Gain_X = Compare_Cross[0].Gain_X; + IQ_Pont[0].Phase_Y = Compare_Cross[0].Phase_Y; + IQ_Pont[0].Value = Compare_Cross[0].Value; + + IQ_Pont[1].Gain_X = Compare_Cross[3].Gain_X; //Q1 + IQ_Pont[1].Phase_Y = Compare_Cross[3].Phase_Y; //0 + IQ_Pont[1].Value = Compare_Cross[3].Value; + + IQ_Pont[2].Gain_X = Compare_Cross[4].Gain_X; //I1 + IQ_Pont[2].Phase_Y = Compare_Cross[4].Phase_Y; //0 + IQ_Pont[2].Value = Compare_Cross[4].Value; + } + return R850_Success; +} + + +R850_ErrCode R850_IQ( struct r850_priv*priv, struct R850_SectType* IQ_Pont) +{ + struct R850_SectType Compare_IQ[3]; + u8 X_Direction; // 1:X, 0:Y + + //------- increase Filter gain max to let ADC read value significant ---------// + + priv->regs[41] = (priv->regs[41] | 0xF0); + if(r850_wr(priv,41,priv->regs[41])!=0) + return R850_Fail; + + + + //give a initial value, no useful + Compare_IQ[0].Gain_X = priv->regs[R850_IMR_GAIN_REG] & 0xD0; + Compare_IQ[0].Phase_Y = priv->regs[R850_IMR_PHASE_REG] & 0xD0; + + + // Determine X or Y + if(R850_IMR_Cross( priv,&Compare_IQ[0], &X_Direction) != R850_Success) + return R850_Fail; + + if(X_Direction==1) + { + //compare and find min of 3 points. determine I/Q direction + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + //increase step to find min value of this direction + if(R850_CompreStep(priv, &Compare_IQ[0], R850_IMR_GAIN_REG) != R850_Success) //X + return R850_Fail; + } + else + { + //compare and find min of 3 points. determine I/Q direction + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + //increase step to find min value of this direction + if(R850_CompreStep(priv, &Compare_IQ[0], R850_IMR_PHASE_REG) != R850_Success) //Y + return R850_Fail; + } + + //Another direction + if(X_Direction==1) //Y-direct + { + // if(R850_IQ_Tree( Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) //Y + if(R850_IQ_Tree5( priv,Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) //Y + + return R850_Fail; + + //compare and find min of 3 points. determine I/Q direction + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + //increase step to find min value of this direction + if(R850_CompreStep(priv, &Compare_IQ[0], R850_IMR_PHASE_REG) != R850_Success) //Y + return R850_Fail; + } + else //X-direct + { + // if(R850_IQ_Tree( Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, R850_IMR_PHASE_REG, &Compare_IQ[0]) != R850_Success) //X + if(R850_IQ_Tree5(priv,Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, R850_IMR_PHASE_REG, &Compare_IQ[0]) != R850_Success) //X + return R850_Fail; + + //compare and find min of 3 points. determine I/Q direction + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + //increase step to find min value of this direction + if(R850_CompreStep(priv, &Compare_IQ[0], R850_IMR_GAIN_REG) != R850_Success) //X + return R850_Fail; + } + + + //--- Check 3 points again---// + if(X_Direction==1) //X-direct + { + if(R850_IQ_Tree(priv, Compare_IQ[0].Phase_Y, Compare_IQ[0].Gain_X, R850_IMR_PHASE_REG, &Compare_IQ[0]) != R850_Success) //X + return R850_Fail; + } + else //Y-direct + { + if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) //Y + return R850_Fail; + } + + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + //Section-9 check + if(R850_Section(priv, &Compare_IQ[0]) != R850_Success) + return R850_Fail; + + //clear IQ_Cap = 0 + //Compare_IQ[0].Iqcap = priv->regs[R850_IMR_IQCAP_REG] & 0x3F; + Compare_IQ[0].Iqcap = 0; + + if(R850_IMR_Iqcap(priv, &Compare_IQ[0]) != R850_Success) + return R850_Fail; + + *IQ_Pont = Compare_IQ[0]; + + //reset gain/phase/iqcap control setting + //R850_I2C.RegAddr = R850_IMR_GAIN_REG; + priv->regs[R850_IMR_GAIN_REG] = priv->regs[R850_IMR_GAIN_REG] & 0xD0; + if(r850_wr(priv,R850_IMR_GAIN_REG,priv->regs[R850_IMR_GAIN_REG])!=0) + return R850_Fail; + + + priv->regs[R850_IMR_PHASE_REG] = priv->regs[R850_IMR_PHASE_REG] & 0xD0; + if(r850_wr(priv,R850_IMR_PHASE_REG,priv->regs[R850_IMR_PHASE_REG])!=0) + return R850_Fail; + + + priv->regs[R850_IMR_IQCAP_REG] = priv->regs[R850_IMR_IQCAP_REG] & 0x3F; + if(r850_wr(priv,R850_IMR_IQCAP_REG,priv->regs[R850_IMR_IQCAP_REG])!=0) + return R850_Fail; + + + return R850_Success; +} + + + + + + +//----------------------------------------------------------------------------------------// +// purpose: search surrounding points from previous point +// try (x-1), (x), (x+1) columns, and find min IMR result point +// input: IQ_Pont: previous point data(IMR Gain, Phase, ADC Result, RefRreq) +// will be updated to final best point +// output: TRUE or FALSE +//----------------------------------------------------------------------------------------// +R850_ErrCode R850_F_IMR(struct r850_priv *priv, struct R850_SectType* IQ_Pont) +{ + struct R850_SectType Compare_IQ[3]; + struct R850_SectType Compare_Bet[3]; + + //------- increase Filter gain max to let ADC read value significant ---------// + priv->regs[41] = (priv->regs[41] | 0xF0); + if(r850_wr(priv,41,priv->regs[41]) != 0) + return R850_Fail; + + //Try X-1 column and save min result to Compare_Bet[0] + if((IQ_Pont->Gain_X & 0x0F) == 0x00) + { + Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) & 0xDF) + 1; //Q-path, Gain=1 + } + else + { + Compare_IQ[0].Gain_X = IQ_Pont->Gain_X - 1; //left point + } + Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; + + if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) // y-direction + return R850_Fail; + + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + Compare_Bet[0].Gain_X = Compare_IQ[0].Gain_X; + Compare_Bet[0].Phase_Y = Compare_IQ[0].Phase_Y; + Compare_Bet[0].Value = Compare_IQ[0].Value; + + //Try X column and save min result to Compare_Bet[1] + Compare_IQ[0].Gain_X = IQ_Pont->Gain_X; + Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; + + if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) + return R850_Fail; + + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + Compare_Bet[1].Gain_X = Compare_IQ[0].Gain_X; + Compare_Bet[1].Phase_Y = Compare_IQ[0].Phase_Y; + Compare_Bet[1].Value = Compare_IQ[0].Value; + + //Try X+1 column and save min result to Compare_Bet[2] + if((IQ_Pont->Gain_X & 0x0F) == 0x00) + Compare_IQ[0].Gain_X = ((IQ_Pont->Gain_X) | 0x20) + 1; //I-path, Gain=1 + else + Compare_IQ[0].Gain_X = IQ_Pont->Gain_X + 1; + Compare_IQ[0].Phase_Y = IQ_Pont->Phase_Y; + + if(R850_IQ_Tree(priv, Compare_IQ[0].Gain_X, Compare_IQ[0].Phase_Y, R850_IMR_GAIN_REG, &Compare_IQ[0]) != R850_Success) + return R850_Fail; + + if(R850_CompreCor(&Compare_IQ[0]) != R850_Success) + return R850_Fail; + + Compare_Bet[2].Gain_X = Compare_IQ[0].Gain_X; + Compare_Bet[2].Phase_Y = Compare_IQ[0].Phase_Y; + Compare_Bet[2].Value = Compare_IQ[0].Value; + + if(R850_CompreCor(&Compare_Bet[0]) != R850_Success) + return R850_Fail; + + //clear IQ_Cap = 0 + //Compare_Bet[0].Iqcap = priv->regs[3] & 0xFC; + Compare_Bet[0].Iqcap = 0; + + if(R850_IMR_Iqcap(priv, &Compare_Bet[0]) != R850_Success) + return R850_Fail; + + *IQ_Pont = Compare_Bet[0]; + + return R850_Success; +} + + + +R850_ErrCode R850_InitReg(struct r850_priv *priv)//ok +{ + u8 InitArrayCunt = 0; + + + //Write Full Table, Set Xtal Power = highest at initial + //R850_I2C_Len.RegAddr = 0; + //R850_I2C_Len.Len = R850_REG_NUM; + u8 XtalCap; + u8 Capx; + u8 Capx_3_0, Capxx; + int ret=0; + + if(priv->R850_clock_out==1) + { + if(priv->R850_Xtal_cap>31) + { + XtalCap = 1; //10 + Capx = priv->R850_Xtal_cap-10; + } + else + { + XtalCap = 0; //0 + Capx = priv->R850_Xtal_cap; + } + + Capxx = Capx & 0x01; + Capx_3_0 = Capx >> 1; + + // Set Xtal Cap R33[6:3], R34[3] XtalCap => R33[7] + R850_iniArray[0][33] = 0x01 | (Capx_3_0 << 3) | ( XtalCap << 7); + R850_iniArray[1][33] = 0x01 | (Capx_3_0 << 3) | ( XtalCap << 7); + R850_iniArray[2][33] = 0x01 | (Capx_3_0 << 3) | ( XtalCap << 7); + // Set GM=strong + R850_iniArray[0][34] = 0x04 | (Capxx << 3); + R850_iniArray[1][34] = 0x04 | (Capxx << 3); + R850_iniArray[2][34] = 0x04 | (Capxx << 3); + } + else + { + R850_iniArray[0][33]= 0x01; + R850_iniArray[1][33]= 0x01; + R850_iniArray[2][33]= 0x01; + + R850_iniArray[0][34]= 0x74; + R850_iniArray[1][34]= 0x74; + R850_iniArray[2][34]= 0x74; + + } + + + + if(priv->cfg->R850_Xtal == 24000) + { + for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_iniArray[0][InitArrayCunt]; + } + } + else if(priv->cfg->R850_Xtal == 16000) + { + for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_iniArray[1][InitArrayCunt]; + } + } + else if(priv->cfg->R850_Xtal == 27000) + { + for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_iniArray[2][InitArrayCunt]; + } + } + else + { + //no support now + return R850_Fail; + } + + +//Xtal cap + + if(priv->R850_clock_out == 1) + { + R850_SetXtalPW( priv, R850_XTAL_HIGHEST); + R850_SetXtalCap_No_Write(priv, priv->R850_Xtal_cap); + } + else if(priv->R850_clock_out == 0) + { + R850_SetXtalPW(priv, R850_XTAL_LOWEST); + R850_SetXtalCap_No_Write(priv, 0); + //gm off + R850_Set_XTAL_GM(priv, 1); //3:xtal gm off + } + else + { + R850_SetXtalCap_No_Write(priv, priv->R850_Xtal_cap); + } + + ret = r850_wrm(priv,8,&priv->regs[8],40); + if(ret!=0) + return R850_Fail; + + return R850_Success; +} + +R850_ErrCode R850_Cal_Prepare(struct r850_priv *priv,u8 u1CalFlag) +{ + //R850_Cal_Info_Type Cal_Info; + u8 InitArrayCunt = 0; + + //Write Full Table, include PLL & RingPLL all settings + //R850_I2C_Len.RegAddr = 0; + //R850_I2C_Len.Len = R850_REG_NUM; + + int ret = 0; + + switch(u1CalFlag) + { + case R850_IMR_CAL: + if(priv->cfg->R850_Xtal == 24000) + { + //542MHz + for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_IMR_CAL_Array[0][InitArrayCunt]; + } + } + else if(priv->cfg->R850_Xtal == 16000) + { + //542MHz + for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_IMR_CAL_Array[1][InitArrayCunt]; + } + } + else if(priv->cfg->R850_Xtal == 27000) + { + //542MHz + for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_IMR_CAL_Array[2][InitArrayCunt]; + } + } + else + { + //no support now + return R850_Fail; + } + break; + + case R850_IMR_LNA_CAL: + + break; + + case R850_LPF_CAL: + + if(priv->cfg->R850_Xtal == 24000) + { + for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_LPF_CAL_Array[0][InitArrayCunt]; + } + } + else if(priv->cfg->R850_Xtal == 16000) + { + for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_LPF_CAL_Array[1][InitArrayCunt]; + } + } + else if(priv->cfg->R850_Xtal == 27000) + { + for(InitArrayCunt = 8; InitArrayCuntregs[InitArrayCunt] = R850_LPF_CAL_Array[2][InitArrayCunt]; + } + } + else + { + //no support 27MHz now + return R850_Fail; + } + break; + + default: + break; + + } + + +//Xtal cap + if(priv->R850_clock_out == 1) + { + R850_SetXtalPW(priv, R850_XTAL_HIGHEST); + R850_SetXtalCap_No_Write( priv, priv->R850_Xtal_cap); + } + else if(priv->R850_clock_out == 0) + { + R850_SetXtalPW(priv, R850_XTAL_LOWEST); + R850_SetXtalCap_No_Write(priv, 0); + //gm off + R850_Set_XTAL_GM(priv, 1); //3:xtal gm off + } + else + { + R850_SetXtalCap_No_Write(priv, priv->R850_Xtal_cap); + } + + ret = r850_wrm(priv,8,&priv->regs[8],40); + if(ret) + return R850_Fail; + + return R850_Success; +} + + +R850_ErrCode R850_IMR(struct r850_priv* priv, u8 IMR_MEM, u8 IM_Flag) +{ + + //------------------------------------------------------------------- + //to do + u32 RingVCO = 0; + u32 RingFreq = 0; + u32 RingRef = priv->cfg->R850_Xtal; + u8 divnum_ring = 0; + //u8 u1MixerGain = 6; //fix at initial test + + u8 IMR_Gain = 0; + u8 IMR_Phase = 0; + struct R850_SectType IMR_POINT; + + //priv->regs[24] &= 0x3F; //clear ring_div1, R24[7:6] + //priv->regs[25] &= 0xFC; //clear ring_div2, R25[1:0] + + if(priv->cfg->R850_Xtal==24000) //24M + { + divnum_ring = 17; + } + else if(priv->cfg->R850_Xtal==16000) //16M + { + divnum_ring = 25; //3200/8/16. 32>divnum>7 + } + else if(priv->cfg->R850_Xtal==27000) //27M + { + divnum_ring = 15; //3200/8/16. 32>divnum>7 + } + else //not support + { + return R850_Fail; + } + + RingVCO = (divnum_ring)* 8 * RingRef; + RingFreq = RingVCO/48; + + switch(IMR_MEM) + { + case 0: // RingFreq = 136.0M (16M, 24M) ; RingFreq = 135.0M (27M) ; + RingFreq = RingVCO/24; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x08; // ring_div2 /4 (2) R35[1:0] => R36[3:2] + break; + case 1: // RingFreq = 326M (16M, 24M) ; RingFreq = 324.0M (27M) ; + RingFreq = RingVCO/10; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x01; // ring_div1 /5 (1) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x04; // ring_div2 /2 (1) R35[1:0] => R36[3:2] + break; + case 2: // RingFreq = 544M (16M, 24M) ; RingFreq = 540.0M (27M) ; + RingFreq = RingVCO/6; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] + break; + case 3: // RingFreq = 816M (16M, 24M) ; RingFreq = 810.0M (27M) ; + RingFreq = RingVCO/4; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x00; // ring_div1 /4 (0) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] + break; + case 4: // RingFreq = 200M (16M, 24M) ; RingFreq = 202M (27M) ; + RingFreq = RingVCO/16; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x00; // ring_div1 /4 (0) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x08; // ring_div2 /4 (2) R35[1:0] => R36[3:2] + break; + case 5: // RingFreq = 136M (16M, 24M) ; RingFreq = 135.0M (27M) ; + RingFreq = RingVCO/24; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x08; // ring_div2 /4 (2) R35[1:0] => R36[3:2] + break; + case 6: // RingFreq = 326M (16M, 24M) ; RingFreq = 324.0M (27M) ; + RingFreq = RingVCO/10; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x01; // ring_div1 /5 (1) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x04; // ring_div2 /2 (1) R35[1:0] => R36[3:2] + break; + case 7: // RingFreq = 544M (16M, 24M) ; RingFreq = 540.0M (27M) ; + RingFreq = RingVCO/6; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] + break; + case 8: // RingFreq = 816M (16M, 24M) ; RingFreq = 810.0M (27M) ; + RingFreq = RingVCO/4; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x00; // ring_div1 /4 (0) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] + break; + case 9: // RingFreq = 200M (16M, 24M) ; RingFreq = 202M (27M) ; + RingFreq = RingVCO/16; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x00; // ring_div1 /4 (0) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x08; // ring_div2 /4 (2) R35[1:0] => R36[3:2] + break; + default: // RingFreq = 544M (16M, 24M) ; RingFreq = 540.0M (27M) ; + RingFreq = RingVCO/6; + priv->regs[36] = (priv->regs[36] & 0xFC) | 0x02; // ring_div1 /6 (2) R34[6:5] => R36[1:0] + priv->regs[36] = (priv->regs[36] & 0xF3) | 0x00; // ring_div2 /1 (0) R35[1:0] => R36[3:2] + break; + } + + //write RingPLL setting, R34[4:0] => R35[4:0] + priv->regs[35] = (priv->regs[35] & 0xE0) | divnum_ring; //ring_div_num, R34[4:0] + + if(RingVCO>=3200000) + priv->regs[35] = (priv->regs[35] & 0xBF); //vco_band=high, R34[7]=0 => R35[6] + else + priv->regs[35] = (priv->regs[35] | 0x40); //vco_band=low, R34[7]=1 => R35[6] + + //write RingPLL setting, R35 + if(r850_wr(priv,35,priv->regs[35])!=0) + return R850_Fail; + + //write RingPLL setting, R36 + if(r850_wr(priv,36,priv->regs[36])!=0) + return R850_Fail; + + //Ring PLL power initial at "min_lp" + /* + //Ring PLL power, R25[2:1] + if((RingFreq>0) && (RingFreqregs[25] = (priv->regs[25] & 0xF9) | 0x04; //R25[2:1]=2'b10; min_lp + else + priv->regs[25] = (priv->regs[25] & 0xF9) | 0x00; //R25[2:1]=2'b00; min + + R850_I2C.RegAddr = 0x19; + R850_I2C.Data = priv->regs[25]; + if(I2C_Write( &R850_I2C) != R850_Success) + return R850_Fail; + */ + + { + //Must do MUX before PLL() + if(R850_MUX( priv,RingFreq - R850_IMR_IF, RingFreq, R850_STD_SIZE) != R850_Success) //IMR MUX (LO, RF) + return R850_Fail; + + priv->R850_IF_GOLOBAL = R850_IMR_IF; + if(R850_PLL(priv, (RingFreq - R850_IMR_IF), R850_STD_SIZE) != R850_Success) //IMR PLL + return R850_Fail; + + //Img_R = normal + priv->regs[19] = (priv->regs[19] & 0xEF); //R20[7]=0 => R19[4]=0 + // Mixer Amp LPF=7 (0 is widest) + priv->regs[19] = (priv->regs[19] & 0xF8) | (7); + if(r850_wr(priv,19,priv->regs[19])!=0) + return R850_Fail; + + + if(IMR_MEM==4) + { + //output atten + priv->regs[36] = (priv->regs[36] & 0xCF) | (0x10); // R41[3:0]=0 + } + else + { + //output atten + priv->regs[36] = (priv->regs[36] & 0xCF) | (0x30); // R41[3:0]=0 + + } + if(r850_wr(priv,36,priv->regs[36])!=0) + return R850_Fail; + + //Mixer Gain = 8 + priv->regs[41] = (priv->regs[41] & 0xF0) | (8); //R41[3:0]=0 + if(r850_wr(priv,41,priv->regs[41])!=0) + return R850_Fail; + + + //clear IQ_cap + //IMR_POINT.Iqcap = priv->regs[19] & 0x3F; + IMR_POINT.Iqcap = 0; + + if(IM_Flag == TRUE) + { + if(R850_IQ( priv, &IMR_POINT) != R850_Success) + return R850_Fail; + } + else //IMR_MEM 1, 0, 3, 4 + { + if((IMR_MEM==1) || (IMR_MEM==3)) + { + IMR_POINT.Gain_X = priv->imr_data[2].Gain_X; //node 3 + IMR_POINT.Phase_Y = priv->imr_data[2].Phase_Y; + IMR_POINT.Value = priv->imr_data[2].Value; + } + else if((IMR_MEM==0) || (IMR_MEM==4)) + { + IMR_POINT.Gain_X = priv->imr_data[1].Gain_X; + IMR_POINT.Phase_Y = priv->imr_data[1].Phase_Y; + IMR_POINT.Value = priv->imr_data[1].Value; + } + + if(R850_F_IMR(priv,&IMR_POINT) != R850_Success) + return R850_Fail; + } + } + + //Save IMR Value + priv->imr_data[IMR_MEM].Gain_X = IMR_POINT.Gain_X; + priv->imr_data[IMR_MEM].Phase_Y = IMR_POINT.Phase_Y; + priv->imr_data[IMR_MEM].Value = IMR_POINT.Value; + priv->imr_data[IMR_MEM].Iqcap = IMR_POINT.Iqcap; + + IMR_Gain = priv->imr_data[IMR_MEM].Gain_X & 0x2F; //R20[3:0] + IMR_Phase = priv->imr_data[IMR_MEM].Phase_Y & 0x2F; //R21[3:0] + + + if(((IMR_Gain & 0x0F)>6) || ((IMR_Phase & 0x0F)>6)) + { + priv->R850_IMR_Cal_Result = 1; //fail + } + + return R850_Success; +} + +//----------------------------------------------------------------------// +// R850_GetRfRssi( ): Get RF RSSI // +// 1st parameter: input RF Freq (KHz) // +// 2nd parameter: input Standard // +// 3rd parameter: output signal level (dBm*1000) // +// 4th parameter: output RF max gain indicator (1:max gain) // +//-----------------------------------------------------------------------// +R850_ErrCode R850_GetRfRssi( struct r850_priv*priv,u32 RF_Freq_Khz, enum R850_Standard_Type RT_Standard, s32 *RfLevelDbm, u8 *fgRfMaxGain) +{ + //u8 bPulseFlag; + struct R850_RF_Gain_Info rf_gain_info; + u16 acc_lna_gain; + u16 acc_rfbuf_gain; + u16 acc_mixer_gain; + u16 rf_total_gain; + u8 u1FreqIndex; + s16 u2FreqFactor=0; + u8 u1LnaGainqFactorIdx; + s32 rf_rssi; + s32 fine_tune = 0; //for find tune + u8 rf_limit; + u8 mixer_limit; + u8 mixer_1315_gain = 0; + u8 filter_limit; + //{50~135, 135~215, 215~265, 265~315, 315~325, 325~345, 345~950} + s8 R850_Start_Gain_Cal_By_Freq[7] = {10, -10, -30, -10, 20, 20, 20}; + u8 buf[6]; + + + r850_rd(priv,0,buf,6); + + //bPulseFlag = ((R850_I2C_Len.Data[1] & 0x40) >> 6); + + rf_gain_info.RF_gain1 = (buf[3] & 0x1F); //lna + rf_gain_info.RF_gain2 = (buf[4] & 0x0F); //rf + rf_gain_info.RF_gain3 = (buf[4] & 0xF0)>>4; //mixer + rf_gain_info.RF_gain4 = (buf[5] & 0x0F); //filter + + + //max gain indicator + if((rf_gain_info.RF_gain1==31) && (rf_gain_info.RF_gain2==15) && (rf_gain_info.RF_gain3==15) && (rf_gain_info.RF_gain4==15)) + *fgRfMaxGain = 1; + else + *fgRfMaxGain = 0; + rf_limit = (((priv->regs[18]&0x04)>>1) + ((priv->regs[16]&0x40)>>6)); + + if(rf_limit==0) + rf_limit = 15; + else if(rf_limit==1) + rf_limit = 11; + else if(rf_limit==2) + rf_limit = 13; + else + rf_limit = 9; + + mixer_limit = (((priv->regs[22]&0xC0)>>6)*2)+6; //0=6, 1=8, 2=10, 3=12 + mixer_1315_gain = ((priv->regs[25]&0x02)>>1); //0:original, 1:ctrl by mixamp (>10) + + if( rf_gain_info.RF_gain2 > rf_limit) + rf_gain_info.RF_gain2 = rf_limit; + + if((rf_gain_info.RF_gain3 > 12)&&(mixer_1315_gain==1)) + mixer_1315_gain = rf_gain_info.RF_gain3; //save 0 or 13 or 14 or 15 + + if( rf_gain_info.RF_gain3 > mixer_limit) + rf_gain_info.RF_gain3 = mixer_limit; + + + filter_limit = (priv->regs[22]&0x01); + if(filter_limit==1) + filter_limit = 15; + else + filter_limit = 13; + + if( rf_gain_info.RF_gain4 > filter_limit) + rf_gain_info.RF_gain4 = filter_limit; + + + //coarse adjustment + if(RF_Freq_Khz<135000) //<135M + { + u1FreqIndex = 0; + u2FreqFactor = R850_Start_Gain_Cal_By_Freq[0]; + } + else if((RF_Freq_Khz>=135000)&&(RF_Freq_Khz<215000)) //135~215M + { + u1FreqIndex = 0; + u2FreqFactor = R850_Start_Gain_Cal_By_Freq[1]; + } + else if((RF_Freq_Khz>=215000)&&(RF_Freq_Khz<265000)) //215~265M + { + u1FreqIndex = 1; + u2FreqFactor = R850_Start_Gain_Cal_By_Freq[2]; + } + else if((RF_Freq_Khz>=265000)&&(RF_Freq_Khz<315000)) //265~315M + { + u1FreqIndex = 1; + u2FreqFactor = R850_Start_Gain_Cal_By_Freq[3]; + } + else if((RF_Freq_Khz>=315000)&&(RF_Freq_Khz<325000)) //315~325M + { + u1FreqIndex = 1; + u2FreqFactor = R850_Start_Gain_Cal_By_Freq[4]; + } + else if((RF_Freq_Khz>=325000)&&(RF_Freq_Khz<345000)) //325~345M + { + u1FreqIndex = 1; + u2FreqFactor = R850_Start_Gain_Cal_By_Freq[5]; + } + else if((RF_Freq_Khz>=345000)&&(RF_Freq_Khz<420000)) //345~420M + { + u1FreqIndex = 1; + u2FreqFactor = R850_Start_Gain_Cal_By_Freq[6]; + } + else if((RF_Freq_Khz>=420000)&&(RF_Freq_Khz<710000)) //420~710M + { + u1FreqIndex = 2; + u2FreqFactor = R850_Start_Gain_Cal_By_Freq[6]; + + } + else // >=710 + { + u1FreqIndex = 3; + u2FreqFactor = R850_Start_Gain_Cal_By_Freq[6]; + } + + + //LNA Gain + acc_lna_gain = R850_Lna_Acc_Gain[u1FreqIndex][rf_gain_info.RF_gain1]; + + + + //fine adjustment + //Cal LNA Gain by Freq + + //Method 2 : All frequencies are finely adjusted.. + + + if(rf_gain_info.RF_gain1 >= 10) + { + u1LnaGainqFactorIdx = (u8) ((RF_Freq_Khz-50000) / 10000); + + if( ((RF_Freq_Khz-50000) - (u1LnaGainqFactorIdx * 10000))>=5000) + u1LnaGainqFactorIdx +=1; + acc_lna_gain += (u16)(Lna_Acc_Gain_offset[u1LnaGainqFactorIdx]); + + } + + //RF buf + acc_rfbuf_gain = R850_Rf_Acc_Gain[rf_gain_info.RF_gain2]; + if(RF_Freq_Khz<=300000) + acc_rfbuf_gain += (rf_gain_info.RF_gain2 * 1); + else if (RF_Freq_Khz>=600000) + acc_rfbuf_gain -= (rf_gain_info.RF_gain2 * 1); + + //Mixer + acc_mixer_gain = R850_Mixer_Acc_Gain [rf_gain_info.RF_gain3] ; + + if((mixer_1315_gain!=0) && (mixer_1315_gain!=1)) //Gain 13 or 14 or 15 + acc_mixer_gain = acc_mixer_gain + (R850_Mixer_Acc_Gain[mixer_1315_gain] - R850_Mixer_Acc_Gain[12]); + + + + //Add Rf Buf and Mixer Gain + rf_total_gain = acc_lna_gain + acc_rfbuf_gain + acc_mixer_gain + rf_gain_info.RF_gain4*153/10; + + rf_rssi = fine_tune - (s32) (rf_total_gain - u2FreqFactor); + + + *RfLevelDbm = rf_rssi*100; + + return R850_Success; +} + + +//-----------------------------------------------------------------------// +// R850_GetIfRssi( ): Get IF VGA GAIN // +// 1st parameter: return IF VGA Gain (dB*100) // +//-----------------------------------------------------------------------// +R850_ErrCode R850_GetIfRssi(struct r850_priv*priv,s32 *VgaGain) +{ + u8 adc_read; + u8 buf[2]; + //Optimize value + u16 vga_table[64] = { //*100 + 0, 0, 20, 20, 30, 50, 60, 80, 110, 130, 130, 160, //0~11 + 200, 240, 280, 330, 380, 410, 430, 480, 530, 590, //12~21 + 640, 690, 730, 760, 780, 810, 840, 890, 930, 950, //22~31 + 980, 1010, 1010, 1030, 1060, 1100, 1120, 1140, 1170, 1180, //32~41 + 1190, 1210, 1220, 1260, 1270, 1300, 1320, 1320, 1340, 1340, //42~51 + 1360, 1390, 1400, 1420, 1440, 1450, 1460, 1480, 1490, 1510, //52~61 + 1550, 1600 //62~63 + }; + + //ADC sel : vagc, R22[3:2]=2 + priv->regs[22] = (priv->regs[22] & 0xF3) | 0x08; + if(r850_wr(priv,22,priv->regs[22]) != 0) + return R850_Fail; + + //IF_AGC read, R18[5]=1 + priv->regs[18] = priv->regs[18] | 0x20; + if(r850_wr(priv,18,priv->regs[18]) != 0) + return R850_Fail; + + //ADC power on, R11[1]=0 + priv->regs[11] = priv->regs[11] & 0xFD; + if(r850_wr(priv,11,priv->regs[11]) != 0) + return R850_Fail; + + //read adc value + r850_rd(priv,0x00,buf,2); + adc_read = (buf[1] & 0x3F); + + *VgaGain = vga_table[adc_read]; + + return R850_Success; +} + + +// R850_GetRfRssi( ): Get RF RSSI // +// 1st parameter: input RF Freq (KHz) // +// 2nd parameter: input Standard // +// 3rd parameter: return signal level indicator (dBm) // +//-----------------------------------------------------------------------// +R850_ErrCode R850_GetTotalRssi( struct r850_priv*priv, u32 RF_Freq_Khz, enum R850_Standard_Type RT_Standard, s32 *RssiDbm) +{ + s32 rf_rssi; + s32 if_rssi; + s32 rem, total_rssi; + s32 ssi_offset = 0; //need to fine tune by platform + s32 total_rssi_dbm; + u8 rf_max_gain_flag; + + R850_GetRfRssi(priv, RF_Freq_Khz, RT_Standard, &rf_rssi, &rf_max_gain_flag); + + R850_GetIfRssi(priv, &if_rssi); //vga gain + + total_rssi = rf_rssi - (if_rssi*10); + rem = total_rssi - (total_rssi/1000)*1000; //for rounding + if((rem>-500) && (rem<500)) + total_rssi_dbm = (total_rssi/1000); + else if(rem<=-500) + total_rssi_dbm = (total_rssi/1000)-1; + else + total_rssi_dbm = (total_rssi/1000)+1; + + //for different platform, need to fine tune offset value + *RssiDbm = total_rssi_dbm + ssi_offset+8; + + return R850_Success; +} + +u8 R850_Filt_Cal_ADC(struct r850_priv *priv, u32 IF_Freq, u8 R850_BW, u8 FilCal_Gap) +{ + u8 u1FilterCodeResult = 0; + u8 u1FilterCode = 0; + u8 u1FilterCalValue = 0; + u8 u1FilterCalValuePre = 0; + u8 initial_cnt = 0; + u8 i = 0; + //u32 RingVCO = 0; + u32 RingFreq = 72000; + u8 ADC_Read_Value = 0; + u8 ADC_Read_Value_8M5Hz = 0; + u8 LPF_Count = 0; + //u32 RingRef = R850_Xtal; + //u8 divnum_ring = 0; + //u8 VGA_Count = 0; + + + if(R850_Cal_Prepare(priv, R850_LPF_CAL) != R850_Success) + return R850_Fail; + + priv->R850_IF_GOLOBAL = IF_Freq; + //Set PLL (TBD, normal) + if(R850_PLL(priv, (RingFreq - IF_Freq), R850_STD_SIZE) != R850_Success) //FilCal PLL + return R850_Fail; + + //------- increase Filter gain to let ADC read value significant ---------// + for(LPF_Count=5; LPF_Count < 16; LPF_Count ++) + { + + priv->regs[41] = (priv->regs[41] & 0x0F) | (LPF_Count<<4); + if(r850_wr(priv,41,priv->regs[41]) != 0) + return R850_Fail; + + msleep( R850_FILTER_GAIN_DELAY); // + + if(R850_Muti_Read(priv, &ADC_Read_Value) != R850_Success) + return R850_Fail; + + if(ADC_Read_Value > 40*R850_ADC_READ_COUNT) + { + break; + } + } + + + //If IF_Freq>10MHz, need to compare 8.5MHz ADC Value, + //If the ADC values greater than 8 in the same gain,the filter corner select 8M / 0 + if(IF_Freq>=10000) + { + priv->R850_IF_GOLOBAL = 8500; + //Set PLL (TBD, normal) + if(R850_PLL( priv,(RingFreq - 8500), R850_STD_SIZE) != R850_Success) //FilCal PLL + return R850_Fail; + + msleep( R850_FILTER_GAIN_DELAY); // + + if(R850_Muti_Read( priv,&ADC_Read_Value_8M5Hz) != R850_Success) + return R850_Fail; + + if(ADC_Read_Value_8M5Hz > (ADC_Read_Value + 8) ) + { + //priv->bw = 0; //8M + u1FilterCodeResult = 0; + return u1FilterCodeResult; + } + else + { + priv->R850_IF_GOLOBAL = IF_Freq; + //Set PLL (TBD, normal) + if(R850_PLL(priv, (RingFreq - IF_Freq), R850_STD_SIZE) != R850_Success) //FilCal PLL + return R850_Fail; + } + } + + + + //------- Try suitable BW --------// + if(R850_BW==2) //6M + initial_cnt = 1; //try 7M first + else + initial_cnt = 0; //try 8M first + + for(i=initial_cnt; i<3; i++) + { + + //Set BW R22[5:4] => R23[6:5] + priv->regs[23] = (priv->regs[23] & 0xCF); + if(r850_wr(priv,23,priv->regs[23]) != 0) + return R850_Fail; + + // read code 0 R22[4:1] => R23[4:1] + priv->regs[23] = (priv->regs[23] & 0xE1); //code 0 + if(r850_wr(priv,23,priv->regs[23]) != 0) + return R850_Fail; + + msleep( R850_FILTER_CODE_DELAY); //delay ms + + if(R850_Muti_Read(priv, &u1FilterCalValuePre) != R850_Success) + return R850_Fail; + + //read code 26 R22[4:1] => R23[4:1] + priv->regs[23] = (priv->regs[23] & 0xE1) | (13<<1); //code 26 + if(r850_wr(priv,23,priv->regs[23]) != 0) + return R850_Fail; + + msleep( R850_FILTER_CODE_DELAY); //delay ms + + if(R850_Muti_Read(priv, &u1FilterCalValue) != R850_Success) + return R850_Fail; + + if(u1FilterCalValuePre > (u1FilterCalValue+16)) //suitable BW found + break; + } + + //-------- Try LPF filter code ---------// + u1FilterCalValuePre = 0; + for(u1FilterCode=0; u1FilterCode<16; u1FilterCode++) + { + priv->regs[23] = (priv->regs[23] & 0xE1) | (u1FilterCode<<1); + if(r850_wr(priv,23,priv->regs[23]) != 0) + + return R850_Fail; + + msleep( R850_FILTER_CODE_DELAY); //delay ms + + if(R850_Muti_Read(priv, &u1FilterCalValue) != R850_Success) + return R850_Fail; + + if((IF_Freq>=10000)&&(u1FilterCode==0)) + { + u1FilterCalValuePre = ADC_Read_Value_8M5Hz; + } + else if(u1FilterCode==0) + { + u1FilterCalValuePre = u1FilterCalValue; + } + + if((u1FilterCalValue+FilCal_Gap*R850_ADC_READ_COUNT) < u1FilterCalValuePre) + { + u1FilterCodeResult = u1FilterCode; + break; + } + } + + //Try LSB bit + if(u1FilterCodeResult>0) //try code-1 & lsb=1 + { + + priv->regs[23] = (priv->regs[23] & 0xE0) | ((u1FilterCodeResult-1)<<1) | 0x01; + if(r850_wr(priv,23,priv->regs[23]) != 0) + return R850_Fail; + + msleep( R850_FILTER_GAIN_DELAY); //delay ms + + if(R850_Muti_Read( priv,&u1FilterCalValue) != R850_Success) + return R850_Fail; + + if((u1FilterCalValue+FilCal_Gap*R850_ADC_READ_COUNT) < u1FilterCalValuePre) + { + u1FilterCodeResult = u1FilterCodeResult - 1; + } + + } + + if(u1FilterCode==16) + u1FilterCodeResult = 15; + + return u1FilterCodeResult; + +} + +R850_ErrCode R850_SetStandard(struct r850_priv *priv, enum R850_Standard_Type RT_Standard) +{ + u8 u1FilCalGap = 16; + + //HPF ext protection + if(priv->fc.flag== 0) + { + priv->fc.code = R850_Filt_Cal_ADC(priv, priv->R850_Sys_Info.FILT_CAL_IF, priv->R850_Sys_Info.BW, u1FilCalGap); + priv->fc.bw = 0; + priv->fc.flag = 1; + priv->fc.lpflsb = 0; + + //Reset register and Array + if(R850_InitReg(priv) != R850_Success) + return R850_Fail; + } + // Set LPF Lsb bit + priv->regs[23] = (priv->regs[23] & 0xFE) ; //R23[0] + // Set LPF fine code + priv->regs[23] = (priv->regs[23] & 0xE1) | (priv->fc.code<<1); //R23[4:1] + // Set LPF coarse BW + priv->regs[23] = (priv->regs[23] & 0x9F) | (priv->fc.bw<<5); //R23[6:5] + //Set HPF notch R23[7] + priv->regs[23] = (priv->regs[23] & 0x7F) | (priv->R850_Sys_Info.HPF_NOTCH<<7); + if(r850_wr(priv,23,priv->regs[23]) != 0) + return R850_Fail; + + + // Set HPF corner + priv->regs[24] = (priv->regs[24] & 0x0F) | (priv->R850_Sys_Info.HPF_COR<<4); //R24[3:0] => R24[7:4] + if(r850_wr(priv,24,priv->regs[24]) != 0) + return R850_Fail; + + + // Set Filter Auto Ext + priv->regs[18] = (priv->regs[18] & 0xBF) | (priv->R850_Sys_Info.FILT_EXT_ENA<<6); // =>R18[6] + if(r850_wr(priv,18,priv->regs[18]) != 0) + return R850_Fail; + + //set Filter Comp //R24[3:2] + priv->regs[24] = (priv->regs[24] & 0xF3) | (priv->R850_Sys_Info.FILT_COMP<<2); + if(r850_wr(priv,24,priv->regs[24]) != 0) + return R850_Fail; + + // Set AGC clk R47[3:2] + priv->regs[47] = (priv->regs[47] & 0xF3) | (priv->R850_Sys_Info.AGC_CLK<<2); + if(r850_wr(priv,47,priv->regs[47]) != 0) + return R850_Fail; + + priv->regs[44] = (priv->regs[44] & 0xFE) | ((priv->R850_Sys_Info.IMG_GAIN & 0x02)>>1); + if(r850_wr(priv,44,priv->regs[44]) != 0) + return R850_Fail; + + priv->regs[46] = (priv->regs[46] & 0xEF) | ((priv->R850_Sys_Info.IMG_GAIN & 0x01)<<4); + if(r850_wr(priv,46,priv->regs[46]) != 0) + return R850_Fail; + + return R850_Success; +} + + + +R850_ErrCode R850_SetFrequency(struct r850_priv *priv, struct R850_Set_Info R850_INFO) //Write Multi byte +{ + + u32 LO_KHz; + u8 Img_R; + u8 SetFreqArrayCunt; + int ret = 0; + + struct R850_SysFreq_Info_Type SysFreq_Info1; + + //Get Sys-Freq parameter + + SysFreq_Info1 = R850_SysFreq_NrbDetOn_Sel( R850_INFO.R850_Standard, R850_INFO.RF_KHz); + + //R850_IMR_point_num = Freq_Info1.IMR_MEM_NOR; + + // Check Input Frequency Range + if((R850_INFO.RF_KHz<40000) || (R850_INFO.RF_KHz>1002000)) + { + return R850_Fail; + } + + + + LO_KHz = R850_INFO.RF_KHz + priv->R850_Sys_Info.IF_KHz; + Img_R = 0; + + priv->regs[19] = (priv->regs[19] & 0xEF) | (Img_R<<4); //R20[7] => R19[4] + if(r850_wr(priv,19,priv->regs[19])) + return R850_Fail; + + + //Set MUX dependent var. Must do before PLL() + if(R850_MUX( priv,LO_KHz, R850_INFO.RF_KHz, R850_INFO.R850_Standard) != R850_Success) //normal MUX + return R850_Fail; + + priv->R850_IF_GOLOBAL = priv->R850_Sys_Info.IF_KHz; + //Set PLL + if(R850_PLL(priv, LO_KHz, R850_INFO.R850_Standard) != R850_Success) //noraml PLL + return R850_Fail; + + // PW + // Set NA det power R10[6] + //if(R850_External_LNA == 0) //External LNA Disable => depend on setting + priv->regs[10] = (priv->regs[10] & 0xBF) | (SysFreq_Info1.NA_PWR_DET<<6); +// else //External LNA Enable => fixed + // priv->regs[R850_I2C.RegAddr] = (priv->regs[R850_I2C.RegAddr] & 0xBF); + + //Set Man Buf Cur R16[5] +// if(R850_External_LNA == 0) //External LNA Disable => depend on initial value + priv->regs[16] = (priv->regs[16] & 0xDF) | (R850_iniArray[0][16] & 0x20); +// else //External LNA Enable => fixed +// priv->regs[R850_I2C.RegAddr] = (priv->regs[R850_I2C.RegAddr] | 0x20); + + + //LNA_NRB_DET R11[7] + priv->regs[11] = (priv->regs[11] & 0x7F) | (SysFreq_Info1.LNA_NRB_DET<<7); + + //LNA + // LNA_TOP R38[2:0] + priv->regs[38] = (priv->regs[38] & 0xF8) | (7 - SysFreq_Info1.LNA_TOP); + + // LNA VTL/H R39[7:0] + priv->regs[39] = (priv->regs[39 ] & 0x00) | SysFreq_Info1.LNA_VTL_H; + + // RF_LTE_PSG R17[4] + priv->regs[17] = (priv->regs[17 ] & 0xEF) | (SysFreq_Info1.RF_LTE_PSG<<4); + + //RF + // RF TOP R38[6:4] + priv->regs[38] = (priv->regs[38] & 0x8F) | ((7 - SysFreq_Info1.RF_TOP)<<4); + + // RF VTL/H R42[7:0] + priv->regs[42] = (priv->regs[42] & 0x00) | SysFreq_Info1.RF_VTL_H; + + // RF Gain Limt (MSB:R18[2] & LSB:R16[6]) + switch(SysFreq_Info1.RF_GAIN_LIMIT) + { + case 0://'b00 + priv->regs[18] = (priv->regs[18] & 0xFB); + priv->regs[16] = (priv->regs[16] & 0xBF); + break; + case 1://'b01 + priv->regs[18] = (priv->regs[18] & 0xFB); + priv->regs[16] = (priv->regs[16] | 0x40); + break; + case 2://'b10 + priv->regs[18] = (priv->regs[18] | 0x02); + priv->regs[16] = (priv->regs[16] & 0xBF); + break; + case 3://'b11 + priv->regs[18] = (priv->regs[18] | 0x02); + priv->regs[16] = (priv->regs[16] | 0x40); + break; + } + + //MIXER & FILTER + //MIXER_AMP_LPF R19[2:0] + priv->regs[19] = (priv->regs[19] & 0xF8) | SysFreq_Info1.MIXER_AMP_LPF; + + // MIXER TOP R40[3:0] + priv->regs[40] = (priv->regs[40] & 0xF0) | (15 - SysFreq_Info1.MIXER_TOP); + + // Filter TOP R44[3:0] for MP, R44[3:1] for MT1 + priv->regs[44] = (priv->regs[44] & 0xF1) | ((7-SysFreq_Info1.FILTER_TOP)<<1); + + //FILT_3TH_LPF_CUR=0; //R10[4] [high (0), low (1)] + priv->regs[10] = (priv->regs[10] & 0xEF) | (SysFreq_Info1.FILT_3TH_LPF_CUR<<4); + + // 3th_LPF_Gain R24[1:0] + priv->regs[24] = (priv->regs[24] & 0xFC) | SysFreq_Info1.FILT_3TH_LPF_GAIN; + + priv->regs[19] = (priv->regs[19] & 0x7F) | 0x80; + // MIXER VTH & Filter VTH R41[7:0] + priv->regs[41] = ((priv->regs[41] & 0x00) | SysFreq_Info1.MIXER_VTH | SysFreq_Info1.FILTER_VTH); + + // MIXER VTL & Filter VTL R43[7:0] + priv->regs[43] = ((priv->regs[43] & 0x00) | SysFreq_Info1.MIXER_VTL | SysFreq_Info1.FILTER_VTL); + + // Mixer Gain Limt R22[7:6] + priv->regs[22] = (priv->regs[22] & 0x3F) | (SysFreq_Info1.MIXER_GAIN_LIMIT << 6); + + // MIXER_DETBW_LPF R46[7] + priv->regs[46] = (priv->regs[46] & 0x7F) | (SysFreq_Info1.MIXER_DETBW_LPF << 7); + + //Discharge + //LNA_RF Discharge Mode (R45[1:0]=2'b01; R9[6]=1) => (R45[1:0]=0'b00; R31[0]=1 ;R32[5]=1) + if(SysFreq_Info1.LNA_RF_DIS_MODE==0) //auto (normal) + { + priv->regs[45] = (priv->regs[45] & 0xFC) | 0x00; //00 + priv->regs[31] = (priv->regs[31] & 0xFE) | 0x01; //1 + priv->regs[32] = (priv->regs[32] & 0xDF) | 0x20; //1 + } + else if(SysFreq_Info1.LNA_RF_DIS_MODE==1) //both(fast+slow) + { + priv->regs[45] = (priv->regs[45] & 0xFC) | 0x03; //11 + priv->regs[31] = (priv->regs[31] & 0xFE) | 0x01; //1 + priv->regs[32] = (priv->regs[32] & 0xDF) | 0x20; //1 + } + else if(SysFreq_Info1.LNA_RF_DIS_MODE==2) //both(slow) + { + priv->regs[45] = (priv->regs[45] & 0xFC) | 0x03; //11 + priv->regs[31] = (priv->regs[31] & 0xFE) | 0x00; //0 + priv->regs[32] = (priv->regs[32] & 0xDF) | 0x00; //0 + } + else if(SysFreq_Info1.LNA_RF_DIS_MODE==3) //LNA(slow) + { + priv->regs[45] = (priv->regs[45] & 0xFC) | 0x03; //11 + priv->regs[31] = (priv->regs[31] & 0xFE) | 0x01; //1 + priv->regs[32] = (priv->regs[32] & 0xDF) | 0x00; //0 + } + else if(SysFreq_Info1.LNA_RF_DIS_MODE==4) //RF(slow) + { + priv->regs[45] = (priv->regs[45] & 0xFC) | 0x03; //11 + priv->regs[31] = (priv->regs[31] & 0xFE) | 0x00; //0 + priv->regs[32] = (priv->regs[32] & 0xDF) | 0x20; //1 + } + else + { + priv->regs[45] = (priv->regs[45] & 0xFC) | 0x00; //00 + priv->regs[31] = (priv->regs[31] & 0xFE) | 0x01; //1 + priv->regs[32] = (priv->regs[32] & 0xDF) | 0x20; //1 + } + + //LNA_RF_CHARGE_CUR R31[1] + priv->regs[31] = (priv->regs[31] & 0xFD) | (SysFreq_Info1.LNA_RF_CHARGE_CUR<<1); + + //LNA_RF_dis current R13[5] + priv->regs[13] = (priv->regs[13] & 0xDF) | (SysFreq_Info1.LNA_RF_DIS_CURR<<5); + + //RF_slow disch(5:4) / fast disch(7:6) //(R45[7:4]) + priv->regs[45] = (priv->regs[45] & 0x0F) | (SysFreq_Info1.RF_DIS_SLOW_FAST<<4); + + //LNA slow disch(5:4) / fast disch(7:6) => R44[7:4] + priv->regs[44] = (priv->regs[44] & 0x0F) | (SysFreq_Info1.LNA_DIS_SLOW_FAST<<4); + + //BB disch current R25[6] + priv->regs[25] = (priv->regs[25] & 0xBF) | (SysFreq_Info1.BB_DIS_CURR<<6); + + //Mixer/Filter disch R37[7:6] + priv->regs[37] = (priv->regs[37] & 0x3F) | (SysFreq_Info1.MIXER_FILTER_DIS<<6); + + //BB Det Mode R37[2] + priv->regs[37] = (priv->regs[37] & 0xFB) | (SysFreq_Info1.BB_DET_MODE<<2); + + //Polyphase + //ENB_POLY_GAIN R25[1] + priv->regs[25] = (priv->regs[25] & 0xFD) | (SysFreq_Info1.ENB_POLY_GAIN<<1); + + //NRB + // NRB TOP R40[7:4] + priv->regs[40] = (priv->regs[40] & 0x0F) | ((15 - SysFreq_Info1.NRB_TOP)<<4); + + //NRB LPF & HPF BW R26[7:6 & 3:2] + priv->regs[26] = (priv->regs[26] & 0x33) | (SysFreq_Info1.NRB_BW_HPF<<2) | (SysFreq_Info1.NRB_BW_LPF<<6); + + //NBR Image TOP adder R46[3:2] + priv->regs[46] = (priv->regs[46] & 0xF3) | (SysFreq_Info1.IMG_NRB_ADDER<<2); + + //VGA + //HPF_COMP R13[2:1] + priv->regs[13] = (priv->regs[13] & 0xF9) | (SysFreq_Info1.HPF_COMP<<1); + + //FB_RES_1ST //R21[4] + priv->regs[21] = (priv->regs[21] & 0xEF) | (SysFreq_Info1.FB_RES_1ST<<4); + + //DEGLITCH_CLK; R38[3] + priv->regs[38] = (priv->regs[38] & 0xF7) | (SysFreq_Info1.DEGLITCH_CLK<<3); + + //NAT_HYS; R35[6] + priv->regs[35] = (priv->regs[35] & 0xBF) | (SysFreq_Info1.NAT_HYS<<6); + + //NAT_CAIN; R31[4:5] + priv->regs[31] = (priv->regs[31] & 0xCF) | (SysFreq_Info1.NAT_CAIN<<4); + + //PULSE_HYS; R26[1:0] + priv->regs[26] = (priv->regs[26] & 0xFC) | (SysFreq_Info1.PULSE_HYS); + + //FAST_DEGLITCH; R36[3:2] + priv->regs[36] = (priv->regs[36] & 0xF3) | (SysFreq_Info1.FAST_DEGLITCH<<2); + + //PUL_RANGE_SEL; R31[2] + priv->regs[31] = (priv->regs[31] & 0xFB) | (SysFreq_Info1.PUL_RANGE_SEL<<2); + + //PUL_FLAG_RANGE; R35[1:0] + priv->regs[35] = (priv->regs[35] & 0xFC) | (SysFreq_Info1.PUL_FLAG_RANGE); + + //PULG_CNT_THRE; R17[1] + priv->regs[17] = (priv->regs[17] & 0xFD) | (SysFreq_Info1.PULG_CNT_THRE<<1); + + //FORCE_PULSE; R46[5] + priv->regs[46] = (priv->regs[46] & 0xDF) | (SysFreq_Info1.FORCE_PULSE<<5); + + //FLG_CNT_CLK; R47[7:6] + priv->regs[47] = (priv->regs[47] & 0x3F) | (SysFreq_Info1.FLG_CNT_CLK<<6); + + //NATG_OFFSET; R36[5:4] + priv->regs[36] = (priv->regs[36] & 0xCF) | (SysFreq_Info1.NATG_OFFSET<<4); + //other setting + + // Set AGC clk R47[3:2] only for isdbt 4.063 (set 1Khz because Div/4, original agc clk is 512Hz) + if( (R850_INFO.RF_KHz >= 478000) && (R850_INFO.RF_KHz < 482000) && (R850_INFO.R850_Standard == R850_ISDB_T_4063) ) + { + priv->regs[47] = (priv->regs[47] & 0xF3); + } + + + //IF AGC1 + priv->regs[25] = priv->regs[25] & 0xDF; + + + //Set LT + if(R850_INFO.R850_LT==R850_LT_ON) + { + //LT Sel: active LT(after LNA) R8[6]=1 ; acLT PW: ON R8[7]=1 + priv->regs[8] = (priv->regs[8] | 0xC0 ); + //Pulse LT on R10[1]=1 + priv->regs[10] = (priv->regs[10] | 0x02); + } + else + { + //LT Sel: active LT(after LNA) R8[6]=1 ; acLT PW: OFF R8[7]=0 + priv->regs[8] = ((priv->regs[8] | 0x40) & 0x7F); + //Pulse LT on R10[1]=0 + priv->regs[10] = (priv->regs[10] & 0xFD); + } + + + //Set Clk Out + if(R850_INFO.R850_ClkOutMode==R850_CLK_OUT_OFF) + { + priv->regs[34] = (priv->regs[34] | 0x04); //no clk out R34[2] = 1 + } + else + { + priv->regs[34] = (priv->regs[34] & 0xFB); //clk out R34[2] = 0 + } + + ret = r850_wrm(priv,8,&priv->regs[8],40); + if(ret!=0) + return R850_Fail; + + + return R850_Success; +} + + +static int r850_init(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct r850_priv *priv = fe->tuner_priv; + + int ret = 0; + + if(priv->inited) + return ret; + + priv->fc.bw = 0x00; + priv->fc.code = 0; + priv->fc.lpflsb = 0; + priv->fc.flag =0; + + priv->R850_Sys_Info.IF_KHz=5000; + priv->R850_Sys_Info.BW=0; //BW=8M R23[6:5] [8M(0), 7M(1), 6M(2)] + priv->R850_Sys_Info.FILT_CAL_IF=8800; //CAL IF + priv->R850_Sys_Info.HPF_COR=11; //R24[7:4] [0~15 ; input: "0~15"] + priv->R850_Sys_Info.FILT_EXT_ENA=0; //R18[6] filter ext disable [off(0), on(1)] + priv->R850_Sys_Info.FILT_COMP=2; //R24[3:2] [0~3 ; input: "0~3"] + priv->R850_Sys_Info.AGC_CLK = 1; //R47[3:2] 1k [1kHz(0), 512Hz(1), 4kHz(2), 64Hz(3)] + priv->R850_Sys_Info.IMG_GAIN = 2; ////MSB:R44[0] , LSB:R46[4] highest [lowest(0), high(1), low(2), highest(3)] + + priv->R850_clock_out = 0; + priv->R850_IMR_Cal_Result = 0; + + priv->R850_Xtal_cap = 29; + priv->R850_IF_GOLOBAL = 6000; + priv->R850_XtalDiv = R850_XTAL_DIV1; + + priv->R850_IMR_done_flag = 0; + priv->R850_IMR_Cal_Result = 0; + + + if(R850_Cal_Prepare(priv, R850_IMR_CAL) != R850_Success) + ret=-1; + + + if(R850_IMR(priv,2, TRUE) != R850_Success) //Full K node 2 + ret=-1; + + if(R850_IMR(priv, 1, FALSE) != R850_Success) + ret=-1; + + if(R850_IMR(priv, 0, FALSE) != R850_Success) + ret=-1; + + if(R850_IMR(priv, 3, FALSE) != R850_Success) + ret=-1; + + if(R850_IMR(priv, 4, FALSE) != R850_Success) + ret=-1; + + priv->R850_IMR_done_flag = 1; + + //do Xtal check + + if(priv->R850_clock_out == 1) + { + priv->R850_Xtal_Pwr = R850_XTAL_HIGHEST; + } + else //==0 + { + priv->R850_Xtal_Pwr = R850_XTAL_LOWEST; + } + + //write initial reg + if(R850_InitReg(priv) != R850_Success) + ret=-1; + + priv->inited = 1; + + /* init statistics in order signal app which are supported */ + c->strength.len = 1; + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + + return ret; + +} + +static int r850_set_params(struct dvb_frontend *fe) +{ + struct r850_priv *priv = fe->tuner_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + struct R850_Set_Info tuner_parameters; + + int ret = 0; + + if(!priv->inited) + r850_init(fe); + + tuner_parameters.RF_KHz = c->frequency /1000; + + tuner_parameters.R850_LT=R850_LT_ON; + tuner_parameters.R850_ClkOutMode=R850_CLK_OUT_OFF; + tuner_parameters.R850_Standard = R850_DTMB_8M_IF_5M; + + + + if(R850_SetStandard(priv,R850_DTMB_8M_IF_5M) != R850_Success) + ret=-1; + + if(R850_SetFrequency(priv, tuner_parameters) != R850_Success) + ret=-1; + + return ret; +} +static int r850_get_rf_strength(struct dvb_frontend *fe, u16 *rssi) +{ + struct r850_priv *priv = fe->tuner_priv; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + s32 RSSI_Value = 0; + int strength; + + R850_GetTotalRssi(priv,c->frequency/1000,R850_DTMB_8M_IF_5M,&RSSI_Value); + + if(RSSI_Value>-70) + RSSI_Value+=8; + + c->strength.len = 2; + c->strength.stat[0].scale = FE_SCALE_DECIBEL; + c->strength.stat[0].svalue = (s8)RSSI_Value * 1000; + + if(RSSI_Value<-85) + RSSI_Value = -80; + if(RSSI_Value> -50) + RSSI_Value = -20; + + strength = (85+RSSI_Value)*100/65+20; + + if(strength>100) + strength=100; + + c->strength.stat[1].scale = FE_SCALE_RELATIVE; + c->strength.stat[1].uvalue = strength*655; + + *rssi =(u16)(strength*655); + + return 0; +} +static void r850_release(struct dvb_frontend *fe) +{ + struct r850_priv *priv = fe->tuner_priv; + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; +} + +static int r850_sleep(struct dvb_frontend *fe) +{ + struct r850_priv *priv = fe->tuner_priv; + int ret = 0; + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + + //if (ret) + // dev_dbg(&priv->i2c->dev, "%s() failed\n", __func__); + return ret; +} + +static const struct dvb_tuner_ops r850_tuner_ops = { + .info = { + .name = "Rafael R850", +// .frequency_min_hz = 250 * MHz, +// .frequency_max_hz = 2300 * MHz, + }, + + .release = r850_release, + + .init = r850_init, + .sleep = r850_sleep, + .set_params = r850_set_params, + .get_rf_strength = r850_get_rf_strength, +}; + +struct dvb_frontend *r850_attach(struct dvb_frontend *fe, + struct r850_config *cfg, struct i2c_adapter *i2c) +{ + struct r850_priv *priv = NULL; + u8 chip_id; + u8 buf[50]; + int ret = 0; + + priv = kzalloc(sizeof(struct r850_priv), GFP_KERNEL); + if (priv == NULL) { + dev_dbg(&i2c->dev, "%s() attach failed\n", __func__); + return NULL; + } + + priv->cfg = cfg; + priv->i2c = i2c; + + priv->inited = 0; + + ret = r850_rd(priv,0x00,buf,48); + if(ret!=0) + return NULL; + + dev_info(&priv->i2c->dev, + "%s: Rafael R850 successfully attached,id is 0x%x\n", + KBUILD_MODNAME,buf[0]); + + memcpy(&fe->ops.tuner_ops, &r850_tuner_ops, + sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = priv; + return fe; +} + +EXPORT_SYMBOL_GPL(r850_attach); + +MODULE_DESCRIPTION("Rafael R850 tuner driver"); +MODULE_AUTHOR("Davin"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/media/tuners/r850.h b/drivers/media/tuners/r850.h index 379aa2556f82..f3e62afe72b2 100644 --- a/drivers/media/tuners/r850.h +++ b/drivers/media/tuners/r850.h @@ -1,28 +1,28 @@ -#ifndef __R850_H__ -#define __R850_H__ - - -#include -#include - -struct r850_config { - /* tuner i2c address */ - u8 i2c_address; - - u32 R850_Xtal; - -}; - -#if IS_REACHABLE(CONFIG_MEDIA_TUNER_R850) -extern struct dvb_frontend *r850_attach(struct dvb_frontend *fe, - struct r850_config *cfg, struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *r850_attach(struct dvb_frontend *fe, - struct r850_config *cfg, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - +#ifndef __R850_H__ +#define __R850_H__ + + +#include +#include + +struct r850_config { + /* tuner i2c address */ + u8 i2c_address; + + u32 R850_Xtal; + +}; + +#if IS_REACHABLE(CONFIG_MEDIA_TUNER_R850) +extern struct dvb_frontend *r850_attach(struct dvb_frontend *fe, + struct r850_config *cfg, struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend *r850_attach(struct dvb_frontend *fe, + struct r850_config *cfg, struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + #endif //__R850_H__ \ No newline at end of file diff --git a/drivers/media/tuners/r850_priv.h b/drivers/media/tuners/r850_priv.h index e8a794113e3d..30224491a8dd 100644 --- a/drivers/media/tuners/r850_priv.h +++ b/drivers/media/tuners/r850_priv.h @@ -1,401 +1,407 @@ -#ifndef __R850_PRIV_H__ -#define __R850_PRIV_H__ - -#define R850_REG_NUM 48 //R0~R7: read only -#define R850_RING_POWER_FREQ 115000 -#define R850_IMR_IF 5300 -#define R850_IMR_TRIAL 9 -#define R850_IMR_GAIN_REG 20 -#define R850_IMR_PHASE_REG 21 -#define R850_IMR_IQCAP_REG 21 -#define R850_IMR_POINT_NUM 10 -#define R850_ADC_READ_COUNT 1 - -#define R850_PLL_LOCK_DELAY 10 -#define R850_FILTER_GAIN_DELAY 5 -#define R850_FILTER_CODE_DELAY 5 - - -enum R850_Standard_Type //Don't remove standand list!! -{ - //DTV - R850_DVB_T_6M = 0, - R850_DVB_T_7M, - R850_DVB_T_8M, - R850_DVB_T2_6M, //IF=4.57M - R850_DVB_T2_7M, //IF=4.57M - R850_DVB_T2_8M, //IF=4.57M - R850_DVB_T2_1_7M, - R850_DVB_T2_10M, - R850_DVB_C_8M, - R850_DVB_C_6M, - R850_J83B, - R850_ISDB_T_4063, //IF=4.063M - R850_ISDB_T_4570, //IF=4.57M - R850_DTMB_8M_4570, //IF=4.57M - R850_DTMB_6M_4500, //IF=4.5M, BW=6M - R850_ATSC, - //DTV IF=5M - R850_DVB_T_6M_IF_5M, - R850_DVB_T_7M_IF_5M, - R850_DVB_T_8M_IF_5M, - R850_DVB_T2_6M_IF_5M, - R850_DVB_T2_7M_IF_5M, - R850_DVB_T2_8M_IF_5M, - R850_DVB_T2_6M_IF_5M_NORMAL, - R850_DVB_T2_7M_IF_5M_NORMAL, - R850_DVB_T2_8M_IF_5M_NORMAL, - R850_DVB_T2_1_7M_IF_5M, - R850_DVB_C_8M_IF_5M, - R850_DVB_C_6M_IF_5M, - R850_J83B_IF_5M, - R850_ISDB_T_IF_5M, - R850_DTMB_8M_IF_5M, - R850_DTMB_6M_IF_5M, - R850_ATSC_IF_5M, - R850_FM, - R850_STD_SIZE, -}; - - -u8 R850_LPF_CAL_Array[3][R850_REG_NUM] = { //24M //16M //27MHz - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only - 0xC0, 0x49, 0x3F, 0x90, 0x13, 0xE1, 0x89, 0x7A, - 0x07, 0xF1, 0x9A, 0x50, 0x30, 0x20, 0xE1, 0x00, - 0x00, 0x04, 0x81, 0x11, 0xEF, 0xEE, 0x17, 0x07, - 0x31, 0x71, 0x54, 0xB2, 0xEE, 0xA9, 0xBB, 0x0B, - 0xA3, 0x00, 0x0B, 0x44, 0x92, 0x1F, 0xE6, 0x80 }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only - 0xC0, 0x49, 0x3F, 0x90, 0x13, 0xE1, 0x89, 0x7A, - 0x07, 0xF1, 0x9A, 0x50, 0x30, 0x20, 0xE1, 0x00, - 0x00, 0x04, 0x81, 0x1C, 0x66, 0x66, 0x16, 0x07, - 0x31, 0x71, 0x94, 0xBB, 0xEE, 0x89, 0xBB, 0x0B, - 0xA3, 0x00, 0x0B, 0x44, 0x92, 0x1F, 0xE6, 0x80 }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only - 0xC0, 0x49, 0x3F, 0x90, 0x13, 0xE1, 0x89, 0x7A, - 0x07, 0xF1, 0x9A, 0x50, 0x30, 0x20, 0xE1, 0x00, - 0x00, 0x04, 0x81, 0x11, 0xEF, 0xEE, 0x17, 0x07, - 0x31, 0x71, 0x54, 0xB0, 0xEE, 0xA9, 0xBB, 0x0B, - 0xA3, 0x00, 0x0B, 0x44, 0x92, 0x1F, 0xE6, 0x80 } -}; -//IMR Cal array 544MHz(24MHz) -u8 R850_IMR_CAL_Array[3][R850_REG_NUM] = { //24M //16M //27MHz - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only - 0xC0, 0x49, 0x3A, 0x90, 0x03, 0xC1, 0x61, 0x71, - 0x17, 0xF1, 0x18, 0x55, 0x30, 0x20, 0xF3, 0xED, - 0x1F, 0x1C, 0x81, 0x13, 0x00, 0x80, 0x0A, 0x07, - 0x21, 0x71, 0x54, 0xF1, 0xF2, 0xA9, 0xBB, 0x0B, - 0xA3, 0xF6, 0x0B, 0x44, 0x92, 0x17, 0xE6, 0x80 }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only - 0xC0, 0x49, 0x3A, 0x90, 0x03, 0xC1, 0x61, 0x71, - 0x17, 0xF1, 0x18, 0x55, 0x30, 0x20, 0xF3, 0xED, - 0x1F, 0x1C, 0x81, 0x13, 0x00, 0x80, 0x0A, 0x07, - 0x21, 0x71, 0x94, 0xF1, 0xF2, 0x89, 0xBB, 0x0B, - 0xA3, 0xF6, 0x0B, 0x44, 0x92, 0x17, 0xE6, 0x80 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only - 0xC0, 0x49, 0x3A, 0x90, 0x03, 0xC1, 0x61, 0x71, - 0x17, 0xF1, 0x18, 0x55, 0x30, 0x20, 0xF3, 0xED, - 0x1F, 0x1C, 0x81, 0x13, 0x00, 0x80, 0x0A, 0x07, - 0x21, 0x71, 0x54, 0xF1, 0xF2, 0xA9, 0xBB, 0x0B, - 0xA3, 0xF6, 0x0B, 0x44, 0x92, 0x17, 0xE6, 0x80 } - -}; - - u16 R850_Lna_Acc_Gain[4][32] = -{ - {0, 13, 24, 36, 49, 62, 76, 90, 105, 120, 135, 151, 163, 177, 191, 207, 222, 235, 249, 258, 267, 267, 267, 267, 267, 275, 286, 300, 316, 332, 329, 343}, - {0, 12, 23, 35, 48, 62, 77, 91, 107, 125, 142, 161, 171, 182, 194, 208, 220, 230, 242, 248, 255, 255, 255, 255, 255, 270, 285, 303, 320, 335, 321, 338}, - {0, 12, 24, 36, 50, 66, 81, 98, 117, 137, 158, 182, 192, 202, 213, 223, 232, 238, 244, 248, 251, 251, 251, 251, 251, 265, 280, 297, 312, 325, 318, 341}, - {0, 11, 23, 35, 49, 64, 80, 96, 114, 134, 153, 173, 184, 193, 202, 209, 215, 220, 222, 225, 227, 227, 227, 227, 227, 240, 254, 268, 281, 292, 307, 323}, -}; - - s8 Lna_Acc_Gain_offset[86]={6, 4, 4, 3, 3, 4, 3, 2, 2, 1, //45~145 - 0, -2, -3, -5, -6, -7, -10, -9, -9, -10, //145~245 - -9, -9, -8, -8, -6, -4, -3, -1, -1, 0, //245~345 - 8, 10, 10, 11, 11, 9, 10, 8, 4, 4, //345~445 - 1, 0, 0, -2, -2, -2, -2, -2, -1, -2, //445~545 - 0, 3, 2, 4, -2, 6, 6, 4, 3, 4, //545~645 - 2, 0, -2, -4, -5, -7, 10, 7, 6, 4, //645~745 - 3, 2, 1, 0, -1, -1, -2, -2, -1, -2, //745~845 - -1, -2, -2, -2, -2, -3}; - - u16 R850_Rf_Acc_Gain[16] = -{ - 0, 15, 31, 46, 58, 58, 58, 58, 58, 72, //0~9 - 86, 99, 113, 113, 124, 134 //10~15 -}; - - u16 R850_Mixer_Acc_Gain[16] = -{ - 0, 0, 0, 0, 10, 22, 34, 46, 58, 70, //0~9 - 82, 93, 102, 122, 142, 142 //10~12 -}; - - u8 R850_iniArray[3][R850_REG_NUM] = { - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //24M initial frequency = 775MHz (LO) - // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - // 0, 1, 2, 3, 4, 5, 6, 7 - 0xCA, 0xC0, 0x72, 0x50, 0x00, 0xE0, 0x00, 0x30, - // 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F - // 8, 9, 10, 11, 12, 13, 14, 15 - 0x86, 0xBB, 0xF8, 0xB0, 0xD2, 0x81, 0xCD, 0x46, - // 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 - // 16, 17, 18, 19, 20, 21, 22, 23 - 0x37, 0x40, 0x89, 0x8C, 0x55, 0x95, 0x07, 0x23, - // 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F - // 24, 25, 26, 27, 28, 29, 30, 31, - 0x21, 0xF1, 0x4C, 0x5F, 0xC4, 0x20, 0xA9, 0x6C, - // 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 - // 32, 33, 34, 35, 36, 37, 38, 39 - 0x53, 0xAB, 0x5B, 0x46, 0xB3, 0x93, 0x6E, 0x41 }, - // 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F - // 40, 41, 42, 43, 44, 45, 46, 47 - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //16M initial frequency = 775MHz (LO) - // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - // 0, 1, 2, 3, 4, 5, 6, 7 - 0xCA, 0xC0, 0x72, 0x50, 0x00, 0xE0, 0x01, 0x30, - // 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F - // 8, 9, 10, 11, 12, 13, 14, 15 - 0x06, 0xBB, 0xF8, 0xB0, 0xF0, 0x61, 0xCD, 0x14, - // 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 - // 16, 17, 18, 19, 20, 21, 22, 23 - 0x37, 0x42, 0x81, 0x92, 0x00, 0xE0, 0x07, 0x23, - // 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F - // 24, 25, 26, 27, 28, 29, 30, 31, - 0x21, 0xF1, 0x8C, 0x5F, 0xC4, 0x00, 0xA9, 0x6C, - // 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 - // 32, 33, 34, 35, 36, 37, 38, 39 - 0x31, 0xAB, 0x5A, 0x47, 0xB3, 0x93, 0xE9, 0x41 }, - // 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F - // 40, 41, 42, 43, 44, 45, 46, 47 - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //27M initial frequency = 780MHz (LO) - // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - // 0, 1, 2, 3, 4, 5, 6, 7 - 0xCA, 0xC0, 0x72, 0x50, 0x00, 0xE0, 0x00, 0x30, - // 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F - // 8, 9, 10, 11, 12, 13, 14, 15 - 0x86, 0xBB, 0xF8, 0xB0, 0xD2, 0x81, 0xCD, 0x46, - // 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 - // 16, 17, 18, 19, 20, 21, 22, 23 - 0x37, 0x40, 0x89, 0x8B, 0x4B, 0x68, 0x04, 0x23, - // 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F - // 24, 25, 26, 27, 28, 29, 30, 31, - 0x21, 0xF1, 0x4C, 0x5F, 0xC4, 0x20, 0xA9, 0x6C, - // 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 - // 32, 33, 34, 35, 36, 37, 38, 39 - 0x53, 0xAB, 0x5B, 0x46, 0xB3, 0x93, 0x6E, 0x41 } - // 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F - // 40, 41, 42, 43, 44, 45, 46, 47 -}; - u8 R850_Fil_Cal_BW_def[R850_STD_SIZE]={ - 3, 2, 2, 3, 2, 2, 2, 0, //{DVB_T_6M, DVB_T_7M, DVB_T_8M, DVB_T2_6M, DVB_T2_7M, DVB_T2_8M, DVB_T2_1_7M, DVB_T2_10M} - 0, 2, 2, 3, 2, 2, 3, 2, //{DVB_C_8M, DVB_C_6M, J83B, ISDB_T_4063, ISDB_T_4570, DTMB_8M_4570, DTMB_6M_4500, ATSC} - 2, 2, 0, 2, 2, 0, 3, //{DVB_T_6M, DVB_T_7M, DVB_T_8M, DVB_T2_6M, DVB_T2_7M, DVB_T2_8M, DVB_T2_1_7M, DVB_T2_10M} (IF 5M) - 0, 2, 2, 2, 0, 2, 2, 2 //{DVB_C_8M, DVB_C_6M, J83B, ISDB_T_4063, ISDB_T_4570, DTMB_8M_4570, DTMB_6M_4500, ATSC} (IF 5M), FM -}; - u8 R850_Fil_Cal_code_def[R850_STD_SIZE]={ - 3, 8, 2, 3, 8, 2, 8, 0, //{DVB_T_6M, DVB_T_7M, DVB_T_8M, DVB_T2_6M, DVB_T2_7M, DVB_T2_8M, DVB_T2_1_7M, DVB_T2_10M} - 8, 4, 7, 5, 16, 1, 5, 6, //{DVB_C_8M, DVB_C_6M, J83B, ISDB_T_4063, ISDB_T_4570, DTMB_8M_4570, DTMB_6M_4500, ATSC} - 13, 1, 13, 13, 1, 13, 23, //{DVB_T_6M, DVB_T_7M, DVB_T_8M, DVB_T2_6M, DVB_T2_7M, DVB_T2_8M, DVB_T2_1_7M, DVB_T2_10M} (IF 5M) - 11, 3, 11, 10, 11, 9, 8, 17 //{DVB_C_8M, DVB_C_6M, J83B, ISDB_T_4063, ISDB_T_4570, DTMB_8M_4570, DTMB_6M_4500, ATSC} (IF 5M), FM -}; - -typedef enum _R850_ErrCode -{ - R850_Success = TRUE, - R850_Fail = FALSE -}R850_ErrCode; - -enum R850_Cal_Type -{ - R850_IMR_CAL = 0, - R850_IMR_LNA_CAL, - R850_LPF_CAL, - R850_LPF_LNA_CAL -}; - - -struct R850_SectType -{ - u8 Phase_Y; - u8 Gain_X; - u8 Iqcap; - u8 Value; -}; - -enum R850_XTAL_PWR_VALUE -{ - R850_XTAL_LOWEST = 0, - R850_XTAL_LOW, - R850_XTAL_HIGH, - R850_XTAL_HIGHEST, - R850_XTAL_CHECK_SIZE -}; - -enum R850_Xtal_Div_TYPE -{ - R850_XTAL_DIV1 = 0, - R850_XTAL_DIV1_2, //1st_div2=0(R34[0]), 2nd_div2=1(R34[1]) ; same AGC clock - R850_XTAL_DIV2_1, //1st_div2=1(R34[0]), 2nd_div2=0(R34[1]) ; diff AGC clock - R850_XTAL_DIV4 -}; - -struct R850_Sys_Info_Type -{ - u8 BW; - u8 HPF_COR; - u8 FILT_EXT_ENA; - u8 HPF_NOTCH; - u8 AGC_CLK; - u8 IMG_GAIN; - u16 FILT_COMP; - u16 IF_KHz; - u16 FILT_CAL_IF; -}; - -struct R850_Freq_Info_Type -{ - u8 RF_POLY; - u8 LNA_BAND; - u8 LPF_CAP; - u8 LPF_NOTCH; - u8 TF_DIPLEXER; - u8 TF_HPF_BPF; - u8 TF_HPF_CNR; - u8 IMR_MEM_NOR; - u8 IMR_MEM_REV; - u8 TEMP; -}; - -struct R850_SysFreq_Info_Type -{ - u8 LNA_TOP; - u8 LNA_VTL_H; - u8 RF_TOP; - u8 RF_VTL_H; - u8 RF_GAIN_LIMIT; - u8 NRB_TOP; - u8 NRB_BW_HPF; - u8 NRB_BW_LPF; - u8 MIXER_TOP; - u8 MIXER_VTH; - u8 MIXER_VTL; - u8 MIXER_GAIN_LIMIT; - u8 FILTER_TOP; - u8 FILTER_VTH; - u8 FILTER_VTL; - u8 LNA_RF_DIS_MODE; - u8 LNA_RF_DIS_CURR; - u8 LNA_DIS_SLOW_FAST; - u8 RF_DIS_SLOW_FAST; - u8 BB_DET_MODE; - u8 BB_DIS_CURR; - u8 MIXER_FILTER_DIS; - u8 IMG_NRB_ADDER; - u8 LNA_NRB_DET; - u8 ENB_POLY_GAIN; - u8 MIXER_AMP_LPF; - u8 NA_PWR_DET; - u8 FILT_3TH_LPF_CUR; - u8 FILT_3TH_LPF_GAIN; - u8 RF_LTE_PSG; - u8 HPF_COMP; - u8 FB_RES_1ST; - u8 MIXER_DETBW_LPF; - u8 LNA_RF_CHARGE_CUR; -//NA - u8 DEGLITCH_CLK; - u8 NAT_HYS; - u8 NAT_CAIN; - u8 PULSE_HYS; - u8 FAST_DEGLITCH; - u8 PUL_RANGE_SEL; - u8 PUL_FLAG_RANGE; - u8 PULG_CNT_THRE; - u8 FORCE_PULSE; - u8 FLG_CNT_CLK; - u8 NATG_OFFSET; - - u8 TEMP; -}; - -struct R850_filer_cal{ - u8 flag; - u8 code; - u8 bw; - u8 lpflsb; - -}; -struct I2C_LEN_TYPE -{ - u8 RegAddr; - u8 Data[50]; - u8 Len; -}; -enum R850_LoopThrough_Type -{ - R850_LT_ON = TRUE, - R850_LT_OFF= FALSE -}; - -enum R850_ClkOutMode_Type -{ - R850_CLK_OUT_OFF = 0, - R850_CLK_OUT_ON -}; - -struct R850_Set_Info -{ - u32 RF_KHz; - enum R850_Standard_Type R850_Standard; - enum R850_LoopThrough_Type R850_LT; - enum R850_ClkOutMode_Type R850_ClkOutMode; -}; - -struct R850_RF_Gain_Info -{ - u16 RF_gain_comb; - u8 RF_gain1; - u8 RF_gain2; - u8 RF_gain3; - u8 RF_gain4; -}; - -struct r850_priv { - struct r850_config *cfg; - struct i2c_adapter *i2c; - u8 inited; - - - u8 regs[R850_REG_NUM]; - struct I2C_LEN_TYPE R850_I2C_Len ; - - struct R850_SectType imr_data[R850_IMR_POINT_NUM]; - u8 R850_IMR_Cal_Result; - u8 R850_IMR_done_flag; - - u8 R850_clock_out; - u8 R850_Xtal_cap; - u8 R850_Xtal_Pwr; - u8 R850_XtalDiv; - - /* tune settings */ - u32 freq; /* kHz */ - u32 R850_IF_GOLOBAL; - - struct R850_filer_cal fc; - - - struct R850_Sys_Info_Type R850_Sys_Info; - -}; - -#endif //__R850_PRIV_H__ +#ifndef __R850_PRIV_H__ +#define __R850_PRIV_H__ + +#define R850_REG_NUM 48 //R0~R7: read only +#define R850_RING_POWER_FREQ 115000 +#define R850_IMR_IF 5300 +#define R850_IMR_TRIAL 9 +#define R850_IMR_GAIN_REG 20 +#define R850_IMR_PHASE_REG 21 +#define R850_IMR_IQCAP_REG 21 +#define R850_IMR_POINT_NUM 10 +#define R850_ADC_READ_COUNT 1 + +#define R850_PLL_LOCK_DELAY 10 +#define R850_FILTER_GAIN_DELAY 5 +#define R850_FILTER_CODE_DELAY 5 + +#ifndef TRUE + #define TRUE 1 +#endif +#ifndef FALSE + #define FALSE 8 +#endif + +enum R850_Standard_Type //Don't remove standand list!! +{ + //DTV + R850_DVB_T_6M = 0, + R850_DVB_T_7M, + R850_DVB_T_8M, + R850_DVB_T2_6M, //IF=4.57M + R850_DVB_T2_7M, //IF=4.57M + R850_DVB_T2_8M, //IF=4.57M + R850_DVB_T2_1_7M, + R850_DVB_T2_10M, + R850_DVB_C_8M, + R850_DVB_C_6M, + R850_J83B, + R850_ISDB_T_4063, //IF=4.063M + R850_ISDB_T_4570, //IF=4.57M + R850_DTMB_8M_4570, //IF=4.57M + R850_DTMB_6M_4500, //IF=4.5M, BW=6M + R850_ATSC, + //DTV IF=5M + R850_DVB_T_6M_IF_5M, + R850_DVB_T_7M_IF_5M, + R850_DVB_T_8M_IF_5M, + R850_DVB_T2_6M_IF_5M, + R850_DVB_T2_7M_IF_5M, + R850_DVB_T2_8M_IF_5M, + R850_DVB_T2_6M_IF_5M_NORMAL, + R850_DVB_T2_7M_IF_5M_NORMAL, + R850_DVB_T2_8M_IF_5M_NORMAL, + R850_DVB_T2_1_7M_IF_5M, + R850_DVB_C_8M_IF_5M, + R850_DVB_C_6M_IF_5M, + R850_J83B_IF_5M, + R850_ISDB_T_IF_5M, + R850_DTMB_8M_IF_5M, + R850_DTMB_6M_IF_5M, + R850_ATSC_IF_5M, + R850_FM, + R850_STD_SIZE, +}; + + +u8 R850_LPF_CAL_Array[3][R850_REG_NUM] = { //24M //16M //27MHz + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only + 0xC0, 0x49, 0x3F, 0x90, 0x13, 0xE1, 0x89, 0x7A, + 0x07, 0xF1, 0x9A, 0x50, 0x30, 0x20, 0xE1, 0x00, + 0x00, 0x04, 0x81, 0x11, 0xEF, 0xEE, 0x17, 0x07, + 0x31, 0x71, 0x54, 0xB2, 0xEE, 0xA9, 0xBB, 0x0B, + 0xA3, 0x00, 0x0B, 0x44, 0x92, 0x1F, 0xE6, 0x80 }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only + 0xC0, 0x49, 0x3F, 0x90, 0x13, 0xE1, 0x89, 0x7A, + 0x07, 0xF1, 0x9A, 0x50, 0x30, 0x20, 0xE1, 0x00, + 0x00, 0x04, 0x81, 0x1C, 0x66, 0x66, 0x16, 0x07, + 0x31, 0x71, 0x94, 0xBB, 0xEE, 0x89, 0xBB, 0x0B, + 0xA3, 0x00, 0x0B, 0x44, 0x92, 0x1F, 0xE6, 0x80 }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only + 0xC0, 0x49, 0x3F, 0x90, 0x13, 0xE1, 0x89, 0x7A, + 0x07, 0xF1, 0x9A, 0x50, 0x30, 0x20, 0xE1, 0x00, + 0x00, 0x04, 0x81, 0x11, 0xEF, 0xEE, 0x17, 0x07, + 0x31, 0x71, 0x54, 0xB0, 0xEE, 0xA9, 0xBB, 0x0B, + 0xA3, 0x00, 0x0B, 0x44, 0x92, 0x1F, 0xE6, 0x80 } +}; +//IMR Cal array 544MHz(24MHz) +u8 R850_IMR_CAL_Array[3][R850_REG_NUM] = { //24M //16M //27MHz + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only + 0xC0, 0x49, 0x3A, 0x90, 0x03, 0xC1, 0x61, 0x71, + 0x17, 0xF1, 0x18, 0x55, 0x30, 0x20, 0xF3, 0xED, + 0x1F, 0x1C, 0x81, 0x13, 0x00, 0x80, 0x0A, 0x07, + 0x21, 0x71, 0x54, 0xF1, 0xF2, 0xA9, 0xBB, 0x0B, + 0xA3, 0xF6, 0x0B, 0x44, 0x92, 0x17, 0xE6, 0x80 }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only + 0xC0, 0x49, 0x3A, 0x90, 0x03, 0xC1, 0x61, 0x71, + 0x17, 0xF1, 0x18, 0x55, 0x30, 0x20, 0xF3, 0xED, + 0x1F, 0x1C, 0x81, 0x13, 0x00, 0x80, 0x0A, 0x07, + 0x21, 0x71, 0x94, 0xF1, 0xF2, 0x89, 0xBB, 0x0B, + 0xA3, 0xF6, 0x0B, 0x44, 0x92, 0x17, 0xE6, 0x80 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //read only + 0xC0, 0x49, 0x3A, 0x90, 0x03, 0xC1, 0x61, 0x71, + 0x17, 0xF1, 0x18, 0x55, 0x30, 0x20, 0xF3, 0xED, + 0x1F, 0x1C, 0x81, 0x13, 0x00, 0x80, 0x0A, 0x07, + 0x21, 0x71, 0x54, 0xF1, 0xF2, 0xA9, 0xBB, 0x0B, + 0xA3, 0xF6, 0x0B, 0x44, 0x92, 0x17, 0xE6, 0x80 } + +}; + + u16 R850_Lna_Acc_Gain[4][32] = +{ + {0, 13, 24, 36, 49, 62, 76, 90, 105, 120, 135, 151, 163, 177, 191, 207, 222, 235, 249, 258, 267, 267, 267, 267, 267, 275, 286, 300, 316, 332, 329, 343}, + {0, 12, 23, 35, 48, 62, 77, 91, 107, 125, 142, 161, 171, 182, 194, 208, 220, 230, 242, 248, 255, 255, 255, 255, 255, 270, 285, 303, 320, 335, 321, 338}, + {0, 12, 24, 36, 50, 66, 81, 98, 117, 137, 158, 182, 192, 202, 213, 223, 232, 238, 244, 248, 251, 251, 251, 251, 251, 265, 280, 297, 312, 325, 318, 341}, + {0, 11, 23, 35, 49, 64, 80, 96, 114, 134, 153, 173, 184, 193, 202, 209, 215, 220, 222, 225, 227, 227, 227, 227, 227, 240, 254, 268, 281, 292, 307, 323}, +}; + + s8 Lna_Acc_Gain_offset[86]={6, 4, 4, 3, 3, 4, 3, 2, 2, 1, //45~145 + 0, -2, -3, -5, -6, -7, -10, -9, -9, -10, //145~245 + -9, -9, -8, -8, -6, -4, -3, -1, -1, 0, //245~345 + 8, 10, 10, 11, 11, 9, 10, 8, 4, 4, //345~445 + 1, 0, 0, -2, -2, -2, -2, -2, -1, -2, //445~545 + 0, 3, 2, 4, -2, 6, 6, 4, 3, 4, //545~645 + 2, 0, -2, -4, -5, -7, 10, 7, 6, 4, //645~745 + 3, 2, 1, 0, -1, -1, -2, -2, -1, -2, //745~845 + -1, -2, -2, -2, -2, -3}; + + u16 R850_Rf_Acc_Gain[16] = +{ + 0, 15, 31, 46, 58, 58, 58, 58, 58, 72, //0~9 + 86, 99, 113, 113, 124, 134 //10~15 +}; + + u16 R850_Mixer_Acc_Gain[16] = +{ + 0, 0, 0, 0, 10, 22, 34, 46, 58, 70, //0~9 + 82, 93, 102, 122, 142, 142 //10~12 +}; + + u8 R850_iniArray[3][R850_REG_NUM] = { + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //24M initial frequency = 775MHz (LO) + // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + // 0, 1, 2, 3, 4, 5, 6, 7 + 0xCA, 0xC0, 0x72, 0x50, 0x00, 0xE0, 0x00, 0x30, + // 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F + // 8, 9, 10, 11, 12, 13, 14, 15 + 0x86, 0xBB, 0xF8, 0xB0, 0xD2, 0x81, 0xCD, 0x46, + // 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 + // 16, 17, 18, 19, 20, 21, 22, 23 + 0x37, 0x40, 0x89, 0x8C, 0x55, 0x95, 0x07, 0x23, + // 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F + // 24, 25, 26, 27, 28, 29, 30, 31, + 0x21, 0xF1, 0x4C, 0x5F, 0xC4, 0x20, 0xA9, 0x6C, + // 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 + // 32, 33, 34, 35, 36, 37, 38, 39 + 0x53, 0xAB, 0x5B, 0x46, 0xB3, 0x93, 0x6E, 0x41 }, + // 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F + // 40, 41, 42, 43, 44, 45, 46, 47 + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //16M initial frequency = 775MHz (LO) + // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + // 0, 1, 2, 3, 4, 5, 6, 7 + 0xCA, 0xC0, 0x72, 0x50, 0x00, 0xE0, 0x01, 0x30, + // 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F + // 8, 9, 10, 11, 12, 13, 14, 15 + 0x06, 0xBB, 0xF8, 0xB0, 0xF0, 0x61, 0xCD, 0x14, + // 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 + // 16, 17, 18, 19, 20, 21, 22, 23 + 0x37, 0x42, 0x81, 0x92, 0x00, 0xE0, 0x07, 0x23, + // 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F + // 24, 25, 26, 27, 28, 29, 30, 31, + 0x21, 0xF1, 0x8C, 0x5F, 0xC4, 0x00, 0xA9, 0x6C, + // 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 + // 32, 33, 34, 35, 36, 37, 38, 39 + 0x31, 0xAB, 0x5A, 0x47, 0xB3, 0x93, 0xE9, 0x41 }, + // 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F + // 40, 41, 42, 43, 44, 45, 46, 47 + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //27M initial frequency = 780MHz (LO) + // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 + // 0, 1, 2, 3, 4, 5, 6, 7 + 0xCA, 0xC0, 0x72, 0x50, 0x00, 0xE0, 0x00, 0x30, + // 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F + // 8, 9, 10, 11, 12, 13, 14, 15 + 0x86, 0xBB, 0xF8, 0xB0, 0xD2, 0x81, 0xCD, 0x46, + // 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 + // 16, 17, 18, 19, 20, 21, 22, 23 + 0x37, 0x40, 0x89, 0x8B, 0x4B, 0x68, 0x04, 0x23, + // 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F + // 24, 25, 26, 27, 28, 29, 30, 31, + 0x21, 0xF1, 0x4C, 0x5F, 0xC4, 0x20, 0xA9, 0x6C, + // 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 + // 32, 33, 34, 35, 36, 37, 38, 39 + 0x53, 0xAB, 0x5B, 0x46, 0xB3, 0x93, 0x6E, 0x41 } + // 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F + // 40, 41, 42, 43, 44, 45, 46, 47 +}; + u8 R850_Fil_Cal_BW_def[R850_STD_SIZE]={ + 3, 2, 2, 3, 2, 2, 2, 0, //{DVB_T_6M, DVB_T_7M, DVB_T_8M, DVB_T2_6M, DVB_T2_7M, DVB_T2_8M, DVB_T2_1_7M, DVB_T2_10M} + 0, 2, 2, 3, 2, 2, 3, 2, //{DVB_C_8M, DVB_C_6M, J83B, ISDB_T_4063, ISDB_T_4570, DTMB_8M_4570, DTMB_6M_4500, ATSC} + 2, 2, 0, 2, 2, 0, 3, //{DVB_T_6M, DVB_T_7M, DVB_T_8M, DVB_T2_6M, DVB_T2_7M, DVB_T2_8M, DVB_T2_1_7M, DVB_T2_10M} (IF 5M) + 0, 2, 2, 2, 0, 2, 2, 2 //{DVB_C_8M, DVB_C_6M, J83B, ISDB_T_4063, ISDB_T_4570, DTMB_8M_4570, DTMB_6M_4500, ATSC} (IF 5M), FM +}; + u8 R850_Fil_Cal_code_def[R850_STD_SIZE]={ + 3, 8, 2, 3, 8, 2, 8, 0, //{DVB_T_6M, DVB_T_7M, DVB_T_8M, DVB_T2_6M, DVB_T2_7M, DVB_T2_8M, DVB_T2_1_7M, DVB_T2_10M} + 8, 4, 7, 5, 16, 1, 5, 6, //{DVB_C_8M, DVB_C_6M, J83B, ISDB_T_4063, ISDB_T_4570, DTMB_8M_4570, DTMB_6M_4500, ATSC} + 13, 1, 13, 13, 1, 13, 23, //{DVB_T_6M, DVB_T_7M, DVB_T_8M, DVB_T2_6M, DVB_T2_7M, DVB_T2_8M, DVB_T2_1_7M, DVB_T2_10M} (IF 5M) + 11, 3, 11, 10, 11, 9, 8, 17 //{DVB_C_8M, DVB_C_6M, J83B, ISDB_T_4063, ISDB_T_4570, DTMB_8M_4570, DTMB_6M_4500, ATSC} (IF 5M), FM +}; + +typedef enum _R850_ErrCode +{ + R850_Success = TRUE, + R850_Fail = FALSE +}R850_ErrCode; + +enum R850_Cal_Type +{ + R850_IMR_CAL = 0, + R850_IMR_LNA_CAL, + R850_LPF_CAL, + R850_LPF_LNA_CAL +}; + + +struct R850_SectType +{ + u8 Phase_Y; + u8 Gain_X; + u8 Iqcap; + u8 Value; +}; + +enum R850_XTAL_PWR_VALUE +{ + R850_XTAL_LOWEST = 0, + R850_XTAL_LOW, + R850_XTAL_HIGH, + R850_XTAL_HIGHEST, + R850_XTAL_CHECK_SIZE +}; + +enum R850_Xtal_Div_TYPE +{ + R850_XTAL_DIV1 = 0, + R850_XTAL_DIV1_2, //1st_div2=0(R34[0]), 2nd_div2=1(R34[1]) ; same AGC clock + R850_XTAL_DIV2_1, //1st_div2=1(R34[0]), 2nd_div2=0(R34[1]) ; diff AGC clock + R850_XTAL_DIV4 +}; + +struct R850_Sys_Info_Type +{ + u8 BW; + u8 HPF_COR; + u8 FILT_EXT_ENA; + u8 HPF_NOTCH; + u8 AGC_CLK; + u8 IMG_GAIN; + u16 FILT_COMP; + u16 IF_KHz; + u16 FILT_CAL_IF; +}; + +struct R850_Freq_Info_Type +{ + u8 RF_POLY; + u8 LNA_BAND; + u8 LPF_CAP; + u8 LPF_NOTCH; + u8 TF_DIPLEXER; + u8 TF_HPF_BPF; + u8 TF_HPF_CNR; + u8 IMR_MEM_NOR; + u8 IMR_MEM_REV; + u8 TEMP; +}; + +struct R850_SysFreq_Info_Type +{ + u8 LNA_TOP; + u8 LNA_VTL_H; + u8 RF_TOP; + u8 RF_VTL_H; + u8 RF_GAIN_LIMIT; + u8 NRB_TOP; + u8 NRB_BW_HPF; + u8 NRB_BW_LPF; + u8 MIXER_TOP; + u8 MIXER_VTH; + u8 MIXER_VTL; + u8 MIXER_GAIN_LIMIT; + u8 FILTER_TOP; + u8 FILTER_VTH; + u8 FILTER_VTL; + u8 LNA_RF_DIS_MODE; + u8 LNA_RF_DIS_CURR; + u8 LNA_DIS_SLOW_FAST; + u8 RF_DIS_SLOW_FAST; + u8 BB_DET_MODE; + u8 BB_DIS_CURR; + u8 MIXER_FILTER_DIS; + u8 IMG_NRB_ADDER; + u8 LNA_NRB_DET; + u8 ENB_POLY_GAIN; + u8 MIXER_AMP_LPF; + u8 NA_PWR_DET; + u8 FILT_3TH_LPF_CUR; + u8 FILT_3TH_LPF_GAIN; + u8 RF_LTE_PSG; + u8 HPF_COMP; + u8 FB_RES_1ST; + u8 MIXER_DETBW_LPF; + u8 LNA_RF_CHARGE_CUR; +//NA + u8 DEGLITCH_CLK; + u8 NAT_HYS; + u8 NAT_CAIN; + u8 PULSE_HYS; + u8 FAST_DEGLITCH; + u8 PUL_RANGE_SEL; + u8 PUL_FLAG_RANGE; + u8 PULG_CNT_THRE; + u8 FORCE_PULSE; + u8 FLG_CNT_CLK; + u8 NATG_OFFSET; + + u8 TEMP; +}; + +struct R850_filer_cal{ + u8 flag; + u8 code; + u8 bw; + u8 lpflsb; + +}; +struct I2C_LEN_TYPE +{ + u8 RegAddr; + u8 Data[50]; + u8 Len; +}; +enum R850_LoopThrough_Type +{ + R850_LT_ON = TRUE, + R850_LT_OFF= FALSE +}; + +enum R850_ClkOutMode_Type +{ + R850_CLK_OUT_OFF = 0, + R850_CLK_OUT_ON +}; + +struct R850_Set_Info +{ + u32 RF_KHz; + enum R850_Standard_Type R850_Standard; + enum R850_LoopThrough_Type R850_LT; + enum R850_ClkOutMode_Type R850_ClkOutMode; +}; + +struct R850_RF_Gain_Info +{ + u16 RF_gain_comb; + u8 RF_gain1; + u8 RF_gain2; + u8 RF_gain3; + u8 RF_gain4; +}; + +struct r850_priv { + struct r850_config *cfg; + struct i2c_adapter *i2c; + u8 inited; + + + u8 regs[R850_REG_NUM]; + struct I2C_LEN_TYPE R850_I2C_Len ; + + struct R850_SectType imr_data[R850_IMR_POINT_NUM]; + u8 R850_IMR_Cal_Result; + u8 R850_IMR_done_flag; + + u8 R850_clock_out; + u8 R850_Xtal_cap; + u8 R850_Xtal_Pwr; + u8 R850_XtalDiv; + + /* tune settings */ + u32 freq; /* kHz */ + u32 R850_IF_GOLOBAL; + + struct R850_filer_cal fc; + + + struct R850_Sys_Info_Type R850_Sys_Info; + +}; + +#endif //__R850_PRIV_H__