diff -ur adm6996/Makefile adm6996.cx82100/Makefile
--- adm6996/Makefile	2004-05-08 13:29:21.000000000 +0200
+++ adm6996.cx82100/Makefile	2006-08-27 15:30:29.000000000 +0200
@@ -1,11 +1,15 @@
-KERNEL       = ../../linux/linux
+KERNEL       = ../kernels/linux-2.4.31/
+
+ARCH		= armnommu
+CROSS_COMPILE	= arm-elf-
+
 INCLUDES     = -I. -I$(KERNEL)/include -I$(KERNEL)/drivers/media/video
 
 SOURCES      = adm6996.c
 TARGETS      = $(SOURCES:.c=.o)
 
 all:
-	make -C $(KERNEL) SUBDIRS=`pwd` EXTRA_CFLAGS="$(INCLUDES) $(KCFLAGS)" modules
+	ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) make -C $(KERNEL) SUBDIRS=`pwd` EXTRA_CFLAGS="$(INCLUDES) $(KCFLAGS)" modules
 	
 O_TARGET := adm6996.o
 
diff -ur adm6996/adm6996.h adm6996.cx82100/adm6996.h
--- adm6996/adm6996.h	2004-07-10 14:19:09.000000000 +0200
+++ adm6996.cx82100/adm6996.h	2006-08-27 15:43:35.000000000 +0200
@@ -1,12 +1,14 @@
 #ifndef ADM6996_H
 #define ADM6996_H
-#include <typedefs.h>
+//JH #include <typedefs.h>
+#include "typedefs.h" //JH
+#include <linux/types.h> //JH
 
 #define ADM6996_VERSION "3.2 by Nikki Chumakov, 10-Jul-2004"
 #define ADM6996_MINOR 99
 
-extern void *bcm947xx_sbh;
-#define sbh bcm947xx_sbh
+//JH extern void *bcm947xx_sbh;
+//JH #define sbh bcm947xx_sbh
 
 /* Private state per ADM switch */
 typedef struct {
@@ -88,7 +90,7 @@
 };
 	
 /* Forward declarations */
-adm_info_t *adm_attach(void *sbh); 
+adm_info_t *adm_attach(); 
 void adm_detach(adm_info_t *adm);
 void adm_enable_device(adm_info_t *adm, char *vars);
 int adm_config_vlan(adm_info_t *adm, char *vars);
diff -ur adm6996/adm_hw.c adm6996.cx82100/adm_hw.c
--- adm6996/adm_hw.c	2004-03-30 01:05:55.000000000 +0200
+++ adm6996.cx82100/adm_hw.c	2006-08-27 15:51:46.000000000 +0200
@@ -16,38 +16,22 @@
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/bsptypes.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/cnxtirq.h>
+#include <asm/arch/cnxtbsp.h>
+#include <asm/arch/syslib.h>
+
 #include "adm6996.h"
 
 
-#include <typedefs.h>
-#include <osl.h>
-#include <sbutils.h>
-#include <bcmutils.h>
-#include <bcmendian.h>
-
-#if 0
-#define GPIO0 0
-#define GPIO1 1
-#define GPIO2 2
-#define GPIO3 3
-#define GPIO4 4
-#define GPIO5 5
-#define GPIO6 6
-#define GPIO7 7
-#define GPIO8 8
-
-#define B_RESET   1<<GPIO0
-#define B_ECS   1<<GPIO2
-#define B_ECK   1<<GPIO3
-#define B_EDO   1<<GPIO4
-#define B_EDI   1<<GPIO5
-
-#define EEDO_PIN  4
-#define EECS_PIN  2
-#define EECK_PIN  3
-#define EEDI_PIN  5
-#define RESET_PIN 0
-#endif
+//JH #include <typedefs.h>
+#include "typedefs.h" //JH
+//JH #include <osl.h>
+//JH #include <sbutils.h>
+//JH #include <bcmutils.h>
+//JH #include <bcmendian.h>
 
 // #include <et_dbg.h>
 
@@ -57,95 +41,23 @@
 #define EECS_SETUP_TIME	1	/* 1us - max(adm no, 93c 200ns) */
 
 /* Forward declarations */
