flush_delayed_work(&rtd->delayed_work);
}
-static void codec2codec_close_delayed_work(struct work_struct *work)
-{
- /*
- * Currently nothing to do for c2c links
- * Since c2c links are internal nodes in the DAPM graph and
- * don't interface with the outside world or application layer
- * we don't have to do any special handling on close.
- */
-}
-
#ifdef CONFIG_PM_SLEEP
/* powers down audio subsystem for suspend */
int snd_soc_suspend(struct device *dev)
return ret;
}
- if (!dai_link->params) {
- /* create the pcm */
- ret = soc_new_pcm(rtd, num);
- if (ret < 0) {
- dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
- dai_link->stream_name, ret);
- return ret;
- }
- ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
- if (ret < 0)
- return ret;
- ret = soc_link_dai_pcm_new(rtd->codec_dais,
- rtd->num_codecs, rtd);
- if (ret < 0)
- return ret;
- } else {
- INIT_DELAYED_WORK(&rtd->delayed_work,
- codec2codec_close_delayed_work);
+ /* create the pcm */
+ ret = soc_new_pcm(rtd, num);
+ if (ret < 0) {
+ dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
+ dai_link->stream_name, ret);
+ return ret;
}
-
- return 0;
+ ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
+ if (ret < 0)
+ return ret;
+ ret = soc_link_dai_pcm_new(rtd->codec_dais,
+ rtd->num_codecs, rtd);
+ return ret;
}
static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
mutex_unlock(&rtd->pcm_mutex);
}
+static void codec2codec_close_delayed_work(struct work_struct *work)
+{
+ /*
+ * Currently nothing to do for c2c links
+ * Since c2c links are internal nodes in the DAPM graph and
+ * don't interface with the outside world or application layer
+ * we don't have to do any special handling on close.
+ */
+}
+
/*
* Called by ALSA when a PCM substream is closed. Private data can be
* freed here. The cpu DAI, codec DAI, machine and components are also
playback = rtd->dai_link->dpcm_playback;
capture = rtd->dai_link->dpcm_capture;
} else {
+ /* Adapt stream for codec2codec links */
+ struct snd_soc_pcm_stream *cpu_capture = rtd->dai_link->params ?
+ &cpu_dai->driver->playback : &cpu_dai->driver->capture;
+ struct snd_soc_pcm_stream *cpu_playback = rtd->dai_link->params ?
+ &cpu_dai->driver->capture : &cpu_dai->driver->playback;
+
for_each_rtd_codec_dai(rtd, i, codec_dai) {
if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
capture = 1;
}
+
+ capture = capture && cpu_capture->channels_min;
+ playback = playback && cpu_playback->channels_min;
}
if (rtd->dai_link->playback_only) {
}
/* create the PCM */
- if (rtd->dai_link->no_pcm) {
+ if (rtd->dai_link->params) {
+ snprintf(new_name, sizeof(new_name), "codec2codec(%s)",
+ rtd->dai_link->stream_name);
+
+ ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
+ playback, capture, &pcm);
+ } else if (rtd->dai_link->no_pcm) {
snprintf(new_name, sizeof(new_name), "(%s)",
rtd->dai_link->stream_name);
dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name);
/* DAPM dai link stream work */
- INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
+ if (rtd->dai_link->params)
+ INIT_DELAYED_WORK(&rtd->delayed_work,
+ codec2codec_close_delayed_work);
+ else
+ INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
pcm->nonatomic = rtd->dai_link->nonatomic;
rtd->pcm = pcm;
pcm->private_data = rtd;
- if (rtd->dai_link->no_pcm) {
+ if (rtd->dai_link->no_pcm || rtd->dai_link->params) {
if (playback)
pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
if (capture)