All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] ASoC: omap-mcpdm: Fix for full duplex audio
@ 2013-03-20  9:47 Peter Ujfalusi
  2013-03-20  9:47 ` [PATCH 1/3] ASoC: omap-mcpdm: Collect link direction configuration under a struct Peter Ujfalusi
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Peter Ujfalusi @ 2013-03-20  9:47 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Misael Lopez Cruz, Jyri Sarha

Hi,

We had this issue for a long time but I had no time to think and fix it.
With this series the full duplex audio will work correctly with McPDM.

Under the hood we have HW limitation which prevents us to start up/downlink
separately.

Regards,
Peter
---
Peter Ujfalusi (3):
  ASoC: omap-mcpdm: Collect link direction configuration under a struct
  ASoC: omap-mcpdm: Fix for full duplex audio use case
  ASoC: omap-mcpdm: Remove leftower define for IO address

 sound/soc/omap/omap-mcpdm.c | 66 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 48 insertions(+), 18 deletions(-)

-- 
1.8.1.5

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] ASoC: omap-mcpdm: Collect link direction configuration under a struct
  2013-03-20  9:47 [PATCH 0/3] ASoC: omap-mcpdm: Fix for full duplex audio Peter Ujfalusi
@ 2013-03-20  9:47 ` Peter Ujfalusi
  2013-03-20 10:00   ` Mark Brown
  2013-03-20  9:47 ` [PATCH 2/3] ASoC: omap-mcpdm: Fix for full duplex audio use case Peter Ujfalusi
  2013-03-20  9:47 ` [PATCH 3/3] ASoC: omap-mcpdm: Remove leftower define for IO address Peter Ujfalusi
  2 siblings, 1 reply; 5+ messages in thread
From: Peter Ujfalusi @ 2013-03-20  9:47 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Misael Lopez Cruz, Jyri Sarha

mcpdm_link_config will collect the link direction related configurations like
channel masks, FIFO threshold.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 sound/soc/omap/omap-mcpdm.c | 41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index ddfcc18..6e19f44 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -45,6 +45,11 @@
 
 #define OMAP44XX_MCPDM_L3_BASE		0x49032000
 
+struct mcpdm_link_config {
+	u32 link_mask; /* channel mask for the direction */
+	u32 threshold; /* FIFO threshold */
+};
+
 struct omap_mcpdm {
 	struct device *dev;
 	unsigned long phys_base;
@@ -53,13 +58,8 @@ struct omap_mcpdm {
 
 	struct mutex mutex;
 
-	/* channel data */
-	u32 dn_channels;
-	u32 up_channels;
-
-	/* McPDM FIFO thresholds */
-	u32 dn_threshold;
-	u32 up_threshold;
+	/* Playback/Capture configuration */
+	struct mcpdm_link_config config[2];
 
 	/* McPDM dn offsets for rx1, and 2 channels */
 	u32 dn_rx_offset;
@@ -130,11 +130,12 @@ static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {}
 static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
 {
 	u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
+	u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask;
 
 	ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
 	omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
 
-	ctrl |= mcpdm->dn_channels | mcpdm->up_channels;
+	ctrl |= link_mask;
 	omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
 
 	ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
@@ -148,11 +149,12 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
 static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
 {
 	u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
+	u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask;
 
 	ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
 	omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
 
-	ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels);
+	ctrl &= ~(link_mask);
 	omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
 
 	ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
@@ -188,8 +190,10 @@ static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
 		omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset);
 	}
 
-	omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold);
-	omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold);
+	omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN,
+			 mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold);
+	omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP,
+			 mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold);
 
 	omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET,
 			MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE);
@@ -296,6 +300,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
 	struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
 	int stream = substream->stream;
 	struct omap_pcm_dma_data *dma_data;
+	u32 threshold;
 	int channels;
 	int link_mask = 0;
 
@@ -325,15 +330,16 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
 
 	dma_data = snd_soc_dai_get_dma_data(dai, substream);
 
+	threshold = mcpdm->config[stream].threshold;
 	/* Configure McPDM channels, and DMA packet size */
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		mcpdm->dn_channels = link_mask << 3;
+		link_mask <<= 3;
 		dma_data->packet_size =
-			(MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels;
+				(MCPDM_DN_THRES_MAX - threshold) * channels;
 	} else {
-		mcpdm->up_channels = link_mask << 0;
-		dma_data->packet_size = mcpdm->up_threshold * channels;
+		dma_data->packet_size = threshold * channels;
 	}
+	mcpdm->config[stream].link_mask = link_mask;
 
 	return 0;
 }
@@ -380,8 +386,9 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
 	}
 
 	/* Configure McPDM threshold values */
-	mcpdm->dn_threshold = 2;
-	mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3;
+	mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2;
+	mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold =
+							MCPDM_UP_THRES_MAX - 3;
 	return ret;
 }
 
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] ASoC: omap-mcpdm: Fix for full duplex audio use case
  2013-03-20  9:47 [PATCH 0/3] ASoC: omap-mcpdm: Fix for full duplex audio Peter Ujfalusi
  2013-03-20  9:47 ` [PATCH 1/3] ASoC: omap-mcpdm: Collect link direction configuration under a struct Peter Ujfalusi
@ 2013-03-20  9:47 ` Peter Ujfalusi
  2013-03-20  9:47 ` [PATCH 3/3] ASoC: omap-mcpdm: Remove leftower define for IO address Peter Ujfalusi
  2 siblings, 0 replies; 5+ messages in thread
From: Peter Ujfalusi @ 2013-03-20  9:47 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Misael Lopez Cruz, Jyri Sarha

Due to HW limitation within OMAP McPDM IP uplink and downlink need to be
started at the same time. This causes issues when we have two streams
running, for example:
arecord | aplay

