大家好:
我在linux环境下在AM1808上驱动DM9000AEP时遇到了问题。DM9000以SRAM的模式接在了EMIF上,在
设置了DM9000的地址并配置了CE4CFG总线后,在dm9000.c中的dm9000_probe()函数里可以正常读取DM9000的
ID号,但是等在系统打开网络设备调用dm9000_init_dm9000()函数时,再次读取ID就不正确了,读回来是
0x00000000,之后对DM9000寄存器的操作也是无效的,DM9000无法工作。在dm9000_init_dm9000()函数中读
取寄存器CE4CFG的值也是0,也无法对寄存器CE4CFG进行写操作。没有找到其他修改CE4CFG的地方。
所以请大家帮忙看一下是什么原因使得第二次读取DM9000 ID失败的。
使用的软件环境是:dvsdk_omapl138-evm_04_03_00_06+Ubuntu 10.04
在board-da830-evm.c中添加有关DM9000的代码如下:
static struct resource dm850evm_dm9000_rsrc[] = {
{
/* addr */
.start = 0x64000000,
.end = 0x64000000,
.flags = IORESOURCE_MEM,
}, {
/* data */
.start = 0x64000004,
.end = 0x64000004,
.flags = IORESOURCE_MEM,
}, {
.flags = IORESOURCE_IRQ | IRQ_TYPE_EDGE_FALLING /* rising (active high)
*/,
},
};
static struct dm9000_plat_data dm850evm_dm9000_pdata = {
.flags =( DM9000_PLATF_8BITONLY | IRQ_TYPE_EDGE_FALLING |
DM9000_PLATF_NO_EEPROM ),
};
static struct platform_device dm850evm_dm9000 = {
.name = "dm9000",
.id = 0,
.resource = dm850evm_dm9000_rsrc,
.num_resources = ARRAY_SIZE(dm850evm_dm9000_rsrc),
.dev = {
.platform_data = &dm850evm_dm9000_pdata,
},
};
static struct platform_device *dm850_evm_devices[] __initdata = {
&dm850evm_dm9000,
};
在函数 "da850_evm_init" 中添加代码如下:
#define DA8XX_AEMIF_CE2CFG_OFFSET 0x10
#define DA8XX_AEMIF_CE3CFG_OFFSET 0x14
#define DA8XX_AEMIF_CE4CFG_OFFSET 0x18
#define DA8XX_AEMIF_CE5CFG_OFFSET 0x1c
#define DA8XX_AEMIF_ASIZE_8BIT 0x0
static const short da850_evm_dm9000_pins[] = {
DA850_EMA_BA_1,DA850_EMA_BA_0,
DA850_NEMA_CS_2,DA850_NEMA_CS_3,DA850_NEMA_CS_4,DA850_NEMA_CS_5,
DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1,
DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5,
DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_A_0,
-1
};
ret = davinci_cfg_reg_list(da850_evm_dm9000_pins);
if (ret)
pr_warning("da850_evm_init: nand mux setup failed: %d\n", ret);
void __iomem *aemif_addr;
aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) &(~0x3),aemif_addr +
DA8XX_AEMIF_CE2CFG_OFFSET);
printk("the addr is 0x%x\n",aemif_addr);
printk("the CE2CFG=%x\n",readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET));
unsigned int value = 0;
value |= (0UL<<31); /* [31] SS=0, Normal Mode enabled. */
value |= (0UL<<30); /* [30] EW=0, Extended wait cycles disabled. */
value |= (1UL<<26); /* [29:26] W_SETUP, 0~0x0F */
value |= (6UL<<20); /* [25:20] W_STROBE, 0~0x3F */
value |= (3UL<<17); /* [19:17] W_HOLD, 0~0x07 */
value |= (1UL<<13); /* [16:13] R_SETUP, 0~0x0F */
value |= (7UL<<7); /* [12:7] R_STROBE, 0~0x3F */
value |= (3UL<<4); /* [6:4] R_HOLD, 0~0x07 */
value |= (3UL<<2); /* [3:2] TA, 0~0x03 */
value |= (0UL<<0); /* [1:0] 0=8bit,1=16bit */
writel( value,aemif_addr + DA8XX_AEMIF_CE4CFG_OFFSET);
writel( value,aemif_addr + DA8XX_AEMIF_CE5CFG_OFFSET);
iounmap(aemif_addr);