/******************************************************************************
 *
 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 ******************************************************************************/
/******************************************************************************
 *
 *
 * Module:	rtl8192c_rf6052.c	(Source C File)
 *
 * Note:	Provide RF 6052 series relative API.
 *
 * Function:
 *
 * Export:
 *
 * Abbrev:
 *
 * History:
 * Data			Who		Remark
 *
 * 09/25/2008	MHC		Create initial version.
 * 11/05/2008	MHC		Add API for tw power setting.
 *
 *
******************************************************************************/

#define _RTL8723A_RF6052_C_

#include <osdep_service.h>
#include <drv_types.h>

#include <rtl8723a_hal.h>
#include <usb_ops_linux.h>

/*-----------------------------------------------------------------------------
 * Function:    PHY_RF6052SetBandwidth()
 *
 * Overview:    This function is called by SetBWMode23aCallback8190Pci() only
 *
 * Input:       struct rtw_adapter *				Adapter
 *			WIRELESS_BANDWIDTH_E	Bandwidth	20M or 40M
 *
 * Output:      NONE
 *
 * Return:      NONE
 *
 * Note:		For RF type 0222D
 *---------------------------------------------------------------------------*/
void rtl8723a_phy_rf6052set_bw(struct rtw_adapter *Adapter,
			       enum ht_channel_width Bandwidth)	/* 20M or 40M */
{
	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);

	switch (Bandwidth) {
	case HT_CHANNEL_WIDTH_20:
		pHalData->RfRegChnlVal[0] =
			(pHalData->RfRegChnlVal[0] & 0xfffff3ff) | 0x0400;
		PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
			     pHalData->RfRegChnlVal[0]);
		break;
	case HT_CHANNEL_WIDTH_40:
		pHalData->RfRegChnlVal[0] =
			(pHalData->RfRegChnlVal[0] & 0xfffff3ff);
		PHY_SetRFReg(Adapter, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
			     pHalData->RfRegChnlVal[0]);
		break;
	default:
		break;
	}
}

/*-----------------------------------------------------------------------------
 * Function:	PHY_RF6052SetCckTxPower
 *
 * Overview:
 *
 * Input:       NONE
 *
 * Output:      NONE
 *
 * Return:      NONE
 *
 * Revised History:
 * When			Who		Remark
 * 11/05/2008	MHC		Simulate 8192series..
 *
 *---------------------------------------------------------------------------*/

void rtl823a_phy_rf6052setccktxpower(struct rtw_adapter *Adapter,
				     u8 *pPowerlevel)
{
	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
	struct dm_priv *pdmpriv = &pHalData->dmpriv;
	struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;
	u32 TxAGC[2] = {0, 0}, tmpval = 0;
	u8 idx1, idx2;
	u8 *ptr;

	if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
		TxAGC[RF_PATH_A] = 0x3f3f3f3f;
		TxAGC[RF_PATH_B] = 0x3f3f3f3f;

		for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
			TxAGC[idx1] = pPowerlevel[idx1] |
				(pPowerlevel[idx1] << 8) |
				(pPowerlevel[idx1] << 16) |
				(pPowerlevel[idx1] << 24);
			/*
			 * 2010/10/18 MH For external PA module. We need
			 * to limit power index to be less than 0x20.
			 */
			if (TxAGC[idx1] > 0x20 && pHalData->ExternalPA)
				TxAGC[idx1] = 0x20;
		}
	} else {
/*  20100427 Joseph: Driver dynamic Tx power shall not affect Tx
 *  power. It shall be determined by power training mechanism. */
/*  Currently, we cannot fully disable driver dynamic tx power
 *  mechanism because it is referenced by BT coexist mechanism. */
/*  In the future, two mechanism shall be separated from each other
 *  and maintained independently. Thanks for Lanhsin's reminder. */
		if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) {
			TxAGC[RF_PATH_A] = 0x10101010;
			TxAGC[RF_PATH_B] = 0x10101010;
		} else if (pdmpriv->DynamicTxHighPowerLvl ==
			   TxHighPwrLevel_Level2) {
			TxAGC[RF_PATH_A] = 0x00000000;
			TxAGC[RF_PATH_B] = 0x00000000;
		} else {
			for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
				TxAGC[idx1] = pPowerlevel[idx1] |
					(pPowerlevel[idx1] << 8) |
					(pPowerlevel[idx1] << 16) |
					(pPowerlevel[idx1] << 24);
			}

			if (pHalData->EEPROMRegulatory == 0) {
				tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][6]) +
						(pHalData->MCSTxPowerLevelOriginalOffset[0][7]<<8);
				TxAGC[RF_PATH_A] += tmpval;

				tmpval = (pHalData->MCSTxPowerLevelOriginalOffset[0][14]) +
						(pHalData->MCSTxPowerLevelOriginalOffset[0][15]<<24);
				TxAGC[RF_PATH_B] += tmpval;
			}
		}
	}

	for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
		ptr = (u8 *)(&TxAGC[idx1]);
		for (idx2 = 0; idx2 < 4; idx2++) {
			if (*ptr > RF6052_MAX_TX_PWR)
				*ptr = RF6052_MAX_TX_PWR;
			ptr++;
		}
	}

	/*  rf-A cck tx power */
	tmpval = TxAGC[RF_PATH_A] & 0xff;
	PHY_SetBBReg(Adapter, rTxAGC_A_CCK1_Mcs32, bMaskByte1, tmpval);
	tmpval = TxAGC[RF_PATH_A] >> 8;
	PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);

	/*  rf-B cck tx power */
	tmpval = TxAGC[RF_PATH_B] >> 24;
	PHY_SetBBReg(Adapter, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval);
	tmpval = TxAGC[RF_PATH_B] & 0x00ffffff;
	PHY_SetBBReg(Adapter, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval);
}	/* PHY_RF6052SetCckTxPower */