In this case the playback stream would have no channels enabled since at the
capture start we are not aware that a playback is going to start.

The workaround is to configure the other direction to stereo when the first
stream is started. When the second stream is coming we check the new stream's
number of channels against the pre-configured channels. If it does not match
we stop and restart McPDM to update the configuration. This might result a
small pop. If the coming stream is a match we do nothing in the McPDM driver.

This workaround can handle most use cases without the need to restart McPDM.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 sound/soc/omap/omap-mcpdm.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 6e19f44..cd0e2ec 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -63,6 +63,9 @@ struct omap_mcpdm {
 
 	/* McPDM dn offsets for rx1, and 2 channels */
 	u32 dn_rx_offset;
+
+	/* McPDM needs to be restarted due to runtime reconfiguration */
+	bool restart;
 };
 
 /*
@@ -149,7 +152,7 @@ static void omap_mcpdm_start(struct omap_mcpdm *mcpdm)
 static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm)
 {
 	u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
-	u32 link_mask = mcpdm->config[0].link_mask | mcpdm->config[1].link_mask;
+	u32 link_mask = MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK;
 
 	ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST);
 	omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl);
@@ -287,6 +290,8 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
 		if (omap_mcpdm_active(mcpdm)) {
 			omap_mcpdm_stop(mcpdm);
 			omap_mcpdm_close_streams(mcpdm);
+			mcpdm->config[0].link_mask = 0;
+			mcpdm->config[1].link_mask = 0;
 		}
 	}
 
@@ -334,11 +339,26 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
 	/* Configure McPDM channels, and DMA packet size */
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		link_mask <<= 3;
+
+		/* If capture is not running assume a stereo stream to come */
+		if (!mcpdm->config[!stream].link_mask)
+			mcpdm->config[!stream].link_mask = 0x3;
+
 		dma_data->packet_size =
 				(MCPDM_DN_THRES_MAX - threshold) * channels;
 	} else {
+		/* If playback is not running assume a stereo stream to come */
+		if (!mcpdm->config[!stream].link_mask)
+			mcpdm->config[!stream].link_mask = (0x3 << 3);
+
 		dma_data->packet_size = threshold * channels;
 	}
+
+	/* Check if we need to restart McPDM with this stream */
+	if (mcpdm->config[stream].link_mask &&
+	    mcpdm->config[stream].link_mask != link_mask)
+		mcpdm->restart = true;
+
 	mcpdm->config[stream].link_mask = link_mask;
 
 	return 0;
@@ -352,6 +372,11 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
 	if (!omap_mcpdm_active(mcpdm)) {
 		omap_mcpdm_start(mcpdm);
 		omap_mcpdm_reg_dump(mcpdm);
+	} else if (mcpdm->restart) {
+		omap_mcpdm_stop(mcpdm);
+		omap_mcpdm_start(mcpdm);
+		mcpdm->restart = false;
+		omap_mcpdm_reg_dump(mcpdm);
 	}
 
 	return 0;
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] ASoC: omap-mcpdm: Remove leftower define for IO address
  2013-03-20  9:47 [PATCH 0/3] ASoC: omap-mcpdm: Fix for full duplex audio Peter Ujfalusi
  2013-03-20  9:47 ` [PATCH 1/3] ASoC: omap-mcpdm: Collect link direction configuration under a struct Peter Ujfalusi
  2013-03-20  9:47 ` [PATCH 2/3] ASoC: omap-mcpdm: Fix for full duplex audio use case Peter Ujfalusi
@ 2013-03-20  9:47 ` Peter Ujfalusi
  2 siblings, 0 replies; 5+ messages in thread
From: Peter Ujfalusi @ 2013-03-20  9:47 UTC (permalink / raw)
  To: Mark Brown, Liam Girdwood; +Cc: alsa-devel, Misael Lopez Cruz, Jyri Sarha

The IO address is no longer hardwired into the driver.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 sound/soc/omap/omap-mcpdm.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index cd0e2ec..e1d3998 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -43,8 +43,6 @@
 #include "omap-mcpdm.h"
 #include "omap-pcm.h"
 
-#define OMAP44XX_MCPDM_L3_BASE		0x49032000
-
 struct mcpdm_link_config {
 	u32 link_mask; /* channel mask for the direction */
 	u32 threshold; /* FIFO threshold */
-- 
1.8.1.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/3] ASoC: omap-mcpdm: Collect link direction configuration under a struct
  2013-03-20  9:47 ` [PATCH 1/3] ASoC: omap-mcpdm: Collect link direction configuration under a struct Peter Ujfalusi
@ 2013-03-20 10:00   ` Mark Brown
  0 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2013-03-20 10:00 UTC (permalink / raw)
  To: Peter Ujfalusi; +Cc: Liam Girdwood, alsa-devel, Misael Lopez Cruz, Jyri Sarha


[-- Attachment #1.1: Type: text/plain, Size: 199 bytes --]

On Wed, Mar 20, 2013 at 10:47:12AM +0100, Peter Ujfalusi wrote:
> mcpdm_link_config will collect the link direction related configurations like
> channel masks, FIFO threshold.

Applied all, thanks.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-03-20 10:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-20  9:47 [PATCH 0/3] ASoC: omap-mcpdm: Fix for full duplex audio Peter Ujfalusi
2013-03-20  9:47 ` [PATCH 1/3] ASoC: omap-mcpdm: Collect link direction configuration under a struct Peter Ujfalusi
2013-03-20 10:00   ` Mark Brown
2013-03-20  9:47 ` [PATCH 2/3] ASoC: omap-mcpdm: Fix for full duplex audio use case Peter Ujfalusi
2013-03-20  9:47 ` [PATCH 3/3] ASoC: omap-mcpdm: Remove leftower define for IO address Peter Ujfalusi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.