Lines Matching +full:free +full:- +full:flowing

1 // SPDX-License-Identifier: GPL-2.0-only
9 * The I2S interface consists of two ring buffers - one for RX and one for
11 * on which way the data is flowing, either the software or the hardware
25 * busy-waiting, which would keep stalling the kernel for quite a long time.
30 * are wait-free.
70 .name = "chv3-i2s",
103 writel(val, i2s->iobase + offset); in chv3_i2s_wr()
108 return readl(i2s->iobase + offset); in chv3_i2s_rd()
116 reg = readl(i2s->iobase_irq + I2S_IRQ_CLR); in chv3_i2s_isr()
121 snd_pcm_period_elapsed(i2s->rx_substream); in chv3_i2s_isr()
124 snd_pcm_period_elapsed(i2s->tx_substream); in chv3_i2s_isr()
126 writel(reg, i2s->iobase_irq + I2S_IRQ_CLR); in chv3_i2s_isr()
140 res = snd_pcm_hw_constraint_pow2(substream->runtime, 0, in chv3_dma_open()
145 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in chv3_dma_open()
146 i2s->rx_substream = substream; in chv3_dma_open()
148 i2s->tx_substream = substream; in chv3_dma_open()
158 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) in chv3_dma_close()
173 substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; in chv3_dma_pcm_construct()
175 res = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, i2s->dev, in chv3_dma_pcm_construct()
176 I2S_MAX_BUFFER_SIZE, &substream->dma_buffer); in chv3_dma_pcm_construct()
181 substream = rtd->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; in chv3_dma_pcm_construct()
183 res = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, i2s->dev, in chv3_dma_pcm_construct()
184 I2S_MAX_BUFFER_SIZE, &substream->dma_buffer); in chv3_dma_pcm_construct()
196 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); in chv3_dma_hw_params()
209 period_size = substream->runtime->period_size; in chv3_dma_prepare()
211 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { in chv3_dma_prepare()
213 chv3_i2s_wr(i2s, I2S_RX_BASE_ADDR, substream->dma_buffer.addr); in chv3_dma_prepare()
219 chv3_i2s_wr(i2s, I2S_TX_BASE_ADDR, substream->dma_buffer.addr); in chv3_dma_prepare()
221 chv3_i2s_wr(i2s, I2S_TX_IRQ, ((period_bytes / i2s->tx_bytes_to_fetch) << 8) | 1); in chv3_dma_prepare()
224 writel(I2S_IRQ_RX_BIT | I2S_IRQ_TX_BIT, i2s->iobase_irq + I2S_IRQ_MASK); in chv3_dma_prepare()
237 frame_bytes = substream->runtime->frame_bits * 8; in chv3_dma_pointer()
240 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { in chv3_dma_pointer()
245 idx_bytes = (idx_bytes - frame_bytes) & (buffer_bytes - 1); in chv3_dma_pointer()
248 return bytes_to_frames(substream->runtime, idx_bytes); in chv3_dma_pointer()
254 struct snd_pcm_runtime *runtime = substream->runtime; in chv3_dma_ack()
259 bytes = frames_to_bytes(runtime, runtime->control->appl_ptr); in chv3_dma_ack()
260 idx = bytes & (snd_pcm_lib_buffer_bytes(substream) - 1); in chv3_dma_ack()
262 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) in chv3_dma_ack()
271 .name = "chv3-i2s-comp",
287 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); in chv3_i2s_probe()
289 return -ENOMEM; in chv3_i2s_probe()
291 i2s->iobase = devm_platform_ioremap_resource(pdev, 0); in chv3_i2s_probe()
292 if (IS_ERR(i2s->iobase)) in chv3_i2s_probe()
293 return PTR_ERR(i2s->iobase); in chv3_i2s_probe()
295 i2s->iobase_irq = devm_platform_ioremap_resource(pdev, 1); in chv3_i2s_probe()
296 if (IS_ERR(i2s->iobase_irq)) in chv3_i2s_probe()
297 return PTR_ERR(i2s->iobase_irq); in chv3_i2s_probe()
299 i2s->tx_bytes_to_fetch = (chv3_i2s_rd(i2s, I2S_TX_IRQ_CONST) >> 8) & 0xffff; in chv3_i2s_probe()
301 i2s->dev = &pdev->dev; in chv3_i2s_probe()
302 dev_set_drvdata(&pdev->dev, i2s); in chv3_i2s_probe()
306 return -ENXIO; in chv3_i2s_probe()
307 res = devm_request_irq(i2s->dev, irq, chv3_i2s_isr, 0, "chv3-i2s", i2s); in chv3_i2s_probe()
311 res = devm_snd_soc_register_component(&pdev->dev, &chv3_i2s_comp, in chv3_i2s_probe()
314 dev_err(&pdev->dev, "couldn't register component: %d\n", res); in chv3_i2s_probe()
322 { .compatible = "google,chv3-i2s" },
330 .name = "chv3-i2s",