**************************************************************
*SoM-9260M board support
*NZG/mwelling
*09/04/2007
*EMAC.Inc
**************************************************************
diff -uprN linux-2.6.20-at92_e1.1/arch/arm/mach-at91rm9200/Kconfig linux-2.6.20-at92_e1.1_dirty/arch/arm/mach-at91rm9200/Kconfig
--- linux-2.6.20-at92_e1.1/arch/arm/mach-at91rm9200/Kconfig	2007-09-04 16:24:41.000000000 -0400
+++ linux-2.6.20-at92_e1.1_dirty/arch/arm/mach-at91rm9200/Kconfig	2007-08-29 16:39:06.000000000 -0400
@@ -111,8 +111,13 @@ config MACH_AT91SAM9260EK
 	  Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933>
 
-endif
+config MACH_SOM9260M
+	bool "EMAC SoM-9260M"
+	depends on ARCH_AT91SAM9260
+	help
+	  Select this if you are using EMAC's SoM-9260M module.
 
+endif
 # ----------------------------------------------------------
 
 if ARCH_AT91SAM9261
diff -uprN linux-2.6.20-at92_e1.1/arch/arm/mach-at91rm9200/Makefile linux-2.6.20-at92_e1.1_dirty/arch/arm/mach-at91rm9200/Makefile
--- linux-2.6.20-at92_e1.1/arch/arm/mach-at91rm9200/Makefile	2007-09-04 16:24:41.000000000 -0400
+++ linux-2.6.20-at92_e1.1_dirty/arch/arm/mach-at91rm9200/Makefile	2007-08-29 16:39:06.000000000 -0400
@@ -29,6 +29,7 @@ obj-$(CONFIG_MACH_KAFA)		+= board-kafa.o
 
 # AT91SAM9260 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
+obj-$(CONFIG_MACH_SOM9260M) += board-som9260m.o
 
 # AT91SAM9261 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
