summaryrefslogtreecommitdiffstats
path: root/sound/soc/ti
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2019-09-09 15:55:18 +0200
committerMark Brown <broonie@kernel.org>2019-09-09 15:55:18 +0200
commit6652ddbb5d83ecfc2591b92be063519714e40ebf (patch)
treeb1d088382aadb792e703b2f4035e0fc6584ca3c1 /sound/soc/ti
parentLinux 5.3-rc8 (diff)
parentASoC: ams-delta: Take control over audio mute GPIO pins (diff)
downloadlinux-6652ddbb5d83ecfc2591b92be063519714e40ebf.tar.xz
linux-6652ddbb5d83ecfc2591b92be063519714e40ebf.zip
Merge branch 'asoc-5.3' into asoc-linus
Diffstat (limited to 'sound/soc/ti')
-rw-r--r--sound/soc/ti/ams-delta.c31
-rw-r--r--sound/soc/ti/davinci-i2s.c82
2 files changed, 63 insertions, 50 deletions
diff --git a/sound/soc/ti/ams-delta.c b/sound/soc/ti/ams-delta.c
index dee8fc70a64f..8e2fb81ad05c 100644
--- a/sound/soc/ti/ams-delta.c
+++ b/sound/soc/ti/ams-delta.c
@@ -23,14 +23,31 @@
#include "omap-mcbsp.h"
#include "../codecs/cx20442.h"
+static struct gpio_desc *handset_mute;
+static struct gpio_desc *handsfree_mute;
+
+static int ams_delta_event_handset(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ gpiod_set_value_cansleep(handset_mute, !SND_SOC_DAPM_EVENT_ON(event));
+ return 0;
+}
+
+static int ams_delta_event_handsfree(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ gpiod_set_value_cansleep(handsfree_mute, !SND_SOC_DAPM_EVENT_ON(event));
+ return 0;
+}
+
/* Board specific DAPM widgets */
static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = {
/* Handset */
SND_SOC_DAPM_MIC("Mouthpiece", NULL),
- SND_SOC_DAPM_HP("Earpiece", NULL),
+ SND_SOC_DAPM_HP("Earpiece", ams_delta_event_handset),
/* Handsfree/Speakerphone */
SND_SOC_DAPM_MIC("Microphone", NULL),
- SND_SOC_DAPM_SPK("Speaker", NULL),
+ SND_SOC_DAPM_SPK("Speaker", ams_delta_event_handsfree),
};
/* How they are connected to codec pins */
@@ -542,6 +559,16 @@ static int ams_delta_probe(struct platform_device *pdev)
card->dev = &pdev->dev;
+ handset_mute = devm_gpiod_get(card->dev, "handset_mute",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(handset_mute))
+ return PTR_ERR(handset_mute);
+
+ handsfree_mute = devm_gpiod_get(card->dev, "handsfree_mute",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(handsfree_mute))
+ return PTR_ERR(handsfree_mute);
+
ret = snd_soc_register_card(card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
diff --git a/sound/soc/ti/davinci-i2s.c b/sound/soc/ti/davinci-i2s.c
index 92c1bdc69086..27afdbb9adf3 100644
--- a/sound/soc/ti/davinci-i2s.c
+++ b/sound/soc/ti/davinci-i2s.c
@@ -187,57 +187,9 @@ static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback)
static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
u32 spcr;
u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
- spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
- if (spcr & mask) {
- /* start off disabled */
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
- spcr & ~mask);
- toggle_clock(dev, playback);
- }
- if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM |
- DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM)) {
- /* Start the sample generator */
- spcr |= DAVINCI_MCBSP_SPCR_GRST;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
- }
-
- if (playback) {
- /* Stop the DMA to avoid data loss */
- /* while the transmitter is out of reset to handle XSYNCERR */
- if (component->driver->ops->trigger) {
- int ret = component->driver->ops->trigger(substream,
- SNDRV_PCM_TRIGGER_STOP);
- if (ret < 0)
- printk(KERN_DEBUG "Playback DMA stop failed\n");
- }
-
- /* Enable the transmitter */
- spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
- spcr |= DAVINCI_MCBSP_SPCR_XRST;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
-
- /* wait for any unexpected frame sync error to occur */
- udelay(100);
-
- /* Disable the transmitter to clear any outstanding XSYNCERR */
- spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
- spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
- davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
- toggle_clock(dev, playback);
-
- /* Restart the DMA */
- if (component->driver->ops->trigger) {
- int ret = component->driver->ops->trigger(substream,
- SNDRV_PCM_TRIGGER_START);
- if (ret < 0)
- printk(KERN_DEBUG "Playback DMA start failed\n");
- }
- }
/* Enable transmitter or receiver */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
@@ -575,7 +527,41 @@ static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
{
struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+ u32 spcr;
+ u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
+
davinci_mcbsp_stop(dev, playback);
+
+ spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
+ if (spcr & mask) {
+ /* start off disabled */
+ davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
+ spcr & ~mask);
+ toggle_clock(dev, playback);
+ }
+ if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM |
+ DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM)) {
+ /* Start the sample generator */
+ spcr |= DAVINCI_MCBSP_SPCR_GRST;
+ davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
+ }
+
+ if (playback) {
+ /* Enable the transmitter */
+ spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
+ spcr |= DAVINCI_MCBSP_SPCR_XRST;
+ davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
+
+ /* wait for any unexpected frame sync error to occur */
+ udelay(100);
+
+ /* Disable the transmitter to clear any outstanding XSYNCERR */
+ spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
+ spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
+ davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
+ toggle_clock(dev, playback);
+ }
+
return 0;
}