@@ -3065,6 +3065,36 @@ static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_contr
30653065 return 0 ;
30663066}
30673067
3068+ static void
3069+ sof_ipc4_add_init_ext_module_data (struct snd_sof_dev * sdev ,
3070+ struct snd_sof_widget * swidget ,
3071+ u32 * payload , u32 * ext_pos ,
3072+ struct sof_ipc4_module_init_ext_object * * hdr )
3073+ {
3074+ struct sof_ipc4_process * process = swidget -> private ;
3075+ u32 data_size ;
3076+ void * data ;
3077+
3078+ /*
3079+ * Check if widget is process module and if it is using
3080+ * init_ext_module_data
3081+ */
3082+ if (!WIDGET_IS_PROCESS (swidget -> id ) || !process -> init_ext_module_size )
3083+ return ;
3084+
3085+ data_size = process -> init_ext_module_size ;
3086+ data = process -> init_ext_module_data ;
3087+
3088+ * hdr = (struct sof_ipc4_module_init_ext_object * )& payload [* ext_pos ];
3089+ (* hdr )-> header = SOF_IPC4_MOD_INIT_EXT_OBJ_ID (SOF_IPC4_MOD_INIT_DATA_ID_MODULE_DATA ) |
3090+ SOF_IPC4_MOD_INIT_EXT_OBJ_WORDS (DIV_ROUND_UP (data_size , sizeof (u32 )));
3091+ * ext_pos += DIV_ROUND_UP (sizeof (* (* hdr )), sizeof (u32 ));
3092+
3093+ memcpy (& payload [* ext_pos ], data , data_size );
3094+
3095+ * ext_pos += DIV_ROUND_UP (data_size , sizeof (u32 ));
3096+ }
3097+
30683098static int sof_ipc4_widget_setup_msg_payload (struct snd_sof_dev * sdev ,
30693099 struct snd_sof_widget * swidget ,
30703100 struct sof_ipc4_msg * msg ,
@@ -3073,20 +3103,11 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
30733103{
30743104 struct sof_ipc4_mod_init_ext_dp_memory_data * dp_mem_data ;
30753105 struct sof_ipc4_module_init_ext_init * ext_init ;
3076- struct sof_ipc4_module_init_ext_object * hdr ;
3106+ struct sof_ipc4_module_init_ext_object * hdr = NULL ;
30773107 int new_size ;
30783108 u32 * payload ;
30793109 u32 ext_pos ;
30803110
3081- /* For the moment the only reason for adding init_ext_init payload is DP
3082- * memory data. If both stack and heap size are 0 (= use default), then
3083- * there is no need for init_ext_init payload.
3084- */
3085- if (swidget -> comp_domain != SOF_COMP_DOMAIN_DP ) {
3086- msg -> extension &= ~SOF_IPC4_MOD_EXT_EXTENDED_INIT_MASK ;
3087- return 0 ;
3088- }
3089-
30903111 payload = kzalloc (sdev -> ipc -> max_payload_size , GFP_KERNEL );
30913112 if (!payload )
30923113 return - ENOMEM ;
@@ -3101,7 +3122,7 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
31013122 /* Add dp_memory_data if comp_domain indicates DP */
31023123 if (swidget -> comp_domain == SOF_COMP_DOMAIN_DP ) {
31033124 hdr = (struct sof_ipc4_module_init_ext_object * )& payload [ext_pos ];
3104- hdr -> header = SOF_IPC4_MOD_INIT_EXT_OBJ_LAST_MASK |
3125+ hdr -> header =
31053126 SOF_IPC4_MOD_INIT_EXT_OBJ_ID (SOF_IPC4_MOD_INIT_DATA_ID_DP_DATA ) |
31063127 SOF_IPC4_MOD_INIT_EXT_OBJ_WORDS (DIV_ROUND_UP (sizeof (* dp_mem_data ),
31073128 sizeof (u32 )));
@@ -3113,7 +3134,15 @@ static int sof_ipc4_widget_setup_msg_payload(struct snd_sof_dev *sdev,
31133134 ext_pos += DIV_ROUND_UP (sizeof (* dp_mem_data ), sizeof (u32 ));
31143135 }
31153136
3116- /* If another array object is added, remember clear previous OBJ_LAST bit */
3137+ sof_ipc4_add_init_ext_module_data (sdev , swidget , payload , & ext_pos , & hdr );
3138+
3139+ /* Set last bit for the last object in the array */
3140+ if (hdr ) {
3141+ hdr -> header |= SOF_IPC4_MOD_INIT_EXT_OBJ_LAST_MASK ;
3142+ } else {
3143+ kfree (payload );
3144+ return 0 ;
3145+ }
31173146
31183147 /* Calculate final size and check that it fits to max payload size */
31193148 new_size = ext_pos * sizeof (u32 ) + ipc_size ;
0 commit comments