The Microsoft MN-700 router (very similar to the ASUS WL-500g) is not
detected correctly by the broadcom-diag kernel module. Also it is not
possible to switch off the power LED after it was enabled. With the
included patch these two issues are solved. It also exports the LED
flash interval via /proc.

Signed-off-by: Michael Heimpold <mhei @ heimpold.de>

---
Index: target/linux/brcm-2.4/profiles/MN700.mk
===================================================================
--- target/linux/brcm-2.4/profiles/MN700.mk     (Revision 0)
+++ target/linux/brcm-2.4/profiles/MN700.mk     (Revision 0)
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/MN700
+  NAME:=Microsoft MN-700
+  PACKAGES:=kmod-brcm-wl wlc nas kmod-wlcompat -kmod-switch
+endef
+
+define Profile/MN700/Description
+       Package set optimized for the Microsoft MN-700
+endef
+$(eval $(call Profile,MN700))
Index: target/linux/brcm-2.4/base-files/etc/init.d/netconfig
===================================================================
--- target/linux/brcm-2.4/base-files/etc/init.d/netconfig       (Revision 11305)
+++ target/linux/brcm-2.4/base-files/etc/init.d/netconfig       (Arbeitskopie)
@@ -57,7 +57,7 @@
                        c["wan_ifname"] = ""
                        c["lan_ifname"] = "eth1"
                }
-               if (model == "ASUS WL-500g") {
+               if ((model == "ASUS WL-500g") || (model == "Microsoft MN-700")) 
{
                        c["wan_ifname"] = "eth1"
                        c["lan_ifname"] = "eth0"
                }
Index: target/linux/brcm-2.4/base-files/etc/diag.sh
===================================================================
--- target/linux/brcm-2.4/base-files/etc/diag.sh        (Revision 11305)
+++ target/linux/brcm-2.4/base-files/etc/diag.sh        (Arbeitskopie)
@@ -12,11 +12,19 @@
                preinit)
                        set_led dmz 1
                        set_led diag 1
-                       set_led power 0
+                       if [ "$(cat /proc/diag/model)" = "Microsoft MN-700" ] ; 
then
+                               set_led power f
+                       else
+                               set_led power 0
+                       fi
                ;;
                failsafe)
                        set_led diag f
-                       set_led power f
+                       if [ "$(cat /proc/diag/model)" = "Microsoft MN-700" ] ; 
then
+                               set_led power 2
+                       else
+                               set_led power f
+                       fi
                        set_led dmz f
                ;;
                done)
Index: package/broadcom-diag/src/diag.c
===================================================================
--- package/broadcom-diag/src/diag.c    (Revision 11305)
+++ package/broadcom-diag/src/diag.c    (Arbeitskopie)
@@ -51,6 +51,8 @@
 static int fill_event(struct event_t *);
 static unsigned int gpiomask = 0;
 module_param(gpiomask, int, 0644);
+static unsigned int flashtime = FLASH_TIME;
+module_param(flashtime, int, 0644);
 
 enum {
        /* Linksys */
@@ -123,6 +125,9 @@
 
        /* Sitecom */
        WL105B,
+
+       /* Microsoft */
+       MN700,
 };
 
 static void __init bcm4780_init(void) {
@@ -670,6 +675,16 @@
                        { .name = "power",      .gpio = 1 << 3},
                },
        },
+       /* Microsoft */
+       [MN700] = {
+               .name   = "Microsoft MN-700",
+               .buttons        = {
+                       { .name = "reset",      .gpio = 1 << 7 },
+               },
+               .leds     = {
+                       { .name = "power",      .gpio = 1 << 6, .polarity = 
MULTI },
+               },
+       },
 };
 
 static struct platform_t __init *platform_detect(void)
@@ -781,6 +796,9 @@
                        if (simple_strtoul(boardnum, NULL, 0) == 2)
                                return &platforms[WAP54GV1];
                }
