[Gta04-owner] Headset detection.

Flemming Richter Mikkelsen quatrox at gmail.com
Mon Aug 27 20:11:21 CEST 2012


On 8/25/12, NeilBrown <neilb at suse.de> wrote:
> On Wed, 22 Aug 2012 11:08:43 +1000 NeilBrown <neilb at suse.de> wrote:
>
>> On Tue, 21 Aug 2012 12:30:47 +0200 "Dr. H. Nikolaus Schaller"
>> <hns at goldelico.com> wrote:
>>
>> > Hi Neil,
>> >
>> > Am 18.08.2012 um 02:13 schrieb NeilBrown:
>
>> >
>> > > I don't suppose there is an existing standard....
>> >
>> > Not really.
>> >
>> > Generally you can only say:
>> > short on Mic = green phone key (answer call on headset)
>> > some kOhm on Mic = there is a Mic
>> > high Z = there is no Mic
>>
>> So 'short on Mic' cannot be distinguished from a 3-contact headset (no
>> microphone, 'shield' is larger and shorts together 'shield' and
>> 'ring-1').
>> I guess  a transition from 'some kOhm' to 'short-on-Mic' means the button
>> was
>> pressed, where as a transition from 'high Z' to 'short on Mic' means a
>> 3-contact headset was plugged in.
>>
>> Also if we want button presses to work well I probably need to increase
>> the
>> poll rate when something is plugged in.
>>
>> I don't have a working 2.5mm headset, or a working 3.5-2.5 4-contact
>> converter so I cannot experiment very much.
>> I'll see if I can get hold of one...
>
> I got hold of one (next day delivery! I was impressed :-)
>
> The following patch which I have committed detects whether a mic is present
> or not, and can detect a button which shorts the mic line.
>
> I'm perplexed by the numbers though.
> - open circuit (nothing plugged in) gives a very low reading (20) -
> negligible
>   current flowing.  That makes sense.
> - closed circuit (3-pin connector or button pressed) gives a high readings,
>   (800ish).  Max current allowed by internal resistors is flowing.  That
> also
>   makes sense.
> - mic present gives an *even*higher* reading!!  830 to 850.  What could
> cause
>   that?  How can the mic cause more current to flow?  I thought there might
> be
>   leakage from the headphone driver but I couldn't measure any.
>

Could this be the effect of the impedance from the mic together with
the impedance in the circuit?

What is the real value of the resistors?
It should not be too difficult to calculate the maximum current.
Voltage/Restistance = Ampere still applies here.

