Skip to content

Conversation

@SurajSonawane2415
Copy link

@SurajSonawane2415 SurajSonawane2415 commented Aug 31, 2025

This PR is part of the GSoC 2025 Project: Add Virtual DAI Component to SOF and is based on SOF Issue #9349.

We introduce a new DAI_VIRTUAL type with driver its associated support to enable audio pipelines that do not rely on physical DAI hardware. This is useful in the following scenarios:

  • Debugging and rapid prototyping: Quickly create and test audio pipelines without needing actual hardware.
  • Software loopback preparation: Lays the groundwork for a memory-to-memory audio pipeline within SOF.

Key Changes

  • Added Virtual DAI driver (initial version with basic logs).
  • Added DTS binding (dai-virtual.yaml).
  • Updated Kconfig/CMake and integrated with i.MX8M DTS.
  • Added ztest-based test suite for basic API validation.

Testing

  • Platform: i.MX8MP EVK with Virtual DAI topology.
  • Environment: Zephyr-based SOF build.
  • Results:
    • NoCodec card + Virtual DAI detected.
    • Probe, config, and removal flows working as expected.
    • All test cases executed successfully, all tests passed

Logs:

*** Booting Zephyr OS build 6e3ea447cbfb ***
[00:00:00.046,014] <inf> main: SOF on imx8mp_evk
[00:00:00.051,043] <inf> main: SOF initialized
[00:00:00.055,909] <inf> ipc: ipc: new cmd 0x90030000
[00:00:00.061,749] <inf> ipc: ipc: new cmd 0x30100000
[00:00:00.066,973] <inf> pipe: pipeline new pipe_id 1 priority 0
[00:00:00.074,086] <inf> ipc: ipc: new cmd 0x30010000
[00:00:00.079,312] <inf> ipc: comp new 0x924549b4U type 2 id 1.4
[00:00:00.085,734] <inf> dai_comp: DAIZ: dai_new()
[00:00:00.090,941] <inf> dai_comp: DAIZ: dai_common_new()
[00:00:00.096,757] <inf> virtual_dai: virtual_dai_config_get
[00:00:00.102,833] <inf> virtual_dai: virtual_dai_probe
[00:00:00.108,476] <inf> dma: sof_dma_get: dir=0, cap=0x0, dev=0x0, flags=0x0
[00:00:00.116,028] <inf> dma: dma_init
[00:00:00.120,198] <inf> dma: sof_dma_get(): Final selection -> ID 0, sref=1, busy=0
[00:00:00.129,043] <inf> ipc: ipc: new cmd 0x80010000
[00:00:00.134,266] <inf> ipc: ipc: dai 16.7 -> config 
[00:00:00.139,820] <inf> virtual_dai: virtual_dai_config_get
[00:00:00.145,896] <inf> virtual_dai: virtual_dai_probe
[00:00:00.151,539] <inf> dai_comp: DAIZ: dai_set_config()
[00:00:00.157,354] <inf> virtual_dai: virtual_dai_config_set
[00:00:00.163,429] <inf> virtual_dai: virtual_dai_remove
[00:00:00.169,163] <inf> ipc: ipc_comp_dai_config() dai type = 16 index = 7
[00:00:00.176,541] <inf> ipc: comp:1.4 dai_config() dai type = 16 index = 7 dd 0x92c05ee0
[00:00:00.185,132] <inf> dai_comp: DAIZ: dai_get_handshake()
[00:00:00.191,208] <inf> virtual_dai: virtual_dai_get_properties

Related Work

Future Work

  • Implement playback and record:
    • Playback: log output frames and discard.
    • Record: generate frames filled with zeroes.
      (Current limitation: To get aplay and arecord working, I replaced the real DMA with emul_dma for Virtual DAI. All functions execute, but data is not being copied in dma_emul_work_handler during playback.)

@github-actions
Copy link

Hello @SurajSonawane2415, and thank you very much for your first pull request to the Zephyr project!
Our Continuous Integration pipeline will execute a series of checks on your Pull Request commit messages and code, and you are expected to address any failures by updating the PR. Please take a look at our commit message guidelines to find out how to format your commit messages, and at our contribution workflow to understand how to update your Pull Request. If you haven't already, please make sure to review the project's Contributor Expectations and update (by amending and force-pushing the commits) your pull request if necessary.
If you are stuck or need help please join us on Discord and ask your question there. Additionally, you can escalate the review when applicable. 😊

Copy link
Contributor

@kv2019i kv2019i left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @SurajSonawane24 ! Code is looking good. Only some minor notes on documentation, Kconfig defaults and log verbosity. Please see inline.


config DAI_VIRTUAL
bool "Virtual DAI driver support for SOF"
default n
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also no need to mention SOF. While SOF is currently the primary user of DAI interface, DAIs could be used by any app.

bool "Virtual DAI driver support for SOF"
default n
help
Enable support for a Virtual DAI (Digital Audio Interface) in SOF.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto here.


