[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