Chinaunix首页 | 论坛 | 博客
  • 博客访问: 635523
  • 博文数量: 121
  • 博客积分: 8469
  • 博客等级: 中将
  • 技术积分: 1065
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-03 10:32
文章分类

全部博文(121)

文章存档

2013年(1)

2012年(15)

2010年(2)

2009年(8)

2008年(95)

我的朋友

分类: LINUX

2008-08-14 14:14:21

板子的CPU是PXA270,网卡是CS8900A,linux版本2.6.26。

搜索了一下网上关于CS8900A的移植,发现2种方法:
1.下载驱动cs8900.c
2.移植内核本身的驱动cs89x0.c

现在介绍的是第2种方法。


首先修改/driver/net/Kconfig文件,这样在配置时才会出现"cs89x0 support"的选项。
config CS89x0
 
tristate "CS89x0 support"
删除这一行 depends on NET_PCI && (ISA || MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X)
或者把它放到下面的--help--里。

修改arch/arm/mach-pxa/ads270.c
添加结构
static struct map_desc
ads270_io_desc[] __initdata = {
    {
        .virtual    =  0xf9000000,    //虚地址
        .pfn        = __phys_to_pfn(0x14000000), //物理地址,网卡接到CS5
        .length     = 0x00100000,
        .type       = MT_DEVICE
    }
};

修改cs89x0.c,以下是我的补丁:
--- cs89x0-orig.c    2008-08-14 13:37:48.000000000 +0800
+++ cs89x0.c    2008-08-14 13:41:59.000000000 +0800
@@ -152,7 +152,13 @@
 #if ALLOW_DMA
 #include
 #endif
-
+#ifdef CONFIG_
MACH_ADS270
+#include
+#include
+#include
+#endif
 #include "cs89x0.h"
 
 static char version[] __initdata =
@@ -194,6 +200,17 @@
 #define CIRRUS_DEFAULT_IRQ    VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
 static unsigned int netcard_portlist[] __used __initdata = {CIRRUS_DEFAULT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
+#elif defined(CONFIG_
MACH_ADS270)
+static unsigned int netcard_portlist[] __initdata = { 0xf9000000 + 0x300, 0};
+static unsigned int cs8900_irq_map[] = { IRQ_GPIO(103), 0, 0, 0 };
+#ifdef request_region
+#undef request_region
+#endif
+#ifdef release_region
+#undef release_region
+#endif
+#define request_region(a, s, n) request_mem_region(a, s, n)
+#define release_region(a, s) release_mem_region(a, s)
 #else
 static unsigned int netcard_portlist[] __used __initdata =
    { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
@@ -350,7 +367,19 @@
 }
 #endif
 
-#if defined(CONFIG_MACH_IXDP2351)
+#if defined(CONFIG_
MACH_ADS270)
+static u16
+readword(unsigned long base_addr, int portno)
+{
+    return __raw_readw(base_addr + portno);
+}
+
+static void
+writeword(unsigned long base_addr, int portno, u16 value)
+{
+    __raw_writew(value, base_addr + portno);
+}
+#elif defined(CONFIG_MACH_IXDP2351)
 static u16
 readword(unsigned long base_addr, int portno)
 {
@@ -630,7 +659,17 @@
            dev->base_addr);
 
     reset_chip(dev);
-
+#ifdef CONFIG_
MACH_ADS270
+     lp->force = FORCE_RJ45;
+     lp->auto_neg_cnf = IMM_BIT;
+
+     dev->dev_addr[0] = 0x12;
+     dev->dev_addr[1] = 0x34;
+     dev->dev_addr[2] = 0x56;
+     dev->dev_addr[3] = 0x78;
+     dev->dev_addr[4] = 0x9a;
+     dev->dev_addr[5] = 0x00;
+#endif
         /* Here we read the current configuration of the chip. If there
        is no Extended EEPROM then the idea is to not disturb the chip
        configuration, it should have been correctly setup by automatic
@@ -1273,7 +1312,7 @@
     int i;
     int ret;
 
-#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) /* uses irq#1, so this won't work */
+#if !defined(CONFIG_MACH_
ADS270) && !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) /* uses irq#1, so this won't work */
     if (dev->irq < 2) {
         /* Allow interrupts to be generated by the chip */
 /* Cirrus' release had this: */
@@ -1304,7 +1343,7 @@
     else
 #endif
     {
-#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
+#if !defined(CONFIG_MACH_
ADS270) && !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
         if (((1 << dev->irq) & lp->irq_map) == 0) {
             printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
                                dev->name, dev->irq, lp->irq_map);
@@ -1319,6 +1358,7 @@
         writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
 #endif
         write_irq(dev, lp->chip_type, dev->irq);
+        set_irq_type(dev->irq, IRQT_RISING);
         ret = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);
         if (ret) {
             if (net_debug)




阅读(3113) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~