Reply 920 of 1724, by thp
Ok, so now I actually read the backlog of this thread and it seems like you tried some Linux kernel 2.6.x distro already, and it works there?
There was also a link somewhere to this patch in FreeBSD: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=140591
The description there says:
+ * AD198x register 0x76
+ * 0x0400: select mixer for SURR_OUT/HP_OUT output pins (default surround DAC)
+ * 0x0020: select surround DAC for LINE_OUT output pins (default mixer)
[...]
+ * Fujitsu C610 seems to wire SURR_OUT/HP_OUT for
+ * internal speaker, and LINE_OUT for lineout AND headphone jacks;
+ * by setting previous 0x0420, internal speaker works but
+ * no output for either jacks.
[...]
+ case 0x122f10cf: /* Fujitsu C610 (perhaps for others) */
+ ac97_wrcd(codec, 0x76, ac97_rdcd(codec, 0x76) | 0x0400);
+ break;
The current FreeBSD source by default sets 0x420 (HPSEL = mixer, LOSEL = surround):
void ad198x_patch(struct ac97_info* codec)
{
switch (ac97_getsubvendor(codec)) {
case 0x11931043: /* Not for ASUS A9T (probably else too). */
break;
default:
ac97_wrcd(codec, 0x76, ac97_rdcd(codec, 0x76) | 0x0420);
break;
}
}
So this fix sets the bits 0x0400 in register 0x76. Bit 0x0400 is bit 10 when counting from the right and starting at 0.
Analog Devices still has the AD1980 data sheet online, which says that 0x76 is the "Miscellaneous Control Bit Register". Furthermore, D10 (the 10th bit, counting from zero) is "HPSEL", which the data sheet describes as:
Headphone Amplifier Input Select. This bit allows the headphone power amps to be driven from the surround DACs or from the mixer outputs. There are two reasons for this: one is to allow 2-channel media to use the higher power headphone amplifiers available on the SURR/HP_OUT outputs; the other is to allow spreading of 2-channel media to the surround outputs.
Together with the LOSEL bit (see above), this bit also provides for analog swapping of the mixer (front) and sur- round outputs.
0 = SURR_out/HP_out outputs are driven by the surround DACs (reset default).
1 = SURR_out/HP_out outputs are driven by the mixer outputs.
For completeness, the data sheet describes "LOSEL" as:
LINE_OUT Amplifiers Input Select. This bit allows the LINE_OUT output amplifiers to be driven by the mixer or the surround DACs. The main purpose for this is to allow swapping of the front and surround channels to make better use of the SURR/HP_OUT output amplifiers. This bit should normally be used in tandem with the HPSEL bit (see below).
0 = LINE_OUT amplifiers are driven by the mixer outputs (reset default).
1 = LINE_OUT amplifiers are driven by the surround DAC outputs.
I assume that your line out is wired to the internal speaker, and headphone is line out and headphone. Also, "mixer outputs" is the normal output (that you want), and "surround DAC outputs" is something else that doesn't provide any audio in your case (i.e. virtually muted).
So in order to get mixer output on headphone/line out, you want to set bit D10 in the 0x76 register.
If you also want mixer output on the internal spaker, you want to clear bit D5 in the 0x76 register.
By default, LOSEL = 0 (internal speakers work?) and HPSEL = 0 (headphone/line out don't work).
Instead of using DOSSOUND, you should be able to just do port I/O at the NABM (native audio bus master) port address (BAR1) -- not to be confused with NAM (native audio mixer / BAR0) and add the offset 0x76.
So to read the register:
inw(baseport_bm+0x76);
And to write the register:
outw(baseport_bm+0x76, data)
In a previous message you write:
E600 i865g D1980 (not working sound)
NAMBAR 2800 NAMBAR 2400 IRQ5
One of these (0x2800 or 0x2400) is the NABMBAR (bm = bus master -> the one we want), one is NAMBAR (mixer -> not the one we want).
So IMHO what could "fix" the issue (in your particular case):
int baseport = 0x2400; /* please put in the right NABMBAR value here! */
outw(baseport + 0x76, inw(baseport + 0x76) | 0x0400);
If that doesn't fix it fully, you can also try clearing D5 (the LOSEL bit) to (re-)enable the internal speaker(?):
int baseport = 0x2400; /* please put in the right NABMBAR value here! */
outw(baseport + 0x76, inw(baseport + 0x76) & ~0x0020);
If that doesn't work, check out the other registers in the data sheet, e.g. "Jack Sense/Audio Interrupt Status Register (Index 72h)", if you clear D12, D11 and D10 (JSMT0, JSMT1, JSMT2), it should ignore any jack sense pin inputs and never mute based on jack sense.
Other than that, check out the data sheet and dump register contents to find something interesting.
HTH.