Skip to content

Commit b615983

Browse files
committed
copier: dai: use HD-A dai to configure soundwire on LNL
Since LNL soundwire uses HD-A DMA to transfer data add LNL specific configuration to select HD-A DMA in case of soundwire audio interface. Refactor copier dai code for sndw/alh node id type. Add support for sndw link aggregation mode for LNL platform based on DMA config being sent during Copier Init Instance IPC. Signed-off-by: Ievgen Ganakov <ievgen.ganakov@intel.com>
1 parent 415aab5 commit b615983

File tree

3 files changed

+116
-43
lines changed

3 files changed

+116
-43
lines changed

src/audio/copier/copier_dai.c

Lines changed: 84 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,78 @@ static int copier_set_alh_multi_gtw_channel_map(struct comp_dev *dev,
6464
return 0;
6565
}
6666

67+
static int copier_alh_assign_dai_index(struct comp_dev *dev,
68+
void *gtw_cfg_data,
69+
union ipc4_connector_node_id node_id,
70+
struct ipc_config_dai *dai,
71+
int *dai_index,
72+
int *dai_count)
73+
{
74+
struct processing_module *mod = comp_get_drvdata(dev);
75+
struct copier_data *cd = module_get_private_data(mod);
76+
const struct sof_alh_configuration_blob *alh_blob = gtw_cfg_data;
77+
int i, dai_num;
78+
79+
if (!cd->config.gtw_cfg.config_length) {
80+
comp_err(mod->dev, "No gateway config found in blob!");
81+
return -EINVAL;
82+
}
83+
84+
#if defined(CONFIG_ACE_VERSION_2_0)
85+
int ret;
86+
size_t alh_cfg_size = get_alh_config_size(alh_blob);
87+
uint8_t *dma_config = (uint8_t *)gtw_cfg_data + alh_cfg_size;
88+
size_t dma_config_length = (cd->config.gtw_cfg.config_length << 2) - alh_cfg_size;
89+
90+
if (!is_multi_gateway(node_id)) {
91+
ret = ipc4_find_dma_config_multiple(dai, dma_config, dma_config_length,
92+
alh_blob->alh_cfg.mapping[0].alh_id);
93+
if (ret != 0) {
94+
comp_err(mod->dev, "No sndw dma_config found in blob!");
95+
return -EINVAL;
96+
}
97+
dai_index[0] = dai->host_dma_config[0]->stream_id;
98+
99+
return 0;
100+
}
101+
102+
dai_num = alh_blob->alh_cfg.count;
103+
if (dai_num > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_num < 0) {
104+
comp_err(mod->dev, "Invalid dai_count: %d", dai_num);
105+
return -EINVAL;
106+
}
107+
for (i = 0; i < dai_num; i++) {
108+
ret = ipc4_find_dma_config_multiple(dai, dma_config,
109+
dma_config_length,
110+
alh_blob->alh_cfg.mapping[i].alh_id);
111+
if (ret != 0) {
112+
comp_err(mod->dev, "No sndw dma_config found in blob!");
113+
return -EINVAL;
114+
}
115+
dai_index[i] = dai->host_dma_config[i]->stream_id;
116+
}
117+
*dai_count = dai_num;
118+
119+
#else /* defined(CONFIG_ACE_VERSION_2_0) */
120+
if (!is_multi_gateway(node_id)) {
121+
dai_index[0] = IPC4_ALH_DAI_INDEX(node_id.f.v_index);
122+
return 0;
123+
}
124+
125+
dai_num = alh_blob->alh_cfg.count;
126+
if (dai_num > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_num < 0) {
127+
comp_err(mod->dev, "Invalid dai_count: %d", dai_num);
128+
return -EINVAL;
129+
}
130+
131+
for (i = 0; i < dai_num; i++)
132+
dai_index[i] = IPC4_ALH_DAI_INDEX(alh_blob->alh_cfg.mapping[i].alh_id);
133+
134+
*dai_count = dai_num;
135+
#endif /* defined(CONFIG_ACE_VERSION_2_0) */
136+
return 0;
137+
}
138+
67139
static int copier_dai_init(struct comp_dev *dev,
68140
struct comp_ipc_config *config,
69141
const struct ipc4_copier_module_cfg *copier,
@@ -100,7 +172,8 @@ static int copier_dai_init(struct comp_dev *dev,
100172
}
101173

102174
/* save the channel map and count for ALH multi-gateway */
103-
if (type == ipc4_gtw_alh && is_multi_gateway(copier->gtw_cfg.node_id)) {
175+
if ((type == ipc4_gtw_alh || type == ipc4_gtw_link)
176+
&& is_multi_gateway(copier->gtw_cfg.node_id)) {
104177
ret = copier_set_alh_multi_gtw_channel_map(dev, copier, index);
105178
if (ret < 0)
106179
return ret;
@@ -182,50 +255,19 @@ int copier_dai_create(struct comp_dev *dev, struct copier_data *cd,
182255
break;
183256
case ipc4_alh_link_output_class:
184257
case ipc4_alh_link_input_class:
258+
#if defined(CONFIG_ACE_VERSION_2_0)
259+
dai.type = SOF_DAI_INTEL_HDA;
260+
dai.is_config_blob = true;
261+
type = ipc4_gtw_link;
262+
#else
185263
dai.type = SOF_DAI_INTEL_ALH;
186264
dai.is_config_blob = true;
187265
type = ipc4_gtw_alh;
188-
189-
/* copier
190-
* {
191-
* gtw_cfg
192-
* {
193-
* gtw_node_id;
194-
* config_length;
195-
* config_data
196-
* {
197-
* count;
198-
* {
199-
* node_id; \\ normal gtw id
200-
* mask;
201-
* } mapping[MAX_ALH_COUNT];
202-
* }
203-
* }
204-
* }
205-
*/
206-
/* get gtw node id in config data */
207-
if (is_multi_gateway(node_id)) {
208-
if (copier->gtw_cfg.config_length) {
209-
const struct sof_alh_configuration_blob *alh_blob =
210-
(const struct sof_alh_configuration_blob *)
211-
copier->gtw_cfg.config_data;
212-
213-
dai_count = alh_blob->alh_cfg.count;
214-
if (dai_count > IPC4_ALH_MAX_NUMBER_OF_GTW || dai_count < 0) {
215-
comp_err(dev, "Invalid dai_count: %d", dai_count);
216-
return -EINVAL;
217-
}
218-
for (i = 0; i < dai_count; i++)
219-
dai_index[i] =
220-
IPC4_ALH_DAI_INDEX(alh_blob->alh_cfg.mapping[i].alh_id);
221-
} else {
222-
comp_err(dev, "No ipc4_alh_multi_gtw_cfg found in blob!");
223-
return -EINVAL;
224-
}
225-
} else {
226-
dai_index[dai_count - 1] = IPC4_ALH_DAI_INDEX(node_id.f.v_index);
227-
}
228-
266+
#endif /* defined(CONFIG_ACE_VERSION_2_0) */
267+
ret = copier_alh_assign_dai_index(dev, cd->gtw_cfg, node_id,
268+
&dai, dai_index, &dai_count);
269+
if (ret)
270+
return ret;
229271
break;
230272
case ipc4_dmic_link_input_class:
231273
dai.type = SOF_DAI_INTEL_DMIC;
@@ -426,7 +468,6 @@ int copier_dai_params(struct copier_data *cd, struct comp_dev *dev,
426468
cd->converter[IPC4_COPIER_GATEWAY_PIN];
427469
return ret;
428470
}
429-
430471
/* For ALH multi-gateway case, params->channels is a total multiplexed
431472
* number of channels. Demultiplexed number of channels for each individual
432473
* gateway comes in blob's struct ipc4_alh_multi_gtw_cfg.

src/include/ipc4/alh.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,12 @@ struct sof_alh_configuration_blob {
6666
struct ipc4_alh_multi_gtw_cfg alh_cfg;
6767
} __attribute__((packed, aligned(4)));
6868

69+
static inline size_t
70+
get_alh_config_size(const struct sof_alh_configuration_blob *alh_blob)
71+
{
72+
return sizeof(alh_blob->gtw_attributes) +
73+
sizeof(alh_blob->alh_cfg.count) +
74+
sizeof(alh_blob->alh_cfg.mapping[0]) * alh_blob->alh_cfg.count;
75+
}
76+
6977
#endif

src/ipc/ipc4/dai.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <stdbool.h>
2929
#include <stddef.h>
3030
#include <stdint.h>
31+
#include <sof/audio/module_adapter/module/generic.h>
3132

3233
LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);
3334

@@ -83,6 +84,29 @@ int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void
8384
#endif
8485
break;
8586
case SOF_DAI_INTEL_HDA:
87+
#if defined(CONFIG_ACE_VERSION_2_0)
88+
if (copier_cfg->gtw_cfg.node_id.f.dma_type == ipc4_alh_link_output_class ||
89+
copier_cfg->gtw_cfg.node_id.f.dma_type == ipc4_alh_link_input_class) {
90+
struct processing_module *mod = comp_get_drvdata(dev);
91+
struct copier_data *cd = module_get_private_data(mod);
92+
93+
if (!cd->gtw_cfg) {
94+
comp_err(dev, "No gateway config found!");
95+
return DMA_CHAN_INVALID;
96+
}
97+
98+
channel = DMA_CHAN_INVALID;
99+
const struct sof_alh_configuration_blob *alh_blob = cd->gtw_cfg;
100+
101+
for (int i = 0; i < alh_blob->alh_cfg.count; i++) {
102+
if (dai->host_dma_config[i]->stream_id == dai->dai_index) {
103+
channel = dai->host_dma_config[i]->dma_channel_id;
104+
break;
105+
}
106+
}
107+
break;
108+
}
109+
#endif /* defined(CONFIG_ACE_VERSION_2_0) */
86110
channel = copier_cfg->gtw_cfg.node_id.f.v_index;
87111
break;
88112
case SOF_DAI_INTEL_ALH:

0 commit comments

Comments
 (0)