RFC: massive snd_hda driver update to better conform UAA

Alexander Motin mav at FreeBSD.org
Wed Aug 13 15:09:47 UTC 2008


Andriy Gapon wrote:
> on 13/08/2008 16:59 Andriy Gapon said the following:
>> Alexander,
>>
>> I've tried a slightly tweaked version of your releng_7 patch on 6.3.
>> It seems that with your patch recording stopped working for me, but
>> everything else is OK.
>>
>> From (non-verbose) dmesg:
>> hdac0: <NVidia MCP51 High Definition Audio Controller> mem
>> 0xfe024000-0xfe027fff irq 22 at device 16.1 on pci0
>> hdac0: <HDA Driver Revision: 20080812_0000>
>> hdac0: <HDA Codec #0: Analog Devices AD1986A>
>> hdac0: hdac_widget_connection_parse: nid=18 WARNING: zero cnid entnum=4
>> j=2 index=0 entries=8 found=2 res=0x21002211
>> hdac0: hdac_audio_as_parse: Pin 28 has wrong direction for association
>> 1! Disabling association.
>> hdac0: hdac_audio_as_parse: Pin 29 has wrong direction for association
>> 1! Disabling association.
>> pcm0: <HDA codec Analog Devices AD1986A PCM #0> on hdac0
>> pcm1: <HDA codec Analog Devices AD1986A PCM #1> on hdac0

Here is an answer:

> nid 27 0x01014011 as  1 seq  1      Line out  Jack jack  1 loc  1 color
>   Green misc 0
> nid 28 0x01813012 as  1 seq  2       Line in  Jack jack  1 loc  1 color
>    Blue misc 0
> nid 29 0x01a19015 as  1 seq  5        Mic in  Jack jack  1 loc  1 color
>    Pink misc 0

pin 27 configured as output while 28 and 29 as inputs
Pin 27 is output only so we can't configure it as input.

> Parsing pin associations...
> hdac_audio_as_parse: Pin 28 has wrong direction for association 1!
> Disabling association.
> hdac_audio_as_parse: Pin 29 has wrong direction for association 1!
> Disabling association.
> 7 associations found
> Association 1 out (disabled):
>   Pin nid=27 seq=1
>   Pin nid=28 seq=2
>   Pin nid=29 seq=5

But they've used in same assignment. So we can:
  1. change assignment numbers and get recording from two pins and 
playback via the third.
  2. remove quirks and let BIOS configure those pins as 6 channel 
output, but then you will probably loose headphone output as soon as 
there is only three stereo DACs in codec and no HP redirection 
configured by BIOS.
hdac0: Association 1 out (disabled):
hdac0:   Pin nid=27 seq=1      <- this was going to be 5.1 out
hdac0:   Pin nid=28 seq=2
hdac0:   Pin nid=29 seq=5
hdac0: Association 2 out:
hdac0:   Pin nid=26 seq=1      <- this was going to be HP
  3. if HP redirection supported it can be enabled in addition to 2
  4. There is a lot of different recording sources configured,
hdac0: Association 15 in: 

hdac0:   Pin nid=31 seq=0 

hdac0: Association 15 in: 

hdac0:   Pin nid=32 seq=0 

hdac0: Association 15 in: 

hdac0:   Pin nid=34 seq=0 

hdac0: Association 15 in: 

but as soon as there is only one ADC present they are not working. It 
may be possible to join them together to use with same ADC.

>> I can see that current (non-patched) code has the following quirks for
>> the above two pins with my codec and my subvendor (ASUS M2NPV-MX
>> motherboard):
>>
>> } else if (id == HDA_CODEC_AD1986A &&
>> 	    (sc->pci_subvendor == ASUS_M2NPVMX_SUBVENDOR ||
>> 	    sc->pci_subvendor == ASUS_A8NVMCSM_SUBVENDOR)) {
>> 		switch (nid) {
>> 		case 28:	/* LINE */
>> 			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
>> 			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN;
>> 			break;
>> 		case 29:	/* MIC */
>> 			config &= ~HDA_CONFIG_DEFAULTCONF_DEVICE_MASK;
>> 			config |= HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN;
>> 			break;
>> 		default:
>> 			break;
>> 		}
>> 	}
> 
> The above code is still there after the patch, but the following is gone:
> case HDA_CODEC_AD1986A:

That is a problem. We must decide what to do with it. It is incorrect 
and must be revised.

>         if (subvendor == ASUS_M2NPVMX_SUBVENDOR ||
>             subvendor == ASUS_A8NVMCSM_SUBVENDOR) {
>                 /* nid 28 is mic, nid 29 is line-in */
>                 w = hdac_widget_get(devinfo, 15);
>                 if (w != NULL)
>                         w->selconn = 2;
>                 w = hdac_widget_get(devinfo, 16);
>                 if (w != NULL)
>                         w->selconn = 1;

It was workaround for double stage multiplexing used in this codec. It 
is dirty hack, so I have removed it. New driver still lack of this setup 
support so depending on configuration you may still not get those inputs 
working. I am thinking about that now.

-- 
Alexander Motin


More information about the freebsd-multimedia mailing list