>>
>> If someone else wants to experiment, just report the values that appear in
>>
>>     /sys/class/hwmon/hwmon0/device/in7_input
>> when different events happen with some headset (with my any kernel which
>> enables this driver, just as my 3.5 branch).
>
> Note that you need to have /dev/input/jack open (e.g. evtest
> /dev/input/jack)
> for these readings to be valid.
>
>
> Finally: while I can play music through my headset with no trouble, the mic
> doesn't work very well - I can hear what I say but it is very very quiet.
> Has anyone else tried with a head-set microphone?  Any luck?
> Among the things I tried was
>    alsactl -f  /opt/qtmoko/etc/alsa/gsmheadset.state  restore
>
> This is weird  - when I play music I hear it coming from the earpiece even
> though that is muted.   When I unmute the earpiece it keeps playing.  When
> I
> mute again it goes silent.  Something must be wrong in the driver.
>
> NeilBrown
>
>
> commit 169e831d949b83f7b7bb536b9b5009468af98cd2
> Author: NeilBrown <neilb at suse.de>
> Date:   Sat Aug 25 08:44:51 2012 +1000
>
>     GTA04 audio headset jack detect.
>
>     Enhance jack detection to differentiate with and without a microphone,
>     and to report a button-press when the microphone is shorted.
>
>     Signed-off-by: NeilBrown <neilb at suse.de>
>
> diff --git a/GTA04/udev-rules/input.rules b/GTA04/udev-rules/input.rules
> index a96feb8..2cc8df9 100644
> --- a/GTA04/udev-rules/input.rules
> +++ b/GTA04/udev-rules/input.rules
> @@ -4,4 +4,4 @@ SUBSYSTEM=="input", KERNEL=="event[0-9]*",
> ATTRS{modalias}=="input:*-e0,3,*a0,1,
>  SUBSYSTEM=="input", KERNEL=="event[0-9]*",
> ATTRS{modalias}=="input:*-e0,1,*k74,*", SYMLINK+="input/power"
>  SUBSYSTEM=="input", KERNEL=="event[0-9]*",
> ATTRS{modalias}=="input:*-e0,1,*kA9,*", SYMLINK+="input/aux"
>  SUBSYSTEM=="input", KERNEL=="event[0-9]*",
> ATTRS{modalias}=="input:*-e0,1,*kF0,*", SYMLINK+="input/incoming"
> -SUBSYSTEM=="input", KERNEL=="event[0-9]*",
> ATTRS{modalias}=="input:*-e0,5,*w[24678D]*", SYMLINK+="input/jack"
> +SUBSYSTEM=="input", KERNEL=="event[0-9]*",
> ATTRS{modalias}=="input:*-e0*,5,*w[24678D]*", SYMLINK+="input/jack"
> diff --git a/sound/soc/omap/gta04-audio.c b/sound/soc/omap/gta04-audio.c
> index 1048098..804bce9 100644
> --- a/sound/soc/omap/gta04-audio.c
> +++ b/sound/soc/omap/gta04-audio.c
> @@ -145,20 +145,63 @@ static struct {
>  	struct delayed_work jack_work;
>  	struct snd_soc_codec *codec;
>  	int open;
> +	/* When any jack is present, we:
> +	 * - poll more quickly to catch button presses
> +	 * - assume a 'short' is 'button press', not 'headset has
> +	 *   no mic
> +	 * 'present' stores SND_JACK_HEADPHONE and SND_JACK_MICROPHONE
> +	 * indication what we thing is present.
> +	 */
> +	int present;
>  } jack;
>
>  static void gta04_audio_jack_work(struct work_struct *work)
>  {
>  	long val;
> +	long delay = msecs_to_jiffies(500);
> +	int jackbits;
> +
> +	/* choose delay *before* checking presence so we still get
> +	 * one long delay on first insertion to help with debounce.
> +	 */
> +	if (jack.present)
> +		delay = msecs_to_jiffies(50);
>
>  	val = twl4030_get_madc_conversion(7);
> -	if (val < 100)
> -		snd_soc_jack_report(&jack.hs_jack, 0, SND_JACK_HEADSET);
> -	else
> -		snd_soc_jack_report(&jack.hs_jack, SND_JACK_HEADSET,
> -				     SND_JACK_HEADSET);
> +	/* On my device:
> +	 * open circuit = around 20
> +	 * short circuit = around 800
> +	 * microphone   = around 830-840 !!!
> +	 */
> +	if (val < 100) {
> +		/* open circuit */
> +		jackbits = 0;
> +		jack.present = 0;
> +		/* debounce */
> +		delay = msecs_to_jiffies(500);
> +	} else if (val < 820) {
> +		/* short */
> +		if (jack.present == 0) {
> +			/* Inserted headset with no mic */
> +			jack.present = SND_JACK_HEADPHONE;
> +			jackbits = jack.present;
> +		} else if (jack.present & SND_JACK_MICROPHONE) {
> +			/* mic shorter == button press */
> +			jackbits = SND_JACK_BTN_0 | jack.present;
> +		} else {
> +			/* headphones still present */
> +			jackbits = jack.present;
> +		}
> +	} else {
> +		/* There is a microphone there */
> +		jack.present = SND_JACK_HEADSET;
> +		jackbits = jack.present;
> +	}
> +	snd_soc_jack_report(&jack.hs_jack, jackbits,
> +			    SND_JACK_HEADSET | SND_JACK_BTN_0);
> +
>  	if (jack.open)
> -		schedule_delayed_work(&jack.jack_work, msecs_to_jiffies(500));
> +		schedule_delayed_work(&jack.jack_work, delay);
>  }
>
>  static int gta04_audio_suspend(struct snd_soc_card *card)
> @@ -237,7 +280,8 @@ static int omap3gta04_init(struct snd_soc_pcm_runtime
> *runtime)
>  	 * but we need to poll :-(
>  	 */
>  	ret = snd_soc_jack_new(codec, "Headset Jack",
> -			       SND_JACK_HEADSET, &jack.hs_jack);
> +			       SND_JACK_HEADSET | SND_JACK_BTN_0,
> +			       &jack.hs_jack);
>  	if (ret)
>  		return ret;
>  	INIT_DELAYED_WORK(&jack.jack_work, gta04_audio_jack_work);
>
>
> NeilBrown
>


-- 
 The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
 how) you may access your data; but nobody's threatening your freedom: we
 still allow you to remove your data and not access it at all."


More information about the Gta04-owner mailing list