[Gta04-owner] Headset detection.

NeilBrown neilb at suse.de
Wed Aug 22 03:08:43 CEST 2012


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:
> 
> > Hi all,
> > 
> > I've push out a patch to my 3.5 branch which provides headset detection
> > support.  It is included below.
> 
> ++
> 
> > It currently just report Headphones and Mic, or neither.
> > To do any better than that we need some sort of standard for resistance
> > between 'shield' and 'ring-1' on different cables (such as headset versus
> > line-in versus AV-out).
> 
> Hm. Could you simply report the measured resistance in Ohms?
> Then, it is easy to define thresholds in drivers and user interface code.

My preferred approach is to have hardware abstraction happen in the kernel,
so I'd really like to be able to give thresholds too the kernel and have it
report appropriate events.  It remains to be seen if that is practical.

> 
> > 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...

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).


> 
> The circuit was inspired by the Sharp CE-RH2 remote control. I think
> I mentioned it recently:
> 
> http://lists.goldelico.com/pipermail/gta04-owner/2012-May/002325.html
> 
> It is "standardized" here:
> 
> http://www.penguin.cz/~utx/zaurus/hardware
> http://www.relei.de/zaurusfernb.html
> 
> Hope this helps to make a good and universal driver solution.

If anyone has a remote like this and can report the in7_input numbers it
should be easy enough to modify the driver to report the keys.

Thanks,
NeilBrown


