📄 rtl8306.c.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 + -