Re: [alsa-devel] Intel HDA / AD1986A problems
At Tue, 21 Aug 2007 21:45:52 -0400, Peter Skensved wrote:
On Tue, Aug 21, 2007 at 02:34:22PM +0200, Takashi Iwai wrote:
At Mon, 20 Aug 2007 22:27:40 -0400, Peter Skensved wrote:
Configuration : Lenovo 3000 N100 laptop with Intel HDA / Anlog Devices AD1986A soundcard running CentOS5.0 with 2.6.18-8.1.8.el5 kernel ( uses 1.0.12rc1 based alsa driver ).
The driver works with the model=laptop-eapd option except for a few things :
- Plugging in an external headset will not mute the internal speakers ( has to be done
manually in alsa-mixer )
That's an unimplemented feature. It shouldn't be too hard to add it if you help debugging well (i.e. you can build and test drivers from HG tree without hitch).
Ok - I'm willing to give it a try. Do I need development version of theh library and the utilities as well ?
Recommended, but not mandatory.
- The PC speaker ( bell ) appears to be permanently muted.
Partly intended (as I dislike it ;)
It is nice to have the option ...
Another opinion :)
- The external microphone input does not appear to be working no matter what I do.
Do you mean for recording or analog loopback?
Yes - for recording. I was hoping to get it to work well enough to use skype -
Note that recording and analog-loopback are different things.
- When recording from the internal microphone the level is very, very low and almost
drowns in static noise.
There are "Mic Boost" and "Front Mic Boost" mixer volumes.
Not with model=laptop-eapd - my alas mixer only shows Master, PCM, Mic, Capture, Mix, External Amp and Internal Amp
The Mic Boost control was added _after_ 1.0.14 release. (Correction in the above text: Front Mic Boost doesn't exist for AD1986A but for other codec.)
So, please try HG version first. Then let's debug further.
Takashi
At Wed, 22 Aug 2007 11:20:50 +0200, I wrote:
- When recording from the internal microphone the level is very, very low and almost
drowns in static noise.
There are "Mic Boost" and "Front Mic Boost" mixer volumes.
Not with model=laptop-eapd - my alas mixer only shows Master, PCM, Mic, Capture, Mix, External Amp and Internal Amp
The Mic Boost control was added _after_ 1.0.14 release. (Correction in the above text: Front Mic Boost doesn't exist for AD1986A but for other codec.)
So, please try HG version first. Then let's debug further.
Note that the auto-mute feature isn't implemented yet in HG version, too. But the mic boost should work at least.
The below is the untested patch for adding the auto-mute feature. A new model laptop-automute is implemented. Of course, it's against the latest HG version. Give it a try.
Takashi
diff -r 409d36cdf3b2 Documentation/ALSA-Configuration.txt --- a/Documentation/ALSA-Configuration.txt Wed Aug 22 09:45:03 2007 +0200 +++ b/Documentation/ALSA-Configuration.txt Wed Aug 22 11:51:09 2007 +0200 @@ -932,6 +932,7 @@ Prior to version 0.9.0rc4 options had a 3stack 3-stack, shared surrounds laptop 2-channel only (FSC V2060, Samsung M50) laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J) + laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) ultra 2-channel with EAPD (Samsung Ultra tablet PC)
AD1988 diff -r 409d36cdf3b2 pci/hda/patch_analog.c --- a/pci/hda/patch_analog.c Wed Aug 22 09:45:03 2007 +0200 +++ b/pci/hda/patch_analog.c Wed Aug 22 11:51:09 2007 +0200 @@ -73,6 +73,8 @@ struct ad198x_spec { struct snd_kcontrol_new *kctl_alloc; struct hda_input_mux private_imux; hda_nid_t private_dac_nids[4]; + + unsigned int jack_present :1;
#ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_loopback_check loopback; @@ -568,6 +570,106 @@ static struct snd_kcontrol_new ad1986a_l HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = ad198x_mux_enum_info, + .get = ad198x_mux_enum_get, + .put = ad198x_mux_enum_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "External Amplifier", + .info = ad198x_eapd_info, + .get = ad198x_eapd_get, + .put = ad198x_eapd_put, + .private_value = 0x1b | (1 << 8), /* port-D, inversed */ + }, + { } /* end */ +}; + +/* laptop-automute - 2ch only */ + +static void ad1986a_update_hp(struct hda_codec *codec) +{ + struct ad198x_spec *spec = codec->spec; + unsigned int mute; + + if (spec->jack_present) + mute = HDA_AMP_MUTE; /* mute internal speaker */ + else + /* unmute internal speaker if necessary */ + mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0); + snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); +} + +static void ad1986a_hp_automute(struct hda_codec *codec) +{ + struct ad198x_spec *spec = codec->spec; + unsigned int present; + + present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); + spec->jack_present = (present & 0x80000000) != 0; + ad1986a_update_hp(codec); +} + +#define AD1986A_HP_EVENT 0x37 + +static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res) +{ + if ((res >> 26) != AD1986A_HP_EVENT) + return; + ad1986a_hp_automute(codec); +} + +static int ad1986a_hp_init(struct hda_codec *codec) +{ + ad198x_init(codec); + ad1986a_hp_automute(codec); + return 0; +} + +/* bind hp and internal speaker mute (with plug check) */ +static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + long *valp = ucontrol->value.integer.value; + int change; + + change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[0] ? 0 : HDA_AMP_MUTE); + change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[1] ? 0 : HDA_AMP_MUTE); + if (change) + ad1986a_update_hp(codec); + return change; +} + +static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = { + HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = ad1986a_hp_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), + }, + HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Beep Playback Volume", 0x18, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Beep Playback Switch", 0x18, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), { @@ -701,12 +803,20 @@ static struct hda_verb ad1986a_ultra_ini { } /* end */ };
+/* pin sensing on HP jack */ +static struct hda_verb ad1986a_hp_init_verbs[] = { + {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, + {} +}; + + /* models */ enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD, + AD1986A_LAPTOP_AUTOMUTE, AD1986A_ULTRA, AD1986A_MODELS }; @@ -716,6 +826,7 @@ static const char *ad1986a_models[AD1986 [AD1986A_3STACK] = "3stack", [AD1986A_LAPTOP] = "laptop", [AD1986A_LAPTOP_EAPD] = "laptop-eapd", + [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", [AD1986A_ULTRA] = "ultra", };
@@ -744,7 +855,7 @@ static struct snd_pci_quirk ad1986a_cfg_ SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP), SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK), - SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_EAPD), + SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE), SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP), {} }; @@ -820,6 +931,19 @@ static int patch_ad1986a(struct hda_code spec->multiout.dac_nids = ad1986a_laptop_dac_nids; spec->multiout.dig_out_nid = 0; spec->input_mux = &ad1986a_laptop_eapd_capture_source; + break; + case AD1986A_LAPTOP_AUTOMUTE: + spec->mixers[0] = ad1986a_laptop_automute_mixers; + spec->num_init_verbs = 3; + spec->init_verbs[1] = ad1986a_eapd_init_verbs; + spec->init_verbs[2] = ad1986a_hp_init_verbs; + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = 1; + spec->multiout.dac_nids = ad1986a_laptop_dac_nids; + spec->multiout.dig_out_nid = 0; + spec->input_mux = &ad1986a_laptop_eapd_capture_source; + codec->patch_ops.unsol_event = ad1986a_hp_unsol_event; + codec->patch_ops.init = ad1986a_hp_init; break; case AD1986A_ULTRA: spec->mixers[0] = ad1986a_laptop_eapd_mixers;
On Wed, Aug 22, 2007 at 11:52:34AM +0200, Takashi Iwai wrote:
At Wed, 22 Aug 2007 11:20:50 +0200, I wrote:
- When recording from the internal microphone the level is very, very low and almost
drowns in static noise.
There are "Mic Boost" and "Front Mic Boost" mixer volumes.
Not with model=laptop-eapd - my alas mixer only shows Master, PCM, Mic, Capture, Mix, External Amp and Internal Amp
The Mic Boost control was added _after_ 1.0.14 release. (Correction in the above text: Front Mic Boost doesn't exist for AD1986A but for other codec.)
So, please try HG version first. Then let's debug further.
Note that the auto-mute feature isn't implemented yet in HG version, too. But the mic boost should work at least.
I downloaded the HG version, compiled against my kernel and re-loaded just the modules ( so as not to break too much else ). I get the two microphone boost controls ( one for playback and another for capture ) and they work. I can record from both internal and external microphone.
The `Internal Mic.' bar/switch appears to do nothing
The `Microphone" bar/switch is active and behaves as expected
I see a couple of extra modem related controls ( Caller ID and Off-hook ) - does that mean I can make the soft modem ( Si3054 ) work with slmodemd --alsa ???
Still no PC speaker ....
The below is the untested patch for adding the auto-mute feature. A new model laptop-automute is implemented. Of course, it's against the latest HG version. Give it a try.
I tried applying the automute patch but I must have picked the wrong version of pci/hda/patch_analog.c because most of the patch failed. At what stage was the patch supposed to be applied ? I did it after having done all the steps on the devel page.
Takashi
At Tue, 18 Sep 2007 12:56:49 -0400, Peter Skensved wrote:
On Wed, Aug 22, 2007 at 11:52:34AM +0200, Takashi Iwai wrote:
At Wed, 22 Aug 2007 11:20:50 +0200, I wrote:
- When recording from the internal microphone the level is very, very low and almost
drowns in static noise.
There are "Mic Boost" and "Front Mic Boost" mixer volumes.
Not with model=laptop-eapd - my alas mixer only shows Master, PCM, Mic, Capture, Mix, External Amp and Internal Amp
The Mic Boost control was added _after_ 1.0.14 release. (Correction in the above text: Front Mic Boost doesn't exist for AD1986A but for other codec.)
So, please try HG version first. Then let's debug further.
Note that the auto-mute feature isn't implemented yet in HG version, too. But the mic boost should work at least.
I downloaded the HG version, compiled against my kernel and re-loaded just the modules ( so as not to break too much else ). I get the two microphone boost controls ( one for playback and another for capture ) and they work. I can record from both internal and external microphone.
The `Internal Mic.' bar/switch appears to do nothing
The `Microphone" bar/switch is active and behaves as expected
I see a couple of extra modem related controls ( Caller ID and Off-hook ) - does that mean I can make the soft modem ( Si3054 ) work with slmodemd --alsa ???
Possibly. There are some devices that don't work well, and some older slmodem doesn't work, too.
Still no PC speaker ....
I don't care :)
The below is the untested patch for adding the auto-mute feature. A new model laptop-automute is implemented. Of course, it's against the latest HG version. Give it a try.
I tried applying the automute patch but I must have picked the wrong version of pci/hda/patch_analog.c because most of the patch failed. At what stage was the patch supposed to be applied ? I did it after having done all the steps on the devel page.
Then the patch was likely already merged...
Takashi
participants (2)
-
Peter Skensved
-
Takashi Iwai