Skip to content

Commit 93d7124

Browse files
ranj063broonie
authored andcommitted
ASoC: SOF: sof-audio: add helpers for widgets, kcontrols and dai config set up
Refactor the existing code to use helper functions to set up/free widgets, send dai config and set up kcontrols for widgets. These will be reused later on for setting up widgets in the connected DAPM widgets list for a particular PCM when the dynamic pipeline feature is implemented. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://lore.kernel.org/r/20210927120517.20505-5-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 2c28eca commit 93d7124

File tree

1 file changed

+116
-118
lines changed

1 file changed

+116
-118
lines changed

sound/soc/sof/sof-audio.c

Lines changed: 116 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,116 @@
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

Comments
 (0)