/*  powerbase0 for OFDM rates */
/*  powerbase1 for HT MCS rates */
static void getPowerBase(struct rtw_adapter *Adapter, u8 *pPowerLevel,
			 u8 Channel, u32 *OfdmBase, u32 *MCSBase)
{
	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
	u32 ofdm, mcs;
	u8 Legacy_pwrdiff = 0;
	s8 HT20_pwrdiff = 0;
	u8 i, powerlevel[2];

	for (i = 0; i < 2; i++) {
		powerlevel[i] = pPowerLevel[i];
		Legacy_pwrdiff = pHalData->TxPwrLegacyHtDiff[i][Channel-1];
		ofdm = powerlevel[i] + Legacy_pwrdiff;

		ofdm = ofdm << 24 | ofdm << 16 | ofdm << 8 | ofdm;
		*(OfdmBase + i) = ofdm;
	}

	for (i = 0; i < 2; i++) {
		/* Check HT20 to HT40 diff */
		if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20) {
			HT20_pwrdiff = pHalData->TxPwrHt20Diff[i][Channel-1];
			powerlevel[i] += HT20_pwrdiff;
		}
		mcs = powerlevel[i];
		mcs = mcs << 24 | mcs << 16 | mcs << 8 | mcs;
		*(MCSBase + i) = mcs;
	}
}

static void
getTxPowerWriteValByRegulatory(struct rtw_adapter *Adapter, u8 Channel,
			       u8 index, u32 *powerBase0, u32 *powerBase1,
			       u32 *pOutWriteVal)
{
	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
	struct dm_priv	*pdmpriv = &pHalData->dmpriv;
	u8 i, chnlGroup = 0, pwr_diff_limit[4];
	u32 writeVal, customer_limit, rf;

	/*  Index 0 & 1 = legacy OFDM, 2-5 = HT_MCS rate */
	for (rf = 0; rf < 2; rf++) {
		switch (pHalData->EEPROMRegulatory) {
		case 0:	/*  Realtek better performance */
			/*  increase power diff defined by Realtek for
			 *  large power */
			chnlGroup = 0;
			writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] +
				((index < 2) ? powerBase0[rf] : powerBase1[rf]);
			break;
		case 1:	/*  Realtek regulatory */
			/*  increase power diff defined by Realtek for
			 *  regulatory */
			if (pHalData->pwrGroupCnt == 1)
				chnlGroup = 0;
			if (pHalData->pwrGroupCnt >= 3) {
				if (Channel <= 3)
					chnlGroup = 0;
				else if (Channel >= 4 && Channel <= 9)
					chnlGroup = 1;
				else if (Channel > 9)
					chnlGroup = 2;

				if (pHalData->CurrentChannelBW ==
				    HT_CHANNEL_WIDTH_20)
					chnlGroup++;
				else
					chnlGroup += 4;
			}
			writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] +
				   ((index < 2) ? powerBase0[rf] :
				    powerBase1[rf]);
			break;
		case 2:	/*  Better regulatory */
			/*  don't increase any power diff */
			writeVal = (index < 2) ? powerBase0[rf] :
				    powerBase1[rf];
			break;
		case 3:	/*  Customer defined power diff. */
			chnlGroup = 0;

			for (i = 0; i < 4; i++) {
				pwr_diff_limit[i] = (u8)((pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index +
						    (rf ? 8 : 0)]&(0x7f << (i*8))) >> (i*8));
				if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_40) {
					if (pwr_diff_limit[i] > pHalData->PwrGroupHT40[rf][Channel-1])
						pwr_diff_limit[i] = pHalData->PwrGroupHT40[rf][Channel-1];
				} else {
					if (pwr_diff_limit[i] > pHalData->PwrGroupHT20[rf][Channel-1])
						pwr_diff_limit[i] = pHalData->PwrGroupHT20[rf][Channel-1];
				}
			}
			customer_limit = (pwr_diff_limit[3]<<24) | (pwr_diff_limit[2]<<16) |
							(pwr_diff_limit[1]<<8) | (pwr_diff_limit[0]);
			writeVal = customer_limit + ((index<2)?powerBase0[rf]:powerBase1[rf]);
			break;
		default:
			chnlGroup = 0;
			writeVal = pHalData->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf?8:0)] +
					((index < 2) ? powerBase0[rf] : powerBase1[rf]);
			break;
		}

