aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,rsnd.yaml18
-rw-r--r--sound/soc/sof/ipc4-topology.c83
-rw-r--r--sound/soc/sof/ipc4-topology.h2
3 files changed, 83 insertions, 20 deletions
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
index cb90463c7297..b1f08d6af38d 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
+++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
@@ -18,8 +18,7 @@ properties:
- enum:
- renesas,rcar_sound-r8a7778 # R-Car M1A
- renesas,rcar_sound-r8a7779 # R-Car H1
- - enum:
- - renesas,rcar_sound-gen1
+ - const: renesas,rcar_sound-gen1
# for Gen2 SoC
- items:
- enum:
@@ -32,8 +31,7 @@ properties:
- renesas,rcar_sound-r8a7791 # R-Car M2-W
- renesas,rcar_sound-r8a7793 # R-Car M2-N
- renesas,rcar_sound-r8a7794 # R-Car E2
- - enum:
- - renesas,rcar_sound-gen2
+ - const: renesas,rcar_sound-gen2
# for Gen3 SoC
- items:
- enum:
@@ -47,14 +45,12 @@ properties:
- renesas,rcar_sound-r8a77965 # R-Car M3-N
- renesas,rcar_sound-r8a77990 # R-Car E3
- renesas,rcar_sound-r8a77995 # R-Car D3
- - enum:
- - renesas,rcar_sound-gen3
+ - const: renesas,rcar_sound-gen3
# for Generic
- - items:
- - enum:
- - renesas,rcar_sound-gen1
- - renesas,rcar_sound-gen2
- - renesas,rcar_sound-gen3
+ - enum:
+ - renesas,rcar_sound-gen1
+ - renesas,rcar_sound-gen2
+ - renesas,rcar_sound-gen3
reg:
minItems: 1
diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c
index 59f4d42f9011..ba99114e86a9 100644
--- a/sound/soc/sof/ipc4-topology.c
+++ b/sound/soc/sof/ipc4-topology.c
@@ -354,6 +354,13 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
goto free_available_fmt;
}
+ /*
+ * This callback is used by host copier and module-to-module copier,
+ * and only host copier needs to set gtw_cfg.
+ */
+ if (!WIDGET_IS_AIF(swidget->id))
+ goto skip_gtw_cfg;
+
ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size,
SOF_COPIER_GATEWAY_CFG_TOKENS, swidget->tuples,
swidget->num_tuples, sizeof(u32),
@@ -380,7 +387,7 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
}
dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type);
- ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type);
+skip_gtw_cfg:
ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL);
if (!ipc4_copier->gtw_attr) {
ret = -ENOMEM;
@@ -391,6 +398,21 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
ipc4_copier->data.gtw_cfg.config_length =
sizeof(struct sof_ipc4_gtw_attributes) >> 2;
+ switch (swidget->id) {
+ case snd_soc_dapm_aif_in:
+ case snd_soc_dapm_aif_out:
+ ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type);
+ break;
+ case snd_soc_dapm_buffer:
+ ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID;
+ ipc4_copier->ipc_config_size = 0;
+ break;
+ default:
+ dev_err(scomp->dev, "invalid widget type %d\n", swidget->id);
+ ret = -EINVAL;
+ goto free_gtw_attr;
+ }
+
/* set up module info and message header */
ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg);
if (ret)
@@ -951,7 +973,7 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget)
pipeline = pipe_widget->private;
pipeline->mem_usage = 0;
- if (WIDGET_IS_AIF(swidget->id)) {
+ if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) {
ipc4_copier = swidget->private;
} else if (WIDGET_IS_DAI(swidget->id)) {
struct snd_sof_dai *dai = swidget->private;
@@ -1177,6 +1199,22 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
break;
}
+ case snd_soc_dapm_buffer:
+ {
+ ipc4_copier = (struct sof_ipc4_copier *)swidget->private;
+ copier_data = &ipc4_copier->data;
+ available_fmt = &ipc4_copier->available_fmt;
+
+ /*
+ * base_config->audio_fmt represent the input audio formats. Use
+ * the input format as the reference to match pcm params
+ */
+ available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt;
+ ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg);
+ ref_params = pipeline_params;
+
+ break;
+ }
default:
dev_err(sdev->dev, "unsupported type %d for copier %s",
swidget->id, swidget->widget->name);
@@ -1203,8 +1241,11 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
struct sof_ipc4_copier_data *alh_data;
struct sof_ipc4_copier *alh_copier;
struct snd_sof_widget *w;
+ u32 ch_count = 0;
u32 ch_mask = 0;
u32 ch_map;
+ u32 step;
+ u32 mask;
int i;
blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config;
@@ -1214,11 +1255,15 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
/* Get channel_mask from ch_map */
ch_map = copier_data->base_config.audio_fmt.ch_map;
for (i = 0; ch_map; i++) {
- if ((ch_map & 0xf) != 0xf)
+ if ((ch_map & 0xf) != 0xf) {
ch_mask |= BIT(i);
+ ch_count++;
+ }
ch_map >>= 4;
}
+ step = ch_count / blob->alh_cfg.count;
+ mask = GENMASK(step - 1, 0);
/*
* Set each gtw_cfg.node_id to blob->alh_cfg.mapping[]
* for all widgets with the same stream name
@@ -1233,7 +1278,22 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
alh_copier = (struct sof_ipc4_copier *)dai->private;
alh_data = &alh_copier->data;
blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id;
- blob->alh_cfg.mapping[i].channel_mask = ch_mask;
+ /*
+ * Set the same channel mask for playback as the audio data is
+ * duplicated for all speakers. For capture, split the channels
+ * among the aggregated DAIs. For example, with 4 channels on 2
+ * aggregated DAIs, the channel_mask should be 0x3 and 0xc for the
+ * two DAI's.
+ * The channel masks used depend on the cpu_dais used in the
+ * dailink at the machine driver level, which actually comes from
+ * the tables in soc_acpi files depending on the _ADR and devID
+ * registers for each codec.
+ */
+ if (w->id == snd_soc_dapm_dai_in)
+ blob->alh_cfg.mapping[i].channel_mask = ch_mask;
+ else
+ blob->alh_cfg.mapping[i].channel_mask = mask << (step * i);
+
i++;
}
if (blob->alh_cfg.count > 1) {
@@ -1465,6 +1525,7 @@ static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget
break;
case snd_soc_dapm_aif_in:
case snd_soc_dapm_aif_out:
+ case snd_soc_dapm_buffer:
{
struct sof_ipc4_copier *ipc4_copier = swidget->private;
@@ -1970,7 +2031,7 @@ static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
return 0;
}
-static enum sof_tokens host_token_list[] = {
+static enum sof_tokens common_copier_token_list[] = {
SOF_COMP_TOKENS,
SOF_AUDIO_FMT_NUM_TOKENS,
SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS,
@@ -2026,12 +2087,12 @@ static enum sof_tokens src_token_list[] = {
static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = {
[snd_soc_dapm_aif_in] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm,
- host_token_list, ARRAY_SIZE(host_token_list), NULL,
- sof_ipc4_prepare_copier_module,
+ common_copier_token_list, ARRAY_SIZE(common_copier_token_list),
+ NULL, sof_ipc4_prepare_copier_module,
sof_ipc4_unprepare_copier_module},
[snd_soc_dapm_aif_out] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm,
- host_token_list, ARRAY_SIZE(host_token_list), NULL,
- sof_ipc4_prepare_copier_module,
+ common_copier_token_list, ARRAY_SIZE(common_copier_token_list),
+ NULL, sof_ipc4_prepare_copier_module,
sof_ipc4_unprepare_copier_module},
[snd_soc_dapm_dai_in] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai,
dai_token_list, ARRAY_SIZE(dai_token_list), NULL,
@@ -2041,6 +2102,10 @@ static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TY
dai_token_list, ARRAY_SIZE(dai_token_list), NULL,
sof_ipc4_prepare_copier_module,
sof_ipc4_unprepare_copier_module},
+ [snd_soc_dapm_buffer] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm,
+ common_copier_token_list, ARRAY_SIZE(common_copier_token_list),
+ NULL, sof_ipc4_prepare_copier_module,
+ sof_ipc4_unprepare_copier_module},
[snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline,
sof_ipc4_widget_free_comp_pipeline,
pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL,
diff --git a/sound/soc/sof/ipc4-topology.h b/sound/soc/sof/ipc4-topology.h
index 0aa87a8add5d..8dbbf69b0eb7 100644
--- a/sound/soc/sof/ipc4-topology.h
+++ b/sound/soc/sof/ipc4-topology.h
@@ -53,6 +53,8 @@
#define ALH_MAX_NUMBER_OF_GTW 16
+#define SOF_IPC4_INVALID_NODE_ID 0xffffffff
+
/*
* The base of multi-gateways. Multi-gateways addressing starts from
* ALH_MULTI_GTW_BASE and there are ALH_MULTI_GTW_COUNT multi-sources