*参照元 [#t742c843] #backlinks *説明 [#a91463a3] -パス: [[linux-4.4.1/sound/soc/soc-pcm.c]] -FIXME: これは何? --説明 **引数 [#u121d27c] -struct snd_soc_pcm_runtime *rtd -- --[[linux-4.4.1/snd_soc_pcm_runtime]] -int num -- **返り値 [#c40a7465] -int -- **参考 [#l12ecab6] *実装 [#s740e0bf] /* create a new pcm */ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) { struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_pcm *pcm; char new_name[64]; int ret = 0, playback = 0, capture = 0; int i; - --[[linux-4.4.1/snd_soc_platform]] --[[linux-4.4.1/snd_soc_dai]] --[[linux-4.4.1/snd_pcm]] if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { - --rtd->dai_link は struct snd_soc_dai_link * 型 --[[linux-4.4.1/snd_soc_dai_link]] playback = rtd->dai_link->dpcm_playback; capture = rtd->dai_link->dpcm_capture; } else { for (i = 0; i < rtd->num_codecs; i++) { codec_dai = rtd->codec_dais[i]; if (codec_dai->driver->playback.channels_min) playback = 1; if (codec_dai->driver->capture.channels_min) capture = 1; } - --rtd->codec_dais[i]->driver は struct snd_soc_dai_driver * 型 --rtd->codec_dais[i]->driver->playback は struct snd_soc_pcm_stream 型 --[[linux-4.4.1/snd_soc_dai_driver]] --[[linux-4.4.1/snd_soc_pcm_stream]] capture = capture && cpu_dai->driver->capture.channels_min; playback = playback && cpu_dai->driver->playback.channels_min; } if (rtd->dai_link->playback_only) { playback = 1; capture = 0; } if (rtd->dai_link->capture_only) { playback = 0; capture = 1; } /* create the PCM */ if (rtd->dai_link->no_pcm) { snprintf(new_name, sizeof(new_name), "(%s)", rtd->dai_link->stream_name); ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, playback, capture, &pcm); - --rtd->card は struct snd_soc_card * 型 --[[linux-4.4.1/snd_soc_card]] --[[linux-4.4.1/snprintf()]] --[[linux-4.4.1/snd_pcm_new_internal()]] } else { if (rtd->dai_link->dynamic) snprintf(new_name, sizeof(new_name), "%s (*)", rtd->dai_link->stream_name); else snprintf(new_name, sizeof(new_name), "%s %s-%d", rtd->dai_link->stream_name, (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name, num); ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback, capture, &pcm); - --rtd->card は struct snd_soc_card * 型 --[[linux-4.4.1/snd_soc_card]] --[[linux-4.4.1/snd_pcm_new()]] } if (ret < 0) { dev_err(rtd->card->dev, "ASoC: can't create pcm for %s\n", rtd->dai_link->name); return ret; } dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name); - --[[linux-4.4.1/dev_err()]] --[[linux-4.4.1/dev_dbg()]] /* DAPM dai link stream work */ INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); - --[[linux-4.4.1/INIT_DELAYED_WORK()]] --[[linux-4.4.1/close_delayed_work()]] pcm->nonatomic = rtd->dai_link->nonatomic; rtd->pcm = pcm; pcm->private_data = rtd; if (rtd->dai_link->no_pcm) { if (playback) pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; if (capture) pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; goto out; } - --rtd->ops は struct snd_pcm_ops 型 --[[linux-4.4.1/snd_pcm_ops]] /* ASoC PCM operations */ if (rtd->dai_link->dynamic) { rtd->ops.open = dpcm_fe_dai_open; rtd->ops.hw_params = dpcm_fe_dai_hw_params; rtd->ops.prepare = dpcm_fe_dai_prepare; rtd->ops.trigger = dpcm_fe_dai_trigger; rtd->ops.hw_free = dpcm_fe_dai_hw_free; rtd->ops.close = dpcm_fe_dai_close; rtd->ops.pointer = soc_pcm_pointer; rtd->ops.ioctl = soc_pcm_ioctl; - --[[linux-4.4.1/dpcm_fe_dai_open()]] --[[linux-4.4.1/dpcm_fe_dai_hw_params()]] --[[linux-4.4.1/dpcm_fe_dai_prepare()]] --[[linux-4.4.1/dpcm_fe_dai_trigger()]] --[[linux-4.4.1/dpcm_fe_dai_hw_free()]] --[[linux-4.4.1/dpcm_fe_dai_close()]] --[[linux-4.4.1/soc_pcm_pointer()]] --[[linux-4.4.1/soc_pcm_ioctl()]] } else { rtd->ops.open = soc_pcm_open; rtd->ops.hw_params = soc_pcm_hw_params; rtd->ops.prepare = soc_pcm_prepare; rtd->ops.trigger = soc_pcm_trigger; rtd->ops.hw_free = soc_pcm_hw_free; rtd->ops.close = soc_pcm_close; rtd->ops.pointer = soc_pcm_pointer; rtd->ops.ioctl = soc_pcm_ioctl; - --[[linux-4.4.1/soc_pcm_open()]] --[[linux-4.4.1/soc_pcm_hw_params()]] --[[linux-4.4.1/soc_pcm_prepare()]] --[[linux-4.4.1/soc_pcm_trigger()]] --[[linux-4.4.1/soc_pcm_hw_free()]] --[[linux-4.4.1/soc_pcm_close()]] --[[linux-4.4.1/soc_pcm_pointer()]] --[[linux-4.4.1/soc_pcm_ioctl()]] } if (platform->driver->ops) { rtd->ops.ack = platform->driver->ops->ack; rtd->ops.copy = platform->driver->ops->copy; rtd->ops.silence = platform->driver->ops->silence; rtd->ops.page = platform->driver->ops->page; rtd->ops.mmap = platform->driver->ops->mmap; } - --platform->driver は const struct snd_soc_platform_driver * 型 --platform->driver->ops は const struct snd_pcm_ops * 型 --[[linux-4.4.1/snd_soc_platform_driver]] --[[linux-4.4.1/snd_pcm_ops]] if (playback) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops); if (capture) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops); - --[[linux-4.4.1/snd_pcm_set_ops()]] if (platform->driver->pcm_new) { ret = platform->driver->pcm_new(rtd); if (ret < 0) { dev_err(platform->dev, "ASoC: pcm constructor failed: %d\n", ret); return ret; } } pcm->private_free = platform->driver->pcm_free; out: dev_info(rtd->card->dev, "%s <-> %s mapping ok\n", (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name, cpu_dai->name); - --rtd->codec_dai は struct snd_soc_dai * 型 --[[linux-4.4.1/snd_soc_dai]] --[[linux-4.4.1/dev_info()]] return ret; } *コメント [#r3067906]