I didn't read this list until yesterday, so I don't know if something 
similar has been discussed here.

The patch below enables S/PDIF input and output on cmi8338 soundcards. 
It's against the current 3.21 cmpci driver from www.cmedia.com.tw.

([EMAIL PROTECTED] provides patches to make it work with 2.3.99-kernels
on http://web.tiscalinet.it/luvassu)

Unfortunately it doesn't give perfect results - a file piped through 
an spdif channel shows lost bytes, duplicated bytes and random corruption.
This corruption can hardly be heard, but I think spidif should allow 
perfect transfers.

Any ideas?

Jan


--- linux/drivers/sound/cmpci.c.orig    Mon May 29 15:29:40 2000
+++ linux/drivers/sound/cmpci.c Mon May 29 18:03:47 2000
@@ -62,6 +62,7 @@
  *                     Add support for modem, S/PDIF loop and 4 channels.
  *                     (8738 only)
  *                     Fix bug cause x11amp cannot play.
+ *    29.05.00        Added support for S/PDIF in/out ([EMAIL PROTECTED])
  *
  *    28.05.00         Patches for kernel 2.4 compliance ([EMAIL PROTECTED])
  */
@@ -2984,11 +2403,17 @@
 
 #ifdef MODULE
 int    spdif_loop = 0;
+int    spdif_in = 1;
+int    spdif_out = 1;
+int    spdif_32 = 0;
 int    four_ch = 0;
 int    rear_out = 0;
 int    modem = 0;
 int    joystick = 0;
 MODULE_PARM(spdif_loop, "i");
+MODULE_PARM(spdif_in, "i");
+MODULE_PARM(spdif_out, "i");
+MODULE_PARM(spdif_32, "i");
 MODULE_PARM(four_ch, "i");
 MODULE_PARM(rear_out, "i");
 MODULE_PARM(modem, "i");
@@ -2999,6 +2424,15 @@
 #ifdef CONFIG_SOUND_CMPCI_SPDIFLOOP
 int    spdif_loop = 1;
 #endif
+#ifdef CONFIG_SOUND_CMPCI_SPDIFIN
+int    spdif_in = 1;
+#endif
+#ifdef CONFIG_SOUND_CMPCI_SPDIFOUT
+int    spdif_out = 1;
+#endif
+#ifdef CONFIG_SOUND_CMPCI_SPDIF32
+int    spdif_32 = 1;
+#endif
 #ifdef CONFIG_SOUND_CMPCI_4CH
 int    four_ch = 1;
 #endif
@@ -3158,15 +2584,6 @@
                                outb(inb((s->iobase + CODEC_CMI_MISC_CTRL) | 0x80) & 
~0x40, s->iobase + CODEC_CMI_MISC_CTRL);
                                printk(KERN_INFO "cm: modem function supported\n");
                        }
-                       /* enable SPDIF loop */
-                       if (spdif_loop)
-                       {
-                               /* turn on spdif-in to spdif-out */
-                               outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) | 0x80, 
s->iobase + CODEC_CMI_FUNCTRL1);
-                               printk(KERN_INFO "cm: Enable SPDIF loop\n");
-                       }
-                       else
-                               outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) & ~0x80, 
s->iobase + CODEC_CMI_FUNCTRL1);
                        /* enable 4 channels mode */
                        if (four_ch)
                        {
@@ -3188,6 +2605,41 @@
                        else
                                outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 3) & ~0x04, 
s->iobase + CODEC_CMI_MISC_CTRL + 3);
                }
+               /* enable SPDIF loop */
+               if (spdif_loop)
+               {
+                       /* turn on spdif-in to spdif-out */
+                       outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) | 0x80, s->iobase + 
+CODEC_CMI_FUNCTRL1);
+                       printk(KERN_INFO "cm: Enable SPDIF loop\n");
+               }
+               else
+                       outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) & ~0x80, s->iobase + 
+CODEC_CMI_FUNCTRL1);
+               /* enable SPDIF 32-bit-mode (untested) */
+               if (spdif_32)
+               {
+                       /* turn on 32 bit (SPD32SEL) */
+                       outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 2) | 0x20, 
+s->iobase + CODEC_CMI_MISC_CTRL + 2);
+                       printk(KERN_INFO "cm: Enable SPDIF32 \n");
+               }
+               else
+                       outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 2) & ~0x20, 
+s->iobase + CODEC_CMI_MISC_CTRL + 2);
+               /* enable SPDIF in */
+               if (spdif_in)
+               {
+                       /* turn on spdif in */
+                       outb(inb(s->iobase + CODEC_CMI_FUNCTRL1 + 1) | 0x02, s->iobase 
++ CODEC_CMI_FUNCTRL1 + 1);
+                       printk(KERN_INFO "cm: Enable SPDIF in \n");
+               }
+               else
+                       outb(inb(s->iobase + CODEC_CMI_FUNCTRL1 + 1) & ~0x02, 
+s->iobase + CODEC_CMI_FUNCTRL1 + 1);
+               if (spdif_out)
+               {
+                       /* turn on spdif out */
+                       outb(inb(s->iobase + CODEC_CMI_FUNCTRL1 + 1) | 0x01, s->iobase 
++ CODEC_CMI_FUNCTRL1 + 1);
+                       printk(KERN_INFO "cm: Enable SPDIF out \n");
+               }
+               else
+                       outb(inb(s->iobase + CODEC_CMI_FUNCTRL1 + 1) & ~0x01, 
+s->iobase + CODEC_CMI_FUNCTRL1 + 1);
                /* enable joystick */
                if (joystick)
                        outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) | 0x02, s->iobase + 
CODEC_CMI_FUNCTRL1);
--- linux/drivers/sound/Config.in.orig  Fri May 12 03:30:14 2000
+++ linux/drivers/sound/Config.in       Mon May 29 15:32:11 2000
@@ -12,6 +12,11 @@
 dep_tristate '  C-Media PCI (CMI8338/8378)' CONFIG_SOUND_CMPCI $CONFIG_SOUND
 if [ "$CONFIG_SOUND_CMPCI" = "y" -o "$CONFIG_SOUND_CMPCI" = "m" ]; then
     bool '    Enable S/PDIF loop for CMI8738' CONFIG_SOUND_CMPCI_SPDIFLOOP
+    bool '    Enable S/PDIF in for CMI8738' CONFIG_SOUND_CMPCI_SPDIFIN
+    bool '    Enable S/PDIF out for CMI8738' CONFIG_SOUND_CMPCI_SPDIFOUT
+    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+           bool '    Enable S/PDIF 32bit-mode for CMI8738' CONFIG_SOUND_CMPCI_SPDIF32
+    fi
     bool '    Enable 4 channel mode for CMI8738' CONFIG_SOUND_CMPCI_4CH
     if [ "$CONFIG_SOUND_CMPCI_4CH" = "y" ]; then
         bool '    Separate rear out jack' CONFIG_SOUND_CMPCI_REAR

Reply via email to