> 
> BR,
> Nikolaus
> 
> > 
> > NeilBrown
> > 
> > 
> > commit cd6d6b9bc7f7a4e501fb2b6434af856963cc2d79
> > Author: NeilBrown <neilb at suse.de>
> > Date:   Sat Aug 18 07:58:33 2012 +1000
> > 
> >    GTA04: add simple headset-jack detection support.
> > 
> >    As headset-insert doesn't generate an interrupt we need to
> >    poll the MICSENSE line to see if a headset is present.
> >    We do this every 500ms.  It takes nearly that long to physically
> >    insert a jack, so much faster wouldn't help and would impact
> >    power drain more.
> > 
> >    As detection is done by polling, a jack-insert or removal event cannot
> >    wake the device from suspend.  Events are only detected while device
> >    is awake.
> > 
> >    We keep the HSMIC bias enabled whenever the 'input' device is open,
> >    except during suspend so that we can poll reliably.  Turning it off
> >    and on seems to interfere with reliable measurements.
> > 
> >    Currently a reading below 100 is 'nothing plugged in' while a reading
> >    above that is 'mic and headphone plugged in'.
> >    I measure between 19 and 26 when nothing is plugged in, and between
> >    804 and 811 when a headset is plugged in.
> > 
> >    Input device will appear as
> >        /dev/input/jack
> >    if the udev rules file in GTA04/udev-rules/input.rules
> >    is installed.
> > 
> >    Signed-off-by: NeilBrown <neilb at suse.de>
> > 
> > diff --git a/GTA04/udev-rules/input.rules b/GTA04/udev-rules/input.rules
> > index 87782ec..a96feb8 100644
> > --- a/GTA04/udev-rules/input.rules
> > +++ b/GTA04/udev-rules/input.rules
> > @@ -4,3 +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"
> > diff --git a/sound/soc/omap/gta04-audio.c b/sound/soc/omap/gta04-audio.c
> > index 67867f0..1048098 100644
> > --- a/sound/soc/omap/gta04-audio.c
> > +++ b/sound/soc/omap/gta04-audio.c
> > @@ -23,8 +23,10 @@
> > #include <linux/clk.h>
> > #include <linux/platform_device.h>
> > #include <linux/module.h>
> > +#include <linux/input.h>
> > #include <sound/core.h>
> > #include <sound/pcm.h>
> > +#include <sound/jack.h>
> > #include <sound/soc.h>
> > #include <sound/soc-dapm.h>
> > 
> > @@ -33,6 +35,8 @@
> > #include <mach/gpio.h>
> > #include <plat/mcbsp.h>
> > 
> > +#include <linux/i2c/twl4030-madc.h>
> > +
> > #include "omap-mcbsp.h"
> > #include "omap-pcm.h"
> > #include "../codecs/twl4030.h"
> > @@ -136,6 +140,62 @@ static const struct snd_soc_dapm_route audio_map[] = {
> > 	 */
> > };
> > 
> > +static struct {
> > +	struct snd_soc_jack hs_jack;
> > +	struct delayed_work jack_work;
> > +	struct snd_soc_codec *codec;
> > +	int open;
> > +} jack;
> > +
> > +static void gta04_audio_jack_work(struct work_struct *work)
> > +{
> > +	long val;
> > +
> > +	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);
> > +	if (jack.open)
> > +		schedule_delayed_work(&jack.jack_work, msecs_to_jiffies(500));
> > +}
> > +
> > +static int gta04_audio_suspend(struct snd_soc_card *card)
> > +{
> > +	if (jack.codec) {
> > +		snd_soc_dapm_disable_pin(&jack.codec->dapm, "Headset Mic Bias");
> > +		snd_soc_dapm_sync(&jack.codec->dapm);
> > +	}
> > +	return 0;
> > +}
> > +
> > +static int gta04_audio_resume(struct snd_soc_card *card)
> > +{
> > +	if (jack.codec && jack.open) {
> > +		snd_soc_dapm_force_enable_pin(&jack.codec->dapm, "Headset Mic Bias");
> > +		snd_soc_dapm_sync(&jack.codec->dapm);
> > +	}
> > +	return 0;
> > +}
> > +
> > +static int gta04_jack_open(struct input_dev *dev)
> > +{
> > +	snd_soc_dapm_force_enable_pin(&jack.codec->dapm, "Headset Mic Bias");
> > +	snd_soc_dapm_sync(&jack.codec->dapm);
> > +	jack.open = 1;
> > +	schedule_delayed_work(&jack.jack_work, msecs_to_jiffies(100));
> > +	return 0;
> > +}
> > +
> > +static void gta04_jack_close(struct input_dev *dev)
> > +{
> > +	jack.open = 0;
> > +	cancel_delayed_work_sync(&jack.jack_work);
> > +	snd_soc_dapm_disable_pin(&jack.codec->dapm, "Headset Mic Bias");
> > +	snd_soc_dapm_sync(&jack.codec->dapm);
> > +}
> > +
> > static int omap3gta04_init(struct snd_soc_pcm_runtime *runtime)
> > {
> > 	int ret;
> > @@ -172,6 +232,18 @@ static int omap3gta04_init(struct snd_soc_pcm_runtime *runtime)
> > 	//	snd_soc_dapm_nc_pin(codec, "HSMIC");
> > 	snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
> > 	snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
> > +
> > +	/* We can detect when something is plugged in,
> > +	 * but we need to poll :-(
> > +	 */
> > +	ret = snd_soc_jack_new(codec, "Headset Jack",
> > +			       SND_JACK_HEADSET, &jack.hs_jack);
> > +	if (ret)
> > +		return ret;
> > +	INIT_DELAYED_WORK(&jack.jack_work, gta04_audio_jack_work);
> > +	jack.codec = codec;
> > +	jack.hs_jack.jack->input_dev->open = gta04_jack_open;
> > +	jack.hs_jack.jack->input_dev->close = gta04_jack_close;
> > 		
> > 	return snd_soc_dapm_sync(dapm);
> > }
> > @@ -200,6 +272,8 @@ static struct snd_soc_card snd_soc_omap3gta04 = {
> > 	.owner = THIS_MODULE,
> > 	.dai_link = &omap3gta04_dai,
> > 	.num_links = 1,
> > +	.suspend_pre = gta04_audio_suspend,
> > +	.resume_post = gta04_audio_resume,
> > };
> > 
> > static struct platform_device *omap3gta04_snd_device;
> > _______________________________________________
> > Gta04-owner mailing list
> > Gta04-owner at goldelico.com
> > http://lists.goldelico.com/mailman/listinfo/gta04-owner
> 
> _______________________________________________
> Gta04-owner mailing list
> Gta04-owner at goldelico.com
> http://lists.goldelico.com/mailman/listinfo/gta04-owner

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 828 bytes
Desc: not available
URL: <http://lists.goldelico.com/pipermail/gta04-owner/attachments/20120822/f7f39ff5/attachment.bin>


More information about the Gta04-owner mailing list