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