snd_hda(4) pin routing issues

Alexander Motin mav at FreeBSD.org
Mon Jun 6 13:05:45 UTC 2011


Alexey Dokuchaev wrote:
> On Mon, May 16, 2011 at 10:20:02AM +0700, Alexey Dokuchaev wrote:
>> This is what our snd_hda(4) reports about pins (only pin config,
>> association, and sequence numbers quoted for better readability):
>>
>>     nid 8  0x01c5e030 as  3 seq  0
>>     nid 9  0x01451012 as  1 seq  2
>>     nid 13 0x02214011 as  1 seq  1
>>     nid 14 0x01014010 as  1 seq  0
>>     nid 15 0x01813021 as  2 seq  1
>>     nid 16 0x02a19020 as  2 seq  0
>>     nid 17 0x50170013 as  1 seq  3
>>     nid 18 0x90330022 as  2 seq  2
>>
>> [But] snd_hda(4) for some reason is unable to establish correct routing:
>>
>>     hdac0: 3 associations found:
>>     hdac0: Association 0 (1) out:
>>     hdac0:  Pin nid=14 seq=0
>>     hdac0:  Pin nid=13 seq=1
>>     hdac0:  Pin nid=9 seq=2

Here you have output association including three independent outputs.
What's strange is that pin 9 is digital, while the rest two is analog.
It is not fatal, but usually wrong. Also note that all 3 pins configured
to have own channels with no redirection. But looking on further output
you should see that codec has only one analog and one digital DACs!

>>     hdac0: Association 1 (2) in:
>>     hdac0:  Pin nid=16 seq=0
>>     hdac0:  Pin nid=15 seq=1
>>     hdac0:  Pin nid=18 seq=2
>>     hdac0: Association 2 (3) in:
>>     hdac0:  Pin nid=8 seq=0
>>     hdac0: Tracing association 0 (1)
>>     hdac0:  Pin 14 traced to DAC 2
>>     hdac0:  Unable to trace pin 13 seq 1 with min nid 0	<--- WHY?
>>     hdac0:  Unable to trace pin 14 seq 0 with min nid 3	<--- WHY?
>>     hdac0: Association 0 (1) trace failed
> 
> Here is more detailed log for association tracing.  Let's see what
> happens for pin 14:
> 
> hdac0: Tracing association 0 (1)
> hdac0:  Tracing pin 14 with min nid 0
> hdac0:   tracing via nid 14
> hdac0:    tracing via nid 11
> hdac0:     tracing via nid 7
> hdac0:      tracing via nid 2
> hdac0:      nid 2 returned 2
> hdac0:      tracing via nid 8
> hdac0:      nid 8 returned 0
> hdac0:      tracing via nid 10
> hdac0:       tracing via nid 12
> hdac0:        tracing via nid 16
> hdac0:        nid 16 returned 0
> hdac0:        tracing via nid 15
> hdac0:        nid 15 returned 0
> hdac0:        tracing via nid 14
> hdac0:        nid 14 returned 0
> hdac0:        tracing via nid 13
> hdac0:        nid 13 returned 0
> hdac0:        tracing via nid 18
> hdac0:        nid 18 returned 0
> hdac0:       nid 12 returned 0
> hdac0:      nid 10 returned 0
> hdac0:     nid 7 returned 2
> hdac0:    nid 11 returned 2
> hdac0:   nid 14 returned 2
> hdac0:  Pin 14 traced to DAC 2
> 
> This seems correct and matches the picture [1] of what ALSA does.  Now we
> move to pin 13:
> 
> hdac0:  Tracing pin 13 with min nid 0
> hdac0:   tracing via nid 13
> hdac0:    tracing via nid 11
> hdac0:    nid 11 busy by seqmask 1		<--- WTF?!
> hdac0:   nid 13 returned 0
> hdac0:  Unable to trace pin 13 seq 1 with min nid 0
> 
> Apparently, something is wrong with pin 11.  Let's remember this number,

Nid 11 is already busy by signal for pin 14. It can't be reused for pin
13, as they configured to be independent.

> as I will get back to it later.  After tracing for pin 13 failed, it
> then tried to retrace pin 14, presumably, according to this part of
> /sys/dev/sound/pci/hda/hdac.c around line 5159:
> 
> %        /* Trace this pin taking min nid into account. */
> %        res = hdac_audio_trace_dac(devinfo, as, i,
> %            ases[as].pins[i], hpredir, min, 0, 0);
> %        if (res == 0) {
> %                /* If we failed - return to previous and redo it. */
> 
> hdac0:  Tracing pin 14 with min nid 3
> hdac0:   tracing via nid 14
> hdac0:    tracing via nid 11
> hdac0:     tracing via nid 7
> hdac0:      tracing via nid 2
> hdac0:      nid 2 returned 0
> hdac0:      tracing via nid 8
> hdac0:      nid 8 returned 0
> hdac0:      tracing via nid 10
> hdac0:       tracing via nid 12
> hdac0:        tracing via nid 16
> hdac0:        nid 16 returned 0
> hdac0:        tracing via nid 15
> hdac0:        nid 15 returned 0
> hdac0:        tracing via nid 14
> hdac0:        nid 14 returned 0
> hdac0:        tracing via nid 13
> hdac0:        nid 13 returned 0
> hdac0:        tracing via nid 18
> hdac0:        nid 18 returned 0
> hdac0:       nid 12 returned 0
> hdac0:      nid 10 returned 0
> hdac0:     nid 7 returned 0
> hdac0:    nid 11 returned 0
> hdac0:   nid 14 returned 0
> hdac0:  Unable to trace pin 14 seq 0 with min nid 3
> hdac0: Association 0 (1) trace failed
> 
> I have some questions about this part: why do we need to retrace pin 14,
> if it was already successfully traced?  What exactly is "min nid"?  Why
> pin 14 was traced with min nid 0 the first time, and with min nid 3 the
> second time?

Association should be traced either all or none. First, driver traced
pin 14 with no limitations and routed it to DAC 2. But after it failed
to trace pin 13 anywhere, it supposed that initial solution about pin 14
could be wrong and tried to find another DAC for it. Unsuccessfully, as
there is only one analog DAC in this codec.

> Now, let's get back to nid 11, which was "busy by seqmask 1".  I digged
> my old email from July 2007 [2] on acpi@ about this laptop of mine (I was
> running 6.2-STABLE that days and had some ACPI troubles).  From attached
> verbose dmesg log, however, I can see that snd_hda(4) worked!  It was
> at revision 20070710_0047 that time.  Apparently driver had changed
> quite a bit in 2007-2011, so the log is different, but I've noticed some
> interesting bits:
> 
> Old driver (20070710_0047):
> -HDA config/quirks: softpcmvol forcestereo ivref50 ivref80 ivref100 ivref
> New driver (20100226_0142):
> +FG config/quirks: forcestereo ivref50 ivref80 ivref100 ivref

Before rewrite few years ago driver was completely dumb. It was routing
single audio channel everywhere, ignoring any configuration. After
rewrite, driver tried to use your configuration and found it wrong.

Tunable you were using:
hint.hdac.0.cad0.nid13.config="as=1 seq=15"
is correct. It makes driver to setup audio redirection for headphones
output, using same DAC as for the line-out.

I would also added another tunable:
hint.hdac.0.cad0.nid9.config="as=4 seq=0"
to separate digital output into separate device, as it should. By the
way it will return analog recording to pcm0 device, which was pushed out
to pcm1, as pcm0 was considered digital because of using one digital pin
there.

-- 
Alexander Motin


More information about the freebsd-multimedia mailing list