diff -uprN linux-2.6.20-at92_e1.4/arch/arm/mach-at91rm9200/Kconfig linux-2.6.20-at92_e1.4_spi/arch/arm/mach-at91rm9200/Kconfig
--- linux-2.6.20-at92_e1.4/arch/arm/mach-at91rm9200/Kconfig	2007-12-27 18:59:17.000000000 -0500
+++ linux-2.6.20-at92_e1.4_spi/arch/arm/mach-at91rm9200/Kconfig	2007-12-27 19:00:54.000000000 -0500
@@ -117,6 +117,14 @@ config MACH_SOM9260M
 	help
 	  Select this if you are using EMAC's SoM-9260M module.
 
+config ARMSTRONG_HWMS
+	bool "EMAC Armstrong HWMS Project"
+	depends on MACH_SOM9260M
+	help
+	  Support for the EMAC.Inc Armstrong HWMS project carrier
+	  board and peripherals. Enables compilation of drivers
+	  for ADC and counter.
+
 endif
 # ----------------------------------------------------------
 
diff -uprN linux-2.6.20-at92_e1.4/drivers/ioex/Kconfig linux-2.6.20-at92_e1.4_spi/drivers/ioex/Kconfig
--- linux-2.6.20-at92_e1.4/drivers/ioex/Kconfig	2007-12-27 18:59:17.000000000 -0500
+++ linux-2.6.20-at92_e1.4_spi/drivers/ioex/Kconfig	2007-12-27 19:00:54.000000000 -0500
@@ -33,7 +33,26 @@ config ECOREEX_DENM
 		depends on ECOREEX
         bool "DENM expansion I/O"
         ---help---
-        Provides autodetection and support for the DENM expansion        
+        Provides autodetection and support for the DENM expansion       
+
+config ECOREEX_HWMS
+        depends on ECOREEX
+        bool "Armstrong HWMS expansion I/O"
+        ---help---
+        Provides support for the Armstrong HWMS PLD
+        
+config ECOREEX_KEY
+        depends on ECOREEX
+        bool "Define static version key"
+        ---help---
+        Disable auto-detection of the PLD core by defining the version key
+
+config ECOREEX_STATIC_KEY
+        depends on ECOREEX_KEY
+        hex "Version key"
+        default "0xC0"
+        ---help---
+        Set the static version key for the PLD core 
 
 config BOARDSPEC
         tristate "board devices"
diff -uprN linux-2.6.20-at92_e1.4/drivers/ioex/ecoreex.c linux-2.6.20-at92_e1.4_spi/drivers/ioex/ecoreex.c
--- linux-2.6.20-at92_e1.4/drivers/ioex/ecoreex.c	2007-12-27 18:59:19.000000000 -0500
+++ linux-2.6.20-at92_e1.4_spi/drivers/ioex/ecoreex.c	2007-12-27 19:00:54.000000000 -0500
@@ -23,6 +23,62 @@
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 
+/*********************************************************************/
+#ifdef CONFIG_ECOREEX_HWMS
+#define CPLD_HWMS_NAME "HWMS GPI/O expansion R1.0"
+#define CPLD_HWMS 0xC0
+
+/**
+ * handler currently just indicates the that interrupt was handled and returns
+ */
+static irqreturn_t hwms_interrupt(int irq, void *na){
+    return IRQ_HANDLED;
+}
+
+static inline int CPLD_HWMS_map(unsigned long phys_addr, u8 *virt_addr, 
+        unsigned long size, const char *name, struct ecoreex_data *data)
+{   
+    gpio_t *gpio_counter;
+    gpio_t *gpio_control;
+    
+    if (request_mem_region(phys_addr, size, name) == NULL) {
+        printk("Could not obtain physical memory at %lx for EMAC core\n", phys_addr);
+        iounmap(virt_addr);
+    }
+    gpio_declare();
+    
+    gpio_control = gpio_device_create_unregistered(&virt_addr[0], NULL, "control");
+    ecoreex_setup_data_access(data->e_access, gpio_control);
+    /* no index read or write for the control -- only one register */
+    gpio_control->index_write = NULL;
+    gpio_control->index_read = NULL; 
+    
+    gpio_counter = gpio_device_create_unregistered(&virt_addr[1], NULL, "counter");
+    gpio_counter->index_write = gpio_index_write;
+    gpio_counter->index_read = gpio_index_read;
+    gpio_counter->range = 1;
+    ecoreex_setup_data_access(data->e_access, gpio_counter);
+    
+    gpio_register_class_device(gpio_control);
+    gpio_register_class_device(gpio_counter);
+    
+    /*
+     * Allocate the IRQ
+     */
+    if(data->irq){
+        int err = request_irq(data->irq, hwms_interrupt,IRQT_RISING,name, NULL);
+        if(err<0)
+            printk("ecoreex request for irq %d failed with %d\n",data->irq,err);
+        //printk("ecoreex request for irq %d failed\n",e->irq);
+
+        else set_irq_wake(data->irq,1);//if the board provides an irq, register it to wake up pm.
+    }
+
+    return 0;
+}
+
+#endif /* CONFIG_ECOREEX_HWMS */
+
 //---------------------------------------------------------------------------------
 #ifdef CONFIG_ECOREEX_TGPIO
 #define CPLD_BASE_NAME "iPac GPI/O expansion R1.0" 
