aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/gta04-audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/omap/gta04-audio.c')
-rw-r--r--sound/soc/omap/gta04-audio.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/sound/soc/omap/gta04-audio.c b/sound/soc/omap/gta04-audio.c
index d998aae..b5cbe37 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>
@@ -32,6 +34,8 @@
#include <mach/hardware.h>
#include <mach/gpio.h>
+#include <linux/i2c/twl4030-madc.h>
+
#include "omap-mcbsp.h"
#include "omap-pcm.h"
#include "../codecs/twl4030.h"
@@ -135,6 +139,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;
@@ -171,6 +231,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);
}
@@ -199,6 +271,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;