1111#include "sof-audio.h"
1212#include "ops.h"
1313
14+ static int sof_kcontrol_setup (struct snd_sof_dev * sdev , struct snd_sof_control * scontrol )
15+ {
16+ int ipc_cmd , ctrl_type ;
17+ int ret ;
18+
19+ /* reset readback offset for scontrol */
20+ scontrol -> readback_offset = 0 ;
21+
22+ /* notify DSP of kcontrol values */
23+ switch (scontrol -> cmd ) {
24+ case SOF_CTRL_CMD_VOLUME :
25+ case SOF_CTRL_CMD_ENUM :
26+ case SOF_CTRL_CMD_SWITCH :
27+ ipc_cmd = SOF_IPC_COMP_SET_VALUE ;
28+ ctrl_type = SOF_CTRL_TYPE_VALUE_CHAN_SET ;
29+ break ;
30+ case SOF_CTRL_CMD_BINARY :
31+ ipc_cmd = SOF_IPC_COMP_SET_DATA ;
32+ ctrl_type = SOF_CTRL_TYPE_DATA_SET ;
33+ break ;
34+ default :
35+ return 0 ;
36+ }
37+
38+ ret = snd_sof_ipc_set_get_comp_data (scontrol , ipc_cmd , ctrl_type , scontrol -> cmd , true);
39+ if (ret < 0 )
40+ dev_err (sdev -> dev , "error: failed kcontrol value set for widget: %d\n" ,
41+ scontrol -> comp_id );
42+
43+ return ret ;
44+ }
45+
46+ static int sof_dai_config_setup (struct snd_sof_dev * sdev , struct snd_sof_dai * dai )
47+ {
48+ struct sof_ipc_dai_config * config ;
49+ struct sof_ipc_reply reply ;
50+ int ret ;
51+
52+ config = & dai -> dai_config [dai -> current_config ];
53+ if (!config ) {
54+ dev_err (sdev -> dev , "error: no config for DAI %s\n" , dai -> name );
55+ return - EINVAL ;
56+ }
57+
58+ ret = sof_ipc_tx_message (sdev -> ipc , config -> hdr .cmd , config , config -> hdr .size ,
59+ & reply , sizeof (reply ));
60+
61+ if (ret < 0 )
62+ dev_err (sdev -> dev , "error: failed to set dai config for %s\n" , dai -> name );
63+
64+ return ret ;
65+ }
66+
67+ static int sof_widget_setup (struct snd_sof_dev * sdev , struct snd_sof_widget * swidget )
68+ {
69+ struct sof_ipc_pipe_new * pipeline ;
70+ struct sof_ipc_comp_reply r ;
71+ struct sof_ipc_cmd_hdr * hdr ;
72+ struct sof_ipc_comp * comp ;
73+ struct snd_sof_dai * dai ;
74+ size_t ipc_size ;
75+ int ret ;
76+
77+ /* skip if there is no private data */
78+ if (!swidget -> private )
79+ return 0 ;
80+
81+ ret = sof_pipeline_core_enable (sdev , swidget );
82+ if (ret < 0 ) {
83+ dev_err (sdev -> dev , "error: failed to enable target core: %d for widget %s\n" ,
84+ ret , swidget -> widget -> name );
85+ return ret ;
86+ }
87+
88+ switch (swidget -> id ) {
89+ case snd_soc_dapm_dai_in :
90+ case snd_soc_dapm_dai_out :
91+ ipc_size = sizeof (struct sof_ipc_comp_dai ) + sizeof (struct sof_ipc_comp_ext );
92+ comp = kzalloc (ipc_size , GFP_KERNEL );
93+ if (!comp )
94+ return - ENOMEM ;
95+
96+ dai = swidget -> private ;
97+ memcpy (comp , & dai -> comp_dai , sizeof (struct sof_ipc_comp_dai ));
98+
99+ /* append extended data to the end of the component */
100+ memcpy ((u8 * )comp + sizeof (struct sof_ipc_comp_dai ), & swidget -> comp_ext ,
101+ sizeof (swidget -> comp_ext ));
102+
103+ ret = sof_ipc_tx_message (sdev -> ipc , comp -> hdr .cmd , comp , ipc_size , & r , sizeof (r ));
104+ kfree (comp );
105+ break ;
106+ case snd_soc_dapm_scheduler :
107+ pipeline = swidget -> private ;
108+ ret = sof_load_pipeline_ipc (sdev -> dev , pipeline , & r );
109+ break ;
110+ default :
111+ hdr = swidget -> private ;
112+ ret = sof_ipc_tx_message (sdev -> ipc , hdr -> cmd , swidget -> private , hdr -> size ,
113+ & r , sizeof (r ));
114+ break ;
115+ }
116+ if (ret < 0 )
117+ dev_err (sdev -> dev , "error: failed to load widget %s\n" , swidget -> widget -> name );
118+ else
119+ dev_dbg (sdev -> dev , "widget %s setup complete\n" , swidget -> widget -> name );
120+
121+ return ret ;
122+ }
123+
14124/*
15125 * helper to determine if there are only D0i3 compatible
16126 * streams active
@@ -97,46 +207,13 @@ static int sof_restore_kcontrols(struct device *dev)
97207{
98208 struct snd_sof_dev * sdev = dev_get_drvdata (dev );
99209 struct snd_sof_control * scontrol ;
100- int ipc_cmd , ctrl_type ;
101210 int ret = 0 ;
102211
103212 /* restore kcontrol values */
104213 list_for_each_entry (scontrol , & sdev -> kcontrol_list , list ) {
105- /* reset readback offset for scontrol after resuming */
106- scontrol -> readback_offset = 0 ;
107-
108- /* notify DSP of kcontrol values */
109- switch (scontrol -> cmd ) {
110- case SOF_CTRL_CMD_VOLUME :
111- case SOF_CTRL_CMD_ENUM :
112- case SOF_CTRL_CMD_SWITCH :
113- ipc_cmd = SOF_IPC_COMP_SET_VALUE ;
114- ctrl_type = SOF_CTRL_TYPE_VALUE_CHAN_SET ;
115- ret = snd_sof_ipc_set_get_comp_data (scontrol ,
116- ipc_cmd , ctrl_type ,
117- scontrol -> cmd ,
118- true);
119- break ;
120- case SOF_CTRL_CMD_BINARY :
121- ipc_cmd = SOF_IPC_COMP_SET_DATA ;
122- ctrl_type = SOF_CTRL_TYPE_DATA_SET ;
123- ret = snd_sof_ipc_set_get_comp_data (scontrol ,
124- ipc_cmd , ctrl_type ,
125- scontrol -> cmd ,
126- true);
127- break ;
128-
129- default :
130- break ;
131- }
132-
133- if (ret < 0 ) {
134- dev_err (dev ,
135- "error: failed kcontrol value set for widget: %d\n" ,
136- scontrol -> comp_id );
137-
214+ ret = sof_kcontrol_setup (sdev , scontrol );
215+ if (ret < 0 )
138216 return ret ;
139- }
140217 }
141218
142219 return 0 ;
@@ -163,77 +240,14 @@ int sof_restore_pipelines(struct device *dev)
163240 struct snd_sof_dev * sdev = dev_get_drvdata (dev );
164241 struct snd_sof_widget * swidget ;
165242 struct snd_sof_route * sroute ;
166- struct sof_ipc_pipe_new * pipeline ;
167243 struct snd_sof_dai * dai ;
168- struct sof_ipc_cmd_hdr * hdr ;
169- struct sof_ipc_comp * comp ;
170- size_t ipc_size ;
171244 int ret ;
172245
173246 /* restore pipeline components */
174247 list_for_each_entry_reverse (swidget , & sdev -> widget_list , list ) {
175- struct sof_ipc_comp_reply r ;
176-
177- /* skip if there is no private data */
178- if (!swidget -> private )
179- continue ;
180-
181- ret = sof_pipeline_core_enable (sdev , swidget );
182- if (ret < 0 ) {
183- dev_err (dev ,
184- "error: failed to enable target core: %d\n" ,
185- ret );
186-
187- return ret ;
188- }
189-
190- switch (swidget -> id ) {
191- case snd_soc_dapm_dai_in :
192- case snd_soc_dapm_dai_out :
193- ipc_size = sizeof (struct sof_ipc_comp_dai ) +
194- sizeof (struct sof_ipc_comp_ext );
195- comp = kzalloc (ipc_size , GFP_KERNEL );
196- if (!comp )
197- return - ENOMEM ;
198-
199- dai = swidget -> private ;
200- memcpy (comp , & dai -> comp_dai ,
201- sizeof (struct sof_ipc_comp_dai ));
202-
203- /* append extended data to the end of the component */
204- memcpy ((u8 * )comp + sizeof (struct sof_ipc_comp_dai ),
205- & swidget -> comp_ext , sizeof (swidget -> comp_ext ));
206-
207- ret = sof_ipc_tx_message (sdev -> ipc , comp -> hdr .cmd ,
208- comp , ipc_size ,
209- & r , sizeof (r ));
210- kfree (comp );
211- break ;
212- case snd_soc_dapm_scheduler :
213-
214- /*
215- * During suspend, all DSP cores are powered off.
216- * Therefore upon resume, create the pipeline comp
217- * and power up the core that the pipeline is
218- * scheduled on.
219- */
220- pipeline = swidget -> private ;
221- ret = sof_load_pipeline_ipc (dev , pipeline , & r );
222- break ;
223- default :
224- hdr = swidget -> private ;
225- ret = sof_ipc_tx_message (sdev -> ipc , hdr -> cmd ,
226- swidget -> private , hdr -> size ,
227- & r , sizeof (r ));
228- break ;
229- }
230- if (ret < 0 ) {
231- dev_err (dev ,
232- "error: failed to load widget type %d with ID: %d\n" ,
233- swidget -> widget -> id , swidget -> comp_id );
234-
248+ ret = sof_widget_setup (sdev , swidget );
249+ if (ret < 0 )
235250 return ret ;
236- }
237251 }
238252
239253 /* restore pipeline connections */
@@ -266,15 +280,8 @@ int sof_restore_pipelines(struct device *dev)
266280
267281 /* restore dai links */
268282 list_for_each_entry_reverse (dai , & sdev -> dai_list , list ) {
269- struct sof_ipc_reply reply ;
270283 struct sof_ipc_dai_config * config = & dai -> dai_config [dai -> current_config ];
271284
272- if (!config ) {
273- dev_err (dev , "error: no config for DAI %s\n" ,
274- dai -> name );
275- continue ;
276- }
277-
278285 /*
279286 * The link DMA channel would be invalidated for running
280287 * streams but not for streams that were in the PAUSED
@@ -284,18 +291,9 @@ int sof_restore_pipelines(struct device *dev)
284291 if (config -> type == SOF_DAI_INTEL_HDA )
285292 config -> hda .link_dma_ch = DMA_CHAN_INVALID ;
286293
287- ret = sof_ipc_tx_message (sdev -> ipc ,
288- config -> hdr .cmd , config ,
289- config -> hdr .size ,
290- & reply , sizeof (reply ));
291-
292- if (ret < 0 ) {
293- dev_err (dev ,
294- "error: failed to set dai config for %s\n" ,
295- dai -> name );
296-
294+ ret = sof_dai_config_setup (sdev , dai );
295+ if (ret < 0 )
297296 return ret ;
298- }
299297 }
300298
301299 /* complete pipeline */
0 commit comments