-adm_info_t *adm_attach(void *sbh); // , char *vars);
+adm_info_t *adm_attach();
 void adm_detach(adm_info_t *adm);
 void adm_enable_device(adm_info_t *adm, char *vars);
 int adm_config_vlan(adm_info_t *adm, char *vars);
 
+/* JH
 extern uint32 sb_gpioouten(void *sbh, uint32 mask, uint32 val);
 extern uint32 sb_gpioout(void *sbh, uint32 mask, uint32 val);
 extern uint32 sb_gpioin(void *sbh);
 extern uint32 sb_gpiointmask(void *sbh, uint32 mask, uint32 val);
+JH */
 
 #define OUTENMASK B_RESET|B_ECS|B_ECK|B_EDI
 #define CFGMASK   B_ECS|B_ECK|B_EDI
 #define BIT(x)  (1 << (x))
 #define ASSERT(exp)   do {} while (0)
 
-#if 0
-void
-conf_gpio(int x)
-{
-  ASSERT(sbh);
-
-  /* Enable all of output pins */
-  sb_gpioouten(sbh, OUTENMASK, OUTENMASK);
-
-  /* We don't want the B_RESET pin changed, unless
-   * it tries to set the B_RESET pin.
-   */
-  if (x & B_RESET)
-    sb_gpioout(sbh, OUTENMASK, x);
-  else
-    sb_gpioout(sbh, CFGMASK, x);
-
-}
-
-void
-gpio_line_set(int x, unsigned int value)
-{
-  ASSERT(sbh);
-
-  if (value == 1)
-    sb_gpioout(sbh, BIT(x), BIT(x));
-  else if (value == 0)
-    sb_gpioout(sbh, BIT(x), 0);
-}
-
-void
-gpio_line_get(int x, int *value)
-{
-  ASSERT(sbh);
-
-  *value = (sb_gpioin(sbh) >> x) & 0x1;
-}
-void
-gpio_line_config_in(int x)
-{
-  ASSERT(sbh);
-
-  sb_gpioouten(sbh, BIT(x), 0);
-  sb_gpiointmask(sbh, BIT(x), BIT(x));
-}
-
-void
-gpio_line_config_out(int x)
-{
-  ASSERT(sbh);
-
-  sb_gpiointmask(sbh, BIT(x), 0);
-  sb_gpioouten(sbh, BIT(x), BIT(x));
-}
-
-void
-gpio_line_config_out_all(void)
-{
-  ASSERT(sbh);
-
-  sb_gpioouten(sbh, OUTENMASK, OUTENMASK);
-}
-
-inline static void SerialDelay(int count)
-{
-	udelay(count);
-}
-
-static void InitSerialInterface(void)
-{
-	gpio_line_set(EECK_PIN, 0);
-	gpio_line_set(EEDI_PIN, 0);
-}
-#endif
 /* Return gpio number assigned to the named pin */
 /*
 * Variable should be in format:
@@ -163,33 +75,41 @@
 	uint8 i;
 
 	/* Go thru all possibilities till a match in pin name */
+/* JH
 	for (i = 0; i < NUMGPIO; i ++) {
 		sprintf(name, "gpio%d", i);
 		val = getvar(vars, name);
 		if (val && !strcmp(val, pin_name))
 			return (1 << i);
 	}
+JH */
 	return def_gpio;
 }
 
 /* Allocate private resource */
 adm_info_t *
-adm_attach(void *sbh) // , char *vars)
+adm_attach()
 {
 	adm_info_t *adm;
 
 	/* Allocate private data */
-	if (!(adm = MALLOC(sizeof(adm_info_t)))) {
+	if (!(adm = kmalloc(sizeof(adm_info_t), GFP_ATOMIC))) {
 		printk("adm_attach: out of memory");
 		return NULL;
 	}
-	bzero((char *) adm, sizeof(adm_info_t));
-	adm->sbh = sbh;
+	memset((char *) adm, '\0', sizeof(adm_info_t));
+//JH	adm->sbh = sbh;
 
 	/* Init GPIO mapping. Default GPIO: 2, 3, 4 */
+/* JH
 	adm->eecs = (1 << 2);
 	adm->eesk = (1 << 3);
 	adm->eedi = (1 << 5);
+JH */
+
+	adm->eecs = 6;
+	adm->eedi = 18;
+	adm->eesk = 7;
 
 #if 0
 	/* nvram overrides */
@@ -206,7 +126,7 @@
 adm_detach(adm_info_t *adm)
 {
 	/* Free private data */
-	MFREE(adm, sizeof(adm_info_t));
+	kfree(adm);
 }
 
 /*
@@ -219,24 +139,24 @@
 
 
 /* Enable outputs with specified value to the chip */
-static void
-adm_enout(adm_info_t *adm, uint8 pins, uint8 val)
-{
-	/* Prepare GPIO output value */
-	sb_gpioout(adm->sbh, pins, val);
-	/* Enable GPIO outputs */
-	sb_gpioouten(adm->sbh, pins, pins);
-	OSL_DELAY(EECK_EDGE_TIME);
-}
+//JH static void
+//adm_enout(adm_info_t *adm, uint8 pins, uint8 val)
+//{
+//	/* Prepare GPIO output value */
+//	sb_gpioout(adm->sbh, pins, val);
+//	/* Enable GPIO outputs */
+//	sb_gpioouten(adm->sbh, pins, pins);
+//	udelay(EECK_EDGE_TIME);
+//}
 
 /* Disable outputs to the chip */
-static void
-adm_disout(adm_info_t *adm, uint8 pins)
-{
-	/* Disable GPIO outputs */
-	sb_gpioouten(adm->sbh, pins, 0);
-	OSL_DELAY(EECK_EDGE_TIME);
-}
+//JH static void
+//adm_disout(adm_info_t *adm, uint8 pins)
+//{
+//	/* Disable GPIO outputs */
+//	sb_gpioouten(adm->sbh, pins, 0);
+//	udelay(EECK_EDGE_TIME);
+//}
 
 /* Advance clock(s) */
 static void
@@ -245,11 +165,13 @@
 	int i;
 	for (i = 0; i < clocks; i ++) {
 		/* Clock high */
-		sb_gpioout(adm->sbh, adm->eesk, adm->eesk);
-		OSL_DELAY(EECK_EDGE_TIME);
+//JH		sb_gpioout(adm->sbh, adm->eesk, adm->eesk);
+WriteGPIOData(adm->eesk, 1);
+		udelay(EECK_EDGE_TIME);
 		/* Clock low */
-		sb_gpioout(adm->sbh, adm->eesk, 0);
-		OSL_DELAY(EECK_EDGE_TIME);
+//JH		sb_gpioout(adm->sbh, adm->eesk, 0);
+WriteGPIOData(adm->eesk, 0);
+		udelay(EECK_EDGE_TIME);
 	}
 }	
 
@@ -261,7 +183,13 @@
 	uint8 mask;
 
 	if (cs)
-		sb_gpioout(adm->sbh, adm->eecs, adm->eecs);
+//JH		sb_gpioout(adm->sbh, adm->eecs, adm->eecs);
+WriteGPIOData(adm->eecs, 1);
+
+			/* Clock low */
+//JH			sb_gpioout(adm->sbh, adm->eesk, 0);
+WriteGPIOData(adm->eesk, 0);
+			udelay(EECK_EDGE_TIME);
 	
 	/* read sequence */
 	/* Byte assemble from MSB to LSB */
@@ -270,31 +198,38 @@
 		/* Bit bang from MSB to LSB */
 		for (mask = 0x80, byte = 0; mask && rbits > 0; mask >>= 1, rbits --) {
 			uint8 gp;
-			
-			/* Clock low */
-			sb_gpioout(adm->sbh, adm->eesk, 0);
-			OSL_DELAY(EECK_EDGE_TIME);
 
-			gp = sb_gpioin(adm->sbh);
-			
-			if (gp & adm->eedi)
-				byte |= mask;
 				
 			/* Clock high */
-			sb_gpioout(adm->sbh, adm->eesk, adm->eesk);
-			OSL_DELAY(EECK_EDGE_TIME);
+//JH			sb_gpioout(adm->sbh, adm->eesk, adm->eesk);
+WriteGPIOData(adm->eesk, 1);
+			udelay(EECK_EDGE_TIME);
+
+//JH			gp = sb_gpioin(adm->sbh);
+gp = ReadGPIOData(adm->eedi);
+			
+//JH			if (gp & adm->eedi)
+			if (gp)
+				byte |= mask;
+
+			/* Clock low */
+//JH			sb_gpioout(adm->sbh, adm->eesk, 0);
+WriteGPIOData(adm->eesk, 0);
+			udelay(EECK_EDGE_TIME);
 		}
 
 		*rbuf++ = byte;
 	}
 
 	/* Clock low */
