[alsa-devel] [RFC] hda - is_jack_detectable()
Refer to HDA Specification
7.3.3.31 Configuration Default
Misc[3:0] is a bit field used to indicate other information about the jack. Currently, only bit 0 is defined. If bit 0 is set, it indicates that the jack has no presence detect capability, so even if a Pin Complex indicates that the codec hardware supports the presence detect functionality on the jack, the external circuitry is not capable of supporting the functionality. The bit definitions for the Miscfield are in Table 106.
Do we need to change is_jack_detectable() when user setup BIOS to use AC97 Front Audio Panel which set AC_DEFCFG_MISC_NO_PRESENCE bit ?
+#define get_defcfg_misc(cfg) \ + ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT)
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && + (!(get_defcfg_misc(codec,nid) & AC_DEFCFG_MISC_NO_PRESENCE)) && (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); }
or add another fuction is_defcfg_misc_no_presence() to indicate jack has no presence detect capability ?
sorry, it should be
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && + !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & AC_DEFCFG_MISC_NO_PRESENCE)) && (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); }
At Tue, 25 Oct 2011 11:31:23 +0800, Raymond Yau wrote:
sorry, it should be
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) &&
!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & AC_DEFCFG_MISC_NO_PRESENCE)) && (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP);
}
The idea sounds good, but we may need testing via hda-emu. Anyway, could you post a proper patch with your sign-off, etc?
thanks,
Takashi
2011-10-24 23:31, Raymond Yau skrev:
sorry, it should be
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid)& AC_PINCAP_PRES_DETECT)&&
!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & AC_DEFCFG_MISC_NO_PRESENCE))&& (get_wcaps(codec, nid)& AC_WCAP_UNSOL_CAP);
}
I also think it is a good idea, in fact I thought it was this way already. Can we merge this patch?
// David
At Tue, 01 Nov 2011 17:03:29 -0400, David Henningsson wrote:
2011-10-24 23:31, Raymond Yau skrev:
sorry, it should be
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid)& AC_PINCAP_PRES_DETECT)&&
!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & AC_DEFCFG_MISC_NO_PRESENCE))&& (get_wcaps(codec, nid)& AC_WCAP_UNSOL_CAP);
}
I also think it is a good idea, in fact I thought it was this way already. Can we merge this patch?
OK, I checked through alsa-info series and confirmed that this causes no harm, so I merged it now.
thanks,
Takashi
2011/11/2 Takashi Iwai tiwai@suse.de:
At Tue, 01 Nov 2011 17:03:29 -0400, David Henningsson wrote:
2011-10-24 23:31, Raymond Yau skrev:
sorry, it should be
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid)& AC_PINCAP_PRES_DETECT)&&
- !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)
& AC_DEFCFG_MISC_NO_PRESENCE))&& (get_wcaps(codec, nid)& AC_WCAP_UNSOL_CAP); }
I also think it is a good idea, in fact I thought it was this way already. Can we merge this patch?
OK, I checked through alsa-info series and confirmed that this causes no harm, so I merged it now.
thanks,
Takashi
Sorry the previous patch is wrong
attach the patch and test cases (pins 0x11 and 0x14) front panel green and pink jacks when set Front Audio Panel to AC97 or HD in BIOS setup
At Sat, 5 Nov 2011 13:30:21 +0800, Raymond Yau wrote:
2011/11/2 Takashi Iwai tiwai@suse.de:
At Tue, 01 Nov 2011 17:03:29 -0400, David Henningsson wrote:
2011-10-24 23:31, Raymond Yau skrev:
sorry, it should be
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid)& AC_PINCAP_PRES_DETECT)&&
- !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)
& AC_DEFCFG_MISC_NO_PRESENCE))&& (get_wcaps(codec, nid)& AC_WCAP_UNSOL_CAP); }
I also think it is a good idea, in fact I thought it was this way already. Can we merge this patch?
OK, I checked through alsa-info series and confirmed that this causes no harm, so I merged it now.
thanks,
Takashi
Sorry the previous patch is wrong
Ugh, so actually changing it would may bring too many changes, and most likely regressions, too. I disabled the code for now for 3.2-rc1. Once when we cover all test cases and fix broken BIOS devices enough, we can re-enable it in near future.
attach the patch and test cases (pins 0x11 and 0x14) front panel green and pink jacks when set Front Audio Panel to AC97 or HD in BIOS setup
OK, thanks, we can refer to this for more tests.
Takashi
2011/11/6 Takashi Iwai tiwai@suse.de:
At Sat, 5 Nov 2011 13:30:21 +0800, Raymond Yau wrote:
2011/11/2 Takashi Iwai tiwai@suse.de:
At Tue, 01 Nov 2011 17:03:29 -0400, David Henningsson wrote:
2011-10-24 23:31, Raymond Yau skrev:
sorry, it should be
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid)& AC_PINCAP_PRES_DETECT)&&
- !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)
& AC_DEFCFG_MISC_NO_PRESENCE))&& (get_wcaps(codec, nid)& AC_WCAP_UNSOL_CAP); }
I also think it is a good idea, in fact I thought it was this way already. Can we merge this patch?
OK, I checked through alsa-info series and confirmed that this causes no harm, so I merged it now.
thanks,
Takashi
Sorry the previous patch is wrong
Ugh, so actually changing it would may bring too many changes, and most likely regressions, too. I disabled the code for now for 3.2-rc1. Once when we cover all test cases and fix broken BIOS devices enough, we can re-enable it in near future.
attach the patch and test cases (pins 0x11 and 0x14) front panel green and pink jacks when set Front Audio Panel to AC97 or HD in BIOS setup
OK, thanks, we can refer to this for more tests.
Takashi
If bit 0 is set, it indicates that the jack has no presence detect capability
The Configuration Default register is defined as shown in Figure 66. 31:30 29:24 23:20 19:16 15:12 11:8 7:4 3:0 Port Location Default Connection Color Misc Default Sequence Connectivity Device Type Association Figure 66. Configuration Data Structure
This mean that bit 0 of Misc is bit 8 of the Configuration Default register
!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & AC_DEFCFG_MISC_NO_PRESENCE)&&
Node 0x18 [Pin Complex] wcaps 0x400001: Stereo Pincap 0x00000020: IN Pin Default 0x9933112e: [Fixed] CD at Int ATAPI Conn = ATAPI, Color = Black DefAssociation = 0x2, Sequence = 0xe Misc = NO_PRESENCE Pin-ctls: 0x20: IN Node 0x1a [Pin Complex] wcaps 0x400000: Mono Pincap 0x00000020: IN Pin Default 0x99f301f0: [Fixed] Other at Int ATAPI Conn = ATAPI, Color = Unknown DefAssociation = 0xf, Sequence = 0x0 Misc = NO_PRESENCE Pin-ctls: 0x20: IN Node 0x1b [Pin Complex] wcaps 0x40030d: Stereo Digital Amp-Out Control: name="IEC958 Playback Volume", index=0, device=0 ControlAmp: chs=3, dir=Out, idx=0, ofs=0 Control: name="IEC958 Playback Source", index=0, device=0 Amp-Out caps: ofs=0x27, nsteps=0x27, stepsize=0x05, mute=1 Amp-Out vals: [0x00 0x00] Pincap 0x00000010: OUT Pin Default 0x0145f1f0: [Jack] SPDIF Out at Ext Rear Conn = Optical, Color = Other DefAssociation = 0xf, Sequence = 0x0 Misc = NO_PRESENCE Pin-ctls: 0x40: OUT Connection: 1 0x02
At Wed, 9 Nov 2011 12:06:04 +0800, Raymond Yau wrote:
2011/11/6 Takashi Iwai tiwai@suse.de:
At Sat, 5 Nov 2011 13:30:21 +0800, Raymond Yau wrote:
2011/11/2 Takashi Iwai tiwai@suse.de:
At Tue, 01 Nov 2011 17:03:29 -0400, David Henningsson wrote:
2011-10-24 23:31, Raymond Yau skrev:
sorry, it should be
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid)& AC_PINCAP_PRES_DETECT)&&
- !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)
& AC_DEFCFG_MISC_NO_PRESENCE))&& (get_wcaps(codec, nid)& AC_WCAP_UNSOL_CAP); }
I also think it is a good idea, in fact I thought it was this way already. Can we merge this patch?
OK, I checked through alsa-info series and confirmed that this causes no harm, so I merged it now.
thanks,
Takashi
Sorry the previous patch is wrong
Ugh, so actually changing it would may bring too many changes, and most likely regressions, too. I disabled the code for now for 3.2-rc1. Once when we cover all test cases and fix broken BIOS devices enough, we can re-enable it in near future.
attach the patch and test cases (pins 0x11 and 0x14) front panel green and pink jacks when set Front Audio Panel to AC97 or HD in BIOS setup
OK, thanks, we can refer to this for more tests.
Takashi
If bit 0 is set, it indicates that the jack has no presence detect capability
The Configuration Default register is defined as shown in Figure 66. 31:30 29:24 23:20 19:16 15:12 11:8 7:4 3:0 Port Location Default Connection Color Misc Default Sequence Connectivity Device Type Association Figure 66. Configuration Data Structure
This mean that bit 0 of Misc is bit 8 of the Configuration Default register
!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & AC_DEFCFG_MISC_NO_PRESENCE)&&
Yeah, I already tried it and it still gives too many false-positives. Many ASUS laptops (also mobo) set this bit to all pins no matter whether it's an obviously detectable jack or not. Some Toshiba laptops do so, too.
That being said, checking this bit alone isn't reliable because of too many BIOS bugs. A bit more clever test is necessary.
Takashi
At Wed, 09 Nov 2011 08:08:17 +0100, Takashi Iwai wrote:
At Wed, 9 Nov 2011 12:06:04 +0800, Raymond Yau wrote:
2011/11/6 Takashi Iwai tiwai@suse.de:
At Sat, 5 Nov 2011 13:30:21 +0800, Raymond Yau wrote:
2011/11/2 Takashi Iwai tiwai@suse.de:
At Tue, 01 Nov 2011 17:03:29 -0400, David Henningsson wrote:
2011-10-24 23:31, Raymond Yau skrev: > sorry, it should be > > static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) > { > return (snd_hda_query_pin_caps(codec, nid)& AC_PINCAP_PRES_DETECT)&& > + !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) > & AC_DEFCFG_MISC_NO_PRESENCE))&& > (get_wcaps(codec, nid)& AC_WCAP_UNSOL_CAP); > } > I also think it is a good idea, in fact I thought it was this way already. Can we merge this patch?
OK, I checked through alsa-info series and confirmed that this causes no harm, so I merged it now.
thanks,
Takashi
Sorry the previous patch is wrong
Ugh, so actually changing it would may bring too many changes, and most likely regressions, too. I disabled the code for now for 3.2-rc1. Once when we cover all test cases and fix broken BIOS devices enough, we can re-enable it in near future.
attach the patch and test cases (pins 0x11 and 0x14) front panel green and pink jacks when set Front Audio Panel to AC97 or HD in BIOS setup
OK, thanks, we can refer to this for more tests.
Takashi
If bit 0 is set, it indicates that the jack has no presence detect capability
The Configuration Default register is defined as shown in Figure 66. 31:30 29:24 23:20 19:16 15:12 11:8 7:4 3:0 Port Location Default Connection Color Misc Default Sequence Connectivity Device Type Association Figure 66. Configuration Data Structure
This mean that bit 0 of Misc is bit 8 of the Configuration Default register
!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & AC_DEFCFG_MISC_NO_PRESENCE)&&
Yeah, I already tried it and it still gives too many false-positives. Many ASUS laptops (also mobo) set this bit to all pins no matter whether it's an obviously detectable jack or not. Some Toshiba laptops do so, too.
That being said, checking this bit alone isn't reliable because of too many BIOS bugs. A bit more clever test is necessary.
It seems that a broken BIOS sets this bit on all pins in general. So, the patch below (against the latest sound git tree or 3.2-rc1 kernel) seems working well by filtering out such a brokenness.
Let me know if this works. If it's OK, I'll try to merge it for 3.2-rc2.
Takashi
--- diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 916a186..2518299 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -4752,6 +4752,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, memset(sequences_hp, 0, sizeof(sequences_hp)); assoc_line_out = 0;
+ codec->ignore_misc_bit = true; end_nid = codec->start_nid + codec->num_nodes; for (nid = codec->start_nid; nid < end_nid; nid++) { unsigned int wid_caps = get_wcaps(codec, nid); @@ -4767,6 +4768,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, continue;
def_conf = snd_hda_codec_get_pincfg(codec, nid); + if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & + AC_DEFCFG_MISC_NO_PRESENCE)) + codec->ignore_misc_bit = false; conn = get_defcfg_connect(def_conf); if (conn == AC_JACK_PORT_NONE) continue; diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 755f2b0..5644711 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -854,6 +854,7 @@ struct hda_codec { unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ unsigned int pins_shutup:1; /* pins are shut up */ unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ + unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ unsigned int power_transition :1; /* power-state in transition */ diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index dcbea0d..6579e0f 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -510,13 +510,15 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { - return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && - /* disable MISC_NO_PRESENCE check because it may break too - * many devices - */ - /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & - AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ - (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); + if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) + return false; + if (!codec->ignore_misc_bit && + (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & + AC_DEFCFG_MISC_NO_PRESENCE)) + return false; + if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) + return false; + return true; }
/* flags for hda_nid_item */
2011/11/2 David Henningsson david.henningsson@canonical.com:
2011-10-24 23:31, Raymond Yau skrev:
I also think it is a good idea, in fact I thought it was this way already. Can we merge this patch?
// David
commit 729d55ba972348234759f8e40abf8de020f0d505
ALSA: hda - Disable tigger at pin-sensing on AD codecs
It is possible to measure the impedance of the jack with modification of hda-jack-sense-test.py with ad1988
The headphone was plugged into grey jack since my computer chassis only have AC97 front audio panel
The result seem close to my headset specification
Pin 0x11 Green HP Out (Ext Front): No jack detect capability Pin 0x12 Green Line Out (Ext Rear): present = YES impedance = 3776 Pin 0x14 Pink Mic (Ext Front): No jack detect capability Pin 0x15 Blue Line In (Ext Rear): present = No Pin 0x16 Black Line Out (Ext Rear): present = YES impedance = 6080 Pin 0x17 Pink Mic (Ext Rear): present = YES impedance = 1008 Pin 0x18 Black CD (Int ATAPI): No jack detect capability Pin 0x1a Other (Int ATAPI): No jack detect capability Pin 0x1b Other SPDIF Out (Ext Rear): No jack detect capability Pin 0x24 Orange Line Out (Ext Rear): present = No Pin 0x25 Grey Line Out (Ext Rear): present = YES impedance = 25
participants (3)
-
David Henningsson
-
Raymond Yau
-
Takashi Iwai