/***********************************************************************
*  TX desense with WIFI/BT
*
***********************************************************************/
int MT6620_TX_DESENSE(uint16_t freq, int *ctr)
{
    int ret = 0;
    uint16_t dataRead = 0;
    uint16_t tmp = 0;
    
    FM_LOG_DBG(D_MAIN,"+%s, [freq=%d]\n", __func__, (int)freq);
    FM_COM_ASSERT(op_cb->read);
    FM_COM_ASSERT(op_cb->write);
    FM_COM_ASSERT(op_cb->setbits);

    // enable FM TX VCO tracking
    if((ret = op_cb->read(0x29, &dataRead)))//read 29 
        goto out;
    FM_LOG_NTC(D_MAIN,"Before VCO On, [0x29=0x%04x]\n", dataRead);
    if((ret = op_cb->read(0x12, &dataRead)))//read 12 
        goto out;
    FM_LOG_NTC(D_MAIN,"Before VCO On, [0x12=0x%04x]\n", dataRead);
    
    if((ret = op_cb->setbits(0x12, 0, MASK(15))))//set 12 D15=0
        goto out;
    if((ret = op_cb->setbits(0x41, BITn(0), MASK(0))))//set 41 D0=1
        goto out;
    if((ret = op_cb->setbits(0x48, BITn(15), MASK(15))))//set 48 D15=1
        goto out;

    // wait 100ms (VCO tracking 100ms)
    if(*ctr > FM_TX_TRACKING_TIME_MAX){
        *ctr = FM_TX_TRACKING_TIME_MAX;
    }
    Delayms(*ctr);

    // disable FM TX VCO tracking
    if((ret = op_cb->setbits(0x28, BITn(2), MASK(2))))//set 28 D2=1
        goto out;
    if((ret = op_cb->read(0x29, &dataRead)))//read 29 D11~D0
        goto out;
    FM_LOG_NTC(D_MAIN,"Before VCO Off, [0x29=0x%04x]\n", dataRead);
    tmp = dataRead&0x0FFF; // Read 0x29 D11~D0
    if((ret = op_cb->read(0x12, &dataRead)))//read 12 
        goto out;
    //Set 0x12 D15 to 1, D11:D0 to read(0x29 D11~D0)
    dataRead &= 0xF000; 
    dataRead |= tmp;
    dataRead |= 1<<15;
    if((ret = op_cb->write(0x12, dataRead)))
        goto out;
    FM_LOG_NTC(D_MAIN,"Before VCO Off, [0x12=0x%04x]\n", dataRead);
    if((ret = op_cb->setbits(0x48, 0, MASK(15))))//set 48 D15=0
        goto out;
    if((ret = op_cb->setbits(0x41, 0, MASK(0))))//set 41 D0=0
        goto out;
    
out:
    FM_LOG_DBG(D_MAIN,"-%s, [freq=%d][delay=%dms][ret=%d]\n", __func__, (int)freq, *ctr, ret);
    return ret;
}
/***********************************************************************
*  TX PWR CTRL
*
***********************************************************************/
int MT6620_TX_PWR_CTRL(uint16_t freq, int *ctr)
{
    #define MT6620_TX_PWR_LEV_MAX 120
    #define MT6620_TX_PWR_LEV_MIN 85
    int ret = 0;
    int tmp = 0;
    uint16_t reg = 0;
    uint16_t coarse;
    uint16_t fine;
    
    FM_LOG_DBG(D_MAIN,"+%s, [freq=%d]\n", __func__, (int)freq);
    FM_COM_ASSERT(op_cb->read);
    FM_COM_ASSERT(op_cb->write);
    FM_COM_ASSERT(ctr);

    if(freq < FM_TX_PWR_CTRL_FREQ_THR){
        //Power setting - 1dB, 3C(HEX)=A9E9
        *ctr -= 1;
    }else{
        //Power setting -2 dB, 3C(HEX)=A8E9
        *ctr -= 2;
    }
    
    if(*ctr > MT6620_TX_PWR_LEV_MAX){
        *ctr = MT6620_TX_PWR_LEV_MAX;
    }else if(*ctr < MT6620_TX_PWR_LEV_MIN){
        *ctr = MT6620_TX_PWR_LEV_MIN;
    }
    fine = 43017 + ((1<<((*ctr-85)%6))-1)*32;
    FM_LOG_DBG(D_MAIN,"0x3C = 0x%04x \n", fine);
    coarse = 514 + ((1<<((*ctr-85)/6))-1)*4;
    FM_LOG_DBG(D_MAIN,"0x3D = 0x%04x \n", coarse);
    
    if((ret = op_cb->write(0x3C, fine)))
            goto out;
    if((ret = op_cb->write(0x3D, coarse)))
            goto out;

    tmp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ);
    if((ret = op_cb->read(0x9C, &reg)))
        goto out;
    reg &= 0xC0FF;
    if(tmp < FM_TX_PWR_CTRL_TMP_THR_DOWN){
        reg |= (0x1C << 8);  //9CH, D13~D8 = 1C
    }else if(tmp > FM_TX_PWR_CTRL_TMP_THR_UP){
        reg |= (0x33 << 8);  //9CH, D13~D8 ==33
    }else{
        reg |= (0x25 << 8);  //9CH, D13~D8 =25
    }
    if((ret = op_cb->write(0x9C, reg)))
        goto out;