+               /* MN-700 has also hardware_version 'WL500-...', so use 
boardnum and keep 
before */
+               if (startswith(boardnum, "mn700"))
+                       return &platforms[MN700];
                if (startswith(getvar("hardware_version"), "WL500-"))
                        return &platforms[WL500G];
                if (startswith(getvar("hardware_version"), "WL300-")) {
@@ -1004,9 +1022,10 @@
                        l->state = 0;
                        set_led_extif(l);
                } else {
-                       if (l->polarity != INPUT) oe_mask |= l->gpio;
+                       if (l->polarity == REVERSE || l->polarity == NORMAL)
+                               oe_mask |= l->gpio;
                        mask |= l->gpio;
-                       val |= (l->polarity == NORMAL)?0:l->gpio;
+                       val |= (l->polarity == NORMAL) ? 0 : l->gpio;
                }
 
                if (l->polarity == INPUT) continue;
@@ -1038,8 +1057,10 @@
 }
 
 static void led_flash(unsigned long dummy) {
+       static u8 state = 0;
        struct led_t *l;
        u32 mask = 0;
+       u32 oe_mask = 0;
        u8 extif_blink = 0;
 
        for (l = platform.leds; l->name; l++) {
@@ -1048,13 +1069,24 @@
                                extif_blink = 1;
                                l->state = !l->state;
                                set_led_extif(l);
-                       } else {
-                               mask |= l->gpio;
+                               continue;
                        }
+                       switch (l->polarity) {
+                               case REVERSE:
+                               case NORMAL:
+                                       mask |= l->gpio;
+                                       break;
+                               case MULTI:
+                                       oe_mask |= l->gpio;
+                                       break;
+                               default:
+                                       break;
+                       }
                }
        }
 
        mask &= ~gpiomask;
+       oe_mask &= ~gpiomask;
        if (mask) {
                u32 val = ~gpio_in();
 
@@ -1062,9 +1094,13 @@
                gpio_control(mask, 0);
                gpio_out(mask, val);
        }
