Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions include/sound/sof/dai.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,30 @@ enum sof_ipc_dai_type {
SOF_DAI_AMD_HS_VIRTUAL, /**< AMD ACP HS VIRTUAL */
SOF_DAI_IMX_MICFIL, /** < i.MX MICFIL PDM */
SOF_DAI_AMD_SDW, /**< AMD ACP SDW */
SOF_DAI_VIRTUAL, /**< Virtual DAI for testing/debugging */
};

/* VIRTUAL DAI Configuration Request - SOF_IPC_DAI_VIRTUAL_CONFIG */
struct sof_ipc_dai_virtual_params {
struct sof_ipc_hdr hdr;

/* MCLK */
uint16_t reserved1;
uint16_t mclk_id;
uint32_t mclk_direction;

uint32_t mclk_rate; /* MCLK frequency in Hz */
uint32_t fsync_rate; /* FSYNC frequency in Hz */
uint32_t bclk_rate; /* BCLK frequency in Hz */

/* TDM */
uint32_t tdm_slots;
uint32_t rx_slots;
uint32_t tx_slots;
uint16_t tdm_slot_width;
uint16_t reserved2; /* alignment */
} __packed;

/* general purpose DAI configuration */
struct sof_ipc_dai_config {
struct sof_ipc_cmd_hdr hdr;
Expand Down Expand Up @@ -121,6 +143,7 @@ struct sof_ipc_dai_config {
struct sof_ipc_dai_mtk_afe_params afe;
struct sof_ipc_dai_micfil_params micfil;
struct sof_ipc_dai_acp_sdw_params acp_sdw;
struct sof_ipc_dai_virtual_params virtual_dai;
};
} __packed;

Expand Down
3 changes: 3 additions & 0 deletions include/uapi/sound/sof/tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,4 +222,7 @@
#define SOF_TKN_AMD_ACP_SDW_RATE 2100
#define SOF_TKN_AMD_ACP_SDW_CH 2101

/* VIRTUAL DAI */
#define SOF_TKN_DAI_VIRTUAL_MCLK_ID 2102

#endif
7 changes: 7 additions & 0 deletions sound/soc/sof/imx/imx8m.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,13 @@ static int imx8m_get_bar_index(struct snd_sof_dev *sdev, u32 type)
}

static struct snd_soc_dai_driver imx8m_dai[] = {
{
.name = "virtual_dai",
.playback = {
.channels_min = 1,
.channels_max = 32,
},
},
{
.name = "sai1",
.playback = {
Expand Down
10 changes: 10 additions & 0 deletions sound/soc/sof/ipc3-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,16 @@ static int sof_ipc3_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
dev_dbg(component->dev, "AMD_SDW channels_min: %d channels_max: %d\n",
channels->min, channels->max);
break;
case SOF_DAI_VIRTUAL:
rate->min = private->dai_config->virtual_dai.fsync_rate;
rate->max = private->dai_config->virtual_dai.fsync_rate;
channels->min = private->dai_config->virtual_dai.tdm_slots;
channels->max = private->dai_config->virtual_dai.tdm_slots;

dev_dbg(component->dev, "rate_min: %d rate_max: %d\n", rate->min, rate->max);
dev_dbg(component->dev, "channels_min: %d channels_max: %d\n",
channels->min, channels->max);
break;
default:
dev_err(component->dev, "Invalid DAI type %d\n", private->dai_config->type);
break;
Expand Down
43 changes: 43 additions & 0 deletions sound/soc/sof/ipc3-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ static const struct sof_topology_token sai_tokens[] = {
offsetof(struct sof_ipc_dai_sai_params, mclk_id)},
};

/* DAI VIRTUAL */
static const struct sof_topology_token dai_virtual_tokens[] = {
{SOF_TKN_DAI_VIRTUAL_MCLK_ID, SND_SOC_TPLG_TUPLE_TYPE_SHORT, get_token_u16,
offsetof(struct sof_ipc_dai_virtual_params, mclk_id)},
};

/*
* DMIC PDM Tokens
* SOF_TKN_INTEL_DMIC_PDM_CTRL_ID should be the first token
Expand Down Expand Up @@ -348,6 +354,7 @@ static const struct sof_token_info ipc3_token_list[SOF_TOKEN_COUNT] = {
[SOF_MICFIL_TOKENS] = {"MICFIL PDM tokens",
micfil_pdm_tokens, ARRAY_SIZE(micfil_pdm_tokens)},
[SOF_ACP_SDW_TOKENS] = {"ACP_SDW tokens", acp_sdw_tokens, ARRAY_SIZE(acp_sdw_tokens)},
[SOF_DAI_VIRTUAL_TOKENS] = {"DAI VIRTUAL tokens", dai_virtual_tokens, ARRAY_SIZE(dai_virtual_tokens)},
};

/**
Expand Down Expand Up @@ -1164,6 +1171,39 @@ static int sof_link_esai_load(struct snd_soc_component *scomp, struct snd_sof_da
return 0;
}

static int sof_link_virtual_dai_load(struct snd_soc_component *scomp, struct snd_sof_dai_link *slink,
struct sof_ipc_dai_config *config, struct snd_sof_dai *dai)
{
struct snd_soc_tplg_hw_config *hw_config = slink->hw_configs;
struct sof_dai_private_data *private = dai->private;
u32 size = sizeof(*config);
int ret;

/* init IPC */
memset(&config->virtual_dai, 0, sizeof(config->virtual_dai));
config->hdr.size = size;

/* set format */
sof_dai_set_format(hw_config, config);

ret = sof_update_ipc_object(scomp, &config->virtual_dai, SOF_DAI_VIRTUAL_TOKENS,
slink->tuples, slink->num_tuples, size, 1);
if (ret < 0)
return ret;

dev_info(scomp->dev,
"tplg: config VIRTUAL_DAI%d fmt 0x%x\n",
config->dai_index, config->format);

dai->number_configs = 1;
dai->current_config = 0;
private->dai_config = kmemdup(config, size, GFP_KERNEL);
if (!private->dai_config)
return -ENOMEM;

return 0;
}

static int sof_link_micfil_load(struct snd_soc_component *scomp, struct snd_sof_dai_link *slink,
struct sof_ipc_dai_config *config, struct snd_sof_dai *dai)
{
Expand Down Expand Up @@ -1661,6 +1701,9 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget)
case SOF_DAI_IMX_ESAI:
ret = sof_link_esai_load(scomp, slink, config, dai);
break;
case SOF_DAI_VIRTUAL:
ret = sof_link_virtual_dai_load(scomp, slink, config, dai);
break;
case SOF_DAI_IMX_MICFIL:
ret = sof_link_micfil_load(scomp, slink, config, dai);
break;
Expand Down
1 change: 1 addition & 0 deletions sound/soc/sof/sof-audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ enum sof_tokens {
SOF_ACPI2S_TOKENS,
SOF_MICFIL_TOKENS,
SOF_ACP_SDW_TOKENS,
SOF_DAI_VIRTUAL_TOKENS,

/* this should be the last */
SOF_TOKEN_COUNT,
Expand Down
5 changes: 5 additions & 0 deletions sound/soc/sof/topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ static const struct sof_dai_types sof_dais[] = {
{"ACPHS_VIRTUAL", SOF_DAI_AMD_HS_VIRTUAL},
{"MICFIL", SOF_DAI_IMX_MICFIL},
{"ACP_SDW", SOF_DAI_AMD_SDW},
{"DAI_VIRTUAL", SOF_DAI_VIRTUAL},

};

Expand Down Expand Up @@ -1948,6 +1949,10 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_
token_id = SOF_ESAI_TOKENS;
num_tuples += token_list[SOF_ESAI_TOKENS].count;
break;
case SOF_DAI_VIRTUAL:
token_id = SOF_DAI_VIRTUAL_TOKENS;
num_tuples += token_list[SOF_DAI_VIRTUAL_TOKENS].count;
break;
case SOF_DAI_MEDIATEK_AFE:
token_id = SOF_AFE_TOKENS;
num_tuples += token_list[SOF_AFE_TOKENS].count;
Expand Down