make atheros wifi cards used on arcaydian 4519 ifxmips based boards work
authorJohn Crispin <john@openwrt.org>
Sun, 6 Jul 2008 00:59:48 +0000 (00:59 +0000)
committerJohn Crispin <john@openwrt.org>
Sun, 6 Jul 2008 00:59:48 +0000 (00:59 +0000)
SVN-Revision: 11676

package/madwifi/patches/353-devid.patch [new file with mode: 0644]
package/madwifi/patches/354-ifxmips_eeprom.patch [new file with mode: 0644]
target/linux/ifxmips/config-2.6.25
target/linux/ifxmips/files/arch/mips/ifxmips/board.c
target/linux/ifxmips/files/drivers/watchdog/ifxmips_wdt.c
target/linux/ifxmips/files/include/asm-mips/mach-ifxmips/gpio.h

diff --git a/package/madwifi/patches/353-devid.patch b/package/madwifi/patches/353-devid.patch
new file mode 100644 (file)
index 0000000..b79caca
--- /dev/null
@@ -0,0 +1,19 @@
+Index: madwifi-trunk-r3314/ath/if_ath_pci.c
+===================================================================
+--- madwifi-trunk-r3314.orig/ath/if_ath_pci.c  2008-07-06 01:38:57.000000000 +0200
++++ madwifi-trunk-r3314/ath/if_ath_pci.c       2008-07-06 01:52:09.000000000 +0200
+@@ -114,11 +114,13 @@
+       { 0x168c, 0x0023, PCI_ANY_ID, PCI_ANY_ID },
+       { 0x168c, 0x0024, PCI_ANY_ID, PCI_ANY_ID },
+       { 0x168c, 0x9013, PCI_ANY_ID, PCI_ANY_ID }, /* sonicwall */
++      { 0x168c, 0xff1a, PCI_ANY_ID, PCI_ANY_ID },
+       { 0 }
+ };
+ static u16 ath_devidmap[][2] = {
+-      { 0x9013, 0x0013 }
++      { 0x9013, 0x0013 },
++      { 0xff1a, 0x001a }
+ };
+ static int
diff --git a/package/madwifi/patches/354-ifxmips_eeprom.patch b/package/madwifi/patches/354-ifxmips_eeprom.patch
new file mode 100644 (file)
index 0000000..f4c8f73
--- /dev/null
@@ -0,0 +1,100 @@
+Index: madwifi-trunk-r3314/ath_hal/ah_os.c
+===================================================================
+--- madwifi-trunk-r3314.orig/ath_hal/ah_os.c   2008-07-06 02:42:52.000000000 +0200
++++ madwifi-trunk-r3314/ath_hal/ah_os.c        2008-07-06 02:51:53.000000000 +0200
+@@ -343,6 +343,46 @@
+  * NB: see the comments in ah_osdep.h about byte-swapping register
+  *     reads and writes to understand what's going on below.
+  */
++
++#ifdef CONFIG_IFXMIPS
++extern int ifxmips_has_brn_block(void);
++static int ifxmips_emulate = 0;
++#define EEPROM_EMULATION 1
++#endif
++
++#ifdef EEPROM_EMULATION
++static int ath_hal_eeprom(struct ath_hal *ah, unsigned long addr, int val, int write)
++{
++      static int addrsel = 0;
++      static int rc = 0;
++
++      if (write) {
++              if(addr == 0x6000) {
++                      addrsel = val * 2;
++                      rc = 0;
++              }
++      } else {
++              switch(addr)
++              {
++              case 0x600c:
++                      if(rc++ < 2)
++                              val = 0x00000000;
++                      else
++                              val = 0x00000002;
++                      break;
++              case 0x6004:
++                      val = cpu_to_le16(__raw_readw((u16 *) KSEG1ADDR(0xb07f0400 + addrsel)));
++                      /* this forces the regdomain to 0x00 (worldwide), as the original setting
++                       * causes issues with the HAL */
++                      if (addrsel == 0x17e)
++                              val = 0;
++                      break;
++              }
++      }
++      return val;
++}
++#endif
++
+ void __ahdecl
+ ath_hal_reg_write(struct ath_hal *ah, u_int reg, u_int32_t val)
+ {
+@@ -351,20 +391,33 @@
+               ath_hal_printf(ah, "%s: WRITE 0x%x <= 0x%x\n", 
+                               (ath_hal_func ?: "unknown"), reg, val);
+ #endif
+-      _OS_REG_WRITE(ah, reg, val);
++#ifdef EEPROM_EMULATION
++      if((reg >= 0x6000) && (reg <= 0x6010) && ifxmips_emulate)
++      {
++              val = ath_hal_eeprom(ah, reg, val, 1);
++      } else
++#endif
++              _OS_REG_WRITE(ah, reg, val);
+ }
+ EXPORT_SYMBOL(ath_hal_reg_write);
++
+ /* This should only be called while holding the lock, sc->sc_hal_lock. */
+ u_int32_t __ahdecl
+ ath_hal_reg_read(struct ath_hal *ah, u_int reg)
+ {
+-      u_int32_t val;
++      u_int32_t val;
++#ifdef EEPROM_EMULATION
++      if((reg >= 0x6000) && (reg <= 0x6010) && ifxmips_emulate)
++      {
++              val = ath_hal_eeprom(ah, reg, 0, 0);
++      } else
++#endif
++              val = _OS_REG_READ(ah, reg);
+-      val = _OS_REG_READ(ah, reg);
+ #ifdef AH_DEBUG
+       if (ath_hal_debug > 1)
+-              ath_hal_printf(ah, "%s: READ 0x%x => 0x%x\n", 
++              ath_hal_printf(ah, "%s: READ 0x%x => 0x%x\n",
+                               (ath_hal_func ?: "unknown"), reg, val);
+ #endif
+       return val;
+@@ -581,7 +634,9 @@
+ {
+       const char *sep;
+       int i;
+-
++#ifdef CONFIG_IFXMIPS
++      ifxmips_emulate = ifxmips_has_brn_block();
++#endif
+       printk(KERN_INFO "%s: %s (", dev_info, ath_hal_version);
+       sep = "";
+       for (i = 0; ath_hal_buildopts[i] != NULL; i++) {
index c15aa0be66de6fc31c74a47ae1a28d489c245a50..5cfa773ed7f9e51d717d4db38cd78224036bddfa 100644 (file)
@@ -93,7 +93,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_IRQ_CPU=y
 CONFIG_KALLSYMS=y
 # CONFIG_LEDS_ALIX is not set
-# CONFIG_LEDS_GPIO is not set
+CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_IFXMIPS=y
 # CONFIG_LEMOTE_FULONG is not set
 CONFIG_LZO_COMPRESS=m
index f0c2f70321d176bea6e3243f99bc6dafb755f8a9..25cc03c6d3613bacbcb13c626026d5f70346e32e 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/io.h>
 #include <linux/etherdevice.h>
 #include <asm/ifxmips/ifxmips.h>
+#include <linux/leds.h>
 
 #define MAX_BOARD_NAME_LEN             32
 #define MAX_IFXMIPS_DEVS               9
@@ -120,6 +121,31 @@ ifxmips_gpio_dev = {
        .num_resources    =     1,
 };
 
+#ifdef CONFIG_LEDS_GPIO
+static struct gpio_led arv4519_leds[] = {
+       { .name = "ifxmips:green:power0", .gpio = 3, .active_low = 0, },
+       { .name = "ifxmips:red:power1", .gpio = 7, .active_low = 1, },
+       { .name = "ifxmips:green:adsl", .gpio = 4, .active_low = 1, },
+       { .name = "ifxmips:green:internet0", .gpio = 5, .active_low = 0, },
+       { .name = "ifxmips:red:internet1", .gpio = 8, .active_low = 1, },
+       { .name = "ifxmips:green:wlan", .gpio = 6, .active_low = 1, },
+       { .name = "ifxmips:green:usb", .gpio = 19, .active_low = 1, },
+};
+
+static const struct gpio_led_platform_data arv4519_led_data = {
+       .num_leds = ARRAY_SIZE(arv4519_leds),
+       .leds = (void *) arv4519_leds,
+};
+
+static struct platform_device arv4519_gpio_leds = {
+       .name = "leds-gpio",
+       .id = -1,
+       .dev = {
+               .platform_data = (void *) &arv4519_led_data,
+        }
+};
+#endif
+
 const char*
 get_system_type(void)
 {
@@ -235,8 +261,11 @@ static struct ifxmips_board boards[] =
                .system_type = SYSTEM_DANUBE_CHIPID2,
                .devs =
                {
-                       &ifxmips_led, &ifxmips_gpio, &ifxmips_mii,
+                       &ifxmips_gpio, &ifxmips_mii,
                        &ifxmips_mtd, &ifxmips_wdt, &ifxmips_gpio_dev,
+#ifdef CONFIG_LEDS_GPIO
+                       &arv4519_gpio_leds,
+#endif
                },
                .reset_resource =
                {
@@ -277,6 +306,7 @@ ifxmips_has_brn_block(void)
 {
        return ifxmips_brn;
 }
+EXPORT_SYMBOL(ifxmips_has_brn_block);
 
 struct ifxmips_board*
 ifxmips_find_board(void)
index 1556a2324725029f6d164cbfcb0774a6cf4b553b..58e216148915896bee6d07e65896c0668b3aa236 100644 (file)
@@ -122,7 +122,6 @@ static int
 ifxmips_wdt_open(struct inode *inode, struct file *file)
 {
        ifxmips_wdt_enable(wdt_timeout);
-       printk("ifxmips_wdt: activated");
        return nonseekable_open(inode, file);
 }
 
index 0d207b093898506aef2831c5d5741d0f7021960b..76d42c2e3b4b55925f7338b9394040833d5d3923 100644 (file)
 #include <asm/ifxmips/ifxmips.h>
 #include <asm/ifxmips/ifxmips_gpio.h>
 
+#define GPIO_TO_PORT(x) ((x > 15)?(1):(0))
+#define GPIO_TO_GPIO(x) ((x > 15)?(x-16):(x))
+
 static inline int gpio_direction_input(unsigned gpio) {
-       ifxmips_port_set_dir_in(0, gpio);
+       ifxmips_port_set_open_drain(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_clear_altsel0(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+    ifxmips_port_clear_altsel1(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_set_dir_in(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
        return 0;
 }
 
 static inline int gpio_direction_output(unsigned gpio, int value) {
-       ifxmips_port_set_dir_out(0, gpio);
+       ifxmips_port_clear_open_drain(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_clear_altsel0(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_clear_altsel1(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       ifxmips_port_set_dir_out(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
        return 0;
 }
 
 static inline int gpio_get_value(unsigned gpio) {
-       ifxmips_port_get_input(0, gpio);
+       ifxmips_port_get_input(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
        return 0;
 }
 
 static inline void gpio_set_value(unsigned gpio, int value) {
-       ifxmips_port_set_output(0, gpio);
+       if(value)
+               ifxmips_port_set_output(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
+       else
+               ifxmips_port_clear_output(GPIO_TO_PORT(gpio), GPIO_TO_GPIO(gpio));
 }
 
 static inline int gpio_request(unsigned gpio, const char *label) {