/*  20100427 Joseph: Driver dynamic Tx power shall not affect Tx power.
    It shall be determined by power training mechanism. */
/*  Currently, we cannot fully disable driver dynamic tx power mechanism
    because it is referenced by BT coexist mechanism. */
/*  In the future, two mechanism shall be separated from each other and
    maintained independently. Thanks for Lanhsin's reminder. */

		if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1)
			writeVal = 0x14141414;
		else if (pdmpriv->DynamicTxHighPowerLvl ==
			 TxHighPwrLevel_Level2)
			writeVal = 0x00000000;

		/* 20100628 Joseph: High power mode for BT-Coexist mechanism. */
		/* This mechanism is only applied when
		   Driver-Highpower-Mechanism is OFF. */
		if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT1)
			writeVal = writeVal - 0x06060606;
		else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_BT2)
			writeVal = writeVal;
		*(pOutWriteVal + rf) = writeVal;
	}
}

static void writeOFDMPowerReg(struct rtw_adapter *Adapter, u8 index,
			      u32 *pValue)
{
	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
	u16 RegOffset_A[6] = {
		rTxAGC_A_Rate18_06, rTxAGC_A_Rate54_24,
		rTxAGC_A_Mcs03_Mcs00, rTxAGC_A_Mcs07_Mcs04,
		rTxAGC_A_Mcs11_Mcs08, rTxAGC_A_Mcs15_Mcs12
	};
	u16 RegOffset_B[6] = {
		rTxAGC_B_Rate18_06, rTxAGC_B_Rate54_24,
		rTxAGC_B_Mcs03_Mcs00, rTxAGC_B_Mcs07_Mcs04,
		rTxAGC_B_Mcs11_Mcs08, rTxAGC_B_Mcs15_Mcs12
	};
	u8 i, rf, pwr_val[4];
	u32 writeVal;
	u16 RegOffset;

	for (rf = 0; rf < 2; rf++) {
		writeVal = pValue[rf];
		for (i = 0; i < 4; i++) {
			pwr_val[i] = (u8)((writeVal &
					   (0x7f << (i * 8))) >> (i * 8));
			if (pwr_val[i] > RF6052_MAX_TX_PWR)
				pwr_val[i]  = RF6052_MAX_TX_PWR;
		}
		writeVal = pwr_val[3] << 24 | pwr_val[2] << 16 |
			pwr_val[1] << 8 | pwr_val[0];

		if (rf == 0)
			RegOffset = RegOffset_A[index];
		else
			RegOffset = RegOffset_B[index];

		rtl8723au_write32(Adapter, RegOffset, writeVal);

		/*  201005115 Joseph: Set Tx Power diff for Tx power
		    training mechanism. */
		if (((pHalData->rf_type == RF_2T2R) &&
		    (RegOffset == rTxAGC_A_Mcs15_Mcs12 ||
		     RegOffset == rTxAGC_B_Mcs15_Mcs12)) ||
		    ((pHalData->rf_type != RF_2T2R) &&
		     (RegOffset == rTxAGC_A_Mcs07_Mcs04 ||
		      RegOffset == rTxAGC_B_Mcs07_Mcs04))) {
			writeVal = pwr_val[3];
			if (RegOffset == rTxAGC_A_Mcs15_Mcs12 ||
			    RegOffset == rTxAGC_A_Mcs07_Mcs04)
				RegOffset = 0xc90;
			if (RegOffset == rTxAGC_B_Mcs15_Mcs12 ||
			    RegOffset == rTxAGC_B_Mcs07_Mcs04)
				RegOffset = 0xc98;
			for (i = 0; i < 3; i++) {
				if (i != 2)
					writeVal = (writeVal > 8) ?
						(writeVal - 8) : 0;
				else
					writeVal = (writeVal > 6) ?
						(writeVal - 6) : 0;
				rtl8723au_write8(Adapter, RegOffset + i,
						 (u8)writeVal);
			}
		}
	}
}
/*-----------------------------------------------------------------------------
 * Function:	PHY_RF6052SetOFDMTxPower
 *
 * Overview:	For legacy and HY OFDM, we must read EEPROM TX power index for
 *		different channel and read original value in TX power
 *		register area from 0xe00. We increase offset and
 *		original value to be correct tx pwr.
 *
 * Input:       NONE
 *
 * Output:      NONE
 *
 * Return:      NONE
 *
 * Revised History:
 * When			Remark
 * 11/05/2008	MHC	Simulate 8192 series method.
 * 01/06/2009	MHC	1. Prevent Path B tx power overflow or
 *			underflow dure to A/B pwr difference or
 *			legacy/HT pwr diff.
 *			2. We concern with path B legacy/HT OFDM difference.
 * 01/22/2009	MHC	Support new EPRO format from SD3.
 *
 *---------------------------------------------------------------------------*/
