Skip to content

Commit 3c1dcf3

Browse files
decsnykartben
authored andcommitted
drivers: i2s_mcux_sai: Cleanup dma callbacks
The dma callback functions were written in a very confusing way, clean them up, and this change also saves some bytes of ROM. Signed-off-by: Declan Snyder <declan.snyder@nxp.com>
1 parent d22607a commit 3c1dcf3

File tree

1 file changed

+75
-79
lines changed

1 file changed

+75
-79
lines changed

drivers/i2s/i2s_mcux_sai.c

Lines changed: 75 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,9 @@ static void i2s_dma_tx_callback(const struct device *dma_dev, void *arg, uint32_
255255
const struct device *dev = (struct device *)arg;
256256
struct i2s_dev_data *dev_data = dev->data;
257257
struct stream *strm = &dev_data->tx;
258+
uint8_t blocks_queued;
258259
void *buffer = NULL;
259260
int ret;
260-
uint8_t blocks_queued;
261261

262262
LOG_DBG("tx cb");
263263

@@ -289,35 +289,30 @@ static void i2s_dma_tx_callback(const struct device *dma_dev, void *arg, uint32_
289289
goto disabled_exit_no_drop;
290290
}
291291

292-
switch (strm->state) {
293-
case I2S_STATE_RUNNING:
294-
case I2S_STATE_STOPPING:
295-
ret = i2s_tx_reload_multiple_dma_blocks(dev, &blocks_queued);
292+
if (strm->state != I2S_STATE_RUNNING && strm->state != I2S_STATE_STOPPING) {
293+
goto disabled_exit_drop;
294+
}
296295

297-
if (ret) {
298-
strm->state = I2S_STATE_ERROR;
299-
goto disabled_exit_no_drop;
300-
}
296+
ret = i2s_tx_reload_multiple_dma_blocks(dev, &blocks_queued);
297+
if (ret) {
298+
strm->state = I2S_STATE_ERROR;
299+
goto disabled_exit_no_drop;
300+
}
301301

302-
if (blocks_queued || (strm->free_tx_dma_blocks < MAX_TX_DMA_BLOCKS)) {
303-
goto enabled_exit;
304-
} else {
305-
/* all DMA blocks are free but no blocks were queued */
306-
if (strm->state == I2S_STATE_STOPPING) {
307-
/* TX queue has drained */
308-
strm->state = I2S_STATE_READY;
309-
LOG_DBG("TX stream has stopped");
310-
} else {
311-
strm->state = I2S_STATE_ERROR;
312-
LOG_ERR("TX Failed to reload DMA");
313-
}
314-
goto disabled_exit_no_drop;
315-
}
302+
if (blocks_queued || (strm->free_tx_dma_blocks < MAX_TX_DMA_BLOCKS)) {
303+
goto enabled_exit;
304+
}
316305

317-
case I2S_STATE_ERROR:
318-
default:
319-
goto disabled_exit_drop;
306+
/* all DMA blocks are free but no blocks were queued */
307+
if (strm->state == I2S_STATE_STOPPING) {
308+
/* TX queue has drained */
309+
strm->state = I2S_STATE_READY;
310+
LOG_DBG("TX stream has stopped");
311+
} else {
312+
strm->state = I2S_STATE_ERROR;
313+
LOG_ERR("TX Failed to reload DMA");
320314
}
315+
goto disabled_exit_no_drop;
321316

322317
disabled_exit_no_drop:
323318
i2s_tx_stream_disable(dev, false);
@@ -344,61 +339,62 @@ static void i2s_dma_rx_callback(const struct device *dma_dev, void *arg, uint32_
344339

345340
LOG_DBG("RX cb");
346341

347-
switch (strm->state) {
348-
case I2S_STATE_STOPPING:
349-
case I2S_STATE_RUNNING:
350-
/* retrieve buffer from input queue */
351-
ret = k_msgq_get(&strm->in_queue, &buffer, K_NO_WAIT);
352-
__ASSERT_NO_MSG(ret == 0);
353-
354-
/* put buffer to output queue */
355-
ret = k_msgq_put(&strm->out_queue, &buffer, K_NO_WAIT);
356-
if (ret != 0) {
357-
LOG_ERR("buffer %p -> out_queue %p err %d", buffer, &strm->out_queue, ret);
358-
i2s_rx_stream_disable(dev, false, false);
359-
strm->state = I2S_STATE_ERROR;
360-
return;
361-
}
362-
if (strm->state == I2S_STATE_RUNNING) {
363-
/* allocate new buffer for next audio frame */
364-
ret = k_mem_slab_alloc(strm->cfg.mem_slab, &buffer, K_NO_WAIT);
365-
if (ret != 0) {
366-
LOG_ERR("buffer alloc from slab %p err %d", strm->cfg.mem_slab,
367-
ret);
368-
i2s_rx_stream_disable(dev, false, false);
369-
strm->state = I2S_STATE_ERROR;
370-
} else {
371-
uint32_t data_path = strm->start_channel;
372-
373-
ret = dma_reload(dev_data->dev_dma, strm->dma_channel,
374-
(uint32_t)&base->RDR[data_path], (uint32_t)buffer,
375-
strm->cfg.block_size);
376-
if (ret != 0) {
377-
LOG_ERR("dma_reload() failed with error 0x%x", ret);
378-
i2s_rx_stream_disable(dev, false, false);
379-
strm->state = I2S_STATE_ERROR;
380-
return;
381-
}
382-
383-
/* put buffer in input queue */
384-
ret = k_msgq_put(&strm->in_queue, &buffer, K_NO_WAIT);
385-
if (ret != 0) {
386-
LOG_ERR("%p -> in_queue %p err %d", buffer, &strm->in_queue,
387-
ret);
388-
}
389-
}
390-
} else {
391-
i2s_rx_stream_disable(dev, true, false);
392-
/* Received a STOP/DRAIN trigger */
393-
strm->state = I2S_STATE_READY;
394-
}
395-
break;
396-
case I2S_STATE_ERROR:
342+
if (strm->state == I2S_STATE_ERROR) {
397343
i2s_rx_stream_disable(dev, true, true);
398-
break;
399-
default:
400-
break;
401344
}
345+
346+
if (strm->state != I2S_STATE_STOPPING && strm->state != I2S_STATE_RUNNING) {
347+
return;
348+
}
349+
350+
/* retrieve buffer from input queue */
351+
ret = k_msgq_get(&strm->in_queue, &buffer, K_NO_WAIT);
352+
__ASSERT_NO_MSG(ret == 0);
353+
354+
/* put buffer to output queue */
355+
ret = k_msgq_put(&strm->out_queue, &buffer, K_NO_WAIT);
356+
if (ret != 0) {
357+
LOG_ERR("buffer %p -> out_queue %p err %d", buffer, &strm->out_queue, ret);
358+
goto error;
359+
}
360+
361+
if (strm->state == I2S_STATE_STOPPING) {
362+
i2s_rx_stream_disable(dev, true, false);
363+
/* Received a STOP/DRAIN trigger */
364+
strm->state = I2S_STATE_READY;
365+
return;
366+
}
367+
368+
/* Now the only possible case is the running state */
369+
370+
/* allocate new buffer for next audio frame */
371+
ret = k_mem_slab_alloc(strm->cfg.mem_slab, &buffer, K_NO_WAIT);
372+
if (ret != 0) {
373+
LOG_ERR("buffer alloc from slab %p err %d", strm->cfg.mem_slab, ret);
374+
goto error;
375+
}
376+
377+
uint32_t data_path = strm->start_channel;
378+
379+
ret = dma_reload(dev_data->dev_dma, strm->dma_channel,
380+
(uint32_t)&base->RDR[data_path], (uint32_t)buffer,
381+
strm->cfg.block_size);
382+
if (ret != 0) {
383+
LOG_ERR("dma_reload() failed with error 0x%x", ret);
384+
goto error;
385+
}
386+
387+
/* put buffer in input queue */
388+
ret = k_msgq_put(&strm->in_queue, &buffer, K_NO_WAIT);
389+
if (ret != 0) {
390+
LOG_ERR("%p -> in_queue %p err %d", buffer, &strm->in_queue, ret);
391+
}
392+
393+
return;
394+
395+
error:
396+
i2s_rx_stream_disable(dev, false, false);
397+
strm->state = I2S_STATE_ERROR;
402398
}
403399

404400
static void enable_mclk_direction(const struct device *dev, bool dir)

0 commit comments

Comments
 (0)