aboutsummaryrefslogblamecommitdiffstats
path: root/drivers/staging/rt2860/common/ee_prom.c
blob: 2083740a844bb29cce3e9927f37cfd235cc46197 (plain) (tree)




































                                                                                

                                
                          
                                                                   


                                             
                                                                              

 
                          
                                                                   





                                             
                          
                                                          
 

                     


                                            
                            
 
                                  



                                                    
                                                                

                             

                                  




                    
                          
                                                            
                                                    
 
                    





                                            



                                  
 
                                                    
 

                                    
 

                                 




                                            
                          
                                                             
 
              









                                            
                                                    
 
              
 
                                     




                                            
                          


                            
                                                                





                                                 
                                                    
 
              
 
                                     




                                            
                          


                            
                                                                





                                                 
                          
                                                    
                                                 
 

                 

                    
                                     




                                            
                                               
                                                                    
                                  


                                    
                                                                      


                                                         
                                                                          



                                



                                   
/*
 *************************************************************************
 * 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(struct rt_rtmp_adapter *pAd, u32 * 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(struct rt_rtmp_adapter *pAd, u32 * x)
{
	*x = *x & ~EESK;
	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
	RTMPusecDelay(1);
}

/* IRQL = PASSIVE_LEVEL */
static inline u16 ShiftInBits(struct rt_rtmp_adapter *pAd)
{
	u32 x, i;
	u16 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(struct rt_rtmp_adapter *pAd,
				u16 data, u16 count)
{
	u32 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(struct rt_rtmp_adapter *pAd)
{
	u32 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(struct rt_rtmp_adapter *pAd)
{
	u32 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(struct rt_rtmp_adapter *pAd)
{
	u32 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(struct rt_rtmp_adapter *pAd,
			u16 Offset, u16 * pValue)
{
	u32 x;
	u16 data;

	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);

	*pValue = data;

	return NDIS_STATUS_SUCCESS;
}