⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtl8306.c.svn-base

📁 realtek的8186芯片ADSL路由AP源代码
💻 SVN-BASE
字号:
/*
 *
 * rtl8306.c : Configure RTL8306 switch via GPIO interface
 *
 * History: 
 *  2007/10/22  SH  Merge Kevin's patch for TECOM LED Issue
 *
 */
#include "gpio.h"

#define RTL_W32(reg, value)			(*(volatile u32*)(ETHBASE+reg)) = (u32)value
#define RTL_W16(reg, value)			(*(volatile u16*)(ETHBASE+reg)) = (u16)value
#define RTL_W8(reg, value)			(*(volatile u8*)(ETHBASE+reg)) = (u8)value
#define RTL_R32(reg)				(*(volatile u32*)(ETHBASE+reg))
#define RTL_R16(reg)				(*(volatile u16*)(ETHBASE+reg))
#define RTL_R8(reg)					(*(volatile u8*)(ETHBASE+reg))


#define REG32GPIO(reg)	*(volatile unsigned int*)(0xb9c01000+reg)
#define GPIO_SHIFT(x)	((x<=7?x:(x-8))+16)

#define PABCDIR		(GPIO_MDC<=7?0x010:0x000)
#define PABCDAT		(GPIO_MDC<=7?0x014:0x004)

void _rtl8305s_smiZBit(void) {
	unsigned int i;
	//REG32(PABCDIR) = (REG32(PABCDIR)& 0x3FFFFFFF) | 0x80000000;
	REG32GPIO(PABCDIR)= (REG32GPIO(PABCDIR)& ~((1<<GPIO_SHIFT(GPIO_MDC))|(1<<GPIO_SHIFT(GPIO_MDIO))))
	 | (1<<GPIO_SHIFT(GPIO_MDC));
	//REG32(PABCDAT) = (REG32(PABCDAT) & 0x3FFFFFFF);
	//REG32GPIO(PABCDAT) = (REG32GPIO(PABCDAT) & 0xFFe7FFFF);
	gpioClear(GPIO_MDC);//GPIO_PA4
	gpioClear(GPIO_MDIO);//GPIO_PA3
	for(i=0; i<25; i++);
}

/* Generate  1 -> 0 transition and sampled at 1 to 0 transition time */
void _rtl8305s_smiReadBit(unsigned char * data) {
	unsigned int i;
	//REG32(PABCDIR) = (REG32(PABCDIR)& 0x3FFFFFFF) | 0x80000000;
	REG32GPIO(PABCDIR)= (REG32GPIO(PABCDIR)& ~((1<<GPIO_SHIFT(GPIO_MDC))|(1<<GPIO_SHIFT(GPIO_MDIO))))
	 | (1<<GPIO_SHIFT(GPIO_MDC));
	//REG32(PABCDAT) = (REG32(PABCDAT) & 0x3FFFFFFF) | 0x80000000;
	//REG32GPIO(PABCDAT) = (REG32GPIO(PABCDAT) & 0xFFe7FFFF) | 0x00100000;
	gpioSet(GPIO_MDC); //GPIO_PA4
	gpioClear(GPIO_MDIO); //GPIO_PA3
	for(i=0; i<25; i++);
	//REG32(PABCDAT) = (REG32(PABCDAT) & 0x3FFFFFFF);
	//REG32GPIO(PABCDAT) = (REG32GPIO(PABCDAT) & 0xFFe7FFFF);	
	gpioClear(GPIO_MDC);//GPIO_PA4
	gpioClear(GPIO_MDIO);//GPIO_PA3	
	//*data = (REG32(PABCDAT) & 0x40000000)?1:0;
	*data = (REG32GPIO(PABCDAT) & (1<<GPIO_SHIFT(GPIO_MDIO)))?1:0;
}

/* Generate  0 -> 1 transition and put data ready during 0 to 1 whole period */
void _rtl8305s_smiWriteBit(unsigned char data) {
	unsigned int i;
	
	//REG32(PABCDIR) = REG32(PABCDIR) | 0xC0000000;
	REG32GPIO(PABCDIR) = REG32GPIO(PABCDIR) | (1<<GPIO_SHIFT(GPIO_MDC)) | (1<<GPIO_SHIFT(GPIO_MDIO));
	if(data) {/* Write 1 */
		//REG32(PABCDAT) = (REG32(PABCDAT) & 0x3FFFFFFF) | 0x40000000;
		//REG32GPIO(PABCDAT) = (REG32GPIO(PABCDAT) & 0xFFe7FFFF) | 0x00080000;
		gpioClear(GPIO_MDC);//GPIO_PA4
		gpioSet(GPIO_MDIO);//GPIO_PA3

		for(i=0; i<25; i++);
		//REG32(PABCDAT) = (REG32(PABCDAT) & 0x3FFFFFFF) | 0xC0000000;
		//REG32GPIO(PABCDAT) = (REG32GPIO(PABCDAT) & 0xFFe7FFFF) | 0x00180000;
		gpioSet(GPIO_MDC);//GPIO_PA4
		gpioSet(GPIO_MDIO);//GPIO_PA3
	} else {
		//REG32(PABCDAT) = (REG32(PABCDAT) & 0x3FFFFFFF);
		//REG32GPIO(PABCDAT) = (REG32GPIO(PABCDAT) & 0xFFe7FFFF);
		gpioClear(GPIO_MDC);//GPIO_PA4
		gpioClear(GPIO_MDIO);//GPIO_PA3
		for(i=0; i<25; i++);
		//REG32(PABCDAT) = (REG32(PABCDAT) & 0x3FFFFFFF) | 0x80000000;
		//REG32GPIO(PABCDAT) = (REG32GPIO(PABCDAT) & 0xFFe7FFFF) | 0x00100000;
		gpioSet(GPIO_MDC);//GPIO_PA4
		gpioClear(GPIO_MDIO);//GPIO_PA3
	}
}