-	sb_gpioout(adm->sbh, adm->eesk, 0);
-	OSL_DELAY(EECK_EDGE_TIME);
+//JH	sb_gpioout(adm->sbh, adm->eesk, 0);
+WriteGPIOData(adm->eesk, 0);
+	udelay(EECK_EDGE_TIME);
 
 	/* CS low */
 	if (cs)
-		sb_gpioout(adm->sbh, adm->eecs, 0);
+//JH		sb_gpioout(adm->sbh, adm->eecs, 0);
+WriteGPIOData(adm->eecs, 0);
 }
 
 /* Write a bit stream to the chip */
@@ -306,42 +241,54 @@
 
 	/* CS high/low */
 	if (cs)
-		sb_gpioout(adm->sbh, adm->eecs, adm->eecs);
+//JH		sb_gpioout(adm->sbh, adm->eecs, adm->eecs);
+WriteGPIOData(adm->eecs, 1);
 	else
-		sb_gpioout(adm->sbh, adm->eecs, 0);
-	OSL_DELAY(EECK_EDGE_TIME);
+//JH		sb_gpioout(adm->sbh, adm->eecs, 0);
+WriteGPIOData(adm->eecs, 0);
+	udelay(EECK_EDGE_TIME);
 
 	/* Byte assemble from MSB to LSB */
 	for (i = 0; i < len; i++) {
 		/* Bit bang from MSB to LSB */
 		for (mask = 0x80; mask && bits > 0; mask >>= 1, bits --) {
 			/* Clock low */
-			sb_gpioout(adm->sbh, adm->eesk, 0);
-			OSL_DELAY(EECK_EDGE_TIME);
+//JH			sb_gpioout(adm->sbh, adm->eesk, 0);
+WriteGPIOData(adm->eesk, 0);
+			udelay(EECK_EDGE_TIME);
 
 			/* Output on rising edge */
 			if (mask & buf[i])
-				sb_gpioout(adm->sbh, adm->eedi, adm->eedi);
+//JH				sb_gpioout(adm->sbh, adm->eedi, adm->eedi);
+WriteGPIOData(adm->eedi, 1);
 			else
-				sb_gpioout(adm->sbh, adm->eedi, 0);
-			OSL_DELAY(EEDI_SETUP_TIME);
+//JH				sb_gpioout(adm->sbh, adm->eedi, 0);
+WriteGPIOData(adm->eedi, 0);
+			udelay(EEDI_SETUP_TIME);
+
 		
 			/* Clock high */
-			sb_gpioout(adm->sbh, adm->eesk, adm->eesk);
-			OSL_DELAY(EECK_EDGE_TIME);
+//JH			sb_gpioout(adm->sbh, adm->eesk, adm->eesk);
+WriteGPIOData(adm->eesk, 1);
+			udelay(EECK_EDGE_TIME);
+
 		}
 	}
 
 	/* Clock low */
-	sb_gpioout(adm->sbh, adm->eesk, 0);
-	OSL_DELAY(EECK_EDGE_TIME);
+//JH	sb_gpioout(adm->sbh, adm->eesk, 0);
+WriteGPIOData(adm->eesk, 0);
+	udelay(EECK_EDGE_TIME);
 
 	/* CS low */
 	if (cs)
-		sb_gpioout(adm->sbh, adm->eecs, 0);
+//JH		sb_gpioout(adm->sbh, adm->eecs, 0);
+WriteGPIOData(adm->eecs, 0);
 }
 
 
