[alsa-devel] [PATCH] ALSA: HDA: Conexant auto: Handle multiple connections to ADC node

Takashi Iwai tiwai at suse.de
Sat Feb 19 16:19:02 CET 2011


At Tue, 15 Feb 2011 20:24:13 +0100,
David Henningsson wrote:
> 
> Conexant 20641 has several inputs to its ADC node, with one selector
> and individual amps for all inputs. This patch adds support in the
> Conexant auto parser to handle that case.
> 
> It also means that the pin node's volume is being renamed to "Boost"
> to avoid name clash with the new volume controls on the ADC node.
> 
> I was a little unsure whether to rename it to "Boost" or "Boost Capture" 
> - 20641 does not have analog monitoring possibility, so that would be 
> "Boost Capture", but OTOH, if the volume is on the pin, there is no 
> possibility it cannot affect playback, if there is a link. So "Boost" 
> feels more future-safe, whereas "Boost Capture" feels more correct given 
> current situation. What do you think?

I guess it's no big issue.  We have no analog loopback for Conexant.

> I'm attaching a codec proc with the codec in question (before applied 
> patch).
> 
> I would want this in 2.6.38, but if you feel the change is too large too 
> late, I'll merge it downstream (in Ubuntu) for the time being.

I queued this for 2.6.38, as this isn't so intrusive change.


thanks,

Takashi


> 
> -- 
> David Henningsson, Canonical Ltd.
> http://launchpad.net/~diwic
> [2 0001-ALSA-HDA-Conexant-auto-parser-Add-multiple-connectio.patch <text/x-patch (7bit)>]
> >From 7dcbd106a51e276b7cdbf37bf855c70ef07c33f1 Mon Sep 17 00:00:00 2001
> From: David Henningsson <david.henningsson at canonical.com>
> Date: Tue, 15 Feb 2011 19:57:09 +0100
> Subject: [PATCH] ALSA: HDA: Conexant auto: Handle multiple connections to ADC node
> 
> Conexant 20641 has several inputs to its ADC node, with one selector
> and individual amps for all inputs. This patch adds support in the
> Conexant auto parser to handle that case.
> 
> It also means that the pin node's volume is being renamed to "Boost"
> to avoid name clash with the new volume controls on the ADC node.
> 
> BugLink: http://bugs.launchpad.net/bugs/719524
> Signed-off-by: David Henningsson <david.henningsson at canonical.com>
> ---
>  sound/pci/hda/patch_conexant.c |   61 +++++++++++++++++++++++++++++++--------
>  1 files changed, 48 insertions(+), 13 deletions(-)
> 
> diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
> index fbe97d3..cd29eaf 100644
> --- a/sound/pci/hda/patch_conexant.c
> +++ b/sound/pci/hda/patch_conexant.c
> @@ -3729,9 +3729,9 @@ static int cx_auto_init(struct hda_codec *codec)
>  	return 0;
>  }
>  
> -static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
> +static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
>  			      const char *dir, int cidx,
> -			      hda_nid_t nid, int hda_dir)
> +			      hda_nid_t nid, int hda_dir, int amp_idx)
>  {
>  	static char name[32];
>  	static struct snd_kcontrol_new knew[] = {
> @@ -3743,7 +3743,8 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
>  
>  	for (i = 0; i < 2; i++) {
>  		struct snd_kcontrol *kctl;
> -		knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, hda_dir);
> +		knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
> +							    hda_dir);
>  		knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
>  		knew[i].index = cidx;
>  		snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]);
> @@ -3759,6 +3760,9 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
>  	return 0;
>  }
>  
> +#define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir)		\
> +	cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
> +
>  #define cx_auto_add_pb_volume(codec, nid, str, idx)			\
>  	cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
>  
> @@ -3808,29 +3812,60 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
>  	struct conexant_spec *spec = codec->spec;
>  	struct auto_pin_cfg *cfg = &spec->autocfg;
>  	static const char *prev_label;
> -	int i, err, cidx;
> +	int i, err, cidx, conn_len;
> +	hda_nid_t conn[HDA_MAX_CONNECTIONS];
> +
> +	int multi_adc_volume = 0; /* If the ADC nid has several input volumes */
> +	int adc_nid = spec->adc_nids[0];
> +
> +	conn_len = snd_hda_get_connections(codec, adc_nid, conn,
> +					   HDA_MAX_CONNECTIONS);
> +	if (conn_len < 0)
> +		return conn_len;
> +
> +	multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1;
> +	if (!multi_adc_volume) {
> +		err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid,
> +					 HDA_INPUT);
> +		if (err < 0)
> +			return err;
> +	}
>  
> -	err = cx_auto_add_volume(codec, "Capture", "", 0, spec->adc_nids[0],
> -				 HDA_INPUT);
> -	if (err < 0)
> -		return err;
>  	prev_label = NULL;
>  	cidx = 0;
>  	for (i = 0; i < cfg->num_inputs; i++) {
>  		hda_nid_t nid = cfg->inputs[i].pin;
>  		const char *label;
> -		if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
> +		int j;
> +		int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP;
> +		if (!pin_amp && !multi_adc_volume)
>  			continue;
> +
>  		label = hda_get_autocfg_input_label(codec, cfg, i);
>  		if (label == prev_label)
>  			cidx++;
>  		else
>  			cidx = 0;
>  		prev_label = label;
> -		err = cx_auto_add_volume(codec, label, " Capture", cidx,
> -					 nid, HDA_INPUT);
> -		if (err < 0)
> -			return err;
> +
> +		if (pin_amp) {
> +			err = cx_auto_add_volume(codec, label, " Boost", cidx,
> +						 nid, HDA_INPUT);
> +			if (err < 0)
> +				return err;
> +		}
> +
> +		if (!multi_adc_volume)
> +			continue;
> +		for (j = 0; j < conn_len; j++) {
> +			if (conn[j] == nid) {
> +				err = cx_auto_add_volume_idx(codec, label,
> +				    " Capture", cidx, adc_nid, HDA_INPUT, j);
> +				if (err < 0)
> +					return err;
> +				break;
> +			}
> +		}
>  	}
>  	return 0;
>  }
> -- 
> 1.7.1
> 
> [3 conexant_20641.txt <text/plain (7bit)>]
> Codec: Conexant CX20641
> Address: 2
> AFG Function Id: 0x1 (unsol 1)
> Vendor Id: 0x14f150a1
> Subsystem Id: 0x102804f5
> Revision Id: 0x100100
> No Modem Function Group found
> Default PCM:
>     rates [0x160]: 44100 48000 96000
>     bits [0xe]: 16 20 24
>     formats [0x1]: PCM
> Default Amp-In caps: N/A
> Default Amp-Out caps: N/A
> GPIO: io=5, o=0, i=0, unsolicited=1, wake=1
>   IO[0]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
>   IO[1]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
>   IO[2]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
>   IO[3]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
>   IO[4]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
> Node 0x10 [Audio Output] wcaps 0xc1d: Stereo Amp-Out R/L
>   Control: name="Front Playback Volume", index=0, device=0
>     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
>   Control: name="Front Playback Switch", index=0, device=0
>     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
>   Device: name="CONEXANT Analog", type="Audio", device=0
>   Amp-Out caps: ofs=0x4a, nsteps=0x4a, stepsize=0x03, mute=1
>   Amp-Out vals:  [0x49 0x49]
>   Converter: stream=5, channel=0
>   PCM:
>     rates [0x560]: 44100 48000 96000 192000
>     bits [0xe]: 16 20 24
>     formats [0x1]: PCM
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
> Node 0x11 [Audio Output] wcaps 0xc1d: Stereo Amp-Out R/L
>   Control: name="Headphone Playback Volume", index=0, device=0
>     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
>   Control: name="Headphone Playback Switch", index=0, device=0
>     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
>   Amp-Out caps: ofs=0x4a, nsteps=0x4a, stepsize=0x03, mute=1
>   Amp-Out vals:  [0x46 0x46]
>   Converter: stream=5, channel=0
>   PCM:
>     rates [0x560]: 44100 48000 96000 192000
>     bits [0xe]: 16 20 24
>     formats [0x1]: PCM
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
> Node 0x12 [Audio Output] wcaps 0x611: Stereo Digital
>   Converter: stream=0, channel=0
>   Digital:
>   Digital category: 0x0
>   PCM:
>     rates [0x5e0]: 44100 48000 88200 96000 192000
>     bits [0xe]: 16 20 24
>     formats [0x5]: PCM AC3
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
> Node 0x13 [Beep Generator Widget] wcaps 0x70000c: Mono Amp-Out
>   Control: name="Beep Playback Volume", index=0, device=0
>     ControlAmp: chs=1, dir=Out, idx=0, ofs=0
>   Control: name="Beep Playback Switch", index=0, device=0
>     ControlAmp: chs=1, dir=Out, idx=0, ofs=0
>   Amp-Out caps: ofs=0x07, nsteps=0x07, stepsize=0x0f, mute=0
>   Amp-Out vals:  [0x00]
> Node 0x14 [Audio Input] wcaps 0x100d1b: Stereo Amp-In R/L
>   Control: name="Capture Volume", index=0, device=0
>     ControlAmp: chs=3, dir=In, idx=0, ofs=0
>   Control: name="Capture Switch", index=0, device=0
>     ControlAmp: chs=3, dir=In, idx=0, ofs=0
>   Device: name="CONEXANT Analog", type="Audio", device=0
>   Amp-In caps: ofs=0x4a, nsteps=0x50, stepsize=0x03, mute=1
>   Amp-In vals:  [0x50 0x50] [0x45 0x45] [0x00 0x00] [0x4a 0x4a]
>   Converter: stream=1, channel=0
>   SDI-Select: 0
>   PCM:
>     rates [0x160]: 44100 48000 96000
>     bits [0xe]: 16 20 24
>     formats [0x1]: PCM
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 4
>      0x1a 0x1b 0x1d* 0x1e
> Node 0x15 [Audio Input] wcaps 0x100d1b: Stereo Amp-In R/L
>   Amp-In caps: ofs=0x4a, nsteps=0x50, stepsize=0x03, mute=1
>   Amp-In vals:  [0x4a 0x4a] [0x4a 0x4a] [0x4a 0x4a] [0x4a 0x4a]
>   Converter: stream=0, channel=0
>   SDI-Select: 0
>   PCM:
>     rates [0x160]: 44100 48000 96000
>     bits [0xe]: 16 20 24
>     formats [0x1]: PCM
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 4
>      0x1a* 0x1b 0x1d 0x1e
> Node 0x16 [Audio Input] wcaps 0x100d1b: Stereo Amp-In R/L
>   Amp-In caps: ofs=0x4a, nsteps=0x50, stepsize=0x03, mute=1
>   Amp-In vals:  [0x4a 0x4a]
>   Converter: stream=0, channel=0
>   SDI-Select: 0
>   PCM:
>     rates [0x160]: 44100 48000 96000
>     bits [0xe]: 16 20 24
>     formats [0x1]: PCM
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 1
>      0x22
> Node 0x17 [Audio Output] wcaps 0xc1d: Stereo Amp-Out R/L
>   Control: name="Speaker Playback Volume", index=0, device=0
>     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
>   Control: name="Speaker Playback Switch", index=0, device=0
>     ControlAmp: chs=3, dir=Out, idx=0, ofs=0
>   Amp-Out caps: ofs=0x4a, nsteps=0x4a, stepsize=0x03, mute=1
>   Amp-Out vals:  [0x00 0x00]
>   Converter: stream=5, channel=0
>   PCM:
>     rates [0x560]: 44100 48000 96000 192000
>     bits [0xe]: 16 20 24
>     formats [0x1]: PCM
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
> Node 0x18 [Pin Complex] wcaps 0x400581: Stereo
>   Pincap 0x00010014: OUT EAPD Detect
>   EAPD 0x0:
>   Pin Default 0x04f001f0: [Jack] Other at Ext Right
>     Conn = Unknown, Color = Unknown
>     DefAssociation = 0xf, Sequence = 0x0
>     Misc = NO_PRESENCE
>   Pin-ctls: 0x40: OUT
>   Unsolicited: tag=00, enabled=0
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 3
>      0x10* 0x11 0x17
> Node 0x19 [Pin Complex] wcaps 0x400581: Stereo
>   Pincap 0x0000001c: OUT HP Detect
>   Pin Default 0x02214040: [Jack] HP Out at Ext Front
>     Conn = 1/8, Color = Green
>     DefAssociation = 0x4, Sequence = 0x0
>   Pin-ctls: 0xc0: OUT HP
>   Unsolicited: tag=37, enabled=1
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 3
>      0x10 0x11* 0x17
> Node 0x1a [Pin Complex] wcaps 0x40048b: Stereo Amp-In
>   Control: name="Front Mic Capture Volume", index=0, device=0
>     ControlAmp: chs=3, dir=In, idx=0, ofs=0
>   Amp-In caps: ofs=0x00, nsteps=0x04, stepsize=0x27, mute=0
>   Amp-In vals:  [0x04 0x04]
>   Pincap 0x00001324: IN Detect
>     Vref caps: HIZ 50 80
>   Pin Default 0x02a19020: [Jack] Mic at Ext Front
>     Conn = 1/8, Color = Pink
>     DefAssociation = 0x2, Sequence = 0x0
>   Pin-ctls: 0x24: IN VREF_80
>   Unsolicited: tag=00, enabled=0
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
> Node 0x1b [Pin Complex] wcaps 0x40058b: Stereo Amp-In
>   Control: name="Rear Mic Capture Volume", index=0, device=0
>     ControlAmp: chs=3, dir=In, idx=0, ofs=0
>   Amp-In caps: ofs=0x00, nsteps=0x04, stepsize=0x27, mute=0
>   Amp-In vals:  [0x04 0x04]
>   Pincap 0x00011334: IN OUT EAPD Detect
>     Vref caps: HIZ 50 80
>   EAPD 0x0:
>   Pin Default 0x01a1903e: [Jack] Mic at Ext Rear
>     Conn = 1/8, Color = Pink
>     DefAssociation = 0x3, Sequence = 0xe
>   Pin-ctls: 0x24: IN VREF_80
>   Unsolicited: tag=00, enabled=0
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 3
>      0x10* 0x11 0x17
> Node 0x1c [Pin Complex] wcaps 0x400581: Stereo
>   Pincap 0x0000001c: OUT HP Detect
>   Pin Default 0x01014010: [Jack] Line Out at Ext Rear
>     Conn = 1/8, Color = Green
>     DefAssociation = 0x1, Sequence = 0x0
>   Pin-ctls: 0x40: OUT
>   Unsolicited: tag=00, enabled=0
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 3
>      0x10* 0x11 0x17
> Node 0x1d [Pin Complex] wcaps 0x40058b: Stereo Amp-In
>   Control: name="Line Capture Volume", index=0, device=0
>     ControlAmp: chs=3, dir=In, idx=0, ofs=0
>   Amp-In caps: ofs=0x00, nsteps=0x04, stepsize=0x27, mute=0
>   Amp-In vals:  [0x04 0x04]
>   Pincap 0x00010034: IN OUT EAPD Detect
>   EAPD 0x0:
>   Pin Default 0x01813030: [Jack] Line In at Ext Rear
>     Conn = 1/8, Color = Blue
>     DefAssociation = 0x3, Sequence = 0x0
>   Pin-ctls: 0x20: IN
>   Unsolicited: tag=00, enabled=0
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 3
>      0x10* 0x11 0x17
> Node 0x1e [Pin Complex] wcaps 0x40048b: Stereo Amp-In
>   Amp-In caps: ofs=0x00, nsteps=0x04, stepsize=0x27, mute=0
>   Amp-In vals:  [0x00 0x00]
>   Pincap 0x00000024: IN Detect
>   Pin Default 0x40f001f0: [N/A] Other at Ext N/A
>     Conn = Unknown, Color = Unknown
>     DefAssociation = 0xf, Sequence = 0x0
>     Misc = NO_PRESENCE
>   Pin-ctls: 0x00:
>   Unsolicited: tag=00, enabled=0
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
> Node 0x1f [Pin Complex] wcaps 0x400501: Stereo
>   Pincap 0x00000010: OUT
>   Pin Default 0x9217011f: [Fixed] Speaker at Int Front
>     Conn = Analog, Color = Unknown
>     DefAssociation = 0x1, Sequence = 0xf
>     Misc = NO_PRESENCE
>   Pin-ctls: 0x40: OUT
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 3
>      0x10 0x11 0x17*
> Node 0x20 [Pin Complex] wcaps 0x400781: Stereo Digital
>   Pincap 0x00000014: OUT Detect
>   Pin Default 0x40f001f0: [N/A] Other at Ext N/A
>     Conn = Unknown, Color = Unknown
>     DefAssociation = 0xf, Sequence = 0x0
>     Misc = NO_PRESENCE
>   Pin-ctls: 0x00:
>   Unsolicited: tag=00, enabled=0
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 1
>      0x12
> Node 0x21 [Pin Complex] wcaps 0x400501: Stereo
>   Pincap 0x00010010: OUT EAPD
>   EAPD 0x0:
>   Pin Default 0x40f001f0: [N/A] Other at Ext N/A
>     Conn = Unknown, Color = Unknown
>     DefAssociation = 0xf, Sequence = 0x0
>     Misc = NO_PRESENCE
>   Pin-ctls: 0x40: OUT
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 3
>      0x10* 0x11 0x17
> Node 0x22 [Audio Mixer] wcaps 0x20050b: Stereo Amp-In
>   Amp-In caps: ofs=0x4a, nsteps=0x4a, stepsize=0x03, mute=1
>   Amp-In vals:  [0x00 0x00] [0x00 0x00] [0x00 0x00]
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 3
>      0x10 0x11 0x17
> Node 0x23 [Vendor Defined Widget] wcaps 0xf00000: Mono
> Node 0x24 [Volume Knob Widget] wcaps 0x600080: Mono
>   Volume-Knob: delta=1, steps=74, direct=0, val=60
>   Unsolicited: tag=00, enabled=0
>   Connection: 3
>      0x10 0x11 0x17
> Node 0x25 [Audio Input] wcaps 0x100711: Stereo Digital
>   Converter: stream=0, channel=0
>   SDI-Select: 0
>   Digital:
>   Digital category: 0x0
>   PCM:
>     rates [0x560]: 44100 48000 96000 192000
>     bits [0xe]: 16 20 24
>     formats [0x5]: PCM AC3
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
>   Connection: 1
>      0x26
> Node 0x26 [Pin Complex] wcaps 0x400681: Stereo Digital
>   Pincap 0x00000024: IN Detect
>   Pin Default 0x40f001f0: [N/A] Other at Ext N/A
>     Conn = Unknown, Color = Unknown
>     DefAssociation = 0xf, Sequence = 0x0
>     Misc = NO_PRESENCE
>   Pin-ctls: 0x00:
>   Unsolicited: tag=00, enabled=0
>   Power states:  D0 D1 D2 D3 EPSS
>   Power: setting=D0, actual=D0
> 


More information about the Alsa-devel mailing list