*参照元 [#kfe995a3] #backlinks *説明 [#ub9f0e43] -パス: [[linux-4.4.1/include/sound/pcm.h]] -FIXME: これは何? --PCM substream の情報 -card, pcm, substream の関係については、ALSA のページ参照。 --[[linux-4.4/ALSA]] ** 参考: private_data について [#t3e87be1] struct snd_pcm_ops にて与える PCM デバイス操作に使う関数群は、 引数として struct snd_pcm_substream * を受け取るものがほとんど。 この構造体から、ドライバ独自のデータを取り出す方法を調べた。 -[[linux-4.4.1/snd_pcm_ops]] -取得は snd_pcm_substream_chip() で行う。 --こんな感じ。 static int sample_pcm_open(struct snd_pcm_substream *substream) { struct sample_driver_data *d = snd_pcm_substream_chip(substream); ... } static const struct snd_pcm_ops sample_pcm_ops = { .open = sample_pcm_open, ... }; --もし ALSA SoC Layer を使っている場合は、snd_pcm はドライバに見えず、 ドライバ独自のデータは入れられない(snd_pcm の解説も参照のこと)。 代わりに snd_soc_pcm_runtime が入っているようだ。 static int sample_pcm_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); ... } --取得関数は void * を返すだけなので、間違った構造体のポインタにキャストすると、 一発で Kernel が死ぬ。辛い。 -設定は snd_pcm_attach_substream() と思われる。 --親となる snd_pcm の private_data がそのまま使われるようなので、 snd_pcm の private_data を設定しておけば良いわけですね。 -リンク --[[linux-4.4.1/snd_pcm_substream_chip()]] --[[linux-4.4.1/snd_soc_pcm_runtime]] --[[linux-4.4.1/snd_pcm]] --[[linux-4.4.1/snd_pcm_attach_substream()]] *実装 [#v661f421] struct snd_pcm_substream { struct snd_pcm *pcm; struct snd_pcm_str *pstr; void *private_data; /* copied from pcm->private_data */ - --[[linux-4.4.1/snd_pcm]] --[[linux-4.4.1/snd_pcm_str]] int number; char name[32]; /* substream name */ int stream; /* stream (direction) */ -SNDRV_PCM_STREAM_PLAYBACK か SNDRV_PCM_STREAM_CAPTURE を取る。 --[[linux-4.4.1/SNDRV_PCM_STREAM_PLAYBACK]] --[[linux-4.4.1/SNDRV_PCM_STREAM_CAPTURE]] --定義は [[linux-4.4.1/include/uapi/sound/asound.h]] にある。 struct pm_qos_request latency_pm_qos_req; /* pm_qos request */ - --[[linux-4.4.1/pm_qos_request]] size_t buffer_bytes_max; /* limit ring buffer size */ struct snd_dma_buffer dma_buffer; size_t dma_max; - --[[linux-4.4.1/snd_dma_buffer]] /* -- hardware operations -- */ const struct snd_pcm_ops *ops; - --[[linux-4.4.1/snd_pcm_ops]] /* -- runtime information -- */ struct snd_pcm_runtime *runtime; - --[[linux-4.4.1/snd_pcm_runtime]] /* -- timer section -- */ struct snd_timer *timer; /* timer */ unsigned timer_running: 1; /* time is running */ - --[[linux-4.4.1/snd_timer]] /* -- next substream -- */ struct snd_pcm_substream *next; - --[[linux-4.4.1/snd_pcm_substream]] /* -- linked substreams -- */ struct list_head link_list; /* linked list member */ struct snd_pcm_group self_group; /* fake group for non linked substream (with substream lock inside) */ struct snd_pcm_group *group; /* pointer to current group */ - --[[linux-4.4.1/list_head]] --[[linux-4.4.1/snd_pcm_group]] /* -- assigned files -- */ void *file; int ref_count; atomic_t mmap_count; unsigned int f_flags; void (*pcm_release)(struct snd_pcm_substream *); struct pid *pid; - --[[linux-4.4.1/atomic_t]] --[[linux-4.4.1/pid]] #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) - --[[linux-4.4.1/CONFIG_SND_PCM_OSS]] --[[linux-4.4.1/CONFIG_SND_PCM_OSS_MODULE]] /* -- OSS things -- */ struct snd_pcm_oss_substream oss; - --[[linux-4.4.1/snd_pcm_oss_substream]] #endif #ifdef CONFIG_SND_VERBOSE_PROCFS - --[[linux-4.4.1/CONFIG_SND_VERBOSE_PROCFS]] struct snd_info_entry *proc_root; struct snd_info_entry *proc_info_entry; struct snd_info_entry *proc_hw_params_entry; struct snd_info_entry *proc_sw_params_entry; struct snd_info_entry *proc_status_entry; struct snd_info_entry *proc_prealloc_entry; struct snd_info_entry *proc_prealloc_max_entry; - --[[linux-4.4.1/snd_info_entry]] #ifdef CONFIG_SND_PCM_XRUN_DEBUG - --[[linux-4.4.1/CONFIG_SND_PCM_XRUN_DEBUG]] struct snd_info_entry *proc_xrun_injection_entry; #endif #endif /* CONFIG_SND_VERBOSE_PROCFS */ /* misc flags */ unsigned int hw_opened: 1; }; *コメント [#v7119b80]