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>

authored by Kuninori Morimoto and committed by Mark Brown 47fc9a0a db72c2f8

+25 -21
+25 -21
sound/soc/sh/fsi.c
··· 388 } 389 390 /* playback interrupt */ 391 - static int fsi_data_push(struct fsi_priv *fsi) 392 { 393 struct snd_pcm_runtime *runtime; 394 struct snd_pcm_substream *substream = NULL; ··· 397 int fifo_free; 398 int width; 399 u8 *start; 400 - int i, ret, over_period; 401 402 if (!fsi || 403 !fsi->substream || ··· 453 454 fsi->byte_offset += send * width; 455 456 - ret = 0; 457 status = fsi_reg_read(fsi, DOFF_ST); 458 - if (status & ERR_OVER) { 459 struct snd_soc_dai *dai = fsi_get_dai(substream); 460 - dev_err(dai->dev, "over run error\n"); 461 - fsi_reg_write(fsi, DOFF_ST, status & ~ST_ERR); 462 - ret = -EIO; 463 } 464 465 fsi_irq_enable(fsi, 1); 466 467 if (over_period) 468 snd_pcm_period_elapsed(substream); 469 470 - return ret; 471 } 472 473 - static int fsi_data_pop(struct fsi_priv *fsi) 474 { 475 struct snd_pcm_runtime *runtime; 476 struct snd_pcm_substream *substream = NULL; ··· 481 int fifo_fill; 482 int width; 483 u8 *start; 484 - int i, ret, over_period; 485 486 if (!fsi || 487 !fsi->substream || ··· 536 537 fsi->byte_offset += fifo_fill * width; 538 539 - ret = 0; 540 status = fsi_reg_read(fsi, DIFF_ST); 541 - if (status & ERR_UNDER) { 542 struct snd_soc_dai *dai = fsi_get_dai(substream); 543 - dev_err(dai->dev, "under run error\n"); 544 - fsi_reg_write(fsi, DIFF_ST, status & ~ST_ERR); 545 - ret = -EIO; 546 } 547 548 fsi_irq_enable(fsi, 0); 549 550 if (over_period) 551 snd_pcm_period_elapsed(substream); 552 553 - return ret; 554 } 555 556 static irqreturn_t fsi_interrupt(int irq, void *data) ··· 566 fsi_master_write(master, SOFT_RST, status | 0x00000010); 567 568 if (int_st & INT_A_OUT) 569 - fsi_data_push(&master->fsia); 570 if (int_st & INT_B_OUT) 571 - fsi_data_push(&master->fsib); 572 if (int_st & INT_A_IN) 573 - fsi_data_pop(&master->fsia); 574 if (int_st & INT_B_IN) 575 - fsi_data_pop(&master->fsib); 576 577 fsi_master_write(master, INT_ST, 0x0000000); 578 ··· 730 fsi_stream_push(fsi, substream, 731 frames_to_bytes(runtime, runtime->buffer_size), 732 frames_to_bytes(runtime, runtime->period_size)); 733 - ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 734 break; 735 case SNDRV_PCM_TRIGGER_STOP: 736 fsi_irq_disable(fsi, is_play);
··· 388 } 389 390 /* playback interrupt */ 391 + static int fsi_data_push(struct fsi_priv *fsi, int startup) 392 { 393 struct snd_pcm_runtime *runtime; 394 struct snd_pcm_substream *substream = NULL; ··· 397 int fifo_free; 398 int width; 399 u8 *start; 400 + int i, over_period; 401 402 if (!fsi || 403 !fsi->substream || ··· 453 454 fsi->byte_offset += send * width; 455 456 status = fsi_reg_read(fsi, DOFF_ST); 457 + if (!startup) { 458 struct snd_soc_dai *dai = fsi_get_dai(substream); 459 + 460 + if (status & ERR_OVER) 461 + dev_err(dai->dev, "over run\n"); 462 + if (status & ERR_UNDER) 463 + dev_err(dai->dev, "under run\n"); 464 } 465 + fsi_reg_write(fsi, DOFF_ST, 0); 466 467 fsi_irq_enable(fsi, 1); 468 469 if (over_period) 470 snd_pcm_period_elapsed(substream); 471 472 + return 0; 473 } 474 475 + static int fsi_data_pop(struct fsi_priv *fsi, int startup) 476 { 477 struct snd_pcm_runtime *runtime; 478 struct snd_pcm_substream *substream = NULL; ··· 479 int fifo_fill; 480 int width; 481 u8 *start; 482 + int i, over_period; 483 484 if (!fsi || 485 !fsi->substream || ··· 534 535 fsi->byte_offset += fifo_fill * width; 536 537 status = fsi_reg_read(fsi, DIFF_ST); 538 + if (!startup) { 539 struct snd_soc_dai *dai = fsi_get_dai(substream); 540 + 541 + if (status & ERR_OVER) 542 + dev_err(dai->dev, "over run\n"); 543 + if (status & ERR_UNDER) 544 + dev_err(dai->dev, "under run\n"); 545 } 546 + fsi_reg_write(fsi, DIFF_ST, 0); 547 548 fsi_irq_enable(fsi, 0); 549 550 if (over_period) 551 snd_pcm_period_elapsed(substream); 552 553 + return 0; 554 } 555 556 static irqreturn_t fsi_interrupt(int irq, void *data) ··· 562 fsi_master_write(master, SOFT_RST, status | 0x00000010); 563 564 if (int_st & INT_A_OUT) 565 + fsi_data_push(&master->fsia, 0); 566 if (int_st & INT_B_OUT) 567 + fsi_data_push(&master->fsib, 0); 568 if (int_st & INT_A_IN) 569 + fsi_data_pop(&master->fsia, 0); 570 if (int_st & INT_B_IN) 571 + fsi_data_pop(&master->fsib, 0); 572 573 fsi_master_write(master, INT_ST, 0x0000000); 574 ··· 726 fsi_stream_push(fsi, substream, 727 frames_to_bytes(runtime, runtime->buffer_size), 728 frames_to_bytes(runtime, runtime->period_size)); 729 + ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1); 730 break; 731 case SNDRV_PCM_TRIGGER_STOP: 732 fsi_irq_disable(fsi, is_play);