out:
    FM_LOG_NTC(D_MAIN,"-%s, [temp=%d][ret=%d]\n", __func__, (int)tmp, ret);
    return ret;
}
//fm lock methods
static fm_s32 fm_lock_try(struct fm_lock *thiz,fm_s32 retryCnt)
{
    fm_s32 retry_cnt = 0;
    struct semaphore *sem;
    struct task_struct *task = current;
    FMR_ASSERT(thiz);
    FMR_ASSERT(thiz->priv);

    while(down_trylock((struct semaphore*)thiz->priv))
    {
        WCN_DBG(FM_WAR | MAIN, "down_trylock failed\n");
        if(++retry_cnt < retryCnt)
        {
            WCN_DBG(FM_WAR | MAIN,"[retryCnt=%d]\n", retry_cnt);
            msleep_interruptible(50); 
            continue;
        }
        else
        {
            WCN_DBG(FM_CRT | MAIN,"down_trylock retry failed\n");
			return -FM_ELOCK;
        }    
    }

    sem = (struct semaphore*)thiz->priv;
    FM_LOG_DBG(MAIN, "%s --->trylock, cnt=%d, pid=%d\n", thiz->name, (int)sem->count, task->pid);
    return 0;
}
Exemple #4
0
static fm_s32 fm_spin_lock_unlock(struct fm_lock *thiz)
{
	struct task_struct *task = current;
	FMR_ASSERT(thiz);
	FMR_ASSERT(thiz->priv);

	FM_LOG_DBG(MAIN, "%s <---unlock, pid=%d\n", thiz->name, task->pid);
	spin_unlock_bh((spinlock_t *) thiz->priv);
	return 0;
}
Exemple #5
0
static fm_s32 fm_lock_unlock(struct fm_lock *thiz)
{
	struct semaphore *sem;
	struct task_struct *task = current;
	FMR_ASSERT(thiz);
	FMR_ASSERT(thiz->priv);
	sem = (struct semaphore *)thiz->priv;
	FM_LOG_DBG(MAIN, "%s <---unlock, cnt=%d, pid=%d\n", thiz->name, (int)sem->count + 1, task->pid);
	up((struct semaphore *)thiz->priv);
	return 0;
}
Exemple #6
0
/* fm try lock methods */
static fm_s32 fm_lock_lock(struct fm_lock *thiz)
{
	struct semaphore *sem;
	struct task_struct *task = current;
	FMR_ASSERT(thiz);
	FMR_ASSERT(thiz->priv);

	if (down_interruptible((struct semaphore *)thiz->priv)) {
		WCN_DBG(FM_CRT | MAIN, "get mutex failed\n");
		return -FM_ELOCK;
	}

	sem = (struct semaphore *)thiz->priv;
	FM_LOG_DBG(MAIN, "%s --->lock, cnt=%d, pid=%d\n", thiz->name, (int)sem->count, task->pid);
	return 0;
}
/***********************************************************************
*  Frequency Avoidance
*
***********************************************************************/
int MT6620_MCU_Freq_Avoid(uint16_t freq, int *freqavoid)
{
    int ret = 0;
    int mcuDsense = FM_MCU_DESENSE_DISABLE;
    uint16_t len = 0;
    uint16_t indx = 0;
    static uint16_t FreqList[] ={780, 794, 832, 926, 960, 1040};

    FM_LOG_DBG(D_MAIN,"+%s, [freq=%d]\n", __func__, (int)freq);
    FM_COM_ASSERT(op_cb->read);
    FM_COM_ASSERT(op_cb->write);

    *freqavoid = 0;
    
    len = sizeof(FreqList)/sizeof(FreqList[0]);
    indx = 0;
    while((indx < len) && (mcuDsense != FM_MCU_DESENSE_ENABLE)){
        if(FreqList[indx] == freq){
            mcuDsense = FM_MCU_DESENSE_ENABLE;
            *freqavoid = 1;
        }
        indx++;
    }

	if(mcuDsense == FM_MCU_DESENSE_DISABLE){
		if(mtk_wcn_wmt_dsns_ctrl(WMTDSNS_FM_DISABLE)){
			ret = 0;
		}else{
			ret = -ERR_STP;
		}
	}else if(mcuDsense == FM_MCU_DESENSE_ENABLE){
		if(mtk_wcn_wmt_dsns_ctrl(WMTDSNS_FM_ENABLE)){
			ret = 0;
		}else{
			ret = -ERR_STP;
		}
	}else{
		FM_LOG_ERR(D_MAIN,"para error!\n");
		ret = -ERR_INVALID_PARA;
	}
    
    FM_LOG_NTC(D_MAIN,"-%s, [mcuDsense=%d][ret=%d]\n", __func__, (int)mcuDsense, ret);
    return ret;
}
/***********************************************************************
*  Hi-Lo Side Injection
*
***********************************************************************/
int MT6620_HL_Side_Adj(uint16_t freq, int *hl)
{
    int ret = 0;
    int isHiSide= 0;
    int tblsize = 0;
    int indx = 0;
    uint16_t tmp;
    static uint16_t Hi_Channels[] = {795, 807, 821, 1064};

    FM_LOG_DBG(D_INIT,"+%s, [freq=%d]\n", __func__, (int)freq);
    FM_COM_ASSERT(op_cb->read);
    FM_COM_ASSERT(op_cb->write);
    
    *hl = 0;
    
    if(sizeof(Hi_Channels) == 0)
        goto out;
    
    tblsize = sizeof(Hi_Channels)/sizeof(Hi_Channels[0]);
    for(indx = 0; indx < tblsize; indx++){
        if(Hi_Channels[indx] == freq){
            isHiSide = 1;
            *hl = 1;
            goto set_HL;
        }     
    }
    
set_HL:
    if(isHiSide){
  	    //Set high-side injection (AFC)
  	    if((ret = op_cb->read(0x0F, &tmp)))
            goto out;
  	    if((ret = op_cb->write(0x0F, tmp |0x0400)))
            goto out;
  	    if((ret = op_cb->write(FM_MAIN_PGSEL, 0)))
            goto out;
  	    //Set high-side injection (DFE)
  	    if((ret = op_cb->read(0xCB, &tmp)))
            goto out;
  	    if((ret = op_cb->write(0xCB, tmp | 0x01)))
            goto out;
  	    //op_cb->write(0xCB, dataRead&0xFFFE);
    }else{
        //Set low-side injection (AFC)
        if((ret = op_cb->read(0x0F, &tmp)))
            goto out;
  	    if((ret = op_cb->write(0x0F, tmp&0xFBFF)))
            goto out;
  	    if((ret = op_cb->write(FM_MAIN_PGSEL, 0)))
            goto out;
  	    //Set low-side injection (DFE)
  	    if((ret = op_cb->read(0xCB, &tmp)))
            goto out;
  	    //op_cb->write(0xCB, dataRead | 0x01);
        if((ret = op_cb->write(0xCB, tmp&0xFFFE)))
            goto out;
    }
 out:   
    FM_LOG_NTC(D_INIT,"-%s, [isHiSide=%d][ret=%d]\n", __func__, (int)isHiSide, ret);
    return ret;
}
/***********************************************************************
*  TX RTC PWR CTRL
*
***********************************************************************/
int MT6620_RTC_Drift_CTRL(uint16_t freq, int *ctr)
{
    int ret = 0;
    uint16_t reg = 0;
    int chanel_resolution = 1;
    int16_t compensation_int16 = 0;
    int tmp = 0;
    int drift = *ctr;
    
    FM_LOG_DBG(D_MAIN,"+%s, [freq=%d]\n", __func__, (int)freq);
    FM_COM_ASSERT(op_cb->read);
    FM_COM_ASSERT(op_cb->write);
    FM_COM_ASSERT(op_cb->setbits);
    FM_COM_ASSERT(ctr);

    //turn off VCO tracking
    if((ret = op_cb->setbits(0x48, 0, MASK(15))))//set 48 D15=0
        goto out;
    
    //get channel resolution
    if((ret = op_cb->read(0x46, &reg)))
        goto out;
    reg &= 0xC000;
    switch(reg >> 14){
        case 0:
            chanel_resolution = 1024;
            break;
        case 1:
            chanel_resolution = 512;
            break;
        case 2:
            chanel_resolution = 256;
            break;
        case 3:
            chanel_resolution = 128;
            break;
        default:
            FM_LOG_ERR(D_MAIN,"chanel_resolution error[%d]\n", (int)(reg >> 14));
            break;
    }

    //caculate and applye compensation
    FM_LOG_DBG(D_MAIN,"[resolution=%d][freq=%d][drift=%d]\n", chanel_resolution, (int)(freq/10), (*ctr));
    tmp = (2*drift*(freq/10))/chanel_resolution;
    compensation_int16 = (int16_t)tmp;
    if(compensation_int16 >= 511){
        compensation_int16 = 511;
    }else if(compensation_int16 <= -512){
        compensation_int16 = -512;
    }
    if((ret = op_cb->read(0x47, &reg)))
        goto out;
    reg &= 0x003F;
    reg |= (compensation_int16 << 6);
    if((ret = op_cb->write(0x47, reg)))
        goto out;

    /*
    //turn on VCO tracking
    if((ret = op_cb->setbits(0x48, BITn(15), MASK(15))))//set 48 D15=1
        goto out;
        */
out:
    FM_LOG_NTC(D_MAIN,"-%s, [compensation=%d][ret=%d]\n", __func__, (int)(compensation_int16), ret);
    return ret;
}
Exemple #10
0
/***********************************************************************
*  Frequency Avoidance
*
***********************************************************************/
int MT6620_ADPLL_Freq_Avoid(uint16_t freq, int *freqavoid)
{
    int ret = 0;
    int ADPLL_clk = FM_ADPLL_15M;
    uint16_t dataRead = 0;
    uint16_t indx = 0;
    static uint16_t Avoid_Channels[] ={ 
        767, 768, 769, 770, 806, 807, 808, 844, 845, 846, 872, 883, 884, 920,
        921, 922, 923, 936, 949, 960, 961, 998, 999, 1000, 1013, 1036, 1037, 1038, 1074,
        1075, 1076, 1077};

    FM_LOG_DBG(D_MAIN,"+%s, [freq=%d]\n", __func__, (int)freq);
    FM_COM_ASSERT(op_cb->read);
    FM_COM_ASSERT(op_cb->write);

    *freqavoid = 0;
    
    dataRead = sizeof(Avoid_Channels)/sizeof(Avoid_Channels[0]);
    indx = 0;
    while((indx < dataRead) && (ADPLL_clk != FM_ADPLL_16M)){
        if(Avoid_Channels[indx] == freq){
            ADPLL_clk = FM_ADPLL_16M;
            *freqavoid = 1;
        }
        indx++;
    }
    //isADPLL_16M = 1;
    if((ret = op_cb->read(0x1E, &dataRead)))
        goto out;
    if(((dataRead&BITn(9))&&(ADPLL_clk == FM_ADPLL_16M))||(!(dataRead&BITn(9))&&(ADPLL_clk == FM_ADPLL_15M)))//1EH, D9
        goto out; //we need not do freq avoid at these caes

    if(ADPLL_clk == FM_ADPLL_16M){       
        //Set rgf_f16mode_en = X	
      	if((ret = op_cb->setbits(0x61, BITn(0), MASK(0))))//set 61H D0=1, 16.384MHZ
                goto out;
    }else if(ADPLL_clk == FM_ADPLL_15M){
        //Set rgf_f16mode_en = X  		
      	if((ret = op_cb->setbits(0x61, 0, MASK(0))))//set 61H D0=0, 15.36MHZ
                goto out;
    }else{
        ret = -ERR_INVALID_PARA;
        goto out;
    } 
    
    // Disable ADPLL
    ret = MT6620_ADPLL_Power_OnOff(FM_ADPLL_OFF, ADPLL_clk);
    if(ret){
        FM_LOG_NTC(D_MAIN,"%s, ADPLL OFF failed, [ret=%d]n", __func__, ret);
        goto out;
    }
    
    //Set FMCR_DCO_CK_SEL = ? (default = 0, 15.36)
    if(ADPLL_clk == FM_ADPLL_16M){		
        if((ret = op_cb->setbits(0x1E, BITn(9), MASK(9))))//set 1EH D9=1, 16.384MHZ
                goto out;
    }else if(ADPLL_clk == FM_ADPLL_15M){
        if((ret = op_cb->setbits(0x1E, 0, MASK(9))))//set 1EH D9=0, 15.36MHZ
                goto out;
    }else{
        ret = -ERR_INVALID_PARA;
        goto out;
    }
    
    // Ensable ADPLL
    ret = MT6620_ADPLL_Power_OnOff(FM_ADPLL_ON, ADPLL_clk);
    if(ret){
        FM_LOG_NTC(D_MAIN,"%s, ADPLL ON failed, [ret=%d]\n", __func__, ret);
        goto out;
    }
    //Set rgfrf_cnt_resync_b = 0
    if((ret = op_cb->setbits(0x2A, 0, MASK(1))))//set 2AH D1=0
        goto out;
    //Set rgfrf_cnt_resync_b = 1
    if((ret = op_cb->setbits(0x2A, BITn(1), MASK(1))))//set 2AH D1=1
        goto out; 
out:
    FM_LOG_NTC(D_MAIN,"-%s, [ADPLL_clk=%d][ret=%d]\n", __func__, (int)ADPLL_clk, ret);
    return ret;
}