[alsa-devel] [ALC668]: Asus N751JK - Incorrect default pin assignment for external base speaker and external microphone not working
Hi,
While being in the process of making my audio work on my new notebook, I noticed that the audio hardware is partially working out-of-the-Linux-kernel-box v4.0.7 Arch. The following two things seem not to work.
-------------------------------- 1. External base speaker --------------------------------
The Asus N751JK notebook (ALC668) has a small external 'base' speaker (jack 2,5mm 4 rings), which I only can get to work with the help of hdajackretask with the following setting:
* Override unconnected pin 0x1a and connect it to Internal Speaker (LFE).
In the sound kernel tree I have noticed PCI ID fixes which are more or less equal to this situation. https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/pci/...
This SND_PCI_QUIRK definition looks a lot like it: SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
The Vendor/PCI ID is different for this laptop and I guess a new line should be added something like this: SND_PCI_QUIRK(0x1043, 0x17bd, "Asus N751JK", ALC662_FIXUP_BASS_1A),
-------------------------------- 2. External microphone --------------------------------
The Asus N751JK notebook (ALC668) has a 3,5mm 4-ring combo jack for headphones and microphone. The headphone is detected correct and auto-mute works good (jack detection). The microphone is not detected and does not work.
I was unable to get it to work with hdajackretask or any of the Asus model settings, such as: * options snd_hda_intel model=,asus-mode4
I was able to get the microphone to work with the following setting: * options snd_hda_intel model=,dell-headset-multi
This setting creates two new items in PulseAudio making a total of three: * Internal microphone (works out of the box) * Headset microphone (works indeed with a headset) * Microphone (don't know if this works, since I don't have a single microphone, but it does not work with the headset)
Unfortunately the auto-input-device-switch to the Headset microphone does not seem to work. When I plugin a headset, the headphones get detected and the Internal speakers are muted. The Input device does not automatically switch from Internal microphone to Headset microphone. I have to do this manually, after which it works. I don't know if the microphone has a jack detection. If it does not, maybe it is possible to use the headphones jack detection?
I have added the alsa-info without any snd_intel / alsa modifications here: http://www.alsa-project.org/db/?f=0b5135bd12f28bb5cb182f83bfa21bc50022faa6
I don't mind to help to test, for example module options, patches and/or compile kernels.
Who is able and willing to help to fix this issue?
With kind regards, Arthur Borsboom.
-- Arthur Borsboom Email: arthurborsboom@gmail.com
While being in the process of making my audio work on my new notebook, I noticed that the audio hardware is partially working out-of-the-Linux-kernel-box v4.0.7 Arch. The following two things seem not to work.
- External base speaker
The Asus N751JK notebook (ALC668) has a small external 'base' speaker
(jack
2,5mm 4 rings), which I only can get to work with the help of
hdajackretask
with the following setting:
- Override unconnected pin 0x1a and connect it to Internal Speaker (LFE).
Can the external subwoofer be detected by any pin complex jack sense when plug and unplugged ?
hdajacksensetest -a
Since you are not always carry the external subwoofer and can save cpu power not to perform lfe filtering when subwoofer is not plugged
In the sound kernel tree I have noticed PCI ID fixes which are more or
less
equal to this situation.
https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/pci/...
This SND_PCI_QUIRK definition looks a lot like it: SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
The Vendor/PCI ID is different for this laptop and I guess a new line should be added something like this: SND_PCI_QUIRK(0x1043, 0x17bd, "Asus N751JK", ALC662_FIXUP_BASS_1A),
- External microphone
The Asus N751JK notebook (ALC668) has a 3,5mm 4-ring combo jack for headphones and microphone. The headphone is detected correct and auto-mute works good (jack
detection).
The microphone is not detected and does not work.
I was unable to get it to work with hdajackretask or any of the Asus model settings, such as:
- options snd_hda_intel model=,asus-mode4
I was able to get the microphone to work with the following setting:
- options snd_hda_intel model=,dell-headset-multi
This setting creates two new items in PulseAudio making a total of three:
- Internal microphone (works out of the box)
- Headset microphone (works indeed with a headset)
- Microphone (don't know if this works, since I don't have a single
microphone, but it does not work with the headset)
Seem user manual mention external mic is supported
If codec cannot differentitate headphone, headset or mic, you need manually switch the role of the combo jack from default headphone to headset everytime when you plugged your headset
http://voices.canonical.com/david.henningsson/2014/03/07/headset-jacks-on-ne...
Can user giveup some combo jack capability (remove the support of headphone and mic jack and only support headset ) by early patching to reenable auto mic selection ?
Unfortunately the auto-input-device-switch to the Headset microphone does not seem to work. When I plugin a headset, the headphones get detected and the Internal speakers are muted. The Input device does not automatically switch from Internal microphone to Headset microphone. I have to do this manually, after which it works. I don't know if the microphone has a jack detection. If it does not, maybe it is possible to use the headphones jack detection?
I have added the alsa-info without any snd_intel / alsa modifications
here:
http://www.alsa-project.org/db/?f=0b5135bd12f28bb5cb182f83bfa21bc50022faa6
I don't mind to help to test, for example module options, patches and/or compile kernels.
"hdajacksensetest -a" gives
Pin 0x05 ( Digital Out, HDMI): present = No Pin 0x06 ( Digital Out, HDMI): present = No Pin 0x07 (Not connected): present = No
which is a bit of a surprise to me, since at least the headphones (of the headset I plugin) has working jack detection. I would expect to see at least to have 1 non-HDMI pin connected.
----
Can user giveup some combo jack capability (remove the support of
headphone and mic jack and only support headset ) by early patching to reenable auto mic selection ?
To this I don't know the answer.
An image of the side with the different jacks: http://www.notebookcheck.net/fileadmin/Notebooks/Asus/N751JK-T4144H/rechts.j...
The yellow is the external speaker The one next to the USB ports is the headset with a logo of a headset and a microphone drawn in it.
On 2 July 2015 at 18:34, Raymond Yau superquad.vortex2@gmail.com wrote:
While being in the process of making my audio work on my new notebook, I noticed that the audio hardware is partially working out-of-the-Linux-kernel-box v4.0.7 Arch. The following two things seem
not
to work.
- External base speaker
The Asus N751JK notebook (ALC668) has a small external 'base' speaker
(jack
2,5mm 4 rings), which I only can get to work with the help of
hdajackretask
with the following setting:
- Override unconnected pin 0x1a and connect it to Internal Speaker (LFE).
Can the external subwoofer be detected by any pin complex jack sense when plug and unplugged ?
hdajacksensetest -a
Since you are not always carry the external subwoofer and can save cpu power not to perform lfe filtering when subwoofer is not plugged
In the sound kernel tree I have noticed PCI ID fixes which are more or
less
equal to this situation.
https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/tree/sound/pci/...
This SND_PCI_QUIRK definition looks a lot like it: SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
The Vendor/PCI ID is different for this laptop and I guess a new line should be added something like this: SND_PCI_QUIRK(0x1043, 0x17bd, "Asus N751JK", ALC662_FIXUP_BASS_1A),
- External microphone
The Asus N751JK notebook (ALC668) has a 3,5mm 4-ring combo jack for headphones and microphone. The headphone is detected correct and auto-mute works good (jack
detection).
The microphone is not detected and does not work.
I was unable to get it to work with hdajackretask or any of the Asus
model
settings, such as:
- options snd_hda_intel model=,asus-mode4
I was able to get the microphone to work with the following setting:
- options snd_hda_intel model=,dell-headset-multi
This setting creates two new items in PulseAudio making a total of three:
- Internal microphone (works out of the box)
- Headset microphone (works indeed with a headset)
- Microphone (don't know if this works, since I don't have a single
microphone, but it does not work with the headset)
Seem user manual mention external mic is supported
If codec cannot differentitate headphone, headset or mic, you need manually switch the role of the combo jack from default headphone to headset everytime when you plugged your headset
http://voices.canonical.com/david.henningsson/2014/03/07/headset-jacks-on-ne...
Can user giveup some combo jack capability (remove the support of headphone and mic jack and only support headset ) by early patching to reenable auto mic selection ?
Unfortunately the auto-input-device-switch to the Headset microphone does not seem to work. When I plugin a headset, the headphones get detected and the Internal speakers are muted. The Input device does not automatically switch from Internal microphone
to
Headset microphone. I have to do this manually, after which it works. I don't know if the microphone has a jack detection. If it does not, maybe it is possible to use the headphones jack
detection?
I have added the alsa-info without any snd_intel / alsa modifications
here:
http://www.alsa-project.org/db/?f=0b5135bd12f28bb5cb182f83bfa21bc50022faa6
I don't mind to help to test, for example module options, patches and/or compile kernels.
"hdajacksensetest -a" gives
Pin 0x05 ( Digital Out, HDMI): present = No Pin 0x06 ( Digital Out, HDMI): present = No Pin 0x07 (Not connected): present = No
which is a bit of a surprise to me, since at least the headphones (of the
headset I plugin) has working jack detection. I would expect to see at least to have 1 non-HDMI pin connected.
You need to specify card number
hdajacksensetest -c1 -a
If the external subwoofer can be detected with other unconnected pin complex instead of node 0x1a jack sense, you need to call snd_hda_jack_add_kctl in your fixup
snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, const char *name)
Can user giveup some combo jack capability (remove the support of
headphone and mic jack and only support headset ) by early patching to reenable auto mic selection ?
To this I don't know the answer.
An image of the side with the different jacks:
http://www.notebookcheck.net/fileadmin/Notebooks/Asus/N751JK-T4144H/rechts.j...
The yellow is the external speaker The one next to the USB ports is the headset with a logo of a headset and
a microphone drawn in it.
https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/commit/sound/pc...
[ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ + { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ + { } + }, + .chained = true, + .chain_id = ALC668_FIXUP_HEADSET_MODE + }, + [ALC668_FIXUP_HEADSET_MODE] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_headset_mode_alc668, + },
No need to change if you are using headphone since default is headphone
Support of Headphone mic can be removed by alc_fixup_headset_mode_no_hp_mic()
You need to hack the driver to set current_headset_type to cita or omtp instead of unknown
spec->current_headset_type = ALC_HEADSET_MODE_UNKNOWN;
The jack test gives
Without external speaker plugged in:
Pin 0x12 (Internal Mic): present = No Pin 0x14 (Internal Speaker): present = No Pin 0x15 (Black Headphone, Left side): present = No Pin 0x16 (Not connected): present = No Pin 0x18 (Not connected): present = No Pin 0x19 (Not connected): present = No Pin 0x1a (Not connected): present = No Pin 0x1b (Not connected): present = No Pin 0x1d (Not connected): present = No Pin 0x1e (Not connected): present = No Pin 0x1f (Not connected): present = No
With external speaker plugged in:
Pin 0x12 (Internal Mic): present = No Pin 0x14 (Internal Speaker): present = No Pin 0x15 (Black Headphone, Left side): present = No Pin 0x16 (Not connected): present = No Pin 0x18 (Not connected): present = No Pin 0x19 (Not connected): present = No Pin 0x1a (Not connected): present = Yes Pin 0x1b (Not connected): present = No Pin 0x1d (Not connected): present = No Pin 0x1e (Not connected): present = No Pin 0x1f (Not connected): present = No
For the other parts, I lack the experience. I have just set up a test environment, so I can recompile and test kernels without breaking my main system.
If you have any patches to suggest and test (for the external speaker and the auto switch of headset), I am all ears. If not, I will try to dig in it myself.
On 3 July 2015 at 04:20, Raymond Yau superquad.vortex2@gmail.com wrote:
"hdajacksensetest -a" gives
Pin 0x05 ( Digital Out, HDMI): present = No Pin 0x06 ( Digital Out, HDMI): present = No Pin 0x07 (Not connected): present = No
which is a bit of a surprise to me, since at least the headphones (of
the headset I plugin) has working jack detection. I would expect to see at least to have 1 non-HDMI pin connected.
You need to specify card number
hdajacksensetest -c1 -a
If the external subwoofer can be detected with other unconnected pin complex instead of node 0x1a jack sense, you need to call snd_hda_jack_add_kctl in your fixup
snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, const char *name)
Can user giveup some combo jack capability (remove the support of
headphone and mic jack and only support headset ) by early patching to reenable auto mic selection ?
To this I don't know the answer.
An image of the side with the different jacks:
http://www.notebookcheck.net/fileadmin/Notebooks/Asus/N751JK-T4144H/rechts.j...
The yellow is the external speaker The one next to the USB ports is the headset with a logo of a headset
and a microphone drawn in it.
https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/commit/sound/pc...
[ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
- .type = HDA_FIXUP_PINS,
- .v.pins = (const struct hda_pintbl[]) {
- { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack
detect */
- { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect
*/
- { }
- },
- .chained = true,
- .chain_id = ALC668_FIXUP_HEADSET_MODE
- },
- [ALC668_FIXUP_HEADSET_MODE] = {
- .type = HDA_FIXUP_FUNC,
- .v.func = alc_fixup_headset_mode_alc668,
- },
No need to change if you are using headphone since default is headphone
Support of Headphone mic can be removed by alc_fixup_headset_mode_no_hp_mic()
You need to hack the driver to set current_headset_type to cita or omtp instead of unknown
spec->current_headset_type = ALC_HEADSET_MODE_UNKNOWN;
2015-7-4 上午5:03於 "Arthur Borsboom" arthurborsboom@gmail.com寫道:
The jack test gives
Without external speaker plugged in:
Pin 0x12 (Internal Mic): present = No Pin 0x14 (Internal Speaker): present = No Pin 0x15 (Black Headphone, Left side): present = No Pin 0x16 (Not connected): present = No Pin 0x18 (Not connected): present = No Pin 0x19 (Not connected): present = No Pin 0x1a (Not connected): present = No Pin 0x1b (Not connected): present = No Pin 0x1d (Not connected): present = No Pin 0x1e (Not connected): present = No Pin 0x1f (Not connected): present = No
With external speaker plugged in:
Pin 0x12 (Internal Mic): present = No Pin 0x14 (Internal Speaker): present = No Pin 0x15 (Black Headphone, Left side): present = No Pin 0x16 (Not connected): present = No Pin 0x18 (Not connected): present = No Pin 0x19 (Not connected): present = No Pin 0x1a (Not connected): present = Yes Pin 0x1b (Not connected): present = No Pin 0x1d (Not connected): present = No Pin 0x1e (Not connected): present = No Pin 0x1f (Not connected): present = No
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8e02cdf..174c5e5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6179,6 +6179,8 @@ enum { ALC668_FIXUP_AUTO_MUTE, ALC668_FIXUP_DELL_DISABLE_AAMIX, ALC668_FIXUP_DELL_XPS13, + ALC668_FIXUP_BASS_CHMAP, + ALC668_FIXUP_ASUS_N751JK, };
static const struct hda_fixup alc662_fixups[] = { @@ -6419,6 +6421,23 @@ static const struct hda_fixup alc662_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_bass_chmap, }, + [ALC668_FIXUP_BASS_CHMAP] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc_fixup_bass_chmap, + .chained = true, + .chain_id = ALC668_FIXUP_HEADSET_MODE + }, + [ALC668_FIXUP_ASUS_N751JK] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ + { 0x1a, 0x04110011 }, /* bass speaker at Ext Right with jack detect */ + { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ + {} + }, + .chained = true, + .chain_id = ALC668_FIXUP_BASS_CHMAP, + }, };
static const struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -6441,6 +6460,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), + SND_PCI_QUIRK(0x1043, 0x17bd, "Asus N751JK", ALC668_FIXUP_ASUS_N751JK), SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
I have tested the patch by manually adding the lines of code into mainline kernel 4.1.1.
The base speakers works. The headset microphone works. The headphone, headset microphone and microphone jack detection seems to work in PulseAudio (showing by plugged or unplugged status). However it does not automatically switch the (un)plugged microphone. My guess is that it does not know if it should use the headset microphone or the microphone (instead of the default internal microphone).
Do you think there is a way to automate the forward and backward switching between the internal microphone and headset microphone?
On 4 July 2015 at 07:56, Raymond Yau superquad.vortex2@gmail.com wrote:
2015-7-4 上午5:03於 "Arthur Borsboom" arthurborsboom@gmail.com寫道:
The jack test gives
Without external speaker plugged in:
Pin 0x12 (Internal Mic): present = No Pin 0x14 (Internal Speaker): present = No Pin 0x15 (Black Headphone, Left side): present = No Pin 0x16 (Not connected): present = No Pin 0x18 (Not connected): present = No Pin 0x19 (Not connected): present = No Pin 0x1a (Not connected): present = No Pin 0x1b (Not connected): present = No Pin 0x1d (Not connected): present = No Pin 0x1e (Not connected): present = No Pin 0x1f (Not connected): present = No
With external speaker plugged in:
Pin 0x12 (Internal Mic): present = No Pin 0x14 (Internal Speaker): present = No Pin 0x15 (Black Headphone, Left side): present = No Pin 0x16 (Not connected): present = No Pin 0x18 (Not connected): present = No Pin 0x19 (Not connected): present = No Pin 0x1a (Not connected): present = Yes Pin 0x1b (Not connected): present = No Pin 0x1d (Not connected): present = No Pin 0x1e (Not connected): present = No Pin 0x1f (Not connected): present = No
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8e02cdf..174c5e5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6179,6 +6179,8 @@ enum { ALC668_FIXUP_AUTO_MUTE, ALC668_FIXUP_DELL_DISABLE_AAMIX, ALC668_FIXUP_DELL_XPS13,
- ALC668_FIXUP_BASS_CHMAP,
- ALC668_FIXUP_ASUS_N751JK,
};
static const struct hda_fixup alc662_fixups[] = { @@ -6419,6 +6421,23 @@ static const struct hda_fixup alc662_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_bass_chmap, },
- [ALC668_FIXUP_BASS_CHMAP] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_bass_chmap,
.chained = true,
.chain_id = ALC668_FIXUP_HEADSET_MODE
- },
- [ALC668_FIXUP_ASUS_N751JK] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x19, 0x03a1913d }, /* use as headphone mic, without its
own jack detect */
{ 0x1a, 0x04110011 }, /* bass speaker at Ext Right with jack
detect */
{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own
jack detect */
{}
},
.chained = true,
.chain_id = ALC668_FIXUP_BASS_CHMAP,
- },
};
static const struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -6441,6 +6460,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
- SND_PCI_QUIRK(0x1043, 0x17bd, "Asus N751JK",
ALC668_FIXUP_ASUS_N751JK), SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
I have tested the patch by manually adding the lines of code into
mainline kernel 4.1.1.
The base speakers works.
Do you need special name for the external subwoofer jack detect control for pulseaudio automatically switch from stereo profile to 2.1 profile ?
int snd_hda_jack_add_kctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { const hda_nid_t *p; int i, err;
...
for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { + if (cfg->line_outs == 2 && i == 1) + err = add_jack_kctl(codec, *p, cfg, "External Subwoofer"); + else err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) return err; }
The headset microphone works. The headphone, headset microphone and microphone jack detection seems to
work in PulseAudio (showing by plugged or unplugged status).
However it does not automatically switch the (un)plugged microphone. My guess is that it does not know if it should use the headset microphone
or the microphone (instead of the default internal microphone).
Do you think there is a way to automate the forward and backward
switching between the internal microphone and headset microphone?
http://bazaar.launchpad.net/~unity-settings-daemon-team/unity-settings-daemo...
Headphone Mic Jack - indicates headphone and mic-in mode share the same jack, i e, not two separate jacks. Hardware cannot distinguish between headphone and a mic. Headset Mic Phantom Jack - indicates headset jack where hardware can not distinguish between headphones and headsets Headset Mic Jack - indicates headset jack where hardware can distinguish between headphones and headsets. There is no use popping up a dialog in this case, unless we already need to do this for the mic-in mode.
Auto mic need headset mic support jack detection
There are two methods, both methods need to give up the capability of using headphone and mic
cannot use hint for user to select this feature since user hint is applied after pin fixup
1) create headset mic jack as slave of headphone jack , this use headphone jack sense for the jack state of headset mic
spec->gen.combo_use_only_as_headset = 0;
2) change headphone jack to headset jack, this require add [Element Headset] to pulseaudio conf files
spec->gen.headset_and_no_hp = 0;
Method 1 -
Cons - hda-emu cannot emulate this master slave jack ctl and gated/gating jack ctl
Method 2
Cons - some notebook has
a) headset and headphone jacks
b)r headset and dock headset
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index ac0db16..7e9b7ae 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -4384,6 +4384,9 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, /* don't detect pins retasked as outputs */ if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN) continue; + if (pin == spec->headset_mic_pin) + if (spec->headset_and_no_hp) + pin = spec->autocfg.hp_pins[0]; if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) { mux_select(codec, 0, spec->am_entry[i].idx); return; diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 56e4139..4c3e043 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -236,6 +236,10 @@ struct hda_gen_spec { unsigned int indep_hp_enabled:1; /* independent HP enabled */ unsigned int have_aamix_ctl:1; unsigned int hp_mic_jack_modes:1; + unsigned int combo_use_only_as_headset:1; /* headphone mic jack - slave of headphone jack */ + unsigned int headset_and_no_hp:1; /* headset jack */ + + hda_nid_t headset_mic_pin;
/* additional mute flags (only effective with auto_mute_via_amp=1) */ u64 mute_bits; diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 366efbf..771e84f 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -19,6 +19,7 @@ #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_jack.h" +#include "hda_generic.h"
/** * is_jack_detectable - Check whether the given pin is jack-detectable @@ -157,7 +158,10 @@ static void jack_detect_update(struct hda_codec *codec, if (jack->phantom_jack) jack->pin_sense = AC_PINSENSE_PRESENCE; else - jack->pin_sense = read_pin_sense(codec, jack->nid); + if (jack->master_nid) + jack->pin_sense = read_pin_sense(codec, jack->master_nid); + else + jack->pin_sense = read_pin_sense(codec, jack->nid);
/* A gating jack indicates the jack is invalid if gating is unplugged */ if (jack->gating_jack && !snd_hda_jack_detect(codec, jack->gating_jack)) @@ -205,11 +209,20 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_set_dirty_all); u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) { struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); + struct hda_jack_tbl *slave; + u32 sense; if (jack) { jack_detect_update(codec, jack); return jack->pin_sense; } - return read_pin_sense(codec, nid); + if (jack->master_nid) + return read_pin_sense(codec, jack->master_nid); + sense = read_pin_sense(codec, nid); + if (jack->slave_nid) { + slave = snd_hda_jack_tbl_get(codec, jack->slave_nid); + slave->pin_sense = sense; + } + return sense; } EXPORT_SYMBOL_GPL(snd_hda_pin_sense);
@@ -317,6 +330,28 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack);
/** + * snd_hda_jack_set_master_slave + * @codec: the HDA codec + * @master_nid: use this nid for pin sense + * @slave_nid: update slave jack pin sense + * use master pin sense for slave pin sense + */ +int snd_hda_jack_set_master_slave(struct hda_codec *codec, hda_nid_t master_nid, + hda_nid_t slave_nid) +{ + struct hda_jack_tbl *master = snd_hda_jack_tbl_get(codec, master_nid); + struct hda_jack_tbl *slave = snd_hda_jack_tbl_get(codec, slave_nid); + if (master) + master->slave_nid = slave_nid; + if (slave) { + slave->master_nid = master_nid; + snd_hda_codec_write_cache(codec, slave_nid, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, 0); + } + return 0; +} + +/** * snd_hda_jack_report_sync - sync the states of all jacks and report if changed * @codec: the HDA codec */ @@ -469,7 +504,8 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { const hda_nid_t *p; - int i, err; + int i, err, loc; + struct hda_gen_spec *spec = codec->spec;
for (i = 0; i < cfg->num_inputs; i++) { /* If we have headphone mics; make sure they get the right name @@ -481,22 +517,37 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, else err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, "Headphone Mic"); - } else - err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, + } else { + if (cfg->inputs[i].is_headset_mic) { + if (!spec->headset_and_no_hp) + err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, NULL); + else + err = 0; + } + else + err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, NULL); + } if (err < 0) return err; }
for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { - err = add_jack_kctl(codec, *p, cfg, NULL); + loc = get_defcfg_location(get_wcaps(codec, *p)); + if (i == 1 && cfg->line_outs == 2 && loc == AC_JACK_LOC_EXTERNAL) + err = add_jack_kctl(codec, *p, cfg, "External Subwoofer"); + else + err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) return err; } for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { if (*p == *cfg->line_out_pins) /* might be duplicated */ break; - err = add_jack_kctl(codec, *p, cfg, NULL); + if (spec->headset_and_no_hp && i == 0) + err = add_jack_kctl(codec, *p, cfg, "Headset"); + else + err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) return err; } @@ -507,6 +558,13 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, if (err < 0) return err; } + + if (spec->combo_use_only_as_headset) + for (i = 0; i < cfg->num_inputs; i++) { + if (cfg->inputs[i].is_headset_mic) + snd_hda_jack_set_master_slave(codec, cfg->hp_pins[0], cfg->inputs[i].pin); + } + for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index 387d309..364cfa5 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h @@ -39,6 +39,8 @@ struct hda_jack_tbl { unsigned int block_report:1; /* in a transitional state - do not report to userspace */ hda_nid_t gating_jack; /* valid when gating jack plugged */ hda_nid_t gated_jack; /* gated is dependent on this jack */ + hda_nid_t master_nid; /* use master_nid for jack sense */ + hda_nid_t slave_nid; /* update slave_nid jack state */ int type; struct snd_jack *jack; }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8e02cdf..598a442 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3998,6 +3998,16 @@ static void alc_update_headset_mode(struct hda_codec *codec) return; }
+ if (spec->gen.combo_use_only_as_headset || + spec->gen.headset_and_no_hp) { + if (snd_hda_jack_detect(codec, hp_pin)) { + new_headset_mode = ALC_HEADSET_MODE_HEADSET; + alc_determine_headset_type(codec); + codec_info(codec, "mic_autoswitch\n"); + snd_hda_gen_mic_autoswitch(codec, NULL); + } + } + switch (new_headset_mode) { case ALC_HEADSET_MODE_UNPLUGGED: alc_headset_mode_unplugged(codec); @@ -4056,8 +4066,10 @@ static void alc_probe_headset_mode(struct hda_codec *codec)
/* Find mic pins */ for (i = 0; i < cfg->num_inputs; i++) { - if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) + if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) { spec->headset_mic_pin = cfg->inputs[i].pin; + spec->gen.headset_mic_pin = spec->headset_mic_pin; + } if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) spec->headphone_mic_pin = cfg->inputs[i].pin; } @@ -4074,7 +4086,11 @@ static void alc_fixup_headset_mode(struct hda_codec *codec,
switch (action) { case HDA_FIXUP_ACT_PRE_PROBE: - spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; + if (spec->gen.combo_use_only_as_headset || + spec->gen.headset_and_no_hp) + spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; + else + spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; break; case HDA_FIXUP_ACT_PROBE: alc_probe_headset_mode(codec); @@ -6149,6 +6165,43 @@ static void alc668_restore_default_value(struct hda_codec *codec) alc_process_coef_fw(codec, alc668_coefs); }
+static void alc668_fixup_asus_n751jk(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + static const struct hda_pintbl normal_cfgs[] = { + { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ + { 0x1a, 0x04110011 }, /* bass speaker at Ext Right with jack detect */ + { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ + { } + }; + static const struct hda_pintbl headset_cfgs[] = { + { 0x19, 0x411111f0 }, /* N/A */ + { 0x1a, 0x04110011 }, /* bass speaker at Ext Right with jack detect */ + { 0x1b, 0x03a1103c }, /* use as headset mic, without its own jack detect */ + { } + }; + switch(action){ + case HDA_FIXUP_ACT_PRE_PROBE: + spec->gen.combo_use_only_as_headset = 0; + spec->gen.headset_and_no_hp = 0; + codec_info(codec, "use as headset %d\n", spec->gen.combo_use_only_as_headset); + if (spec->gen.combo_use_only_as_headset || + spec->gen.headset_and_no_hp) { + snd_hda_apply_pincfgs(codec, headset_cfgs); + spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; + } + else { + snd_hda_apply_pincfgs(codec, normal_cfgs); + spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; + } + break; + case HDA_FIXUP_ACT_BUILD: + alc_fixup_bass_chmap(codec, fix, action); + break; + } +} + enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_LED_GPIO1, @@ -6179,6 +6232,7 @@ enum { ALC668_FIXUP_AUTO_MUTE, ALC668_FIXUP_DELL_DISABLE_AAMIX, ALC668_FIXUP_DELL_XPS13, + ALC668_FIXUP_ASUS_N751JK, };
static const struct hda_fixup alc662_fixups[] = { @@ -6419,6 +6473,12 @@ static const struct hda_fixup alc662_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_bass_chmap, }, + [ALC668_FIXUP_ASUS_N751JK] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc668_fixup_asus_n751jk, + .chained = true, + .chain_id = ALC668_FIXUP_HEADSET_MODE, + }, };
static const struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -6441,6 +6501,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), + SND_PCI_QUIRK(0x1043, 0x17bd, "Asus N751JK", ALC668_FIXUP_ASUS_N751JK), SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
Hi Raymond,
First I think I am going to split this mail into two topics, starting with the easiest one, the External Base speaker.
The code above added two new options: Surround 2.1 and Surround 4.0. After plugging in the base speaker:
- The Base speaker plays without this code (but the previous code was necessary) on the Speakers. - The Base speaker does not play on Surround 2.1 - The Base speaker does play on Surround 4.0 - The Base speaker does not switch automatically to any Surround when plugged in.
Recently I have been developing against the mainline Kernel 4.2-rc1, but it gives me only kernel panics. Than I realized that I should develop against the Alsa tree. What is the best tree to develop patches against?
On 6 July 2015 at 05:19, Raymond Yau superquad.vortex2@gmail.com wrote:
I have tested the patch by manually adding the lines of code into
mainline kernel 4.1.1.
The base speakers works.
Do you need special name for the external subwoofer jack detect control for pulseaudio automatically switch from stereo profile to 2.1 profile ?
int snd_hda_jack_add_kctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { const hda_nid_t *p; int i, err;
...
for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
if (cfg->line_outs == 2 && i == 1)
err = add_jack_kctl(codec, *p, cfg, "External Subwoofer");
else
err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) return err; }
The headset microphone works. The headphone, headset microphone and microphone jack detection seems to
work in PulseAudio (showing by plugged or unplugged status).
However it does not automatically switch the (un)plugged microphone. My guess is that it does not know if it should use the headset
microphone or the microphone (instead of the default internal microphone).
Do you think there is a way to automate the forward and backward
switching between the internal microphone and headset microphone?
http://bazaar.launchpad.net/~unity-settings-daemon-team/unity-settings-daemo...
Headphone Mic Jack - indicates headphone and mic-in mode share the same jack, i e, not two separate jacks. Hardware cannot distinguish between headphone and a mic. Headset Mic Phantom Jack - indicates headset jack where hardware can not distinguish between headphones and headsets Headset Mic Jack - indicates headset jack where hardware can distinguish between headphones and headsets. There is no use popping up a dialog in this case, unless we already need to do this for the mic-in mode.
Auto mic need headset mic support jack detection
There are two methods, both methods need to give up the capability of using headphone and mic
cannot use hint for user to select this feature since user hint is applied after pin fixup
- create headset mic jack as slave of headphone jack , this use headphone
jack sense for the jack state of headset mic
spec->gen.combo_use_only_as_headset = 0;
- change headphone jack to headset jack, this require add [Element
Headset] to pulseaudio conf files
spec->gen.headset_and_no_hp = 0;
Method 1 -
Cons - hda-emu cannot emulate this master slave jack ctl and gated/gating jack ctl
Method 2
Cons - some notebook has
a) headset and headphone jacks
b)r headset and dock headset
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index ac0db16..7e9b7ae 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -4384,6 +4384,9 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, /* don't detect pins retasked as outputs */ if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN) continue;
if (pin == spec->headset_mic_pin)
if (spec->headset_and_no_hp)
pin = spec->autocfg.hp_pins[0]; if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) { mux_select(codec, 0, spec->am_entry[i].idx); return;
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 56e4139..4c3e043 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -236,6 +236,10 @@ struct hda_gen_spec { unsigned int indep_hp_enabled:1; /* independent HP enabled */ unsigned int have_aamix_ctl:1; unsigned int hp_mic_jack_modes:1;
- unsigned int combo_use_only_as_headset:1; /* headphone mic jack -
slave of headphone jack */
unsigned int headset_and_no_hp:1; /* headset jack */
hda_nid_t headset_mic_pin;
/* additional mute flags (only effective with auto_mute_via_amp=1) */ u64 mute_bits;
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 366efbf..771e84f 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -19,6 +19,7 @@ #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_jack.h" +#include "hda_generic.h"
/**
- is_jack_detectable - Check whether the given pin is jack-detectable
@@ -157,7 +158,10 @@ static void jack_detect_update(struct hda_codec *codec, if (jack->phantom_jack) jack->pin_sense = AC_PINSENSE_PRESENCE; else
jack->pin_sense = read_pin_sense(codec, jack->nid);
if (jack->master_nid)
jack->pin_sense = read_pin_sense(codec, jack->master_nid);
else
jack->pin_sense = read_pin_sense(codec, jack->nid);
/* A gating jack indicates the jack is invalid if gating is unplugged
*/ if (jack->gating_jack && !snd_hda_jack_detect(codec, jack->gating_jack)) @@ -205,11 +209,20 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_set_dirty_all); u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) { struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
- struct hda_jack_tbl *slave;
- u32 sense; if (jack) { jack_detect_update(codec, jack); return jack->pin_sense; }
- return read_pin_sense(codec, nid);
- if (jack->master_nid)
return read_pin_sense(codec, jack->master_nid);
- sense = read_pin_sense(codec, nid);
- if (jack->slave_nid) {
slave = snd_hda_jack_tbl_get(codec, jack->slave_nid);
slave->pin_sense = sense;
- }
- return sense;
} EXPORT_SYMBOL_GPL(snd_hda_pin_sense);
@@ -317,6 +330,28 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack);
/**
- snd_hda_jack_set_master_slave
- @codec: the HDA codec
- @master_nid: use this nid for pin sense
- @slave_nid: update slave jack pin sense
- use master pin sense for slave pin sense
- */
+int snd_hda_jack_set_master_slave(struct hda_codec *codec, hda_nid_t master_nid,
hda_nid_t slave_nid)
+{
- struct hda_jack_tbl *master = snd_hda_jack_tbl_get(codec, master_nid);
- struct hda_jack_tbl *slave = snd_hda_jack_tbl_get(codec, slave_nid);
- if (master)
master->slave_nid = slave_nid;
- if (slave) {
slave->master_nid = master_nid;
snd_hda_codec_write_cache(codec, slave_nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE, 0);
- }
- return 0;
+}
+/**
- snd_hda_jack_report_sync - sync the states of all jacks and report if
changed
- @codec: the HDA codec
*/ @@ -469,7 +504,8 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { const hda_nid_t *p;
- int i, err;
int i, err, loc;
struct hda_gen_spec *spec = codec->spec;
for (i = 0; i < cfg->num_inputs; i++) { /* If we have headphone mics; make sure they get the right name
@@ -481,22 +517,37 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, else err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, "Headphone Mic");
} else
err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg,
} else {
if (cfg->inputs[i].is_headset_mic) {
if (!spec->headset_and_no_hp)
err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg,
NULL);
else
err = 0;
}
else
err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, NULL);
} if (err < 0) return err;
}
for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
err = add_jack_kctl(codec, *p, cfg, NULL);
loc = get_defcfg_location(get_wcaps(codec, *p));
if (i == 1 && cfg->line_outs == 2 && loc == AC_JACK_LOC_EXTERNAL)
err = add_jack_kctl(codec, *p, cfg, "External Subwoofer");
else
} for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { if (*p == *cfg->line_out_pins) /* might be duplicated */ break;err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) return err;
err = add_jack_kctl(codec, *p, cfg, NULL);
if (spec->headset_and_no_hp && i == 0)
err = add_jack_kctl(codec, *p, cfg, "Headset");
else
}err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) return err;
@@ -507,6 +558,13 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, if (err < 0) return err; }
- if (spec->combo_use_only_as_headset)
for (i = 0; i < cfg->num_inputs; i++) {
if (cfg->inputs[i].is_headset_mic)
snd_hda_jack_set_master_slave(codec, cfg->hp_pins[0],
cfg->inputs[i].pin);
}
- for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0)
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index 387d309..364cfa5 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h @@ -39,6 +39,8 @@ struct hda_jack_tbl { unsigned int block_report:1; /* in a transitional state - do not report to userspace */ hda_nid_t gating_jack; /* valid when gating jack plugged */ hda_nid_t gated_jack; /* gated is dependent on this jack */
- hda_nid_t master_nid; /* use master_nid for jack sense */
- hda_nid_t slave_nid; /* update slave_nid jack state */ int type; struct snd_jack *jack;
}; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8e02cdf..598a442 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3998,6 +3998,16 @@ static void alc_update_headset_mode(struct hda_codec *codec) return; }
- if (spec->gen.combo_use_only_as_headset ||
spec->gen.headset_and_no_hp) {
if (snd_hda_jack_detect(codec, hp_pin)) {
new_headset_mode = ALC_HEADSET_MODE_HEADSET;
alc_determine_headset_type(codec);
codec_info(codec, "mic_autoswitch\n");
snd_hda_gen_mic_autoswitch(codec, NULL);
}
- }
- switch (new_headset_mode) { case ALC_HEADSET_MODE_UNPLUGGED: alc_headset_mode_unplugged(codec);
@@ -4056,8 +4066,10 @@ static void alc_probe_headset_mode(struct hda_codec *codec)
/* Find mic pins */ for (i = 0; i < cfg->num_inputs; i++) {
if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) { spec->headset_mic_pin = cfg->inputs[i].pin;
spec->gen.headset_mic_pin = spec->headset_mic_pin;
}} if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) spec->headphone_mic_pin = cfg->inputs[i].pin;
@@ -4074,7 +4086,11 @@ static void alc_fixup_headset_mode(struct hda_codec *codec,
switch (action) { case HDA_FIXUP_ACT_PRE_PROBE:
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC |
HDA_PINCFG_HEADPHONE_MIC;
if (spec->gen.combo_use_only_as_headset ||
spec->gen.headset_and_no_hp)
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
else
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC |
HDA_PINCFG_HEADPHONE_MIC; break; case HDA_FIXUP_ACT_PROBE: alc_probe_headset_mode(codec); @@ -6149,6 +6165,43 @@ static void alc668_restore_default_value(struct hda_codec *codec) alc_process_coef_fw(codec, alc668_coefs); }
+static void alc668_fixup_asus_n751jk(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
+{
- struct alc_spec *spec = codec->spec;
- static const struct hda_pintbl normal_cfgs[] = {
{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own
jack detect */
{ 0x1a, 0x04110011 }, /* bass speaker at Ext Right with jack
detect */
{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack
detect */
{ }
- };
- static const struct hda_pintbl headset_cfgs[] = {
{ 0x19, 0x411111f0 }, /* N/A */
{ 0x1a, 0x04110011 }, /* bass speaker at Ext Right with jack
detect */
{ 0x1b, 0x03a1103c }, /* use as headset mic, without its own jack
detect */
{ }
- };
- switch(action){
- case HDA_FIXUP_ACT_PRE_PROBE:
spec->gen.combo_use_only_as_headset = 0;
spec->gen.headset_and_no_hp = 0;
codec_info(codec, "use as headset %d\n",
spec->gen.combo_use_only_as_headset);
if (spec->gen.combo_use_only_as_headset ||
spec->gen.headset_and_no_hp) {
snd_hda_apply_pincfgs(codec, headset_cfgs);
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
}
else {
snd_hda_apply_pincfgs(codec, normal_cfgs);
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC |
HDA_PINCFG_HEADPHONE_MIC;
}
break;
- case HDA_FIXUP_ACT_BUILD:
alc_fixup_bass_chmap(codec, fix, action);
break;
- }
+}
enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_LED_GPIO1, @@ -6179,6 +6232,7 @@ enum { ALC668_FIXUP_AUTO_MUTE, ALC668_FIXUP_DELL_DISABLE_AAMIX, ALC668_FIXUP_DELL_XPS13,
- ALC668_FIXUP_ASUS_N751JK,
};
static const struct hda_fixup alc662_fixups[] = { @@ -6419,6 +6473,12 @@ static const struct hda_fixup alc662_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_bass_chmap, },
- [ALC668_FIXUP_ASUS_N751JK] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc668_fixup_asus_n751jk,
.chained = true,
.chain_id = ALC668_FIXUP_HEADSET_MODE,
- },
};
static const struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -6441,6 +6501,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
- SND_PCI_QUIRK(0x1043, 0x17bd, "Asus N751JK",
ALC668_FIXUP_ASUS_N751JK), SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
First I think I am going to split this mail into two topics, starting
with the easiest one, the External Base speaker.
The code above added two new options: Surround 2.1 and Surround 4.0. After plugging in the base speaker:
- The Base speaker plays without this code (but the previous code was
necessary) on the Speakers.
- The Base speaker does not play on Surround 2.1
- The Base speaker does play on Surround 4.0
- The Base speaker does not switch automatically to any Surround when
plugged in.
How do you test ? Using sound preference or alsa speaker-test
https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/commit/sound/pc...
Seem pulseaudio bug since driver only define stereo and 2.1 channel map and there is no surround 4.0 channel map
http://git.alsa-project.org/?p=alsa-lib.git;a=commitdiff;h=48f1b308cc66152eb...
+ ttable.0.FL 1 + ttable.1.FR 1 + ttable.2.LFE 1
surround21 is supposed to be also used on 5.1 speaker since it only check
Do you mean it only work on 5.1 speaker since there are three combination of 2.1 chmap ?
https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/commit/sound?id...
1) hda default 2.1
{ .channels = 4, .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE , SNDRV_CHMAP_LFE } }, { }
2) acer aspire /* LFE only on left */
{ .channels = 4, .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, SNDRV_CHMAP_NA} }, /* LFE only on left */ { }
3) LFE only on right on asus latop external sonic master subwoofer { .channels = 4, .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ { }
speaker-test don't check channel map
Those asus n series laptop with alc663 seem use node 0x1e to for the detection of external subwoofer but node 0x1e pincap does not support detect and unsol event
This mean those subwoofer need to use __snd_hda_jack_add_kctl() which does not check pincap and unsol event
This require change of __snd_hda_jack_add_kctl() by adding new parameter sense_nid to use another nid for jack sense without enable unsol event
However there is bug in hda_jack implementation , snd_hda_jack_detect() can be called in patch_realtek.c before creation of the jacktbl entry (i.e. before snd_hda_jack_add_kctls()
https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1040873/comments/...
Did you found the message " lfe filter activated (LR4 type)" in pulseaudio verbose log ?
Hi Raymond,
Honestly some of the Alsa code talk is a bit over my head, so maybe I should just stick to providing PCI/Vendor ID's and test results. :)
RY> How do you test ? Using sound preference or alsa speaker-test
I apply some of your code by retyping this into the mainline kernel 4.2-rc1 code, compile and install the kernel, and then test the audio. The subwoofer I test by playing music with my music player, Audacious. When testing different configurations and output profiles I use pavucontrol. For testing the microphone, I open pavucontrol, switch the input source between Internal Microphone and Microphone and look at the volumebar to see if the microphone works fine.
Do you have suggestions how to apply and test the provided patches?
On 10 July 2015 at 09:49, Raymond Yau superquad.vortex2@gmail.com wrote:
First I think I am going to split this mail into two topics, starting
with the easiest one, the External Base speaker.
The code above added two new options: Surround 2.1 and Surround 4.0. After plugging in the base speaker:
- The Base speaker plays without this code (but the previous code was
necessary) on the Speakers.
- The Base speaker does not play on Surround 2.1
- The Base speaker does play on Surround 4.0
- The Base speaker does not switch automatically to any Surround when
plugged in.
How do you test ? Using sound preference or alsa speaker-test
https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/commit/sound/pc...
Seem pulseaudio bug since driver only define stereo and 2.1 channel map and there is no surround 4.0 channel map
http://git.alsa-project.org/?p=alsa-lib.git;a=commitdiff;h=48f1b308cc66152eb...
ttable.0.FL 1
ttable.1.FR 1
ttable.2.LFE 1
surround21 is supposed to be also used on 5.1 speaker since it only check
Do you mean it only work on 5.1 speaker since there are three combination of 2.1 chmap ?
https://git.kernel.org/cgit/linux/kernel/git/tiwai/sound.git/commit/sound?id...
- hda default 2.1
{ .channels = 4, .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE , SNDRV_CHMAP_LFE } }, { }
- acer aspire /* LFE only on left */
{ .channels = 4, .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE, SNDRV_CHMAP_NA} }, /* LFE only on left */ { }
- LFE only on right on asus latop external sonic master subwoofer
{ .channels = 4, .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ { }
speaker-test don't check channel map
Those asus n series laptop with alc663 seem use node 0x1e to for the detection of external subwoofer but node 0x1e pincap does not support detect and unsol event
This mean those subwoofer need to use __snd_hda_jack_add_kctl() which does not check pincap and unsol event
This require change of __snd_hda_jack_add_kctl() by adding new parameter sense_nid to use another nid for jack sense without enable unsol event
However there is bug in hda_jack implementation , snd_hda_jack_detect() can be called in patch_realtek.c before creation of the jacktbl entry (i.e. before snd_hda_jack_add_kctls()
https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1040873/comments/...
Did you found the message " lfe filter activated (LR4 type)" in pulseaudio verbose log ?
Honestly some of the Alsa code talk is a bit over my head, so maybe I
should just stick to providing PCI/Vendor ID's and test results. :)
RY> How do you test ? Using sound preference or alsa speaker-test
I apply some of your code by retyping this into the mainline kernel
4.2-rc1 code, compile and install the kernel, and then test the audio.
The subwoofer I test by playing music with my music player, Audacious. When testing different configurations and output profiles I use
pavucontrol.
For testing the microphone, I open pavucontrol, switch the input source
between Internal Microphone and Microphone and look at the volumebar to see if the microphone works fine.
Do you have suggestions how to apply and test the provided patches?
you have to provide alsa-info of patched driver
http://git.alsa-project.org/?p=alsa-lib.git;a=blob;f=test/chmap.c;hb=HEAD
./chmap -Dhw:0 query
Do chmap show the stereo and 2.1 channel map ?
the "External Subwoofer Jack" detect kctl should return true when you plug the Sonic Master Subwoofer and false when you unplug
after you add analog-output-subwoofer.conf and replace the output path analog-output-lineout and analog-output-speaker in 2.1 profiles in profile-sets/default.conf
You have to provide pulseaudio verbsose log if pulseaudio did not automatically switch to 2.1 profile
The dirty workaround for the headset mic when your codec cannot distinguish headphone and headset but you use only headset
Change the headset.conf to use jsck headphone instead of headset mic jack
http://cgit.freedesktop.org/pulseaudio/pulseaudio/plain/src/modules/alsa/mix...
-[Jack Headset Mic] -required-any = any
-[Jack Headset Mic Phantom] -state.plugged = unknown -state.unplugged = unknown -required-any = any
[Jack Headphone] -state.plugged = unknown +required-any = any
Alsa-info patched kernel: http://www.alsa-project.org/db/?f=cd23a3f0bb72e38d73224620e3e8ab57a73aa441
Chmap results:
Type = FIXED, Channels = 2 FL FR Type = FIXED, Channels = 4 FL FR NA LFE
When unplugging the subwoofer, then chmap gives this and stays like this.
Cannot open PCM stream hw:1 for PLAYBACK
[Pavucontrol] -> [Configuration] -> [Built-in Audio] gives
Analog Stereo Duplex Analog Stereo Output Analog Surround 2.1 Output + Analog Stereo Input Analog Surround 2.1 Output Analog Surround 4.0 Output + Analog Stereo Input Analog Surround 4.0 Output Analog Stereo Input Off
Pulseaudio verbose log while plugging in the subwoofer: http://pastebin.com/Ya5u1qz6
On 13 July 2015 at 13:24, Raymond Yau superquad.vortex2@gmail.com wrote:
Honestly some of the Alsa code talk is a bit over my head, so maybe I
should just stick to providing PCI/Vendor ID's and test results. :)
RY> How do you test ? Using sound preference or alsa speaker-test
I apply some of your code by retyping this into the mainline kernel
4.2-rc1 code, compile and install the kernel, and then test the audio.
The subwoofer I test by playing music with my music player, Audacious. When testing different configurations and output profiles I use
pavucontrol.
For testing the microphone, I open pavucontrol, switch the input source
between Internal Microphone and Microphone and look at the volumebar to see if the microphone works fine.
Do you have suggestions how to apply and test the provided patches?
you have to provide alsa-info of patched driver
http://git.alsa-project.org/?p=alsa-lib.git;a=blob;f=test/chmap.c;hb=HEAD
./chmap -Dhw:0 query
Do chmap show the stereo and 2.1 channel map ?
the "External Subwoofer Jack" detect kctl should return true when you plug the Sonic Master Subwoofer and false when you unplug
after you add analog-output-subwoofer.conf and replace the output path analog-output-lineout and analog-output-speaker in 2.1 profiles in profile-sets/default.conf
You have to provide pulseaudio verbsose log if pulseaudio did not automatically switch to 2.1 profile
The dirty workaround for the headset mic when your codec cannot distinguish headphone and headset but you use only headset
Change the headset.conf to use jsck headphone instead of headset mic jack
http://cgit.freedesktop.org/pulseaudio/pulseaudio/plain/src/modules/alsa/mix...
-[Jack Headset Mic] -required-any = any
-[Jack Headset Mic Phantom] -state.plugged = unknown -state.unplugged = unknown -required-any = any
[Jack Headphone] -state.plugged = unknown +required-any = any
Alsa-info patched kernel:
http://www.alsa-project.org/db/?f=cd23a3f0bb72e38d73224620e3e8ab57a73aa441
Node 0x1a [Pin Complex] wcaps 0x40058f: Stereo Amp-In Amp-Out Control: name="Bass Speaker Playback Switch", index=0, device=0 ControlAmp: chs=3, dir=Out, idx=0, ofs=0 Control: name="Speaker Surround Jack", index=0, device=0 Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0 Amp-In vals: [0x00 0x00] Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1 Amp-Out vals: [0x80 0x80] Pincap 0x0000373c: IN OUT HP Detect Vref caps: HIZ 50 GRD 80 100 Pin Default 0x411111f0: [N/A] Speaker at Ext Rear Conn = 1/8, Color = Black DefAssociation = 0xf, Sequence = 0x0 Misc = NO_PRESENCE Pin-ctls: 0x00: VREF_HIZ Unsolicited: tag=05, enabled=1 Power states: D0 D1 D2 D3 EPSS Power: setting=D0, actual=D0 Connection: 3 0x0c 0x0d* 0x0e
"Speaker Surround Jack" should return true when you plugged the external subwoofer as you didn't change the name of the jack detect kctl
Chmap results:
Type = FIXED, Channels = 2 FL FR Type = FIXED, Channels = 4 FL FR NA LFE
When unplugging the subwoofer, then chmap gives this and stays like this.
Cannot open PCM stream hw:1 for PLAYBACK
[Pavucontrol] -> [Configuration] -> [Built-in Audio] gives
Analog Stereo Duplex Analog Stereo Output Analog Surround 2.1 Output + Analog Stereo Input Analog Surround 2.1 Output Analog Surround 4.0 Output + Analog Stereo Input Analog Surround 4.0 Output Analog Stereo Input Off
Pulseaudio verbose log while plugging in the subwoofer:
Seem not probe surround21 profile
Hi Raymond,
I have to apologize.
When you said Pulseaudio might have a bug, I rechecked my steps and I believe I had only applied half of your patches. I have applied all the patches this time, against the 4.2.0-rc3 kernel and posted the requested info again.
alsa-info: http://www.alsa-project.org/db/?f=ab56d544c53402fc7fdb96956299753de2708a6f
chmap-result (stable, does not change after plugging or unplugging jacks):
Type = FIXED, Channels = 2 FL FR Type = FIXED, Channels = 4 FL FR NA LFE
[Pavucontrol] -> [Configuration] -> [Built-in Audio] gives
Analog Stereo Duplex Analog Stereo Output Analog Surround 2.1 Output + Analog Stereo Input Analog Surround 2.1 Output Analog Surround 4.0 Output + Analog Stereo Input Analog Surround 4.0 Output Analog Stereo Input Off
Pulseaudio verbose log: http://pastebin.com/MwC3KQS5
Pulseaudio log is created by the following steps:
1. echo autospawn = no >> ~/.config/pulse/client.conf 2. killall pulseaudio 3. LANG=C pulseaudio -vvvv --log-time=1 > ~/pulseverbose.log 2>&1 4. Wait a couple of seconds 5. Plugin jack external subwoofer 6. Plugin jack headset 7. Press CTRL-C
Are the results the same, or is there more hope this time? :-)
On 13 July 2015 at 13:24, Raymond Yau superquad.vortex2@gmail.com wrote:
Honestly some of the Alsa code talk is a bit over my head, so maybe I
should just stick to providing PCI/Vendor ID's and test results. :)
RY> How do you test ? Using sound preference or alsa speaker-test
I apply some of your code by retyping this into the mainline kernel
4.2-rc1 code, compile and install the kernel, and then test the audio.
The subwoofer I test by playing music with my music player, Audacious. When testing different configurations and output profiles I use
pavucontrol.
For testing the microphone, I open pavucontrol, switch the input source
between Internal Microphone and Microphone and look at the volumebar to see if the microphone works fine.
Do you have suggestions how to apply and test the provided patches?
you have to provide alsa-info of patched driver
http://git.alsa-project.org/?p=alsa-lib.git;a=blob;f=test/chmap.c;hb=HEAD
./chmap -Dhw:0 query
Do chmap show the stereo and 2.1 channel map ?
the "External Subwoofer Jack" detect kctl should return true when you plug the Sonic Master Subwoofer and false when you unplug
after you add analog-output-subwoofer.conf and replace the output path analog-output-lineout and analog-output-speaker in 2.1 profiles in profile-sets/default.conf
You have to provide pulseaudio verbsose log if pulseaudio did not automatically switch to 2.1 profile
The dirty workaround for the headset mic when your codec cannot distinguish headphone and headset but you use only headset
Change the headset.conf to use jsck headphone instead of headset mic jack
http://cgit.freedesktop.org/pulseaudio/pulseaudio/plain/src/modules/alsa/mix...
-[Jack Headset Mic] -required-any = any
-[Jack Headset Mic Phantom] -state.plugged = unknown -state.unplugged = unknown -required-any = any
[Jack Headphone] -state.plugged = unknown +required-any = any
2015-07-26 19:55 GMT+08:00 Arthur Borsboom arthurborsboom@gmail.com:
Hi Raymond,
I have to apologize.
When you said Pulseaudio might have a bug, I rechecked my steps and I believe I had only applied half of your patches. I have applied all the patches this time, against the 4.2.0-rc3 kernel and posted the requested info again.
alsa-info: http://www.alsa-project.org/db/?f=ab56d544c53402fc7fdb96956299753de2708a6f
control.23 { iface CARD name 'External Subwoofer Jack' value true comment { access read type BOOLEAN count 1 } }
As "External Subwoofer Jack" can report the presence of the external Sonice Master Subwoofer
You need David to answer whether pulseaudio can auto mute since there is NO "Headphone Jack" kctl for model=dell-headset-multi
http://git.kernel.org/cgit/linux/kernel/git/tiwai/hda-emu.git/tree/codecs/ca...
There is no "Headphone Jack" kctl for those alc3661-dell which use dell-headset-multi,
control.19 { iface CARD name 'Headphone Mic Jack' value false comment { access read type BOOLEAN count 1 } } control.20 { iface CARD name 'Headset Mic Phantom Jack' value true comment { access read type BOOLEAN count 1 } } control.21 { iface CARD name 'Internal Mic Phantom Jack' value true comment { access read type BOOLEAN count 1 } } control.22 { iface CARD name 'Speaker Front Phantom Jack' value true comment { access read type BOOLEAN count 1 } }
chmap-result (stable, does not change after plugging or unplugging jacks):
Type = FIXED, Channels = 2 FL FR Type = FIXED, Channels = 4 FL FR NA LFE
[Pavucontrol] -> [Configuration] -> [Built-in Audio] gives
Analog Stereo Duplex Analog Stereo Output Analog Surround 2.1 Output + Analog Stereo Input Analog Surround 2.1 Output Analog Surround 4.0 Output + Analog Stereo Input Analog Surround 4.0 Output Analog Stereo Input Off
Pulseaudio verbose log: http://pastebin.com/MwC3KQS5
Pulseaudio expect "Headphone Jack" but it is not available in dell-headset-multi
( 0.088| 0.000) D: [pulseaudio] alsa-mixer.c: Looking at profile output:analog-surround-21 ( 0.088| 0.000) D: [pulseaudio] alsa-mixer.c: Checking for playback on Analog Surround 2.1 (analog-surround-21) ( 0.088| 0.000) D: [pulseaudio] alsa-util.c: Trying surround21:1 with SND_PCM_NO_AUTO_FORMAT ... ( 0.088| 0.000) D: [pulseaudio] alsa-util.c: Managed to open surround21:1 ( 0.088| 0.000) D: [pulseaudio] alsa-util.c: Maximum hw buffer size is 11888 ms ( 0.106| 0.017) D: [pulseaudio] alsa-util.c: Set buffer size first (to 4408 samples), period size second (to 1102 samples). ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Profile output:analog-surround-21 supported. ( 0.106| 0.000) I: [pulseaudio] (alsa-lib)control.c: Invalid CTL surround21:1 ( 0.106| 0.000) I: [pulseaudio] alsa-util.c: Unable to attach to mixer surround21:1: No such file or directory ( 0.106| 0.000) I: [pulseaudio] alsa-util.c: Successfully attached to mixer 'hw:1' ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Removing path 'analog-output' as it is a subset of 'analog-output-speaker'. ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Available mixer paths (after tidying): ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Path Set 0xc8a0b0, direction=1 ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Path analog-output-speaker (Speakers), direction=1, priority=100, probed=yes, supported=yes, has_mute=yes, has_volume=yes, has_dB=yes, min_volume=0, max_volume=87, min_dB=-181.5, max_dB=0 ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element Master, direction=1, switch=1, volume=1, volume_limit=-1, enumeration=0, required=0, required_any=0, required_absent=0, mask=0x7ffffffffffff, n_channels=1, override_map=yes ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element Headphone, direction=1, switch=2, volume=2, volume_limit=-1, enumeration=0, required=0, required_any=0, required_absent=0, mask=0x6, n_channels=2, override_map=no ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element Speaker, direction=1, switch=1, volume=1, volume_limit=-1, enumeration=0, required=0, required_any=4, required_absent=0, mask=0x3600000000f66, n_channels=2, override_map=yes ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element Bass Speaker, direction=1, switch=1, volume=1, volume_limit=-1, enumeration=0, required=0, required_any=4, required_absent=0, mask=0x80, n_channels=2, override_map=yes ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element PCM, direction=1, switch=0, volume=1, volume_limit=-1, enumeration=0, required=0, required_any=0, required_absent=0, mask=0x3600000000f66, n_channels=2, override_map=yes ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Headphone, alsa_name='Headphone Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Dock Headphone, alsa_name='Dock Headphone Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Front Headphone, alsa_name='Front Headphone Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Line Out, alsa_name='Line Out Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Line Out Front, alsa_name='Line Out Front Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Speaker Phantom, alsa_name='Speaker Phantom Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Speaker Front Phantom, alsa_name='Speaker Front Phantom Jack', detection possible ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Skipping profile output:analog-surround-21+input:analog-mono - will not be able to open input:analog-mono ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Looking at profile output:analog-surround-21+input:analog-stereo ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Checking for recording on Analog Stereo (analog-stereo) ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Trying front:1 with SND_PCM_NO_AUTO_FORMAT ... ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Managed to open front:1 ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Maximum hw buffer size is 23777 ms ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Set buffer size first (to 4408 samples), period size second (to 1102 samples). ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Profile output:analog-surround-21+input:analog-stereo supported. ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Skipping profile output:analog-surround-21+input:iec958-stereo - will not be able to open input:iec958-stereo ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Looking at profile output:analog-surround-40 ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Checking for playback on Analog Surround 4.0 (analog-surround-40) ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Trying surround40:1 with SND_PCM_NO_AUTO_FORMAT ... ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Managed to open surround40:1 ( 0.107| 0.000) D: [pulseaudio] alsa-util.c: Maximum hw buffer size is 11888 ms ( 0.107| 0.000) D: [pulseaudio] alsa-util.c: Set buffer size first (to 4408 samples), period size second (to 1102 samples). ( 0.107| 0.000) D: [pulseaudio] alsa-mixer.c: Profile output:analog-surround-40 supported.
it is pulseaudio bug to support surround40 since your laptop does not have "RL and RR" chmap
I shall file a bug against Pulseaudio with the subject.
Pulseaudio enables Surround 4.0, while chmap reports no RL and RR.
While waiting for the Pulseaudio result, do you think it is a good idea to send your Alsa patches upstream, so at least some of the functionality start working soon? If so, do you guess this patch will be available in v4.2 or v4.3?
On 27 July 2015 at 04:11, Raymond Yau superquad.vortex2@gmail.com wrote:
2015-07-26 19:55 GMT+08:00 Arthur Borsboom arthurborsboom@gmail.com:
Hi Raymond,
I have to apologize.
When you said Pulseaudio might have a bug, I rechecked my steps and I believe I had only applied half of your patches. I have applied all the patches this time, against the 4.2.0-rc3 kernel and posted the requested info again.
alsa-info: http://www.alsa-project.org/db/?f=ab56d544c53402fc7fdb96956299753de2708a6f
control.23 { iface CARD name 'External Subwoofer Jack' value true comment { access read type BOOLEAN count 1 } }
As "External Subwoofer Jack" can report the presence of the external Sonice Master Subwoofer
You need David to answer whether pulseaudio can auto mute since there is NO "Headphone Jack" kctl for model=dell-headset-multi
http://git.kernel.org/cgit/linux/kernel/git/tiwai/hda-emu.git/tree/codecs/ca...
There is no "Headphone Jack" kctl for those alc3661-dell which use dell-headset-multi,
control.19 { iface CARD name 'Headphone Mic Jack' value false comment { access read type BOOLEAN count 1 } } control.20 { iface CARD name 'Headset Mic Phantom Jack' value true comment { access read type BOOLEAN count 1 } } control.21 { iface CARD name 'Internal Mic Phantom Jack' value true comment { access read type BOOLEAN count 1 } } control.22 { iface CARD name 'Speaker Front Phantom Jack' value true comment { access read type BOOLEAN count 1 } }
chmap-result (stable, does not change after plugging or unplugging jacks):
Type = FIXED, Channels = 2 FL FR Type = FIXED, Channels = 4 FL FR NA LFE
[Pavucontrol] -> [Configuration] -> [Built-in Audio] gives
Analog Stereo Duplex Analog Stereo Output Analog Surround 2.1 Output + Analog Stereo Input Analog Surround 2.1 Output Analog Surround 4.0 Output + Analog Stereo Input Analog Surround 4.0 Output Analog Stereo Input Off
Pulseaudio verbose log: http://pastebin.com/MwC3KQS5
Pulseaudio expect "Headphone Jack" but it is not available in dell-headset-multi
( 0.088| 0.000) D: [pulseaudio] alsa-mixer.c: Looking at profile output:analog-surround-21 ( 0.088| 0.000) D: [pulseaudio] alsa-mixer.c: Checking for playback on Analog Surround 2.1 (analog-surround-21) ( 0.088| 0.000) D: [pulseaudio] alsa-util.c: Trying surround21:1 with SND_PCM_NO_AUTO_FORMAT ... ( 0.088| 0.000) D: [pulseaudio] alsa-util.c: Managed to open surround21:1 ( 0.088| 0.000) D: [pulseaudio] alsa-util.c: Maximum hw buffer size is 11888 ms ( 0.106| 0.017) D: [pulseaudio] alsa-util.c: Set buffer size first (to 4408 samples), period size second (to 1102 samples). ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Profile output:analog-surround-21 supported. ( 0.106| 0.000) I: [pulseaudio] (alsa-lib)control.c: Invalid CTL surround21:1 ( 0.106| 0.000) I: [pulseaudio] alsa-util.c: Unable to attach to mixer surround21:1: No such file or directory ( 0.106| 0.000) I: [pulseaudio] alsa-util.c: Successfully attached to mixer 'hw:1' ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Removing path 'analog-output' as it is a subset of 'analog-output-speaker'. ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Available mixer paths (after tidying): ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Path Set 0xc8a0b0, direction=1 ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Path analog-output-speaker (Speakers), direction=1, priority=100, probed=yes, supported=yes, has_mute=yes, has_volume=yes, has_dB=yes, min_volume=0, max_volume=87, min_dB=-181.5, max_dB=0 ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element Master, direction=1, switch=1, volume=1, volume_limit=-1, enumeration=0, required=0, required_any=0, required_absent=0, mask=0x7ffffffffffff, n_channels=1, override_map=yes ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element Headphone, direction=1, switch=2, volume=2, volume_limit=-1, enumeration=0, required=0, required_any=0, required_absent=0, mask=0x6, n_channels=2, override_map=no ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element Speaker, direction=1, switch=1, volume=1, volume_limit=-1, enumeration=0, required=0, required_any=4, required_absent=0, mask=0x3600000000f66, n_channels=2, override_map=yes ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element Bass Speaker, direction=1, switch=1, volume=1, volume_limit=-1, enumeration=0, required=0, required_any=4, required_absent=0, mask=0x80, n_channels=2, override_map=yes ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Element PCM, direction=1, switch=0, volume=1, volume_limit=-1, enumeration=0, required=0, required_any=0, required_absent=0, mask=0x3600000000f66, n_channels=2, override_map=yes ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Headphone, alsa_name='Headphone Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Dock Headphone, alsa_name='Dock Headphone Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Front Headphone, alsa_name='Front Headphone Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Line Out, alsa_name='Line Out Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Line Out Front, alsa_name='Line Out Front Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Speaker Phantom, alsa_name='Speaker Phantom Jack', detection unavailable ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Jack Speaker Front Phantom, alsa_name='Speaker Front Phantom Jack', detection possible ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Skipping profile output:analog-surround-21+input:analog-mono - will not be able to open input:analog-mono ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Looking at profile output:analog-surround-21+input:analog-stereo ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Checking for recording on Analog Stereo (analog-stereo) ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Trying front:1 with SND_PCM_NO_AUTO_FORMAT ... ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Managed to open front:1 ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Maximum hw buffer size is 23777 ms ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Set buffer size first (to 4408 samples), period size second (to 1102 samples). ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Profile output:analog-surround-21+input:analog-stereo supported. ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Skipping profile output:analog-surround-21+input:iec958-stereo - will not be able to open input:iec958-stereo ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Looking at profile output:analog-surround-40 ( 0.106| 0.000) D: [pulseaudio] alsa-mixer.c: Checking for playback on Analog Surround 4.0 (analog-surround-40) ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Trying surround40:1 with SND_PCM_NO_AUTO_FORMAT ... ( 0.106| 0.000) D: [pulseaudio] alsa-util.c: Managed to open surround40:1 ( 0.107| 0.000) D: [pulseaudio] alsa-util.c: Maximum hw buffer size is 11888 ms ( 0.107| 0.000) D: [pulseaudio] alsa-util.c: Set buffer size first (to 4408 samples), period size second (to 1102 samples). ( 0.107| 0.000) D: [pulseaudio] alsa-mixer.c: Profile output:analog-surround-40 supported.
it is pulseaudio bug to support surround40 since your laptop does not have "RL and RR" chmap
I shall file a bug against Pulseaudio with the subject.
Pulseaudio enables Surround 4.0, while chmap reports no RL and RR.
While waiting for the Pulseaudio result, do you think it is a good idea
to send your Alsa patches upstream, so at least some of the functionality start working soon?
If so, do you guess this patch will be available in v4.2 or v4.3?
Do dell-headset-multi really work as expected ?
http://voices.canonical.com/david.henningsson/2014/03/07/headset-jacks-on-ne...
Seem need popup dialog to set the combo jack type correctly when you are using headset or conventional mic
Do "pactl list sinks" show the headphone port since your alsa-info did not have any Headphone Jack kctl ?
Your pulseaudio log only have surround21 profile but no message about lfe filter enabled
pa_log_debug(" lfe filter activated (LR4 type)");
http://cgit.freedesktop.org/pulseaudio/pulseaudio/commit/?id=979f19a434733af...
At this moment the headset works this way: I plugin the headset, I change the input source from Internal Microphone to Microphone and I can start using the headset. There is no popup.
The sub woofer works on Pulseaudio setting "Stereo" and "Surround 4.0", but not on "Surround 2.1".
pactl list sinks: http://pastebin.com/uZH1nwtE
On 27 July 2015 at 11:08, Raymond Yau superquad.vortex2@gmail.com wrote:
I shall file a bug against Pulseaudio with the subject.
Pulseaudio enables Surround 4.0, while chmap reports no RL and RR.
While waiting for the Pulseaudio result, do you think it is a good idea
to send your Alsa patches upstream, so at least some of the functionality start working soon?
If so, do you guess this patch will be available in v4.2 or v4.3?
Do dell-headset-multi really work as expected ?
http://voices.canonical.com/david.henningsson/2014/03/07/headset-jacks-on-ne...
Seem need popup dialog to set the combo jack type correctly when you are using headset or conventional mic
Do "pactl list sinks" show the headphone port since your alsa-info did not have any Headphone Jack kctl ?
Your pulseaudio log only have surround21 profile but no message about lfe filter enabled
pa_log_debug(" lfe filter activated (LR4 type)");
http://cgit.freedesktop.org/pulseaudio/pulseaudio/commit/?id=979f19a434733af...
At this moment the headset works this way: I plugin the headset, I change
the input source from Internal Microphone to Microphone and I can start using the headset. There is no popup.
The sub woofer works on Pulseaudio setting "Stereo" and "Surround 4.0",
but not on "Surround 2.1".
Refer to your pulseaudio verbose log
( 6.509| 1.381) D: [pulseaudio] module-alsa-card.c: Jack 'Headphone Mic Jack' is now plugged in ( 6.509| 0.000) D: [pulseaudio] device-port.c: Setting port analog-output-headphones to status yes
This look like pulseaudio use headphone mic jack to set the headphone to available
( 6.509| 0.000) D: [pulseaudio] module-switch-on-port-available.c: Finding best profile ( 6.509| 0.000) D: [pulseaudio] module-switch-on-port-available.c: No suitable profile found ( 6.509| 0.000) D: [pulseaudio] device-port.c: Setting port analog-input-headphone-mic to status unknown
( 6.509| 0.000) D: [pulseaudio] core-subscribe.c: Dropped redundant event due to change event. ( 6.509| 0.000) D: [pulseaudio] device-port.c: Setting port analog-input-headset-mic to status unknown
But I don't understand why pulseaudio set status of headphone mic and headset mic to unknown
You did not use External Subwoofer Jack to change the status of external subwoofer, there is no traces of external subwoofer jack in your log
Hi Raymond,
I would like to apply your patches to a Linux kernel tree, so I can test them. However, the patches get rejected against Mainline kernel 4.1.1 and 4.2.0-rc1.
What kernel version did you use to write these patches?
On 6 July 2015 at 05:19, Raymond Yau superquad.vortex2@gmail.com wrote:
I have tested the patch by manually adding the lines of code into
mainline kernel 4.1.1.
The base speakers works.
Do you need special name for the external subwoofer jack detect control for pulseaudio automatically switch from stereo profile to 2.1 profile ?
int snd_hda_jack_add_kctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { const hda_nid_t *p; int i, err;
...
for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
if (cfg->line_outs == 2 && i == 1)
err = add_jack_kctl(codec, *p, cfg, "External Subwoofer");
else
err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) return err; }
The headset microphone works. The headphone, headset microphone and microphone jack detection seems to
work in PulseAudio (showing by plugged or unplugged status).
However it does not automatically switch the (un)plugged microphone. My guess is that it does not know if it should use the headset
microphone or the microphone (instead of the default internal microphone).
Do you think there is a way to automate the forward and backward
switching between the internal microphone and headset microphone?
http://bazaar.launchpad.net/~unity-settings-daemon-team/unity-settings-daemo...
Headphone Mic Jack - indicates headphone and mic-in mode share the same jack, i e, not two separate jacks. Hardware cannot distinguish between headphone and a mic. Headset Mic Phantom Jack - indicates headset jack where hardware can not distinguish between headphones and headsets Headset Mic Jack - indicates headset jack where hardware can distinguish between headphones and headsets. There is no use popping up a dialog in this case, unless we already need to do this for the mic-in mode.
Auto mic need headset mic support jack detection
There are two methods, both methods need to give up the capability of using headphone and mic
cannot use hint for user to select this feature since user hint is applied after pin fixup
- create headset mic jack as slave of headphone jack , this use headphone
jack sense for the jack state of headset mic
spec->gen.combo_use_only_as_headset = 0;
- change headphone jack to headset jack, this require add [Element
Headset] to pulseaudio conf files
spec->gen.headset_and_no_hp = 0;
Method 1 -
Cons - hda-emu cannot emulate this master slave jack ctl and gated/gating jack ctl
Method 2
Cons - some notebook has
a) headset and headphone jacks
b)r headset and dock headset
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index ac0db16..7e9b7ae 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -4384,6 +4384,9 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, /* don't detect pins retasked as outputs */ if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN) continue;
if (pin == spec->headset_mic_pin)
if (spec->headset_and_no_hp)
pin = spec->autocfg.hp_pins[0]; if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) { mux_select(codec, 0, spec->am_entry[i].idx); return;
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h index 56e4139..4c3e043 100644 --- a/sound/pci/hda/hda_generic.h +++ b/sound/pci/hda/hda_generic.h @@ -236,6 +236,10 @@ struct hda_gen_spec { unsigned int indep_hp_enabled:1; /* independent HP enabled */ unsigned int have_aamix_ctl:1; unsigned int hp_mic_jack_modes:1;
- unsigned int combo_use_only_as_headset:1; /* headphone mic jack -
slave of headphone jack */
unsigned int headset_and_no_hp:1; /* headset jack */
hda_nid_t headset_mic_pin;
/* additional mute flags (only effective with auto_mute_via_amp=1) */ u64 mute_bits;
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 366efbf..771e84f 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c @@ -19,6 +19,7 @@ #include "hda_local.h" #include "hda_auto_parser.h" #include "hda_jack.h" +#include "hda_generic.h"
/**
- is_jack_detectable - Check whether the given pin is jack-detectable
@@ -157,7 +158,10 @@ static void jack_detect_update(struct hda_codec *codec, if (jack->phantom_jack) jack->pin_sense = AC_PINSENSE_PRESENCE; else
jack->pin_sense = read_pin_sense(codec, jack->nid);
if (jack->master_nid)
jack->pin_sense = read_pin_sense(codec, jack->master_nid);
else
jack->pin_sense = read_pin_sense(codec, jack->nid);
/* A gating jack indicates the jack is invalid if gating is unplugged
*/ if (jack->gating_jack && !snd_hda_jack_detect(codec, jack->gating_jack)) @@ -205,11 +209,20 @@ EXPORT_SYMBOL_GPL(snd_hda_jack_set_dirty_all); u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) { struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
- struct hda_jack_tbl *slave;
- u32 sense; if (jack) { jack_detect_update(codec, jack); return jack->pin_sense; }
- return read_pin_sense(codec, nid);
- if (jack->master_nid)
return read_pin_sense(codec, jack->master_nid);
- sense = read_pin_sense(codec, nid);
- if (jack->slave_nid) {
slave = snd_hda_jack_tbl_get(codec, jack->slave_nid);
slave->pin_sense = sense;
- }
- return sense;
} EXPORT_SYMBOL_GPL(snd_hda_pin_sense);
@@ -317,6 +330,28 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, EXPORT_SYMBOL_GPL(snd_hda_jack_set_gating_jack);
/**
- snd_hda_jack_set_master_slave
- @codec: the HDA codec
- @master_nid: use this nid for pin sense
- @slave_nid: update slave jack pin sense
- use master pin sense for slave pin sense
- */
+int snd_hda_jack_set_master_slave(struct hda_codec *codec, hda_nid_t master_nid,
hda_nid_t slave_nid)
+{
- struct hda_jack_tbl *master = snd_hda_jack_tbl_get(codec, master_nid);
- struct hda_jack_tbl *slave = snd_hda_jack_tbl_get(codec, slave_nid);
- if (master)
master->slave_nid = slave_nid;
- if (slave) {
slave->master_nid = master_nid;
snd_hda_codec_write_cache(codec, slave_nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE, 0);
- }
- return 0;
+}
+/**
- snd_hda_jack_report_sync - sync the states of all jacks and report if
changed
- @codec: the HDA codec
*/ @@ -469,7 +504,8 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { const hda_nid_t *p;
- int i, err;
int i, err, loc;
struct hda_gen_spec *spec = codec->spec;
for (i = 0; i < cfg->num_inputs; i++) { /* If we have headphone mics; make sure they get the right name
@@ -481,22 +517,37 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, else err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, "Headphone Mic");
} else
err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg,
} else {
if (cfg->inputs[i].is_headset_mic) {
if (!spec->headset_and_no_hp)
err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg,
NULL);
else
err = 0;
}
else
err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, NULL);
} if (err < 0) return err;
}
for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
err = add_jack_kctl(codec, *p, cfg, NULL);
loc = get_defcfg_location(get_wcaps(codec, *p));
if (i == 1 && cfg->line_outs == 2 && loc == AC_JACK_LOC_EXTERNAL)
err = add_jack_kctl(codec, *p, cfg, "External Subwoofer");
else
} for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { if (*p == *cfg->line_out_pins) /* might be duplicated */ break;err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) return err;
err = add_jack_kctl(codec, *p, cfg, NULL);
if (spec->headset_and_no_hp && i == 0)
err = add_jack_kctl(codec, *p, cfg, "Headset");
else
}err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0) return err;
@@ -507,6 +558,13 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, if (err < 0) return err; }
- if (spec->combo_use_only_as_headset)
for (i = 0; i < cfg->num_inputs; i++) {
if (cfg->inputs[i].is_headset_mic)
snd_hda_jack_set_master_slave(codec, cfg->hp_pins[0],
cfg->inputs[i].pin);
}
- for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { err = add_jack_kctl(codec, *p, cfg, NULL); if (err < 0)
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index 387d309..364cfa5 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h @@ -39,6 +39,8 @@ struct hda_jack_tbl { unsigned int block_report:1; /* in a transitional state - do not report to userspace */ hda_nid_t gating_jack; /* valid when gating jack plugged */ hda_nid_t gated_jack; /* gated is dependent on this jack */
- hda_nid_t master_nid; /* use master_nid for jack sense */
- hda_nid_t slave_nid; /* update slave_nid jack state */ int type; struct snd_jack *jack;
}; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8e02cdf..598a442 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3998,6 +3998,16 @@ static void alc_update_headset_mode(struct hda_codec *codec) return; }
- if (spec->gen.combo_use_only_as_headset ||
spec->gen.headset_and_no_hp) {
if (snd_hda_jack_detect(codec, hp_pin)) {
new_headset_mode = ALC_HEADSET_MODE_HEADSET;
alc_determine_headset_type(codec);
codec_info(codec, "mic_autoswitch\n");
snd_hda_gen_mic_autoswitch(codec, NULL);
}
- }
- switch (new_headset_mode) { case ALC_HEADSET_MODE_UNPLUGGED: alc_headset_mode_unplugged(codec);
@@ -4056,8 +4066,10 @@ static void alc_probe_headset_mode(struct hda_codec *codec)
/* Find mic pins */ for (i = 0; i < cfg->num_inputs; i++) {
if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) { spec->headset_mic_pin = cfg->inputs[i].pin;
spec->gen.headset_mic_pin = spec->headset_mic_pin;
}} if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) spec->headphone_mic_pin = cfg->inputs[i].pin;
@@ -4074,7 +4086,11 @@ static void alc_fixup_headset_mode(struct hda_codec *codec,
switch (action) { case HDA_FIXUP_ACT_PRE_PROBE:
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC |
HDA_PINCFG_HEADPHONE_MIC;
if (spec->gen.combo_use_only_as_headset ||
spec->gen.headset_and_no_hp)
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
else
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC |
HDA_PINCFG_HEADPHONE_MIC; break; case HDA_FIXUP_ACT_PROBE: alc_probe_headset_mode(codec); @@ -6149,6 +6165,43 @@ static void alc668_restore_default_value(struct hda_codec *codec) alc_process_coef_fw(codec, alc668_coefs); }
+static void alc668_fixup_asus_n751jk(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
+{
- struct alc_spec *spec = codec->spec;
- static const struct hda_pintbl normal_cfgs[] = {
{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own
jack detect */
{ 0x1a, 0x04110011 }, /* bass speaker at Ext Right with jack
detect */
{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack
detect */
{ }
- };
- static const struct hda_pintbl headset_cfgs[] = {
{ 0x19, 0x411111f0 }, /* N/A */
{ 0x1a, 0x04110011 }, /* bass speaker at Ext Right with jack
detect */
{ 0x1b, 0x03a1103c }, /* use as headset mic, without its own jack
detect */
{ }
- };
- switch(action){
- case HDA_FIXUP_ACT_PRE_PROBE:
spec->gen.combo_use_only_as_headset = 0;
spec->gen.headset_and_no_hp = 0;
codec_info(codec, "use as headset %d\n",
spec->gen.combo_use_only_as_headset);
if (spec->gen.combo_use_only_as_headset ||
spec->gen.headset_and_no_hp) {
snd_hda_apply_pincfgs(codec, headset_cfgs);
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
}
else {
snd_hda_apply_pincfgs(codec, normal_cfgs);
spec->parse_flags |= HDA_PINCFG_HEADSET_MIC |
HDA_PINCFG_HEADPHONE_MIC;
}
break;
- case HDA_FIXUP_ACT_BUILD:
alc_fixup_bass_chmap(codec, fix, action);
break;
- }
+}
enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_LED_GPIO1, @@ -6179,6 +6232,7 @@ enum { ALC668_FIXUP_AUTO_MUTE, ALC668_FIXUP_DELL_DISABLE_AAMIX, ALC668_FIXUP_DELL_XPS13,
- ALC668_FIXUP_ASUS_N751JK,
};
static const struct hda_fixup alc662_fixups[] = { @@ -6419,6 +6473,12 @@ static const struct hda_fixup alc662_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc_fixup_bass_chmap, },
- [ALC668_FIXUP_ASUS_N751JK] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc668_fixup_asus_n751jk,
.chained = true,
.chain_id = ALC668_FIXUP_HEADSET_MODE,
- },
};
static const struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -6441,6 +6501,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
- SND_PCI_QUIRK(0x1043, 0x17bd, "Asus N751JK",
ALC668_FIXUP_ASUS_N751JK), SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
participants (2)
-
Arthur Borsboom
-
Raymond Yau