DM9000C在linux3.1,S3C2416移植过程分析

这里写图片描述
上图为板子上连线图,从图可以确定一下几点:
1. 片选为CSn4,2416访问DM9000的基地址为0x20000000(BANK4的基值)
2. INT管脚上的标号EINT4,用到中断EINT4
3. 用到管脚SD0到SD15,总线位宽为16
4. 用到一根地址线:LADDR2。DM9000数据与地址是分时复用的。用该管脚来区分,CPU与DM9000芯片传输的地址线与数据线。当ADDR2为1则,CPU发出的是读写数据信号,否则,CPU发出的是地址信号。与本次移植相关的源文件是drivers/net/dm9000.c , linux/arch/arm/mach/smdk2416.c ,源码中的smdk2416.c文件中没有DM9000设备,需要再这个文件中添加DM9000设备驱动一些信息。


static struct platform_device *smdk2416_devices[] __initdata = {
    &s3c_device_fb,
    &s3c_device_wdt,
    &s3c_device_ohci,
    &s3c_device_i2c0,
    &s3c_device_hsmmc0,
    &s3c_device_hsmmc1,
    &s3c_device_usb_hsudc,
};

这里没有DM9000平台设备,我们做出如下修改:
1.添加需要包含的头文件,增加以下代码

#ifdef CONFIG_DM9000   //在.config文件中有CONFIG_DM9000
#include <linux/dm9000.h> 
#include <mach/regs-mem.h>
#endif

2.添加平台设备结构体。

static struct platform_device my_device_eth = {
    .name       = "dm9000",//设备名称
    .id     = -1,
    .num_resources  = ARRAY_SIZE(my2416_dm9k_resource),
    .resource   = my2416_dm9k_resource,//平台所使用资源
    .dev        = {
        .platform_data  = &my2416_dm9k_pdata,//数据位访问方式设置
    },
};

实现这两个函数my2416_dm9k_resource,my2416_dm9k_pdata

#ifdef CONFIG_DM9000
#define MACH_MY2416_DM9K_BASE       (S3C2410_CS4 + 0x300)  //这里没必要加0x300的偏移地址
static struct resource my2416_dm9k_resource[] = {//该结构体确定需要访问的资源,前两个数组用来定义内存空间,最后一个是定义中断资源,由于DM9000传输数据与地址是复用,数组0保存地址,数组1保存数据
    [0] = {
        .start = MACH_MY2416_DM9K_BASE,  //发送地址时,使用这个地址
        .end   = MACH_MY2416_DM9K_BASE + 3,//一个地址占4个字节
        .flags = IORESOURCE_MEM  
    },
    [1] = {
        .start = MACH_MY2416_DM9K_BASE + 4,  /*发送数据时,使用这个地址,为何加4,这是由于
        LADDR2为高低电平变化时,CPU的寻址范围发生变化,当LADDR2为低电平,与DM9000传输地址,CPU可寻址范围是:0x20000000-------0x27FFFFFF,当LADDR2为高电平,与DM9000传输数据,可以寻址范围0x20000004-------0x27FFFFFF,看到没有起始地址发生了变化,即需要加4。假如原理图是LADDR3引脚与DM9000的CMD数据/地址复用控制管脚相连那么,不是加4了而是加8。这样不管数据/地址管脚是数据还是地址,是地址信号在数组0,是数据在数组1.*/
        .end   = MACH_MY2416_DM9K_BASE + 4 + 3,//一个数据占4个字节
        .flags = IORESOURCE_MEM
    },
    [2] = {
        .start = IRQ_EINT4,//根据原理图,用的是第4个中断号。
        .end   = IRQ_EINT4,
        .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
    }
};
static struct dm9000_plat_data my2416_dm9k_pdata = {
    .flags      = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),  //指定访问DM9000是16位方式,可以根据原理图连线知道,用到LDATA0到LDATA15。或者是DM9000芯片没有接EEPROM。
};
在结构体中 platform_device添加
static struct platform_device *smdk2416_devices[] __initdata = {
    &s3c_device_fb,
    &s3c_device_wdt,
    &s3c_device_ohci,
    &s3c_device_i2c0,
    &s3c_device_hsmmc0,
    &s3c_device_hsmmc1,
    &s3c_device_usb_hsudc,
#ifdef CONFIG_DM9000 //这段代码新增,系统启动时候,对DM9000驱动进行注册
    &my2416_device_eth,
#endif
};

在smdk_machine_init函数里添加,在代码最后初始化加入:

#ifdef CONFIG_DM9000
    my2416_srom_init();
#endif /* CONFIG_DM9000 *
static void __init my2416_srom_init(void)
{//在这里设置bank4有关的控制寄存器,数据位宽的设置,信号之间的延时等等,具体可以参考S3C2416手册,SROM初始化
    *(volatile unsigned int *)S3C2416_EBI_BANKCFG &= ~((1<<8)|(1<<9)|(1<<10));
    *(volatile unsigned int *)S3C2416_SMBIDCYR(4) = 0xF;//当nWAIT信号没有用时,它们才有用
    *(volatile unsigned int *)S3C2416_SMBWSTRDR(4) = 12;
    *(volatile unsigned int *)S3C2416_SMBWSTWRR(4) = 12;
    *(volatile unsigned int *)S3C2416_SMBWSTOENR(4) = 2;
    *(volatile unsigned int *)S3C2416_SMBWSTWENR(4) = 2;
    *(volatile unsigned int *)S3C2416_SMBCR(4) = (*(volatile unsigned int *)S3C2416_SMBCR(4)) | ((1<<15)|(1<<7)); //信号与信号之间有延时
    *(volatile unsigned int *)S3C2416_SMBCR(4) = (*(volatile unsigned int *)S3C2416_SMBCR(4)) | ((1<<2)|(1<<0)); //nBE有关
    *(volatile unsigned int *)S3C2416_SMBCR(4) = (*(volatile unsigned int *)S3C2416_SMBCR(4)) & (~((3<<20)|(3<<12))); //写和读时,RSMAVD是高电平,
    *(volatile unsigned int *)S3C2416_SMBCR(4) = (*(volatile unsigned int *)S3C2416_SMBCR(4)) & (~(3<<4)); //先clear
    *(volatile unsigned int *)S3C2416_SMBCR(4) = (*(volatile unsigned int *)S3C2416_SMBCR(4)) | (1<<4); //设置数据位宽16
}
#endif /* CONFIG_DM9000 */

设置mac的默认值进入
drivers/net/dm9000.c
在函数dm9000_probe

    if (!is_valid_ether_addr(ndev->dev_addr)) {
        /* try reading from mac */
#if 0   //屏蔽掉原来的内容  
        mac_src = "chip";
        for (i = 0; i < 6; i++)
            ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
#else  //新增加的,设置默认的mac地址,在系统启动后,可以使用Ifconfig修改
    printk("%s: Invalid ethernet MAC address. using default config,  Please "
               "set using ifconfig\n", ndev->name); 
        ndev->dev_addr[0] = 0x10;
        ndev->dev_addr[1] = 0x23;
        ndev->dev_addr[2] = 0x45;
        ndev->dev_addr[3] = 0x67;
        ndev->dev_addr[4] = 0x89;
        ndev->dev_addr[5] = 0xab;
#endif
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值