/*********************************************************************** * 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, ®))) 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; }
static INT32 wmt_dev_tm_temp_query(void) { #define HISTORY_NUM 5 #define TEMP_THRESHOLD 65 #define REFRESH_TIME 300 //sec static INT32 temp_table[HISTORY_NUM] = {99}; //not query yet. static INT32 idx_temp_table = 0; static struct timeval query_time, now_time; INT8 query_cond = 0; INT32 current_temp = 0; INT32 index = 0; //Query condition 1: // If we have the high temperature records on the past, we continue to query/monitor // the real temperature until cooling for(index = 0; index < HISTORY_NUM ; index++) { if(temp_table[index] >= TEMP_THRESHOLD) { query_cond = 1; WMT_INFO_FUNC("high temperature (current temp = %d), we must keep querying temp temperature..\n", temp_table[index]); } } do_gettimeofday(&now_time); // Query condition 2: // Moniter the hif_sdio activity to decide if we have the need to query temperature. if(!query_cond) { if( wmt_dev_tra_sdio_poll()==0) { query_cond = 1; WMT_INFO_FUNC("sdio traffic , we must query temperature..\n"); } else { WMT_DBG_FUNC("sdio idle traffic ....\n"); } //only WIFI tx power might make temperature varies largely #if 0 if(!query_cond) { last_access_time = wmt_dev_tra_uart_poll(); if( jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { query_cond = 1; WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n"); } else { WMT_DBG_FUNC("uart still idle traffic , we don't query temp temperature..\n"); } } #endif } // Query condition 3: // If the query time exceeds the a certain of period, refresh temp table. // if(!query_cond) { if( (now_time.tv_sec < query_time.tv_sec) || //time overflow, we refresh temp table again for simplicity! ((now_time.tv_sec > query_time.tv_sec) && (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) { query_cond = 1; WMT_INFO_FUNC("It is long time (> %d sec) not to query, we must query temp temperature..\n", REFRESH_TIME); for (index = 0; index < HISTORY_NUM ; index++) { temp_table[index] = 99; } } } if(query_cond) { // update the temperature record mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE); current_temp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ); mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE); wmt_lib_notify_stp_sleep(); idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; temp_table[idx_temp_table] = current_temp; do_gettimeofday(&query_time); WMT_INFO_FUNC("[Thermal] current_temp = 0x%x \n", (current_temp & 0xFF)); } else { current_temp = temp_table[idx_temp_table]; idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; temp_table[idx_temp_table] = current_temp; } // // Dump information // WMT_DBG_FUNC("[Thermal] idx_temp_table = %d \n", idx_temp_table); WMT_DBG_FUNC("[Thermal] now.time = %d, query.time = %d, REFRESH_TIME = %d\n", now_time.tv_sec, query_time.tv_sec, REFRESH_TIME); WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d \n----\n", temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]); return current_temp; }
INT32 wmt_dev_tm_temp_query(VOID) { #define HISTORY_NUM 5 #define TEMP_THRESHOLD 65 #define REFRESH_TIME 300 /* sec */ static INT32 temp_table[HISTORY_NUM] = { 99 }; /* not query yet. */ static INT32 idx_temp_table; static struct timeval query_time, now_time; INT8 query_cond = 0; INT8 ctemp = 0; INT32 current_temp = 0; INT32 index = 0; MTK_WCN_BOOL bRet = MTK_WCN_BOOL_FALSE; /* Query condition 1: */ /* If we have the high temperature records on the past, we continue to query/monitor */ /* the real temperature until cooling */ for (index = 0; index < HISTORY_NUM; index++) { if (temp_table[index] >= TEMP_THRESHOLD) { query_cond = 1; WMT_INFO_FUNC ("high temperature (current temp = %d), we must keep querying temp temperature..\n", temp_table[index]); } } do_gettimeofday(&now_time); #if 1 /* Query condition 2: */ /* Moniter the hif_sdio activity to decide if we have the need to query temperature. */ if (!query_cond) { if (wmt_dev_tra_sdio_poll() == 0) { query_cond = 1; WMT_DBG_FUNC("sdio traffic , we must query temperature..\n"); } else { WMT_DBG_FUNC("sdio idle traffic ....\n"); } /* only WIFI tx power might make temperature varies largely */ #if 0 if (!query_cond) { last_access_time = wmt_dev_tra_uart_poll(); if (jiffies_to_msecs(last_access_time) < TIME_THRESHOLD_TO_TEMP_QUERY) { query_cond = 1; WMT_DBG_FUNC("uart busy traffic , we must query temperature..\n"); } else { WMT_DBG_FUNC ("uart still idle traffic , we don't query temp temperature..\n"); } } #endif } #endif /* Query condition 3: */ /* If the query time exceeds the a certain of period, refresh temp table. */ /* */ if (!query_cond) { if ((now_time.tv_sec < query_time.tv_sec) || /* time overflow, we refresh temp table again for simplicity! */ ((now_time.tv_sec > query_time.tv_sec) && (now_time.tv_sec - query_time.tv_sec) > REFRESH_TIME)) { query_cond = 1; WMT_INFO_FUNC ("It is long time (> %d sec) not to query, we must query temp temperature..\n", REFRESH_TIME); for (index = 0; index < HISTORY_NUM; index++) { temp_table[index] = 99; } } } if (query_cond) { /* update the temperature record */ bRet = mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE); if (bRet == MTK_WCN_BOOL_TRUE) { ctemp = mtk_wcn_wmt_therm_ctrl(WMTTHERM_READ); bRet = mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE); if(bRet == MTK_WCN_BOOL_TRUE) wmt_lib_notify_stp_sleep(); if (0 != (ctemp & 0x80)) { ctemp &= 0x7f; current_temp = ~((INT32)ctemp - 1); } else current_temp = ctemp; } else { current_temp = -1; if (MTK_WCN_BOOL_TRUE == wmt_lib_is_therm_ctrl_support()) WMT_WARN_FUNC("thermal function enable command failed, set current_temp = 0x%x \n", current_temp); } idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; temp_table[idx_temp_table] = current_temp; do_gettimeofday(&query_time); WMT_DBG_FUNC("[Thermal] current_temp = 0x%x \n", current_temp); } else { current_temp = temp_table[idx_temp_table]; idx_temp_table = (idx_temp_table + 1) % HISTORY_NUM; temp_table[idx_temp_table] = current_temp; } /* */ /* Dump information */ /* */ WMT_DBG_FUNC("[Thermal] idx_temp_table = %d\n", idx_temp_table); WMT_DBG_FUNC("[Thermal] now.time = %ld, query.time = %ld, REFRESH_TIME = %d\n", now_time.tv_sec, query_time.tv_sec, REFRESH_TIME); WMT_DBG_FUNC("[0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d\n----\n", temp_table[0], temp_table[1], temp_table[2], temp_table[3], temp_table[4]); return current_temp; }