[alsa-devel] [RFC] hda - is_jack_detectable()
Raymond Yau
superquad.vortex2 at gmail.com
Wed Nov 16 08:14:17 CET 2011
2011/11/14 Takashi Iwai <tiwai at suse.de>:
> At Sat, 12 Nov 2011 19:31:20 +0800,
> Raymond Yau wrote:
>>
>> 2011/11/9 Takashi Iwai <tiwai at suse.de>:
>> > 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.
>> >
>>
>> The patch seem ok
>>
>> Need a hack to build the hda-jack branch
>>
>> It is quite simple to enable unsolicited event for all proper jacks by
>>
>> snd_hda_jack_add_kctrls(codec,(codec->spec->autocfg));
>>
>> and
>>
>> static void ad1988_unsol_event(struct hda_codec *codec, unsigned int res)
>> {
>> struct ad198x_spec *spec = codec->spec;
>> struct hda_jack_tbl *jack;
>> u32 sense, caps;
>> int pin;
>> jack = snd_hda_jack_tbl_get_from_tag(codec, res >> 26);
>> pin = jack->nid;
>> caps = snd_hda_codec_get_pincfg(codec, pin);
>> sense = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_PIN_SENSE, 0);
>> if (sense & AC_PINSENSE_PRESENCE)
>> snd_printdd("Pin 0x%x pd=1 imp=%d %s at %s %s %s\n",
>> pin,
>> sense & AC_PINSENSE_IMPEDANCE_MASK,
>> snd_hda_get_jack_type(caps),
>> snd_hda_get_jack_connectivity(caps),
>> snd_hda_get_jack_location(caps),
>> get_jack_color(caps));
>> else
>> snd_printdd("Pin 0x%x pd=0 %s at %s %s %s\n",
>> pin,
>> snd_hda_get_jack_type(caps),
>> snd_hda_get_jack_connectivity(caps),
>> snd_hda_get_jack_location(caps),
>> get_jack_color(caps));
>>
>> if (pin == spec->autocfg.hp_pins[0] && !spec->independent_hp)
>> ad198x_hp_automute(codec);
>> if (pin == spec->ext_mic_pin)
>> ad198x_mic_automute(codec);
>> }
>>
>>
>> However it seem that result is different in kctl
>>
>>
>> amixer -c1 contents
>> numid=5,iface=CARD,name='Front Headphone Jack'
>> ; type=BOOLEAN,access=r-------,values=1
>> : values=off
>> numid=6,iface=CARD,name='Front Mic Jack'
>> ; type=BOOLEAN,access=r-------,values=1
>> : values=off
>> numid=8,iface=CARD,name='Line Jack'
>> ; type=BOOLEAN,access=r-------,values=1
>> : values=off
>> numid=1,iface=CARD,name='Line-Out Jack'
>> ; type=BOOLEAN,access=r-------,values=1
>> : values=off
>> numid=2,iface=CARD,name='Line-Out Jack',index=1
>> ; type=BOOLEAN,access=r-------,values=1
>> : values=off
>> numid=3,iface=CARD,name='Line-Out Jack',index=2
>> ; type=BOOLEAN,access=r-------,values=1
>> : values=off
>> numid=4,iface=CARD,name='Line-Out Jack',index=3
>> ; type=BOOLEAN,access=r-------,values=1
>> : values=off
>> numid=7,iface=CARD,name='Rear Mic Jack'
>> ; type=BOOLEAN,access=r-------,values=1
>> : values=off
>>
>>
>>
>>
>> ./hda-jack-sense-test.py -c1
>> Pin 0x11 Green HP Out (Ext Front): Present = NO
>> Pin 0x12 Green Line Out (Ext Rear): Present = YES Impedance = 19
>> Pin 0x14 Pink Mic (Ext Front): Present = NO
>> Pin 0x15 Blue Line In (Ext Rear): Present = NO
>> Pin 0x16 Black Line Out (Ext Rear): Present = YES Impedance = 3200
>> Pin 0x17 Pink Mic (Ext Rear): Present = YES Impedance = 896
>> 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 = 3200
>>
>>
>> It need "SET_PIN_SENSE" and some delay to get the correct impedance
>> of the jacks during driver load
>>
>>
>> int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
>> unsigned char action)
>> {
>> + int ret;
>> struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
>> if (!jack)
>> return -ENOMEM;
>> if (jack->jack_detect)
>> return 0; /* already registered */
>> jack->jack_detect = 1;
>> if (action)
>> jack->action = action;
>> + ret = snd_hda_codec_write_cache(codec, nid, 0,
>> + AC_VERB_SET_UNSOLICITED_ENABLE,
>> + AC_USRSP_EN | jack->tag);
>> + if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IMP_SENSE) {
>> snd_hda_codec_read(codec, nid, 0,
>> AC_VERB_SET_PIN_SENSE, 0);
>> + msleep(200);
>> + }
>> + return ret;
>
> The lack of the initial pin-state of kclts was fixed in a different
> patch now. But, the need of 200ms delay worries me whether it's
> needed generically at each pin-sense reading or it's just only for the
> initial reading.
>
> Does the pin-sense reading work in general after loading the driver
> stably?
>
>
>
Presence detect bit is alway correct, without the delay.
the only issue is the impedance measurement of the plugged jacks at
computer boot need a delay 200ms
For the user application to know the impedance ,
it seem the client application have to issue
1) set_pin_sense
2) delay
3) get_pin_sense to get the correct impedance of the attached device
just like my modified hda-jack-sense-test in previous email
Can it measure the impedance of the jacks of your computer ?
More information about the Alsa-devel
mailing list