void rtl8723a_PHY_RF6052SetOFDMTxPower(struct rtw_adapter *Adapter,
				       u8 *pPowerLevel, u8 Channel)
{
	u32 writeVal[2], powerBase0[2], powerBase1[2];
	u8 index = 0;

	getPowerBase(Adapter, pPowerLevel, Channel,
		     &powerBase0[0], &powerBase1[0]);

	for (index = 0; index < 6; index++) {
		getTxPowerWriteValByRegulatory(Adapter, Channel, index,
			&powerBase0[0], &powerBase1[0], &writeVal[0]);

		writeOFDMPowerReg(Adapter, index, &writeVal[0]);
	}
}

static int phy_RF6052_Config_ParaFile(struct rtw_adapter *Adapter)
{
	u32 u4RegValue = 0;
	u8 eRFPath;
	struct bb_reg_define *pPhyReg;
	int rtStatus = _SUCCESS;
	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);

	/* 3----------------------------------------------------------------- */
	/* 3 <2> Initialize RF */
	/* 3----------------------------------------------------------------- */
	for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {

		pPhyReg = &pHalData->PHYRegDef[eRFPath];

		/*----Store original RFENV control type----*/
		switch (eRFPath) {
		case RF_PATH_A:
			u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs,
						    bRFSI_RFENV);
			break;
		case RF_PATH_B:
			u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs,
						    bRFSI_RFENV << 16);
			break;
		}

		/*----Set RF_ENV enable----*/
		PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV << 16, 0x1);
		udelay(1);/* PlatformStallExecution(1); */

		/*----Set RF_ENV output high----*/
		PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
		udelay(1);/* PlatformStallExecution(1); */

		/* Set bit number of Address and Data for RF register */
		PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength,
			     0x0);	/*  Set 1 to 4 bits for 8255 */
		udelay(1);/* PlatformStallExecution(1); */

		PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength,
			     0x0);	/*  Set 0 to 12  bits for 8255 */
		udelay(1);/* PlatformStallExecution(1); */

		/*----Initialize RF fom connfiguration file----*/
		switch (eRFPath) {
		case RF_PATH_A:
			ODM_ReadAndConfig_RadioA_1T_8723A(&pHalData->odmpriv);
			break;
		case RF_PATH_B:
			break;
		}

		/*----Restore RFENV control type----*/;
		switch (eRFPath) {
		case RF_PATH_A:
			PHY_SetBBReg(Adapter, pPhyReg->rfintfs,
				     bRFSI_RFENV, u4RegValue);
			break;
		case RF_PATH_B:
			PHY_SetBBReg(Adapter, pPhyReg->rfintfs,
				     bRFSI_RFENV << 16, u4RegValue);
			break;
		}

		if (rtStatus != _SUCCESS) {
			goto phy_RF6052_Config_ParaFile_Fail;
		}
	}
phy_RF6052_Config_ParaFile_Fail:
	return rtStatus;
}

int PHY_RF6052_Config8723A(struct rtw_adapter *Adapter)
{
	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);

	/*  Initialize general global value */
	/*  TODO: Extend RF_PATH_C and RF_PATH_D in the future */
	if (pHalData->rf_type == RF_1T1R)
		pHalData->NumTotalRFPath = 1;
	else
		pHalData->NumTotalRFPath = 2;

	/*  Config BB and RF */
	return phy_RF6052_Config_ParaFile(Adapter);
}

/* End of HalRf6052.c */