-       if (mask || extif_blink) {
-               mod_timer(&led_timer, jiffies + FLASH_TIME);
+       if (oe_mask) {
+               state = !state;
+               gpio_outen(oe_mask, state ? oe_mask : 0);
        }
+       if (mask || oe_mask || extif_blink) {
+               mod_timer(&led_timer, jiffies + flashtime);
+       }
 }
 
 static ssize_t diag_proc_read(struct file *file, char *buf, size_t count, 
loff_t *ppos)
@@ -1087,9 +1123,12 @@
                        case PROC_LED: {
                                struct led_t * led = (struct led_t *) 
handler->ptr;
                                if (led->flash) {
-                                       len = sprintf(page, "f\n");
+                                       if (led->polarity == MULTI)
+                                               len = sprintf(page, "f%d\n", 
led->state);
+                                       else
+                                               len = sprintf(page, "f\n");
                                } else {
-                                       if (led->gpio & GPIO_TYPE_EXTIF) {
+                                       if (led->gpio & GPIO_TYPE_EXTIF || 
led->polarity == MULTI) {
                                                len = sprintf(page, "%d\n", 
led->state);
                                        } else {
                                                u32 in = (gpio_in() & led->gpio 
? 1 : 0);
@@ -1105,6 +1144,9 @@
                        case PROC_GPIOMASK:
                                len = sprintf(page, "0x%04x\n", gpiomask);
                                break;
+                       case PROC_FLASHTIME:
+                               len = sprintf(page, "%d\n", flashtime);
+                               break;
                }
        }
        len += 1;
@@ -1150,10 +1192,29 @@
                switch (handler->type) {
                        case PROC_LED: {
                                struct led_t *led = (struct led_t *) 
handler->ptr;
-                               int p = (led->polarity == NORMAL ? 0 : 1);
+                               int p = (led->polarity == REVERSE ? 1 : 0);
 
                                if (page[0] == 'f') {
                                        led->flash = 1;
+                                       if (led->polarity == MULTI) {
+                                               switch (page[1]) {
+                                                       case 0:  /* No char 
after 'f' or cr/lf */
+                                                       case 10:
+                                                       case 13:
+                                                               led->state = 1;
+                                                               break;
+                                                       case '1':
+                                                       case '2':
+                                                               led->state = 
page[1] - '0';
+                                                               break;
+                                                       default:
+                                                               kfree(page);
+                                                               return -EINVAL;
+                                                               break;
+                                               }
+                                               gpio_control(led->gpio, 0);
+                                               gpio_out(led->gpio, ((p ^ 
(led->state == 1)) ? led->gpio : 0));
+                                       }
                                        led_flash(0);
                                } else {
                                        led->flash = 0;
@@ -1161,9 +1222,23 @@
                                                led->state = p ^ ((page[0] == 
'1') ? 1 : 0);
                                                set_led_extif(led);
                                        } else {
-                                               gpio_outen(led->gpio, 
led->gpio);
+                                               switch (page[0]) {
+                                                       case '0':
+                                                       case '1':
+                                                       case '2':
+                                                               led->state = 
page[0] - '0';
+                                                               break;
+                                                       default:
+                                                               kfree(page);
+                                                               return -EINVAL;
+                                                               break;
+                                               }
+                                               if (led->polarity == MULTI && 
led->state == 0)
+                                                       gpio_outen(led->gpio, 
0);
+                                               else
+                                                       gpio_outen(led->gpio, 
led->gpio);
                                                gpio_control(led->gpio, 0);
-                                               gpio_out(led->gpio, ((p ^ 
(page[0] == '1')) ? led->gpio : 0));
+                                               gpio_out(led->gpio, ((p ^ 
(led->state == 1)) ? led->gpio : 0));
                                        }
                                }
                                break;
@@ -1181,6 +1256,9 @@
                                        register_leds(platform.leds);
                                }
                                break;
+                       case PROC_FLASHTIME:
+                               flashtime = simple_strtoul(page, NULL, 0);
+                               break;
                }
                ret = count;
        }
@@ -1221,6 +1299,11 @@
                p->proc_fops = &diag_proc_fops;
        }
 
+       if ((p = create_proc_entry("flashtime", S_IRUSR | S_IWUSR, diag))) {
+               p->data = (void *) &proc_flashtime;
+               p->proc_fops = &diag_proc_fops;
+       }
+
        if (platform.buttons)
                register_buttons(platform.buttons);
 
@@ -1242,6 +1325,7 @@
 
        remove_proc_entry("model", diag);
        remove_proc_entry("gpiomask", diag);
+       remove_proc_entry("flashtime", diag);
        remove_proc_entry("diag", NULL);
 }
 
Index: package/broadcom-diag/src/diag.h
===================================================================
--- package/broadcom-diag/src/diag.h    (Revision 11305)
+++ package/broadcom-diag/src/diag.h    (Arbeitskopie)
@@ -18,7 +18,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 
USA.
  *
- * $Id:$
+ * $Id$
  */
 
 #include <linux/irq.h>
@@ -31,13 +31,15 @@
        REVERSE = 0,
        NORMAL = 1,
        INPUT = 2,
+       MULTI = 3,
 };
 
 enum {
        PROC_BUTTON,
        PROC_LED,
        PROC_MODEL,
-       PROC_GPIOMASK
+       PROC_GPIOMASK,
+       PROC_FLASHTIME,
 };
 
 struct prochandler_t {
@@ -137,4 +139,4 @@
 
 static struct prochandler_t proc_model = { .type = PROC_MODEL };
 static struct prochandler_t proc_gpiomask = { .type = PROC_GPIOMASK };
-
+static struct prochandler_t proc_flashtime = { .type = PROC_FLASHTIME };
_______________________________________________
openwrt-devel mailing list
[email protected]
http://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to