diff options
author | Xinyu Chen <xinyu.chen@freescale.com> | 2013-01-04 13:41:54 +0800 |
---|---|---|
committer | Xinyu Chen <xinyu.chen@freescale.com> | 2013-01-04 13:41:54 +0800 |
commit | ccce7dc63f494aaed6bd3ea55b9e14c76da0931e (patch) | |
tree | 6892e44aff8fda5dac08bb0aefa6a0d9b3b92af2 /sound | |
parent | 60daab290bbab00c73cc057ff868f658ec73d304 (diff) | |
parent | c27cb3851bb6f822f8a92e4a1e10fba19284bdd4 (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.c | 55 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 7 |
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; } |