1/* 2 ************************************************************************* 3 * Ralink Tech Inc. 4 * 5F., No.36, Taiyuan St., Jhubei City, 5 * Hsinchu County 302, 6 * Taiwan, R.O.C. 7 * 8 * (c) Copyright 2002-2007, Ralink Technology, Inc. 9 * 10 * This program is free software; you can redistribute it and/or modify * 11 * it under the terms of the GNU General Public License as published by * 12 * the Free Software Foundation; either version 2 of the License, or * 13 * (at your option) any later version. * 14 * * 15 * This program is distributed in the hope that it will be useful, * 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 * GNU General Public License for more details. * 19 * * 20 * You should have received a copy of the GNU General Public License * 21 * along with this program; if not, write to the * 22 * Free Software Foundation, Inc., * 23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 24 * * 25 ************************************************************************* 26 27 Module Name: 28 rt30xx.c 29 30 Abstract: 31 Specific funcitons and variables for RT30xx. 32 33 Revision History: 34 Who When What 35 -------- ---------- ---------------------------------------------- 36*/ 37 38#ifdef RT30xx 39 40#ifndef RTMP_RF_RW_SUPPORT 41#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" 42#endif /* RTMP_RF_RW_SUPPORT // */ 43 44#include "../rt_config.h" 45 46/* */ 47/* RF register initialization set */ 48/* */ 49struct rt_reg_pair RT30xx_RFRegTable[] = { 50 {RF_R04, 0x40} 51 , 52 {RF_R05, 0x03} 53 , 54 {RF_R06, 0x02} 55 , 56 {RF_R07, 0x60} 57 , 58 {RF_R09, 0x0F} 59 , 60 {RF_R10, 0x41} 61 , 62 {RF_R11, 0x21} 63 , 64 {RF_R12, 0x7B} 65 , 66 {RF_R14, 0x90} 67 , 68 {RF_R15, 0x58} 69 , 70 {RF_R16, 0xB3} 71 , 72 {RF_R17, 0x92} 73 , 74 {RF_R18, 0x2C} 75 , 76 {RF_R19, 0x02} 77 , 78 {RF_R20, 0xBA} 79 , 80 {RF_R21, 0xDB} 81 , 82 {RF_R24, 0x16} 83 , 84 {RF_R25, 0x01} 85 , 86 {RF_R29, 0x1F} 87 , 88}; 89 90u8 NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(struct rt_reg_pair)); 91 92/* Antenna divesity use GPIO3 and EESK pin for control */ 93/* Antenna and EEPROM access are both using EESK pin, */ 94/* Therefor we should avoid accessing EESK at the same time */ 95/* Then restore antenna after EEPROM access */ 96/* The original name of this function is AsicSetRxAnt(), now change to */ 97/*void AsicSetRxAnt( */ 98void RT30xxSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant) 99{ 100 u32 Value; 101#ifdef RTMP_MAC_PCI 102 u32 x; 103#endif 104 105 if ((pAd->EepromAccess) || 106 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || 107 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || 108 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) || 109 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { 110 return; 111 } 112 /* the antenna selection is through firmware and MAC register(GPIO3) */ 113 if (Ant == 0) { 114 /* Main antenna */ 115#ifdef RTMP_MAC_PCI 116 RTMP_IO_READ32(pAd, E2PROM_CSR, &x); 117 x |= (EESK); 118 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); 119#else 120 AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0); 121#endif /* RTMP_MAC_PCI // */ 122 123 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); 124 Value &= ~(0x0808); 125 RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); 126 DBGPRINT_RAW(RT_DEBUG_TRACE, 127 ("AsicSetRxAnt, switch to main antenna\n")); 128 } else { 129 /* Aux antenna */ 130#ifdef RTMP_MAC_PCI 131 RTMP_IO_READ32(pAd, E2PROM_CSR, &x); 132 x &= ~(EESK); 133 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); 134#else 135 AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0); 136#endif /* RTMP_MAC_PCI // */ 137 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); 138 Value &= ~(0x0808); 139 Value |= 0x08; 140 RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); 141 DBGPRINT_RAW(RT_DEBUG_TRACE, 142 ("AsicSetRxAnt, switch to aux antenna\n")); 143 } 144} 145 146/* 147 ======================================================================== 148 149 Routine Description: 150 For RF filter calibration purpose 151 152 Arguments: 153 pAd Pointer to our adapter 154 155 Return Value: 156 None 157 158 IRQL = PASSIVE_LEVEL 159 160 ======================================================================== 161*/ 162void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd) 163{ 164 u8 R55x = 0, value, FilterTarget = 0x1E, BBPValue = 0; 165 u32 loop = 0, count = 0, loopcnt = 0, ReTry = 0; 166 u8 RF_R24_Value = 0; 167 168 /* Give bbp filter initial value */ 169 pAd->Mlme.CaliBW20RfR24 = 0x1F; 170 pAd->Mlme.CaliBW40RfR24 = 0x2F; /*Bit[5] must be 1 for BW 40 */ 171 172 do { 173 if (loop == 1) { /*BandWidth = 40 MHz */ 174 /* Write 0x27 to RF_R24 to program filter */ 175 RF_R24_Value = 0x27; 176 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); 177 if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) 178 FilterTarget = 0x15; 179 else 180 FilterTarget = 0x19; 181 182 /* when calibrate BW40, BBP mask must set to BW40. */ 183 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); 184 BBPValue &= (~0x18); 185 BBPValue |= (0x10); 186 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); 187 188 /* set to BW40 */ 189 RT30xxReadRFRegister(pAd, RF_R31, &value); 190 value |= 0x20; 191 RT30xxWriteRFRegister(pAd, RF_R31, value); 192 } else { /*BandWidth = 20 MHz */ 193 /* Write 0x07 to RF_R24 to program filter */ 194 RF_R24_Value = 0x07; 195 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); 196 if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) 197 FilterTarget = 0x13; 198 else 199 FilterTarget = 0x16; 200 201 /* set to BW20 */ 202 RT30xxReadRFRegister(pAd, RF_R31, &value); 203 value &= (~0x20); 204 RT30xxWriteRFRegister(pAd, RF_R31, value); 205 } 206 207 /* Write 0x01 to RF_R22 to enable baseband loopback mode */ 208 RT30xxReadRFRegister(pAd, RF_R22, &value); 209 value |= 0x01; 210 RT30xxWriteRFRegister(pAd, RF_R22, value); 211 212 /* Write 0x00 to BBP_R24 to set power & frequency of passband test tone */ 213 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); 214 215 do { 216 /* Write 0x90 to BBP_R25 to transmit test tone */ 217 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); 218 219 RTMPusecDelay(1000); 220 /* Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0] */ 221 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); 222 R55x = value & 0xFF; 223 224 } while ((ReTry++ < 100) && (R55x == 0)); 225 226 /* Write 0x06 to BBP_R24 to set power & frequency of stopband test tone */ 227 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06); 228 229 while (TRUE) { 230 /* Write 0x90 to BBP_R25 to transmit test tone */ 231 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); 232 233 /*We need to wait for calibration */ 234 RTMPusecDelay(1000); 235 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); 236 value &= 0xFF; 237 if ((R55x - value) < FilterTarget) { 238 RF_R24_Value++; 239 } else if ((R55x - value) == FilterTarget) { 240 RF_R24_Value++; 241 count++; 242 } else { 243 break; 244 } 245 246 /* prevent infinite loop cause driver hang. */ 247 if (loopcnt++ > 100) { 248 DBGPRINT(RT_DEBUG_ERROR, 249 ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", 250 loopcnt)); 251 break; 252 } 253 /* Write RF_R24 to program filter */ 254 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); 255 } 256 257 if (count > 0) { 258 RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0)); 259 } 260 /* Store for future usage */ 261 if (loopcnt < 100) { 262 if (loop++ == 0) { 263 /*BandWidth = 20 MHz */ 264 pAd->Mlme.CaliBW20RfR24 = (u8)RF_R24_Value; 265 } else { 266 /*BandWidth = 40 MHz */ 267 pAd->Mlme.CaliBW40RfR24 = (u8)RF_R24_Value; 268 break; 269 } 270 } else 271 break; 272 273 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); 274 275 /* reset count */ 276 count = 0; 277 } while (TRUE); 278 279 /* */ 280 /* Set back to initial state */ 281 /* */ 282 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); 283 284 RT30xxReadRFRegister(pAd, RF_R22, &value); 285 value &= ~(0x01); 286 RT30xxWriteRFRegister(pAd, RF_R22, value); 287 288 /* set BBP back to BW20 */ 289 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); 290 BBPValue &= (~0x18); 291 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); 292 293 DBGPRINT(RT_DEBUG_TRACE, 294 ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", 295 pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24)); 296} 297 298/* add by johnli, RF power sequence setup */ 299/* 300 ========================================================================== 301 Description: 302 303 Load RF normal operation-mode setup 304 305 ========================================================================== 306 */ 307void RT30xxLoadRFNormalModeSetup(struct rt_rtmp_adapter *pAd) 308{ 309 u8 RFValue; 310 311 /* RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1 */ 312 RT30xxReadRFRegister(pAd, RF_R01, &RFValue); 313 RFValue = (RFValue & (~0x0C)) | 0x31; 314 RT30xxWriteRFRegister(pAd, RF_R01, RFValue); 315 316 /* TX_LO2_en, RF R15 register Bit 3 to 0 */ 317 RT30xxReadRFRegister(pAd, RF_R15, &RFValue); 318 RFValue &= (~0x08); 319 RT30xxWriteRFRegister(pAd, RF_R15, RFValue); 320 321 /* move to NICInitRT30xxRFRegisters 322 // TX_LO1_en, RF R17 register Bit 3 to 0 323 RT30xxReadRFRegister(pAd, RF_R17, &RFValue); 324 RFValue &= (~0x08); 325 // to fix rx long range issue 326 if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0)) 327 { 328 RFValue |= 0x20; 329 } 330 // set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h 331 if (pAd->TxMixerGain24G >= 2) 332 { 333 RFValue &= (~0x7); // clean bit [2:0] 334 RFValue |= pAd->TxMixerGain24G; 335 } 336 RT30xxWriteRFRegister(pAd, RF_R17, RFValue); 337 */ 338 339 /* RX_LO1_en, RF R20 register Bit 3 to 0 */ 340 RT30xxReadRFRegister(pAd, RF_R20, &RFValue); 341 RFValue &= (~0x08); 342 RT30xxWriteRFRegister(pAd, RF_R20, RFValue); 343 344 /* RX_LO2_en, RF R21 register Bit 3 to 0 */ 345 RT30xxReadRFRegister(pAd, RF_R21, &RFValue); 346 RFValue &= (~0x08); 347 RT30xxWriteRFRegister(pAd, RF_R21, RFValue); 348 349 /* add by johnli, reset RF_R27 when interface down & up to fix throughput problem */ 350 /* LDORF_VC, RF R27 register Bit 2 to 0 */ 351 RT30xxReadRFRegister(pAd, RF_R27, &RFValue); 352 /* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */ 353 /* Raising RF voltage is no longer needed for RT3070(F) */ 354 if (IS_RT3090(pAd)) { /* RT309x and RT3071/72 */ 355 if ((pAd->MACVersion & 0xffff) < 0x0211) 356 RFValue = (RFValue & (~0x77)) | 0x3; 357 else 358 RFValue = (RFValue & (~0x77)); 359 RT30xxWriteRFRegister(pAd, RF_R27, RFValue); 360 } 361 /* end johnli */ 362} 363 364/* 365 ========================================================================== 366 Description: 367 368 Load RF sleep-mode setup 369 370 ========================================================================== 371 */ 372void RT30xxLoadRFSleepModeSetup(struct rt_rtmp_adapter *pAd) 373{ 374 u8 RFValue; 375 u32 MACValue; 376 377#ifdef RTMP_MAC_USB 378 if (!IS_RT3572(pAd)) 379#endif /* RTMP_MAC_USB // */ 380 { 381 /* RF_BLOCK_en. RF R1 register Bit 0 to 0 */ 382 RT30xxReadRFRegister(pAd, RF_R01, &RFValue); 383 RFValue &= (~0x01); 384 RT30xxWriteRFRegister(pAd, RF_R01, RFValue); 385 386 /* VCO_IC, RF R7 register Bit 4 & Bit 5 to 0 */ 387 RT30xxReadRFRegister(pAd, RF_R07, &RFValue); 388 RFValue &= (~0x30); 389 RT30xxWriteRFRegister(pAd, RF_R07, RFValue); 390 391 /* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0 */ 392 RT30xxReadRFRegister(pAd, RF_R09, &RFValue); 393 RFValue &= (~0x0E); 394 RT30xxWriteRFRegister(pAd, RF_R09, RFValue); 395 396 /* RX_CTB_en, RF R21 register Bit 7 to 0 */ 397 RT30xxReadRFRegister(pAd, RF_R21, &RFValue); 398 RFValue &= (~0x80); 399 RT30xxWriteRFRegister(pAd, RF_R21, RFValue); 400 } 401 402 if (IS_RT3090(pAd) || /* IS_RT3090 including RT309x and RT3071/72 */ 403 IS_RT3572(pAd) || 404 (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) { 405#ifdef RTMP_MAC_USB 406 if (!IS_RT3572(pAd)) 407#endif /* RTMP_MAC_USB // */ 408 { 409 RT30xxReadRFRegister(pAd, RF_R27, &RFValue); 410 RFValue |= 0x77; 411 RT30xxWriteRFRegister(pAd, RF_R27, RFValue); 412 } 413 414 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); 415 MACValue |= 0x1D000000; 416 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); 417 } 418} 419 420/* 421 ========================================================================== 422 Description: 423 424 Reverse RF sleep-mode setup 425 426 ========================================================================== 427 */ 428void RT30xxReverseRFSleepModeSetup(struct rt_rtmp_adapter *pAd) 429{ 430 u8 RFValue; 431 u32 MACValue; 432 433#ifdef RTMP_MAC_USB 434 if (!IS_RT3572(pAd)) 435#endif /* RTMP_MAC_USB // */ 436 { 437 /* RF_BLOCK_en, RF R1 register Bit 0 to 1 */ 438 RT30xxReadRFRegister(pAd, RF_R01, &RFValue); 439 RFValue |= 0x01; 440 RT30xxWriteRFRegister(pAd, RF_R01, RFValue); 441 442 /* VCO_IC, RF R7 register Bit 4 & Bit 5 to 1 */ 443 RT30xxReadRFRegister(pAd, RF_R07, &RFValue); 444 RFValue |= 0x20; 445 RT30xxWriteRFRegister(pAd, RF_R07, RFValue); 446 447 /* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1 */ 448 RT30xxReadRFRegister(pAd, RF_R09, &RFValue); 449 RFValue |= 0x0E; 450 RT30xxWriteRFRegister(pAd, RF_R09, RFValue); 451 452 /* RX_CTB_en, RF R21 register Bit 7 to 1 */ 453 RT30xxReadRFRegister(pAd, RF_R21, &RFValue); 454 RFValue |= 0x80; 455 RT30xxWriteRFRegister(pAd, RF_R21, RFValue); 456 } 457 458 if (IS_RT3090(pAd) || /* IS_RT3090 including RT309x and RT3071/72 */ 459 IS_RT3572(pAd) || 460 IS_RT3390(pAd) || 461 (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) { 462#ifdef RTMP_MAC_USB 463 if (!IS_RT3572(pAd)) 464#endif /* RTMP_MAC_USB // */ 465 { 466 RT30xxReadRFRegister(pAd, RF_R27, &RFValue); 467 if ((pAd->MACVersion & 0xffff) < 0x0211) 468 RFValue = (RFValue & (~0x77)) | 0x3; 469 else 470 RFValue = (RFValue & (~0x77)); 471 RT30xxWriteRFRegister(pAd, RF_R27, RFValue); 472 } 473 /* RT3071 version E has fixed this issue */ 474 if ((pAd->NicConfig2.field.DACTestBit == 1) 475 && ((pAd->MACVersion & 0xffff) < 0x0211)) { 476 /* patch tx EVM issue temporarily */ 477 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); 478 MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000); 479 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); 480 } else { 481 RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); 482 MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000); 483 RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); 484 } 485 } 486 487 if (IS_RT3572(pAd)) 488 RT30xxWriteRFRegister(pAd, RF_R08, 0x80); 489} 490 491/* end johnli */ 492 493void RT30xxHaltAction(struct rt_rtmp_adapter *pAd) 494{ 495 u32 TxPinCfg = 0x00050F0F; 496 497 /* */ 498 /* Turn off LNA_PE or TRSW_POL */ 499 /* */ 500 if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)) { 501 if ((IS_RT3071(pAd) || IS_RT3572(pAd)) 502#ifdef RTMP_EFUSE_SUPPORT 503 && (pAd->bUseEfuse) 504#endif /* RTMP_EFUSE_SUPPORT // */ 505 ) { 506 TxPinCfg &= 0xFFFBF0F0; /* bit18 off */ 507 } else { 508 TxPinCfg &= 0xFFFFF0F0; 509 } 510 511 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); 512 } 513} 514 515#endif /* RT30xx // */ 516