[Gta04-owner] Headset detection.

Paul Kocialkowski paulk at paulk.fr
Mon Aug 27 13:11:42 CEST 2012


Le samedi 18 août 2012 à 10:13 +1000, NeilBrown a écrit :
> I've push out a patch to my 3.5 branch which provides headset detection
> support.  It is included below.

Can you confirm that it still works after recording from the mic?
I think after recording, the headset mic bias gets disabled.

> 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




More information about the Gta04-owner mailing list