aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2010-12-16 22:55:22 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-12-17 07:57:14 -0500
commit1ec9bc35a6a01555836fa1e4d0f00a3501835b0b (patch)
tree4a2fe3f88b7a5ba5426047dd32266f64ed24081e /sound/soc/sh
parent9e261bbcba087b98b9d60a78e60845d5df488aa3 (diff)
ASoC: sh: fsi: Add over/under run counter
Current FSI driver had printed under/over run error if status register have its error bit. But runtime print cause the next error because print out is slow. This patch add error counter and print error when sound stop Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/fsi.c76
1 files changed, 49 insertions, 27 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 9ab85936e65d..2b06402801ef 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -134,6 +134,9 @@ struct fsi_stream {
134 int buff_len; 134 int buff_len;
135 int period_len; 135 int period_len;
136 int period_num; 136 int period_num;
137
138 int uerr_num;
139 int oerr_num;
137}; 140};
138 141
139struct fsi_priv { 142struct fsi_priv {
@@ -326,17 +329,29 @@ static void fsi_stream_push(struct fsi_priv *fsi,
326 io->buff_offset = 0; 329 io->buff_offset = 0;
327 io->period_len = period_len; 330 io->period_len = period_len;
328 io->period_num = 0; 331 io->period_num = 0;
332 io->oerr_num = -1; /* ignore 1st err */
333 io->uerr_num = -1; /* ignore 1st err */
329} 334}
330 335
331static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) 336static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
332{ 337{
333 struct fsi_stream *io = fsi_get_stream(fsi, is_play); 338 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
339 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
340
341
342 if (io->oerr_num > 0)
343 dev_err(dai->dev, "over_run = %d\n", io->oerr_num);
344
345 if (io->uerr_num > 0)
346 dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
334 347
335 io->substream = NULL; 348 io->substream = NULL;
336 io->buff_len = 0; 349 io->buff_len = 0;
337 io->buff_offset = 0; 350 io->buff_offset = 0;
338 io->period_len = 0; 351 io->period_len = 0;
339 io->period_num = 0; 352 io->period_num = 0;
353 io->oerr_num = 0;
354 io->uerr_num = 0;
340} 355}
341 356
342static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) 357static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
@@ -375,6 +390,27 @@ static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
375 return frames_to_bytes(runtime, 1) / io->chan_num; 390 return frames_to_bytes(runtime, 1) / io->chan_num;
376} 391}
377 392
393static void fsi_count_fifo_err(struct fsi_priv *fsi)
394{
395 u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
396 u32 istatus = fsi_reg_read(fsi, DIFF_ST);
397
398 if (ostatus & ERR_OVER)
399 fsi->playback.oerr_num++;
400
401 if (ostatus & ERR_UNDER)
402 fsi->playback.uerr_num++;
403
404 if (istatus & ERR_OVER)
405 fsi->capture.oerr_num++;
406
407 if (istatus & ERR_UNDER)
408 fsi->capture.uerr_num++;
409
410 fsi_reg_write(fsi, DOFF_ST, 0);
411 fsi_reg_write(fsi, DIFF_ST, 0);
412}
413
378/* 414/*
379 * dma function 415 * dma function
380 */ 416 */
@@ -574,7 +610,7 @@ static void fsi_soft_all_reset(struct fsi_master *master)
574 mdelay(10); 610 mdelay(10);
575} 611}
576 612
577static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream) 613static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
578{ 614{
579 struct snd_pcm_runtime *runtime; 615 struct snd_pcm_runtime *runtime;
580 struct snd_pcm_substream *substream = NULL; 616 struct snd_pcm_substream *substream = NULL;
@@ -667,37 +703,20 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
667 /* update buff_offset */ 703 /* update buff_offset */
668 io->buff_offset += fsi_num2offset(data_num, ch_width); 704 io->buff_offset += fsi_num2offset(data_num, ch_width);
669 705
670 /* check fifo status */
671 if (!startup) {
672 struct snd_soc_dai *dai = fsi_get_dai(substream);
673 u32 status = is_play ?
674 fsi_reg_read(fsi, DOFF_ST) :
675 fsi_reg_read(fsi, DIFF_ST);
676
677 if (status & ERR_OVER)
678 dev_err(dai->dev, "over run\n");
679 if (status & ERR_UNDER)
680 dev_err(dai->dev, "under run\n");
681 }
682
683 is_play ?
684 fsi_reg_write(fsi, DOFF_ST, 0) :
685 fsi_reg_write(fsi, DIFF_ST, 0);
686
687 if (over_period) 706 if (over_period)
688 snd_pcm_period_elapsed(substream); 707 snd_pcm_period_elapsed(substream);
689 708
690 return 0; 709 return 0;
691} 710}
692 711
693static int fsi_data_pop(struct fsi_priv *fsi, int startup) 712static int fsi_data_pop(struct fsi_priv *fsi)
694{ 713{
695 return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_CAPTURE); 714 return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE);
696} 715}
697 716
698static int fsi_data_push(struct fsi_priv *fsi, int startup) 717static int fsi_data_push(struct fsi_priv *fsi)
699{ 718{
700 return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_PLAYBACK); 719 return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK);
701} 720}
702 721
703static irqreturn_t fsi_interrupt(int irq, void *data) 722static irqreturn_t fsi_interrupt(int irq, void *data)
@@ -710,13 +729,16 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
710 fsi_master_mask_set(master, SOFT_RST, IR, IR); 729 fsi_master_mask_set(master, SOFT_RST, IR, IR);
711 730
712 if (int_st & AB_IO(1, AO_SHIFT)) 731 if (int_st & AB_IO(1, AO_SHIFT))
713 fsi_data_push(&master->fsia, 0); 732 fsi_data_push(&master->fsia);
714 if (int_st & AB_IO(1, BO_SHIFT)) 733 if (int_st & AB_IO(1, BO_SHIFT))
715 fsi_data_push(&master->fsib, 0); 734 fsi_data_push(&master->fsib);
716 if (int_st & AB_IO(1, AI_SHIFT)) 735 if (int_st & AB_IO(1, AI_SHIFT))
717 fsi_data_pop(&master->fsia, 0); 736 fsi_data_pop(&master->fsia);
718 if (int_st & AB_IO(1, BI_SHIFT)) 737 if (int_st & AB_IO(1, BI_SHIFT))
719 fsi_data_pop(&master->fsib, 0); 738 fsi_data_pop(&master->fsib);
739
740 fsi_count_fifo_err(&master->fsia);
741 fsi_count_fifo_err(&master->fsib);
720 742
721 fsi_irq_clear_status(&master->fsia); 743 fsi_irq_clear_status(&master->fsia);
722 fsi_irq_clear_status(&master->fsib); 744 fsi_irq_clear_status(&master->fsib);
@@ -855,7 +877,7 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
855 fsi_stream_push(fsi, is_play, substream, 877 fsi_stream_push(fsi, is_play, substream,
856 frames_to_bytes(runtime, runtime->buffer_size), 878 frames_to_bytes(runtime, runtime->buffer_size),
857 frames_to_bytes(runtime, runtime->period_size)); 879 frames_to_bytes(runtime, runtime->period_size));
858 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1); 880 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
859 fsi_irq_enable(fsi, is_play); 881 fsi_irq_enable(fsi, is_play);
860 break; 882 break;
861 case SNDRV_PCM_TRIGGER_STOP: 883 case SNDRV_PCM_TRIGGER_STOP: