diff -Nuar linux-2.4.18/arch/arm/mach-sa1100/m62332.c linux-2.4.18p/arch/arm/mach-sa1100/m62332.c
--- linux-2.4.18/arch/arm/mach-sa1100/m62332.c	2003-05-13 11:18:14.000000000 +0200
+++ linux-2.4.18p/arch/arm/mach-sa1100/m62332.c	2004-10-12 22:36:36.000000000 +0200
@@ -131,3 +131,5 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(m62332_senddata);
+
diff -Nuar linux-2.4.18/arch/arm/mach-sa1100/Makefile linux-2.4.18p/arch/arm/mach-sa1100/Makefile
--- linux-2.4.18/arch/arm/mach-sa1100/Makefile	2003-05-13 11:18:14.000000000 +0200
+++ linux-2.4.18p/arch/arm/mach-sa1100/Makefile	2004-10-12 22:36:19.000000000 +0200
@@ -18,7 +18,7 @@
 export-objs :=	assabet.o consus.o badge4.o dma-sa1100.o dma-sa1111.o \
 		flexanet.o freebird.o generic.o h3600.o \
 		huw_webpanel.o irq.o pcipool.o sa1111.o sa1111-pcibuf.o \
-		system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o
+		system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o m62332.o
 
 # These aren't present yet, and prevents a plain -ac kernel building.
 # hwtimer.o
@@ -36,7 +36,7 @@
 obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
 endif
 
-obj-$(CONFIG_SA1100_COLLIE) += collie.o m62332.o collie_battery.o collie_led.o collie_buzzer.o
+obj-$(CONFIG_SA1100_COLLIE) += collie.o m62332.o collie_battery.o collie_led.o
 
 # Next, the SA1111 stuff.
 obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o
diff -Nuar linux-2.4.18/drivers/char/Makefile linux-2.4.18p/drivers/char/Makefile
--- linux-2.4.18/drivers/char/Makefile	2003-05-13 11:18:18.000000000 +0200
+++ linux-2.4.18p/drivers/char/Makefile	2004-10-12 17:26:44.000000000 +0200
@@ -228,7 +228,7 @@
 obj-y += joystick/js.o
 endif
 
-obj-$(CONFIG_SA1100_COLLIE) += sharp_led.o sharp_kbdctl.o sharp_buzzer.o
+obj-$(CONFIG_SA1100_COLLIE) += sharp_led.o sharp_kbdctl.o
 obj-$(CONFIG_DISCOVERY_LED) += sharp_led.o discovery_led.o
 obj-$(CONFIG_ARCH_PXA_POODLE) += sharp_led.o sharp_kbdctl.o sharpsl_led.o sharp_buzzer.o
 obj-$(CONFIG_ARCH_PXA_CORGI) += sharp_led.o sharpsl_led.o sharp_kbdctl.o corgi_rc.o sharp_buzzer.o
diff -Nuar linux-2.4.18/drivers/sound/colliebuzzer.h linux-2.4.18p/drivers/sound/colliebuzzer.h
--- linux-2.4.18/drivers/sound/colliebuzzer.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.18p/drivers/sound/colliebuzzer.h	2004-10-13 15:24:51.028208808 +0200
@@ -0,0 +1,756 @@
+unsigned short tap_data[] = {
+	0x0000 , 0xff00 , 0xff00 , 0x0000 , 
+	0xff00 , 0x0000 , 0x0000 , 0x0100 , 
+	0x0000 , 0x0100 , 0x0000 , 0x0100 , 
+	0x0100 , 0x0000 , 0x0100 , 0x0100 , 
+	0x0100 , 0x0100 , 0x0100 , 0x0100 , 
+	0x0100 , 0x0100 , 0x0100 , 0x0100 , 
+	0x0100 , 0x0000 , 0x0100 , 0x0000 , 
+	0x0100 , 0xff00 , 0x0100 , 0x0000 , 
+	0x0100 , 0x0000 , 0x0000 , 0x0100 , 
+	0x0000 , 0x0100 , 0x0000 , 0x0100 , 
+	0x0000 , 0x0000 , 0x0000 , 0x0000 , 
+	0x0000 , 0x0100 , 0x0000 , 0x0100 , 
+	0x0000 , 0x0100 , 0x0700 , 0x1c00 , 
+	0xc800 , 0xd900 , 0x2b00 , 0x2700 , 
+	0xbf00 , 0xe000 , 0x0d00 , 0x1000 , 
+	0xf500 , 0xd700 , 0x0100 , 0x0a00 , 
+	0xfb00 , 0xfa00 , 0x2200 , 0x0100 , 
+	0xeb00 , 0x0300 , 0x0600 , 0x1600 , 
+	0xe500 , 0xf500 , 0x0d00 , 0x0a00 , 
+	0x0100 , 0xfb00 , 0x0000 , 0x0100 , 
+	0xf200 , 0x0400 , 0x0600 , 0x0000 , 
+	0xf100 , 0x0300 , 0x1200 , 0xfe00 , 
+	0xe900 , 0x0400 , 0x0100 , 0x0d00 , 
+	0xf500 , 0x0100 , 0x0100 , 0xfe00 , 
+	0x0100 , 0xfb00 , 0x0400 , 0xff00 , 
+	0xf700 , 0x0400 , 0x0000 , 0xfe00 , 
+	0x0200 , 0x0000 , 0x0100 , 0xfd00 , 
+	0x0000 , 0xff00 , 0x0200 , 0x0000 , 
+	0xff00 , 0x0000 , 0x0200 , 0xfc00 , 
+	0xfe00 , 0xff00 , 0x0100 , 0x0200 , 
+	0x0000 , 0xff00 , 0xfc00 , 0x0100 , 
+	0x0100 , 0x0100 , 0xff00 , 0x0000 , 
+	0x0300 , 0xfe00 , 0xfe00 , 0x0200 , 
+	0xff00 , 0x0000 , 0x0000 , 0xfe00 , 
+	0x0000 , 0xff00 , 0x0000 , 0x0000 , 
+	0x0000 , 0xff00 , 0x0000 , 0x0000 , 
+	0xff00 , 0xfe00 , 0xfd00 , 0x0100 , 
+	0x0000 , 0xfe00 , 0xff00 , 0xff00 , 
+	0x0000 , 0xff00 , 0x0100 , 0xfe00 , 
+	0xff00 , 0xff00 , 0x0000 , 0x0000 , 
+	0xfe00 , 0xff00 , 0x0100 , 0x0100 , 
+	0xff00 , 0x0100 , 0x0100 , 0xfe00 , 
+	0x0000 , 0x0000 , 0x0000 , 0x0100 , 
+	0x0000 , 0x0000 , 0xff00 , 0x0000 , 
+	0x0100 , 0x0000 , 0x0200 };
+
+
+unsigned short click_data[] = {
+	0x0100 , 0x0100 , 0x0100 , 0x0000 , 
+	0x0100 , 0xff00 , 0x0100 , 0x0000 , 
+	0xff00 , 0xff00 , 0xff00 , 0x0000 , 
+	0xff00 , 0xff00 , 0xff00 , 0xff00 , 
+	0xff00 , 0xff00 , 0x0000 , 0xff00 , 
+	0xff00 , 0xff00 , 0x0000 , 0xff00 , 
+	0xff00 , 0xff00 , 0xff00 , 0x0100 , 
+	0x0000 , 0xff00 , 0xfe00 , 0x0100 , 
+	0xff00 , 0x0100 , 0xff00 , 0x0100 , 
+	0x0100 , 0x0300 , 0xff00 , 0xff00 , 
+	0xff00 , 0x0100 , 0x0100 , 0x0000 , 
+	0xfe00 , 0xfe00 , 0xfe00 , 0xfc00 , 
+	0xfe00 , 0x0100 , 0xfd00 , 0xff00 , 
+	0xff00 , 0xfc00 , 0xfe00 , 0xfd00 , 
+	0x0100 , 0xfe00 , 0x0100 , 0xf800 , 
+	0xfe00 , 0xfe00 , 0xfc00 , 0xe600 , 
+	0xdb00 , 0x2500 , 0xdb00 , 0xee00 , 
+	0xdb00 , 0x0600 , 0xeb00 , 0x1f00 , 
+	0x1e00 , 0xeb00 , 0xfe00 , 0x0000 , 
+	0xff00 , 0x1900 , 0xef00 , 0xf700 , 
+	0x2100 , 0xe400 , 0x0100 , 0x0600 , 
+	0xff00 , 0x0300 , 0xf900 , 0x0f00 , 
+	0xf600 , 0x0100 , 0xfe00 , 0xf900 , 
+	0x0500 , 0xf500 , 0x0600 , 0xfb00 , 
+	0x0800 , 0x0100 , 0x0300 , 0x0100 , 
+	0xf700 , 0xfa00 , 0xfd00 , 0xfc00 , 
+	0x0800 , 0xfb00 , 0x0500 , 0xfe00 , 
+	0xfc00 , 0xfc00 , 0xfe00 , 0x0400 , 
+	0xff00 , 0xff00 , 0x0500 , 0x0100 , 
+	0xfc00 , 0xff00 , 0xfe00 , 0xfb00 , 
+	0x0200 , 0x0200 , 0xff00 , 0xfe00 , 
+	0xfe00 , 0x0600 , 0xfb00 , 0xff00 , 
+	0xfc00 , 0x0600 , 0xfb00 , 0xff00 , 
+	0xff00 , 0x0100 , 0xff00 , 0x0200 , 
+	0xff00 , 0xfb00 , 0xff00 , 0x0200 , 
+	0xff00 , 0x0200 , 0x0100 , 0xfe00 , 
+	0xfe00 , 0x0100 , 0xfd00 , 0x0200 , 
+	0xfc00 , 0x0800 , 0xfe00 , 0xfe00 , 
+	0x0400 , 0xfc00 , 0xff00 , 0xfc00 , 
+	0x0500 , 0x0200 , 0x0800 , 0x0200 , 
+	0x0100 , 0xfe00 , 0x0100 , 0xff00 , 
+	0x0700 , 0xfb00 , 0xfc00 , 0x0100 , 
+	0xfe00 , 0xfc00 , 0x0b00 , 0xfb00 , 
+	0xfb00 , 0x0700 , 0xfb00 , 0xfb00 , 
+	0x0100 , 0xff00 , 0xfb00 , 0xfd00 , 
+	0x0000 , 0xfe00 , 0xfe00 , 0xff00 , 
+	0xfc00 , 0x0400 , 0x0000 , 0xfe00 , 
+	0xff00 , 0x0200 , 0xff00 , 0x0000 , 
+	0x0500 , 0x0100 , 0x0100 , 0x0100 , 
+	0x0100 , 0x0000 , 0x0300 , 0xfe00 , 
+	0xff00 , 0x0100 , 0x0100 , 0xfe00 , 
+	0x0000 , 0xff00 , 0x0100 , 0xff00 , 
+	0x0200 , 0xff00 , 0xff00 , 0xff00 , 
+	0xff00 , 0xfe00 , 0x0000 , 0xff00 , 
+	0xfe00 , 0xff00 , 0xfd00 , 0x0000 , 
+	0xff00 , 0xfe00 , 0xff00 , 0xfc00 , 
+	0x0100 , 0xfd00 , 0xff00 , 0xff00 , 
+	0x0200 , 0xff00 , 0x0100 , 0xff00 , 
+	0xfc00 , 0x0300 , 0xff00 , 0x0200 , 
+	0xff00 , 0x0100 , 0xff00 , 0x0100 , 
+	0xff00 , 0xff00 , 0x0100 , 0xfe00 , 
+	0x0300 , 0xfc00 , 0x0100 , 0xff00 , 
+	0x0100 , 0x0100 , 0x0100 , 0xfc00 , 
+	0xff00 , 0x0100 , 0x0100 , 0xfe00 , 
+	0x0100 , 0xff00 , 0x0100 , 0xfc00 , 
+	0x0100 , 0x0200 , 0xff00 , 0x0100 , 
+	0xff00 , 0xff00 , 0x0200 , 0xfd00 , 
+	0xfe00 , 0x0100 , 0xff00 , 0x0100 , 
+	0xfe00 , 0x0100 , 0x0300 , 0xfe00 , 
+	0x0300 , 0xfe00 , 0xff00 , 0x0100 , 
+	0xff00 , 0x0200 , 0xfd00 , 0x0000 , 
+	0xff00 , 0x0200 , 0xff00 , 0x0200 , 
+	0xff00 , 0x0100 , 0x0000 , 0xff00 , 
+	0x0200 , 0x0100 , 0x0000 , 0xff00 , 
+	0x0100 , 0xfe00 , 0x0200 , 0xfe00 , 
+	0xfe00 , 0x0100 , 0xfe00 , 0x0100 , 
+	0xfd00 , 0xff00 , 0xff00 , 0xfe00 , 
+	0xff00 , 0xfc00 , 0x0100 , 0xfe00 , 
+	0x0100 , 0xff00 , 0xfe00 , 0xff00 , 
+	0xff00 , 0xfe00 , 0x0100 , 0xfe00 , 
+	0x0100 , 0xff00 , 0x0100 , 0xfe00 , 
+	0xff00 , 0x0200 , 0xfe00 , 0x0000 , 
+	0x0100 , 0x0200 , 0xff00 , 0x0200 , 
+	0xff00 , 0x0000 , 0x0100 , 0x0100 , 
+	0xff00 , 0x0200 , 0xfe00 , 0xff00 , 
+	0xff00 , 0xff00 , 0x0100 , 0x0000 , 
+	0xff00 , 0x0100 , 0xff00 , 0x0000 , 
+	0x0100 , 0xff00 , 0xfe00 , 0xff00 , 
+	0xff00 , 0x0100 , 0xff00 , 0x0100 , 
+	0xfe00 , 0xff00 , 0xff00 , 0xff00 , 
+	0xfe00 , 0xff00 , 0xff00 , 0x0100 , 
+	0xff00 , 0x0200 , 0xff00 , 0x0100 , 
+	0xff00 , 0xff00 };
+
+
+unsigned short alarm_data[] = {
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
+  0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
+
+};
+
+
+
+
+
+#define SHARP_BUZ_TOUCHSOUND 1
+#define SHARP_BUZ_KEYSOUND 2
+#define SHARP_BUZ_ALARM 11
+#define SHARP_BUZZER_MAKESOUND 0x5680
+
+static int collie_ct_s16_buzzer(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
+{
+	ssize_t count, used;
+	signed short *fp = (unsigned short *) &frame[*frameUsed];
+	signed short *up = (unsigned short *) userPtr;
+
+	DPRINTK("Collie_ct_s16 begin\n");
+
+	used = count = (userCount < frameLeft) ? userCount/2 : frameLeft/4;
+
+	DPRINTK("Collie_ct_s16 begin count %d \n",count);
+	
+	while (count > 0) {
+		*fp++ =  *up;
+		*fp++ =  *up++;
+		count--;
+	}
+
+	*frameUsed+=used*4;	
+	DPRINTK("Collie_ct_s16 exit\n");
+	return used*2;
+}
+
+
+static ssize_t sq_write_buzzer(int soundid)
+{
+	const char  * src;
+	audio_stream_t *s = &output_stream;
+	u_char *dest;
+	ssize_t uUsed, bUsed, bLeft, uLeft, ret = 0;
+
+
+	if ((collie_tc_status!=NA) && (collie_tc_status!=PLAY)) 
+	    return -EPERM;
+
+	collie_tc_status=PLAY;
+
+	if (!s->buffers && sq_allocate_buffers(s)) {
+		return -ENOMEM;
+	}
+
+	
+#ifdef CONFIG_PM
+	/* Auto Power off cancel */
+//	autoPowerCancel = 0;
+#endif
+	DPRINTK("sq_write_buzzer: id:%d\n", soundid);
+
+	switch (soundid) {
+	case SHARP_BUZ_TOUCHSOUND:
+	    src=tap_data;
+	    uLeft=176*2;
+	    break;
+	case SHARP_BUZ_KEYSOUND:
+	    src=click_data;
+	    uLeft=360*2;
+	    break;
+	case SHARP_BUZ_ALARM:
+	    src=alarm_data;
+	    uLeft=3072*2;
+	    break;
+	default:
+	    return 0;
+	}
+	DPRINTK("sq_write_buzzer: uLeft=%d\n", uLeft);
+
+	collie_tc_mute_off();
+	while (uLeft > 0) {
+		audio_buf_t *b = s->buf;
+
+		ret = -ERESTARTSYS;
+		if (down_interruptible(&b->sem)) {
+			break;
+		}
+
+		dest = b->start + b->size;
+		bUsed = 0;
+		bLeft = s->fragsize - b->size;
+		uUsed = collie_ct_s16_buzzer(src, uLeft, dest, &bUsed, bLeft);
+		cpu_cache_clean_invalidate_range((unsigned long)dest,
+		    (unsigned long)(dest+(audio_fragsize)), 0);
+		
+		DPRINTK("back to sq_write_buzzer %p\n",dest);		
+
+		if (uUsed < 0) {
+			up(&b->sem);
+			return -EFAULT;
+		}
+		src += uUsed;
+		uLeft -= uUsed;
+		b->size += bUsed;
+
+		if (b->size < s->fragsize) {
+			up(&b->sem);
+			break;
+		}
+
+		/* Send current buffer to dma */
+		sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL,
+		 			(void *) b, b->dma_addr, b->size);
+
+		Collie_volume_set(4);
+
+		b->size = 0;    /* indicate that the buffer has been sent */
+		NEXT_BUF(s, buf);
+	}
+
+	DPRINTK("sq_write_buzzer: return\n");
+	return ret;
+}
+
+
+
+
+
+
+
diff -Nuar linux-2.4.18/drivers/sound/collie_ssp.c linux-2.4.18p/drivers/sound/collie_ssp.c
--- linux-2.4.18/drivers/sound/collie_ssp.c	2003-05-13 11:18:37.000000000 +0200
+++ linux-2.4.18p/drivers/sound/collie_ssp.c	2004-10-13 15:05:36.000000000 +0200
@@ -9,6 +9,7 @@
  *		I/F : Synchronous serial port (SSP) TI mode
  *
  * Copyright (C) 2001  SHARP
+ * p.nis/dolOps messed around with it too!
  *
  * 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
@@ -24,7 +25,18 @@
  *	23-Oct-2001 SHARP
  *		tune hardware control method
  *	12-Nov-2001 Lineo Japan, Inc.
- *	14-Feb-2003 Sharp Corporation 8bit , GETOSPACE
+ *
+ *	26-Dec-2002 getospace added, some unneeded things removed
+ *	
+ *	28-Dec-2002 cut out old stuff, reorder stuff
+ *
+ *	04-Jan-2003 put in getospace from lineo's collie-tc35143.c
+ *	            also added collie_record_on off, and exported these symbols
+ *
+ *	06-Jan-2003 if mixer ioctl SOUND_MIXER_READ_DEVMASK returns 0 as mask,
+ *		    than the headphone(/mic) is not connected
+ *	            
+ *
  */
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -35,7 +47,7 @@
 #include <linux/fcntl.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/sound.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -48,38 +60,30 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/dma.h>
-#include <asm/ucb1200.h>
 
 #include <linux/soundcard.h>
 #include <asm/proc/cache.h>
 
-#include <asm/arch/gpio.h>
+#include <asm/arch/hardware.h>
 #include <asm/arch/m62332.h>
 #include <asm/arch/tc35143.h>
 
 #undef DEBUG
-//#define DEBUG
 #ifdef DEBUG
 #define DPRINTK( x... )  printk( ##x )
 #else
 #define DPRINTK( x... )
 #endif
 
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0) || \
-    defined(CONFIG_COLLIE_TR1) || defined(CONFIG_COLLIE_DEV)
-#define COLLIE_TRY_ONE
-#else
-#undef	COLLIE_TRY_ONE
-#endif
+#define	COLLIE_TRY_ONE
 
 #ifdef COLLIE_TRY_ONE
 #ifndef	GPIO_REMOCON_ADC_SW
 #define	GPIO_REMOCON_ADC_SW	GPIO_GPIO(18)
 #endif
 
+static int collie_rc_irq;
 static DECLARE_WAIT_QUEUE_HEAD(audio_on);
-
-
 static inline void collie_rc_set_int_mode(void)
 {
 	GPSR = GPIO_REMOCON_ADC_SW;
@@ -91,14 +95,12 @@
 }
 #endif
 
-
 int collie_dmasound_irq = -1;
-#define	COLLIE_SOUND_DMA_CHANNEL	(collie_dmasound_irq)
 
+#define	COLLIE_SOUND_DMA_CHANNEL	(collie_dmasound_irq)
 #define SND_NDEVS	256	/* Number of supported devices */
 #define SND_DEV_CTL	0	/* Control port /dev/mixer */
-#define SND_DEV_SEQ	1	/* Sequencer output /dev/sequencer (FM
-				   synthesizer and MIDI output) */
+#define SND_DEV_SEQ	1	/* Sequencer output /dev/sequencer (FM synthesizer and MIDI output) */
 #define SND_DEV_MIDIN	2	/* Raw midi access */
 #define SND_DEV_DSP	3	/* Digitized voice /dev/dsp */
 #define SND_DEV_AUDIO	4	/* Sparc compatible /dev/audio */
@@ -121,142 +123,25 @@
 #endif
 
 /*** Some declarations ***********************************************/
-#define DMASND_TT	1
-#define DMASND_FALCON	2
-#define DMASND_AMIGA	3
-#define DMASND_AWACS	4
-#define DMASND_IRIS	5
-#define DMASND_COLLIE	6
 
-#define COLLIE_WAIT_AMP_ON	1	/* 10ms */
+
 #define COLLIE_WAIT_LCM_ACC_XEN	50	/* 500ms */
-#ifdef MODULE
-static int catchRadius = 0;
-#endif
+
 static int collie_amp_init = 0;
 static int collie_dac_init = 0;
-static int collie_op_shdn_on = 0;
 static int collie_resume = 0;
 static int collie_hard_mute = 1;
 static int collie_soft_mute = 1;
 static int collie_volume = 0;
+int collie_recording=0;
+static int playing=0;
+static int headphone;
 
-int collie_buzzer_volume = 0;
-
-#if 1
-static DECLARE_WAIT_QUEUE_HEAD(open_queue);
+#define AUDIO_NBFRAGS_DEFAULT   64
+#define AUDIO_FRAGSIZE_DEFAULT  4096
 
