[alsa-devel] [PATCH 2/4] ASoC: fsi: Add FIFO size calculate

Kuninori Morimoto morimoto.kuninori at renesas.com
Wed Mar 17 06:26:17 CET 2010


Signed-off-by: Kuninori Morimoto <morimoto.kuninori at renesas.com>
---
 sound/soc/sh/fsi.c |   48 +++++++++++++++++++++++-------------------------
 1 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index db91349..cc41bae 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -46,8 +46,9 @@
 #define MUTE		0x020C
 #define CLK_RST		0x0210
 #define SOFT_RST	0x0214
+#define FIFO_SZ		0x0218
 #define MREG_START	INT_ST
-#define MREG_END	SOFT_RST
+#define MREG_END	FIFO_SZ
 
 /* DO_FMT */
 /* DI_FMT */
@@ -85,6 +86,11 @@
 #define IR		(1 <<  4) /* Interrupt Reset */
 #define FSISR		(1 <<  0) /* Software Reset */
 
+/* FIFO_SZ */
+#define OUT_SZ_MASK	0x7
+#define BO_SZ_SHIFT	8
+#define AO_SZ_SHIFT	0
+
 #define FSI_RATES SNDRV_PCM_RATE_8000_96000
 
 #define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
@@ -590,11 +596,12 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
 			   struct snd_soc_dai *dai)
 {
 	struct fsi_priv *fsi = fsi_get_priv(substream);
+	struct fsi_master *master = fsi_get_master(fsi);
 	const char *msg;
 	u32 flags = fsi_get_info_flags(fsi);
 	u32 fmt;
 	u32 reg;
-	u32 data;
+	u32 data, i;
 	int is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 	int is_master;
 	int ret = 0;
@@ -668,31 +675,22 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
 		dev_err(dai->dev, "unknown format.\n");
 		return -EINVAL;
 	}
-
-	switch (fsi->chan) {
-	case 1:
-		fsi->fifo_max = 256;
-		break;
-	case 2:
-		fsi->fifo_max = 128;
-		break;
-	case 3:
-	case 4:
-		fsi->fifo_max = 64;
-		break;
-	case 5:
-	case 6:
-	case 7:
-	case 8:
-		fsi->fifo_max = 32;
-		break;
-	default:
-		dev_err(dai->dev, "channel size error.\n");
-		return -EINVAL;
-	}
-
 	fsi_reg_write(fsi, reg, data);
 
+	/* calculate FIFO size */
+	data = fsi_master_read(master, FIFO_SZ);
+	data >>= fsi_is_port_a(fsi) ? AO_SZ_SHIFT : BO_SZ_SHIFT;
+	data &= OUT_SZ_MASK;
+	fsi->fifo_max = 256;
+	for (i = 0; i < data; i++)
+		fsi->fifo_max <<= 1;
+	dev_dbg(dai->dev, "fifo = %d words\n", fsi->fifo_max);
+
+	for (i = 1; i < fsi->chan; i *= 2)
+		if (fsi->chan > i)
+			fsi->fifo_max >>= 1;
+	dev_dbg(dai->dev, "%d channel %d store\n", fsi->chan, fsi->fifo_max);
+
 	/*
 	 * clear clk reset if master mode
 	 */
-- 
1.6.3.3



More information about the Alsa-devel mailing list