|
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