diff -u -r linux-source-2.6.22-2.6.22/sound/pci/ca0106/ca0106_main.c linux-source-2.6.22-2.6.22-ben/sound/pci/ca0106/ca0106_main.c
--- linux-source-2.6.22-2.6.22/sound/pci/ca0106/ca0106_main.c	2007-07-09 09:32:17.000000000 +1000
+++ linux-source-2.6.22-2.6.22-ben/sound/pci/ca0106/ca0106_main.c	2008-03-10 23:37:05.000000000 +1100
@@ -247,9 +247,9 @@
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
-	.rates =		(SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
-				 SNDRV_PCM_RATE_192000),
-	.rate_min =		48000,
+	.rates =		(SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
+				 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
+	.rate_min =		44100,
 	.rate_max =		192000,
 	.channels_min =		2,  //1,
 	.channels_max =		2,  //6,
@@ -610,12 +610,20 @@
 	u32 reg40_set = 0;
 	u32 reg40;
 	/* FIXME: Depending on mixer selection of SPDIF out or not, select the spdif rate or the DAC rate. */
-	u32 reg71_mask = 0x03030000 ; /* Global. Set SPDIF rate. We only support 44100 to spdif, not to DAC. */
+	/*u32 reg71_mask = 0x03030000 ; /* Global. Set SPDIF rate. We only support 44100 to spdif, not to DAC. */
+	u32 reg71_mask;
+	u32 reg71_shift;
 	u32 reg71_set = 0;
 	u32 reg71;
 	int i;
+	if (emu->spdif_enable) {
+		reg71_shift = 24; /* SPDIF Output Rate */
+	} else {
+		reg71_shift = 16; /* I2S Output Rate */
+	}
+	reg71_mask = 0x3 << reg71_shift;
 	
-        //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
+        snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
         //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
 	//snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->buffer.addr, emu->buffer.area, emu->buffer.bytes);
 	/* Rate can be set per channel. */
@@ -623,24 +631,27 @@
 	/* reg71 controls DAC rate. */
 	switch (runtime->rate) {
 	case 44100:
-		reg40_set = 0x10000 << (channel<<1);
-		reg71_set = 0x01010000; 
-		break;
+		/* We only support 44100 to spdif, not to DAC. (FIXME WHY?)*/
+		if (emu->spdif_enable) {
+			reg40_set = 0x10000 << (channel<<1);
+			reg71_set = 0x1 << reg71_shift;
+			break;
+		}
         case 48000:
 		reg40_set = 0;
-		reg71_set = 0; 
+		reg71_set = 0;
 		break;
 	case 96000:
 		reg40_set = 0x20000 << (channel<<1);
-		reg71_set = 0x02020000; 
+		reg71_set = 0x2 << reg71_shift;
 		break;
 	case 192000:
 		reg40_set = 0x30000 << (channel<<1);
-		reg71_set = 0x03030000; 
+		reg71_set = 0x3 << reg71_shift;
 		break;
 	default:
 		reg40_set = 0;
-		reg71_set = 0; 
+		reg71_set = 0;
 		break;
 	}
 	/* Format is a global setting */
@@ -660,11 +671,15 @@
 	hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
 	outl(hcfg, emu->port + HCFG);
 	reg40 = snd_ca0106_ptr_read(emu, 0x40, 0);
+        snd_printk("ca0106: old reg40=%x\n", reg40);
 	reg40 = (reg40 & ~reg40_mask) | reg40_set;
 	snd_ca0106_ptr_write(emu, 0x40, 0, reg40);
+        snd_printk("ca0106: new reg40=%x\n", reg40);
 	reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
+        snd_printk("ca0106: old reg71=%x\n", reg71);
 	reg71 = (reg71 & ~reg71_mask) | reg71_set;
 	snd_ca0106_ptr_write(emu, 0x71, 0, reg71);
+        snd_printk("ca0106: new reg71=%x\n", reg71);
 
 	/* FIXME: Check emu->buffer.size before actually writing to it. */
         for(i=0; i < runtime->periods; i++) {
@@ -1300,6 +1315,7 @@
 #if 1
 	printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n", chip->model,
 	       chip->revision, chip->serial);
+	printk(KERN_INFO "snd-ca0106: 44100Hz capable Ben Stanley " __DATE__ ".\n" );
 #endif
 	strcpy(card->driver, "CA0106");
 	strcpy(card->shortname, "CA0106");
