[Openvortex-dev] spdif init

From:

J. Gordon Wolfe

Subject:

[Openvortex-dev] spdif init

Date:

Fri, 14 Nov 2003 17:46:04 -0500

Hi all,
I spent the afternoon hacking on the spdif trying to get AC3 passthru to
work. The bad news is I haven't made it work yet. The good news is I
spent some time messing with vortex_spdif_init() and I fixed a bug,
among other discoveries.
Anyway, without further adieu:
--- alsa/pci/au88x0/au88x0_core.c 2003-10-30 11:01:40.000000000 -0500
+++ alsa-work/pci/au88x0/au88x0_core.c 2003-11-14 16:33:58.444307910 -0500
@@ -2140,7 +2140,7 @@
/* SPDIF support */
void vortex_spdif_init(vortex_t *vortex, int spdif_sr, int spdif_mode) {
int i, this_38 = 0, this_04=0, this_08=0, this_0c=0;
-
+
/* CAsp4Spdif::InitializeSpdifHardware(void) */
hwwrite(vortex->mmio, VORTEX_SPDIF_FLAGS, hwread(vortex->mmio,
VORTEX_SPDIF_FLAGS) & 0xfff3fffd);
//for (i=0x291D4; i<0x29200; i+=4)
@@ -2174,7 +2174,7 @@
this_38 &= 0xFFFFFFFE;
this_38 &= 0xFFFFFFFD;
this_38 &= 0xF3FFFFFF;
- this_38 |= 0x03000000;
+ this_38 |= 0x03000000; /* set 32khz samplerate */
this_38 &= 0xFFFFFF3F;
spdif_sr &= 0xFFFFFFFD;
spdif_sr |= 1;
@@ -2183,7 +2183,7 @@
this_38 &= 0xFFFFFFFE;
this_38 &= 0xFFFFFFFD;
this_38 &= 0xF0FFFFFF;
- this_38 |= 0x03000000;
+ this_38 |= 0x00000000; /* set 44.1khz samplerate */
this_38 &= 0xFFFFFF3F;
spdif_sr &= 0xFFFFFFFC;
break;
@@ -2192,9 +2192,10 @@
this_38 &= 0xFFFFFFFE;
this_38 &= 0xFFFFFFFD;
this_38 &= 0xF2FFFFFF;
- this_38 |= 0x02000000;
+ this_38 |= 0x02000000; /* set 48khz samplerate
*/
this_38 &= 0xFFFFFF3F;
} else {
+ /* I think this stuff is for AC3 */
this_38 |= 0x00000003;
this_38 &= 0xFFFFFFBF;
this_38 |= 0x80;
@@ -2204,9 +2205,11 @@
break;
}
- hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
- hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x10);
- hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);
+ /* looks like the next 2 lines transfer a 16-bit value into 2 8-bit
registers.
+ seems to be for the standard IEC/SPDIF initialization stuff */
+ hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
+ hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x0f);
+ hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr); /* for a
samplerate converter I think */
}
/* Initialization */
Theres a lot of stuff there, but the important change is the 0x10
becoming an 0x0f on the second hwwrite line. I'm convinced thats just
somebodys off-by-one error, and with that change my receiver *finally*
initializes correctly. Also, in the switch statement where I changed
0x03000000 to 0x00000000, that was necessary to get sound from the spdif
when its set to 44.1khz once I'd made the hwwrite change.
Looking at the way emu10k1 uses their spdif, I'm convinced its the
correct way to do things. And now my spdif will play mostly correct
sound when its set to either 44.1khz or 48khz, regardless of the
frequency of the source. Theres a touch of distortion playing 44.1k
sounds at 48k, but nowheres near what I used to get. For some reason,
32khz still doesn't work at all for me. I think it must have to do with
spdif_sr being set incorrectly for that frequency, but that variable's
pretty cryptic and I don't know what to do other than trial and error to
fix it.
For the interested, I also walked through all the setting of this_38 and
spdif_sr, and as best I can tell, most of the code in that function is
unnecessary. You can reduce that part of the function to this, and it
will work:
i = spdif_sr;
switch (i) {
case 32000:
this_38 = 0x03000000;
spdif_sr = 0x7D8D;
break;
case 44100:
this_38 = 0x00000000;
spdif_sr = 0xACCC;
break;
case 48000:
if (spdif_mode == 1) {
this_38 = 0x02000000;
} else {
this_38 = 0x83;
}
spdif_sr = 0xBB8E;
break;
}
hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x0f);
hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);
I'm not sure if thats because we're arbitrarily setting this_38=0 at the
beginning. If we set it to something different to start, all those &=
might be good for something, so maybe we don't want to take them out
just yet. Same goes for spdif_sr, since I don't know why its written
the way it is. Just thought it was interesting that all that code
wasn't doing anything.
Now about getting AC3 working... I think setting spdif_mode=0 will setup
the hardware correctly, though this_38 might need to be 0x02000083
instead of just 0x83, I'm really not sure. For that matter, the 0x80
might be wrong, all I'm really sure of is that the 0x03 sets some flags
that are required for AC3. Anyhow, the problem I'm running into right
now is that I can't get xine to open up the spdif device so I can test.
It keeps giving me "Invalid type" errors. Not being an ALSA expert, I
don't know how to fix this. Any ideas?
- Gordon
--
J. Gordon Wolfe <address@hidden>