1 /*- 2 * SPDX-License-Identifier: ISC 3 * 4 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 5 * Copyright (c) 2002-2008 Atheros Communications, Inc. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 #include "opt_ah.h" 20 21 #ifdef AH_SUPPORT_AR5312 22 23 #include "ah.h" 24 #include "ah_internal.h" 25 #include "ah_devid.h" 26 27 #include "ar5312/ar5312.h" 28 #include "ar5312/ar5312reg.h" 29 #include "ar5312/ar5312phy.h" 30 31 #define AR_NUM_GPIO 6 /* 6 GPIO pins */ 32 #define AR_GPIOD_MASK 0x0000002F /* GPIO data reg r/w mask */ 33 34 /* 35 * Change the LED blinking pattern to correspond to the connectivity 36 */ 37 void 38 ar5312SetLedState(struct ath_hal *ah, HAL_LED_STATE state) 39 { 40 uint32_t val; 41 uint32_t resOffset = (AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh)); 42 if(IS_2316(ah)) return; /* not yet */ 43 val = SM(AR5312_PCICFG_LEDSEL0, AR5312_PCICFG_LEDSEL) | 44 SM(AR5312_PCICFG_LEDMOD0, AR5312_PCICFG_LEDMODE) | 45 2; 46 OS_REG_WRITE(ah, resOffset+AR5312_PCICFG, 47 (OS_REG_READ(ah, AR5312_PCICFG) &~ 48 (AR5312_PCICFG_LEDSEL | AR5312_PCICFG_LEDMODE | 49 AR5312_PCICFG_LEDSBR)) 50 | val); 51 } 52 53 /* 54 * Detect if our wireless mac is present. 55 */ 56 HAL_BOOL 57 ar5312DetectCardPresent(struct ath_hal *ah) 58 { 59 uint16_t macVersion, macRev; 60 uint32_t v; 61 62 /* 63 * Read the Silicon Revision register and compare that 64 * to what we read at attach time. If the same, we say 65 * a card/device is present. 66 */ 67 #if (AH_SUPPORT_2316 || AH_SUPPORT_2317) 68 if(IS_5315(ah)) 69 { 70 v = (OS_REG_READ(ah, 71 (AR5315_RSTIMER_BASE-((uint32_t) ah->ah_sh)) + AR5315_WREV)) 72 & AR_SREV_ID; 73 macVersion = v >> AR_SREV_ID_S; 74 macRev = v & AR_SREV_REVISION; 75 return (AH_PRIVATE(ah)->ah_macVersion == macVersion && 76 AH_PRIVATE(ah)->ah_macRev == macRev); 77 } 78 else 79 #endif 80 { 81 v = (OS_REG_READ(ah, 82 (AR5312_RSTIMER_BASE-((uint32_t) ah->ah_sh)) + AR5312_WREV)) 83 & AR_SREV_ID; 84 macVersion = v >> AR_SREV_ID_S; 85 macRev = v & AR_SREV_REVISION; 86 return (AH_PRIVATE(ah)->ah_macVersion == macVersion && 87 AH_PRIVATE(ah)->ah_macRev == macRev); 88 } 89 } 90 91 /* 92 * If 32KHz clock exists, use it to lower power consumption during sleep 93 * 94 * Note: If clock is set to 32 KHz, delays on accessing certain 95 * baseband registers (27-31, 124-127) are required. 96 */ 97 void 98 ar5312SetupClock(struct ath_hal *ah, HAL_OPMODE opmode) 99 { 100 if (ar5212Use32KHzclock(ah, opmode)) { 101 /* 102 * Enable clocks to be turned OFF in BB during sleep 103 * and also enable turning OFF 32MHz/40MHz Refclk 104 * from A2. 105 */ 106 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f); 107 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x0d); 108 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0c); 109 OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x03); 110 OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0x05); 111 OS_REG_WRITE(ah, AR_PHY_REFCLKPD, 112 IS_RAD5112_ANY(ah) ? 0x14 : 0x18); 113 114 OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, 1); 115 OS_REG_WRITE(ah, AR_TSF_PARM, 61); /* 32 KHz TSF incr */ 116 117 } else { 118 OS_REG_WRITE(ah, AR_TSF_PARM, 1); /* 32 MHz TSF incr */ 119 OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, 120 IS_RAD5112_ANY(ah) ? 39 : 31); 121 122 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f); 123 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x7f); 124 125 if (IS_5312_2_X(ah)) { 126 /* Set ADC/DAC select values */ 127 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x04); 128 } else { 129 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e); 130 OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c); 131 OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff); 132 OS_REG_WRITE(ah, AR_PHY_REFCLKPD, 133 IS_RAD5112_ANY(ah) ? 0x14 : 0x18); 134 } 135 } 136 } 137 138 /* 139 * If 32KHz clock exists, turn it off and turn back on the 32Mhz 140 */ 141 void 142 ar5312RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode) 143 { 144 if (ar5212Use32KHzclock(ah, opmode)) { 145 /* # Set sleep clock rate back to 32 MHz. */ 146 OS_REG_WRITE(ah, AR_TSF_PARM, 1); /* 32 MHz TSF incr */ 147 OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, 148 IS_RAD5112_ANY(ah) ? 39 : 31); 149 150 /* 151 * Restore BB registers to power-on defaults 152 */ 153 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f); 154 OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x7f); 155 if (IS_5312_2_X(ah)) { 156 /* Set ADC/DAC select values */ 157 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x04); 158 } else { 159 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e); 160 OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c); 161 OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff); 162 OS_REG_WRITE(ah, AR_PHY_REFCLKPD, 163 IS_RAD5112_ANY(ah) ? 0x14 : 0x18); 164 } 165 } 166 } 167 168 #endif /* AH_SUPPORT_AR5312 */ 169