免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4509 | 回复: 6
打印 上一主题 下一主题

谁有RTL8305x的驱动程序,任意平台的都行? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-03-23 15:19 |只看该作者 |倒序浏览
那位大写有RTL8305sb或者RTL8305sc的驱动程序,无论哪个操作系统都行,我写了一个Linux下的该驱动,编译加载的时候读了一个寄存器,老是不对!

多谢了!

论坛徽章:
0
2 [报告]
发表于 2007-03-28 09:41 |只看该作者

哈哈,我已经写出来了!

经过一周多的努力,整个驱动程序已经调试完毕!大家需要的话我可以铁上来?

论坛徽章:
0
3 [报告]
发表于 2007-03-28 22:44 |只看该作者
恩,
需要的
全部贴上来

论坛徽章:
0
4 [报告]
发表于 2007-03-29 13:11 |只看该作者

好的,与大家共享!

/*网友注意 :  PC25 for MDIO in the 8271 of 826x; PC22 for MDC in the 8271 of 826x ;IMMAP_BASE请根据自己的硬件进行修改 */
#define TRUE         1
#define FALSE         0
#define ON                1
#define OFF                0

/*------------------------*/
/* Fundamental Data Types */
/*------------------------*/

typedef        char                           BYTE;
typedef unsigned char         UBYTE;       
typedef        short                           HWORD;       
typedef        unsigned short        UHWORD;       
typedef        long                           WORD;       
typedef unsigned long         UWORD;       
typedef unsigned char         BOOL;       

typedef        volatile char                           VBYTE;
typedef volatile unsigned char         VUBYTE;       
typedef        volatile short                           VHWORD;       
typedef        volatile unsigned short        VUHWORD;       
typedef        volatile long                           VWORD;       
typedef volatile unsigned long         VUWORD;       
typedef volatile unsigned char         VBOOL;       
/* CPU base address defination */
#define IMMAP_BASE  0xf0000000
#define IMMAP_LENTH 0x60000


/* The major device number. We can't rely on dynamic
* registration any more, because ioctls need to know
* it. */
#define MAJOR_NUM         100
#define        DEVICE_NAME         "rtl8305"

/*RTL8305 relevant information */
#define MDIO_PIN_MASK 0x00000040  /* PC25 for MDIO in the 8271 of 826x */
#define MDC_PIN_MASK  0x00000200  /* PC22 for MDC in the 8271 of 826x */

#ifndef __KERNEL__
        #define __KERNEL__
#endif
#ifndef MODULE
        #define MODULE
#endif

#ifdef CONFIG_SMP
        # define __SMP__
#endif

#include <linux/kernel.h>
#include <linux/module.h> /*for MOD_DEC_USE_COUNT ,etc.*/
#include <linux/init.h>                /* for module_init */
#include <asm/errno.h>
#include <asm/immap_8260.h>
#include <linux/fs.h>                /*character device definitions*/
#include <linux/wrapper.h>        /*for register_chrdev and unregister_chrdev
                                wrapper for compatibility with future versions*/
#include <asm/uaccess.h>          /*for get_user and put_user*/
#include <sys/mman.h>

#if CONFIG_MODVERSIONS==1
# include <linux/modversions.h>
#endif


#ifndef KERNEL_VERSION
        # define KERNEL_VERSION(a,b,c)        ((a)*65536+(b)*256+(c))
#endif

/***********************/
/* Global Declarations */
/***********************/
        volatile immap_t *IMM  = (immap_t *)(IMMAP_BASE );  /*IMMAP_BASE; Internal Memory Map base pointer (0x30026000)*/
       
static int         Device_Open = 0;

volatile void Z0_Send( void)  //"Z0" during reading
{int j;
        //z0 =z0
        IMM->im_ioport.iop_pdatc &= ~MDC_PIN_MASK;  /* clock fail */
        IMM->im_ioport.iop_pdirc &= ~MDIO_PIN_MASK;  /* pc25=Input low */
            for (j=0; j<10; j++);
        IMM->im_ioport.iop_pdatc |= MDC_PIN_MASK;  /* clock rise */

        IMM->im_ioport.iop_pdirc |= MDIO_PIN_MASK;  /* pc25=1utput high */
        IMM->im_ioport.iop_pdatc &= ~MDC_PIN_MASK;  /* clock fail */
        IMM->im_ioport.iop_pdatc &= ~MDIO_PIN_MASK;  /* IO low */
            for (j=0; j<10; j++);
        IMM->im_ioport.iop_pdatc |= MDC_PIN_MASK;  /* clock rise */
} /*end Z0_Send*/

volatile void Idle_Send(void)  //z* at end of frame
{
        //idle
        IMM->im_ioport.iop_pdirc |= MDIO_PIN_MASK;  /* pc25=1utput high */
        IMM->im_ioport.iop_pdatc &= ~MDIO_PIN_MASK;  /* IO low */
        IMM->im_ioport.iop_pdatc |= MDC_PIN_MASK;  /* clock rise */
        IMM->im_ioport.iop_pdatc &= ~MDC_PIN_MASK;  /* clock fail */
} /*end Idle_Send*/

