|
19 | 19 | #define SOF_IPC4_GAIN_PARAM_ID 0 |
20 | 20 | #define SOF_IPC4_TPLG_ABI_SIZE 6 |
21 | 21 |
|
| 22 | +static DEFINE_IDA(alh_group_ida); |
| 23 | + |
22 | 24 | static const struct sof_topology_token ipc4_sched_tokens[] = { |
23 | 25 | {SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, |
24 | 26 | offsetof(struct sof_ipc4_pipeline, lp_mode)} |
@@ -478,14 +480,24 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) |
478 | 480 | switch (ipc4_copier->dai_type) { |
479 | 481 | case SOF_DAI_INTEL_ALH: |
480 | 482 | { |
| 483 | + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); |
481 | 484 | struct sof_ipc4_alh_configuration_blob *blob; |
| 485 | + struct snd_sof_widget *w; |
482 | 486 |
|
483 | 487 | blob = kzalloc(sizeof(*blob), GFP_KERNEL); |
484 | 488 | if (!blob) { |
485 | 489 | ret = -ENOMEM; |
486 | 490 | goto err; |
487 | 491 | } |
488 | 492 |
|
| 493 | + list_for_each_entry(w, &sdev->widget_list, list) { |
| 494 | + if (w->widget->sname && |
| 495 | + strcmp(w->widget->sname, swidget->widget->sname)) |
| 496 | + continue; |
| 497 | + |
| 498 | + blob->alh_cfg.count++; |
| 499 | + } |
| 500 | + |
489 | 501 | ipc4_copier->copier_config = (uint32_t *)blob; |
490 | 502 | ipc4_copier->data.gtw_cfg.config_length = sizeof(*blob) >> 2; |
491 | 503 | break; |
@@ -844,6 +856,17 @@ static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget) |
844 | 856 | struct snd_sof_dai *dai = swidget->private; |
845 | 857 |
|
846 | 858 | ipc4_copier = dai->private; |
| 859 | + if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { |
| 860 | + struct sof_ipc4_alh_configuration_blob *blob; |
| 861 | + unsigned int group_id; |
| 862 | + |
| 863 | + blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; |
| 864 | + if (blob->alh_cfg.count > 1) { |
| 865 | + group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) - |
| 866 | + ALH_MULTI_GTW_BASE; |
| 867 | + ida_free(&alh_group_ida, group_id); |
| 868 | + } |
| 869 | + } |
847 | 870 | } |
848 | 871 |
|
849 | 872 | if (ipc4_copier) { |
@@ -973,6 +996,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, |
973 | 996 | struct sof_ipc4_copier_data *copier_data; |
974 | 997 | struct snd_pcm_hw_params *ref_params; |
975 | 998 | struct sof_ipc4_copier *ipc4_copier; |
| 999 | + struct snd_sof_dai *dai; |
976 | 1000 | struct snd_mask *fmt; |
977 | 1001 | int out_sample_valid_bits; |
978 | 1002 | size_t ref_audio_fmt_size; |
@@ -1022,7 +1046,7 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, |
1022 | 1046 | case snd_soc_dapm_dai_in: |
1023 | 1047 | case snd_soc_dapm_dai_out: |
1024 | 1048 | { |
1025 | | - struct snd_sof_dai *dai = swidget->private; |
| 1049 | + dai = swidget->private; |
1026 | 1050 |
|
1027 | 1051 | ipc4_copier = (struct sof_ipc4_copier *)dai->private; |
1028 | 1052 | copier_data = &ipc4_copier->data; |
@@ -1077,22 +1101,56 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, |
1077 | 1101 | */ |
1078 | 1102 | if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { |
1079 | 1103 | struct sof_ipc4_alh_configuration_blob *blob; |
| 1104 | + struct sof_ipc4_copier_data *alh_data; |
| 1105 | + struct sof_ipc4_copier *alh_copier; |
| 1106 | + struct snd_sof_widget *w; |
| 1107 | + u32 ch_mask = 0; |
1080 | 1108 | u32 ch_map; |
1081 | 1109 | int i; |
1082 | 1110 |
|
1083 | 1111 | blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; |
1084 | | - /* TODO: add aggregation mode support */ |
1085 | | - blob->alh_cfg.count = 1; |
1086 | | - blob->alh_cfg.mapping[0].alh_id = copier_data->gtw_cfg.node_id; |
| 1112 | + |
1087 | 1113 | blob->gw_attr.lp_buffer_alloc = 0; |
1088 | 1114 |
|
1089 | 1115 | /* Get channel_mask from ch_map */ |
1090 | 1116 | ch_map = copier_data->base_config.audio_fmt.ch_map; |
1091 | 1117 | for (i = 0; ch_map; i++) { |
1092 | 1118 | if ((ch_map & 0xf) != 0xf) |
1093 | | - blob->alh_cfg.mapping[0].channel_mask |= BIT(i); |
| 1119 | + ch_mask |= BIT(i); |
1094 | 1120 | ch_map >>= 4; |
1095 | 1121 | } |
| 1122 | + |
| 1123 | + /* |
| 1124 | + * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] |
| 1125 | + * for all widgets with the same stream name |
| 1126 | + */ |
| 1127 | + i = 0; |
| 1128 | + list_for_each_entry(w, &sdev->widget_list, list) { |
| 1129 | + if (w->widget->sname && |
| 1130 | + strcmp(w->widget->sname, swidget->widget->sname)) |
| 1131 | + continue; |
| 1132 | + |
| 1133 | + dai = w->private; |
| 1134 | + alh_copier = (struct sof_ipc4_copier *)dai->private; |
| 1135 | + alh_data = &alh_copier->data; |
| 1136 | + blob->alh_cfg.mapping[i].alh_id = alh_data->gtw_cfg.node_id; |
| 1137 | + blob->alh_cfg.mapping[i].channel_mask = ch_mask; |
| 1138 | + i++; |
| 1139 | + } |
| 1140 | + if (blob->alh_cfg.count > 1) { |
| 1141 | + int group_id; |
| 1142 | + |
| 1143 | + group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT, |
| 1144 | + GFP_KERNEL); |
| 1145 | + |
| 1146 | + if (group_id < 0) |
| 1147 | + return group_id; |
| 1148 | + |
| 1149 | + /* add multi-gateway base */ |
| 1150 | + group_id += ALH_MULTI_GTW_BASE; |
| 1151 | + copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; |
| 1152 | + copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id); |
| 1153 | + } |
1096 | 1154 | } |
1097 | 1155 | } |
1098 | 1156 | } |
|
0 commit comments