Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions sound/soc/sof/intel/hda-dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,10 @@ static int hda_link_dai_widget_update(struct sof_intel_hda_stream *hda_stream,
}

/* set up/free DAI widget and send DAI_CONFIG IPC */
return hda_ctrl_dai_widget_setup(w, widget_setup);
if (widget_setup)
return hda_ctrl_dai_widget_setup(w);

return hda_ctrl_dai_widget_free(w);
}

static int hda_link_hw_params(struct snd_pcm_substream *substream,
Expand Down Expand Up @@ -447,8 +450,9 @@ static struct snd_soc_cdai_ops sof_probe_compr_ops = {
#endif
#endif

static int ssp_dai_config_update(struct snd_pcm_substream *substream, struct snd_soc_dai *dai,
bool widget_setup)
static int ssp_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_dapm_widget *w;

Expand All @@ -457,20 +461,20 @@ static int ssp_dai_config_update(struct snd_pcm_substream *substream, struct snd
else
w = dai->capture_widget;

return hda_ctrl_dai_widget_setup(w, widget_setup);
}

static int ssp_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
return ssp_dai_config_update(substream, dai, true);
return hda_ctrl_dai_widget_setup(w);
}

static int ssp_dai_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
return ssp_dai_config_update(substream, dai, false);
struct snd_soc_dapm_widget *w;

if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
w = dai->playback_widget;
else
w = dai->capture_widget;

return hda_ctrl_dai_widget_free(w);
}

static const struct snd_soc_dai_ops ssp_dai_ops = {
Expand Down
67 changes: 49 additions & 18 deletions sound/soc/sof/intel/hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@
#define EXCEPT_MAX_HDR_SIZE 0x400
#define HDA_EXT_ROM_STATUS_SIZE 8

/*
* Helper function to set up a DAI widget in the DSP and then send the updated DAI config during
* hw_params or send the updated DAI_CONFIG and then free the DAI widget during hw_free
*/
int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, bool setup)
int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w)
{
struct snd_sof_widget *swidget = w->dobj.private;
struct snd_soc_component *component = swidget->scomp;
Expand All @@ -66,28 +62,60 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, bool setup)

/*
* For static pipelines, the DAI widget would already be set up and calling
* sof_widget_setup()/free() simply returns without doing anything.
* For dynamic pipelines, the DAI widget will be set up or freed here.
* sof_widget_setup() simply returns without doing anything.
* For dynamic pipelines, the DAI widget will be set up now.
*/
if (setup) {
ret = sof_widget_setup(sdev, swidget);
if (ret < 0) {
dev_err(sdev->dev, "error: setting up DAI widget %s\n", w->name);
return ret;
}
ret = sof_widget_setup(sdev, swidget);
if (ret < 0) {
dev_err(sdev->dev, "error: failed setting up DAI widget %s\n", w->name);
return ret;
}

/* send DAI_CONFIG IPC */
return sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
&reply, sizeof(reply));
/* send DAI_CONFIG IPC */
ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
&reply, sizeof(reply));
if (ret < 0) {
dev_err(sdev->dev, "error: failed setting DAI config for %s\n", w->name);
return ret;
}

sof_dai->configured = true;

return 0;
}

int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w)
{
struct snd_sof_widget *swidget = w->dobj.private;
struct snd_soc_component *component = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct sof_ipc_dai_config *config;
struct snd_sof_dai *sof_dai;
struct sof_ipc_reply reply;
int ret;

sof_dai = swidget->private;

if (!sof_dai || !sof_dai->dai_config) {
dev_err(sdev->dev, "error: No config to free DAI %s\n", w->name);
return -EINVAL;
}

/* nothing to do if hw_free() is called without restarting the stream after resume. */
if (!sof_dai->configured)
return 0;

config = &sof_dai->dai_config[sof_dai->current_config];

ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
&reply, sizeof(reply));
if (ret < 0) {
dev_err(sdev->dev, "error: updating DAI config for %s\n", w->name);
dev_err(sdev->dev, "error: failed resetting DAI config for %s\n", w->name);
return ret;
}

sof_dai->configured = false;

return sof_widget_free(sdev, swidget);
}

Expand Down Expand Up @@ -129,7 +157,10 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev,
config->dai_index = (link_id << 8) | dai_id;
config->alh.stream_id = alh_stream_id;

return hda_ctrl_dai_widget_setup(w, setup);
if (setup)
return hda_ctrl_dai_widget_setup(w);

return hda_ctrl_dai_widget_free(w);
}

static int sdw_params_stream(struct device *dev,
Expand Down
3 changes: 2 additions & 1 deletion sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,7 @@ int hda_pci_intel_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)

struct snd_sof_dai;
struct sof_ipc_dai_config;
int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, bool setup);
int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w);
int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w);

#endif
1 change: 1 addition & 0 deletions sound/soc/sof/sof-audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ int sof_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget)
return -ENOMEM;

dai = swidget->private;
dai->configured = false;
memcpy(comp, &dai->comp_dai, sizeof(struct sof_ipc_comp_dai));

/* append extended data to the end of the component */
Expand Down
1 change: 1 addition & 0 deletions sound/soc/sof/sof-audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct snd_sof_dai {
struct sof_ipc_comp_dai comp_dai;
int number_configs;
int current_config;
bool configured; /* DAI configured during BE hw_params */
struct sof_ipc_dai_config *dai_config;
struct list_head list; /* list in sdev dai list */
};
Expand Down