volatile void MdioSend( UWORD txF, int size)
{
  UWORD dmask;
  int i,j;    /* index */

  dmask = 1 << (size-1);  /* msbit out first */

  for ( i = 0; i < size; i++ )
  {  /* for "size" bits */
    IMM->im_ioport.iop_pdatc &= ~MDC_PIN_MASK;  /* clock fall */
    if ( txF & dmask )
    {  /* output data bit high */
      IMM->im_ioport.iop_pdatc |=  MDIO_PIN_MASK;
    }
    else
    {  /* output data bit low, >400ns */
      IMM->im_ioport.iop_pdatc &= ~MDIO_PIN_MASK;
    }
    for (j=0; j<10; j++);
    IMM->im_ioport.iop_pdatc |= MDC_PIN_MASK;  /* clock rise */   
    for (j=0; j<10; j++);

    txF = (UWORD)(txF << 1);  /* >160ns */
  }

} /* end MdioSend */
volatile UWORD MdioReceive(int size)
{
  int i,j;
  UWORD rxF=0x0000;  /* index */

  IMM->im_ioport.iop_pdirc &= ~MDIO_PIN_MASK;  /* pc25=0:input */

  for ( i = 0; i < size; i++ )
  {  /* 16 bits */
    IMM->im_ioport.iop_pdatc |= MDC_PIN_MASK;  /* clock rise */
     if ( IMM->im_ioport.iop_pdatc & MDIO_PIN_MASK )
     {  /* if read in a high bit */
        rxF = ( (UHWORD)(rxF << 1) | 1 );         /* shift in a one */
     }
     else
     {  /* if read in a low bit */
        rxF = ( (UHWORD)(rxF << 1) & ~(UHWORD)1 );  /* shift in a zero */
     }
    for (j=0; j<10; j++);
    IMM->im_ioport.iop_pdatc &= ~MDC_PIN_MASK;  /* clock fall */           
    for (j=0; j<10; j++);
     
  }  /* end of for loop        */
  
  return (rxF);
} /* end MdioReceive */   

/*Prototypes*/
static int rtl8305_open(struct inode *inode, struct file *file);
static int rtl8305_release(struct inode *inode, struct file *file);
static int rtl8305_read(struct file *file,char * buffer, size_t length, loff_t * offset);
static int rtl8305_write(struct file *file,const char * buffer, size_t length, loff_t * offset);
struct file_operations rtl8305_ops = {
        .read=rtl8305_read,
        .write=rtl8305_write,
        .open=rtl8305_open,
        .release=rtl8305_release
};
static int rtl8305_open(struct inode *inode, struct file *file)
{
  UWORD rxF;
  //int fd;
  if (Device_Open) return -1;
  
                        /*To initialize the PortC registers*/
      IMM->im_ioport.iop_podrc &= ~MDIO_PIN_MASK;  //0:normal
      IMM->im_ioport.iop_podrc &= ~MDC_PIN_MASK;
      IMM->im_ioport.iop_pdirc |= MDC_PIN_MASK;       //  1C22 for output
      IMM->im_ioport.iop_pdirc |= MDIO_PIN_MASK;     //1C25 for output
      IMM->im_ioport.iop_pparc &= ~(0x00000240);   //0C22,PC25 as a general purpose IO
  /*read a Rtl8305 register for test*/
        MdioSend (0xffffffff,32);  //preamble
        MdioSend (0x01,2); //start
        MdioSend (0x02,2); //read
        MdioSend (0x00,5); //PHY0
        MdioSend (0x01,5); //PHY0-Reg1
        Z0_Send(); //z0 =z0
        //read from rtl8305
        rxF=MdioReceive(16); //PHY0-1=0x7849
        Idle_Send();          //idle

        printk(KERN_ALERT"\nIn open()HY0-1(0x7849) =ox%lx\n",rxF);
  
   Device_Open++;
        MOD_INC_USE_COUNT;   


  printk(KERN_ALERT"Device Open(%p,%p)\n",inode,file);
  return 0 ;
} /*end rtl8305_open*/


