Esempio n. 1
0
INT8 mtk_wcn_wmt_therm_ctrl(ENUM_WMTTHERM_TYPE_T eType)
#endif
{
	P_OSAL_OP pOp;
	P_WMT_OP pOpData;
	MTK_WCN_BOOL bRet;
	P_OSAL_SIGNAL pSignal;

	/*parameter validation check */
	if (WMTTHERM_MAX < eType || WMTTHERM_ENABLE > eType) {
		WMT_ERR_FUNC("invalid thermal control command (%d)\n", eType);
		return MTK_WCN_BOOL_FALSE;
	}

	/*check if chip support thermal control function or not */
	bRet = wmt_lib_is_therm_ctrl_support();
	if (MTK_WCN_BOOL_FALSE == bRet) {
        WMT_DBG_FUNC("thermal ctrl function not supported\n");
		return MTK_WCN_BOOL_FALSE;
	}

	pOp = wmt_lib_get_free_op();
	if (!pOp) {
		WMT_DBG_FUNC("get_free_lxop fail\n");
		return MTK_WCN_BOOL_FALSE;
	}

	pSignal = &pOp->signal;
	pOpData = &pOp->op;
	pOpData->opId = WMT_OPID_THERM_CTRL;
	/*parameter fill */
	pOpData->au4OpData[0] = eType;
	pSignal->timeoutValue = MAX_EACH_WMT_CMD;

    WMT_DBG_FUNC("OPID(%d) type(%d) start\n",
            pOp->op.opId,
            pOp->op.au4OpData[0]);

	if (DISABLE_PSM_MONITOR()) {
		WMT_ERR_FUNC("wake up failed\n");
		wmt_lib_put_op_to_free_queue(pOp);
		return -1;
	}

	bRet = wmt_lib_put_act_op(pOp);
	ENABLE_PSM_MONITOR();

	if (MTK_WCN_BOOL_FALSE == bRet) {
		WMT_WARN_FUNC("OPID(%d) type(%d) fail\n\n", pOpData->opId, pOpData->au4OpData[0]);
		/*0xFF means read error occurs */
		pOpData->au4OpData[1] = (eType == WMTTHERM_READ) ? 0xFF : MTK_WCN_BOOL_FALSE;	/*will return to function driver */
	} else {
		WMT_DBG_FUNC("OPID(%d) type(%d) return(%d) ok\n\n",
			      pOpData->opId, pOpData->au4OpData[0], pOpData->au4OpData[1]);
	}
	/*return value will be put to lxop->op.au4OpData[1] */
	WMT_DBG_FUNC("therm ctrl type(%d), iRet(0x%08x)\n", eType, pOpData->au4OpData[1]);
	return (INT8) pOpData->au4OpData[1];
}
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;
}