+// domain=table select
+// addr=register address
 void
 adm_rreg(adm_info_t *adm, uint8 domain, uint8 addr, uint32* val)
 {
@@ -361,20 +308,38 @@
 
 	// printk ("enabling gpio output.. (sbh=%p)\n", adm->sbh);
 	/* Enable GPIO outputs with all pins to 0 */
-	adm_enout(adm, (uint8)(adm->eecs | adm->eesk | adm->eedi), 0);
+//JH	adm_enout(adm, (uint8)(adm->eecs | adm->eesk | adm->eedi), 0);
+/* Order of WriteGPIOData/SetGPIODir ok??? */
+/*
+WriteGPIOData(adm->eecs, 0);
+WriteGPIOData(adm->eesk, 0);
+WriteGPIOData(adm->eedi, 0);
+*/
+SetGPIODir(adm->eecs, GP_OUTPUT);
+SetGPIODir(adm->eedi, GP_OUTPUT);
+SetGPIODir(adm->eesk, GP_OUTPUT);
+WriteGPIOData(adm->eecs, 0);
+WriteGPIOData(adm->eedi, 0);
+WriteGPIOData(adm->eesk, 0);
+udelay(EECK_EDGE_TIME);
 
 	// printk ("adm write 46...\n");
 
 	adm_write(adm, 0, bits, 46);
-	adm_disout (adm, (uint8)(adm->eedi));
+//JH	adm_disout (adm, (uint8)(adm->eedi));
+SetGPIODir(adm->eedi, GP_INPUT);
+//!!!udelay(EECK_EDGE_TIME);
 	adm_adclk(adm, 2);
 	adm_read (adm, 0, rbits, 32);
 
 	/* Extra clock(s) required per datasheet */
-	adm_adclk(adm, 2);
+	adm_adclk(adm, 5);
 
 	/* Disable GPIO outputs */
-	adm_disout(adm, (uint8)(adm->eecs | adm->eesk));
+//JH	adm_disout(adm, (uint8)(adm->eecs | adm->eesk));
+SetGPIODir(adm->eecs, GP_INPUT);
+SetGPIODir(adm->eesk, GP_INPUT);
+udelay(EECK_EDGE_TIME);
 
 	*val = (rbits[0]<<24) | (rbits[1]<<16) | (rbits[2]<<8) | rbits[3];
 }
@@ -401,7 +366,18 @@
 		addr, val, bits[0], bits[1], bits[2], bits[3]);
 
 	/* Enable GPIO outputs with all pins to 0 */
-	adm_enout(adm, (uint8)(adm->eecs | adm->eesk | adm->eedi), 0);
+//	adm_enout(adm, (uint8)(adm->eecs | adm->eesk | adm->eedi), 0);
+/* Order of WriteGPIOData/SetGPIODir ok??? */
+WriteGPIOData(adm->eecs, 0);
+WriteGPIOData(adm->eesk, 0);
+WriteGPIOData(adm->eedi, 0);
+SetGPIODir(adm->eecs, GP_OUTPUT);
+SetGPIODir(adm->eesk, GP_OUTPUT);
+SetGPIODir(adm->eedi, GP_OUTPUT);
+WriteGPIOData(adm->eecs, 0);
+WriteGPIOData(adm->eesk, 0);
+WriteGPIOData(adm->eedi, 0);
+udelay(EECK_EDGE_TIME);
 
 	/* Write cmd. Total 27 bits */
 	adm_write(adm, 1, bits, 27);
@@ -410,7 +386,11 @@
 	adm_adclk(adm, 2);
 
 	/* Disable GPIO outputs */
-	adm_disout(adm, (uint8)(adm->eecs | adm->eesk | adm->eedi));
+//JH	adm_disout(adm, (uint8)(adm->eecs | adm->eesk | adm->eedi));
+SetGPIODir(adm->eecs, GP_INPUT);
+SetGPIODir(adm->eesk, GP_INPUT);
+SetGPIODir(adm->eedi, GP_INPUT);
+udelay(EECK_EDGE_TIME);
 }
 
 
@@ -517,8 +497,8 @@
 
 		/* get nvram port settings */
 		sprintf(vlan_group, "vlan%dports", i);
