diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 19:54:53 (GMT) |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-22 20:01:40 (GMT) |
commit | ae19ffbadc1b2100285a5b5b3d0a4e0a11390904 (patch) | |
tree | 3c2086ab67398a019089a47ca3f362a4bc6db74f /drivers/staging/rt3090/common/ee_prom.c | |
parent | 34e84f39a27d059a3e6ec6e8b94aafa702e6f220 (diff) | |
parent | 9173a8ef24a6b1b8031507b35b8ffe5f85a87692 (diff) | |
download | linux-fsl-qoriq-ae19ffbadc1b2100285a5b5b3d0a4e0a11390904.tar.xz |
Merge branch 'master' into for-linus
Diffstat (limited to 'drivers/staging/rt3090/common/ee_prom.c')
-rw-r--r-- | drivers/staging/rt3090/common/ee_prom.c | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/drivers/staging/rt3090/common/ee_prom.c b/drivers/staging/rt3090/common/ee_prom.c new file mode 100644 index 0000000..051cfde --- /dev/null +++ b/drivers/staging/rt3090/common/ee_prom.c @@ -0,0 +1,308 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * 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., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + ee_prom.c + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#include "../rt_config.h" + + +// IRQL = PASSIVE_LEVEL +static inline VOID RaiseClock( + IN PRTMP_ADAPTER pAd, + IN UINT32 *x) +{ + *x = *x | EESK; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); + RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition +} + +// IRQL = PASSIVE_LEVEL +static inline VOID LowerClock( + IN PRTMP_ADAPTER pAd, + IN UINT32 *x) +{ + *x = *x & ~EESK; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); + RTMPusecDelay(1); +} + +// IRQL = PASSIVE_LEVEL +static inline USHORT ShiftInBits( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x,i; + USHORT data=0; + + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + x &= ~( EEDO | EEDI); + + for(i=0; i<16; i++) + { + data = data << 1; + RaiseClock(pAd, &x); + + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + LowerClock(pAd, &x); //prevent read failed + + x &= ~(EEDI); + if(x & EEDO) + data |= 1; + } + + return data; +} + + +// IRQL = PASSIVE_LEVEL +static inline VOID ShiftOutBits( + IN PRTMP_ADAPTER pAd, + IN USHORT data, + IN USHORT count) +{ + UINT32 x,mask; + + mask = 0x01 << (count - 1); + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + x &= ~(EEDO | EEDI); + + do + { + x &= ~EEDI; + if(data & mask) x |= EEDI; + + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + + mask = mask >> 1; + } while(mask); + + x &= ~EEDI; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); +} + + +// IRQL = PASSIVE_LEVEL +static inline VOID EEpromCleanup( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x; + + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + x &= ~(EECS | EEDI); + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + RaiseClock(pAd, &x); + LowerClock(pAd, &x); +} + + +static inline VOID EWEN( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x; + + // reset bits and set EECS + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + // kick a pulse + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + + // output the read_opcode and six pulse in that order + ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5); + ShiftOutBits(pAd, 0, 6); + + EEpromCleanup(pAd); +} + + +static inline VOID EWDS( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x; + + // reset bits and set EECS + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + // kick a pulse + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + + // output the read_opcode and six pulse in that order + ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5); + ShiftOutBits(pAd, 0, 6); + + EEpromCleanup(pAd); +} + + +// IRQL = PASSIVE_LEVEL +int rtmp_ee_prom_read16( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT USHORT *pValue) +{ + UINT32 x; + USHORT data; + +#ifdef RT30xx +#ifdef ANT_DIVERSITY_SUPPORT + if (pAd->NicConfig2.field.AntDiversity) + { + pAd->EepromAccess = TRUE; + } +#endif // ANT_DIVERSITY_SUPPORT // +#endif // RT30xx // + + Offset /= 2; + // reset bits and set EECS + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + // patch can not access e-Fuse issue + if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) + { + // kick a pulse + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + } + + // output the read_opcode and register number in that order + ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3); + ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum); + + // Now read the data (16 bits) in from the selected EEPROM word + data = ShiftInBits(pAd); + + EEpromCleanup(pAd); + +#ifdef RT30xx +#ifdef ANT_DIVERSITY_SUPPORT + // Antenna and EEPROM access are both using EESK pin, + // Therefor we should avoid accessing EESK at the same time + // Then restore antenna after EEPROM access + if ((pAd->NicConfig2.field.AntDiversity)/* || (pAd->RfIcType == RFIC_3020)*/) + { + pAd->EepromAccess = FALSE; + AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); + } +#endif // ANT_DIVERSITY_SUPPORT // +#endif // RT30xx // + + *pValue = data; + + return NDIS_STATUS_SUCCESS; +} + + +int rtmp_ee_prom_write16( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Data) +{ + UINT32 x; + +#ifdef RT30xx +#ifdef ANT_DIVERSITY_SUPPORT + if (pAd->NicConfig2.field.AntDiversity) + { + pAd->EepromAccess = TRUE; + } +#endif // ANT_DIVERSITY_SUPPORT // +#endif // RT30xx // + + Offset /= 2; + + EWEN(pAd); + + // reset bits and set EECS + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + // patch can not access e-Fuse issue + if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) + { + // kick a pulse + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + } + + // output the read_opcode ,register number and data in that order + ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3); + ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum); + ShiftOutBits(pAd, Data, 16); // 16-bit access + + // read DO status + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + EEpromCleanup(pAd); + + RTMPusecDelay(10000); //delay for twp(MAX)=10ms + + EWDS(pAd); + + EEpromCleanup(pAd); + +#ifdef RT30xx +#ifdef ANT_DIVERSITY_SUPPORT + // Antenna and EEPROM access are both using EESK pin, + // Therefor we should avoid accessing EESK at the same time + // Then restore antenna after EEPROM access + if ((pAd->NicConfig2.field.AntDiversity) /*|| (pAd->RfIcType == RFIC_3020)*/) + { + pAd->EepromAccess = FALSE; + AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); + } +#endif // ANT_DIVERSITY_SUPPORT // +#endif // RT30xx // + + return NDIS_STATUS_SUCCESS; + +} |