diff -uprN linux-2.6.20-at92_e1.1/arch/arm/mach-at91rm9200/board-som9260m.c linux-2.6.20-at92_e1.1_dirty/arch/arm/mach-at91rm9200/board-som9260m.c
--- linux-2.6.20-at92_e1.1/arch/arm/mach-at91rm9200/board-som9260m.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.20-at92_e1.1_dirty/arch/arm/mach-at91rm9200/board-som9260m.c	2007-08-31 18:01:57.000000000 -0400
@@ -0,0 +1,358 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-som9260m.c
+ *
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2006 Atmel
+ *  Copyright (C) 2007 EMAC.Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/clk.h>
+#include <linux/ioex/ecoreex.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/at91sam9260.h>
+#include <asm/arch/at91sam926x_mc.h>
+
+#include "generic.h"
+
+
+/*
+ * Serial port configuration.
+ *    0 .. 5 = USART0 .. USART5
+ *    6      = DBGU
+ */
+static struct at91_uart_config __initdata ek_uart_config = {
+	.console_tty	= 0,				/* ttyS0 */
+	.nr_tty		= 5,
+	.tty_map	= { 6, 0, 1, 2, 3, -1, -1 }	/* ttyS0, ..., ttyS6 */
+};
+
+static void __init ek_map_io(void)
+{
+	/* Initialize processor: 18.432 MHz crystal */
+	at91sam9260_initialize(18432000);
+
+	/* Setup the serial ports and console */
+	at91_init_serial(&ek_uart_config);
+}
+
+static void __init ek_init_irq(void)
+{
+	at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+	.ports		= 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+	.vbus_pin	= AT91_PIN_PC5,
+	.pullup_pin	= 0,		/* pull-up driven by UDC */
+};
+
+
+/*
+ * AT73C213
+ */
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+static struct atmel_at73c213_data at73c213_data;
+
+static u64 ssc_dmamask = 0xffffffffUL;
+static struct resource ssc_resource[] = {
+	[0] = {
+		.start	= AT91SAM9260_BASE_SSC,
+		.end	= AT91SAM9260_BASE_SSC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9260_ID_SSC,
+		.end	= AT91SAM9260_ID_SSC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9260_ssc_device = {
+	.name		= "atmel_ssc_at73c213",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &ssc_dmamask,
+				.coherent_dma_mask	= 0xffffffff,
+				.platform_data		= &at73c213_data,
+	},
+	.resource		= ssc_resource,
+	.num_resources	= ARRAY_SIZE(ssc_resource),
+};
+void __init at91_add_device_ssc_at73c213(void)
+{
+	struct clk *at73_clk;
+	struct clk *ssc_clk;
+	struct clk *parent_clk;
+
+	/* Set SSC1 IO */
+	at91_set_A_periph(AT91_PIN_PB16, 0);		/* TK0 */
+	at91_set_A_periph(AT91_PIN_PB17, 0);		/* TF0 */
+	at91_set_A_periph(AT91_PIN_PB18, 0);		/* TD0 */
+
+	/* AT73C213 MCK Clock */
+	at91_set_B_periph(AT91_PIN_PC1, 0);		/* PCK0 */
+
+	at73_clk = clk_get(NULL, "pck0");
+	parent_clk = clk_get(NULL, "plla");
+	clk_set_parent(at73_clk, parent_clk);
+	clk_set_rate(at73_clk, 12416000);
+	clk_enable(at73_clk);
+
+	ssc_clk = clk_get(NULL, "ssc_clk");
+	clk_enable(ssc_clk);
+
+	at73c213_data.ssc_div  = 32;
+	at73c213_data.at73_mck = at73_clk;
+
+	platform_device_register(&at91sam9260_ssc_device);
+}
+#else
+	void __init at91_add_device_ssc_at73c213(void) {}
+#endif
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+#if !defined(CONFIG_MMC_AT91)
+	{	/* DataFlash chip */
+		.modalias	= "mtd_dataflash",
+		.chip_select	= 1,
+		.max_speed_hz	= 15 * 1000 * 1000,
+		.bus_num	= 0,
+	},
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+	{	/* DataFlash card */
+		.modalias	= "mtd_dataflash",
+		.chip_select	= 0,
+		.max_speed_hz	= 15 * 1000 * 1000,
+		.bus_num	= 0,
+	},
+#endif
+#endif
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+	{	/* AT73C213 DAC */
+		.modalias	= "at73c213",
+		.chip_select	= 0,
+		.max_speed_hz	= 10 * 1000 * 1000,
+		.bus_num	= 1,
+	},
+#endif
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct __initdata at91_eth_data ek_macb_data = {
+	.phy_irq_pin	= AT91_PIN_PA7,
+	.is_rmii	= 0,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+	{
+		.name	= "Boot Partition",
+		.offset	= 0,
+		.size	= 64 * 2 * 1024,
+	},
+	{
+		.name	= "UBoot Partition",
+		.offset	= 64 * 2 * 1024,
+		.size	= 64 * 14 * 1024,
+	},
+ 	{
+ 		.name	= "Kernel Partition",
+ 		.offset	= 64 * 16 * 1024,
+ 		.size	= 64 * 48 * 1024,
+ 	},
+ 	{
+ 		.name	= "Disk Partition",
+ 		.offset	= 64 * 64 * 1024,
+ 		.size	= 64 * 256 * 1024,
+ 	},
+};
+
+static struct mtd_partition *nand_partitions(int size, int *num_partitions)
+{
+	*num_partitions = ARRAY_SIZE(ek_nand_partition);
+	return ek_nand_partition;
+}
+
+static struct at91_nand_data __initdata ek_nand_data = {
+	.ale		= 21,
+	.cle		= 22,
+//	.det_pin	= ... not connected
+	.rdy_pin	= AT91_PIN_PC13,
+	.enable_pin	= AT91_PIN_PC14,
+	.partition_info	= nand_partitions,
+#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+	.bus_width_16	= 1,
+#else
+	.bus_width_16	= 0,
+#endif
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata ek_mmc_data = {
+	.slot_b		= 1,
+	.wire4		= 1,
+//	.det_pin	= ... not connected
+//	.wp_pin		= ... not connected
+//	.vcc_pin	= ... not connected
+};
+
+/************************************************************
+ * IOEX Device
+ * Onboard EMAC I/O core platform device used by the ecoreex driver
+ */
+#define CS4_START ((unsigned long)0x50000000)
+#define CS4_END  ((unsigned long)0x5FFFFFFF)
+#define CS4_LEN  ((unsigned long)(CS0_END-CS0_START+1))
+#define CPLDKEY 0xF
+
+static struct ecoreex_data som9260m_ecoreex_data = {
+	.key_offset	= CPLDKEY,
+};
+
+static struct resource som9260m_ecoreex_resource = {
+		.start	= CS4_START,
+		.end	= CS4_END,
+		.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device som9260m_ecoreex_device = {
+	.name		= "ecoreex",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &som9260m_ecoreex_data,
+	},
+	.num_resources	= 1,
+	.resource	= &som9260m_ecoreex_resource,
+};
+
+/**
+ * enable a generic memory map on cs4 and required module I/O
+ */
+static inline void cs4_setup(void){
+	at91_sys_write(AT91_SMC_SETUP(4),
+			0
+	);
+
+	at91_sys_write(AT91_SMC_PULSE(4),
+			AT91_SMC_NWEPULSE_(4)|
+			AT91_SMC_NCS_WRPULSE_(6)|
+			AT91_SMC_NRDPULSE_(3)|
+			AT91_SMC_NCS_RDPULSE_(5)
+	);
+	
+	at91_sys_write(AT91_SMC_CYCLE(4),
+			AT91_SMC_NWECYCLE_(5)|
+			AT91_SMC_NRDCYCLE_(6) 
+	);
+	
+	at91_sys_write(AT91_SMC_MODE(4),
+			AT91_SMC_READMODE|
+			AT91_SMC_WRITEMODE|
+			AT91_SMC_EXNWMODE_DISABLE|
+			AT91_SMC_DBW_8|
+			AT91_SMC_TDF_(0X0f)
+	);
+		
+	//at91_sys_write(AT91C_PIOC_PDR,0x100);
+	//at91_sys_write(AT91C_PIOC_OER,0x100);
+	
+	at91_set_A_periph(AT91_PIN_PC8, 1);	
+}
+
+static inline void at91_add_device_ecoreex4(void){
+	printk("at91_add_device_ecoreex4\n");
+	cs4_setup();
+	platform_device_register(&som9260m_ecoreex_device);
+}
+
+
+
+/************************************************************/
+
+
+static void __init ek_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* USB Host */
+	at91_add_device_usbh(&ek_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&ek_udc_data);
+	/* SPI */
+	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+	/* NAND */
+	at91_add_device_nand(&ek_nand_data);
+	/* Ethernet */
+	at91_add_device_eth(&ek_macb_data);
+	/* MMC */
+	at91_add_device_mmc(0, &ek_mmc_data);
+	/* AT73C213 & SSC port */
+	at91_add_device_ssc_at73c213();
+	
+	at91_add_device_ecoreex4();
+	
+}
+
+MACHINE_START(AT91SAM9260EK, "EMAC SoM-9260M")
+	/* Maintainer: EMAC.Inc */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91sam926x_timer,
+	.map_io		= ek_map_io,
+	.init_irq	= ek_init_irq,
+	.init_machine	= ek_board_init,
+MACHINE_END
diff -uprN linux-2.6.20-at92_e1.1/include/asm-arm/arch-at91rm9200/at91sam9260.h linux-2.6.20-at92_e1.1_dirty/include/asm-arm/arch-at91rm9200/at91sam9260.h
--- linux-2.6.20-at92_e1.1/include/asm-arm/arch-at91rm9200/at91sam9260.h	2007-09-04 16:24:41.000000000 -0400
+++ linux-2.6.20-at92_e1.1_dirty/include/asm-arm/arch-at91rm9200/at91sam9260.h	2007-08-29 16:39:06.000000000 -0400
@@ -117,12 +117,12 @@
 #define AT91SAM9XE_SRAM_BASE	0x00300000	/* Internal SRAM base address */
 
 
-#if 0
+#if 1
 /*
  * PIO pin definitions (peripheral A/B multiplexing).
  */
-
-// TODO: Add
+#define AT91C_PIOC_PDR  (AT91_PIOC + 4)
+#define AT91C_PIOC_OER  (AT91_PIOC + 10)
 
 #endif
 