static int rtl8305_read(struct file *file,char * buffer, size_t length, loff_t * offset)
{
  char rxBuf[2];

        rxBuf[0]=* (buffer++);
        rxBuf[1]=* buffer;

        MdioSend (0x01,2); //start
        MdioSend (0x02,2); //read
        MdioSend (rxBuf[0],5); //PHY0
        MdioSend (rxBuf[1],5); //PHY0-Reg1
        Z0_Send();        //z0 =z0
        //read from rtl8305
        rxBuf[0]=MdioReceive(; //PHYx-x=high 8 bits
        rxBuf[1]=MdioReceive(; //PHYx-x=low 8 bits
        Idle_Send();                //idle

        put_user(rxBuf[0], (--buffer));
        put_user(rxBuf[1], (++buffer));
                                        // printk(KERN_ALERT"register of RTL8305 =ox%x.%x \n",rxBuf[0],rxBuf[1]);

  return (2);
} /*end rtl8305_read*/
static int rtl8305_write(struct file *file,const char * buffer, size_t length, loff_t * offset)
{
  char rxBuf[4];

        rxBuf[0]=* (buffer++);
        rxBuf[1]=* (buffer++);
        rxBuf[3]=* (buffer++);
        rxBuf[4]=* (buffer);
        buffer--;buffer--;buffer--;
        MdioSend (0x01,2); //start
        MdioSend (0x01,2); //read
        MdioSend (rxBuf[0],5); //PHYx
        MdioSend (rxBuf[1],5); //Reg x
        MdioSend (0x02,2); //write 10 ,turn around
        //write to rtl8305
        MdioSend (rxBuf[2],; //high 8 bits
        MdioSend (rxBuf[3],; //low 8 bits
        Idle_Send();                //idle

        //        printk( KERN_ALERT"\nWriting PHY[%d]_Reg[%d]=ox%x.%x successful.\n",rxBuf[0],rxBuf[1],rxBuf[3],rxBuf[4] );

  return (4);
} /*end rtl8305_write*/

static int rtl8305_release(struct inode *inode, struct file *file)
{
  printk(KERN_ALERT"Rtl8305 device_release(%p,%p)\n",inode,file);

  /* We're now ready for our next caller */
  Device_Open --;
        MOD_DEC_USE_COUNT;
  return 0;
} /*end rtl8305_release*/
       
/* Initialize the module - Register the character device
*/
static int __init rtl8305_module_init( void )
{ int ret_val;
  
  /* Register the character device (atleast try) */
  ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &rtl8305_ops);

  /* Negative values signify an error */
  if (ret_val < 0) {
    printk ("%s failed with %d\n",
            "Sorry, registering the Rtl8305 device ", ret_val);

    return ret_val;
  }

  printk ("%s The major device number is %d.\n",
          "Rtl8305 registeration is a success",    MAJOR_NUM);
  printk ("mknod %s c %d 0\n", DEVICE_NAME,MAJOR_NUM);
  
  return 0;
} /*end rtl8305_module_init*/

/* Cleanup - unregister the appropriate file from /proc */
static void __exit rtl8305_cleanup_module(void)
{
  int ret;
  
  /* Unregister the device */
  ret = unregister_chrdev(MAJOR_NUM, DEVICE_NAME);

  /* If there's an error, report it */
  if (ret < 0)
    printk(KERN_ALERT"Error in module_unregister_chrdev: %d\n", ret);
  printk(KERN_ALERT"in module_unregister_chrdev: %d\n", ret);
} /*end rtl8305_cleanup_module*/

module_init(rtl8305_module_init);
module_exit(rtl8305_cleanup_module);

MODULE_LICENSE("GPL";
MODULE_AUTHOR("by Orien Kan";
MODULE_DESCRIPTION("Rtl8305 driver";

论坛徽章:
0
5 [报告]
发表于 2007-03-29 13:13 |只看该作者

一个简单的测试程序

#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>   /*Luck of the three line,an Oops error will be appeared*/

#include <stdio.h>
#include <fcntl.h>                     /*for O_RDWR*/

#include "./MPC8260.h"       /* IMM definitions and declarations */
#define MAJOR_NUM         100
#define        DEVICE_NAME         "rtl8305_dev"

int main(void){
        int test8305,ret;
        char rxF[4];
  printf("\n");

        test8305=open("/dev/rtl8305",O_RDWR);
        if (test8305==(-1) )
                {
                    printf("RTL8305 opened fail! \n");
                return -1;
                }
                                //        printf("RTL8305 open  test8305=%d \n",test8305);  /*test8305=3 I cannot understand it*/
       
        rxF[0]=0x00 ;
        rxF[1]=0x00 ;
  ret=read(test8305, rxF, 2);
        printf("In main:register0_0=ox%x %x \n",rxF[0],rxF[1]);
       
       
        /*PHY0-0=0x8300 : Force model/10M/Full /reset/restart Negotiation*/
        rxF[0]=0x00 ;
        rxF[1]=0x00 ;
        rxF[2]=0x83 ;
        rxF[3]=0x00 ;
        ret=write(test8305, rxF, 4);
        sleep(5);

        rxF[0]=0x00 ;
        rxF[1]=0x00 ;
  ret=read(test8305, rxF, 2);
        printf("In main:register0_0=ox%x %x \n",rxF[0],rxF[1]);
       
        rxF[0]=0x00 ;
        rxF[1]=0x01 ;
  ret=read(test8305, rxF, 2);
        printf("In main:register0_1=0x%x %x \n",rxF[0],rxF[1]);
  

        close(test8305);
        return 0 ;
}

论坛徽章:
0
6 [报告]
发表于 2007-10-07 13:53 |只看该作者

回复 #1 orien 的帖子

怎么不给个精华呀!这可是原创、商用代码呀!

论坛徽章:
0
7 [报告]
发表于 2007-10-13 22:46 |只看该作者
可能真正看完代码的人不多啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP