[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