diff options
author | Paul Kocialkowski <contact@paulk.fr> | 2013-05-19 19:08:04 +0200 |
---|---|---|
committer | Denis 'GNUtoo' Carikli <GNUtoo@no-log.org> | 2013-05-19 19:13:46 +0200 |
commit | 399f8eafa3e3d2899ca3f8272cb79b9c9e5c60b7 (patch) | |
tree | 757871e293fc96947f547b56e5af3ffc018e1683 | |
parent | 7d7b608c38e15e2072d5fcc7e9af3315028a2763 (diff) | |
download | kernel_goldelico_gta04-399f8eafa3e3d2899ca3f8272cb79b9c9e5c60b7.zip kernel_goldelico_gta04-399f8eafa3e3d2899ca3f8272cb79b9c9e5c60b7.tar.gz kernel_goldelico_gta04-399f8eafa3e3d2899ca3f8272cb79b9c9e5c60b7.tar.bz2 |
ASoC: omap: GTA04: Headset detection with Android h2w switch
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
-rw-r--r-- | sound/soc/omap/gta04-audio.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/sound/soc/omap/gta04-audio.c b/sound/soc/omap/gta04-audio.c index 8d802d1..91b4867 100644 --- a/sound/soc/omap/gta04-audio.c +++ b/sound/soc/omap/gta04-audio.c @@ -23,8 +23,11 @@ #include <linux/clk.h> #include <linux/platform_device.h> #include <linux/module.h> +#include <linux/input.h> +#include <linux/switch.h> #include <sound/core.h> #include <sound/pcm.h> +#include <sound/jack.h> #include <sound/soc.h> #include <sound/soc-dapm.h> @@ -33,6 +36,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 +141,56 @@ static const struct snd_soc_dapm_route audio_map[] = { */ }; +static enum { + H2W_HEADSET_MISSING = 0x00, + H2W_HEADSET_MIC = 0x01 << 0, + H2W_HEADSET_NOMIC = 0x01 << 1, +}; + +static struct { + struct delayed_work work; + struct snd_soc_codec *codec; + struct switch_dev h2w_switch; + int open; +} gta04_jack; + +static void gta04_audio_jack_work(struct work_struct *work) +{ + long val; + + val = twl4030_get_madc_conversion(7); + if (val < 100) + switch_set_state(>a04_jack.h2w_switch, H2W_HEADSET_MISSING); + else if (val < 825) + switch_set_state(>a04_jack.h2w_switch, H2W_HEADSET_NOMIC); + else + switch_set_state(>a04_jack.h2w_switch, H2W_HEADSET_MIC); + + if (gta04_jack.open) + schedule_delayed_work(>a04_jack.work, msecs_to_jiffies(500)); +} + +static int gta04_audio_suspend(struct snd_soc_card *card) +{ + if (gta04_jack.codec) { + snd_soc_dapm_disable_pin(>a04_jack.codec->dapm, "Headset Mic Bias"); + snd_soc_dapm_sync(>a04_jack.codec->dapm); + gta04_jack.open = 0; + } + return 0; +} + +static int gta04_audio_resume(struct snd_soc_card *card) +{ + if (gta04_jack.codec) { + snd_soc_dapm_force_enable_pin(>a04_jack.codec->dapm, "Headset Mic Bias"); + snd_soc_dapm_sync(>a04_jack.codec->dapm); + schedule_delayed_work(>a04_jack.work, msecs_to_jiffies(500)); + gta04_jack.open = 1; + } + return 0; +} + static int omap3gta04_init(struct snd_soc_pcm_runtime *runtime) { int ret; @@ -172,7 +227,21 @@ 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"); - + + gta04_jack.h2w_switch.name = "h2w"; + ret = switch_dev_register(>a04_jack.h2w_switch); + if (ret < 0) { + pr_err("%s : Failed to register switch device\n", __func__); + return ret; + } + + gta04_jack.codec = codec; + gta04_jack.open = 1; + + INIT_DELAYED_WORK(>a04_jack.work, gta04_audio_jack_work); + schedule_delayed_work(>a04_jack.work, msecs_to_jiffies(500)); + + snd_soc_dapm_force_enable_pin(dapm, "Headset Mic Bias"); return snd_soc_dapm_sync(dapm); } @@ -198,6 +267,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; |