-		ports = getvar(vars, vlan_group);
-		if (!ports)
+//JH		ports = getvar(vars, vlan_group);
+//JH		if (!ports)
 			continue;
 
 		/*
@@ -527,7 +507,7 @@
 		* cpu port needs special handing to support pmon/cfe/linux...
 		*/
 		foreach (port, ports, next) {
-			int port_num = bcm_atoi(port);
+			int port_num = simple_strtol(port, (char **)NULL, 10);
 			uint16 port_cfg;
 			
 			/* make sure port # is within the range */
@@ -605,21 +585,36 @@
 	* reset logic therefore we must explicitly perform the
 	* sequece in software.
 	*/
+
+SetGPIODir(adm->eesk, GP_OUTPUT);
+SetGPIODir(adm->eedi, GP_OUTPUT);
+SetGPIODir(adm->eecs, GP_OUTPUT);
+SetGPIODir(5, GP_OUTPUT);
+WriteGPIOData(5, 0);
+
 	/* Keep RC high for at least 20ms */
-	adm_enout(adm, rc, rc);
+//JH 	adm_enout(adm, rc, rc);
+WriteGPIOData(5, 1);
 	for (i = 0; i < 20; i ++)
-		OSL_DELAY(1000);
+		udelay(1000);
 	/* Keep RC low for at least 100ms */
-	adm_enout(adm, rc, 0);
+//JH 	adm_enout(adm, rc, 0);
+WriteGPIOData(5, 0);
 	for (i = 0; i < 100; i++)
-		OSL_DELAY(1000);
+		udelay(1000);
 	/* Set default configuration */
-	adm_enout(adm, (uint8)(adm->eesk | adm->eedi), adm->eesk);
+//JH 	adm_enout(adm, (uint8)(adm->eesk | adm->eedi), adm->eesk);
+WriteGPIOData(adm->eesk, 1);
+WriteGPIOData(adm->eedi, 0);
 	/* Keep RC high for at least 30ms */
-	adm_enout(adm, rc, rc);
+//JH 	adm_enout(adm, rc, rc);
+WriteGPIOData(5, 1);
 	for (i = 0; i < 30; i++)
-		OSL_DELAY(1000);
+		udelay(1000);
 	/* Leave RC high and disable GPIO outputs */
-	adm_disout(adm, (uint8)(adm->eecs | adm->eesk | adm->eedi));
+//JH 	adm_disout(adm, (uint8)(adm->eecs | adm->eesk | adm->eedi));
+WriteGPIOData(adm->eecs, 0);
+WriteGPIOData(adm->eesk, 0);
+WriteGPIOData(adm->eedi, 0);
 }
 
diff -ur adm6996/adm_init.c adm6996.cx82100/adm_init.c
--- adm6996/adm_init.c	2004-05-08 13:28:29.000000000 +0200
+++ adm6996.cx82100/adm_init.c	2006-08-27 15:43:48.000000000 +0200
@@ -16,13 +16,14 @@
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 
-#include <typedefs.h>
-#include <sbconfig.h>
-#include <sbpci.h>
-#include <sbutils.h>
-#include <bcmutils.h>
-#include <bcmdevs.h>
-#include <bcmenet47xx.h>
+//JH #include <typedefs.h>
+#include "typedefs.h" //JH
+//JH #include <sbconfig.h>
+//JH #include <sbpci.h>
+//JH #include <sbutils.h>
+//JH #include <bcmutils.h>
+//JH #include <bcmdevs.h>
+//JH #include <bcmenet47xx.h>
 
 #include "adm6996.h"
 
@@ -32,7 +33,7 @@
 	void    *sbh;   /* sb utils handle */
 	char*				vars;
 	int					vars_size;
-	bcmenetregs_t regsva;
+//JH FIXME	bcmenetregs_t regsva;
 	adm_info_t* info;
 } adm_dev ;
 
@@ -86,7 +87,7 @@
 
 	
 	adm_detach (adm_dev.info);		
-	sb_detach(adm_dev.sbh);
+//JH	sb_detach(adm_dev.sbh);
 	return (0);
 }
 
@@ -99,7 +100,7 @@
 
 	printk(KERN_INFO "ADM6996L Driver version %s\n", ADM6996_VERSION);
 		
-	einfo = adm_dev.info = adm_attach (sbh);
+	einfo = adm_dev.info = adm_attach ();
 #ifdef CONFIG_PROC_FS
   err = adm6996_register_procfs (adm_dev.info);
 	if (err)
