Skip to content

Commit 8e916d5

Browse files
Chao Songlgirdwood
authored andcommitted
selector: extend selector module to use base config extension
This patch extend the selector module to use base config extension for module init, which ensures only base_cfg and base_cfg_ext is received in module init on linux side and align the init blob format with other modules. However, on Windows side, the payload base config with output format style payload is still used, this payload should be supported before Windows doing the payload format migration. Signed-off-by: Chao Song <chao.song@linux.intel.com>
1 parent 5a090a6 commit 8e916d5

File tree

2 files changed

+92
-11
lines changed

2 files changed

+92
-11
lines changed

src/audio/selector/selector.c

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -577,22 +577,27 @@ SOF_MODULE_INIT(selector, sys_comp_selector_init);
577577
static void build_config(struct comp_data *cd, struct module_config *cfg)
578578
{
579579
enum sof_ipc_frame __sparse_cache frame_fmt, valid_fmt;
580+
const struct sof_selector_ipc4_config *sel_cfg = &cd->sel_ipc4_cfg;
581+
const struct ipc4_audio_format *out_fmt;
580582
int i;
581583

584+
if (cd->sel_ipc4_cfg.init_payload_fmt == IPC4_SEL_INIT_PAYLOAD_BASE_WITH_EXT)
585+
out_fmt = &sel_cfg->pin_cfg.out_pin.audio_fmt;
586+
else
587+
out_fmt = &sel_cfg->output_format;
588+
582589
audio_stream_fmt_conversion(cfg->base_cfg.audio_fmt.depth,
583590
cfg->base_cfg.audio_fmt.valid_bit_depth,
584591
&frame_fmt, &valid_fmt,
585592
cfg->base_cfg.audio_fmt.s_type);
586593
cd->source_format = frame_fmt;
587594

588-
audio_stream_fmt_conversion(cd->output_format.depth,
589-
cd->output_format.valid_bit_depth,
590-
&frame_fmt, &valid_fmt,
591-
cd->output_format.s_type);
595+
audio_stream_fmt_conversion(out_fmt->depth, out_fmt->valid_bit_depth,
596+
&frame_fmt, &valid_fmt, out_fmt->s_type);
592597
cd->sink_format = frame_fmt;
593598

594599
cd->config.in_channels_count = cfg->base_cfg.audio_fmt.channels_count;
595-
cd->config.out_channels_count = cd->output_format.channels_count;
600+
cd->config.out_channels_count = out_fmt->channels_count;
596601

597602
/* Build default coefficient array (unity Q10 on diagonal, i.e. pass-through mode) */
598603
memset(&cd->coeffs_config, 0, sizeof(cd->coeffs_config));
@@ -604,20 +609,54 @@ static int selector_init(struct processing_module *mod)
604609
{
605610
struct module_data *md = &mod->priv;
606611
struct module_config *cfg = &md->cfg;
607-
const struct ipc4_base_module_cfg *base_cfg = cfg->init_data;
612+
const struct ipc4_base_module_extended_cfg *init_cfg_ext;
613+
const struct sof_selector_avs_ipc4_config *init_cfg_out_fmt;
614+
enum ipc4_selector_init_payload_fmt payload_fmt;
608615
struct comp_data *cd;
616+
size_t base_cfg_size;
617+
size_t bs[2];
609618
int ret;
610619

611620
comp_dbg(mod->dev, "selector_init()");
612621

622+
init_cfg_ext = cfg->init_data;
623+
init_cfg_out_fmt = cfg->init_data;
624+
base_cfg_size = sizeof(struct ipc4_base_module_cfg);
625+
bs[0] = ipc4_calc_base_module_cfg_ext_size(SEL_NUM_IN_PIN_FMTS,
626+
SEL_NUM_OUT_PIN_FMTS);
627+
bs[1] = sizeof(struct ipc4_audio_format);
628+
629+
if (cfg->size == base_cfg_size + bs[0]) {
630+
payload_fmt = IPC4_SEL_INIT_PAYLOAD_BASE_WITH_EXT;
631+
632+
if (init_cfg_ext->base_cfg_ext.nb_input_pins != SEL_NUM_IN_PIN_FMTS ||
633+
init_cfg_ext->base_cfg_ext.nb_output_pins != SEL_NUM_OUT_PIN_FMTS) {
634+
comp_err(mod->dev, "selector_init(): Invalid pin configuration");
635+
return -EINVAL;
636+
}
637+
} else if (cfg->size == base_cfg_size + bs[1]) {
638+
payload_fmt = IPC4_SEL_INIT_PAYLOAD_BASE_WITH_OUT_FMT;
639+
} else {
640+
comp_err(mod->dev, "selector_init(): Invalid configuration size");
641+
return -EINVAL;
642+
}
643+
613644
cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd));
614645
if (!cd)
615646
return -ENOMEM;
616647

648+
cd->sel_ipc4_cfg.init_payload_fmt = payload_fmt;
617649
md->private = cd;
618650

619-
ret = memcpy_s(&cd->output_format, sizeof(cd->output_format),
620-
base_cfg + 1, sizeof(struct ipc4_audio_format));
651+
if (payload_fmt == IPC4_SEL_INIT_PAYLOAD_BASE_WITH_EXT) {
652+
size_t size = sizeof(struct sof_selector_ipc4_pin_config);
653+
654+
ret = memcpy_s(&cd->sel_ipc4_cfg.pin_cfg, size,
655+
init_cfg_ext->base_cfg_ext.pin_formats, size);
656+
} else {
657+
ret = memcpy_s(&cd->sel_ipc4_cfg.output_format, bs[1],
658+
&init_cfg_out_fmt->output_format, bs[1]);
659+
}
621660
assert(!ret);
622661

623662
build_config(cd, cfg);
@@ -631,11 +670,17 @@ static void set_selector_params(struct processing_module *mod,
631670
struct comp_dev *dev = mod->dev;
632671
struct comp_data *cd = module_get_private_data(mod);
633672
struct comp_buffer __sparse_cache *source;
634-
struct ipc4_audio_format *out_fmt;
673+
const struct sof_selector_ipc4_config *sel_cfg = &cd->sel_ipc4_cfg;
674+
const struct ipc4_audio_format *out_fmt = NULL;
635675
struct comp_buffer *src_buf;
636676
struct list_item *sink_list;
637677
int i;
638678

679+
if (cd->sel_ipc4_cfg.init_payload_fmt == IPC4_SEL_INIT_PAYLOAD_BASE_WITH_EXT)
680+
out_fmt = &sel_cfg->pin_cfg.out_pin.audio_fmt;
681+
else
682+
out_fmt = &sel_cfg->output_format;
683+
639684
if (dev->direction == SOF_IPC_STREAM_PLAYBACK)
640685
params->channels = cd->config.in_channels_count;
641686
else
@@ -644,7 +689,6 @@ static void set_selector_params(struct processing_module *mod,
644689
params->rate = mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency;
645690
params->frame_fmt = cd->source_format;
646691

647-
out_fmt = &cd->output_format;
648692
for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++)
649693
params->chmap[i] = (out_fmt->ch_map >> i * 4) & 0xf;
650694

src/include/sof/audio/selector.h

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ struct comp_dev;
4242

4343
/** \brief Maximum supported channel count on output. */
4444
#define SEL_SINK_CHANNELS_MAX 8
45+
46+
#define SEL_NUM_IN_PIN_FMTS 1
47+
#define SEL_NUM_OUT_PIN_FMTS 1
48+
4549
#endif
4650

4751
#if CONFIG_IPC_MAJOR_4
@@ -62,6 +66,39 @@ struct ipc4_selector_coeffs_config {
6266
/** Mixing coefficients in Q10 fixed point format */
6367
int16_t coeffs[SEL_SINK_CHANNELS_MAX][SEL_SOURCE_CHANNELS_MAX];
6468
};
69+
70+
enum ipc4_selector_init_payload_fmt {
71+
IPC4_SEL_INIT_PAYLOAD_BASE_WITH_EXT,
72+
IPC4_SEL_INIT_PAYLOAD_BASE_WITH_OUT_FMT,
73+
};
74+
75+
struct sof_selector_ipc4_pin_config {
76+
struct ipc4_input_pin_format in_pin;
77+
struct ipc4_output_pin_format out_pin;
78+
};
79+
80+
/*
81+
* Base module config is not added in this structure because it is handled
82+
* by module adapter.
83+
*/
84+
struct sof_selector_ipc4_config {
85+
/*
86+
* Windows will send the base_config + output_format payload, but Linux will
87+
* send the base_config + base_config_ext payload, use a union to make the
88+
* selector module be compatible for both OSes.
89+
*/
90+
union {
91+
struct sof_selector_ipc4_pin_config pin_cfg;
92+
struct ipc4_audio_format output_format;
93+
};
94+
enum ipc4_selector_init_payload_fmt init_payload_fmt;
95+
};
96+
97+
struct sof_selector_avs_ipc4_config {
98+
struct ipc4_base_module_cfg base_cfg;
99+
struct ipc4_audio_format output_format;
100+
};
101+
65102
#else
66103
typedef void (*sel_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink,
67104
const struct audio_stream __sparse_cache *source, uint32_t frames);
@@ -70,7 +107,7 @@ typedef void (*sel_func)(struct comp_dev *dev, struct audio_stream __sparse_cach
70107
/** \brief Selector component private data. */
71108
struct comp_data {
72109
#if CONFIG_IPC_MAJOR_4
73-
struct ipc4_audio_format output_format;
110+
struct sof_selector_ipc4_config sel_ipc4_cfg;
74111
struct ipc4_selector_coeffs_config coeffs_config;
75112
#endif
76113

0 commit comments

Comments
 (0)