|
36 | 36 | #include <stddef.h> |
37 | 37 | #include <stdint.h> |
38 | 38 |
|
| 39 | +#if CONFIG_XRUN_NOTIFICATIONS_ENABLE |
| 40 | +#include <sof/ipc/notification_pool.h> |
| 41 | +#include <ipc4/notification.h> |
| 42 | +#endif |
| 43 | + |
39 | 44 | #include "copier/copier.h" |
40 | 45 | #include "copier/dai_copier.h" |
41 | 46 | #include "copier/copier_gain.h" |
@@ -1462,6 +1467,32 @@ static int dai_comp_trigger(struct comp_dev *dev, int cmd) |
1462 | 1467 | return dai_common_trigger(dd, dev, cmd); |
1463 | 1468 | } |
1464 | 1469 |
|
| 1470 | +/* get status from dma and check for xrun */ |
| 1471 | +static int dai_get_status(struct comp_dev *dev, struct dai_data *dd, struct dma_status *stat) |
| 1472 | +{ |
| 1473 | + int ret = dma_get_status(dd->chan->dma->z_dev, dd->chan->index, stat); |
| 1474 | +#if CONFIG_XRUN_NOTIFICATIONS_ENABLE |
| 1475 | + if (ret == -EPIPE && !dd->xrun_notification_sent) { |
| 1476 | + struct ipc_msg *notify = ipc_notification_pool_get(IPC4_RESOURCE_EVENT_SIZE); |
| 1477 | + |
| 1478 | + if (notify) { |
| 1479 | + if (dev->direction == SOF_IPC_STREAM_PLAYBACK) |
| 1480 | + copier_gateway_underrun_notif_msg_init(notify, |
| 1481 | + dev->pipeline->pipeline_id); |
| 1482 | + else |
| 1483 | + copier_gateway_overrun_notif_msg_init(notify, |
| 1484 | + dev->pipeline->pipeline_id); |
| 1485 | + |
| 1486 | + ipc_msg_send(notify, notify->tx_data, false); |
| 1487 | + dd->xrun_notification_sent = true; |
| 1488 | + } |
| 1489 | + } else if (!ret) { |
| 1490 | + dd->xrun_notification_sent = false; |
| 1491 | + } |
| 1492 | +#endif |
| 1493 | + return ret; |
| 1494 | +} |
| 1495 | + |
1465 | 1496 | /* report xrun occurrence */ |
1466 | 1497 | static void dai_report_xrun(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes) |
1467 | 1498 | { |
@@ -1499,7 +1530,7 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev, |
1499 | 1530 | struct dma_status stat; |
1500 | 1531 |
|
1501 | 1532 | /* get data sizes from DMA */ |
1502 | | - ret = dma_get_status(dd[i]->chan->dma->z_dev, dd[i]->chan->index, &stat); |
| 1533 | + ret = dai_get_status(dev, dd[i], &stat); |
1503 | 1534 | switch (ret) { |
1504 | 1535 | case 0: |
1505 | 1536 | break; |
@@ -1633,7 +1664,7 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun |
1633 | 1664 | int ret; |
1634 | 1665 |
|
1635 | 1666 | /* get data sizes from DMA */ |
1636 | | - ret = dma_get_status(dd->chan->dma->z_dev, dd->chan->index, &stat); |
| 1667 | + ret = dai_get_status(dev, dd, &stat); |
1637 | 1668 | switch (ret) { |
1638 | 1669 | case 0: |
1639 | 1670 | break; |
|
0 commit comments