diff -ur adm6996/adm_procfs.c adm6996.cx82100/adm_procfs.c
--- adm6996/adm_procfs.c	2004-05-08 13:41:08.000000000 +0200
+++ adm6996.cx82100/adm_procfs.c	2006-08-27 15:31:15.000000000 +0200
@@ -69,6 +69,94 @@
 	return retval;
 }
 
+static int adm6996_procfs_readdump (char *page, char **start,
+		off_t offset, int count,
+		int *eof, void *data)
+{
+	int len, i;
+	uint32 val;
+	extern adm_info_t* einfo;
+
+	if (offset > 0)
+		return 0;
+
+	len = sprintf (page, "ADM6996L register dump\n");
+
+	len += sprintf (page+len, "--- EEPROM register dump ---\n");
+	for (i=0x00;i<=0x33;i+=2) {
+		if (
+		    (i==0x02) ||
+		    (i==0x04) ||
+		    (i==0x06) ||
+		    (i==0x0c) ||
+		    (i==0x0d) ||
+		    (i==0x23) ||
+		    (i==0x24) ||
+		    (i==0x25) ||
+		    (i==0x26) ||
+		    (i==0x27) ||
+		    (i==0x2d) ||
+		    (i==0x2e)
+		)
+			continue; /* Skip reserved registers */
+
+		if (i==0x0a) {
+			val &= ~0x3fff; /* Bits 13 to 0 are reserved */
+		}
+
+		if ((i==0x28) || (i==0x29) || (i==0x2a) || (i==0x32)) {
+			val &= ~0xff00; /* Bits 15 to 8 are reserved */
+		}
+
+		/* TODO: Registers 0x0a, 0x28, 0x29, 0x2a and 0x32
+		   are partly reserved, set these bits to zero
+		   before displaying the registers */
+
+		adm_rreg(einfo, 0, i, &val);
+		len += sprintf(page+len, "0x%02x: 0x%04x\n",
+                               i, val & 0xffff);
+		len += sprintf(page+len, "0x%02x: 0x%04x\n",
+                               i+1, (val>>16) & 0xffff);
+	}
+
+	len += sprintf (page+len, "--- serial register dump ---\n");
+	for (i=0x00;i<=0x3c;i++) {
+		if (
+		    (i==0x05) ||
+		    (i==0x07) ||
+		    (i==0x09) ||
+		    (i==0x0e) ||
+		    (i==0x10) ||
+		    (i==0x12) ||
+		    (i==0x17) ||
+		    (i==0x19) ||
+		    (i==0x1b) ||
+		    (i==0x20) ||
+		    (i==0x22) ||
+		    (i==0x24) ||
+		    (i==0x29) ||
+		    (i==0x2b) ||
+		    (i==0x2d) ||
+		    (i==0x32) ||
+		    (i==0x34) ||
+		    (i==0x36)
+                   )
+			continue; /* Skip reserved registers */
+
+		adm_rreg(einfo, 1, i, &val);
+		len += sprintf(page+len, "0x%02x: 0x%08x\n", i, val);
+	}
+
+	return len;
+}
+
+static int adm6996_procfs_writedump (struct file *file, const char *buffer,
+		unsigned long count, void *data)
+{
+	int retval = -EINVAL;
+	return retval;
+}
+
 int __init adm6996_register_procfs (adm_info_t *info)
 {
 	static struct proc_dir_entry *adm6996_file;
@@ -86,6 +174,18 @@
 	adm6996_file->size = 0;
 	adm6996_file->owner = THIS_MODULE;
 
+	/* create register dump function */
+	sprintf(filename, "adm6996_regdump");
+	adm6996_file = create_proc_entry (filename, S_IFREG | S_IRUGO | S_IWUSR, proc_root_driver);
+	if (adm6996_file == NULL)
+		return -ENOMEM;
+
+	adm6996_file->data = info;
+	adm6996_file->read_proc = adm6996_procfs_readdump;
+	adm6996_file->write_proc = adm6996_procfs_writedump;
+	adm6996_file->size = 0;
+	adm6996_file->owner = THIS_MODULE;
+
 	/* single card backward compatibility */
 	if (0/*info->nr*/ == 0)
 		proc_symlink ("adm6996", proc_root_driver, "adm6996_0");

