aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
authorKuninori Morimoto <morimoto.kuninori@renesas.com>2010-02-22 02:41:57 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-02-23 05:42:07 -0500
commit47fc9a0a808f23b7b305f6c018e4882118b88d92 (patch)
tree415001ffe968129e9afa5b775539812e0869348a /sound/soc/sh
parentdb72c2f89790f919d65d0adbee390958005c40fc (diff)
ASoC: fsi: Modify over/under run error settlement
In current FSI driver, playback function cares only overrun, and capture function cares only underrun. But playback function should had cared about underrun, and capture function should had cared about overrun too. Signed-off-by: Kuninori Morimoto <morimoto.kuninori@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.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 3c36d24a6c20..993abb730dfa 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -388,7 +388,7 @@ static void fsi_soft_all_reset(struct fsi_master *master)
388} 388}
389 389
390/* playback interrupt */ 390/* playback interrupt */
391static int fsi_data_push(struct fsi_priv *fsi) 391static int fsi_data_push(struct fsi_priv *fsi, int startup)
392{ 392{
393 struct snd_pcm_runtime *runtime; 393 struct snd_pcm_runtime *runtime;
394 struct snd_pcm_substream *substream = NULL; 394 struct snd_pcm_substream *substream = NULL;
@@ -397,7 +397,7 @@ static int fsi_data_push(struct fsi_priv *fsi)
397 int fifo_free; 397 int fifo_free;
398 int width; 398 int width;
399 u8 *start; 399 u8 *start;
400 int i, ret, over_period; 400 int i, over_period;
401 401
402 if (!fsi || 402 if (!fsi ||
403 !fsi->substream || 403 !fsi->substream ||
@@ -453,24 +453,26 @@ static int fsi_data_push(struct fsi_priv *fsi)
453 453
454 fsi->byte_offset += send * width; 454 fsi->byte_offset += send * width;
455 455
456 ret = 0;
457 status = fsi_reg_read(fsi, DOFF_ST); 456 status = fsi_reg_read(fsi, DOFF_ST);
458 if (status & ERR_OVER) { 457 if (!startup) {
459 struct snd_soc_dai *dai = fsi_get_dai(substream); 458 struct snd_soc_dai *dai = fsi_get_dai(substream);
460 dev_err(dai->dev, "over run error\n"); 459
461 fsi_reg_write(fsi, DOFF_ST, status & ~ST_ERR); 460 if (status & ERR_OVER)
462 ret = -EIO; 461 dev_err(dai->dev, "over run\n");
462 if (status & ERR_UNDER)
463 dev_err(dai->dev, "under run\n");
463 } 464 }
465 fsi_reg_write(fsi, DOFF_ST, 0);
464 466
465 fsi_irq_enable(fsi, 1); 467 fsi_irq_enable(fsi, 1);
466 468
467 if (over_period) 469 if (over_period)
468 snd_pcm_period_elapsed(substream); 470 snd_pcm_period_elapsed(substream);
469 471
470 return ret; 472 return 0;
471} 473}
472 474
473static int fsi_data_pop(struct fsi_priv *fsi) 475static int fsi_data_pop(struct fsi_priv *fsi, int startup)
474{ 476{
475 struct snd_pcm_runtime *runtime; 477 struct snd_pcm_runtime *runtime;
476 struct snd_pcm_substream *substream = NULL; 478 struct snd_pcm_substream *substream = NULL;
@@ -479,7 +481,7 @@ static int fsi_data_pop(struct fsi_priv *fsi)
479 int fifo_fill; 481 int fifo_fill;
480 int width; 482 int width;
481 u8 *start; 483 u8 *start;
482 int i, ret, over_period; 484 int i, over_period;
483 485
484 if (!fsi || 486 if (!fsi ||
485 !fsi->substream || 487 !fsi->substream ||
@@ -534,21 +536,23 @@ static int fsi_data_pop(struct fsi_priv *fsi)
534 536
535 fsi->byte_offset += fifo_fill * width; 537 fsi->byte_offset += fifo_fill * width;
536 538
537 ret = 0;
538 status = fsi_reg_read(fsi, DIFF_ST); 539 status = fsi_reg_read(fsi, DIFF_ST);
539 if (status & ERR_UNDER) { 540 if (!startup) {
540 struct snd_soc_dai *dai = fsi_get_dai(substream); 541 struct snd_soc_dai *dai = fsi_get_dai(substream);
541 dev_err(dai->dev, "under run error\n"); 542
542 fsi_reg_write(fsi, DIFF_ST, status & ~ST_ERR); 543 if (status & ERR_OVER)
543 ret = -EIO; 544 dev_err(dai->dev, "over run\n");
545 if (status & ERR_UNDER)
546 dev_err(dai->dev, "under run\n");
544 } 547 }
548 fsi_reg_write(fsi, DIFF_ST, 0);
545 549
546 fsi_irq_enable(fsi, 0); 550 fsi_irq_enable(fsi, 0);
547 551
548 if (over_period) 552 if (over_period)
549 snd_pcm_period_elapsed(substream); 553 snd_pcm_period_elapsed(substream);
550 554
551 return ret; 555 return 0;
552} 556}
553 557
554static irqreturn_t fsi_interrupt(int irq, void *data) 558static irqreturn_t fsi_interrupt(int irq, void *data)
@@ -562,13 +566,13 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
562 fsi_master_write(master, SOFT_RST, status | 0x00000010); 566 fsi_master_write(master, SOFT_RST, status | 0x00000010);
563 567
564 if (int_st & INT_A_OUT) 568 if (int_st & INT_A_OUT)
565 fsi_data_push(&master->fsia); 569 fsi_data_push(&master->fsia, 0);
566 if (int_st & INT_B_OUT) 570 if (int_st & INT_B_OUT)
567 fsi_data_push(&master->fsib); 571 fsi_data_push(&master->fsib, 0);
568 if (int_st & INT_A_IN) 572 if (int_st & INT_A_IN)
569 fsi_data_pop(&master->fsia); 573 fsi_data_pop(&master->fsia, 0);
570 if (int_st & INT_B_IN) 574 if (int_st & INT_B_IN)
571 fsi_data_pop(&master->fsib); 575 fsi_data_pop(&master->fsib, 0);
572 576
573 fsi_master_write(master, INT_ST, 0x0000000); 577 fsi_master_write(master, INT_ST, 0x0000000);
574 578
@@ -726,7 +730,7 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
726 fsi_stream_push(fsi, substream, 730 fsi_stream_push(fsi, substream,
727 frames_to_bytes(runtime, runtime->buffer_size), 731 frames_to_bytes(runtime, runtime->buffer_size),
728 frames_to_bytes(runtime, runtime->period_size)); 732 frames_to_bytes(runtime, runtime->period_size));
729 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 733 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
730 break; 734 break;
731 case SNDRV_PCM_TRIGGER_STOP: 735 case SNDRV_PCM_TRIGGER_STOP:
732 fsi_irq_disable(fsi, is_play); 736 fsi_irq_disable(fsi, is_play);