static int virtual_dai_probe(const struct device *dev)
{
LOG_INF("%s", __func__);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd reduce the number of these LOG_INF()s in the merged version. I know this virtual DAI is more for R&D use, so logging can be on the more verbose side, but I'd still drop the function entry/exit logs (especially as Zephyr logging can add the function info with a build option, no need to add "func" in driver code.

Comment on lines 4 to 8
description: |
Zephyr binding for a Virtual DAI (Digital Audio Interface).
This DAI is not connected to real hardware and is used for software-only
audio routing or testing within SOF + Zephyr systems.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
description: |
Zephyr binding for a Virtual DAI (Digital Audio Interface).
This DAI is not connected to real hardware and is used for software-only
audio routing or testing within SOF + Zephyr systems.
title: Zephyr for a Virtual DAI (Digital Audio Interface)
description: |
This DAI is not connected to real hardware and is used for software-only
audio routing or testing within SOF + Zephyr systems.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the suggestions, I’ve made the changes.

Comment on lines 58 to 55
static const struct dai_properties
*virtual_dai_get_properties(const struct device *dev, enum dai_dir dir, int stream_id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static const struct dai_properties
*virtual_dai_get_properties(const struct device *dev, enum dai_dir dir, int stream_id)
static const struct dai_properties *virtual_dai_get_properties(const struct device *dev,
enum dai_dir dir, int stream_id)

or

Suggested change
static const struct dai_properties
*virtual_dai_get_properties(const struct device *dev, enum dai_dir dir, int stream_id)
static const struct dai_properties*
virtual_dai_get_properties(const struct device *dev, enum dai_dir dir, int stream_id)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rruuaanng I accepted your suggestion, just kept the * with the function name (not the type) to follow kernel coding style.

Comment on lines +106 to +110
static struct virtual_dai_data virtual_dai_data_##inst = { \
.cfg.type = DAI_VIRTUAL, \
.cfg.dai_index = DT_INST_PROP_OR(inst, dai_index, 0), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, \
&virtual_dai_init, NULL, \
&virtual_dai_data_##inst, NULL, \
POST_KERNEL, CONFIG_DAI_INIT_PRIORITY, \
&virtual_dai_api);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static struct virtual_dai_data virtual_dai_data_##inst = { \
.cfg.type = DAI_VIRTUAL, \
.cfg.dai_index = DT_INST_PROP_OR(inst, dai_index, 0), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, \
&virtual_dai_init, NULL, \
&virtual_dai_data_##inst, NULL, \
POST_KERNEL, CONFIG_DAI_INIT_PRIORITY, \
&virtual_dai_api);
static struct virtual_dai_data virtual_dai_data_##inst = { \
.cfg.type = DAI_VIRTUAL, \
.cfg.dai_index = DT_INST_PROP_OR(inst, dai_index, 0), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, \
&virtual_dai_init, NULL, \
&virtual_dai_data_##inst, NULL, \
POST_KERNEL, CONFIG_DAI_INIT_PRIORITY, \
&virtual_dai_api);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rruuaanng Thanks for the suggestion. Can you clarify the reason for these whitespace changes?

@SurajSonawane2415 SurajSonawane2415 force-pushed the feature/zephyr-virtual-dai branch from 7dfac22 to 7f3747d Compare September 3, 2025 05:22
@SurajSonawane2415
Copy link
Author

Thanks @SurajSonawane24 ! Code is looking good. Only some minor notes on documentation, Kconfig defaults and log verbosity. Please see inline.

@kv2019i Thanks for the detailed review!

  • Dropped the redundant default n.
  • Removed “SOF” mention from Kconfig description.
  • Cleaned up logging by dropping function entry/exit logs, keeping only meaningful ones (using DBG instead of INF).

kv2019i
kv2019i previously approved these changes Sep 3, 2025
Copy link
Contributor

@kv2019i kv2019i left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good now @SurajSonawane2415 !

Copy link
Contributor

@LaurentiuM1234 LaurentiuM1234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start, but IMO this should still be in the draft stage. I would like to see some actual functionality being implemented here. IMO, as things stand now, this PR introduces a DAI driver that doesn't seem to do anything and a test suite that doesn't test anything particularly useful?

Zephyr binding for a Virtual DAI (Digital Audio Interface).
This DAI is not connected to real hardware and is used for software-only
audio routing or testing within SOF + Zephyr systems.
compatible: "virtual_dai"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format of the compatible string is "vendor,model". Also, should be virtual-dai. My suggestion would be to use zephyr,virtual-dai.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you I will make the changes.

status = "disabled";
};

virtual_dai: virtual_dai {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no virtual devices in the mainline DT, please. We can move this to the application DT overlay. See host_dma from https://github.com/thesofproject/sof/blob/main/app/boards/imx8qm_mek_mimx8qm6_adsp.overlay as an example.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for pointing this out. I’ve removed it.
I’ll refer to the host_dma example you shared for guidance.

@SurajSonawane2415
Copy link
Author

Good start, but IMO this should still be in the draft stage. I would like to see some actual functionality being implemented here. IMO, as things stand now, this PR introduces a DAI driver that doesn't seem to do anything and a test suite that doesn't test anything particularly useful?

Thanks for the feedback! I’ve marked it as draft.

Introduce a virtual DAI driver for prototyping, loopback, and testing
without requiring physical DAI hardware.

This includes:
- Initial virtual DAI implementation (logging only)
- DTS binding (dai-virtual.yaml)
- Kconfig and CMake updates
- i.MX8M DTS integration

Signed-off-by: Suraj Sonawane <[email protected]>
Add a basic ztest-based testsuite for the virtual DAI driver. This
includes initial API coverage and simple validation.

Signed-off-by: Suraj Sonawane <[email protected]>
@SurajSonawane2415 SurajSonawane2415 force-pushed the feature/zephyr-virtual-dai branch from 7cc9c25 to a6c0c23 Compare September 8, 2025 15:26
@sonarqubecloud
Copy link

sonarqubecloud bot commented Sep 8, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants