/******************************************************************************
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
 *
 ******************************************************************************/

#include <osdep_service.h>
#include <drv_types.h>
#include <phy.h>
#include <rf.h>
#include <rtl8188e_hal.h>

void rtl88eu_phy_rf6052_set_bandwidth(struct adapter *adapt,
				      enum ht_channel_width bandwidth)
{
	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);

	switch (bandwidth) {
	case HT_CHANNEL_WIDTH_20:
		hal_data->RfRegChnlVal[0] = ((hal_data->RfRegChnlVal[0] &
					      0xfffff3ff) | BIT(10) | BIT(11));
		phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
			       hal_data->RfRegChnlVal[0]);
		break;
	case HT_CHANNEL_WIDTH_40:
		hal_data->RfRegChnlVal[0] = ((hal_data->RfRegChnlVal[0] &
					      0xfffff3ff) | BIT(10));
		phy_set_rf_reg(adapt, RF_PATH_A, RF_CHNLBW, bRFRegOffsetMask,
			       hal_data->RfRegChnlVal[0]);
		break;
	default:
		break;
	}
}

void rtl88eu_phy_rf6052_set_cck_txpower(struct adapter *adapt, u8 *powerlevel)
{
	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
	struct dm_priv *pdmpriv = &hal_data->dmpriv;
	struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv;
	u32 tx_agc[2] = {0, 0}, tmpval = 0, pwrtrac_value;
	u8 idx1, idx2;
	u8 *ptr;
	u8 direction;


	if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
		tx_agc[RF_PATH_A] = 0x3f3f3f3f;
		tx_agc[RF_PATH_B] = 0x3f3f3f3f;
		for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
			tx_agc[idx1] = powerlevel[idx1] |
				      (powerlevel[idx1]<<8) |
				      (powerlevel[idx1]<<16) |
				      (powerlevel[idx1]<<24);
			if (tx_agc[idx1] > 0x20 && hal_data->ExternalPA)
				tx_agc[idx1] = 0x20;
		}
	} else {
		if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) {
			tx_agc[RF_PATH_A] = 0x10101010;
			tx_agc[RF_PATH_B] = 0x10101010;
		} else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2) {
			tx_agc[RF_PATH_A] = 0x00000000;
			tx_agc[RF_PATH_B] = 0x00000000;
		} else {
			for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
				tx_agc[idx1] = powerlevel[idx1] |
					       (powerlevel[idx1]<<8) |
					       (powerlevel[idx1]<<16) |
					       (powerlevel[idx1]<<24);
			}
			if (hal_data->EEPROMRegulatory == 0) {
				tmpval = hal_data->MCSTxPowerLevelOriginalOffset[0][6] +
					 (hal_data->MCSTxPowerLevelOriginalOffset[0][7]<<8);
				tx_agc[RF_PATH_A] += tmpval;

				tmpval = hal_data->MCSTxPowerLevelOriginalOffset[0][14] +
					 (hal_data->MCSTxPowerLevelOriginalOffset[0][15]<<24);
				tx_agc[RF_PATH_B] += tmpval;
			}
		}
	}
	for (idx1 = RF_PATH_A; idx1 <= RF_PATH_B; idx1++) {
		ptr = (u8 *)(&(tx_agc[idx1]));
		for (idx2 = 0; idx2 < 4; idx2++) {
			if (*ptr > RF6052_MAX_TX_PWR)
				*ptr = RF6052_MAX_TX_PWR;
			ptr++;
		}
	}
	rtl88eu_dm_txpower_track_adjust(&hal_data->odmpriv, 1, &direction,
				        &pwrtrac_value);

	if (direction == 1) {
		/*  Increase TX power */
		tx_agc[0] += pwrtrac_value;
		tx_agc[1] += pwrtrac_value;
	} else if (direction == 2) {
		/*  Decrease TX power */
		tx_agc[0] -=  pwrtrac_value;
		tx_agc[1] -=  pwrtrac_value;
	}

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

	/*  rf-B cck tx power */
	tmpval = tx_agc[RF_PATH_B]>>24;
	phy_set_bb_reg(adapt, rTxAGC_B_CCK11_A_CCK2_11, bMaskByte0, tmpval);
	tmpval = tx_agc[RF_PATH_B]&0x00ffffff;
	phy_set_bb_reg(adapt, rTxAGC_B_CCK1_55_Mcs32, 0xffffff00, tmpval);
}

/*  powerbase0 for OFDM rates */
/*  powerbase1 for HT MCS rates */
static void getpowerbase88e(struct adapter *adapt, u8 *pwr_level_ofdm,
			    u8 *pwr_level_bw20, u8 *pwr_level_bw40,
			    u8 channel,u32 *ofdmbase, u32 *mcs_base)
{
	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
	u32 powerbase0, powerbase1;
	u8 i, powerlevel[2];

	for (i = 0; i < 2; i++) {
		powerbase0 = pwr_level_ofdm[i];

		powerbase0 = (powerbase0<<24) | (powerbase0<<16) |
			     (powerbase0<<8) | powerbase0;
		*(ofdmbase+i) = powerbase0;
	}
	for (i = 0; i < hal_data->NumTotalRFPath; i++) {
		/* Check HT20 to HT40 diff */
		if (hal_data->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
			powerlevel[i] = pwr_level_bw20[i];
		else
			powerlevel[i] = pwr_level_bw40[i];
		powerbase1 = powerlevel[i];
		powerbase1 = (powerbase1<<24) | (powerbase1<<16) |
			     (powerbase1<<8) | powerbase1;
		*(mcs_base+i) = powerbase1;
	}
}
static void get_rx_power_val_by_reg(struct adapter *adapt, u8 channel,
				    u8 index, u32 *powerbase0, u32 *powerbase1,
				    u32 *out_val)
{
	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
	struct dm_priv	*pdmpriv = &hal_data->dmpriv;
	u8 i, chnlGroup = 0, pwr_diff_limit[4], customer_pwr_limit;
	s8 pwr_diff = 0;
	u32 write_val, customer_limit, rf;
	u8 regulatory = hal_data->EEPROMRegulatory;

	/*  Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */

	for (rf = 0; rf < 2; rf++) {
		u8 j = index + (rf ? 8 : 0);

		switch (regulatory) {
		case 0:
			chnlGroup = 0;
			write_val = hal_data->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 (hal_data->pwrGroupCnt == 1)
				chnlGroup = 0;
			if (hal_data->pwrGroupCnt >= hal_data->PGMaxGroup) {
				if (channel < 3)
					chnlGroup = 0;
				else if (channel < 6)
					chnlGroup = 1;
				else if (channel < 9)
					chnlGroup = 2;
				else if (channel < 12)
					chnlGroup = 3;
				else if (channel < 14)
					chnlGroup = 4;
				else if (channel == 14)
					chnlGroup = 5;
			}
			write_val = hal_data->MCSTxPowerLevelOriginalOffset[chnlGroup][index+(rf ? 8 : 0)] +
					((index < 2) ? powerbase0[rf] : powerbase1[rf]);
			break;
		case 2:	/*  Better regulatory */
				/*  don't increase any power diff */
			write_val = ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
			break;
		case 3:	/*  Customer defined power diff. */
				/*  increase power diff defined by customer. */
			chnlGroup = 0;

			if (index < 2)
				pwr_diff = hal_data->TxPwrLegacyHtDiff[rf][channel-1];
			else if (hal_data->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
				pwr_diff = hal_data->TxPwrHt20Diff[rf][channel-1];

			if (hal_data->CurrentChannelBW == HT_CHANNEL_WIDTH_40)
				customer_pwr_limit = hal_data->PwrGroupHT40[rf][channel-1];
			else
				customer_pwr_limit = hal_data->PwrGroupHT20[rf][channel-1];

			if (pwr_diff >= customer_pwr_limit)
				pwr_diff = 0;
			else
				pwr_diff = customer_pwr_limit - pwr_diff;

			for (i = 0; i < 4; i++) {
				pwr_diff_limit[i] = (u8)((hal_data->MCSTxPowerLevelOriginalOffset[chnlGroup][j] &
							 (0x7f << (i * 8))) >> (i * 8));

				if (pwr_diff_limit[i] > pwr_diff)
					pwr_diff_limit[i] = pwr_diff;
			}
			customer_limit = (pwr_diff_limit[3]<<24) |
					 (pwr_diff_limit[2]<<16) |
					 (pwr_diff_limit[1]<<8) |
					 (pwr_diff_limit[0]);
			write_val = customer_limit + ((index < 2) ? powerbase0[rf] : powerbase1[rf]);
			break;
		default:
			chnlGroup = 0;
			write_val = hal_data->MCSTxPowerLevelOriginalOffset[chnlGroup][j] +
					((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. */
		/* 92d do not need this */
		if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1)
			write_val = 0x14141414;
		else if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level2)
			write_val = 0x00000000;

		*(out_val+rf) = write_val;
	}
}

static void write_ofdm_pwr_reg(struct adapter *adapt, u8 index, u32 *pvalue)
{
	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 write_val;
	u16 regoffset;

	for (rf = 0; rf < 2; rf++) {
		write_val = pvalue[rf];
		for (i = 0; i < 4; i++) {
			pwr_val[i] = (u8)((write_val & (0x7f<<(i*8)))>>(i*8));
			if (pwr_val[i]  > RF6052_MAX_TX_PWR)
				pwr_val[i]  = RF6052_MAX_TX_PWR;
		}
		write_val = (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];

		phy_set_bb_reg(adapt, regoffset, bMaskDWord, write_val);
	}
}

void rtl88eu_phy_rf6052_set_ofdm_txpower(struct adapter *adapt,
					 u8 *pwr_level_ofdm,
					 u8 *pwr_level_bw20,
					 u8 *pwr_level_bw40, u8 channel)
{
	struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt);
	u32 write_val[2], powerbase0[2], powerbase1[2], pwrtrac_value;
	u8 direction;
	u8 index = 0;

	getpowerbase88e(adapt, pwr_level_ofdm, pwr_level_bw20, pwr_level_bw40,
			channel, &powerbase0[0], &powerbase1[0]);

	rtl88eu_dm_txpower_track_adjust(&hal_data->odmpriv, 0, &direction,
					&pwrtrac_value);

	for (index = 0; index < 6; index++) {
		get_rx_power_val_by_reg(adapt, channel, index,
					&powerbase0[0], &powerbase1[0],
					&write_val[0]);

		if (direction == 1) {
			write_val[0] += pwrtrac_value;
			write_val[1] += pwrtrac_value;
		} else if (direction == 2) {
			write_val[0] -= pwrtrac_value;
			write_val[1] -= pwrtrac_value;
		}
		write_ofdm_pwr_reg(adapt, index, &write_val[0]);
	}
}
