diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 312c0ad2573fc6..bbb205e69caa47 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -593,6 +593,17 @@ static int intel_config_stream(struct sdw_intel *sdw, return -EIO; } +static int intel_free_stream(struct sdw_intel *sdw, + struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + if (sdw->res->ops && sdw->res->ops->free_stream && sdw->res->arg) + return sdw->res->ops->free_stream(sdw->res->arg, + substream, dai); + + return 0; +} + /* * bank switch routines */ @@ -738,6 +749,62 @@ static int intel_startup(struct snd_pcm_substream *substream, return ret; } +static int sdw_stream_setup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct sdw_stream_runtime *sdw_stream = NULL; + char *name; + int i, ret = 0; + + name = kzalloc(32, GFP_KERNEL); + if (!name) + return -ENOMEM; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + snprintf(name, 32, "%s-Playback", dai->name); + else + snprintf(name, 32, "%s-Capture", dai->name); + + sdw_stream = sdw_alloc_stream(name); + if (!sdw_stream) { + dev_err(dai->dev, + "alloc stream failed for DAI %s: %d", + dai->name, ret); + ret = -ENOMEM; + goto error; + } + + /* Set stream pointer on CPU DAI */ + ret = snd_soc_dai_set_sdw_stream(dai, + sdw_stream, + substream->stream); + if (ret < 0) { + dev_err(dai->dev, "failed to set stream pointer on cpu dai %s", + dai->name); + return ret; + } + + /* Set stream pointer on all CODEC DAIs */ + for (i = 0; i < rtd->num_codecs; i++) { + ret = snd_soc_dai_set_sdw_stream(rtd->codec_dais[i], + sdw_stream, + substream->stream); + if (ret < 0) { + dev_err(dai->dev, "failed to set stream pointer on codec dai %s", + rtd->codec_dais[i]->name); + return ret; + } + } + + return 0; + +error: + kfree(name); + sdw_release_stream(sdw_stream); + return ret; +} + static int intel_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -750,6 +817,12 @@ static int intel_hw_params(struct snd_pcm_substream *substream, int ret, i, ch, dir; bool pcm = true; + ret = sdw_stream_setup(substream, dai); + if (ret) { + dev_err(cdns->dev, "stream setup failed:%d\n", ret); + return -EIO; + } + dma = snd_soc_dai_get_dma_data(dai, substream); if (!dma) return -EIO; @@ -835,10 +908,72 @@ static int intel_hw_params(struct snd_pcm_substream *substream, return ret; } +static int intel_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct sdw_cdns_dma_data *dma; + int ret; + + dma = snd_soc_dai_get_dma_data(dai, substream); + if (!dma) { + dev_err(dai->dev, "failed to get dma data in %s", + __func__); + return -EIO; + } + + ret = sdw_prepare_stream(dma->stream); + return ret; +} + +static int intel_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct sdw_cdns_dma_data *dma; + int ret; + + dma = snd_soc_dai_get_dma_data(dai, substream); + if (!dma) { + dev_err(dai->dev, "failed to get dma data in %s", __func__); + return -EIO; + } + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: + ret = sdw_enable_stream(dma->stream); + if (ret) { + dev_err(dai->dev, + "%s trigger %d failed: %d", + __func__, cmd, ret); + return ret; + } + break; + + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + ret = sdw_disable_stream(dma->stream); + if (ret) { + dev_err(dai->dev, + "%s trigger %d failed: %d", + __func__, cmd, ret); + return ret; + } + break; + + default: + return -EINVAL; + } + + return 0; +} + static int intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); + struct sdw_intel *sdw = cdns_to_intel(cdns); struct sdw_cdns_dma_data *dma; int ret; @@ -846,6 +981,12 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) if (!dma) return -EIO; + ret = sdw_deprepare_stream(dma->stream); + if (ret) { + dev_err(dai->dev, "sdw_deprepare_stream: failed %d", ret); + return ret; + } + ret = sdw_stream_remove_master(&cdns->bus, dma->stream); if (ret < 0) dev_err(dai->dev, "remove master from stream %s failed: %d\n", @@ -853,6 +994,10 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) intel_port_cleanup(dma); kfree(dma->port); + + ret = intel_free_stream(sdw, substream, dai); + sdw_release_stream(dma->stream); + return ret; } @@ -898,6 +1043,8 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = { .hw_free = intel_hw_free, .shutdown = intel_shutdown, .set_sdw_stream = intel_pcm_set_sdw_stream, + .prepare = intel_prepare, + .trigger = intel_trigger, }; static const struct snd_soc_dai_ops intel_pdm_dai_ops = { @@ -905,6 +1052,8 @@ static const struct snd_soc_dai_ops intel_pdm_dai_ops = { .hw_free = intel_hw_free, .shutdown = intel_shutdown, .set_sdw_stream = intel_pdm_set_sdw_stream, + .prepare = intel_prepare, + .trigger = intel_trigger, }; static const struct snd_soc_component_driver dai_component = { diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h index c9427cb6020b3e..5fab33c2530923 100644 --- a/include/linux/soundwire/sdw_intel.h +++ b/include/linux/soundwire/sdw_intel.h @@ -13,6 +13,7 @@ struct sdw_intel_ops { int (*config_stream)(void *arg, void *substream, void *dai, void *hw_params, int stream_num); + int (*free_stream)(void *arg, void *substream, void *dai); }; /** diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 24a61d45c68ab0..e4851c73039037 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -1232,20 +1232,14 @@ static int rt700_pcm_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_component *component = dai->component; struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); - struct sdw_stream_config stream_config; - struct sdw_port_config port_config; + struct sdw_stream_config *stream_config; + struct sdw_port_config *port_config; enum sdw_data_direction direction; - struct sdw_stream_data *stream; - int retval, port, num_channels; + int port, num_channels; unsigned int val = 0; dev_err(dai->dev, "%s %s", __func__, dai->name); - stream = snd_soc_dai_get_dma_data(dai, substream); - - if (!stream) - return -ENOMEM; - dev_err(dai->dev, "1 %s %s", __func__, dai->name); if (!rt700->slave) return 0; @@ -1269,24 +1263,17 @@ static int rt700_pcm_hw_params(struct snd_pcm_substream *substream, dev_err(component->dev, "Invalid DAI id %d\n", dai->id); return -EINVAL; } - dev_err(dai->dev, "2 %s %s", __func__, dai->name); - stream_config.frame_rate = params_rate(params); - stream_config.ch_count = params_channels(params); - stream_config.bps = snd_pcm_format_width(params_format(params)); - stream_config.direction = direction; + stream_config = &rt700->stream_config; + stream_config->frame_rate = params_rate(params); + stream_config->ch_count = params_channels(params); + stream_config->bps = snd_pcm_format_width(params_format(params)); + stream_config->direction = direction; - dev_err(dai->dev, "3 %s %s", __func__, dai->name); num_channels = params_channels(params); - port_config.ch_mask = (1 << (num_channels)) - 1; - port_config.num = port; - - retval = sdw_stream_add_slave(rt700->slave, &stream_config, - &port_config, 1, stream->sdw_stream); - if (retval) { - dev_err(dai->dev, "Unable to configure port\n"); - return retval; - } + port_config = &rt700->port_config; + port_config->ch_mask = (1 << (num_channels)) - 1; + port_config->num = port; dev_err(dai->dev, "4 %s %s", __func__, dai->name); switch (params_rate(params)) { @@ -1339,7 +1326,33 @@ static int rt700_pcm_hw_params(struct snd_pcm_substream *substream, snd_soc_component_write(component, RT700_ADC_FORMAT_L, val); dev_err(dai->dev, "5 %s %s", __func__, dai->name); - return retval; + return 0; +} + +static int rt700_prepare_stream(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); + struct sdw_stream_data *stream; + int retval; + + stream = snd_soc_dai_get_dma_data(dai, substream); + + if (!stream) { + dev_err(dai->dev, "no dma data found in dai %s", dai->name); + return -ENOMEM; + } + + retval = sdw_stream_add_slave(rt700->slave, &rt700->stream_config, + &rt700->port_config, 1, + stream->sdw_stream); + if (retval) { + dev_err(dai->dev, "Unable to configure port\n"); + return retval; + } + + return 0; } static int rt700_pcm_hw_free(struct snd_pcm_substream *substream, @@ -1365,6 +1378,7 @@ static struct snd_soc_dai_ops rt700_ops = { .hw_params = rt700_pcm_hw_params, .hw_free = rt700_pcm_hw_free, .set_sdw_stream = rt700_set_sdw_stream, + .prepare = rt700_prepare_stream, .shutdown = rt700_shutdown, }; diff --git a/sound/soc/codecs/rt700.h b/sound/soc/codecs/rt700.h index c0771e98b3c9dd..ce00e0f1af33de 100644 --- a/sound/soc/codecs/rt700.h +++ b/sound/soc/codecs/rt700.h @@ -25,6 +25,8 @@ struct rt700_priv { int dbg_payload; enum sdw_slave_status status; struct sdw_bus_params params; + struct sdw_stream_config stream_config; + struct sdw_port_config port_config; bool hw_init; }; diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 3a6432c4ad27a6..6d7d9c93252c81 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -224,7 +224,6 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .pcm_hw_free = hda_dsp_stream_hw_free, .pcm_trigger = hda_dsp_pcm_trigger, .pcm_pointer = hda_dsp_pcm_pointer, - .pcm_prepare = sdw_pcm_prepare, /* firmware loading */ .load_firmware = snd_sof_load_firmware_raw, diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index 40e08e85b6850a..365685045ca2eb 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -128,99 +128,15 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev, return 0; } -static int sof_sdw_stream_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct hdac_stream *hstream = substream->runtime->private_data; - struct sof_intel_hda_stream *hda_stream; - struct sdw_stream_runtime *sdw_stream; - int ret; - - if (rtd->cpu_dai->id < SDW_DAI_ID_RANGE_START || - rtd->cpu_dai->id > SDW_DAI_ID_RANGE_END) - return 0; - - hda_stream = container_of(hstream, - struct sof_intel_hda_stream, - hda_stream.hstream); - - sdw_stream = hda_stream->sdw_stream; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_RESUME: - ret = sdw_enable_stream(sdw_stream); - if (ret) { - dev_err(rtd->cpu_dai->dev, - "sdw_enable_stream: failed: %d", ret); - return ret; - } - break; - - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_STOP: - ret = sdw_disable_stream(sdw_stream); - if (ret) { - dev_err(rtd->cpu_dai->dev, - "sdw_disable_stream: failed: %d", ret); - return ret; - } - break; - - default: - return -EINVAL; - } - - return 0; -} - int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, int cmd) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; struct hdac_stream *hstream = substream->runtime->private_data; struct hdac_ext_stream *stream = stream_to_hdac_ext_stream(hstream); - if (rtd->dai_link->no_pcm) - return sof_sdw_stream_trigger(substream, cmd); - return hda_dsp_stream_trigger(sdev, stream, cmd); } -int sdw_pcm_prepare(struct snd_sof_dev *sdev, - struct snd_pcm_substream *substream) -{ - //struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct hdac_stream *hstream = substream->runtime->private_data; - struct sof_intel_hda_stream *hda_stream; - struct sdw_stream_runtime *sdw_stream; - struct device *dev; - int ret = 0; - - if (rtd->cpu_dai->id >= SDW_DAI_ID_RANGE_START && - rtd->cpu_dai->id <= SDW_DAI_ID_RANGE_END) { - - hda_stream = container_of(hstream, - struct sof_intel_hda_stream, - hda_stream.hstream); - - sdw_stream = hda_stream->sdw_stream; - - if (!sdw_stream) - return -EINVAL; - - dev = rtd->cpu_dai->dev; - ret = sdw_prepare_stream(sdw_stream); - if (ret) - dev_err(dev, "sdw_prepare_stream: failed: %d", ret); - } - - return ret; -} - snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) { @@ -293,24 +209,6 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, { struct hdac_ext_stream *dsp_stream; int direction = substream->stream; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - struct hdac_stream *hstream; - struct sof_intel_hda_stream *hda_stream; - struct sdw_stream_runtime *sdw_stream = NULL; - struct snd_soc_dai_link *dai_link = rtd->dai_link; - int i, ret = 0; - char *name; - - pr_err("plb: in %s dai_link->name %s dai_link->cpus->dai_name %s no pcm %d\n", __func__, dai_link->name, dai_link->cpus->dai_name, dai_link->no_pcm); - - if (runtime->private_data) { - hstream = runtime->private_data; - if (hstream->opened) { - pr_err("bard: hstream is already used\n"); - return 0; - } - } dsp_stream = hda_dsp_stream_get(sdev, direction); @@ -321,82 +219,16 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, /* binding pcm substream to hda stream */ substream->runtime->private_data = &dsp_stream->hstream; - - /* SoundWire handling: THIS IS A HACK */ - if (rtd->cpu_dai->id >= SDW_DAI_ID_RANGE_START && - rtd->cpu_dai->id <= SDW_DAI_ID_RANGE_END) { - - pr_err("plb: in %s sdw handling cpu_dai->id %d\n", __func__, rtd->cpu_dai->id); - - hstream = substream->runtime->private_data; - hda_stream = container_of(hstream, - struct sof_intel_hda_stream, - hda_stream.hstream); - - if (hda_stream->sdw_stream) { - pr_err("bard: sdw_stream is already allocated\n"); - return 0; - } - - name = kzalloc(32, GFP_KERNEL); - if (!name) - return -ENOMEM; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - snprintf(name, 32, "%s-Playback", rtd->cpu_dai->name); - else - snprintf(name, 32, "%s-Capture", rtd->cpu_dai->name); - - sdw_stream = sdw_alloc_stream(name); - if (!sdw_stream) { - dev_err(rtd->cpu_dai->dev, - "alloc stream failed for DAI %s: %d", - rtd->cpu_dai->name, ret); - ret = -ENOMEM; - goto error; - } - - /* Set stream pointer on CPU DAI */ - snd_soc_dai_set_sdw_stream(rtd->cpu_dai, - sdw_stream, - substream->stream); - - /* Set stream pointer on all CODEC DAIs */ - for (i = 0; i < rtd->num_codecs; i++) - snd_soc_dai_set_sdw_stream(rtd->codec_dais[i], - sdw_stream, - substream->stream); - - hda_stream->sdw_stream = sdw_stream; - } - return 0; - -error: - kfree(name); - sdw_release_stream(sdw_stream); - return ret; } int hda_dsp_pcm_close(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) { - struct hdac_stream *hstream = NULL; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - struct sof_intel_hda_stream *hda_stream; - struct sdw_stream_runtime *sdw_stream = NULL; + struct hdac_stream *hstream = substream->runtime->private_data; int direction = substream->stream; int ret; - hstream = runtime->private_data; - - if (rtd->dai_link->no_pcm) - goto be; - - if (!hstream->opened) - goto free; - ret = hda_dsp_stream_put(sdev, direction, hstream->stream_tag); if (ret) { @@ -404,23 +236,6 @@ int hda_dsp_pcm_close(struct snd_sof_dev *sdev, return -ENODEV; } - goto free; - -be: - hda_stream = container_of(hstream, - struct sof_intel_hda_stream, - hda_stream.hstream); - sdw_stream = hda_stream->sdw_stream; - if (!sdw_stream) - return -EINVAL; - - sdw_release_stream(sdw_stream); - hda_stream->sdw_stream = NULL; - -free: - /* unbinding pcm substream to hda stream */ - if (!hstream->opened && !hda_stream->sdw_stream) - substream->runtime->private_data = NULL; - return 0; } + diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 191a8f64531f81..4c8d19527f9038 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -488,59 +488,19 @@ int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev, { struct hdac_stream *stream = substream->runtime->private_data; struct hdac_ext_stream *link_dev = container_of(stream, - struct hdac_ext_stream, - hstream); - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct hdac_stream *hstream = substream->runtime->private_data; - struct sof_intel_hda_stream *hda_stream; - struct sdw_stream_runtime *sdw_stream; + struct hdac_ext_stream, + hstream); struct hdac_bus *bus = sof_to_bus(sdev); u32 mask = 0x1 << stream->index; - int ret; - struct sof_ipc_dai_config config; - struct sof_ipc_reply reply; - u32 size = sizeof(config); - - if (rtd->dai_link->no_pcm) - goto be; spin_lock_irq(&bus->reg_lock); /* couple host and link DMA if link DMA channel is idle */ if (!link_dev->link_locked) snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, - SOF_HDA_REG_PP_PPCTL, mask, 0); + SOF_HDA_REG_PP_PPCTL, mask, 0); spin_unlock_irq(&bus->reg_lock); return 0; -be: - - hda_stream = container_of(hstream, - struct sof_intel_hda_stream, - hda_stream.hstream); - sdw_stream = hda_stream->sdw_stream; - if (!sdw_stream) - return -EINVAL; - - ret = sdw_deprepare_stream(sdw_stream); - if (ret) - dev_err(sdev->dev, "sdw_deprepare_stream: failed %d", ret); - - memset(&config, 0, size); - config.hdr.size = size; - config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG; - config.type = SOF_DAI_INTEL_ALH; - config.dai_index = 0; /* FIXME: make this dynamic */ - config.alh.stream_id = 0xFFFFFFFF; - - /* send message to DSP */ - ret = sof_ipc_tx_message(sdev->ipc, - config.hdr.cmd, &config, size, &reply, - sizeof(reply)); - if (ret < 0) { - dev_err(sdev->dev, "error: failed to set DAI hw_free for ALH %d\n", - config.dai_index); - } - return ret; } irqreturn_t hda_dsp_stream_interrupt(int irq, void *context) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 5a85d86654671c..6684bbb5d25957 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -81,8 +81,36 @@ static int sdw_config_stream(void *arg, void *s, void *dai, return ret; } +static int sdw_free_stream(void *arg, void *s, void *dai) +{ + struct snd_sof_dev *sdev = arg; + struct sof_ipc_dai_config config; + struct sof_ipc_reply reply; + int size = sizeof(config); + int ret; + + memset(&config, 0, size); + config.hdr.size = size; + config.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_CONFIG; + config.type = SOF_DAI_INTEL_ALH; + config.dai_index = 0; /* FIXME: make this dynamic */ + config.alh.stream_id = 0xFFFFFFFF; + + /* send message to DSP */ + ret = sof_ipc_tx_message(sdev->ipc, + config.hdr.cmd, &config, size, &reply, + sizeof(reply)); + if (ret < 0) { + dev_err(sdev->dev, "error: failed to set DAI hw_free for ALH %d\n", + config.dai_index); + } + + return ret; +} + static const struct sdw_intel_ops sdw_callback = { .config_stream = sdw_config_stream, + .free_stream = sdw_free_stream, }; static int hda_sdw_init(struct snd_sof_dev *sdev) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index badbee6723d515..b698edbfc1cc4f 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -248,7 +248,7 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream) /* skip front-end specific inits for BE */ if (rtd->dai_link->no_pcm) - goto platform_hw_free; + return 0; spcm = snd_sof_find_spcm_dai(sdev, rtd); if (!spcm) @@ -269,7 +269,6 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream) if (ret < 0) return ret; -platform_hw_free: ret = snd_sof_pcm_platform_hw_free(sdev, substream); if (ret < 0) dev_err(sdev->dev, "error: platform hw free failed\n"); @@ -287,10 +286,8 @@ static int sof_pcm_prepare(struct snd_pcm_substream *substream) int ret; /* skip front-end specific inits for BE */ - if (rtd->dai_link->no_pcm) { - snd_sof_pcm_platform_prepare(sdev, substream); + if (rtd->dai_link->no_pcm) return 0; - } spcm = snd_sof_find_spcm_dai(sdev, rtd); if (!spcm) @@ -329,10 +326,8 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd) int ret; /* skip front-end specific inits for BE */ - if (rtd->dai_link->no_pcm) { - snd_sof_pcm_platform_trigger(sdev, substream, cmd); + if (rtd->dai_link->no_pcm) return 0; - } spcm = snd_sof_find_spcm_dai(sdev, rtd); if (!spcm) @@ -433,7 +428,7 @@ static int sof_pcm_open(struct snd_pcm_substream *substream) /* skip front-end specific inits for BE */ if (rtd->dai_link->no_pcm) - goto platform_open; + return 0; spcm = snd_sof_find_spcm_dai(sdev, rtd); if (!spcm) @@ -490,7 +485,6 @@ static int sof_pcm_open(struct snd_pcm_substream *substream) spcm->stream[substream->stream].substream = substream; spcm->prepared[substream->stream] = false; -platform_open: ret = snd_sof_pcm_platform_open(sdev, substream); if (ret < 0) dev_err(sdev->dev, "error: pcm open failed %d\n", ret); @@ -509,7 +503,7 @@ static int sof_pcm_close(struct snd_pcm_substream *substream) /* skip front-end specific inits for BE */ if (rtd->dai_link->no_pcm) - goto platform_close; + return 0; spcm = snd_sof_find_spcm_dai(sdev, rtd); if (!spcm) @@ -518,7 +512,6 @@ static int sof_pcm_close(struct snd_pcm_substream *substream) dev_dbg(sdev->dev, "pcm: close stream %d dir %d\n", spcm->pcm.pcm_id, substream->stream); -platform_close: err = snd_sof_pcm_platform_close(sdev, substream); if (err < 0) { dev_err(sdev->dev, "error: pcm close failed %d\n",