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