ar71xx: adding om2p support

Signed-off-by: Marek Lindner <marek@open-mesh.com>

---

--- a/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile	(revision 27448)
+++ b/target/linux/ar71xx/files/arch/mips/ar71xx/Makefile	(working copy)
@@ -43,6 +43,7 @@
 obj-$(CONFIG_AR71XX_MACH_MZK_W04NU)	+= mach-mzk-w04nu.o
 obj-$(CONFIG_AR71XX_MACH_MZK_W300NH)	+= mach-mzk-w300nh.o
 obj-$(CONFIG_AR71XX_MACH_NBG460N)	+= mach-nbg460n.o
+obj-$(CONFIG_AR71XX_MACH_OM2P)		+= mach-om2p.o
 obj-$(CONFIG_AR71XX_MACH_PB42)		+= mach-pb42.o
 obj-$(CONFIG_AR71XX_MACH_PB44)		+= mach-pb44.o
 obj-$(CONFIG_AR71XX_MACH_PB92)		+= mach-pb92.o
--- a/target/linux/ar71xx/files/arch/mips/ar71xx/machtype.h	(revision 27448)
+++ b/target/linux/ar71xx/files/arch/mips/ar71xx/machtype.h	(working copy)
@@ -40,6 +40,7 @@
 	AR71XX_MACH_MZK_W04NU,	/* Planex MZK-W04NU */
 	AR71XX_MACH_MZK_W300NH,	/* Planex MZK-W300NH */
 	AR71XX_MACH_NBG460N,	/* Zyxel NBG460N/550N/550NH */
+	AR71XX_MACH_OM2P,	/* OpenMesh OM2P */
 	AR71XX_MACH_TEW_632BRP,	/* TRENDnet TEW-632BRP */
 	AR71XX_MACH_TL_MR3220,	/* TP-LINK TL-MR3220 */
 	AR71XX_MACH_TL_MR3420,	/* TP-LINK TL-MR3420 */
--- a/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig	(revision 27448)
+++ b/target/linux/ar71xx/files/arch/mips/ar71xx/Kconfig	(working copy)
@@ -244,6 +244,15 @@
 	select AR71XX_DEV_LEDS_GPIO
 	default n
 
+config AR71XX_MACH_OM2P
+	bool "OpenMesh OM2P board support"
+	select SOC_AR724X
+	select AR71XX_DEV_M25P80
+	select AR71XX_DEV_AP91_PCI if PCI
+	select AR71XX_DEV_GPIO_BUTTONS
+	select AR71XX_DEV_LEDS_GPIO
+	default n
+
 config AR71XX_MACH_TL_MR3X20
 	bool "TP-LINK TL-MR3220/3420 support"
 	select SOC_AR724X
--- a/target/linux/ar71xx/files/arch/mips/ar71xx/mach-om2p.c	(revision 0)
+++ b/target/linux/ar71xx/files/arch/mips/ar71xx/mach-om2p.c	(revision 0)
@@ -0,0 +1,185 @@
+/*
+ *  OpenMesh OM2P support
+ *
+ *  Copyright (C) 2011 Marek Lindner <marek@open-mesh.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+
+#include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/gpio.h>
+
+#include "machtype.h"
+#include "devices.h"
+#include "dev-ap91-pci.h"
+#include "dev-m25p80.h"
+#include "dev-leds-gpio.h"
+
+#define OM2P_GPIO_LED_POWER	0
+#define OM2P_GPIO_LED_GREEN	13
+#define OM2P_GPIO_LED_RED	14
+#define OM2P_GPIO_LED_YELLOW	15
+#define OM2P_GPIO_LED_LAN	16
+#define OM2P_GPIO_LED_WAN	17
+#define OM2P_GPIO_BTN_RESET	11
+
+#define OM2P_KEYS_POLL_INTERVAL		20	/* msecs */
+#define OM2P_KEYS_DEBOUNCE_INTERVAL	(3 * OM2P_KEYS_POLL_INTERVAL)
+
+#define OM2P_WAN_PHYMASK	BIT(4)
+
+static int led_ctrl_status = 0;
+
+static struct flash_platform_data om2p_flash_data = {
+	.type = "s25sl12800",
+	.name = "ar7240-nor0",
+};
+
+static struct gpio_led om2p_leds_gpio[] __initdata = {
+	{
+		.name		= "om2p:blue:power",
+		.gpio		= OM2P_GPIO_LED_POWER,
+		.active_low	= 1,
+		.default_state	= LEDS_GPIO_DEFSTATE_ON,
+	}, {
+		.name		= "om2p:red:wifi",
+		.gpio		= OM2P_GPIO_LED_RED,
+		.active_low	= 1,
+	}, {
+		.name		= "om2p:yellow:wifi",
+		.gpio		= OM2P_GPIO_LED_YELLOW,
+		.active_low	= 1,
+	}, {
+		.name		= "om2p:green:wifi",
+		.gpio		= OM2P_GPIO_LED_GREEN,
+		.active_low	= 1,
+	}, {
+		.name		= "om2p:blue:lan",
+		.gpio		= OM2P_GPIO_LED_LAN,
+		.active_low	= 1,
+		.default_state	= LEDS_GPIO_DEFSTATE_OFF,
+	}, {
+		.name		= "om2p:blue:wan",
+		.gpio		= OM2P_GPIO_LED_WAN,
+		.active_low	= 1,
+		.default_state	= LEDS_GPIO_DEFSTATE_OFF,
+	}
+};
+
+static struct resource om2p_gpio_resources[] = {
+	{
+		.name	= "gpio",
+		.start	= (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
+		.end	= (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
+		.flags	= 0,
+	},
+};
+
+static struct platform_device om2p_gpio = {
+	.name		= "GPIODEV",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(om2p_gpio_resources),
+	.resource	= om2p_gpio_resources,
+};
+
+
+static int led_ctrl_read(char *page, char **start, off_t offset,
+			    int count, int *eof, void *data)
+{
+	return snprintf(page, count, "%i\n", led_ctrl_status);
+}
+
+static int led_ctrl_write(struct file *file, const char *buffer,
+			  unsigned long count, void *data)
+{
+	char *led_ctrl_string;
+
+	led_ctrl_string = kmalloc(count, GFP_KERNEL);
+	if (!led_ctrl_string)
+		return -ENOMEM;
+
+	if (copy_from_user(led_ctrl_string, buffer, count))
+		goto end;
+
+	if (led_ctrl_string[0] == '1') {
+		led_ctrl_status = 1;
+		ar71xx_gpio_function_disable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
+					     AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
+					     AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
+					     AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
+					     AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
+	} else {
+		led_ctrl_status = 0;
+		ar71xx_gpio_function_enable(AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
+					    AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
+					    AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
+					    AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
+					    AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
+	}
+
+end:
+	kfree(led_ctrl_string);
+	return count;
+}
+
+static void led_ctrl_create(void)
+{
+	struct proc_dir_entry *proc_led_ctrl;
+
+	proc_led_ctrl = create_proc_entry("led_ctrl", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, NULL);
+
+	if (!proc_led_ctrl) {
+		printk(KERN_INFO "led_ctrl_create(): unable to create led_ctrl proc file\n");
+		return;
+	}
+
+	proc_led_ctrl->read_proc = led_ctrl_read;
+	proc_led_ctrl->write_proc = led_ctrl_write;
+	proc_led_ctrl->data = NULL;
+}
+
+static void __init om2p_setup(void)
+{
+	u8 *mac1 = (u8 *)KSEG1ADDR(0x1ffc0000);
+	u8 *mac2 = (u8 *)KSEG1ADDR(0x1ffc0000 + ETH_ALEN);
+	u8 *ee = (u8 *)KSEG1ADDR(0x1ffc1000);
+
+	ar71xx_add_device_m25p80(&om2p_flash_data);
+
+	ar71xx_add_device_mdio(~OM2P_WAN_PHYMASK);
+
+	ar71xx_init_mac(ar71xx_eth0_data.mac_addr, mac1, 0);
+	ar71xx_init_mac(ar71xx_eth1_data.mac_addr, mac2, 0);
+
+	ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
+	ar71xx_eth0_data.speed = SPEED_100;
+	ar71xx_eth0_data.duplex = DUPLEX_FULL;
+	ar71xx_eth0_data.phy_mask = OM2P_WAN_PHYMASK;
+
+	ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+	ar71xx_eth1_data.speed = SPEED_1000;
+	ar71xx_eth1_data.duplex = DUPLEX_FULL;
+	ar71xx_eth1_data.has_ar7240_switch = 1;
+
+	ar71xx_add_device_eth(0);
+	ar71xx_add_device_eth(1);
+
+	ap91_pci_init(ee, NULL);
+
+	ar71xx_add_device_leds_gpio(-1, ARRAY_SIZE(om2p_leds_gpio),
+					om2p_leds_gpio);
+
+	platform_device_register(&om2p_gpio);
+
+	led_ctrl_create();
+
+}
+
+MIPS_MACHINE(AR71XX_MACH_OM2P, "OM2P", "OpenMesh OM2P", om2p_setup);
--- a/target/linux/ar71xx/image/Makefile	(revision 27448)
+++ b/target/linux/ar71xx/image/Makefile	(working copy)
@@ -465,6 +465,20 @@
   endef
 endif
 
+define Image/Build/OpenMesh
+	$(call CompressLzma,$(KDIR)/vmlinux,$(KDIR)/vmlinux-$(2).bin.lzma)
+	$(call MkImageLzma,$(KDIR)/vmlinux-$(2).bin.lzma,$(KDIR)/vmlinux-$(2).uImage.bin)
+	-sh $(TOPDIR)/scripts/fwupgradecfg-gen.sh \
+		"$(BUILD_DIR)/om2p-fwupgrade.cfg" \
+		"$(KDIR)/vmlinux-$(2).uImage.bin" \
+		"$(KDIR)/root.$(1)"
+	-sh $(TOPDIR)/scripts/combined-ext-image.sh \
+		"OM2P" "$(BIN_DIR)/openwrt-ar71xx-om2p-ext-combined.img" \
+		"$(BUILD_DIR)/om2p-fwupgrade.cfg" "fwupgrade.cfg" \
+		"$(KDIR)/vmlinux-$(2).uImage.bin" "kernel" \
+		"$(KDIR)/root.$(1)" "rootfs"
+endef
+
 define Image/Build/Zcomax
 	$(call PatchKernelLzma,$(2),$(3))
 	$(call MkImageLzma,$(KDIR)/vmlinux-$(2).bin.lzma,$(KDIR)/vmlinux-$(2).uImage.bin)
@@ -674,6 +688,10 @@
 	$(call Image/Build/Template/$(fs_64k)/$(1),ZyXEL,nbg460n_550n_550nh,$(nbg460n_cmdline),NBG-460N)
 endef
 
+define Image/Build/Profile/OM2P
+        $(call Image/Build/Template/$(fs_squash)/$(1),OpenMesh,om2p,$(no_om2p_cmdline),OM2P)
+endef
+
 tlmr3220_cmdline=board=TL-MR3220 console=ttyS0,115200
 define Image/Build/Profile/TLMR3220V1
 	$(call Image/Build/Template/$(fs_64k)/$(1),TPLINK,tl-mr3220-v1,$(tlmr3220_cmdline),TL-MR3220v1)
@@ -812,6 +830,7 @@
 	$(call Image/Build/Profile/MZKW04NU,$(1))
 	$(call Image/Build/Profile/MZKW300NH,$(1))
 	$(call Image/Build/Profile/NBG_460N_550N_550NH,$(1))
+	$(call Image/Build/Profile/OM2P,$(1))
 	$(call Image/Build/Profile/PB42,$(1))
 	$(call Image/Build/Profile/PB44,$(1))
 	$(call Image/Build/Profile/PB92,$(1))
--- a/target/linux/ar71xx/base-files/lib/ar71xx.sh	(revision 27448)
+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh	(working copy)
@@ -61,6 +61,9 @@
 	*"NBG460N/550N/550NH")
 		name="nbg460n_550n_550nh"
 		;;
+	*OM2P)
+		name="om2p"
+		;;
 	*PB42)
 		name="pb42"
 		;;
--- a/target/linux/ar71xx/generic/profiles/openmesh.mk	(revision 0)
+++ b/target/linux/ar71xx/generic/profiles/openmesh.mk	(revision 0)
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/OM2P
+	NAME:=OpenMesh OM2P
+	PACKAGES:=kmod-ath9k
+endef
+
+define Profile/OM2P/Description
+	Package set optimized for the OpenMesh OM2P.
+endef
+
+$(eval $(call Profile,OM2P))
+
--- a/scripts/fwupgradecfg-gen.sh	(revision 0)
+++ b/scripts/fwupgradecfg-gen.sh	(revision 0)
@@ -0,0 +1,52 @@
+#/bin/sh
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+usage() {
+	echo "Usage: $0 <out file path> <kernel path> <rootfs path>"
+	rm -f $CFG_OUT
+	exit 1
+}
+
+[ "$#" -lt 3 ] && usage
+
+FLASH_BS=262144
+CHECK_BS=65536
+MAX_PART_SIZE=7168
+CFG_OUT=$1
+
+KERNEL_PATH=$2
+KERNEL_FLASH_ADDR=0x1c0000
+KERNEL_SIZE=$(stat -c%s "$KERNEL_PATH")
+KERNEL_MD5=$(md5=$(md5sum $KERNEL_PATH); echo ${md5%% *})
+KERNEL_PART_SIZE=$(size=$(($KERNEL_SIZE / $FLASH_BS)); [ $(($size * $FLASH_BS)) -lt $KERNEL_SIZE ] && size=$(($size + 1)); echo $(($size * $FLASH_BS / 1024)))
+
+ROOTFS_PATH=$3
+ROOTFS_FLASH_ADDR=$(addr=$(($KERNEL_FLASH_ADDR + ($KERNEL_PART_SIZE * 1024))); printf "0x%x" $addr)
+ROOTFS_SIZE=$(stat -c%s "$ROOTFS_PATH")
+ROOTFS_CHECK_BLOCKS=$((($ROOTFS_SIZE / $CHECK_BS) - 1))
+ROOTFS_MD5=$(md5=$(dd if=$ROOTFS_PATH bs=$CHECK_BS count=$ROOTFS_CHECK_BLOCKS 2>&- | md5sum); echo ${md5%% *})
+ROOTFS_CHECK_SIZE=$(printf '0x%x' $(($ROOTFS_CHECK_BLOCKS * $CHECK_BS)))
+ROOTFS_PART_SIZE=$(($MAX_PART_SIZE - $KERNEL_PART_SIZE))
+
+cat << EOF > $CFG_OUT
+[vmlinux]
+filename=kernel
+md5sum=$KERNEL_MD5
+flashaddr=$KERNEL_FLASH_ADDR
+checksize=0x0
+cmd_success=setenv bootseq 1,2; setenv kernel_size_1 $KERNEL_PART_SIZE; saveenv
+cmd_fail=reset
+
+[rootfs]
+filename=rootfs
+md5sum=$ROOTFS_MD5
+flashaddr=$ROOTFS_FLASH_ADDR
+checksize=$ROOTFS_CHECK_SIZE
+cmd_success=setenv bootseq 1,2; setenv kernel_size_1 $KERNEL_PART_SIZE; setenv rootfs_size_1 $ROOTFS_PART_SIZE; saveenv
+cmd_fail=reset
+EOF
--- a/scripts/combined-ext-image.sh	(revision 0)
+++ b/scripts/combined-ext-image.sh	(revision 0)
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# Copyright (C) 2011 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+# Write image header followed by all specified files
+# The header is padded to 64k, format is:
+#  CE               magic word ("Combined Extended Image") (2 bytes)
+#  <TYPE>           short description of the target device (10 bytes)
+#  <NUM FILES>      number of files following the header (2 byte)
+#  <file1_name>     name of the first file (20 bytes)
+#  <file1_length>   length of the first file encoded as zero padded 8 digit hex (8 bytes)
+#  <fileN_name>     name of the Nth file (20 bytes)
+#  <fileN_length>   length of the Nth file encoded as zero padded 8 digit hex (8 bytes)
+
+usage() {
+	echo "Usage: $0 <type> <ext filename> <file1> <filename1> [<file2> <filename2> <fileN> <filenameN>]"
+	[ "$IMG_OUT" ] && rm -f "$IMG_OUT"
+	exit 1
+}
+
+[ "$#" -lt 4 ] && usage
+
+IMG_TYPE=$1; shift
+IMG_OUT=$1; shift
+FILE_NUM=$(($# / 2))
+FILES=""
+
+printf "CE%-10s%02x" "$IMG_TYPE" $FILE_NUM > $IMG_OUT
+
+while [ "$#" -gt 1 ]
+   do
+      file=$1
+      filename=$2
+
+      [ ! -f "$file" ] && echo "Not a valid file: $file" && usage
+      FILES="$FILES $file"
+      printf "%-20s%08x" "$filename" $(stat -c "%s" "$file") >> $IMG_OUT
+      shift 2
+   done
+
+[ "$#" -eq 1 ] && echo "Filename not specified: $1" && usage
+
+mv $IMG_OUT $IMG_OUT.tmp
+dd if="$IMG_OUT.tmp" of="$IMG_OUT" bs=65536 conv=sync 2>/dev/null
+rm $IMG_OUT.tmp
+
+cat $FILES >> $IMG_OUT
