aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2013-05-19 19:08:04 +0200
committerDenis 'GNUtoo' Carikli <GNUtoo@no-log.org>2013-05-19 19:13:46 +0200
commit399f8eafa3e3d2899ca3f8272cb79b9c9e5c60b7 (patch)
tree757871e293fc96947f547b56e5af3ffc018e1683
parent7d7b608c38e15e2072d5fcc7e9af3315028a2763 (diff)
downloadkernel_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.c73
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(&gta04_jack.h2w_switch, H2W_HEADSET_MISSING);
+ else if (val < 825)
+ switch_set_state(&gta04_jack.h2w_switch, H2W_HEADSET_NOMIC);
+ else
+ switch_set_state(&gta04_jack.h2w_switch, H2W_HEADSET_MIC);
+
+ if (gta04_jack.open)
+ schedule_delayed_work(&gta04_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(&gta04_jack.codec->dapm, "Headset Mic Bias");
+ snd_soc_dapm_sync(&gta04_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(&gta04_jack.codec->dapm, "Headset Mic Bias");
+ snd_soc_dapm_sync(&gta04_jack.codec->dapm);
+ schedule_delayed_work(&gta04_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(&gta04_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(&gta04_jack.work, gta04_audio_jack_work);
+ schedule_delayed_work(&gta04_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;