Attached is a patch for trunk which fixes gpio assignments for EnGenius devies on the ar231x platform. This patch fixes rebooting as well the reset button for the following devices:
        ECB-3500, EAP-3660, EOA-3630, EOC-2611P, EOC-1650, EOC-5611P
        
Signed-off-by: Jonathan Bither <jonbit...@gmail.com>

Index: target/linux/atheros/patches-2.6.37/400-engenius-support.patch
===================================================================
--- target/linux/atheros/patches-2.6.37/400-engenius-support.patch (revision 0) +++ target/linux/atheros/patches-2.6.37/400-engenius-support.patch (revision 0)
@@ -0,0 +1,159 @@
+--- a/arch/mips/include/asm/mach-ar231x/ar231x_platform.h
++++ b/arch/mips/include/asm/mach-ar231x/ar231x_platform.h
+@@ -66,6 +66,15 @@
+
+       /* radio calibration data */
+       const char *radio;
++
++      /* Reset GPIO */
++      u32 resetGpio;
++
++      /* Reset Button GPIO */
++      u32 resetButtonGpio;
++
++      /* EnGenius AP Workaround */
++      int EnGenius;
+ };
+
+ /*
+--- a/arch/mips/ar231x/ar2315.c
++++ b/arch/mips/ar231x/ar2315.c
+@@ -554,8 +554,8 @@
+       ar2315_led_data.num_leds = 0;
+       for(i = 1; i < 8; i++)
+       {
+-              if((i == AR2315_RESET_GPIO) ||
+-                 (i == ar231x_board.config->resetConfigGpio))
++              if((i == ar231x_board.resetGpio) ||
++                 (i == ar231x_board.resetButtonGpio))
+                       continue;
+
+               if(i == ar231x_board.config->sysLedGpio)
+@@ -610,11 +610,11 @@
+ /* Cold reset does not work on the AR2315/6, use the GPIO reset bits a workaround.
+        * give it some time to attempt a gpio based hardware reset
+        * (atheros reference design workaround) */
+-      gpio_direction_output(AR2315_RESET_GPIO, 0);
++      gpio_request(ar231x_board.resetGpio, "");
++      gpio_direction_output(ar231x_board.resetGpio, 0);
+       mdelay(100);
+
+-      /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic
+-       * workaround. Attempt to jump to the mips reset location -
++      /* Attempt to jump to the mips reset location -
+        * the boot loader itself might be able to recover the system */
+       mips_reset_vec();
+ }
+--- a/arch/mips/ar231x/reset.c
++++ b/arch/mips/ar231x/reset.c
+@@ -13,12 +13,12 @@
+ #include <ar231x.h>
+ #include "devices.h"
+
+-#define AR531X_RESET_GPIO_IRQ (AR531X_GPIO_IRQ(ar231x_board.config->resetConfigGpio)) ++#define AR531X_RESET_GPIO_IRQ (AR531X_GPIO_IRQ(ar231x_board.resetButtonGpio))
+
+ struct event_t {
+       struct work_struct wq;
+       int set;
+-      unsigned long jiffies;
++      unsigned long jiffies, jiffies_prev;
+ };
+
+ static struct timer_list rst_button_timer;
+@@ -68,8 +68,14 @@
+       add_msg(skb, "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
+       add_msg(skb, "SUBSYSTEM=button");
+       add_msg(skb, "BUTTON=reset");
+-      add_msg(skb, (event->set ? "ACTION=pressed" : "ACTION=released"));
+-      sprintf(buf, "SEEN=%ld", (event->jiffies - seen)/HZ);
++
++      /* EnGenius input level is reversed */
++      if (ar231x_board.EnGenius)
++              add_msg(skb, (event->set ? "ACTION=released" : 
"ACTION=pressed"));
++      else
++              add_msg(skb, (event->set ? "ACTION=pressed" : 
"ACTION=released"));
++
++      sprintf(buf, "SEEN=%lu", (event->jiffies - event->jiffies_prev)/HZ);
+       add_msg(skb, buf);
+       snprintf(buf, 128, "SEQNUM=%llu", uevent_next_seqnum());
+       add_msg(skb, buf);
+@@ -103,6 +109,7 @@
+
+       event->set = 0;
+       event->jiffies = jiffies;
++      event->jiffies_prev = seen;
+       INIT_WORK(&event->wq, hotplug_button);
+       schedule_work(&event->wq);
+ }
+@@ -144,7 +151,7 @@
+ {
+       seen = jiffies;
+
+-      if (ar231x_board.config->resetConfigGpio == 0xffff)
++      if (ar231x_board.resetButtonGpio == 0xffff)
+               return -ENODEV;
+
+       init_timer(&rst_button_timer);
+--- a/arch/mips/ar231x/board.c
++++ b/arch/mips/ar231x/board.c
+@@ -23,6 +23,7 @@
+ #include <asm/io.h>
+
+ #include <ar231x_platform.h>
++#include <ar2315_regs.h>
+ #include "devices.h"
+ #include "ar5312.h"
+ #include "ar2315.h"
+@@ -138,6 +139,8 @@
+       u8 *board_data;
+       u8 *radio_data;
+       u8 *mac_addr;
++      u16 *radio_info;
++      u16 vendor, id, subvendor, subid;
+       u32 offset;
+
+       ar231x_board.config = NULL;
+@@ -190,11 +193,42 @@
+
+       radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff);
+       ar231x_board.radio = radio_data;
++      ar231x_board.EnGenius = 0;
++      ar231x_board.resetGpio = AR2315_RESET_GPIO;
++      ar231x_board.resetButtonGpio = ar231x_board.config->resetConfigGpio;
+       offset = radio_data - board_data;
+ printk(KERN_INFO "Radio config found at offset 0x%x(0x%x)\n", rcfg - bcfg, offset);
+       rcfg_size = BOARD_CONFIG_BUFSZ - offset;
+       memcpy(radio_data, rcfg, rcfg_size);
+
++      /* If we have radio information try to identify the board */
++      radio_info = (u16 *) ar231x_board.radio;
++      if (radio_info) {
++              vendor = radio_info[1];
++              id = radio_info[0];
++              subid = radio_info[7];
++              subvendor = radio_info[8];
++
++              if ((vendor == 0x168c) && (id == 0x13) &&
++                  (subid == 0xa051) && (subvendor == 0x168c)) {
++                      /* ECB-3500, EAP-3660, EOA-3630, EOC-2611P */
++                      ar231x_board.EnGenius = 1;
++                      ar231x_board.resetGpio = 0;
++                      ar231x_board.resetButtonGpio = 5;
++              } else if ((vendor == 0x168c) && (id == 0x13) &&
++                         (subid == 0xa052) && (subvendor == 0x168c)) {
++                              /* EOC-1650 */
++                              ar231x_board.EnGenius = 1;
++                              ar231x_board.resetGpio = 0;
++                              ar231x_board.resetButtonGpio = 5;
++              } else if ((vendor == 0x168c) && (id == 0xa017) &&
++                         (subid == 0xa048) && (subvendor == 0x168c)) {
++                              /* EOC-5611P */
++                              ar231x_board.EnGenius = 1;
++                              ar231x_board.resetButtonGpio = 6;
++              }
++      }
++
+       mac_addr = &radio_data[0x1d * 2];
+       if (is_broadcast_ether_addr(mac_addr)) {
+               printk(KERN_INFO "Radio MAC is blank; using board-data\n");
Index: target/linux/atheros/patches-2.6.37/400-engenius-support.patch
===================================================================
--- target/linux/atheros/patches-2.6.37/400-engenius-support.patch	(revision 0)
+++ target/linux/atheros/patches-2.6.37/400-engenius-support.patch	(revision 0)
@@ -0,0 +1,159 @@
+--- a/arch/mips/include/asm/mach-ar231x/ar231x_platform.h
++++ b/arch/mips/include/asm/mach-ar231x/ar231x_platform.h
+@@ -66,6 +66,15 @@
+ 
+ 	/* radio calibration data */
+ 	const char *radio;
++
++	/* Reset GPIO */
++	u32 resetGpio;
++
++	/* Reset Button GPIO */
++	u32 resetButtonGpio;
++
++	/* EnGenius AP Workaround */
++	int EnGenius;
+ };
+ 
+ /*
+--- a/arch/mips/ar231x/ar2315.c
++++ b/arch/mips/ar231x/ar2315.c
+@@ -554,8 +554,8 @@
+ 	ar2315_led_data.num_leds = 0;
+ 	for(i = 1; i < 8; i++)
+ 	{
+-		if((i == AR2315_RESET_GPIO) ||
+-		   (i == ar231x_board.config->resetConfigGpio))
++		if((i == ar231x_board.resetGpio) ||
++		   (i == ar231x_board.resetButtonGpio))
+ 			continue;
+ 
+ 		if(i == ar231x_board.config->sysLedGpio)
+@@ -610,11 +610,11 @@
+ 	/* Cold reset does not work on the AR2315/6, use the GPIO reset bits a workaround.
+ 	 * give it some time to attempt a gpio based hardware reset
+ 	 * (atheros reference design workaround) */
+-	gpio_direction_output(AR2315_RESET_GPIO, 0);
++	gpio_request(ar231x_board.resetGpio, "");
++	gpio_direction_output(ar231x_board.resetGpio, 0);
+ 	mdelay(100);
+ 
+-	/* Some boards (e.g. Senao EOC-2610) don't implement the reset logic
+-	 * workaround. Attempt to jump to the mips reset location -
++	/* Attempt to jump to the mips reset location -
+ 	 * the boot loader itself might be able to recover the system */
+ 	mips_reset_vec();
+ }
+--- a/arch/mips/ar231x/reset.c
++++ b/arch/mips/ar231x/reset.c
+@@ -13,12 +13,12 @@
+ #include <ar231x.h>
+ #include "devices.h"
+ 
+-#define AR531X_RESET_GPIO_IRQ	(AR531X_GPIO_IRQ(ar231x_board.config->resetConfigGpio))
++#define AR531X_RESET_GPIO_IRQ  (AR531X_GPIO_IRQ(ar231x_board.resetButtonGpio))
+ 
+ struct event_t {
+ 	struct work_struct wq;
+ 	int set;
+-	unsigned long jiffies;
++	unsigned long jiffies, jiffies_prev;
+ };
+ 
+ static struct timer_list rst_button_timer;
+@@ -68,8 +68,14 @@
+ 	add_msg(skb, "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
+ 	add_msg(skb, "SUBSYSTEM=button");
+ 	add_msg(skb, "BUTTON=reset");
+-	add_msg(skb, (event->set ? "ACTION=pressed" : "ACTION=released"));
+-	sprintf(buf, "SEEN=%ld", (event->jiffies - seen)/HZ);
++
++	/* EnGenius input level is reversed */
++	if (ar231x_board.EnGenius)
++		add_msg(skb, (event->set ? "ACTION=released" : "ACTION=pressed"));
++	else
++		add_msg(skb, (event->set ? "ACTION=pressed" : "ACTION=released"));
++
++	sprintf(buf, "SEEN=%lu", (event->jiffies - event->jiffies_prev)/HZ);
+ 	add_msg(skb, buf);
+ 	snprintf(buf, 128, "SEQNUM=%llu", uevent_next_seqnum());
+ 	add_msg(skb, buf);
+@@ -103,6 +109,7 @@
+ 
+ 	event->set = 0;
+ 	event->jiffies = jiffies;
++	event->jiffies_prev = seen;
+ 	INIT_WORK(&event->wq, hotplug_button);
+ 	schedule_work(&event->wq);
+ }
+@@ -144,7 +151,7 @@
+ {
+ 	seen = jiffies;
+ 
+-	if (ar231x_board.config->resetConfigGpio == 0xffff)
++	if (ar231x_board.resetButtonGpio == 0xffff)
+ 		return -ENODEV;
+ 
+ 	init_timer(&rst_button_timer);
+--- a/arch/mips/ar231x/board.c
++++ b/arch/mips/ar231x/board.c
+@@ -23,6 +23,7 @@
+ #include <asm/io.h>
+ 
+ #include <ar231x_platform.h>
++#include <ar2315_regs.h>
+ #include "devices.h"
+ #include "ar5312.h"
+ #include "ar2315.h"
+@@ -138,6 +139,8 @@
+ 	u8 *board_data;
+ 	u8 *radio_data;
+ 	u8 *mac_addr;
++	u16 *radio_info;
++	u16 vendor, id, subvendor, subid;
+ 	u32 offset;
+ 
+ 	ar231x_board.config = NULL;
+@@ -190,11 +193,42 @@
+ 
+ 	radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff);
+ 	ar231x_board.radio = radio_data;
++	ar231x_board.EnGenius = 0;
++	ar231x_board.resetGpio = AR2315_RESET_GPIO;
++	ar231x_board.resetButtonGpio = ar231x_board.config->resetConfigGpio;
+ 	offset = radio_data - board_data;
+ 	printk(KERN_INFO "Radio config found at offset 0x%x(0x%x)\n", rcfg - bcfg, offset);
+ 	rcfg_size = BOARD_CONFIG_BUFSZ - offset;
+ 	memcpy(radio_data, rcfg, rcfg_size);
+ 
++	/* If we have radio information try to identify the board */
++	radio_info = (u16 *) ar231x_board.radio;
++	if (radio_info) {
++		vendor = radio_info[1];
++		id = radio_info[0];
++		subid = radio_info[7];
++		subvendor = radio_info[8];
++
++		if ((vendor == 0x168c) && (id == 0x13) &&
++		    (subid == 0xa051) && (subvendor == 0x168c)) {
++			/* ECB-3500, EAP-3660, EOA-3630, EOC-2611P */
++			ar231x_board.EnGenius = 1;
++			ar231x_board.resetGpio = 0;
++			ar231x_board.resetButtonGpio = 5;
++		} else if ((vendor == 0x168c) && (id == 0x13) &&
++			   (subid == 0xa052) && (subvendor == 0x168c)) {
++				/* EOC-1650 */
++				ar231x_board.EnGenius = 1;
++				ar231x_board.resetGpio = 0;
++				ar231x_board.resetButtonGpio = 5;
++		} else if ((vendor == 0x168c) && (id == 0xa017) &&
++			   (subid == 0xa048) && (subvendor == 0x168c)) {
++				/* EOC-5611P */
++				ar231x_board.EnGenius = 1;
++				ar231x_board.resetButtonGpio = 6;
++		}
++	}
++
+ 	mac_addr = &radio_data[0x1d * 2];
+ 	if (is_broadcast_ether_addr(mac_addr)) {
+ 		printk(KERN_INFO "Radio MAC is blank; using board-data\n");
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to