[PATCH 3/3] ASoC: fsi: Add over/under run error settlement

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Kuninori Morimoto <morimoto.kuninori@xxxxxxxxxxx>
---
 sound/soc/sh/fsi.c |   29 +++++++++++++++++++++++++----
 1 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 099fc8c..5f9f269 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -67,6 +67,7 @@
 /* DOFF_ST */
 #define ERR_OVER	0x00000010
 #define ERR_UNDER	0x00000001
+#define ST_ERR		(ERR_OVER | ERR_UNDER)
 
 /* CLK_RST */
 #define B_CLK		0x00000010
@@ -375,11 +376,12 @@ static int fsi_data_push(struct fsi_priv *fsi)
 {
 	struct snd_pcm_runtime *runtime;
 	struct snd_pcm_substream *substream = NULL;
+	u32 status;
 	int send;
 	int fifo_free;
 	int width;
 	u8 *start;
-	int i, over_period;
+	int i, ret, over_period;
 
 	if (!fsi			||
 	    !fsi->substream		||
@@ -435,23 +437,33 @@ static int fsi_data_push(struct fsi_priv *fsi)
 
 	fsi->byte_offset += send * width;
 
+	ret = 0;
+	status = fsi_reg_read(fsi, DOFF_ST);
+	if (status & ERR_OVER) {
+		struct snd_soc_dai *dai = fsi_get_dai(substream);
+		dev_err(dai->dev, "over run error\n");
+		fsi_reg_write(fsi, DOFF_ST, status & ~ST_ERR);
+		ret = -EIO;
+	}
+
 	fsi_irq_enable(fsi, 1);
 
 	if (over_period)
 		snd_pcm_period_elapsed(substream);
 
-	return 0;
+	return ret;
 }
 
 static int fsi_data_pop(struct fsi_priv *fsi)
 {
 	struct snd_pcm_runtime *runtime;
 	struct snd_pcm_substream *substream = NULL;
+	u32 status;
 	int free;
 	int fifo_fill;
 	int width;
 	u8 *start;
-	int i, over_period;
+	int i, ret, over_period;
 
 	if (!fsi			||
 	    !fsi->substream		||
@@ -506,12 +518,21 @@ static int fsi_data_pop(struct fsi_priv *fsi)
 
 	fsi->byte_offset += fifo_fill * width;
 
+	ret = 0;
+	status = fsi_reg_read(fsi, DIFF_ST);
+	if (status & ERR_UNDER) {
+		struct snd_soc_dai *dai = fsi_get_dai(substream);
+		dev_err(dai->dev, "under run error\n");
+		fsi_reg_write(fsi, DIFF_ST, status & ~ST_ERR);
+		ret = -EIO;
+	}
+
 	fsi_irq_enable(fsi, 0);
 
 	if (over_period)
 		snd_pcm_period_elapsed(substream);
 
-	return 0;
+	return ret;
 }
 
 static irqreturn_t fsi_interrupt(int irq, void *data)
-- 
1.6.3.3

_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux