summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2013-01-04 13:41:54 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2013-01-04 13:41:54 +0800
commitccce7dc63f494aaed6bd3ea55b9e14c76da0931e (patch)
tree6892e44aff8fda5dac08bb0aefa6a0d9b3b92af2 /sound
parent60daab290bbab00c73cc057ff868f658ec73d304 (diff)
parentc27cb3851bb6f822f8a92e4a1e10fba19284bdd4 (diff)
Merge tag 'rel_imx_3.0.35_1.1.0' into imx_3.0.35_android
Conflicts: drivers/mxc/vpu/mxc_vpu.c drivers/usb/gadget/arcotg_udc.c sound/soc/imx/imx-wm8962.c
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/imx/imx-wm8962.c55
-rw-r--r--sound/soc/soc-core.c7
2 files changed, 59 insertions, 3 deletions
diff --git a/sound/soc/imx/imx-wm8962.c b/sound/soc/imx/imx-wm8962.c
index a9e52d3bdaf6..ad8e5fd94e02 100644
--- a/sound/soc/imx/imx-wm8962.c
+++ b/sound/soc/imx/imx-wm8962.c
@@ -28,7 +28,7 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/switch.h>
-
+#include <linux/kthread.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -60,6 +60,10 @@ unsigned int sample_format = SNDRV_PCM_FMTBIT_S16_LE;
static struct imx_priv card_priv;
static struct snd_soc_card snd_soc_card_imx;
static struct snd_soc_codec *gcodec;
+static int suspend_hp_flag;
+static int suspend_mic_flag;
+static int hp_irq;
+static int mic_irq;
static int imx_hifi_startup(struct snd_pcm_substream *substream)
{
@@ -215,6 +219,11 @@ static void headphone_detect_handler(struct work_struct *wor)
kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
kfree(buf);
+ if ((suspend_hp_flag == 1) && (hp_irq == 0)) {
+ suspend_hp_flag = 0;
+ return;
+ }
+ hp_irq = 0;
enable_irq(priv->hp_irq);
return;
@@ -224,6 +233,10 @@ static DECLARE_DELAYED_WORK(hp_event, headphone_detect_handler);
static irqreturn_t imx_headphone_detect_handler(int irq, void *data)
{
+ if (suspend_hp_flag == 1)
+ return IRQ_HANDLED;
+
+ hp_irq = 1;
disable_irq_nosync(irq);
schedule_delayed_work(&hp_event, msecs_to_jiffies(200));
return IRQ_HANDLED;
@@ -288,6 +301,11 @@ static void amic_detect_handler(struct work_struct *work)
kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, envp);
kfree(buf);
+ if ((suspend_mic_flag == 1) && (mic_irq == 0)) {
+ suspend_mic_flag = 0;
+ return;
+ }
+ mic_irq = 0;
enable_irq(priv->amic_irq);
}
@@ -295,6 +313,10 @@ static DECLARE_DELAYED_WORK(amic_event, amic_detect_handler);
static irqreturn_t imx_amic_detect_handler(int irq, void *data)
{
+ if (suspend_mic_flag == 1)
+ return IRQ_HANDLED;
+
+ mic_irq = 1;
disable_irq_nosync(irq);
schedule_delayed_work(&amic_event, msecs_to_jiffies(200));
return IRQ_HANDLED;
@@ -319,6 +341,32 @@ static ssize_t show_amic(struct device_driver *dev, char *buf)
static DRIVER_ATTR(amic, S_IRUGO | S_IWUSR, show_amic, NULL);
+static DECLARE_DELAYED_WORK(resume_hp_event, headphone_detect_handler);
+static DECLARE_DELAYED_WORK(resume_mic_event, amic_detect_handler);
+
+
+int imx_hifi_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct imx_priv *priv = &card_priv;
+ struct platform_device *pdev = priv->pdev;
+ struct mxc_audio_platform_data *plat = pdev->dev.platform_data;
+
+ if (SNDRV_PCM_TRIGGER_SUSPEND == cmd) {
+ suspend_hp_flag = 1;
+ suspend_mic_flag = 1;
+ }
+ if (SNDRV_PCM_TRIGGER_RESUME == cmd) {
+ if (plat->hp_gpio != -1)
+ schedule_delayed_work(&resume_hp_event,
+ msecs_to_jiffies(200));
+ if (plat->mic_gpio != -1)
+ schedule_delayed_work(&resume_mic_event,
+ msecs_to_jiffies(200));
+ }
+
+ return 0;
+}
+
static int imx_wm8962_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
@@ -339,8 +387,6 @@ static int imx_wm8962_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack");
snd_soc_dapm_enable_pin(&codec->dapm, "AMIC");
- snd_soc_dapm_sync(&codec->dapm);
-
if (plat->hp_gpio != -1) {
priv->hp_irq = gpio_to_irq(plat->hp_gpio);
@@ -397,6 +443,8 @@ static int imx_wm8962_init(struct snd_soc_pcm_runtime *rtd)
} else if (!snd_soc_dapm_get_pin_status(&codec->dapm, "DMICDAT"))
snd_soc_dapm_nc_pin(&codec->dapm, "DMIC");
+ snd_soc_dapm_sync(&codec->dapm);
+
return 0;
}
@@ -404,6 +452,7 @@ static struct snd_soc_ops imx_hifi_ops = {
.startup = imx_hifi_startup,
.shutdown = imx_hifi_shutdown,
.hw_params = imx_hifi_hw_params,
+ .trigger = imx_hifi_trigger,
};
static struct snd_soc_dai_link imx_dai[] = {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ad12a4c17b72..e62ad5ffce66 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -5,6 +5,7 @@
* Copyright 2005 Openedhand Ltd.
* Copyright (C) 2010 Slimlogic Ltd.
* Copyright (C) 2010 Texas Instruments Inc.
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
*
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
* with code, comments and ideas from :-
@@ -986,6 +987,12 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
if (ret < 0)
return ret;
}
+
+ if (rtd->dai_link->ops && rtd->dai_link->ops->trigger) {
+ ret = rtd->dai_link->ops->trigger(substream, cmd);
+ if (ret < 0)
+ return ret;
+ }
return 0;
}