[alsa-devel] [RFC] hda - is_jack_detectable()
Takashi Iwai
tiwai at suse.de
Wed Nov 9 08:50:07 CET 2011
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 at suse.de>:
> > > At Sat, 5 Nov 2011 13:30:21 +0800,
> > > Raymond Yau wrote:
> > >>
> > >> 2011/11/2 Takashi Iwai <tiwai at 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 */
More information about the Alsa-devel
mailing list