diff options
Diffstat (limited to 'linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch')
-rw-r--r-- | linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch | 5602 |
1 files changed, 5602 insertions, 0 deletions
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch index e69de29bb2..867774aab8 100644 --- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch +++ b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch @@ -0,0 +1,5602 @@ +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(50); ++ ++ 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 |