}
/* playback interrupt */
-static int fsi_data_push(struct fsi_priv *fsi)
+static int fsi_data_push(struct fsi_priv *fsi, int startup)
{
struct snd_pcm_runtime *runtime;
struct snd_pcm_substream *substream = NULL;
int fifo_free;
int width;
u8 *start;
- int i, ret, over_period;
+ int i, over_period;
if (!fsi ||
!fsi->substream ||
fsi->byte_offset += send * width;
- ret = 0;
status = fsi_reg_read(fsi, DOFF_ST);
- if (status & ERR_OVER) {
+ if (!startup) {
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;
+
+ if (status & ERR_OVER)
+ dev_err(dai->dev, "over run\n");
+ if (status & ERR_UNDER)
+ dev_err(dai->dev, "under run\n");
}
+ fsi_reg_write(fsi, DOFF_ST, 0);
fsi_irq_enable(fsi, 1);
if (over_period)
snd_pcm_period_elapsed(substream);
- return ret;
+ return 0;
}
-static int fsi_data_pop(struct fsi_priv *fsi)
+static int fsi_data_pop(struct fsi_priv *fsi, int startup)
{
struct snd_pcm_runtime *runtime;
struct snd_pcm_substream *substream = NULL;
int fifo_fill;
int width;
u8 *start;
- int i, ret, over_period;
+ int i, over_period;
if (!fsi ||
!fsi->substream ||
fsi->byte_offset += fifo_fill * width;
- ret = 0;
status = fsi_reg_read(fsi, DIFF_ST);
- if (status & ERR_UNDER) {
+ if (!startup) {
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;
+
+ if (status & ERR_OVER)
+ dev_err(dai->dev, "over run\n");
+ if (status & ERR_UNDER)
+ dev_err(dai->dev, "under run\n");
}
+ fsi_reg_write(fsi, DIFF_ST, 0);
fsi_irq_enable(fsi, 0);
if (over_period)
snd_pcm_period_elapsed(substream);
- return ret;
+ return 0;
}
static irqreturn_t fsi_interrupt(int irq, void *data)
fsi_master_write(master, SOFT_RST, status | 0x00000010);
if (int_st & INT_A_OUT)
- fsi_data_push(&master->fsia);
+ fsi_data_push(&master->fsia, 0);
if (int_st & INT_B_OUT)
- fsi_data_push(&master->fsib);
+ fsi_data_push(&master->fsib, 0);
if (int_st & INT_A_IN)
- fsi_data_pop(&master->fsia);
+ fsi_data_pop(&master->fsia, 0);
if (int_st & INT_B_IN)
- fsi_data_pop(&master->fsib);
+ fsi_data_pop(&master->fsib, 0);
fsi_master_write(master, INT_ST, 0x0000000);
fsi_stream_push(fsi, substream,
frames_to_bytes(runtime, runtime->buffer_size),
frames_to_bytes(runtime, runtime->period_size));
- ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
+ ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
break;
case SNDRV_PCM_TRIGGER_STOP:
fsi_irq_disable(fsi, is_play);