Loading sound/soc/sh/fsi.c +86 −7 Original line number Original line Diff line number Diff line Loading @@ -447,6 +447,75 @@ static int fsi_data_push(struct fsi_priv *fsi) return 0; return 0; } } static int fsi_data_pop(struct fsi_priv *fsi) { struct snd_pcm_runtime *runtime; struct snd_pcm_substream *substream = NULL; int free; int fifo_fill; int width; u8 *start; int i; if (!fsi || !fsi->substream || !fsi->substream->runtime) return -EINVAL; runtime = fsi->substream->runtime; /* FSI FIFO has limit. * So, this driver can not send periods data at a time */ if (fsi->byte_offset >= fsi->period_len * (fsi->periods + 1)) { substream = fsi->substream; fsi->periods = (fsi->periods + 1) % runtime->periods; if (0 == fsi->periods) fsi->byte_offset = 0; } /* get 1 channel data width */ width = frames_to_bytes(runtime, 1) / fsi->chan; /* get free space for alsa */ free = (fsi->buffer_len - fsi->byte_offset) / width; /* get recv size */ fifo_fill = fsi_get_fifo_residue(fsi, 0); if (free < fifo_fill) fifo_fill = free; start = runtime->dma_area; start += fsi->byte_offset; switch (width) { case 2: for (i = 0; i < fifo_fill; i++) *((u16 *)start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8); break; case 4: for (i = 0; i < fifo_fill; i++) *((u32 *)start + i) = fsi_reg_read(fsi, DIDT); break; default: return -EINVAL; } fsi->byte_offset += fifo_fill * width; fsi_irq_enable(fsi, 0); if (substream) snd_pcm_period_elapsed(substream); return 0; } static irqreturn_t fsi_interrupt(int irq, void *data) static irqreturn_t fsi_interrupt(int irq, void *data) { { u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; Loading @@ -460,6 +529,10 @@ static irqreturn_t fsi_interrupt(int irq, void *data) fsi_data_push(&master->fsia); fsi_data_push(&master->fsia); if (int_st & INT_B_OUT) if (int_st & INT_B_OUT) fsi_data_push(&master->fsib); fsi_data_push(&master->fsib); if (int_st & INT_A_IN) fsi_data_pop(&master->fsia); if (int_st & INT_B_IN) fsi_data_pop(&master->fsib); fsi_master_write(INT_ST, 0x0000000); fsi_master_write(INT_ST, 0x0000000); Loading Loading @@ -612,16 +685,12 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; int ret = 0; int ret = 0; /* capture not supported */ if (!is_play) return -ENODEV; switch (cmd) { switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START: fsi_stream_push(fsi, substream, fsi_stream_push(fsi, substream, frames_to_bytes(runtime, runtime->buffer_size), frames_to_bytes(runtime, runtime->buffer_size), frames_to_bytes(runtime, runtime->period_size)); frames_to_bytes(runtime, runtime->period_size)); ret = fsi_data_push(fsi); ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); break; break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP: fsi_irq_disable(fsi, is_play); fsi_irq_disable(fsi, is_play); Loading Loading @@ -757,7 +826,12 @@ struct snd_soc_dai fsi_soc_dai[] = { .channels_min = 1, .channels_min = 1, .channels_max = 8, .channels_max = 8, }, }, /* capture not supported */ .capture = { .rates = FSI_RATES, .formats = FSI_FMTS, .channels_min = 1, .channels_max = 8, }, .ops = &fsi_dai_ops, .ops = &fsi_dai_ops, }, }, { { Loading @@ -769,7 +843,12 @@ struct snd_soc_dai fsi_soc_dai[] = { .channels_min = 1, .channels_min = 1, .channels_max = 8, .channels_max = 8, }, }, /* capture not supported */ .capture = { .rates = FSI_RATES, .formats = FSI_FMTS, .channels_min = 1, .channels_max = 8, }, .ops = &fsi_dai_ops, .ops = &fsi_dai_ops, }, }, }; }; Loading Loading
sound/soc/sh/fsi.c +86 −7 Original line number Original line Diff line number Diff line Loading @@ -447,6 +447,75 @@ static int fsi_data_push(struct fsi_priv *fsi) return 0; return 0; } } static int fsi_data_pop(struct fsi_priv *fsi) { struct snd_pcm_runtime *runtime; struct snd_pcm_substream *substream = NULL; int free; int fifo_fill; int width; u8 *start; int i; if (!fsi || !fsi->substream || !fsi->substream->runtime) return -EINVAL; runtime = fsi->substream->runtime; /* FSI FIFO has limit. * So, this driver can not send periods data at a time */ if (fsi->byte_offset >= fsi->period_len * (fsi->periods + 1)) { substream = fsi->substream; fsi->periods = (fsi->periods + 1) % runtime->periods; if (0 == fsi->periods) fsi->byte_offset = 0; } /* get 1 channel data width */ width = frames_to_bytes(runtime, 1) / fsi->chan; /* get free space for alsa */ free = (fsi->buffer_len - fsi->byte_offset) / width; /* get recv size */ fifo_fill = fsi_get_fifo_residue(fsi, 0); if (free < fifo_fill) fifo_fill = free; start = runtime->dma_area; start += fsi->byte_offset; switch (width) { case 2: for (i = 0; i < fifo_fill; i++) *((u16 *)start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8); break; case 4: for (i = 0; i < fifo_fill; i++) *((u32 *)start + i) = fsi_reg_read(fsi, DIDT); break; default: return -EINVAL; } fsi->byte_offset += fifo_fill * width; fsi_irq_enable(fsi, 0); if (substream) snd_pcm_period_elapsed(substream); return 0; } static irqreturn_t fsi_interrupt(int irq, void *data) static irqreturn_t fsi_interrupt(int irq, void *data) { { u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; Loading @@ -460,6 +529,10 @@ static irqreturn_t fsi_interrupt(int irq, void *data) fsi_data_push(&master->fsia); fsi_data_push(&master->fsia); if (int_st & INT_B_OUT) if (int_st & INT_B_OUT) fsi_data_push(&master->fsib); fsi_data_push(&master->fsib); if (int_st & INT_A_IN) fsi_data_pop(&master->fsia); if (int_st & INT_B_IN) fsi_data_pop(&master->fsib); fsi_master_write(INT_ST, 0x0000000); fsi_master_write(INT_ST, 0x0000000); Loading Loading @@ -612,16 +685,12 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; int ret = 0; int ret = 0; /* capture not supported */ if (!is_play) return -ENODEV; switch (cmd) { switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START: fsi_stream_push(fsi, substream, fsi_stream_push(fsi, substream, frames_to_bytes(runtime, runtime->buffer_size), frames_to_bytes(runtime, runtime->buffer_size), frames_to_bytes(runtime, runtime->period_size)); frames_to_bytes(runtime, runtime->period_size)); ret = fsi_data_push(fsi); ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); break; break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP: fsi_irq_disable(fsi, is_play); fsi_irq_disable(fsi, is_play); Loading Loading @@ -757,7 +826,12 @@ struct snd_soc_dai fsi_soc_dai[] = { .channels_min = 1, .channels_min = 1, .channels_max = 8, .channels_max = 8, }, }, /* capture not supported */ .capture = { .rates = FSI_RATES, .formats = FSI_FMTS, .channels_min = 1, .channels_max = 8, }, .ops = &fsi_dai_ops, .ops = &fsi_dai_ops, }, }, { { Loading @@ -769,7 +843,12 @@ struct snd_soc_dai fsi_soc_dai[] = { .channels_min = 1, .channels_min = 1, .channels_max = 8, .channels_max = 8, }, }, /* capture not supported */ .capture = { .rates = FSI_RATES, .formats = FSI_FMTS, .channels_min = 1, .channels_max = 8, }, .ops = &fsi_dai_ops, .ops = &fsi_dai_ops, }, }, }; }; Loading