cmpci spdif in/out
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
drivers/sound/cmpci.c renamed from drivers/sound/cmpci.c.orig +51 -9
@@ -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 );
drivers/sound/Config.in renamed from drivers/sound/Config.in.orig +5 -0
@@ -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