@@ -271,13 +327,21 @@ return 0;
  */
 static inline void map_core(unsigned long phys_addr, unsigned long size, struct ecoreex_data *data)
 {
-	u8 *virt_addr = ioremap_nocache(phys_addr,size);
-	int version;
-	if(virt_addr==NULL)printk("could not remap physical memory at %lx for EMAC core\n",phys_addr);
-	else{
-		version =ioread8(&virt_addr[data->key_offset]);
+    u8 *virt_addr = ioremap_nocache(phys_addr,size);
+    int version = VERSION_KEY;
+    if(virt_addr==NULL)printk("could not remap physical memory at %lx for EMAC core\n",phys_addr);
+    else{
+//      version =ioread8(&virt_addr[data->key_offset]);
+        if (VERSION_KEY == -1)
+            version = data->e_access->ecoreex_key_read(data->key_offset, virt_addr);
+        /* else the version is predefined */
 		//printk("EMAC core version %x detected at %lx\n",version,phys_addr+data->key_offset );
 		switch(version){
+#ifdef CONFIG_ECOREEX_HWMS
+        case CPLD_HWMS:
+            CPLD_HWMS_map(phys_addr, virt_addr, size, CPLD_HWMS_NAME, data);
+        break;
+#endif
 			//-----------------------------------------------------------
 			#ifdef CONFIG_ECOREEX_TGPIO
 			case CPLD_BASE:
diff -uprN linux-2.6.20-at92_e1.4/include/linux/ioex/ecoreex.h linux-2.6.20-at92_e1.4_spi/include/linux/ioex/ecoreex.h
--- linux-2.6.20-at92_e1.4/include/linux/ioex/ecoreex.h	2007-12-27 18:59:18.000000000 -0500
+++ linux-2.6.20-at92_e1.4_spi/include/linux/ioex/ecoreex.h	2007-12-27 19:00:54.000000000 -0500
@@ -2,14 +2,61 @@
 #define ECOREEX_H_
 
 #include <linux/class/pwm.h>
+#include <linux/class/gpio.h>
 #include <linux/class/mmcprot.h>
 
+
+#ifdef CONFIG_ECOREEX_KEY
+#define VERSION_KEY CONFIG_ECOREEX_STATIC_KEY
+#else
+#define VERSION_KEY -1
+#endif
+
+/* Use this structure to specify read/write commands
+ * that differ from the direct ioread/write functions
+ * in the gpio class. If these members are not specified,
+ * the corresponding gpio function will be used as the
+ * default
+ */
+struct ecoreex_access_s
+{
+    gpio_data (*ecoreex_data_read)(struct gpio_s *gpio);
+    int (*ecoreex_data_write)(struct gpio_s *gpio,gpio_data data);
+    gpio_data (*ecoreex_ddr_read)(struct gpio_s *gpio); 
+    int (*ecoreex_ddr_write)(struct gpio_s *gpio,gpio_data data);
+    gpio_data (*ecoreex_index_read)(struct gpio_s *gpio);   
+    int (*ecoreex_index_write)(struct gpio_s *gpio,gpio_data data);
+    u8 (*ecoreex_key_read)(u8 index, u8 *virt_addr); /* function to read the key offset -- defaults to ioread8 */
+};
+
 struct ecoreex_data
 {
-	int	key_offset;
-	__u32 (*read_periodusa)(pwm_t *pwm);//a pwm input clock, defined as a period to minimize calculation
-	mmcslot_t *mmcslot;//structure for implementing mmc connections.
-	unsigned int irq;//irq number, 0 if no irq is used. 
+    int key_offset;
+#ifdef CONFIG_PWMCLASS
+    __u32 (*read_periodusa)(pwm_t *pwm);//a pwm input clock, defined as a period to minimize calculation
+#endif
+    mmcslot_t *mmcslot;//structure for implementing mmc connections.
+    unsigned int irq;
+    struct ecoreex_access_s *e_access;  
 };
 
+static inline u8 ecoreex_default_key_read(u8 index, u8 *virt_addr)
+{
+    return ioread8(&(virt_addr[index]));
+}
+
+static inline int ecoreex_setup_data_access(struct ecoreex_access_s *e_access, struct gpio_s *gpio)
+{
+    if (!e_access || !gpio) return -1;
+    if (e_access->ecoreex_data_read) gpio->data_read = e_access->ecoreex_data_read;
+    if (e_access->ecoreex_data_write) gpio->data_write = e_access->ecoreex_data_write;
+    if (e_access->ecoreex_ddr_read) gpio->ddr_read = e_access->ecoreex_ddr_read;
+    if (e_access->ecoreex_ddr_write) gpio->ddr_write = e_access->ecoreex_ddr_write;
+    if (e_access->ecoreex_index_read) gpio->index_read = e_access->ecoreex_index_read;
+    if (e_access->ecoreex_index_write) gpio->index_write = e_access->ecoreex_index_write;
+    if (!e_access->ecoreex_key_read) e_access->ecoreex_key_read = ecoreex_default_key_read;
+    
+    return 0;
+}
+
 #endif /*ECOREEX_H_*/
