@@ -577,22 +577,27 @@ SOF_MODULE_INIT(selector, sys_comp_selector_init);
577577static 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
0 commit comments