FIXME: なにをするもの?
card0 -+- PCM0 -+- substream0 | | | +- substream1 | +- PCM1 --- substream0 | ... card1 --- PCM0 --- substream0 ...
ALSA のコールバック API に渡ってくる構造体から、 ドライバの独自データを獲る方法について。
ALSA SoC Layer を使う場合とそうでない場合が大きく違っていて、 難しすぎだろこれ…。
ALSA SoC Layer を使わない場合
snd_pcm_substream --(snd_pcm_substream_chip)--> ドライバ独自データ
ALSA SoC Layer を使っていて、CPU/CODEC DAI の場合
snd_pcm_substream --(snd_pcm_substream_chip)--> snd_soc_pcm_runtime --(cpu_dai メンバ/codec_dai メンバ)--> ※SoC のドライバなら cpu_dai で、 CODEC のドライバなら codec_dai を使うはず snd_soc_dai --(snd_soc_dai_get_drvdata)--> ドライバ独自データ
ALSA SoC Layer を使っていて、Card の場合
platform_device --(platform_get_drvdata)--> snd_soc_card --(snd_soc_card_get_drvdata)--> ドライバ独自データ
必要そうなものメモ。
包含関係
- snd_soc_platform_driver - snd_pcm_ops
包含関係
- snd_soc_component_driver - snd_soc_dai_driver - snd_soc_dai_ops - snd_soc_pcm_stream
包含関係
- snd_soc_card - snd_soc_dai_link - snd_soc_dpcm_trigger - snd_soc_ops - snd_soc_compr_ops - snd_soc_codec_conf - snd_soc_kcontrol_new - snd_soc_dapm_widget - snd_soc_dapm_route
platform_bus を使う場合、
struct hoge_device { struct snd_soc_card card; }; static int hoge_probe(struct platform_device *pdev) { struct hoge_device *d; struct device *dev = &pdev->dev; ... d = devm_kzalloc(dev, sizeof(struct hoge_device)); ... snd_soc_register_platform(dev, &hoge_snd_soc_platform_driver); ... snd_soc_register_component(dev, &hoge_snd_soc_component_driver, hoge_snd_soc_dai_drivers, ARRAY_SIZE(hoge_snd_soc_dai_drivers)); ... //FIXME: 他の手立てがありそう d->card.dev = dev; snd_soc_card_set_drvdata(&d->card, d); snd_soc_register_card(&d->card); ... return 0; }
static int hoge_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct hoge_device *d = snd_soc_card_get_drvdata(card); struct device *dev = &pdev->dev; ... snd_soc_unregister_card(&d->card); ... snd_soc_unregister_component(dev); ... snd_soc_unregister_platform(dev); ... return 0; } static struct platform_driver hoge_driver = { .driver = { .name = "hoge", }, .probe = hoge_probe, .remove = hoge_remove, }; module_platform_driver(hoge_driver);