void rtl8305s_smiRead(unsigned char phyad, unsigned char regad, unsigned short * data) {
	int i;
	unsigned char readBit;

	/* Configure port A pin 6, 7 to be GPIO and disable interrupts of these two pins */
	//REG32(PABCCNR) = REG32(PABCCNR) & 0x3FFFFFFF;
	//REG32(PABIMR) = REG32(PABIMR) & 0xFFFFFFF;
	/* 32 continuous 1 as preamble*/
	for(i=0; i<32; i++)
		_rtl8305s_smiWriteBit(1);
	/* ST: Start of Frame, <01>*/
	_rtl8305s_smiWriteBit(0);
	_rtl8305s_smiWriteBit(1);
	/* OP: Operation code, read is <10> */
	_rtl8305s_smiWriteBit(1);
	_rtl8305s_smiWriteBit(0);
	/* PHY Address */
	for(i=4; i>=0; i--) 
		_rtl8305s_smiWriteBit((phyad>>i)&0x1);
	/* Register Address */
	for(i=4; i>=0; i--) 
		_rtl8305s_smiWriteBit((regad>>i)&0x1);
	/* TA: Turnaround <z0> */
	_rtl8305s_smiZBit();
	_rtl8305s_smiReadBit(&readBit);
	/* Data */
	*data = 0;
	for(i=15; i>=0; i--) {
		_rtl8305s_smiReadBit(&readBit);
		*data = (*data<<1) | readBit;
	}
	_rtl8305s_smiZBit();
}

void rtl8305s_smiWrite(unsigned char phyad, unsigned char regad, unsigned short data) {
	int i;

	/* Configure port A pin 6, 7 to be GPIO and disable interrupts of these two pins */
	//REG32(PABCCNR) = REG32(PABCCNR) & 0x3FFFFFFF;
	//REG32(PABIMR) = REG32(PABIMR) & 0xFFFFFFF;
	/* 32 continuous 1 as preamble*/
	for(i=0; i<32; i++)
		_rtl8305s_smiWriteBit(1);
	/* ST: Start of Frame, <01>*/
	_rtl8305s_smiWriteBit(0);
	_rtl8305s_smiWriteBit(1);
	/* OP: Operation code, write is <01> */
	_rtl8305s_smiWriteBit(0);
	_rtl8305s_smiWriteBit(1);
	/* PHY Address */
	for(i=4; i>=0; i--) 
		_rtl8305s_smiWriteBit((phyad>>i)&0x1);
	/* Register Address */
	for(i=4; i>=0; i--) 
		_rtl8305s_smiWriteBit((regad>>i)&0x1);
	/* TA: Turnaround <10> */
	_rtl8305s_smiWriteBit(1);
	_rtl8305s_smiWriteBit(0);
	/* Data */
	for(i=15; i>=0; i--) 
		_rtl8305s_smiWriteBit((data>>i)&0x1);
	_rtl8305s_smiZBit();
}



void miiar_write(unsigned char phyaddr,unsigned char regaddr,unsigned short value){	
	rtl8305s_smiWrite(phyaddr,regaddr,value);
}

void miiar_read(unsigned char phyaddr,unsigned char regaddr,unsigned short *value){
	
	rtl8305s_smiRead(phyaddr,regaddr,value);
}

/*
	Enable_8306: Using GPIO to simulate MDC/MDIO to config rtl8306
	modification by Kevin Chung on 2007/09/19
        Please refer to loader/internal.doc 
 */              
void Enable_8306(void)
{		
    unsigned short val=0,HW_ID=0;    
    
    miiar_read(4, 30, &val);    
    switch(val)
    {
	case 0x5826 : 
	case 0x5982 :
    			printf("Connected RTL8305SC. \n\r");   
			break;
	case 0x5988 :
			printf("Connected RTL8306. \n\r");   
    			miiar_read(0, 16, &val);
				val|=0x0800;			//disable read protection
			miiar_write(0, 16, val);
    			miiar_read(4, 26, &val);		//
			if (val)				//
			{
    				miiar_read(0, 19, &val);
					val|=0x3000;		//
				miiar_write(0, 19, val);  
				printf("AC:\n"); 
			}else					//
			{
				val=0x56;			
				miiar_write(2, 26, val);        // 
				printf("AB:\n"); 
                                miiar_read(0, 19, &val);
			}   
//printf("1. val= %x  HW_ID = %x\n", val, HW_ID);
			if(val&0x400)				//check Hardware ID
				HW_ID|=(1<< 4);     
			miiar_read(0, 20,&val);		//check Hardware ID
//printf("2. val= %x  HW_ID = %x\n", val, HW_ID);
			if(val&=0x0f0)
				HW_ID|=(val >> 4);
//printf("3. val= %x  HW_ID = %x\n", val, HW_ID);
			break;
	default :
			printf("not detect external phy ,ID -->0x%x\n",val);   
    }
    switch(HW_ID)
    {
	case 0 :
		break;
	case 0x17 :
    		printf("Enable RTL8306 phy4 (MII_0) Hardware ID :10111\n\r");         
		break;
	case 0x0a :
    		printf("Enable RTL8306 phy6 (MII_1) Hardware ID :01010\n\r");
    miiar_read(6, 22, &val);    
    val|= (1<< 15);  // Link up port 5
    miiar_write(6, 22, val);
		printf("PHY6 Register 22 :0x%x\n",val);      
		break;
	default :
    		printf("RTL8306 configuration strapping failure ,H/W ID :0x%x\n",HW_ID);
    }	
}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -