static int skl_link_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); struct hdac_ext_stream *link_dev; struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); struct hdac_ext_dma_params *dma_params; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct skl_pipe_params p_params = {0}; link_dev = snd_hdac_ext_stream_assign(ebus, substream, HDAC_EXT_STREAM_TYPE_LINK); if (!link_dev) return -EBUSY; snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); /* set the stream tag in the codec dai dma params */ dma_params = snd_soc_dai_get_dma_data(codec_dai, substream); if (dma_params) dma_params->stream_tag = hdac_stream(link_dev)->stream_tag; p_params.s_fmt = snd_pcm_format_width(params_format(params)); p_params.ch = params_channels(params); p_params.s_freq = params_rate(params); p_params.stream = substream->stream; p_params.link_dma_id = hdac_stream(link_dev)->stream_tag - 1; return skl_tplg_be_update_params(dai, &p_params); }
static int skl_dsp_prepare(struct device *dev, unsigned int format, unsigned int size, struct snd_dma_buffer *dmab) { struct hdac_bus *bus = dev_get_drvdata(dev); struct hdac_ext_stream *estream; struct hdac_stream *stream; struct snd_pcm_substream substream; int ret; if (!bus) return -ENODEV; memset(&substream, 0, sizeof(substream)); substream.stream = SNDRV_PCM_STREAM_PLAYBACK; estream = snd_hdac_ext_stream_assign(bus, &substream, HDAC_EXT_STREAM_TYPE_HOST); if (!estream) return -ENODEV; stream = hdac_stream(estream); /* assign decouple host dma channel */ ret = snd_hdac_dsp_prepare(stream, format, size, dmab); if (ret < 0) return ret; skl_dsp_setup_spib(dev, size, stream->stream_tag, true); return stream->stream_tag; }
static int skl_pcm_open(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev); struct hdac_ext_stream *stream; struct snd_pcm_runtime *runtime = substream->runtime; struct skl_dma_params *dma_params; dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); stream = snd_hdac_ext_stream_assign(ebus, substream, skl_get_host_stream_type(ebus)); if (stream == NULL) return -EBUSY; skl_set_pcm_constrains(ebus, runtime); /* * disable WALLCLOCK timestamps for capture streams * until we figure out how to handle digital inputs */ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */ runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME; } runtime->private_data = stream; dma_params = kzalloc(sizeof(*dma_params), GFP_KERNEL); if (!dma_params) return -ENOMEM; dma_params->stream_tag = hdac_stream(stream)->stream_tag; snd_soc_dai_set_dma_data(dai, substream, dma_params); dev_dbg(dai->dev, "stream tag set in dma params=%d\n", dma_params->stream_tag); skl_set_suspend_active(substream, dai, true); snd_pcm_set_sync(substream); return 0; }