-#define SIGNAL_RECEIVED	(signal_pending(current))
-#define ONE_SECOND	HZ	/* in jiffies (100ths of a second) */
-#define SLEEP(queue, time_limit) \
-	interruptible_sleep_on_timeout((wait_queue_head_t*)&queue, (time_limit));
-#define WAKE_UP(queue)	(wake_up_interruptible((wait_queue_head_t*)&queue))
-#endif
-
-#define AUDIO_NBFRAGS_DEFAULT   8
-#define AUDIO_FRAGSIZE_DEFAULT  8192
-
-
-#define TRACE 0
-#if TRACE
-#define TRACE_ON	1
-#define TRACE_SEM	0
-#define	TRACE_SENDDATA	0
-#define	TRACE_PM	1
-#define TRACE_AMP	1
-#define TRACE_DAC	1
-#define TRACE_OP_SHDN	1
-#define TRACE_WRITE	1
-#define TRACE_MUTE	1
-#define TRACE_CLOCK	1
-#define TRACE_PAIF	1
-#define TRACE_SSP	1
-#define TRACE_VOLUME	1
-#define TRACE_MIC	1
-#define TRACE_INTERRUPT	0
-int	cLevel = 0;
-char	*pLevel[16] = {
-	/*  0 */"",
-	/*  1 */" ",
-	/*  2 */"  ",
-	/*  3 */"   ",
-	/*  4 */"    ",
-	/*  5 */"     ",
-	/*  6 */"      ",
-	/*  7 */"       ",
-	/*  8 */"        ",
-	/*  9 */"         ",
-	/* 10 */"          ",
-	/* 11 */"           ",
-	/* 12 */"            ",
-	/* 13 */"             ",
-	/* 14 */"              ",
-	/* 15 */"               "
-};
-char *
-indent(int level)
-{
-  int	i;
-  return (level < 16 ) ? pLevel[level] : pLevel[15];
-}
-
-#define	P_ID	(current->tgid)
-#define	ENTER(f,fn)	{if(f)printk("%d:%s+[%d]%s\n",jiffies,indent(cLevel),P_ID,(fn));cLevel++;}
-#define LEAVE(f,fn)	{cLevel--;if(f>1)printk("%d:%s-[%d]%s\n",jiffies,indent(cLevel),P_ID,(fn));}
-#else	/* ! TRACE */
-#define	ENTER(f,fn)
-#define LEAVE(f,fn)
-#endif	/* end TRACE */
 
-/*
- * DAC power management
- */
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0) || \
-    defined(CONFIG_COLLIE_TR1) || defined(CONFIG_COLLIE_DEV)
-#define	DAC_OFF_WITH_DEVICE_OFF		1
-#undef	HARD_MUTE_CTRL_DISABLE		
-#else
-#undef	DAC_OFF_WITH_DEVICE_OFF
 #undef	HARD_MUTE_CTRL_DISABLE		
-#endif
-
-
-#define TRY_DELAY_OFF
-#ifdef TRY_DELAY_OFF	/* H.Hayami SHARP 2001.12.19 */
-static DECLARE_WAIT_QUEUE_HEAD(delay_off);
-struct semaphore df_sem;
-/*
- * delay execution
- */
-static unsigned int	DelayedFlag = 0;
-#define DELAY_DAC_OFF		0x1
-#define DELAY_HARD_MUTE_ON	0x2
-
-static inline void ResetDelayAll(void)
-{
-	DelayedFlag = 0;
-}
-
-static inline int isDelayedExist(void)
-{
-	return DelayedFlag;
-}
-
-static inline void SetDelay(unsigned int flag)
-{
-	DelayedFlag |= flag;
-}
-
-static inline void ResetDelay(unsigned int flag)
-{
-	DelayedFlag &= ~flag;
-}
-
-static inline unsigned int isDelayed(unsigned int flag)
-{
-	return DelayedFlag & flag;
-}
-#endif
 
 /*
  * Buffer Management
@@ -268,6 +153,7 @@
 	dma_addr_t dma_addr;    /* physical buffer address */
 	struct semaphore sem;   /* down before touching the buffer */
 	int master;             /* master owner for buffer allocation */
+	u_int idx;		/* buffer index, so that we know which buffer was sent last*/
 } audio_buf_t;
 
 typedef struct {
@@ -291,16 +177,6 @@
 
 static volatile int audio_wr_refcount;	/* nbr of concurrent open() for playback */
 
-static ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
-
-#ifdef MODULE
-MODULE_PARM(catchRadius, "i");
-#endif
-MODULE_PARM(numBufs, "i");
-MODULE_PARM(bufSize, "i");
-
-#define min(x, y)	((x) < (y) ? (x) : (y))
-
 #define IOCTL_IN(arg, ret) \
 	do { int error = get_user(ret, (int *)(arg)); \
 		if (error) return error; \
@@ -310,11 +186,7 @@
 /*
  * SA1110 GPIO (17)
  */
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-#define COLLIE_GPIO_OPSHDN	GPIO_GPIO (17)	/* AMP contorol        */
-#else	/* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
 #define COLLIE_GPIO_MIC		GPIO_GPIO (17)	/* MIC contorol        */
-#endif	/* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
 
 /*
  * DAC setup data
@@ -352,122 +224,11 @@
 		( LCM_ACC_XSEL1 | LCM_ACC_CLKSEL101 ) ,
 };
 
+/*** "Translations" ************************************************************/
 
-/* 16 bit mu-law */
-
-static short ulaw2dma16[] = {
-	-32124,	-31100,	-30076,	-29052,	-28028,	-27004,	-25980,	-24956,
-	-23932,	-22908,	-21884,	-20860,	-19836,	-18812,	-17788,	-16764,
-	-15996,	-15484,	-14972,	-14460,	-13948,	-13436,	-12924,	-12412,
-	-11900,	-11388,	-10876,	-10364,	-9852,	-9340,	-8828,	-8316,
-	-7932,	-7676,	-7420,	-7164,	-6908,	-6652,	-6396,	-6140,
-	-5884,	-5628,	-5372,	-5116,	-4860,	-4604,	-4348,	-4092,
-	-3900,	-3772,	-3644,	-3516,	-3388,	-3260,	-3132,	-3004,
-	-2876,	-2748,	-2620,	-2492,	-2364,	-2236,	-2108,	-1980,
-	-1884,	-1820,	-1756,	-1692,	-1628,	-1564,	-1500,	-1436,
-	-1372,	-1308,	-1244,	-1180,	-1116,	-1052,	-988,	-924,
-	-876,	-844,	-812,	-780,	-748,	-716,	-684,	-652,
-	-620,	-588,	-556,	-524,	-492,	-460,	-428,	-396,
-	-372,	-356,	-340,	-324,	-308,	-292,	-276,	-260,
-	-244,	-228,	-212,	-196,	-180,	-164,	-148,	-132,
-	-120,	-112,	-104,	-96,	-88,	-80,	-72,	-64,
-	-56,	-48,	-40,	-32,	-24,	-16,	-8,	0,
-	32124,	31100,	30076,	29052,	28028,	27004,	25980,	24956,
-	23932,	22908,	21884,	20860,	19836,	18812,	17788,	16764,
-	15996,	15484,	14972,	14460,	13948,	13436,	12924,	12412,
-	11900,	11388,	10876,	10364,	9852,	9340,	8828,	8316,
-	7932,	7676,	7420,	7164,	6908,	6652,	6396,	6140,
-	5884,	5628,	5372,	5116,	4860,	4604,	4348,	4092,
-	3900,	3772,	3644,	3516,	3388,	3260,	3132,	3004,
-	2876,	2748,	2620,	2492,	2364,	2236,	2108,	1980,
-	1884,	1820,	1756,	1692,	1628,	1564,	1500,	1436,
-	1372,	1308,	1244,	1180,	1116,	1052,	988,	924,
-	876,	844,	812,	780,	748,	716,	684,	652,
-	620,	588,	556,	524,	492,	460,	428,	396,
-	372,	356,	340,	324,	308,	292,	276,	260,
-	244,	228,	212,	196,	180,	164,	148,	132,
-	120,	112,	104,	96,	88,	80,	72,	64,
-	56,	48,	40,	32,	24,	16,	8,	0,
-};
-
-/* 16 bit A-law */
-
-static short alaw2dma16[] = {
-	-5504,	-5248,	-6016,	-5760,	-4480,	-4224,	-4992,	-4736,
-	-7552,	-7296,	-8064,	-7808,	-6528,	-6272,	-7040,	-6784,
-	-2752,	-2624,	-3008,	-2880,	-2240,	-2112,	-2496,	-2368,
-	-3776,	-3648,	-4032,	-3904,	-3264,	-3136,	-3520,	-3392,
-	-22016,	-20992,	-24064,	-23040,	-17920,	-16896,	-19968,	-18944,
-	-30208,	-29184,	-32256,	-31232,	-26112,	-25088,	-28160,	-27136,
-	-11008,	-10496,	-12032,	-11520,	-8960,	-8448,	-9984,	-9472,
-	-15104,	-14592,	-16128,	-15616,	-13056,	-12544,	-14080,	-13568,
-	-344,	-328,	-376,	-360,	-280,	-264,	-312,	-296,
-	-472,	-456,	-504,	-488,	-408,	-392,	-440,	-424,
-	-88,	-72,	-120,	-104,	-24,	-8,	-56,	-40,
-	-216,	-200,	-248,	-232,	-152,	-136,	-184,	-168,
-	-1376,	-1312,	-1504,	-1440,	-1120,	-1056,	-1248,	-1184,
-	-1888,	-1824,	-2016,	-1952,	-1632,	-1568,	-1760,	-1696,
-	-688,	-656,	-752,	-720,	-560,	-528,	-624,	-592,
-	-944,	-912,	-1008,	-976,	-816,	-784,	-880,	-848,
-	5504,	5248,	6016,	5760,	4480,	4224,	4992,	4736,
-	7552,	7296,	8064,	7808,	6528,	6272,	7040,	6784,
-	2752,	2624,	3008,	2880,	2240,	2112,	2496,	2368,
-	3776,	3648,	4032,	3904,	3264,	3136,	3520,	3392,
-	22016,	20992,	24064,	23040,	17920,	16896,	19968,	18944,
-	30208,	29184,	32256,	31232,	26112,	25088,	28160,	27136,
-	11008,	10496,	12032,	11520,	8960,	8448,	9984,	9472,
-	15104,	14592,	16128,	15616,	13056,	12544,	14080,	13568,
-	344,	328,	376,	360,	280,	264,	312,	296,
-	472,	456,	504,	488,	408,	392,	440,	424,
-	88,	72,	120,	104,	24,	8,	56,	40,
-	216,	200,	248,	232,	152,	136,	184,	168,
-	1376,	1312,	1504,	1440,	1120,	1056,	1248,	1184,
-	1888,	1824,	2016,	1952,	1632,	1568,	1760,	1696,
-	688,	656,	752,	720,	560,	528,	624,	592,
-	944,	912,	1008,	976,	816,	784,	880,	848,
-};
-
-
-
-/*** Translations ************************************************************/
-
-static ssize_t collie_ct_law(const u_char *userPtr, size_t userCount,
-			     u_char frame[], ssize_t *frameUsed,
-			     ssize_t frameLeft);
-static ssize_t collie_ct_s8(const u_char *userPtr, size_t userCount,
-			    u_char frame[], ssize_t *frameUsed,
-			    ssize_t frameLeft);
-static ssize_t collie_ct_u8(const u_char *userPtr, size_t userCount,
-			    u_char frame[], ssize_t *frameUsed,
-			    ssize_t frameLeft);
 static ssize_t collie_ct_s16(const u_char *userPtr, size_t userCount,
 			     u_char frame[], ssize_t *frameUsed,
 			     ssize_t frameLeft);
-static ssize_t collie_ct_u16(const u_char *userPtr, size_t userCount,
-			     u_char frame[], ssize_t *frameUsed,
-			     ssize_t frameLeft);
-
-/*** Machine definitions *****************************************************/
-
-
-typedef struct {
-	int type;
-	void *(*dma_alloc)(unsigned int, int);
-	void (*dma_free)(void *, unsigned int);
-	int (*irqinit)(void);
-#ifdef MODULE
-	void (*irqcleanup)(void);
-#endif /* MODULE */
-	void (*init)(void);
-	void (*silence)(void);
-	int (*setFormat)(int);
-	int (*setVolume)(int);
-	int (*setBass)(int);
-	int (*setTreble)(int);
-	int (*setGain)(int);
-	void (*play)(void);
-} MACHINE;
-
 
 /*** Low level stuff *********************************************************/
 
@@ -477,71 +238,28 @@
 	int stereo;		/* 0 = mono, 1 = stereo */
 	int size;		/* 8/16 bit*/
 	int speed;		/* speed */
+	int volume;
 } SETTINGS;
 
-typedef struct {
-	ssize_t (*ct_ulaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-	ssize_t (*ct_alaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-	ssize_t (*ct_s8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-	ssize_t (*ct_u8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-	ssize_t (*ct_s16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-	ssize_t (*ct_u16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-	ssize_t (*ct_s16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-	ssize_t (*ct_u16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-} TRANS;
-
-struct sound_settings {
-	MACHINE mach;		/* machine dependent things */
-	SETTINGS hard;		/* hardware settings */
-	SETTINGS soft;		/* software settings */
-	SETTINGS dsp;		/* /dev/dsp default settings */
-	TRANS *trans;		/* supported translations */
-	int volume_left;	/* volume (range is machine dependent) */
-	int volume_right;
-	int bass;		/* tone (range is machine dependent) */
-	int treble;
-	int gain;
-	int minDev;		/* minor device number currently open */
-};
-
-static struct sound_settings sound;
+static SETTINGS sound;
 
 #ifdef CONFIG_PM
-extern int autoPowerCancel;
+//extern int autoPowerCancel;
 #endif
-int collie_main_volume;
-extern int collie_under_recording;      /* collie_buzzer.c */
-#define COLLE_RECORDING	(collie_under_recording)
 
 static void Collie_Set_Volume(int volume);
 static int Collie_Get_Volume(void);
-static void Collie_disable_sound(void);
-#ifdef CONFIG_PM
-#if 0
-static void Collie_clock_stop(void);
-static void Collie_FS8KLPF_stop(void);
-#endif
-#endif
 static int CollieIrqInit(void);
 static int CollieGetSamp(void);
-static void Collie_OP_SHDN_on(void);
-static void Collie_OP_SHDN_off(void);
-static void Collie_FS8KLPF_start(void);
-#ifdef MODULE
-static void CollieIrqCleanUp(void);
-#endif /* MODULE */
-static void CollieSilence(void);
 static void Collie_DAC_sendword(int);
-static void CollieInit(void);
 static int CollieSetFormat(int format);
 static void Collie_sq_interrupt(void*, int);
 static int sq_allocate_buffers(audio_stream_t*);
 static void sq_release_buffers(audio_stream_t*);
+static inline void Collie_volume_init(void);
+static void Collie_volume_set(int);
 
 /*** Mid level stuff *********************************************************/
-static void sound_silence(void);
-static void sound_init(void);
-static int sound_set_format(int format);
 static int sound_set_speed(int speed);
 static int sound_set_stereo(int stereo);
 
@@ -572,468 +290,122 @@
 static long long sound_lseek(struct file *file, long long offset, int orig);
 static inline int ioctl_return(int *addr, int value)
 {
-	ENTER(TRACE_ON,"ioctl_return");
 	if (value < 0) {
-		LEAVE(TRACE_ON,"ioctl_return");
 		return(value);
 	}
-
-	LEAVE(TRACE_ON,"ioctl_return");
 	return put_user(value, addr)? -EFAULT: 0;
 }
 
-
-/*** Config & Setup **********************************************************/
-
-
-void dmasound_init(void);
-void dmasound_setup(char *str, int *ints);
-
-
-/*** Translations ************************************************************/
-
-
-/* ++TeSche: radically changed for new expanding purposes...
- *
- * These two routines now deal with copying/expanding/translating the samples
- * from user space into our buffer at the right frequency. They take care about
- * how much data there's actually to read, how much buffer space there is and
- * to convert samples into the right frequency/encoding. They will only work on
- * complete samples so it may happen they leave some bytes in the input stream
- * if the user didn't write a multiple of the current sample size. They both
- * return the number of bytes they've used from both streams so you may detect
- * such a situation. Luckily all programs should be able to cope with that.
- *
- * I think I've optimized anything as far as one can do in plain C, all
- * variables should fit in registers and the loops are really short. There's
- * one loop for every possible situation. Writing a more generalized and thus
- * parameterized loop would only produce slower code. Feel free to optimize
- * this in assembler if you like. :)
- *
- * I think these routines belong here because they're not yet really hardware
- * independent, especially the fact that the Falcon can play 16bit samples
- * only in stereo is hardcoded in both of them!
- *
- * ++geert: split in even more functions (one per format)
- */
-
-static ssize_t collie_ct_law(const u_char *userPtr, size_t userCount,
-			     u_char frame[], ssize_t *frameUsed,
-			     ssize_t frameLeft)
-{
-	short *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16;
-	ssize_t count, used;
-	short *p = (short *) &frame[*frameUsed];
-	int val, stereo = sound.soft.stereo;
-
-	ENTER(TRACE_ON,"collie_ct_law");
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min(userCount, frameLeft);
-	if (!COLLE_RECORDING) {
-		while (count > 0) {
-			u_char data;
-			if (get_user(data, userPtr++)) {
-				LEAVE(TRACE_ON,"collie_ct_law");
-				return -EFAULT;
-			}
-			val = table[data];
-			*p++ = val;		/* Left Ch. */
-			if (stereo) {
-				if (get_user(data, userPtr++)) {
-				LEAVE(TRACE_ON,"collie_ct_law");
-				return -EFAULT;
-				}
-				val = table[data];
-			}
-			*p++ = val;		/* Right Ch. */
-			count--;
-		}
-	} else {
-		while (count > 0) {
-			u_char data;
-			int ave;
-			if (get_user(data, userPtr++)) {
-				LEAVE(TRACE_ON,"collie_ct_law");
-				return -EFAULT;
-			}
-			val = table[data];
-			ave = val;		/* Left Ch. */
-			if (stereo) {
-				if (get_user(data, userPtr++)) {
-					LEAVE(TRACE_ON,"collie_ct_law");
-					return -EFAULT;
-				}
-				val = table[data];
-			}
-			ave += val;		/* Right Ch. */
-			ave >>= 1;
-			*p++ = 0;		/* Left Ch. */
-			*p++ = ave;		/* Right Ch. */
-			count--;
-		}
-	}
-	*frameUsed += used * 4;
-	LEAVE(TRACE_ON,"collie_ct_law");
-	return stereo? used * 2: used;
-}
-
-
-static ssize_t collie_ct_s8(const u_char *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
-{
-	ssize_t count, used;
-	short *p = (short *) &frame[*frameUsed];
-	int stereo = sound.soft.stereo;
-	short val;
-
-	ENTER(TRACE_ON,"collie_ct_s8");
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min(userCount, frameLeft);
-	if (!COLLE_RECORDING) {
-		while (count > 0) {
-			u_char data;
-
-			if (get_user(data, userPtr++)) {
-				LEAVE(TRACE_ON,"collie_ct_s8");
-				return -EFAULT;
-			}
-			val = ( data - 0x80 ) << 8;
-			*p++ = val;		/* Left Ch. */
-			if ( stereo ) {
-				if ( get_user(data, userPtr++)) {
-					LEAVE(TRACE_ON,"collie_ct_s8");
-					return -EFAULT;
-				}
-				val = ( data - 0x80 ) << 8;
-			}
-			*p++ = val;		/* Right Ch. */
-			count--;
-		}
-	} else {
-		while (count > 0) {
-			u_char data;
-			int ave;
-
-			if (get_user(data, userPtr++)) {
-				LEAVE(TRACE_ON,"collie_ct_s8");
-				return -EFAULT;
-			}
-			val = ( data - 0x80 ) << 8;
-			ave = val;		/* Left Ch. */
-			if ( stereo ) {
-				if ( get_user(data, userPtr++)) {
-					LEAVE(TRACE_ON,"collie_ct_s8");
-					return -EFAULT;
-				}
-				val = ( data - 0x80 ) << 8;
-			}
-			ave += val;		/* Right Ch. */
-			ave >>= 1;
-			*p++ = 0;		/* Left Ch. */
-			*p++ = ave;		/* Right Ch. */
-			count--;
-		}
-	}
-	*frameUsed += used * 4;
-	LEAVE(TRACE_ON,"collie_ct_s8");
-	return stereo? used * 2: used;
-}
-
-
-static ssize_t collie_ct_u8(const u_char *userPtr, size_t userCount,
-			  u_char frame[], ssize_t *frameUsed,
-			  ssize_t frameLeft)
+static void wait_ms(int ten_ms)
 {
-	ssize_t count, used;
-	short *p = (short *) &frame[*frameUsed];
-	int stereo = sound.soft.stereo;
-	short val;
-
-	ENTER(TRACE_ON,"collie_ct_u8");
-	frameLeft >>= 2;
-	if (stereo)
-		userCount >>= 1;
-	used = count = min(userCount, frameLeft);
-	if (!COLLE_RECORDING) {
-		while (count > 0) {
-			u_char data;
-
-			if (get_user(data, userPtr++)) {
-				LEAVE(TRACE_ON,"collie_ct_u8");
-				return -EFAULT;
-			}
-			val = data;
-			*p++ = (val ^ 0x80) << 8;		/* Left Ch. */
-			if ( stereo ) {
-				if ( get_user(data, userPtr++)) {
-					LEAVE(TRACE_ON,"collie_ct_u8");
-					return -EFAULT;
-				}
-				val = data;
-			}
-			*p++ = (val ^ 0x80) << 8;		/* Right Ch. */
-			count--;
-		}
-	} else {
-		while (count > 0) {
-			u_char data;
-			int ave;
-
-			if (get_user(data, userPtr++)) {
-				LEAVE(TRACE_ON,"collie_ct_u8");
-				return -EFAULT;
-			}
-			val = data;
-			ave = (val ^ 0x80) << 8;		/* Left Ch. */
-			if ( stereo ) {
-				if ( get_user(data, userPtr++)) {
-					LEAVE(TRACE_ON,"collie_ct_u8");
-					return -EFAULT;
-				}
-				val = data;
-			}
-			ave += (val ^ 0x80) << 8;		/* Right Ch. */
-			ave >>= 1;
-			*p++ = 0;			/* Left Ch. */
-			*p++ = ave;			/* Right Ch. */
-			count--;
-		}
-	}
-	*frameUsed += used * 4;
-	LEAVE(TRACE_ON,"collie_ct_u8");
-	return stereo? used * 2: used;
+	schedule_timeout(ten_ms);
 }
 
+/*** Translation ************************************************************/
 
 static ssize_t collie_ct_s16(const u_char *userPtr, size_t userCount,
 			   u_char frame[], ssize_t *frameUsed,
 			   ssize_t frameLeft)
 {
 	ssize_t count, used;
-	int stereo = sound.soft.stereo;
 	short *fp = (short *) &frame[*frameUsed];
+	short *up = (short *) userPtr;
 
-	ENTER(TRACE_ON,"collie_ct_s16");
 	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	used = count = min(userCount, frameLeft);
-	if (!stereo) {
-		short *up = (short *) userPtr;
-		while (count > 0) {
-			short data;
-			if (get_user(data, up++)) {
-				LEAVE(TRACE_ON,"collie_ct_s16");
-				return -EFAULT;
-			}
-			*fp++ = (!COLLE_RECORDING) ? data : 0;	/* Left Ch. */
-			*fp++ = data;
-			count--;
+	userCount >>= 2;
+	used = count = (userCount < frameLeft) ? userCount : frameLeft;
+	
+	while (count > 0) {
+
+		short data;
+		if (get_user(data, up++)) {
+			return -EFAULT;
 		}
-	} else {
-		short *up = (short *) userPtr;
-		while (count > 0) {
-			short data;
-			short temp;
-			if (get_user(data, up++)) {
-				LEAVE(TRACE_ON,"collie_ct_s16");
-				return -EFAULT;
-			}
-			if (get_user(temp, up++)) {
-				LEAVE(TRACE_ON,"collie_ct_s16");
-				return -EFAULT;
-			}
-			if (!COLLE_RECORDING) {
-				*fp++ = data;		/* Left Ch. */
-				*fp++ = temp;		/* Right Ch. */
-			} else {
-				data >>= 1;
-				data += (temp >> 1);
-				*fp++ = 0;		/* Left Ch. */
-				*fp++ = data;		/* Right Ch. */
-			}
-			count--;
+		if (!collie_recording) *fp++ = data;		
+		else *fp++=0;
+		
+		if (get_user(data, up++)) {
+			return -EFAULT;
 		}
+		*fp++ = data;		
+		count--;
 	}
+	
 	*frameUsed += used * 4;
-	LEAVE(TRACE_ON,"collie_ct_s16");
-	return stereo? used * 4: used * 2;
+	return used * 4;
 }
 
-static ssize_t collie_ct_u16(const u_char *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	ssize_t count, used;
-	int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-	int stereo = sound.soft.stereo;
-	short *fp = (short *) &frame[*frameUsed];
-	short *up = (short *) userPtr;
+/*** HARDWARE dependent stuff *********************************************************/
 
-	ENTER(TRACE_ON,"collie_ct_u16");
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	used = count = min(userCount, frameLeft);
-	if (!COLLE_RECORDING) {
-		while (count > 0) {
-			int data;
-			int temp;
-			if (get_user(data, up++)) {
-				LEAVE(TRACE_ON,"collie_ct_u16");
-				return -EFAULT;
-			}
-			data ^= mask;
-			*fp++ = data;			/* Left Ch. */
-			if (stereo) {
-				if (get_user(temp, up++)) {
-					LEAVE(TRACE_ON,"collie_ct_u16");
-					return -EFAULT;
-				}
-				temp ^= mask;
-				data  = temp;
-				data ^= mask;
-			}
-			*fp++ = data;			/* Right Ch. */
-			count--;
-		}
+static inline void Collie_DAC_sendbit(int bit_data)
+{
+	if (bit_data & 1) {
+		LCM_GPO |=  (LCM_GPIO_DAC_SDATA);
 	} else {
-		while (count > 0) {
-			int data;
-			int temp;
-			int ave;
-			if (get_user(data, up++)) {
-				LEAVE(TRACE_ON,"collie_ct_u16");
-				return -EFAULT;
-			}
-			data ^= mask;
-			ave = data;			/* Left Ch. */
-			if (stereo) {
-				if (get_user(temp, up++)) {
-					LEAVE(TRACE_ON,"collie_ct_u16");
-					return -EFAULT;
-				}
-				temp ^= mask;
-				data  = temp;
-				data ^= mask;
-			}
-			ave += data;
-			ave >>= 1;
-			*fp++ = 0;			/* Left Ch. */
-			*fp++ = ave;			/* Right Ch. */
-			count--;
-		}
+		LCM_GPO &= ~(LCM_GPIO_DAC_SDATA);
 	}
-	*frameUsed += used * 4;
-	LEAVE(TRACE_ON,"collie_ct_u16");
-	return stereo? used * 4: used * 2;
-}
 
-static TRANS transCollie = {
-	collie_ct_law, collie_ct_law, collie_ct_s8, collie_ct_u8,
-	collie_ct_s16, collie_ct_u16, collie_ct_s16, collie_ct_u16
-};
+	udelay(1);
+	LCM_GPO |=  (LCM_GPIO_DAC_SCK);
 
-/*** Low level stuff *********************************************************/
+	udelay(1);
+	LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
+	udelay(1);
+	LCM_GPO &= ~(LCM_GPIO_DAC_SDATA);
+	udelay(1);
+}
 
-static void Collie_Set_Volume(int volume)
+static void Collie_DAC_sendword(int data)
 {
-	ENTER(TRACE_ON,"Collie_Set_Volume");
-
-	sound.volume_left = volume & 0xff;
-	if ( sound.volume_left > 100 ) sound.volume_left = 100;
-
-	collie_main_volume = sound.volume_left;
-
-	sound.volume_right = ( volume & 0xff00 >> 8);
-	if ( sound.volume_right > 100 ) sound.volume_right = 100;
-	LEAVE(TRACE_ON,"Collie_Set_Volume");
+	int i;
 
-	collie_buzzer_volume = sound.volume_right;
+#if defined(CONFIG_COLLIE_PCM1741)
+	
+	LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
+	udelay(1);
+	LCM_GPO |=  (LCM_GPIO_DAC_SLOAD);
+	udelay(1);
 
-}
+	for (i = 0; i < 16; i++)
+		Collie_DAC_sendbit(data >> (15 - i));
 
+	LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
+	udelay(2);
 
-static int Collie_Get_Volume(void)
-{
-	ENTER(TRACE_ON,"Collie_Get_Volume");
-	LEAVE(TRACE_ON,"Collie_Get_Volume");
-	return ( sound.volume_right << 8 | sound.volume_left );
-}
+#elif defined(CONFIG_COLLIE_PCM1717)
+	
+	LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
+	udelay(1000);
+	LCM_GPO |=  (LCM_GPIO_DAC_SLOAD);
+	udelay(1000);
+	LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
+	udelay(1000);
 
-static void wait_ms(int ten_ms)
-{
-	ENTER(TRACE_ON,"wait_ms");
-	LEAVE(TRACE_ON,"wait_ms");
-	schedule_timeout(ten_ms);
-}
+	for (i = 0; i < 16; i++)
+		Collie_DAC_sendbit(data >> (15 - i));
 
-static inline void Collie_AMP_off(void)
-{
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_AMP,"Collie_AMP_off");
-#if 0	/* OBSOLETED: power controled by only OP_SHDN */
-	/* Set up TC35143 GPIO I/O Direction (GPIO4 output mode) */
-	ucb1200_set_io_direction(TC35143_GPIO_AMP_ON,
-				 TC35143_IODIR_OUTPUT);
- 	/* AMP OFF */
-	ucb1200_set_io(TC35143_GPIO_AMP_ON,
-		       TC35143_IODAT_LOW);
-	collie_amp_init = 0;
-#endif	/* 0 */
-	LEAVE(TRACE_AMP,"Collie_AMP_off");
-#endif	/* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
-}
-
-static inline void Collie_AMP_on(void)
-{
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_AMP,"Collie_AMP_on");
-//	if (!collie_amp_init) {
-		/* Set up TC35143 GPIO I/O Direction (GPIO4 output mode) */
-		ucb1200_set_io_direction(TC35143_GPIO_AMP_ON,
-					 TC35143_IODIR_OUTPUT);
-		/* AMP ON */
-		ucb1200_set_io(TC35143_GPIO_AMP_ON, TC35143_IODAT_HIGH);
-		SCP_REG_GPWR |= SCP_AMP_ON;
-		wait_ms(COLLIE_WAIT_AMP_ON);
-		collie_amp_init = 1;
-//	}
-	LEAVE(TRACE_AMP,"Collie_AMP_on");
-#endif	/* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
+	LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
+	udelay(1000);
+	LCM_GPO |=  (LCM_GPIO_DAC_SLOAD);
+	udelay(1000);
+	LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
+	udelay(1000);
+#endif
 }
 
-static inline void Collie_AMP_init(void)
-{
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_AMP,"Collie_AMP_init");
-  	Collie_AMP_off();
-	LEAVE(TRACE_AMP,"Collie_AMP_init");
-#endif	/* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
-}
 
 static inline void Collie_DAC_off(void)
 {
-	ENTER(TRACE_DAC,"Collie_DAC_off");
-	if (!COLLE_RECORDING) {
-		/* DAC OFF */
-		LCM_GPD &= ~(LCM_GPIO_DAC_ON);	/* set up output */
-		LCM_GPO &= ~(LCM_GPIO_DAC_ON);
-
-		/* LoCoMo GPIO disable */
-		LCM_GPE &= ~(LCM_GPIO_DAC_ON);
-		collie_dac_init = 0;
-	}
-	LEAVE(TRACE_DAC,"Collie_DAC_off");
+	/* DAC OFF */
+	LCM_GPD &= ~(LCM_GPIO_DAC_ON);	/* set up output */
+	LCM_GPO &= ~(LCM_GPIO_DAC_ON);
+	/* LoCoMo GPIO disable */
+	LCM_GPE &= ~(LCM_GPIO_DAC_ON);
+	collie_dac_init = 0;
 }
 
 static inline void Collie_DAC_on(void)
 {
-	ENTER(TRACE_DAC,"Collie_DAC_on");
-//	if (!collie_dac_init) {
 	if (!(LCM_GPO & LCM_GPIO_DAC_ON)) {
 		/* LoCoMo GPIO enable */
 		LCM_GPE &= ~LCM_GPIO_DAC_ON;
@@ -1049,24 +421,10 @@
 		    schedule();
 		}
 	}
-//	}
-	LEAVE(TRACE_DAC,"Collie_DAC_on");
-}
-
-#ifdef TRY_DELAY_OFF	/* H.Hayami SHARP */
-static inline void Collie_DAC_delay_off(void)
-{
-	ENTER(TRACE_DAC,"Collie_DAC_deleay_off");
-	down(&df_sem);
-	SetDelay(DELAY_DAC_OFF);
-	up(&df_sem);
-	LEAVE(TRACE_DAC,"Collie_DAC_delay_off");
 }
-#endif
 
 static inline void Collie_DAC_init(void)
 {
-	ENTER(TRACE_DAC,"Collie_DAC_init");
 	/* LoCoMo GPIO enable */
 	LCM_GPE &=
 	  ~(LCM_GPIO_DAC_SDATA | LCM_GPIO_DAC_SCK | LCM_GPIO_DAC_SLOAD);
@@ -1075,7 +433,6 @@
 	  ~(LCM_GPIO_DAC_SDATA | LCM_GPIO_DAC_SCK | LCM_GPIO_DAC_SLOAD);
 
 #if defined(CONFIG_COLLIE_PCM1741)
-
 	Collie_DAC_sendword(DAC_REG16_SetupData);	/* register16 */
 	Collie_DAC_sendword(DAC_REG17_SetupData);	/* register17 */
 	Collie_DAC_sendword(DAC_REG18_SetupData);	/* register18 */
@@ -1083,78 +440,53 @@
 	Collie_DAC_sendword(DAC_REG20_SetupData);	/* register20 */
 ////	Collie_DAC_sendword(DAC_REG21_SetupData);	/* register21 */
 	Collie_DAC_sendword(DAC_REG22_SetupData);	/* register22 */
-
 #elif defined(CONFIG_COLLIE_PCM1717)
-
 	Collie_DAC_sendword(DAC_MODE0_SetupData);	/* MODE0 */
 	Collie_DAC_sendword(DAC_MODE1_SetupData);	/* MODE1 */
 	Collie_DAC_sendword(DAC_MODE2_SetupData);	/* MODE2 */
 	Collie_DAC_sendword(DAC_MODE3_SetupData);	/* MODE3 */
-
 #endif
-
 	/* LoCoMo GPIO disable */
 	LCM_GPE &=
 	  ~(LCM_GPIO_DAC_SDATA | LCM_GPIO_DAC_SCK | LCM_GPIO_DAC_SLOAD);
-	LEAVE(TRACE_DAC,"Collie_DAC_init");
 }
 
 static inline void Collie_soft_DAC_on(void)
 {
 #if defined(CONFIG_COLLIE_PCM1741)
-	ENTER(TRACE_DAC, "Collie_soft_DAC_on");
 	Collie_DAC_sendword(DAC_REG19_DACOn);	/* register19 */
-	LEAVE(TRACE_DAC, "Collie_soft_DAC_on");
 #endif	/* CONFIG_COLLIE_PCM1741 */
 }
 
 static inline void Collie_soft_DAC_off(void)
 {
 #if defined(CONFIG_COLLIE_PCM1741)
-	ENTER(TRACE_DAC, "Collie_soft_DAC_off");
        	Collie_DAC_sendword(DAC_REG19_DACOff);	/* register19 */
-	LEAVE(TRACE_DAC, "Collie_soft_DAC_off");
-#endif	/* CONFIG_COLLIE_PCM1741 */
-}
-
-static inline void Collie_soft_mute_init(void)
-{
-#if defined(CONFIG_COLLIE_PCM1741)
-	ENTER(TRACE_MUTE, "Collie_soft_mute_init");
-	Collie_DAC_sendword(DAC_REG18_MuteOn);	/* register18 */
-	collie_soft_mute = 1;
-	LEAVE(TRACE_MUTE, "Collie_soft_mute_init");
 #endif	/* CONFIG_COLLIE_PCM1741 */
 }
 
 static inline void Collie_soft_mute_on(void)
 {
 #if defined(CONFIG_COLLIE_PCM1741)
-	ENTER(TRACE_MUTE, "Collie_soft_mute_on");
 	if (!collie_soft_mute) {
 		Collie_DAC_sendword(DAC_REG18_MuteOn);	/* register18 */
 		collie_soft_mute = 1;
 	}
-	LEAVE(TRACE_MUTE, "Collie_soft_mute_on");
 #endif	/* CONFIG_COLLIE_PCM1741 */
 }
 
 static inline void Collie_soft_mute_off(void)
 {
 #if defined(CONFIG_COLLIE_PCM1741)
-	ENTER(TRACE_MUTE, "Collie_soft_mute_off");
 	if (collie_soft_mute) {
 		Collie_DAC_sendword(DAC_REG18_MuteOff);	/* register18 */
 		collie_soft_mute = 0;
 	}
-	LEAVE(TRACE_MUTE, "Collie_soft_mute_off");
 #endif	/* CONFIG_COLLIE_PCM1741 */
 }
 
 static inline void Collie_hard_mute_init(void)
 {
-#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_MUTE, "Collie_hard_mute_init");
 	SCP_REG_GPCR |= (SCP_GPCR_PA14 | SCP_GPCR_PA15);
 #ifdef HARD_MUTE_CTRL_DISABLE
 	SCP_REG_GPWR |= (SCP_GPCR_PA14 | SCP_GPCR_PA15);
@@ -1162,84 +494,107 @@
 	SCP_REG_GPWR &= ~(SCP_GPCR_PA14 | SCP_GPCR_PA15);
 #endif	/* HARD_MUTE_CTRL_DISABLE */
 	collie_hard_mute = 1;
-#if !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
+
 	{
 		int time = jiffies + 5;
 		while (jiffies <= time)
 			schedule();
 	}
-#endif
-	LEAVE(TRACE_MUTE, "Collie_hard_mute_init");
-#endif	/* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
 }
 
 static inline void Collie_hard_mute_on(void)
 {
-#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
 #ifndef HARD_MUTE_CTRL_DISABLE
-	ENTER(TRACE_MUTE, "Collie_hard_mute_on");
 	if (!collie_hard_mute) {
 		SCP_REG_GPWR &= ~(SCP_GPCR_PA14 | SCP_GPCR_PA15);
 		collie_hard_mute = 1;
-#if !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
 		{
 			int time = jiffies + 5;
 			while (jiffies <= time)
 				schedule();
 		}
-#endif
 	}
-	LEAVE(TRACE_MUTE, "Collie_hard_mute_on");
 #endif	/* HARD_MUTE_CTRL_DISABLE */
-#endif	/* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
 }
 
 static inline void Collie_hard_mute_off(void)
 {
-#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
 #ifndef HARD_MUTE_CTRL_DISABLE
-	ENTER(TRACE_MUTE, "Collie_hard_mute_off");
 	if (collie_hard_mute) {
-		if (!COLLE_RECORDING)
 			SCP_REG_GPWR |= (SCP_GPCR_PA14 | SCP_GPCR_PA15);
-		else
-			SCP_REG_GPWR |= (SCP_GPCR_PA15);
 		collie_hard_mute = 0;
-#if !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
 		{
 			int i;
 			for (i=0; i<=1000; i++) {
 				udelay(1);
 			}
 		}
-#endif
 	}
-	LEAVE(TRACE_MUTE, "Collie_hard_mute_off");
 #endif	/* HARD_MUTE_CTRL_DISABLE */
-#endif	/* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
-}
-
-#ifdef TRY_DELAY_OFF	/* H.Hayami SHARP 2001.12.19 */
-static inline void Collie_hard_mute_delay_on(void)
-{
-	ENTER(TRACE_MUTE, "Collie_hard_mute_delay_on");
-	down(&df_sem);
-	SetDelay(DELAY_HARD_MUTE_ON);
-	up(&df_sem);
-	LEAVE(TRACE_MUTE, "Collie_hard_mute_delay_on");
 }
-#endif
 
-static inline void Collie_audio_clock_init(void)
+static inline void Collie_hard_mute_left_on(void)
+{
+#ifndef HARD_MUTE_CTRL_DISABLE
+//	if (!collie_hard_mute) {
+		SCP_REG_GPWR &= ~(SCP_GPCR_PA14);
+		{
+			int time = jiffies + 5;
+			while (jiffies <= time)
+				schedule();
+		}
+//	}
+#endif	/* HARD_MUTE_CTRL_DISABLE */
+}
+
+static inline void Collie_hard_mute_left_off(void)
+{
+#ifndef HARD_MUTE_CTRL_DISABLE
+//	if (collie_hard_mute) {
+		SCP_REG_GPWR |= (SCP_GPCR_PA14);
+		{
+			int i;
+			for (i=0; i<=1000; i++) {
+				udelay(1);
+			}
+		}
+//	}
+#endif	/* HARD_MUTE_CTRL_DISABLE */
+}
+
+
+static int CollieGetSamp(void)
+{
+	switch (sound.speed) {
+	case 8000:
+	  	return clock_set_data[7];
+	case 44100:
+	  	return clock_set_data[0];
+	case 22050:
+	  	return clock_set_data[1];
+	case 11025:
+	  	return clock_set_data[2];
+	case 48000:
+	  	return clock_set_data[3];
+	case 32000:
+	  	return clock_set_data[4];
+	case 24000:
+	  	return clock_set_data[5];
+	case 16000:
+	  	return clock_set_data[6];
+	default:
+		printk("Collie sound: Illegal sound rate %d\n", sound.speed);
+		return clock_set_data[7];
+	}
+}
+
+static inline void Collie_audio_clock_init(void)
 {
-	ENTER(TRACE_CLOCK, "Collie_audio_clock_init");
 	LCM_ACC = 0;
-	LEAVE(TRACE_CLOCK, "Collie_audio_clock_init");
 }
 
 static inline void Collie_audio_clock_on(void)
 {
-	ENTER(TRACE_CLOCK, "Collie_audio_clock_on");
 	/* LoCoMo Audio clock on */
 	LCM_ACC  = CollieGetSamp();
 	barrier();
@@ -1248,263 +603,58 @@
 	LCM_ACC |= LCM_ACC_XEN;
 	barrier();
 	LCM_ACC |= (LCM_ACC_MCLKEN | LCM_ACC_64FSEN);
-	LEAVE(TRACE_CLOCK, "Collie_audio_clock_on");
 }
 
 static inline void Collie_audio_clock_off(void)
 {
-	ENTER(TRACE_CLOCK, "Collie_audio_clock_off");
 	/* LoCoMo Audio clock off */
 	LCM_ACC &= ~(LCM_ACC_XEN | LCM_ACC_MCLKEN | LCM_ACC_64FSEN);
 	barrier();
 	LCM_ACC &= ~(LCM_ACC_XON);
-	LEAVE(TRACE_CLOCK, "Collie_audio_clock_off");
-}
-
-static inline void Collie_paif_init(void)
-{
-	ENTER(TRACE_PAIF, "Collie_paif_init");
-	//	LCM_PAIF  = (LCM_PAIF_SCINV | LCM_PAIF_LRCRST);
-	LCM_PAIF  = (LCM_PAIF_LRCRST);
-	LEAVE(TRACE_PAIF, "Collie_paif_init");
 }
 
 static inline void Collie_paif_on(void)
 {
-	ENTER(TRACE_PAIF, "Collie_paif_on");
 	LCM_PAIF  = (LCM_PAIF_SCINV | LCM_PAIF_LRCRST);
 	LCM_PAIF &= ~(LCM_PAIF_LRCRST);
 	LCM_PAIF |= (LCM_PAIF_SCEN | LCM_PAIF_LRCEN);
-	LEAVE(TRACE_PAIF, "Collie_paif_on");
 }
 
 static inline void Collie_paif_off(void)
 {
-	ENTER(TRACE_PAIF, "Collie_paif_off");
-	//	LCM_PAIF  = (LCM_PAIF_SCINV | LCM_PAIF_LRCRST);
 	LCM_PAIF  = (LCM_PAIF_LRCRST);
-	LEAVE(TRACE_PAIF, "Collie_paif_off");
 }
 
 static inline void Collie_MIC_init(void)
 {
-#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_MIC, "Collie_MIC_init");
 	/* MIC to GPIO 17 */
 	/* alternate functions for the GPIOs */
-	GAFR &= ~( COLLIE_GPIO_MIC );
-	
+	GAFR &= ~( COLLIE_GPIO_MIC );	
 	/* Set the direction: 17 output */
 	GPDR |= ( COLLIE_GPIO_MIC );
-	
-#if defined(CONFIG_COLLIE_TR1)
-	/* Set pin level (Low) */
-       	GPCR = ( COLLIE_GPIO_MIC );
-#else
 	/* Set pin level (High) */
        	GPSR = ( COLLIE_GPIO_MIC );
-#endif
-	LEAVE(TRACE_MIC, "Collie_MIC_init");
-#endif	/* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
 }
 
 static inline void Collie_MIC_on(void)
 {
-#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_MIC, "Collie_MIC_on");
-#if defined(CONFIG_COLLIE_TR1)
-	GPSR = ( COLLIE_GPIO_MIC );
-#else
 	GPCR = ( COLLIE_GPIO_MIC );
-#endif
-	LEAVE(TRACE_MIC, "Collie_MIC_on");
-#endif	/* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
 }
 
 static inline void Collie_MIC_off(void)
 {
-#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_MIC, "Collie_MIC_off");
-	if (!COLLE_RECORDING) {
-#if defined(CONFIG_COLLIE_TR1)
-	       	GPCR = ( COLLIE_GPIO_MIC );
-#else
-       		GPSR = ( COLLIE_GPIO_MIC );
-#endif
-	}
-	LEAVE(TRACE_MIC, "Collie_MIC_off");
-#endif	/* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
-}
-
-static inline void Collie_volume_init(void)
-{
-	ENTER(TRACE_VOLUME, "Collie_volume_init");
-	m62332_senddata(0, M62332_EVR_CH);
-	collie_volume = 0;
-	LEAVE(TRACE_VOLUME, "Collie_volume_init");
-}
-
-static inline void Collie_volume_on(void)
-{
-	ENTER(TRACE_VOLUME, "Collie_volume_on");
-	if (collie_volume != sound.volume_left) {
-		//Collie_hard_mute_on();
-		m62332_senddata(0xff * sound.volume_left / 100, M62332_EVR_CH);
-		//Collie_hard_mute_off();
-		collie_volume = sound.volume_left;
-	}
-	LEAVE(TRACE_VOLUME, "Collie_volume_on");
-}
-
-static inline void Collie_volume_off(void)
-{
-	ENTER(TRACE_VOLUME, "Collie_volume_off");
-	if (collie_volume) {
-		//Collie_hard_mute_on();
-		m62332_senddata(0, M62332_EVR_CH);
-		//Collie_hard_mute_off();
-		collie_volume = 0;
-	}
-	LEAVE(TRACE_VOLUME, "Collie_volume_off");
-}
-
-#define	VOL_THRES	40
-static void Collie_volume_half_adjust(void)
-{
-	int	volume = collie_volume;
-	ENTER(TRACE_VOLUME, "Collie_volume_half_adjust");
-	if (collie_volume > sound.volume_left) {
-		/* volume down */
-		if (collie_volume > VOL_THRES) {
-			if (sound.volume_left > VOL_THRES) {
-				volume = (collie_volume + sound.volume_left)/2;
-				if (volume == collie_volume) {
-					volume = sound.volume_left;
-				}
-			} else {
-				volume = (collie_volume + VOL_THRES)/2;
-				if (volume == collie_volume) {
-					volume = VOL_THRES;
-				}
-			}
-		} else {
-			/* we can pull down without noise */
-			volume = sound.volume_left;
-		}
-	} else if (collie_volume < sound.volume_left) {
-		/* volume up */
-		if (sound.volume_left > VOL_THRES) {
-			if (collie_volume < VOL_THRES) {
-				/* we can pull up to VOL_THRES without noise */
-				volume = VOL_THRES;;
-			} else {
-				volume = (collie_volume + sound.volume_left)/2;
-				if (volume == collie_volume) {
-					volume = sound.volume_left;
-				}
-			}
-		} else {
-			/* we can pull up without noise */
-			volume = sound.volume_left;
-		}
-	}
-	if (collie_volume != volume) {
-		m62332_senddata(0xff * volume / 100, M62332_EVR_CH);
-		collie_volume = volume;
-	}
-	LEAVE(TRACE_VOLUME, "Collie_volume_half_adjust");
-}
-
-static void Collie_volume_half_off(void)
-{
-	int volume;
-	int delta = 1;
-	ENTER(TRACE_VOLUME, "Collie_volume_half_off");
-	while (0 < collie_volume) {
-		if (collie_volume <= VOL_THRES) {
-			volume = 0;
-		} else {
-			if (collie_volume > delta) {
-				volume = collie_volume - delta;
-			} else {
-				volume = 0;
-			}
-			if (volume && volume < VOL_THRES) {
-				volume = VOL_THRES;
-			}
-			delta <<= 1;
-		}
-		m62332_senddata(0xff * volume / 100, M62332_EVR_CH);
-		collie_volume = volume;
-		udelay(100);
-	}
-	LEAVE(TRACE_VOLUME, "Collie_volume_half_off");
-}
-
-static void Collie_OP_SHDN_on(void)
-{
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_OP_SHDN,"Collie_OP_SHDN_on");
-	if (!collie_op_shdn_on) {
-		/* set volume */
-		Collie_volume_off();
-
-		/* OP_SHDN to GPIO 17 */
-		/* alternate functions for the GPIOs */
-		GAFR &= ~( COLLIE_GPIO_OPSHDN );
-	
-		/* Set the direction: 17 output */
-		GPDR |= ( COLLIE_GPIO_OPSHDN );
-	
-		/* Set pin level (high) */
-		GPSR |= ( COLLIE_GPIO_OPSHDN );
-		
-		/* set volume */
-		Collie_volume_on();
-
-		collie_op_shdn_on = 1;
-	}
-	LEAVE(TRACE_OP_SHDN,"Collie_OP_SHDN_on");
-#endif	/* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
-}
-
-static void Collie_OP_SHDN_off(void)
-{
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_OP_SHDN,"Collie_OP_SHDN_off");
-	/* OP_SHDN to GPIO 17 */
-	/* alternate functions for the GPIOs */
-	GAFR &= ~( COLLIE_GPIO_OPSHDN );
-	
-	/* Set the direction: 17 output */
-	GPDR |= ( COLLIE_GPIO_OPSHDN );
-	
-	/* Clear pin level (low) */
-	GPCR |= ( COLLIE_GPIO_OPSHDN );
-
-	collie_op_shdn_on = 0;
-	LEAVE(TRACE_OP_SHDN,"Collie_OP_SHDN_off");
-#endif	/* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
+ 	GPSR = ( COLLIE_GPIO_MIC );
 }
 
 static inline void Collie_ssp_init(void)
 {
-	ENTER(TRACE_SSP, "Collie_ssp_init");
 	/* alternate functions for the GPIOs */
 	/* SSP port to GPIO 10,12,13, 19 */
 	GAFR |= ( GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK );
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-	/* SSP port to GPIO 11 */
-	GAFR |= GPIO_SSP_RXD;
-#endif	/* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
 
 	/* Set the direction: 10, 12, 13 output; 19 input */
 	GPDR |= ( GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM );
 	GPDR &= ~( GPIO_SSP_CLK );
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-	/* Set the direction: 11 input */
-	GPDR &= ~( GPIO_SSP_RXD );
-#endif	/* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
 
 	/* enable SSP pin swap */
 	PPAR |= PPAR_SPR;
@@ -1516,400 +666,162 @@
 	/* the SSP setting */
 	Ser4SSCR0 = (SSCR0_DataSize(16) | SSCR0_TI | SSCR0_SerClkDiv(2));
 	Ser4SSCR1 = (SSCR1_SClkIactL | SSCR1_SClk1P | SSCR1_ExtClk);
-
-	LEAVE(TRACE_SSP, "Collie_ssp_init");
 }
 
 static inline void Collie_ssp_on(void)
 {
-	ENTER(TRACE_SSP, "Collie_ssp_on");
 	/* turn on the SSP */
 	Ser4SSCR0 |= ( SSCR0_SSE );
-	LEAVE(TRACE_SSP, "Collie_ssp_on");
 }
 
 static inline void Collie_ssp_off(void)
 {
-	ENTER(TRACE_SSP, "Collie_ssp_off");
 	/* turn off the SSP */
 	Ser4SSCR0 &= ~( SSCR0_SSE );
-	LEAVE(TRACE_SSP, "Collie_ssp_off");
-}
-
-static inline void Collie_sound_hard_init(void)
-{
-	ENTER(TRACE_ON, "Collie_sound_hard_init");
-	Collie_hard_mute_init();
-	Collie_audio_clock_init();
-	Collie_paif_init();
-	Collie_volume_init();
-	Collie_ssp_init();
-	Collie_MIC_init();
-
-	Collie_FS8KLPF_start();
-	LEAVE(TRACE_ON, "Collie_sound_hard_init");
-}
-
-static inline void Collie_sound_hard_term(void)
-{
-	ENTER(TRACE_ON, "Collie_sound_hard_term");
-#ifdef DAC_OFF_WITH_DEVICE_OFF
-	/* DAC Off */
-	Collie_DAC_off();
-#endif
-	LEAVE(TRACE_ON, "Collie_sound_hard_term");
-}
-
-static void Collie_FS8KLPF_start(void)
-{
-#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-	ENTER(TRACE_ON,"Collie_FS8KLPF_start");
-	/* Set up TC35143 GPIO I/O Direction (GPIO5 output mode) */
-	ucb1200_set_io_direction(TC35143_GPIO_FS8KLPF,
-				 TC35143_IODIR_OUTPUT);
-	/* Set up TC35143 GPIO 5 (set LOW) */
-	ucb1200_set_io(TC35143_GPIO_FS8KLPF, TC35143_IODAT_LOW);
-	LEAVE(TRACE_ON,"Collie_FS8KLPF_start");
-#endif	/* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
-}
-
-#ifdef CONFIG_PM
-#if 0
-static void Collie_FS8KLPF_stop(void)
-{
-	/* Set up TC35143 GPIO I/O Direction (GPIO5 output mode) */
-	ucb1200_set_io_direction(TC35143_GPIO_FS8KLPF,
-				 TC35143_IODIR_OUTPUT);
-	/* Set up TC35143 GPIO 5 (set LOW) */
-	ucb1200_set_io(TC35143_GPIO_FS8KLPF, TC35143_IODAT_HIGH);
-}
-
-static void Collie_clock_stop(void)
-{
-	/* LoCoMo PCM audio interface */
-	Collie_paif_off();
-
-	/* LoCoMo audio clock off */
-	Collie_audio_clock_off();
-}
-#endif
-#endif
-
-#ifdef TRY_DELAY_OFF	/* H.Hayami SHARP 2001.12.19 */
-static unsigned long in_timehandle = 0;
-static struct timer_list timer;
-
-static void collieDoDelayedSilence(void)
-{
-	ENTER(TRACE_ON,"collieDoDelayedSilence");
-	down(&df_sem);
-	if(isDelayed(DELAY_HARD_MUTE_ON)) {
-		Collie_hard_mute_on();
-	}
-	if(isDelayed(DELAY_DAC_OFF)) {
-		Collie_DAC_off();
-	}
-	ResetDelayAll();
-	up(&df_sem);
-	LEAVE(TRACE_ON,"colliDoDelayedSilence");
-}
-
-static void collieDelayedSilence(void)
-{
-	ENTER(TRACE_ON,"collieDelayedSilence");
-	while (1) {
-		sleep_on(&delay_off);
-		collieDoDelayedSilence();
-	}
-	LEAVE(TRACE_ON,"collieDelayedSilence");
-}
-
-static void collieStartDelayedSilence(unsigned long data)
-{
-	ENTER(TRACE_ON,"collieStartDelayedSilence");
-	in_timehandle = 0;
-	wake_up(&delay_off);
-	LEAVE(TRACE_ON,"collieStartDelayedSilence");
-}
-
-static void collieTriggerDelayedSilence(void)
-{
-	ENTER(TRACE_ON,"collieTriggerDelayedSilence");
-	in_timehandle = 1;
-	init_timer(&timer);
-	timer.function = collieStartDelayedSilence;
-	timer.expires = jiffies + 5*100;
-	add_timer(&timer);
-	LEAVE(TRACE_ON,"collieTriggerDelayedSilence");
-}
-
-static void collieCancelDelayedSilence(void)
-{
-	ENTER(TRACE_ON,"collieCancelDelayedSilence");
-	down(&df_sem);
-	ResetDelayAll();;
-	up(&df_sem);
-	if (in_timehandle) {
-		del_timer(&timer);
-		in_timehandle = 0;
-	}
-	LEAVE(TRACE_ON,"collieCancelDelayedSilence");
-}
-#endif
-
-static void Collie_disable_sound(void)
-{
-	ENTER(TRACE_ON,"Collie_disable_sound");
-	sa1100_dma_stop(COLLIE_SOUND_DMA_CHANNEL);
-	sa1100_dma_flush_all(COLLIE_SOUND_DMA_CHANNEL);
-#ifndef TRY_DELAY_OFF	/* H.Hayami SHARP 2001.12.18 */
-	Collie_volume_half_off();
-	Collie_hard_mute_on();
-	Collie_soft_mute_on();
-
-	Collie_ssp_off();
-
-	/* Collie_clock_stop(); */
-#endif
-	LEAVE(TRACE_ON,"Collie_disable_sound");
-}
-
-static void CollieSilence(void)
-{
-	ENTER(TRACE_ON,"CollieSilence");
-	/* Disable sound & DMA */
-	Collie_disable_sound();
-
-#ifdef TRY_DELAY_OFF	/* H.Hayami SHARP 2001.12.18 */
-	Collie_volume_half_off();
-	Collie_hard_mute_delay_on();
-	Collie_soft_mute_on();
-
-	Collie_ssp_off();
-
-	/* Collie_clock_stop(); */
-#endif
-
-#if 0	/* H.Hayami SHARP 2001.12.18 */
-#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0) && \
-    !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
-	Collie_volume_off();
-#endif
-#endif
-	Collie_OP_SHDN_off();
-	Collie_soft_DAC_off();
-	Collie_paif_off();
-	Collie_audio_clock_off();
-
-	//Collie_MIC_on();
-
-#ifndef DAC_OFF_WITH_DEVICE_OFF
-	/* DAC Off */
-#ifdef TRY_DELAY_OFF	/* H.Hayami 2001.12.15 */
-	Collie_DAC_delay_off();
-#else
-	Collie_DAC_off();
-#endif
-#endif	/* end DAC_OFF_WITH_DEVICE_OFF */
-
-	/* AMP Off */
-	Collie_AMP_off();
-
-#ifdef TRY_DELAY_OFF	/* H.Hayami SHARP 2001.12.18 */
-	collieTriggerDelayedSilence();
-#endif
-	LEAVE(TRACE_ON,"CollieSilence");
-}
-
-static int CollieGetSamp(void)
-{
-	ENTER(TRACE_ON,"CollieGetSamp");
-	switch (sound.soft.speed) {
-	case 8000:
-		LEAVE(TRACE_ON,"CollieGetSamp");
-	  	return clock_set_data[7];
-	case 44100:
-		LEAVE(TRACE_ON,"CollieGetSamp");
-	  	return clock_set_data[0];
-	case 22050:
-		LEAVE(TRACE_ON,"CollieGetSamp");
-	  	return clock_set_data[1];
-	case 11025:
-		LEAVE(TRACE_ON,"CollieGetSamp");
-	  	return clock_set_data[2];
-	case 48000:
-		LEAVE(TRACE_ON,"CollieGetSamp");
-	  	return clock_set_data[3];
-	case 32000:
-		LEAVE(TRACE_ON,"CollieGetSamp");
-	  	return clock_set_data[4];
-	case 24000:
-		LEAVE(TRACE_ON,"CollieGetSamp");
-	  	return clock_set_data[5];
-	case 16000:
-		LEAVE(TRACE_ON,"CollieGetSamp");
-	  	return clock_set_data[6];
-	default:
-		printk("Collie sound: Illegal sound rate %d\n", sound.soft.speed);
-		LEAVE(TRACE_ON,"CollieGetSamp");
-		return clock_set_data[7];
-	}
-}
-
-static inline void Collie_DAC_sendbit(int bit_data)
-{
-	ENTER(TRACE_SENDDATA,"Collie_DAC_sendbit");
-	if (bit_data & 1) {
-		LCM_GPO |=  (LCM_GPIO_DAC_SDATA);
-	} else {
-		LCM_GPO &= ~(LCM_GPIO_DAC_SDATA);
-	}
-
-	udelay(1);
-	LCM_GPO |=  (LCM_GPIO_DAC_SCK);
-
-	udelay(1);
-	LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
-	udelay(1);
-	LCM_GPO &= ~(LCM_GPIO_DAC_SDATA);
-	udelay(1);
-	LEAVE(TRACE_SENDDATA,"Collie_DAC_sendbit");
-}
-
-static void Collie_DAC_sendword(int data)
-{
-	int i;
-
-	ENTER(TRACE_SENDDATA,"Collie_DAC_sendword");
-#if defined(CONFIG_COLLIE_PCM1741)
-	
-	LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
-	udelay(1);
-	LCM_GPO |=  (LCM_GPIO_DAC_SLOAD);
-	udelay(1);
-
-	for (i = 0; i < 16; i++)
-		Collie_DAC_sendbit(data >> (15 - i));
-
-	LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-	udelay(2);
-
-#elif defined(CONFIG_COLLIE_PCM1717)
-	
-	LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-	udelay(1000);
-	LCM_GPO |=  (LCM_GPIO_DAC_SLOAD);
-	udelay(1000);
-	LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
-	udelay(1000);
-
-	for (i = 0; i < 16; i++)
-		Collie_DAC_sendbit(data >> (15 - i));
-
-	LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-	udelay(1000);
-	LCM_GPO |=  (LCM_GPIO_DAC_SLOAD);
-	udelay(1000);
-	LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-	udelay(1000);
-	
-#endif
-	LEAVE(TRACE_SENDDATA,"Collie_DAC_sendword");
 }
 
-void
-Collie_audio_power_on(void)
+
+static inline void Collie_sound_hard_init(void)
 {
-	int send_data;
+	Collie_hard_mute_init();
+	Collie_audio_clock_init();
+	Collie_paif_off();
+	Collie_volume_init();
+	Collie_ssp_init();
+	Collie_MIC_init();
+	Collie_soft_mute_on();
+	Collie_DAC_on();
+}
 
-	ENTER(TRACE_ON,"Collie_audio_power_on");
+void Collie_recording_on(void)
+{
+	collie_recording=1;
+	if (!playing) 
+	    Collie_DAC_on();
+	else
+	    Collie_hard_mute_left_on();
+	Collie_MIC_on();
+}
 
-#ifdef TRY_DELAY_OFF	/* H.Hayami SHARP 2001.12.19 */
-	collieCancelDelayedSilence();
-#endif
+void Collie_recording_off(void)
+{
+	collie_recording=0;
+	Collie_MIC_off();
+	if (!playing) 
+	    Collie_DAC_off();
+	else 
+	    Collie_hard_mute_left_off();
+}
 
+static void Collie_audio_power_on(void)
+{
+	playing=1;
 	collie_amp_init = 0;
-
-	/* OP_SHDN off */
-	Collie_OP_SHDN_off();
-
-	/* AMP on */
-	Collie_AMP_on();
-
-	/* DAC ON */
-	Collie_DAC_on();
-
-	Collie_MIC_off();
-	Collie_ssp_on();
-	
-	/* LoCoMo Audio clock */
-	Collie_audio_clock_off();
+	if (!collie_recording)
+	    Collie_DAC_on();
+	Collie_ssp_on();	
+	Collie_audio_clock_off();       /* LoCoMo Audio clock */
 	Collie_audio_clock_on();
-
-	/* LoCoMo PCM audio interface */
-	Collie_paif_on();
-
+	Collie_paif_on();		/* LoCoMo PCM audio interface */
 	udelay(1000);
-
-	/* DAC Setting */
 	Collie_DAC_init();
-
 	Collie_soft_DAC_on();
-	Collie_soft_mute_init();
+	Collie_soft_mute_off();
+	Collie_hard_mute_off();
+	if (collie_recording)
+	    Collie_hard_mute_left_on();
+	Collie_volume_set(sound.volume);
+}
 
-	sound.hard = sound.soft;
+static void Collie_audio_power_off(void){	/* Disable sound only */
+    Collie_volume_set(0);
+    Collie_hard_mute_on();
+    Collie_soft_mute_on();
+    Collie_ssp_off();
+    Collie_soft_DAC_off();
+    Collie_paif_off();
+    Collie_audio_clock_off();
+    if (!collie_recording)
+	Collie_DAC_off();
+    playing=0;
+}
 
-#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0) && \
-    !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
-	/* Volume set */
-	Collie_volume_half_adjust();
-	{
-		int i;
-		for (i=0; i<10*1000; i++) {
-			udelay(1);
+
+static inline void Collie_volume_init(void)
+{
+	m62332_senddata(0, M62332_EVR_CH);
+	collie_volume = 0;
+}
+
+#define	VOL_THRES	10
+
+static void Collie_volume_set(int dest)
+{
+	int	chn;
+	while (dest != collie_volume) {
+		chn = dest-collie_volume;
+		if (chn>VOL_THRES)
+		    chn=VOL_THRES;    
+		else if (chn<-VOL_THRES)
+		    chn=-VOL_THRES;
+		if (chn) {
+		    collie_volume += chn;
+		    m62332_senddata(0xff * collie_volume / 100, M62332_EVR_CH);
 		}
+		udelay(100);
 	}
-#endif
+}
 
-	Collie_soft_mute_off();
-	Collie_hard_mute_off();
+static int sound_set_speed(int speed)
+{
+	if (speed < 0) {
+		return(sound.speed);
+	}
+
+	if (speed<8000) sound.speed=8000;
+	else if (speed<=11025) sound.speed=11025;
+	else if (speed<=16000) sound.speed=16000;
+	else if (speed<=22050) sound.speed=22050;
+	else if (speed<=24000) sound.speed=24000;
+	else if (speed<=32000) sound.speed=32000;
+	else if (speed<=44100) sound.speed=44100;
+	else sound.speed=48000;
+
+	/* LoCoMo Audio clock */
+	Collie_audio_clock_off();
+	Collie_audio_clock_on();
+	return(sound.speed);
+}
 
-	LEAVE(TRACE_ON,"Collie_audio_power_on");
+/*** Mid level stuff *********************************************************/
+
+static void Collie_Set_Volume(int volume)
+{
+	sound.volume = volume & 0xff;
+	sound.volume += ( volume & 0xff00 >> 8);
+	sound.volume >>=1;
+	if (sound.volume>100) sound.volume=100;	
 }
 
-static void CollieInit(void)
+static int Collie_Get_Volume(void)
 {
-	ENTER(TRACE_ON,"CollieInit");
-	sound.hard = sound.soft;
-	LEAVE(TRACE_ON,"CollieInit");
+	return ( sound.volume << 8 | sound.volume );
 }
 
+
 static void Collie_sq_interrupt(void* id, int size)
 {
 	audio_buf_t *b = (audio_buf_t *) id;
-	ENTER(TRACE_INTERRUPT,"Collie_sq_interrupt");
-/***** DEBUG *****
-printk("Collie_sq_interrupt: Start\n");
-*****************/
+
 	/*
 	 * Current buffer is sent: wake up any process waiting for it.
 	 */
-	ENTER(TRACE_SEM,"up sem");
 	up(&b->sem);
-	LEAVE(TRACE_SEM,"up sem");
-/***** DEBUG *****
-printk("Collie_sq_interrupt: up End\n");
-*****************/
 	/* And any process polling on write. */
-	ENTER(TRACE_SEM,"up wait");
-	wake_up(&b->sem.wait);
-	LEAVE(TRACE_SEM,"up wait");
-/***** DEBUG *****
-printk("Collie_sq_interrupt: wake_up End\n");
-*****************/
+	wake_up_interruptible(&b->sem.wait);
+	/* And indicate which was the last buffer sent */
 
 	DPRINTK("Collie_sq_interrupt \n");
-	LEAVE(TRACE_INTERRUPT,"Collie_sq_interrupt");
 }
 
 
@@ -1917,191 +829,52 @@
 {
 	int err;
 
-	ENTER(TRACE_ON,"CollieIrqInit");
 	err = sa1100_request_dma(&collie_dmasound_irq, "dmasound",
 				 DMA_Ser4SSPWr);
 	if (err) {
-		LEAVE(TRACE_ON,"CollieIrqInit");
 		return 0;
 	}
-	/* printk("collie_dmasound_irq=%d\n", collie_dmasound_irq); */
+	printk("collie_dmasound_irq=%d\n", collie_dmasound_irq); 
 
 	sa1100_dma_set_callback(collie_dmasound_irq,
 			       (dma_callback_t)Collie_sq_interrupt);
 
-
-	/* Disable sound & DMA */
-	Collie_disable_sound();
-
-	LEAVE(TRACE_ON,"CollieIrqInit");
+	sa1100_dma_stop(COLLIE_SOUND_DMA_CHANNEL);
+	sa1100_dma_flush_all(COLLIE_SOUND_DMA_CHANNEL);
+	Collie_audio_power_off();
 	return(1);
-
-}
-
-#ifdef MODULE
-static void CollieIrqCleanUp(void)
-{
-	ENTER(TRACE_ON,"CollieIrqCleanUp");
-	/* Disable sound & DMA */
-	Collie_disable_sound();
-
-	/* release the interrupt */
-	free_irq(IRQ_DMA, Collie_sq_interrupt);
-	LEAVE(TRACE_ON,"CollieIrqCleanUp");
 }
-#endif /* MODULE */
-
 
 static int CollieSetFormat(int format)
 {
 	int size;
 
-	ENTER(TRACE_ON,"CollieSetFormat");
-	/* Falcon sound DMA supports 8bit and 16bit modes */
-
 	switch (format) {
 	case AFMT_QUERY:
-		LEAVE(TRACE_ON,"CollieSetFormat");
-		return(sound.soft.format);
-	case AFMT_MU_LAW:
-		size = 8;
-		ct_func = sound.trans->ct_ulaw;
-		break;
-	case AFMT_A_LAW:
-		size = 8;
-		ct_func = sound.trans->ct_alaw;
-		break;
-	case AFMT_S8:
-		size = 8;
-		ct_func = sound.trans->ct_s8;
-		break;
-	case AFMT_U8:
-		size = 8;
-		ct_func = sound.trans->ct_u8;
-		break;
-	case AFMT_S16_BE:
-		size = 16;
-		ct_func = sound.trans->ct_s16be;
-		break;
-	case AFMT_U16_BE:
-		size = 16;
-		ct_func = sound.trans->ct_u16be;
-		break;
-	case AFMT_S16_LE:
-		size = 16;
-		ct_func = sound.trans->ct_s16le;
-		break;
-	case AFMT_U16_LE:
+		return(sound.format);
+	default: /* This is the only one supported by the hardware it seems */
 		size = 16;
-		ct_func = sound.trans->ct_u16le;
-		break;
-	default: /* :-) */
-		size = 8;
-		format = AFMT_S8;
-	}
-
-	sound.soft.format = format;
-	sound.soft.size = size;
-	if (sound.minDev == SND_DEV_DSP) {
-		sound.dsp.format = format;
-		sound.dsp.size = sound.soft.size;
+		format = AFMT_S16_LE;
 	}
+	sound.format = format;
+	sound.size = size;
 
-	LEAVE(TRACE_ON,"CollieSetFormat");
 	return(format);
 }
 
-/*** Machine definitions *****************************************************/
-
-static MACHINE machCollie = {
-	DMASND_COLLIE,		// int type
-	NULL,			// void *dma_alloc(uint, int)
-	NULL,			// void  dma_free(void *, uint)
-	CollieIrqInit,		// void  irqinit(void)
-#ifdef MODULE
-	CollieIrqCleanUp,	// void  irqcleanup(void)
-#endif /* MODULE */
-	CollieInit,		// void  init(void)
-	CollieSilence,		// void  silence(void)
-	CollieSetFormat,	// int   setFormat(int)
-	NULL,			// int   setVolume(int)
-	NULL,			// int   setBass(int)
-	NULL,			// int   setTreble(int)
-	NULL,			// int   setGain(int)
-	NULL			// void  play(void)
-};
-
-
-/*** Mid level stuff *********************************************************/
-
-
-static void sound_silence(void)
-{
-	ENTER(TRACE_ON,"sound_silence");
-	/* update hardware settings one more */
-	//(*sound.mach.init)();
-	(*sound.mach.silence)();
-	LEAVE(TRACE_ON,"sound_silence");
-
-}
-
-
-static void sound_init(void)
-{
-	ENTER(TRACE_ON,"sound_init");
-	(*sound.mach.init)();
-	LEAVE(TRACE_ON,"sound_init");
-}
-
-
-static int sound_set_format(int format)
-{
-	ENTER(TRACE_ON,"sound_set_format");
-	LEAVE(TRACE_ON,"sound_set_format");
-	return(*sound.mach.setFormat)(format);
-}
-
-
-static int sound_set_speed(int speed)
-{
-	ENTER(TRACE_ON,"sound_set_speed");
-	if (speed < 0) {
-		LEAVE(TRACE_ON,"sound_set_speed");
-		return(sound.soft.speed);
-	}
-
-	sound.soft.speed = speed;
-	(*sound.mach.init)();
-	if (sound.minDev == SND_DEV_DSP)
-		sound.dsp.speed = sound.soft.speed;
-
-	/* LoCoMo Audio clock */
-	Collie_audio_clock_off();
-	Collie_audio_clock_on();
-
-	LEAVE(TRACE_ON,"sound_set_speed");
-	return(sound.soft.speed);
-}
 
 
 static int sound_set_stereo(int stereo)
 {
-	ENTER(TRACE_ON,"sound_set_stereo");
+/* Only stereo is supported by hardware */
 	if (stereo < 0) {
-		LEAVE(TRACE_ON,"sound_set_stereo");
-		return(sound.soft.stereo);
+		return(sound.stereo);
 	}
+	return(1);
+}
 
-	stereo = !!stereo;    /* should be 0 or 1 now */
-
-	sound.soft.stereo = stereo;
-	if (sound.minDev == SND_DEV_DSP)
-		sound.dsp.stereo = stereo;
-	//(*sound.mach.init)();
 
-	LEAVE(TRACE_ON,"sound_set_stereo");
-	return(stereo);
-}
+/* Higher level stuff ************************************************/
 
 /*
  * /dev/mixer abstraction
@@ -2109,20 +882,15 @@
 
 static int mixer_open(struct inode *inode, struct file *file)
 {
-	ENTER(TRACE_ON,"mixer_open");
 	MOD_INC_USE_COUNT;
 	mixer.busy = 1;
-	LEAVE(TRACE_ON,"mixer_open");
 	return 0;
 }
 
-
 static int mixer_release(struct inode *inode, struct file *file)
 {
-	ENTER(TRACE_ON,"mixer_release");
 	mixer.busy = 0;
 	MOD_DEC_USE_COUNT;
-	LEAVE(TRACE_ON,"mixer_release");
 	return 0;
 }
 
@@ -2132,58 +900,37 @@
 {
 	int data;
 
-	ENTER(TRACE_ON,"mixer_ioctl");
-	switch (sound.mach.type) {
-	case DMASND_COLLIE:
-	{
-		switch (cmd) {
-			case SOUND_MIXER_READ_DEVMASK:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, SOUND_MASK_VOLUME );
-			case SOUND_MIXER_READ_RECMASK:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, 0);
-			case SOUND_MIXER_READ_STEREODEVS:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
-			case SOUND_MIXER_READ_CAPS:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, 0);
-
-			case SOUND_MIXER_WRITE_VOLUME:
-				IOCTL_IN(arg, data);
-				Collie_Set_Volume(data);
-			case SOUND_MIXER_READ_VOLUME:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, Collie_Get_Volume());
-
-			case SOUND_MIXER_READ_TREBLE:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, 0);
-			case SOUND_MIXER_WRITE_TREBLE:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, 0);
-
-			case SOUND_MIXER_WRITE_MIC:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, 0);
-			case SOUND_MIXER_READ_MIC:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, 0);
-
-			case SOUND_MIXER_READ_SPEAKER:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, 0);
-			case SOUND_MIXER_WRITE_SPEAKER:
-				LEAVE(TRACE_ON,"mixer_ioctl");
-				return IOCTL_OUT(arg, 0);
-		}
-			break;
-	}
-	}
-	LEAVE(TRACE_ON,"mixer_ioctl");
+	switch (cmd) {
+		case SOUND_MIXER_READ_DEVMASK:
+			return IOCTL_OUT(arg, headphone ? SOUND_MASK_VOLUME : 0 );
+		case SOUND_MIXER_READ_RECMASK:
+			return IOCTL_OUT(arg, 0);
+		case SOUND_MIXER_READ_STEREODEVS:
+			return IOCTL_OUT(arg, headphone ? SOUND_MASK_VOLUME : 0 );
+		case SOUND_MIXER_READ_CAPS:
+			return IOCTL_OUT(arg, 0);
+
+		case SOUND_MIXER_WRITE_VOLUME:
+			IOCTL_IN(arg, data);
+			Collie_Set_Volume(data);
+		case SOUND_MIXER_READ_VOLUME:
+			return IOCTL_OUT(arg, Collie_Get_Volume());
+		case SOUND_MIXER_READ_TREBLE:
+			return IOCTL_OUT(arg, 0);
+		case SOUND_MIXER_WRITE_TREBLE:
+			return IOCTL_OUT(arg, 0);
+
+		case SOUND_MIXER_WRITE_MIC:
+			return IOCTL_OUT(arg, 0);
+		case SOUND_MIXER_READ_MIC:
+			return IOCTL_OUT(arg, 0);
+
+		case SOUND_MIXER_READ_SPEAKER:
+			return IOCTL_OUT(arg, 0);
+		case SOUND_MIXER_WRITE_SPEAKER:
+			return IOCTL_OUT(arg, 0);
+	}	
 	return -EINVAL;
-
 }
 
 
@@ -2198,32 +945,13 @@
 
 static void __init mixer_init(void)
 {
-#ifndef MODULE
-	int mixer_unit;
-#endif
-	ENTER(TRACE_ON,"mixer_init");
 	mixer_unit = register_sound_mixer(&mixer_fops, -1);
 	if (mixer_unit < 0) {
-		LEAVE(TRACE_ON,"mixer_init");
 		return;
 	}
-
 	mixer.busy = 0;
-	sound.treble = 0;
-	sound.bass = 0;
-	switch (sound.mach.type) {
-		case DMASND_COLLIE:
-		  //			sound.volume_left  = 0x3c;
-		  //			sound.volume_right = 0x3c;
-		  	sound.volume_left  = 80;
-		  	sound.volume_right = 80;
-			collie_main_volume = sound.volume_left;
-			break;
-	}
-
-	//	printk("mixer_init : ret \n");
-
-	LEAVE(TRACE_ON,"mixer_init");
+	sound.volume  = 80;
+	Collie_volume_set(sound.volume);
 }
 
 /* This function allocates the buffer structure array and buffer data space
@@ -2237,11 +965,9 @@
 	char *dmabuf = 0;
 	dma_addr_t dmaphys = 0;
 
-	ENTER(TRACE_ON,"sq_allocate_buffers");
 	DPRINTK("sq_allocate_buffers\n");
 
 	if (s->buffers) {
-		LEAVE(TRACE_ON,"sq_allocate_buffers");
 		return -EBUSY;
 	}
 
@@ -2279,10 +1005,8 @@
 
 		b->start = dmabuf;
 		b->dma_addr = dmaphys;
+		b->idx = frag;
 		sema_init(&b->sem, 1);
-		DPRINTK("buf %d: start %p dma %p\n", frag, b->start,
-			b->dma_addr);
-
 		dmabuf += s->fragsize;
 		dmaphys += s->fragsize;
 		dmasize -= s->fragsize;
@@ -2291,13 +1015,12 @@
 	s->buf_idx = 0;
 	s->buf = &s->buffers[0];
 
-	LEAVE(TRACE_ON,"sq_allocate_buffers");
+
 	return 0;
 
 err:
 	printk("sound driver : unable to allocate audio memory\n ");
 	sq_release_buffers(s);
-	LEAVE(TRACE_ON,"sq_allocate_buffers");
 	return -ENOMEM;
 }
 
@@ -2307,7 +1030,6 @@
 
 static void sq_release_buffers(audio_stream_t * s)
 {
-	ENTER(TRACE_ON,"sq_release_buffers");
 	DPRINTK("sq_release_buffers\n");
 
 	/* ensure DMA won't run anymore */
@@ -2328,7 +1050,6 @@
 
 	s->buf_idx = 0;
 	s->buf = NULL;
-	LEAVE(TRACE_ON,"sq_release_buffers");
 }
 
 static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
@@ -2339,27 +1060,20 @@
 	u_char *dest;
 	ssize_t uUsed, bUsed, bLeft, ret = 0;
 
-	ENTER(TRACE_WRITE,"sq_write");
 	DPRINTK("sq_write: uLeft=%d\n", uLeft);
 
-	/* OP_SHDN on */
-	Collie_OP_SHDN_on();
-
 	switch (file->f_flags & O_ACCMODE) {
 	case O_WRONLY:
 	case O_RDWR:
 		break;
 	default: 
-		LEAVE(TRACE_WRITE,"sq_write1");
 		return -EPERM;
 	} 
 
 	if (!s->buffers && sq_allocate_buffers(s)) {
-		LEAVE(TRACE_WRITE,"sq_write2");
 		return -ENOMEM;
 	}
 
-#if 1
 	if (collie_resume == 1) {
 		int	i;
 		collie_resume = 0;
@@ -2367,10 +1081,9 @@
 			udelay(1);
 		}
 	}
-#endif
 #ifdef CONFIG_PM
 	/* Auto Power off cancel */
-	autoPowerCancel = 0;
+//	autoPowerCancel = 0;
 #endif
 
 	while (uLeft > 0) {
@@ -2379,41 +1092,30 @@
 		/* Wait for a buffer to become free */
 		if (file->f_flags & O_NONBLOCK) {
 			ret = -EAGAIN;
-			ENTER(TRACE_SEM,"down_try sem");
 			if (down_trylock(&b->sem)) {
-				LEAVE(TRACE_SEM,"down_try1 sem");
 				break;
 			}
-			LEAVE(TRACE_SEM,"down_try2 sem");
 		} else {
 			ret = -ERESTARTSYS;
-			ENTER(TRACE_SEM,"down_int sem");
-			//printk("### 0x%08x:%d\n", &b->sem.count, atomic_read(&b->sem.count));
 			if (down_interruptible(&b->sem)) {
-				LEAVE(TRACE_SEM,"down_int1 sem");
 				break;
 			}
-			LEAVE(TRACE_SEM,"down_int2 sem");
 		}
 
 		dest = b->start + b->size;
 		bUsed = 0;
 		bLeft = s->fragsize - b->size;
 
-		if (ct_func) {
-			uUsed = ct_func(src, uLeft, dest, &bUsed, bLeft);
+		if (collie_ct_s16) {
+			uUsed = collie_ct_s16(src, uLeft, dest, &bUsed, bLeft);
 			cpu_cache_clean_invalidate_range((unsigned long)dest,
 				(unsigned long)(dest+(audio_fragsize)), 0);
 		} else {
-			LEAVE(TRACE_WRITE,"sq_write3");
 			return -EFAULT;
 		}
 
 		if (uUsed < 0) {
-			ENTER(TRACE_SEM,"up sem");
 			up(&b->sem);
-			LEAVE(TRACE_SEM,"up sem");
-			LEAVE(TRACE_WRITE,"sq_write4");
 			return -EFAULT;
 		}
 		src += uUsed;
@@ -2421,9 +1123,7 @@
 		b->size += bUsed;
 
 		if (b->size < s->fragsize) {
-			ENTER(TRACE_SEM,"up sem");
 			up(&b->sem);
-			LEAVE(TRACE_SEM,"up sem");
 			break;
 		}
 
@@ -2431,7 +1131,7 @@
 		sa1100_dma_queue_buffer(COLLIE_SOUND_DMA_CHANNEL,
 		 			(void *) b, b->dma_addr, b->size);
 
-		Collie_volume_half_adjust();
+		Collie_volume_set(sound.volume);
 
 		b->size = 0;    /* indicate that the buffer has been sent */
 		NEXT_BUF(s, buf);
@@ -2440,7 +1140,6 @@
 	if ((src - buffer0))
 		ret = src - buffer0;
 	DPRINTK("sq_write: return=%d\n", ret);
-	LEAVE(TRACE_WRITE,"sq_write0");
 	return ret;
 }
 
@@ -2450,7 +1149,6 @@
 	unsigned int mask = 0;
 	int i;
 
-	ENTER(TRACE_ON,"sq_poll");
 	DPRINTK("sq_poll(): mode=%s%s\n",
 		(file->f_mode & FMODE_READ) ? "r" : "",
 		(file->f_mode & FMODE_WRITE) ? "w" : "");
@@ -2458,12 +1156,9 @@
 	if (file->f_mode & FMODE_WRITE) {
 		if (!output_stream.buffers 
 		    && sq_allocate_buffers(&output_stream)) {
-			LEAVE(TRACE_ON,"sq_poll");
 			return -ENOMEM;
 		}
-		ENTER(TRACE_SEM,"poll_wait wait");
 		poll_wait(file, &output_stream.buf->sem.wait, wait);
-		LEAVE(TRACE_SEM,"poll_wait wait");
 	}
 
 	if (file->f_mode & FMODE_WRITE) {
@@ -2477,65 +1172,33 @@
 		(mask & POLLIN) ? "r" : "",
 		(mask & POLLOUT) ? "w" : "");
 
-	LEAVE(TRACE_ON,"sq_poll");
 	return mask;
 }
 
 static int sq_open(struct inode *inode, struct file *file)
 {
-	ENTER(TRACE_ON,"sq_open");
 	DPRINTK("sq_open\n");
 
 	if (((file->f_flags & O_ACCMODE) == O_WRONLY)
 	 || ((file->f_flags & O_ACCMODE) == O_RDWR)) {
-#if 0
-		MOD_INC_USE_COUNT;
-		while(audio_wr_refcount) {
-			SLEEP(open_queue, ONE_SECOND);
-			if (SIGNAL_RECEIVED) {
-				MOD_DEC_USE_COUNT;
-				LEAVE(TRACE_ON,"sq_open");
-				return -EINTR;
-			}
-		}
-#else
 		if (audio_wr_refcount) {
 			DPRINTK(" sq_open        EBUSY\n");
-			LEAVE(TRACE_ON,"sq_open");
 			return -EBUSY;
 		}
 		MOD_INC_USE_COUNT;
-#endif
 		audio_wr_refcount++;
 	} else {
 		DPRINTK(" sq_open        EINVAL\n");
-		LEAVE(TRACE_ON,"sq_open");
 		return -EINVAL;
 	}
 
-	if (audio_wr_refcount == 1) {
-		DPRINTK("cold\n");
-
-		audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;
-		audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;
-		sq_release_buffers(&output_stream);
-		sound.minDev = MINOR(inode->i_rdev) & 0x0f;
-		sound.soft = sound.dsp;
-		sound.hard = sound.dsp;
-
-		if ((MINOR(inode->i_rdev) & 0x0f) == SND_DEV_AUDIO) {
-			sound_set_speed(8000);
-			sound_set_stereo(0);
-			sound_set_format(AFMT_MU_LAW);
-		}
-		Collie_audio_power_on();
-	}
 
-#if 0
-	MOD_INC_USE_COUNT;
-#endif
-	LEAVE(TRACE_ON,"sq_open");
-	return 0;
+	audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;
+	audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;
+	sq_release_buffers(&output_stream);
+	output_stream.buf_idx=0;
+	Collie_audio_power_on();
+    	return 0;
 }
 
 static int sq_fsync(struct file *filp, struct dentry *dentry)
@@ -2543,11 +1206,9 @@
 	audio_stream_t *s = &output_stream;
 	audio_buf_t *b = s->buf;
 
-	ENTER(TRACE_ON,"sq_fsync");
 	DPRINTK("sq_fsync\n");
 
 	if (!s->buffers) {
-		LEAVE(TRACE_ON,"sq_fsync");
 		return 0;
 	}
 
@@ -2557,12 +1218,10 @@
 
 #ifdef CONFIG_PM
 		/* Auto Power off cancel */
-		autoPowerCancel = 0;
+//		autoPowerCancel = 0;
 #endif
 
-		ENTER(TRACE_SEM,"down sem");
 		down(&b->sem);
-		LEAVE(TRACE_SEM,"down sem");
 		sa1100_dma_queue_buffer(COLLIE_SOUND_DMA_CHANNEL,
 					(void *) b, b->dma_addr, b->size);
 		b->size = 0;
@@ -2576,23 +1235,15 @@
 	 * - the buffer was already free thus nothing else to sync.
 	 */
 	b = s->buffers + ((s->nbfrags + s->buf_idx - 1) % s->nbfrags);
-	ENTER(TRACE_SEM,"down-int sem");
 	if (down_interruptible(&b->sem)) {
-		LEAVE(TRACE_SEM,"down-int sem");
-		LEAVE(TRACE_ON,"sq_fsync");
 		return -EINTR;
 	}
-	LEAVE(TRACE_SEM,"down-int sem");
-	ENTER(TRACE_SEM,"up sem");
 	up(&b->sem);
-	LEAVE(TRACE_SEM,"up sem");
-	LEAVE(TRACE_ON,"sq_fsync");
 	return 0;
 }
 
 static int sq_release(struct inode *inode, struct file *file)
 {
-	ENTER(TRACE_ON,"sq_release");
 	DPRINTK("sq_release\n");
 
 	switch (file->f_flags & O_ACCMODE) {
@@ -2606,24 +1257,12 @@
 	}       
 
 	if (!audio_wr_refcount) {
-		sound.soft = sound.dsp;
-		sound.hard = sound.dsp;
-		sound_silence();
-		Collie_OP_SHDN_off();
+		sa1100_dma_stop(COLLIE_SOUND_DMA_CHANNEL);
+		sa1100_dma_flush_all(COLLIE_SOUND_DMA_CHANNEL);
+		Collie_audio_power_off();
 	} 
 
-#if 0
-	switch (file->f_flags & O_ACCMODE) {
-	case O_WRONLY:
-	case O_RDWR:
-		if (!audio_wr_refcount) {
-			WAKE_UP(open_queue);
-		}
-	}
-#endif
-
 	MOD_DEC_USE_COUNT;
-	LEAVE(TRACE_ON,"sq_release");
 	return 0;
 }
 
@@ -2634,8 +1273,8 @@
 	u_long fmt;
 	int data;
 	long val;
+//	audio_buf_info abinfo;
 
-	ENTER(TRACE_ON,"sq_ioctl");
 	switch (cmd) {
 	case SNDCTL_DSP_RESET:
 		switch (file->f_flags & O_ACCMODE) {
@@ -2643,11 +1282,9 @@
 		case O_RDWR:
 			sq_release_buffers(&output_stream);
 		}
-		LEAVE(TRACE_ON,"sq_ioctl");
 		return 0;
 	case SNDCTL_DSP_POST:
 	case SNDCTL_DSP_SYNC:
-		LEAVE(TRACE_ON,"sq_ioctl");
 		return sq_fsync(file, file->f_dentry);
 
 		/* ++TeSche: before changing any of these it's
@@ -2656,59 +1293,34 @@
 	case SNDCTL_DSP_SPEED:
 		sq_fsync(file, file->f_dentry);
 		IOCTL_IN(arg, data);
-		LEAVE(TRACE_ON,"sq_ioctl");
 		return IOCTL_OUT(arg, sound_set_speed(data));
 	case SNDCTL_DSP_STEREO:
 		sq_fsync(file, file->f_dentry);
 		IOCTL_IN(arg, data);
-		LEAVE(TRACE_ON,"sq_ioctl");
 		return IOCTL_OUT(arg, sound_set_stereo(data));
-	case SOUND_PCM_WRITE_CHANNELS:
+	case SNDCTL_DSP_CHANNELS:
 		sq_fsync(file, file->f_dentry);
 		IOCTL_IN(arg, data);
-		LEAVE(TRACE_ON,"sq_ioctl");
 		return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
 	case SNDCTL_DSP_SETFMT:
 		sq_fsync(file, file->f_dentry);
 		IOCTL_IN(arg, data);
-		LEAVE(TRACE_ON,"sq_ioctl");
-		return IOCTL_OUT(arg, sound_set_format(data));
+		return IOCTL_OUT(arg, CollieSetFormat(data));
 	case SNDCTL_DSP_GETFMTS:
-		fmt = 0;
-		if (sound.trans) {
-			if (sound.trans->ct_ulaw)
-				fmt |= AFMT_MU_LAW;
-			if (sound.trans->ct_alaw)
-				fmt |= AFMT_A_LAW;
-			if (sound.trans->ct_s8)
-				fmt |= AFMT_S8;
-			if (sound.trans->ct_u8)
-				fmt |= AFMT_U8;
-			if (sound.trans->ct_s16be)
-				fmt |= AFMT_S16_BE;
-			if (sound.trans->ct_u16be)
-				fmt |= AFMT_U16_BE;
-			if (sound.trans->ct_s16le)
-				fmt |= AFMT_S16_LE;
-			if (sound.trans->ct_u16le)
-				fmt |= AFMT_U16_LE;
-		}
-		LEAVE(TRACE_ON,"sq_ioctl");
+		fmt = AFMT_S16_LE;
 		return IOCTL_OUT(arg, fmt);
 	case SNDCTL_DSP_GETBLKSIZE:
-		LEAVE(TRACE_ON,"sq_ioctl");
 		return IOCTL_OUT(arg, audio_fragsize);
 	case SNDCTL_DSP_SUBDIVIDE:
 		break;
 	case SNDCTL_DSP_SETFRAGMENT:
 		if (output_stream.buffers) {
-			LEAVE(TRACE_ON,"sq_ioctl");
 			return -EBUSY;
 		}
 		get_user(val, (long *) arg);
 		audio_fragsize = 1 << (val & 0xFFFF);
-		if (audio_fragsize < 16)
-			audio_fragsize = 16;
+		if (audio_fragsize < 256)
+			audio_fragsize = 256;
 		if (audio_fragsize > 16384)
 			audio_fragsize = 16384;
 		audio_nbfrags = (val >> 16) & 0x7FFF;
@@ -2717,46 +1329,54 @@
 		if (audio_nbfrags * audio_fragsize > 128 * 1024)
 			audio_nbfrags = 128 * 1024 / audio_fragsize;
 		if (sq_allocate_buffers(&output_stream)) {
-			LEAVE(TRACE_ON,"sq_ioctl");
 			return -ENOMEM;
 		}
-		LEAVE(TRACE_ON,"sq_ioctl");
 		return 0;
 
-#if 1 // 2003.2.14
+/*	case SNDCTL_DSP_GETOSPACE:
+		abinfo.fragsize   = audio_fragsize;
+		abinfo.fragstotal = audio_nbfrags;
+		abinfo.fragments  = lastsent-output_stream.buf_idx;
+		if (abinfo.fragments<0)
+		    abinfo.fragments += abinfo.fragstotal;		    
+		abinfo.bytes      = abinfo.fragments*abinfo.fragsize;
+		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+*/
 	case SNDCTL_DSP_GETOSPACE:
 	    {
-		audio_buf_info inf = { 0, };
+		audio_stream_t *s = &output_stream;
+		audio_buf_info *inf = (audio_buf_info *) arg;
+		int err = verify_area(VERIFY_WRITE, inf, sizeof(*inf));
 		int i;
+		int frags = 0, bytes = 0;
 
-		if (!(file->f_mode & FMODE_WRITE))
-			return -EINVAL;
-		if (!output_stream.buffers && sq_allocate_buffers(&output_stream))
-			return -ENOMEM;
-		for (i = 0; i < output_stream.nbfrags; i++) {
-			if (atomic_read(&output_stream.buffers[i].sem.count) > 0) {
-				if (output_stream.buffers[i].size == 0)
-					inf.fragments++;
-				inf.bytes += output_stream.fragsize - output_stream.buffers[i].size;
-			}
+		if (err)
+			return err;
+		if (output_stream.buffers)  {
+		    for (i = 0; i < s->nbfrags; i++) {
+			if (atomic_read(&s->buffers[i].sem.count) > 0) {
+				if (s->buffers[i].size == 0) frags++;
+				bytes += s->fragsize - s->buffers[i].size;
+			}
+		    }
+		    put_user(s->nbfrags, &inf->fragstotal);
+		    put_user(s->fragsize, &inf->fragsize);
+		} else {
+		    frags=audio_nbfrags;
+		    bytes=frags*audio_fragsize;
+		    put_user(frags, &inf->fragstotal);
+		    put_user(audio_fragsize, &inf->fragsize);
 		}
-		inf.fragstotal = output_stream.nbfrags;
-		inf.fragsize = output_stream.fragsize;
-		return copy_to_user((void *)arg, &inf, sizeof(inf));
+		put_user(frags, &inf->fragments);
+		return put_user(bytes, &inf->bytes);
 	    }
-#endif
-
 
 	default:
-		LEAVE(TRACE_ON,"sq_ioctl");
 		return mixer_ioctl(inode, file, cmd, arg);
 	}
-	LEAVE(TRACE_ON,"sq_ioctl");
 	return -EINVAL;
 }
 
-
-
 static struct file_operations sq_fops =
 {
 	llseek: sound_lseek,
@@ -2770,40 +1390,18 @@
 
 static void __init sq_init(void)
 {
-#ifndef MODULE
-	int sq_unit;
-#endif
-	ENTER(TRACE_ON,"sq_init");
 	sq_unit = register_sound_dsp(&sq_fops, -1);
 	if (sq_unit < 0) {
-		LEAVE(TRACE_ON,"sq_init");
 		return;
 	}
 
-	/* whatever you like as startup mode for /dev/dsp,
-	 * (/dev/audio hasn't got a startup mode). note that
-	 * once changed a new open() will *not* restore these!
-	 */
-	sound.dsp.format = AFMT_S16_LE;
-
-	sound.dsp.stereo = 0;
-	sound.dsp.size = 16;
-
-	/* set minimum rate possible without expanding */
-	switch (sound.mach.type) {
-		case DMASND_COLLIE:
-		  	sound.dsp.speed = 8000;
-			break;
-	}
-
-	/* before the first open to /dev/dsp this wouldn't be set */
-	sound.soft = sound.dsp;
-	sound.hard = sound.dsp;
-	sound.trans = &transCollie;
-
-	CollieSetFormat(sound.dsp.format);
-	sound_silence();
-	LEAVE(TRACE_ON,"sq_init");
+	sound.format = AFMT_S16_LE;
+	sound.stereo = 1;
+	sound.speed = 44100;
+
+	CollieSetFormat(AFMT_S16_LE);
+	Collie_audio_power_off();
+	output_stream.buf=output_stream.buffers=NULL;
 }
 
 /*
@@ -2816,9 +1414,7 @@
 	char *buffer = state.buf;
 	int len = 0;
 
-	ENTER(TRACE_ON,"state_open");
 	if (state.busy) {
-		LEAVE(TRACE_ON,"state_open");
 		return -EBUSY;
 	}
 
@@ -2828,8 +1424,8 @@
 
 	len += sprintf(buffer+len, "  COLLIE DMA sound driver:\n");
 
-	len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format);
-	switch (sound.soft.format) {
+	len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.format);
+	switch (sound.format) {
 	case AFMT_MU_LAW:
 		len += sprintf(buffer+len, " (mu-law)");
 		break;
@@ -2857,22 +1453,19 @@
 	}
 	len += sprintf(buffer+len, "\n");
 	len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
-		       sound.soft.speed, sound.hard.speed);
+		       sound.speed, sound.speed);
 	len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
-		       sound.soft.stereo,
-		       sound.soft.stereo ? "stereo" : "mono");
+		       sound.stereo,
+		       sound.stereo ? "stereo" : "mono");
 	state.len = len;
-	LEAVE(TRACE_ON,"state_open");
 	return 0;
 }
 
 
 static int state_release(struct inode *inode, struct file *file)
 {
-	ENTER(TRACE_ON,"state_release");
 	state.busy = 0;
 	MOD_DEC_USE_COUNT;
-	LEAVE(TRACE_ON,"state_release");
 	return 0;
 }
 
@@ -2881,19 +1474,15 @@
 			  loff_t *ppos)
 {
 	int n = state.len - state.ptr;
-	ENTER(TRACE_ON,"state_read");
 	if (n > count)
 		n = count;
 	if (n <= 0) {
-		LEAVE(TRACE_ON,"state_read");
 		return 0;
 	}
 	if (copy_to_user(buf, &state.buf[state.ptr], n)) {
-		LEAVE(TRACE_ON,"state_read");
 		return -EFAULT;
 	}
 	state.ptr += n;
-	LEAVE(TRACE_ON,"state_read");
 	return n;
 }
 
@@ -2909,20 +1498,11 @@
 
 static void __init state_init(void)
 {
-#ifndef MODULE
-	int state_unit;
-#endif
-	ENTER(TRACE_ON,"state_unit");
 	state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
 	if (state_unit < 0) {
-		LEAVE(TRACE_ON,"state_unit");
 		return;
 	}
 	state.busy = 0;
-
-	//	printk("state_init : ret \n");
-	LEAVE(TRACE_ON,"state_unit");
-
 }
 
 
@@ -2930,8 +1510,6 @@
 
 static long long sound_lseek(struct file *file, long long offset, int orig)
 {
-	ENTER(TRACE_ON,"sound_lseek");
-	LEAVE(TRACE_ON,"sound_lseek");
 	return -ESPIPE;
 }
 
@@ -2941,96 +1519,41 @@
 static int collie_sound_pm_callback(struct pm_dev *pm_dev,
 				    pm_request_t req, void *data)
 {
-	ENTER(TRACE_PM,"collie_sound_pm_callback");
 	switch (req) {
 	case PM_SUSPEND:
 #ifdef COLLIE_TRY_ONE
 		disable_irq(IRQ_GPIO_nREMOCON_INT);
 #endif
-#ifdef TRY_DELAY_OFF	/* H.Hayami SHARP 2001.12.19 */
-		collieDoDelayedSilence();
-		collieCancelDelayedSilence();
-#endif
-		if (audio_wr_refcount == 1) {
-			Collie_volume_off();
-			Collie_hard_mute_on();
-			Collie_soft_mute_on();
-			sa1100_dma_sleep((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
-
-#if 0	/* H.Hayami SHARP 2001.12.18 */
-#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0) && \
-    !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
-			Collie_volume_off();
-#endif
-#endif
-			Collie_OP_SHDN_off();
-			Collie_soft_DAC_off();
-			Collie_paif_off();
-			Collie_audio_clock_off();
-			//Collie_MIC_on();
-			Collie_DAC_off();
-			Collie_AMP_off();
-		} else {
-			sa1100_dma_sleep((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
-		}
-		Collie_sound_hard_term();
+		sa1100_dma_sleep((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
+		Collie_audio_power_off();
 		break;
 	case PM_RESUME:
-/***** DEBUG *****g
-printk("collie_sound_pm_callback: audio_wr_refcount=%d\n", audio_wr_refcount);
-*****************/
+
 #ifdef COLLIE_TRY_ONE
 		enable_irq(IRQ_GPIO_nREMOCON_INT);
 #endif
-
-		Collie_sound_hard_init();
-
-		if (audio_wr_refcount == 1) {
-			collie_resume = 1;
-
-			Collie_audio_power_on();
-
-			sa1100_dma_wakeup((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
-#if 0	/* H.Hayami SHARP 2001.12.18 */
-			Collie_soft_mute_off();
-			Collie_hard_mute_off();
-#endif
-		} else {
+		Collie_sound_hard_init();    /* this needs to be done! */
+		collie_resume = 1;
+		Collie_audio_power_off();
+		if (audio_wr_refcount) Collie_audio_power_on();
+		if (collie_recording) Collie_recording_on();
+		sa1100_dma_wakeup((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
 #ifdef COLLIE_TRY_ONE
-		  if ( !( GPLR & GPIO_nREMOCON_INT ) )
+		if ( !( GPLR & GPIO_nREMOCON_INT ) )
 		    Collie_DAC_on();
 #endif
-			sa1100_dma_wakeup((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
-		}
-
-
 		break;
-
 	}
-	LEAVE(TRACE_PM,"collie_sound_pm_callback");
 	return 0;
 }
 #endif
 
 
 #ifdef COLLIE_TRY_ONE
-
-static void collie_audio_on(void)
-{
-    while(1) {
-      sleep_on(&audio_on);
-
-      /* DAC ON */
-      Collie_DAC_on();
-      //      printk("call audio on \n");
-
-    }
-}
-
 void Collie_rc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-  //  printk("int !\n");
-  wake_up(&audio_on);
+  headphone=!headphone;
+  printk("%s headphone \n",headphone ? "connected" : "disconnected");
 }
 #endif
 
@@ -3038,113 +1561,85 @@
 
 int __init Collie_sound_init(void)
 {
-	int has_sound = 0;
-
-
-	ENTER(TRACE_ON,"Collie_sound_init");
-	has_sound = 1;
-	sound.mach = machCollie;
-
-	if (!has_sound) {
-		LEAVE(TRACE_ON,"Collie_sound_init");
-		return -1;
-	}
-
-#ifdef TRY_DELAY_OFF	/* H.Hayami SHARP 2001.12.19 */
-	sema_init(&df_sem, 1);
-	kernel_thread(collieDelayedSilence, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-#endif
-
 	Collie_sound_hard_init();
-
-	if (!sound.mach.irqinit()) {
+	if (!CollieIrqInit()) {
 		printk("Sound driver: Interrupt initialization failed\n");
-		LEAVE(TRACE_ON,"Collie_sound_init");
 		return -1;
 	}
-
-	/* Set up sound queue, /dev/audio and /dev/dsp. */
-
 	/* Set default settings. */
 	sq_init();
-
 	/* Set up /dev/sndstat. */
 	state_init();
-
 	/* Set up /dev/mixer. */
 	mixer_init();
-
 #ifdef MODULE
 	irq_installed = 1;
 #endif
-
 	printk("Collie Sound Driver Installed\n");
-
 #ifdef CONFIG_PM
 	collie_sound_pm_dev = pm_register(PM_SYS_DEV, 0,
 						collie_sound_pm_callback);
 #endif
-
-
 #ifdef COLLIE_TRY_ONE
 	/* enable int sw */
 	collie_rc_set_int_mode();
-
 	/* GPIO15(int):IN, GPIO18(sw):OUT */
 	GPDR = ((GPDR)&~GPIO_nREMOCON_INT)|GPIO_REMOCON_ADC_SW;
-
 	/* GPIO15,18:not Alternate */
 	GAFR &= ~(GPIO_nREMOCON_INT|GPIO_REMOCON_ADC_SW);
-
+	/* Initialize headphone state */
+	headphone=!(GPLR & GPIO_nREMOCON_INT);
 	/* GPIO15:Falling Edge */
-	set_GPIO_IRQ_edge(GPIO_nREMOCON_INT, GPIO_FALLING_EDGE);
-
+	set_GPIO_IRQ_edge(GPIO_nREMOCON_INT, GPIO_BOTH_EDGES);
 	/* Register interrupt handler */
 	if ( request_irq(IRQ_GPIO_nREMOCON_INT, Collie_rc_interrupt,
-			       SA_INTERRUPT, "INSERT-HEADPHONE", Collie_rc_interrupt))	{
-		printk("%s: request_irq(%d) failed.\n",
-			__FUNCTION__, IRQ_GPIO_nREMOCON_INT);
-	}
+			       SA_INTERRUPT, "headphone", 0))	{
+		printk("headphone: request_irq failed.\n");
 
-	/* Make threads */
-	kernel_thread(collie_audio_on,  NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
+	}
+	printk("Requested irq collie_rc succesfully (headphone) \n");
+	printk("Headphone is now %s\n",headphone ? "connected" : "disconnected");
 #endif
 
-
-	LEAVE(TRACE_ON,"Collie_sound_init");
+	Collie_audio_power_on();  // decreasing rec. noise?
+	Collie_audio_power_off();
 	return 0;
 }
 
-module_init(Collie_sound_init);
-
-
 #ifdef MODULE
-
-int init_module(void)
+static int collie_ssp_init_module(void)
 {
-	ENTER(TRACE_ON,"init_module");
 	Collie_sound_init();
-	LEAVE(TRACE_ON,"init_module");
 	return 0;
 }
 
-void cleanup_module(void)
+static void collie_ssp_cleanup_module(void)
 {
-	ENTER(TRACE_ON,"cleanup_module");
+#ifdef CONFIG_PM
+	pm_unregister(collie_sound_pm_dev);
+#endif
 	if (irq_installed) {
-		sound_silence();
-		sound.mach.irqcleanup();
+		sa1100_dma_stop(COLLIE_SOUND_DMA_CHANNEL);
+		sa1100_dma_flush_all(COLLIE_SOUND_DMA_CHANNEL);
+		Collie_audio_power_off();		
+		sa1100_free_dma(COLLIE_SOUND_DMA_CHANNEL);
 	}
-
-	sq_release_buffers();
-
-	if (mixer_unit >= 0)
-		unregister_sound_mixer(mixer_unit);
-	if (state_unit >= 0)
-		unregister_sound_special(state_unit);
-	if (sq_unit >= 0)
-		unregister_sound_dsp(sq_unit);
-	LEAVE(TRACE_ON,"cleanup_module");
-}
-
+#ifdef COLLIE_TRY_ONE
+	free_irq(IRQ_GPIO_nREMOCON_INT,0);
+#endif
+	unregister_sound_mixer(mixer_unit);
+	unregister_sound_special(state_unit);
+	unregister_sound_dsp(sq_unit);
+	printk("collie_ssp has to go now, see you later!\n");
+}
+
+module_init(collie_ssp_init_module);
+module_exit(collie_ssp_cleanup_module);
+MODULE_DESCRIPTION("Collie 16bit sound driver");
+MODULE_AUTHOR("SHARP");
+MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(Collie_recording_off);
+EXPORT_SYMBOL(Collie_recording_on);
+EXPORT_SYMBOL(collie_recording);
 #endif /* MODULE */
+
diff -Nuar linux-2.4.18/drivers/sound/collie_tc35143af.c linux-2.4.18p/drivers/sound/collie_tc35143af.c
--- linux-2.4.18/drivers/sound/collie_tc35143af.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.18p/drivers/sound/collie_tc35143af.c	2004-10-13 15:26:20.336631864 +0200
@@ -0,0 +1,1457 @@
+/*
+    TODO
+
+    buzzer compatibility is not fool proof - if an app starts sending buzzer ioctls
+    and then write or read, nothing good will happen    / but this api is obsolote anyway
+        
+    mixer_ioctls missing: write/read_mic/igain  (there are sane defaults for those)
+    
+    fixed samplerate at 22050hz (mono,s16_le), although it can be changed
+    between 8000-22050hz hardwarewise 
+
+    
+    DONE
+
+    buffers are only allocated once, and freed when module is unloaded
+    mute left channel when duplex playing & recording    
+    cleanup
+    depend on collie_ssp, and call needed functions when needed 
+    (recording noise should be gone too as a consequence)
+    lineo's getospace incorporated (getispace left alone)
+    "optimized" default fragsize and number, so there is now no clicking all the time
+    commented out scndctl_dsp_setfragment so that no application can set bad settings (eg.xmms)
+    if you start reading from this device, than it won't let you write later unless you close it first
+    (and vica-versa)    
+    speaker is muted if nothing is playing, so noise is gone
+    
+*/
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/poll.h>
+#include <linux/major.h>
+#include <linux/config.h>
+#include <linux/fcntl.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/sound.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <linux/pm.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <asm/ucb1200.h>
+#include <linux/soundcard.h>
+#include <asm/proc/cache.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/tc35143.h>
+
+#undef DEBUG
+#ifdef DEBUG
+#define DPRINTK( x... )  printk( ##x )
+#else
+#define DPRINTK( x... )
+#endif
+
+extern int collie_recording;
+extern void Collie_recording_on(void);
+extern void Collie_recording_off(void);
+
+int collie_tc35143f_irq = -1;
+int collie_tc35143f_input_irq = -1;
+
+#define	COLLIE_BUZZER_DMA_CHANNEL	(collie_tc35143f_irq)
+#define	COLLIE_BUZZER_DMA_CHANNEL_INPUT	(collie_tc35143f_input_irq)
+#define COLLIE_GPIO_MIC			GPIO_GPIO (17)
+
+#define SND_NDEVS	256	/* Number of supported devices */
+#define SND_DEV_CTL	0	/* Control port /dev/mixer */
+#define SND_DEV_SEQ	1	/* Sequencer output /dev/sequencer (FM synthesizer and MIDI output) */
+#define SND_DEV_MIDIN	2	/* Raw midi access */
+#define SND_DEV_DSP	3	/* Digitized voice /dev/dsp */
+#define SND_DEV_AUDIO	4	/* Sparc compatible /dev/audio */
+#define SND_DEV_DSP16	5	/* Like /dev/dsp but 16 bits/sample */
+#define SND_DEV_STATUS	6	/* /dev/sndstat */
+/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
+#define SND_DEV_SEQ2	8	/* /dev/sequencer, level 2 interface */
+#define SND_DEV_SNDPROC 9	/* /dev/sndproc for programmable devices */
+#define SND_DEV_PSS	SND_DEV_SNDPROC
+
+#ifdef MODULE
+static int sq_unit = -1;
+static int mixer_unit = -1;
+static int state_unit = -1;
+static int irq_installed = 0;
+#endif /* MODULE */
+
+#ifdef CONFIG_PM
+static struct pm_dev* collie_sound_pm_dev;
+#endif
+
+/*** Some declarations ***********************************************/
+static int collie_buzzer_volume = 100;
+static int audio_igain = 0;
+static int audio_iamp = 0x05;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+static struct ucb1x00 * ucbstruct;
+#endif
+static int TC35143f_control_reg_a;
+static int TC35143f_control_reg_b;
+static int TC35143f_mode;
+
+#define AUDIO_NBFRAGS_DEFAULT   32
+#define AUDIO_FRAGSIZE_DEFAULT  2048
+
+typedef struct {
+	int size;               /* buffer size */
+	char *start;            /* points to actual buffer */
+	dma_addr_t dma_addr;    /* physical buffer address */
+	struct semaphore sem;   /* down before touching the buffer */
+	int master;             /* master owner for buffer allocation */
+	u_int idx;		/* buffer index, so that we know which buffer was sent last*/
+} audio_buf_t;
+
+typedef struct {
+	audio_buf_t *buffers;   /* pointer to audio buffer structures */
+	audio_buf_t *buf;       /* current buffer used by read/write */
+	u_int buf_idx;          /* index for the pointer above... */
+	u_int fragsize;         /* fragment i.e. buffer size */
+	u_int nbfrags;          /* nbr of fragments i.e. buffers */
+} audio_stream_t;
+
+static audio_stream_t output_stream, input_stream;
+
+#define NEXT_BUF(_s_,_b_) { \
+	(_s_)->_b_##_idx++; \
+	(_s_)->_b_##_idx %= (_s_)->nbfrags; \
+	(_s_)->_b_ = (_s_)->buffers + (_s_)->_b_##_idx; }
+					
+/* Current specs for incoming audio data */
+static u_int audio_fragsize=AUDIO_FRAGSIZE_DEFAULT;
+static u_int audio_nbfrags=AUDIO_NBFRAGS_DEFAULT;
+
+static volatile int audio_refcount;	/* nbr of concurrent open() for playback */
+typedef enum { REC,PLAY,NA,BUZZ } collie_tc_status_t;
+static collie_tc_status_t collie_tc_status;
+int collie_tc_muted;
+
+#define IOCTL_IN(arg, ret) \
+	do { int error = get_user(ret, (int *)(arg)); \
+		if (error) return error; \
+	} while (0)
+#define IOCTL_OUT(arg, ret)	ioctl_return((int *)(arg), ret)
+
+/*** "Translations" ************************************************************/
+
+static ssize_t collie_ct_s16(const u_char *userPtr, size_t userCount,
+			     u_char frame[], ssize_t *frameUsed,
+			     ssize_t frameLeft);
+static signed short ct_out=0;
+/*** Low level stuff *********************************************************/
+
+
+typedef struct {
+	int format;		/* AFMT_* */
+	int stereo;		/* 0 = mono, 1 = stereo */
+	int size;		/* 8/16 bit*/
+	int speed;		/* speed */
+	int volume;
+} SETTINGS;
+
+static SETTINGS sound;
+
+#ifdef CONFIG_PM
+//extern int autoPowerCancel;
+#endif
+
+static void Collie_Set_Volume(int volume);
+static int Collie_Get_Volume(void);
+static int CollieIrqInit(void);
+static int CollieSetFormat(int format);
+static void Collie_sq_interrupt(void*, int);
+static int sq_allocate_buffers(audio_stream_t*);
+static void sq_release_buffers(audio_stream_t*);
+
+/*** Mid level stuff *********************************************************/
+static int sound_set_speed(int speed);
+
+/*
+ * /dev/mixer abstraction
+ */
+
+struct sound_mixer {
+    int busy;
+};
+
+static struct sound_mixer mixer;
+
+/*
+ * /dev/sndstat
+ */
+
+/*** Common stuff ********************************************************/
+
+static long long sound_lseek(struct file *file, long long offset, int orig);
+static inline int ioctl_return(int *addr, int value)
+{
+	if (value < 0) {
+		return(value);
+	}
+	return put_user(value, addr)? -EFAULT: 0;
+}
+
+static void wait_ms(int ten_ms)
+{
+	schedule_timeout(ten_ms);
+}
+
+/*** Translation ************************************************************/
+
+static ssize_t collie_ct_s16(const u_char *userPtr, size_t userCount,
+			   u_char frame[], ssize_t *frameUsed,
+			   ssize_t frameLeft)
+{
+	ssize_t count, used;
+	signed short *fp = (unsigned short *) &frame[*frameUsed];
+	signed short *up = (unsigned short *) userPtr;
+
+	frameLeft >>= 1;
+	userCount >>= 1;
+	used = count = (userCount < frameLeft) ? userCount : frameLeft;
+	
+	while (count > 0) {
+		signed short data;
+		if (get_user(data, up++)) {
+			return -EFAULT;
+		} /* lowpass filtering, not that it matters much - something is resonating inside the Zaurus at high frequencies ? */
+		*fp++ =  ct_out = (short)( ( (long)data  + (long)ct_out ) >> 1LL );
+		count--;
+	}
+	
+	*frameUsed += used * 2;
+	return used * 2;
+}
+
+/*** HARDWARE dependent stuff *********************************************************/
+#define	VOL_THRES	10
+#define	CODEC_ASD_NUMERATOR 13
+/*~ (9216000 / ( 32 * 22050 )) */
+
+static int Collie_Sampling_value(void)
+{
+  int asd = CODEC_ASD_NUMERATOR;
+  DPRINTK("Collie_Sampling_value %x\n",asd);
+  return asd;
+}
+
+static void Collie_sound_hard_init(void)
+{
+  int asd;
+
+  DPRINTK("CollieInit\n");
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+  ucb1x00_enable(ucbstruct);
+  ucb1x00_io_set_dir(ucbstruct,0, TC35143_GPIO_BUZZER_BIAS); 
+  ucb1x00_disable(ucbstruct);
+#else
+  ucb1200_set_io_direction(TC35143_GPIO_BUZZER_BIAS, TC35143_IODIR_OUTPUT); 
+#endif
+
+  DPRINTK("TC35143F Init");
+
+  // init MCP
+  asd = Collie_Sampling_value();
+  Ser4MCCR0 &= ~MCCR0_MCE;
+  Ser4MCCR0 &= ~0xff;
+  Ser4MCCR0 |= (MCCR0_ARE | MCCR0_ATE |MCCR0_ADM | MCCR0_ECS | asd);
+  Ser4MCCR0 |= MCCR0_MCE;
+  Ser4MCSR   = 0xffffffff;
+
+  DPRINTK("Init MCP %x\n",Ser4MCCR0);
+}
+
+static void Collie_audio_power_on(void)
+{
+  if ( collie_buzzer_volume > 100 ) collie_buzzer_volume = 100;
+  if ( collie_buzzer_volume < 0   ) collie_buzzer_volume = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+  ucb1x00_enable(ucbstruct);
+#endif
+  TC35143f_control_reg_a = ( TC35143_VDIV_22KHZ );
+  TC35143f_control_reg_b = ( TC35143_VADMUTE | TC35143_VHSMUTE | ( 7 - collie_buzzer_volume / 13));
+  TC35143f_mode = ( TC35143_VOFFCAN | TC35143_VCOF_22_OR_16KHZ );
+  TC35143f_control_reg_a &= ~(TC35143_VINSEL_MASK | TC35143_VGAIN_MASK | TC35143_VAMP_MASK);
+  TC35143f_control_reg_a |= (TC35143_VINSEL_VBIN2 | ((audio_igain & 0x3)<<11) | ((audio_iamp & 0x0f)<<7));
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+  ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B , TC35143f_control_reg_b);
+  ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_A , TC35143f_control_reg_a);
+  ucb1x00_reg_write(ucbstruct,TC35143_MODE_REG      , TC35143f_mode );
+  ucb1x00_io_write(ucbstruct, TC35143_GPIO_BUZZER_BIAS,0);
+  ucb1x00_disable(ucbstruct);
+#else
+  ucb1200_write_reg(TC35143_CONTROL_REG_B , TC35143f_control_reg_b );
+  ucb1200_write_reg(TC35143_MODE_REG      , TC35143f_mode );
+  ucb1200_write_reg(TC35143_CONTROL_REG_A , TC35143f_control_reg_a );
+  ucb1200_set_io(TC35143_GPIO_BUZZER_BIAS, TC35143_IODAT_HIGH);
+#endif
+  collie_tc_muted=1;
+}
+
+static void Collie_audio_power_off(void){	/* Disable sound only */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+  ucb1x00_enable(ucbstruct);
+  ucb1x00_io_write(ucbstruct,0, TC35143_GPIO_BUZZER_BIAS);
+#else
+  ucb1200_set_io(TC35143_GPIO_BUZZER_BIAS, TC35143_IODAT_LOW);
+#endif
+
+  TC35143f_control_reg_a = ( TC35143_VDIV_22KHZ );
+  TC35143f_control_reg_b = ( TC35143_ALL_MUTE );
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+  ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B , TC35143f_control_reg_b);
+  ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_A , TC35143f_control_reg_a);
+  ucb1x00_disable(ucbstruct);
+#else
+  ucb1200_write_reg(TC35143_CONTROL_REG_B , TC35143f_control_reg_b );
+  ucb1200_write_reg(TC35143_CONTROL_REG_A , TC35143f_control_reg_a );
+#endif
+}
+
+static void collie_tc_mute_on(void){
+    unsigned int reg_b;
+    unsigned int reg_a;
+
+    if (!collie_tc_muted) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+	ucb1x00_enable(ucbstruct);
+	reg_b  = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_B);
+	reg_a  = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_A);
+#else
+	reg_b  = ucb1200_read_reg(TC35143_CONTROL_REG_B);
+	reg_a  = ucb1200_read_reg(TC35143_CONTROL_REG_A);
+#endif
+	reg_b &= ~TC35143_VOUT1_EN;
+	reg_a &= ~TC35143_VOUT2_EN;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+	ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_A, reg_a);
+	ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B, reg_b);
+	ucb1x00_disable(ucbstruct);
+#else
+	ucb1200_write_reg(TC35143_CONTROL_REG_A, reg_a);
+	ucb1200_write_reg(TC35143_CONTROL_REG_B, reg_b);
+#endif
+	collie_tc_muted=1;
+    }
+}
+
+static void collie_tc_mute_off(void){
+    unsigned int reg_b;
+    unsigned int reg_a;
+
+    if (collie_tc_muted) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+	ucb1x00_enable(ucbstruct);
+	reg_b  = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_B);
+	reg_a  = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_A);
+#else
+	reg_b  = ucb1200_read_reg(TC35143_CONTROL_REG_B);
+	reg_a  = ucb1200_read_reg(TC35143_CONTROL_REG_A);	
+#endif
+	reg_b |= TC35143_VOUT1_EN ;
+	reg_b &= ~7;
+	reg_b |= ( 7 - collie_buzzer_volume / 13);
+	reg_a |= TC35143_VOUT2_EN;
+	reg_a &= ~(TC35143_VGAIN_MASK | TC35143_VAMP_MASK);
+	reg_a |= (((audio_igain & 0x3)<<11) | ((audio_iamp & 0x0f)<<7));
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+	ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_A, reg_a);
+	ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B, reg_b);
+	ucb1x00_disable(ucbstruct);
+#else
+	ucb1200_write_reg(TC35143_CONTROL_REG_A, reg_a);
+	ucb1200_write_reg(TC35143_CONTROL_REG_B, reg_b);
+#endif
+	collie_tc_muted=0;
+    }
+}
+
+
+static void Collie_volume_set(int dest)
+{
+    if (collie_buzzer_volume==dest) return;
+    collie_buzzer_volume=dest;
+    collie_tc_mute_on();    
+    collie_tc_mute_off();    
+}
+
+
+/*********** GENERAL stuff, same as collie_ssp *******************************/
+
+
+static void Collie_Set_Volume(int volume)
+{
+	sound.volume = volume & 0xff;
+	sound.volume += ( volume & 0xff00 >> 8);
+	sound.volume >>=1;
+	if (sound.volume>100) sound.volume=100;	
+}
+
+static int Collie_Get_Volume(void)
+{
+	return ( sound.volume << 8 | sound.volume );
+}
+
+static void Collie_sq_interrupt(void* id, int size)
+{
+	audio_buf_t *b  = (audio_buf_t *) id;
+	audio_buf_t *b2 = output_stream.buffers + ((b->idx + 1) % output_stream.nbfrags);
+
+	/* If this is the last buffer for know, let's mute the speaker */
+	if (!down_trylock(&b2->sem)) {
+		collie_tc_mute_on();
+		up(&b2->sem);
+	}
+	
+	/*
+	 * Current buffer is sent: wake up any process waiting for it.
+	 */
+	up(&b->sem);
+	/* And any process polling on write. */
+	wake_up_interruptible(&b->sem.wait);
+
+	DPRINTK("Collie_sq_interrupt \n");
+}
+
+static void Collie_sq_input_interrupt(void* id, int size)
+{
+	audio_buf_t *b = (audio_buf_t *) id;
+	/*
+	 * Current buffer is sent: wake up any process waiting for it.
+	 */
+	b->size = size;
+	up(&b->sem);
+	/* And any process polling on write. */
+	wake_up_interruptible(&b->sem.wait);
+	/* And indicate which was the last buffer sent */
+
+	DPRINTK("Collie_sq_input_interrupt \n");
+}
+
+
+static int __init CollieIrqInit(void)
+{
+	int err;
+
+	err = sa1100_request_dma(&COLLIE_BUZZER_DMA_CHANNEL, "buzzer output",
+			   DMA_Ser4MCP0Wr);
+
+	if (err) {
+		return 0;
+	}
+	printk("collie_tc35143f_irq=%d\n", collie_tc35143f_irq); 
+
+	err = sa1100_request_dma(&COLLIE_BUZZER_DMA_CHANNEL_INPUT, "buzzer input",
+			   DMA_Ser4MCP0Rd);
+
+	if (err) {
+		return 0;
+	}
+	printk("collie_tc35143f_input_irq=%d\n", collie_tc35143f_input_irq); 
+
+
+	sa1100_dma_set_callback(COLLIE_BUZZER_DMA_CHANNEL,
+			       (dma_callback_t)Collie_sq_interrupt);
+
+	sa1100_dma_set_callback(COLLIE_BUZZER_DMA_CHANNEL_INPUT,
+			       (dma_callback_t)Collie_sq_input_interrupt);
+
+
+	sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL);
+	Collie_audio_power_off();
+	sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
+	sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL);
+	return(1);
+}
+
+static int CollieSetFormat(int format)
+{
+	int size;
+
+	switch (format) {
+	case AFMT_QUERY:
+		return(sound.format);
+	default: /* This is the only one supported by the hardware it seems */
+		size = 16;
+		format = AFMT_S16_LE;
+	}
+	sound.format = format;
+	sound.size = size;
+
+	return(format);
+}
+
+
+static int sound_set_speed(int speed)
+{
+	if (speed < 0) {
+		return(sound.speed);
+	}
+	sound.speed=22050;
+	return(sound.speed);
+}
+
+/* Higher level stuff ************************************************/
+
+/*
+ * /dev/mixer abstraction
+ */
+
+static int mixer_open(struct inode *inode, struct file *file)
+{
+	MOD_INC_USE_COUNT;
+	mixer.busy = 1;
+	return 0;
+}
+
+static int mixer_release(struct inode *inode, struct file *file)
+{
+	mixer.busy = 0;
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+
+static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		       u_long arg)
+{
+	int data;
+
+	DPRINTK("Got mixer ioctl \n");
+
+    	switch (cmd) {
+		case SOUND_MIXER_INFO:
+			DPRINTK("0\n");
+			return 0;
+		case SOUND_OLD_MIXER_INFO:
+			DPRINTK("0\n");
+			return 0;
+
+		case SOUND_MIXER_READ_DEVMASK:
+			DPRINTK("1\n");
+			return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_IGAIN );
+		case SOUND_MIXER_READ_RECMASK:
+			DPRINTK("2\n");
+			return IOCTL_OUT(arg, SOUND_MASK_MIC);
+		case SOUND_MIXER_READ_STEREODEVS:
+			DPRINTK("3\n");
+			return IOCTL_OUT(arg, 0);
+		case SOUND_MIXER_READ_CAPS:
+			DPRINTK("4\n");
+			return IOCTL_OUT(arg, 0);
+
+		case SOUND_MIXER_WRITE_VOLUME:
+			IOCTL_IN(arg, data);
+			Collie_Set_Volume(data);
+			DPRINTK("mix_io returning\n");
+			return IOCTL_OUT(arg, data);
+		case SOUND_MIXER_READ_VOLUME:
+			DPRINTK("5\n");
+			return IOCTL_OUT(arg, Collie_Get_Volume());
+		case SOUND_MIXER_READ_TREBLE:
+			DPRINTK("6\n");
+			return IOCTL_OUT(arg, 0);
+		case SOUND_MIXER_WRITE_TREBLE:
+			DPRINTK("7\n");
+			return IOCTL_OUT(arg, 0);
+
+		case SOUND_MIXER_READ_BASS:
+			DPRINTK("6b\n");
+			return IOCTL_OUT(arg, 0);
+		case SOUND_MIXER_WRITE_BASS:
+			DPRINTK("7b\n");
+			return IOCTL_OUT(arg, 0);
+
+
+		case SOUND_MIXER_WRITE_MIC:
+		case SOUND_MIXER_WRITE_IGAIN:
+			DPRINTK("8\n");
+			return IOCTL_OUT(arg, 100);
+		case SOUND_MIXER_READ_MIC:
+		case SOUND_MIXER_READ_IGAIN:
+			DPRINTK("9\n");
+			return IOCTL_OUT(arg, 0);
+
+		case SOUND_MIXER_READ_SPEAKER:
+			DPRINTK("10\n");
+			return IOCTL_OUT(arg, 0);
+		case SOUND_MIXER_WRITE_SPEAKER:
+			DPRINTK("11\n");
+			return IOCTL_OUT(arg, 0);
+		default:
+			DPRINTK("12 %d\n",cmd);
+			return -ENOSYS;
+	}	
+	DPRINTK("EINVAL %d??\n",cmd);
+	return -EINVAL;
+}
+
+
+static struct file_operations mixer_fops =
+{
+	llseek:  sound_lseek,
+	ioctl:   mixer_ioctl,
+	open:    mixer_open,
+	release: mixer_release,
+};
+
+
+static void __init mixer_init(void)
+{
+	mixer_unit = register_sound_mixer(&mixer_fops, -1);
+	if (mixer_unit < 0) {
+		return;
+	}
+	mixer.busy = 0;
+	sound.volume  = 100;
+	Collie_volume_set(sound.volume);
+}
+
+/* This function initializes the buffer
+ */
+
+static void sq_clean_buffers(audio_stream_t * s)
+{
+	int frag;
+
+	sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL);
+	sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
+
+	s->nbfrags = audio_nbfrags;
+	s->fragsize = audio_fragsize;
+
+	if (!s->buffers)
+	    goto err;
+
+	for (frag = 0; frag < s->nbfrags; frag++) {
+		audio_buf_t *b = &s->buffers[frag];
+		b->size=0;
+		sema_init(&b->sem, 1);
+	}
+	s->buf_idx = 0;
+	s->buf = &s->buffers[0];
+	return;
+
+err:
+	printk("sound driver : where did the buffer go ??\n ");
+}
+
+/* This function allocates the buffer structure array and buffer data space
+ * according to the current number of fragments and fragment size.
+ */
+ 
+static int sq_allocate_buffers(audio_stream_t * s)
+{
+	int frag;
+	int dmasize = 0;
+	char *dmabuf = 0;
+	dma_addr_t dmaphys = 0;
+
+	DPRINTK("sq_allocate_buffers\n");
+
+	if (s->buffers) {
+		return -EBUSY;
+	}
+
+	s->nbfrags = audio_nbfrags;
+	s->fragsize = audio_fragsize;
+
+	s->buffers = (audio_buf_t *)
+		kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
+	if (!s->buffers)
+	goto err;
+	memset(s->buffers, 0, sizeof(audio_buf_t) * s->nbfrags);
+
+	for (frag = 0; frag < s->nbfrags; frag++) {
+		audio_buf_t *b = &s->buffers[frag];
+
+		/*
+		 * Let's allocate non-cached memory for DMA buffers.
+		 * We try to allocate all memory at once.
+		 * If this fails (a common reason is memory fragmentation),
+		 * then we allocate more smaller buffers.
+		 */
+		if (!dmasize) {
+			dmasize = (s->nbfrags - frag) * s->fragsize;
+			do {
+				dmabuf = consistent_alloc(GFP_KERNEL|GFP_DMA,
+							  dmasize,
+							  &dmaphys);
+				if (!dmabuf)
+					dmasize -= s->fragsize;
+			} while (!dmabuf && dmasize);
+			if (!dmabuf)
+				goto err;
+			b->master = dmasize;
+		}
+
+		b->start = dmabuf;
+		b->dma_addr = dmaphys;
+		b->idx = frag;
+		sema_init(&b->sem, 1);
+		dmabuf += s->fragsize;
+		dmaphys += s->fragsize;
+		dmasize -= s->fragsize;
+	}
+
+	s->buf_idx = 0;
+	s->buf = &s->buffers[0];
+
+	return 0;
+
+err:
+	printk("sound driver : unable to allocate audio memory\n ");
+	sq_release_buffers(s);
+	return -ENOMEM;
+}
+
+/*
+ * This function frees all buffers
+ */
+
+static void sq_release_buffers(audio_stream_t * s)
+{
+	DPRINTK("sq_release_buffers\n");
+
+	/* ensure DMA won't run anymore */
+	sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL);
+	sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
+
+	if (s->buffers) {
+		int frag;
+		for (frag = 0; frag < s->nbfrags; frag++) {
+			if (!s->buffers[frag].master)
+				continue;
+			consistent_free(s->buffers[frag].start,
+					s->buffers[frag].master,
+					s->buffers[frag].dma_addr);
+		}
+		kfree(s->buffers);
+		s->buffers = NULL;
+	}
+
+	s->buf_idx = 0;
+	s->buf = NULL;
+}
+
+static int audio_recording(audio_stream_t * s)
+{
+	int i;
+	unsigned int reg_b;
+
+	if (!collie_recording) {
+		/*
+		 * Set TC35143 Audio in enable
+		 */
+////		DPRINTK("audio_recording : audio in enable\n");
+////		reg_b  = ucb1200_read_reg(TC35143_CONTROL_REG_B);
+////		reg_b &= ~(TC35143_VADMUTE);
+////		reg_b |=  (TC35143_VIN_EN | TC35143_VCLP_CLR);
+////		ucb1200_write_reg(TC35143_CONTROL_REG_B, reg_b);
+
+		/*
+		 * We must ensure there is an output stream at any time while 
+		 * recording since this is how the TC35143 gets its clock.
+		 * So if there is no playback data to send, the output DMA will
+		 * spin with all zeroes.
+		 */
+
+		Collie_recording_on();
+		collie_tc_mute_off();  /* This is needed for good volume */
+		DPRINTK("audio_recording : sa1100_dma_set_spin\n");
+		sa1100_dma_set_spin(COLLIE_BUZZER_DMA_CHANNEL,
+					    (dma_addr_t) FLUSH_BASE_PHYS, 2048);
+
+		/* 
+		 * Since we just allocated all buffers, we must send them to
+		 * the DMA code before receiving data.
+		 */
+		DPRINTK("audio_recording : for loop\n");
+		for (i = 0; i < s->nbfrags; i++) {
+			audio_buf_t *b = s->buf;
+			down(&b->sem);
+			sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL_INPUT, (void *) b,
+						b->dma_addr, s->fragsize);
+			NEXT_BUF(s, buf);
+		}
+		DPRINTK("audio_recording : End for loop\n");
+
+		/*
+		 * Set TC35143 Audio in enable
+		 */
+		DPRINTK("audio_recording : audio in enable\n");
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+		ucb1x00_enable(ucbstruct);
+  		ucb1x00_io_write(ucbstruct, 0, TC35143_GPIO_BUZZER_BIAS);
+		reg_b  = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_B);
+#else
+		ucb1200_set_io(TC35143_GPIO_BUZZER_BIAS, TC35143_IODAT_LOW);
+		reg_b  = ucb1200_read_reg(TC35143_CONTROL_REG_B);
+#endif
+		reg_b &= ~(TC35143_VADMUTE);
+		reg_b |=  (TC35143_VIN_EN | TC35143_VCLP_CLR);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+		ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B, reg_b);
+		ucb1x00_disable(ucbstruct);
+#else
+		ucb1200_write_reg(TC35143_CONTROL_REG_B, reg_b);
+#endif
+	}
+	return 0;
+}
+
+
+static int sq_read(struct file *file, char *buffer,
+		      size_t count, loff_t * ppos)
+{
+	char *buffer0 = buffer;
+	audio_stream_t *s = &input_stream;
+	int chunksize, ret = 0;
+
+	DPRINTK("audio_read: count=%d\n", count);
+
+
+	ret = audio_recording(s);
+
+	if ((collie_tc_status!=NA) && (collie_tc_status!=REC)) 
+	    return -EPERM;
+	collie_tc_status=REC;
+
+	if (ret)
+		return ret;
+
+	/* be sure to have a full sample byte count */
+	count &= ~0x03;
+
+//	DPRINTK("audio_read : Start while loop\n");
+	while (count > 0) {
+		audio_buf_t *b = s->buf;
+
+		/* Wait for a buffer to become full */
+		if (file->f_flags & O_NONBLOCK) {
+//			DPRINTK("audio_read : down_trylock\n");
+			ret = -EAGAIN;
+			if (down_trylock(&b->sem))
+				break;
+		} else {
+//			DPRINTK("audio_read : down_interruptible\n");
+			ret = -ERESTARTSYS;
+			if (down_interruptible(&b->sem))
+				break;
+		}
+
+		/* Grab data from the current buffer */
+		chunksize = b->size;
+		if (chunksize > count)
+		    chunksize = count;
+		DPRINTK("read %d from %d\n", chunksize, s->buf_idx);
+		
+		if (copy_to_user(buffer, b->start + s->fragsize - b->size, chunksize)) {
+		    up(&b->sem);
+		    DPRINTK("not copied to buffer \n");
+		    return -EFAULT;
+		}
+		DPRINTK("copied to buffer \n");
+
+		b->size -= chunksize;
+		buffer += chunksize;
+		count -= chunksize;
+		
+		if (b->size > 0) {
+			up(&b->sem);
+			break;
+		}
+
+		/* Make current buffer available for DMA again */
+		sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL_INPUT, (void *) b,
+					b->dma_addr, s->fragsize);
+		NEXT_BUF(s, buf);
+	}
+//	DPRINTK("audio_read : End while loop\n");
+
+	if ((buffer - buffer0))
+		ret = buffer - buffer0;
+//	DPRINTK("audio_read: return=%d\n", ret);
+	return ret;
+}
+
+static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
+			loff_t *ppos)
+{
+	const char *buffer0 = src;
+	audio_stream_t *s = &output_stream;
+	u_char *dest;
+	ssize_t uUsed, bUsed, bLeft, ret = 0;
+
+	DPRINTK("sq_write: uLeft=%d\n", uLeft);
+
+	if ((collie_tc_status!=NA) && (collie_tc_status!=PLAY)) 
+	    return -EPERM;
+
+	collie_tc_status=PLAY;
+
+	if (!s->buffers && sq_allocate_buffers(s)) {
+		return -ENOMEM;
+	}
+
+
+#ifdef CONFIG_PM
+	/* Auto Power off cancel */
+//	autoPowerCancel = 0;
+#endif
+
+	collie_tc_mute_off();
+	while (uLeft > 0) {
+		audio_buf_t *b = s->buf;
+
+		/* Wait for a buffer to become free */
+		if (file->f_flags & O_NONBLOCK) {
+			ret = -EAGAIN;
+			if (down_trylock(&b->sem)) {
+				break;
+			}
+		} else {
+			ret = -ERESTARTSYS;
+			if (down_interruptible(&b->sem)) {
+				break;
+			}
+		}
+
+		dest = b->start + b->size;
+		bUsed = 0;
+		bLeft = s->fragsize - b->size;
+
+		if (collie_ct_s16) {
+			uUsed = collie_ct_s16(src, uLeft, dest, &bUsed, bLeft);
+			cpu_cache_clean_invalidate_range((unsigned long)dest,
+				(unsigned long)(dest+(audio_fragsize)), 0);
+		} else {
+			return -EFAULT;
+		}
+
+		if (uUsed < 0) {
+			up(&b->sem);
+			return -EFAULT;
+		}
+		src += uUsed;
+		uLeft -= uUsed;
+		b->size += bUsed;
+
+		if (b->size < s->fragsize) {
+			up(&b->sem);
+			break;
+		}
+
+		/* Send current buffer to dma */
+		sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL,
+		 			(void *) b, b->dma_addr, b->size);
+
+		Collie_volume_set(sound.volume);
+
+		b->size = 0;    /* indicate that the buffer has been sent */
+		NEXT_BUF(s, buf);
+	}
+
+	if ((src - buffer0))
+		ret = src - buffer0;
+	DPRINTK("sq_write: return=%d\n", ret);
+	return ret;
+}
+
+static unsigned int sq_poll(struct file *file, 
+			       struct poll_table_struct *wait)
+{
+	unsigned int mask = 0;
+	int i,ret;
+
+	DPRINTK("sq_poll(): mode=%s%s\n",
+		(file->f_mode & FMODE_READ) ? "r" : "",
+		(file->f_mode & FMODE_WRITE) ? "w" : "");
+
+	if ((file->f_mode & FMODE_READ) && (file->f_mode & FMODE_WRITE) && (collie_tc_status==NA))
+	    return mask;
+	
+	if ((file->f_mode & FMODE_WRITE) && (collie_tc_status!=REC)) {
+		if (!output_stream.buffers 
+		    && sq_allocate_buffers(&output_stream)) {
+			return -ENOMEM;
+		}
+		poll_wait(file, &output_stream.buf->sem.wait, wait);
+	}
+
+	if ((file->f_mode & FMODE_WRITE) && (collie_tc_status!=REC)) {
+		for (i = 0; i < output_stream.nbfrags; i++) {
+			if (atomic_read(&output_stream.buffers[i].sem.count) > 0)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	}
+
+	if ((file->f_mode & FMODE_READ) && (collie_tc_status!=PLAY)) {
+		ret = audio_recording(&input_stream);
+		if (ret<0) {
+			return ret;
+		}
+		poll_wait(file, &input_stream.buf->sem.wait, wait);
+	}
+
+	if ((file->f_mode & FMODE_READ) && (collie_tc_status!=PLAY)) {
+		for (i = 0; i < input_stream.nbfrags; i++) {
+			if (atomic_read(&input_stream.buffers[i].sem.count) > 0)
+				mask |= POLLIN | POLLRDNORM;
+		}
+	}
+
+	DPRINTK("sq_poll() returned mask of %s%s\n",
+		(mask & POLLIN) ? "r" : "",
+		(mask & POLLOUT) ? "w" : "");
+
+	return mask;
+}
+
+static int sq_open(struct inode *inode, struct file *file)
+{
+	DPRINTK("sq_open\n");
+
+	if (audio_refcount) {
+		DPRINTK(" sq_open        EBUSY\n");
+		return -EBUSY;
+	}
+
+	switch (file->f_flags & O_ACCMODE) {
+	    case O_WRONLY:
+		collie_tc_status=PLAY;
+		sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
+		break;
+	    case O_RDONLY:
+		collie_tc_status=REC;
+		break;
+	    case O_RDWR:
+		collie_tc_status=NA;
+		break;
+	    default:
+		DPRINTK(" sq_open        EINVAL\n");
+		return -EINVAL;
+	}
+	
+	MOD_INC_USE_COUNT;
+	audio_refcount++;
+
+	audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;
+	audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;
+	sq_clean_buffers(&input_stream);
+	sq_clean_buffers(&output_stream);
+	Collie_audio_power_on();
+	DPRINTK("Going back\n");
+    	return 0;
+}
+
+static int sq_post(void)
+{
+	audio_stream_t *s = &output_stream;
+	audio_buf_t *b = s->buf;
+
+	DPRINTK("sq_post\n");
+
+	if (!s->buffers) {
+		return 0;
+	}
+
+	/* Send half-full buffers */
+	if (b->size != 0) {
+		DPRINTK("half-full_buf\n");
+
+#ifdef CONFIG_PM
+		/* Auto Power off cancel */
+//		autoPowerCancel = 0;
+#endif
+
+		down(&b->sem);
+		sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL,
+					(void *) b, b->dma_addr, b->size);
+		b->size = 0;
+		NEXT_BUF(s, buf);
+	}
+	return 0;
+}
+
+static int sq_fsync(void)
+{
+	audio_stream_t *s = &output_stream;
+	audio_buf_t *b = s->buf;
+
+	DPRINTK("sq_fsync\n");
+
+	if (!s->buffers) {
+		return 0;
+	}
+
+	/* Send half-full buffers */
+	if (b->size != 0) {
+		DPRINTK("half-full_buf\n");
+
+#ifdef CONFIG_PM
+		/* Auto Power off cancel */
+//		autoPowerCancel = 0;
+#endif
+
+		down(&b->sem);
+		sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL,
+					(void *) b, b->dma_addr, b->size);
+		b->size = 0;
+		NEXT_BUF(s, buf);
+	}
+
+	/*
+	 * Let's wait for the last buffer we sent i.e. the one before the
+	 * current buf_idx.  When we acquire the semaphore, this means either:
+	 * - DMA on the buffer completed or
+	 * - the buffer was already free thus nothing else to sync.
+	 */
+	b = s->buffers + ((s->nbfrags + s->buf_idx - 1) % s->nbfrags);
+	if (down_interruptible(&b->sem)) {
+		return -EINTR;
+	}
+	up(&b->sem);
+	return 0;
+}
+
+static int sq_release(struct inode *inode, struct file *file)
+{
+	DPRINTK("speaker_sq_release\n");
+
+	switch (collie_tc_status) {
+
+	case REC:
+	    sa1100_dma_set_spin(COLLIE_BUZZER_DMA_CHANNEL,0,0);
+	    sq_clean_buffers(&input_stream);
+	    Collie_recording_off();
+	    break;
+	case PLAY:
+	    sq_fsync();
+	    sq_clean_buffers(&output_stream);
+	    break;
+	default:
+	    break;		
+	}       
+	audio_refcount = 0;
+	collie_tc_status=NA;
+	sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL);
+	Collie_audio_power_off();
+	sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL_INPUT);	
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/* Buzzer compatibility */
+#include "colliebuzzer.h"   
+
+
+static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		    u_long arg)
+{
+	u_long fmt;
+	int data,ret;
+//	audio_buf_info abinfo;
+
+	DPRINTK("Got ioctl %ld \n",cmd);
+	
+	switch (cmd) {
+	case 22144:
+		sq_write_buzzer(arg);
+		sq_fsync();
+		return 0;	
+	case SNDCTL_DSP_RESET:
+		switch (collie_tc_status) {
+		case REC:
+		    sq_clean_buffers(&input_stream);
+		case PLAY:
+		    sq_fsync();
+		    sq_clean_buffers(&output_stream);
+		default:
+		    break;
+		}
+		return 0;
+	case SNDCTL_DSP_POST:
+		sq_post();
+		return 0;
+	case SNDCTL_DSP_SYNC:
+		sq_fsync();
+		return 0;
+
+		/* ++TeSche: before changing any of these it's
+		 * probably wise to wait until sound playing has
+		 * settled down. */
+	case SNDCTL_DSP_SPEED:
+//		sq_fsync(file, file->f_dentry);
+		IOCTL_IN(arg, data);
+		return IOCTL_OUT(arg, sound_set_speed(data));
+
+	case SOUND_PCM_READ_RATE:
+		return 0;
+
+	case SNDCTL_DSP_STEREO:
+//		sq_fsync(file, file->f_dentry);
+		IOCTL_IN(arg, data);
+		return IOCTL_OUT(arg, 0);
+	case SNDCTL_DSP_CHANNELS:
+//		sq_fsync(file, file->f_dentry);
+		IOCTL_IN(arg, data);
+		return IOCTL_OUT(arg, 1);
+	case SNDCTL_DSP_SETFMT:
+//		sq_fsync(file, file->f_dentry);
+		IOCTL_IN(arg, data);
+		return IOCTL_OUT(arg, CollieSetFormat(data));
+	case SNDCTL_DSP_GETFMTS:
+		fmt = AFMT_S16_LE;
+		return IOCTL_OUT(arg, fmt);
+	case SNDCTL_DSP_GETBLKSIZE:
+		return IOCTL_OUT(arg, audio_fragsize);
+	case SNDCTL_DSP_SUBDIVIDE:
+		break;
+	case SNDCTL_DSP_SETFRAGMENT:
+/*		if (output_stream.buffers) {
+			return -EBUSY;
+		}
+		get_user(val, (long *) arg);
+		audio_fragsize = 1 << (val & 0xFFFF);
+		if (audio_fragsize < 256)
+			audio_fragsize = 256;
+		if (audio_fragsize > 16384)
+			audio_fragsize = 16384;
+		audio_nbfrags = (val >> 16) & 0x7FFF;
+		if (audio_nbfrags < 2)
+			audio_nbfrags = 2;
+		if (audio_nbfrags * audio_fragsize > 128 * 1024)
+			audio_nbfrags = 128 * 1024 / audio_fragsize;
+		if (sq_allocate_buffers(&output_stream)) {
+			return -ENOMEM;
+		}
+		return 0;
+	case SNDCTL_DSP_GETOSPACE:
+		abinfo.fragsize   = audio_fragsize;
+		abinfo.fragstotal = audio_nbfrags;
+		abinfo.fragments  = lastsent-output_stream.buf_idx;
+		if (abinfo.fragments<0)
+		    abinfo.fragments += abinfo.fragstotal;		    
+		abinfo.bytes      = abinfo.fragments*abinfo.fragsize;
+     		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+*/
+
+	case SNDCTL_DSP_GETOSPACE:
+	    {
+		audio_stream_t *s = &output_stream;
+		audio_buf_info *inf = (audio_buf_info *) arg;
+		int err = verify_area(VERIFY_WRITE, inf, sizeof(*inf));
+		int i;
+		int frags = 0, bytes = 0;
+
+		if (err)
+			return err;
+		if (output_stream.buffers)  {
+		    for (i = 0; i < s->nbfrags; i++) {
+			if (atomic_read(&s->buffers[i].sem.count) > 0) {
+				if (s->buffers[i].size == 0) frags++;
+				bytes += s->fragsize - s->buffers[i].size;
+			}
+		    }
+		    put_user(s->nbfrags, &inf->fragstotal);
+		    put_user(s->fragsize, &inf->fragsize);
+		} else {
+		    frags=audio_nbfrags;
+		    bytes=frags*audio_fragsize;
+		    put_user(frags, &inf->fragstotal);
+		    put_user(audio_fragsize, &inf->fragsize);
+		}
+		put_user(frags, &inf->fragments);
+		return put_user(bytes, &inf->bytes);
+	    }
+
+	case SNDCTL_DSP_GETISPACE:
+	    {
+		audio_stream_t *s = &input_stream;
+		audio_buf_info *inf = (audio_buf_info *) arg;
+		int err = verify_area(VERIFY_WRITE, inf, sizeof(*inf));
+		int i;
+		int frags = 0, bytes = 0;
+
+		if (err)
+			return err;
+		if (input_stream.buffers) 
+		    for (i = 0; i < s->nbfrags; i++) {
+			if (atomic_read(&s->buffers[i].sem.count) > 0) {
+				if (s->buffers[i].size == s->fragsize) frags++;
+				bytes += s->buffers[i].size;
+			}
+		    }
+		else {
+		    frags=0;
+		    bytes=0;
+		}
+		put_user(frags, &inf->fragments);
+		put_user(s->nbfrags, &inf->fragstotal);
+		put_user(s->fragsize, &inf->fragsize);
+		return put_user(bytes, &inf->bytes);		
+	    }
+
+	default:
+		ret = mixer_ioctl(inode, file, cmd, arg);
+		DPRINTK("Returning after mixer_ioctl\n");
+		return ret;
+	}
+	return -EINVAL;
+}
+
+static struct file_operations sq_fops =
+{
+	llseek: sound_lseek,
+	write: sq_write,
+	read: sq_read,
+	poll: sq_poll,
+	ioctl: sq_ioctl,
+	open: sq_open,
+	release: sq_release,
+};
+
+
+static void __init sq_init(void)
+{
+	sq_unit = register_sound_dsp(&sq_fops, -1);
+	if (sq_unit < 0) {
+		return;
+	}
+
+	sound.format = AFMT_S16_LE;
+	sound.stereo = 0;
+	sound.speed = 22050;
+
+	CollieSetFormat(sound.format);
+	Collie_audio_power_off();
+	input_stream.buf=input_stream.buffers=output_stream.buf=output_stream.buffers=NULL;
+}
+
+
+/*** Common stuff ********************************************************/
+
+static long long sound_lseek(struct file *file, long long offset, int orig)
+{
+	return -ESPIPE;
+}
+
+/*** Power Management ****************************************************/
+
+#ifdef CONFIG_PM
+static int collie_sound_pm_callback(struct pm_dev *pm_dev,
+				    pm_request_t req, void *data)
+{
+	switch (req) {
+	case PM_SUSPEND:
+		if (audio_refcount == 1) {
+		        sa1100_dma_sleep((dmach_t)COLLIE_BUZZER_DMA_CHANNEL);
+		        sa1100_dma_sleep((dmach_t)COLLIE_BUZZER_DMA_CHANNEL_INPUT);
+			Collie_audio_power_off();
+		} else {
+			sa1100_dma_sleep((dmach_t)COLLIE_BUZZER_DMA_CHANNEL);
+		        sa1100_dma_sleep((dmach_t)COLLIE_BUZZER_DMA_CHANNEL_INPUT);
+		}
+		break;
+	case PM_RESUME:
+		Collie_sound_hard_init();
+//		Collie_audio_power_off();
+		if (audio_refcount == 1) {
+			Collie_audio_power_on();
+			sa1100_dma_wakeup((dmach_t)COLLIE_BUZZER_DMA_CHANNEL);
+			sa1100_dma_wakeup((dmach_t)COLLIE_BUZZER_DMA_CHANNEL_INPUT);
+		} else {
+			sa1100_dma_wakeup((dmach_t)COLLIE_BUZZER_DMA_CHANNEL);
+			sa1100_dma_wakeup((dmach_t)COLLIE_BUZZER_DMA_CHANNEL_INPUT);
+		}
+		break;
+	}
+	return 0;
+}
+#endif
+
+/*** Config & Setup ******************************************************/
+
+int __init Collie_sound_init(void)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
+	ucbstruct = ucb1x00_get();
+#endif
+	if (!CollieIrqInit()) {
+	    printk("Sound driver: Interrupt initialization failed\n");
+	    return -1;
+	}
+	Ser4MCDR0 = 0; /* ucb1200_sa1100_set_mcdr0(0); */   
+
+	Collie_sound_hard_init();
+	
+	/* Set default settings. */
+	sq_init();
+	/* Set up /dev/mixer. */
+	mixer_init();
+#ifdef MODULE
+	irq_installed = 1;
+#endif
+	printk("Collie tc35143af Sound Driver Installed\n");
+#ifdef CONFIG_PM
+	collie_sound_pm_dev = pm_register(PM_SYS_DEV, 0,
+						collie_sound_pm_callback);
+#endif
+	return 0;
+}
+
+#ifdef MODULE
+static int collie_tc35143_init_module(void)
+{
+	Collie_sound_init();
+	sq_allocate_buffers(&output_stream);
+	sq_allocate_buffers(&input_stream);
+	return 0;
+}
+
+static void collie_tc35143_cleanup_module(void)
+{
+#ifdef CONFIG_PM
+	pm_unregister(collie_sound_pm_dev);
+#endif
+	if (irq_installed) {
+		sa1100_free_dma(COLLIE_BUZZER_DMA_CHANNEL);
+		sa1100_free_dma(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
+	}
+
+	sq_release_buffers(&output_stream);
+	sq_release_buffers(&input_stream);
+	unregister_sound_mixer(mixer_unit);
+	unregister_sound_special(state_unit);
+	unregister_sound_dsp(sq_unit);
+	printk("collie_tc35143af has to go now, see you later!\n");
+}
+
+module_init(collie_tc35143_init_module);
+module_exit(collie_tc35143_cleanup_module);
+MODULE_DESCRIPTION("Collie tc35143af 16bit sound driver");
+MODULE_AUTHOR("SHARP");
+MODULE_LICENSE("GPL");
+#endif /* MODULE */
+
diff -Nuar linux-2.4.18/drivers/sound/Makefile linux-2.4.18p/drivers/sound/Makefile
--- linux-2.4.18/drivers/sound/Makefile	2003-05-13 11:18:36.000000000 +0200
+++ linux-2.4.18p/drivers/sound/Makefile	2004-10-12 23:11:29.000000000 +0200
@@ -11,7 +11,7 @@
 		    msnd.o opl3.o sb_common.o sequencer_syms.o \
 		    sound_core.o sound_syms.o uart401.o	\
 		    nm256_audio.o ac97.o ac97_codec.o aci.o \
-		    sa1100-audio.o pxa-audio.o pxa-ac97.o
+		    sa1100-audio.o pxa-audio.o pxa-ac97.o collie_ssp.o
 
 # Each configuration option enables a list of files.
 
@@ -78,7 +78,7 @@
 obj-$(CONFIG_SOUND_SA1111_UDA1341) += sa1111-uda1341.o
 obj-$(CONFIG_SOUND_SA1100SSP)	+= sa1100ssp.o
 obj-$(CONFIG_SOUND_COLLIE_SSP)	+= collie_ssp.o
-obj-$(CONFIG_SOUND_COLLIE_TC35143) += collie-tc35143.o
+obj-$(CONFIG_SOUND_COLLIE_TC35143) += collie_tc35143af.o
 obj-$(CONFIG_SOUND_PXA_AC97)+= pxa-ac97.o pxa-audio.o ac97_codec.o
 obj-$(CONFIG_SOUND_EMU10K1)	+= ac97_codec.o
 obj-$(CONFIG_SOUND_RME96XX)     += rme96xx.o