1de3a9980SAnton Yakovlev /* SPDX-License-Identifier: GPL-2.0+ */ 2de3a9980SAnton Yakovlev /* 3de3a9980SAnton Yakovlev * virtio-snd: Virtio sound device 4de3a9980SAnton Yakovlev * Copyright (C) 2021 OpenSynergy GmbH 5de3a9980SAnton Yakovlev */ 6de3a9980SAnton Yakovlev #ifndef VIRTIO_SND_CARD_H 7de3a9980SAnton Yakovlev #define VIRTIO_SND_CARD_H 8de3a9980SAnton Yakovlev 9de3a9980SAnton Yakovlev #include <linux/slab.h> 10de3a9980SAnton Yakovlev #include <linux/virtio.h> 11de3a9980SAnton Yakovlev #include <sound/core.h> 12de3a9980SAnton Yakovlev #include <uapi/linux/virtio_snd.h> 13de3a9980SAnton Yakovlev 149d45e514SAnton Yakovlev #include "virtio_ctl_msg.h" 1529b96bf5SAnton Yakovlev #include "virtio_pcm.h" 169d45e514SAnton Yakovlev 17de3a9980SAnton Yakovlev #define VIRTIO_SND_CARD_DRIVER "virtio-snd" 18de3a9980SAnton Yakovlev #define VIRTIO_SND_CARD_NAME "VirtIO SoundCard" 1929b96bf5SAnton Yakovlev #define VIRTIO_SND_PCM_NAME "VirtIO PCM" 2029b96bf5SAnton Yakovlev 21ca61a41fSAnton Yakovlev struct virtio_jack; 2229b96bf5SAnton Yakovlev struct virtio_pcm_substream; 23de3a9980SAnton Yakovlev 24de3a9980SAnton Yakovlev /** 25de3a9980SAnton Yakovlev * struct virtio_snd_queue - Virtqueue wrapper structure. 26de3a9980SAnton Yakovlev * @lock: Used to synchronize access to a virtqueue. 27de3a9980SAnton Yakovlev * @vqueue: Underlying virtqueue. 28de3a9980SAnton Yakovlev */ 29de3a9980SAnton Yakovlev struct virtio_snd_queue { 30de3a9980SAnton Yakovlev spinlock_t lock; 31de3a9980SAnton Yakovlev struct virtqueue *vqueue; 32de3a9980SAnton Yakovlev }; 33de3a9980SAnton Yakovlev 34de3a9980SAnton Yakovlev /** 35de3a9980SAnton Yakovlev * struct virtio_snd - VirtIO sound card device. 36de3a9980SAnton Yakovlev * @vdev: Underlying virtio device. 37de3a9980SAnton Yakovlev * @queues: Virtqueue wrappers. 38de3a9980SAnton Yakovlev * @card: ALSA sound card. 399d45e514SAnton Yakovlev * @ctl_msgs: Pending control request list. 40de3a9980SAnton Yakovlev * @event_msgs: Device events. 4129b96bf5SAnton Yakovlev * @pcm_list: VirtIO PCM device list. 42ca61a41fSAnton Yakovlev * @jacks: VirtIO jacks. 43ca61a41fSAnton Yakovlev * @njacks: Number of jacks. 4429b96bf5SAnton Yakovlev * @substreams: VirtIO PCM substreams. 4529b96bf5SAnton Yakovlev * @nsubstreams: Number of PCM substreams. 46*19325fedSAnton Yakovlev * @chmaps: VirtIO channel maps. 47*19325fedSAnton Yakovlev * @nchmaps: Number of channel maps. 48de3a9980SAnton Yakovlev */ 49de3a9980SAnton Yakovlev struct virtio_snd { 50de3a9980SAnton Yakovlev struct virtio_device *vdev; 51de3a9980SAnton Yakovlev struct virtio_snd_queue queues[VIRTIO_SND_VQ_MAX]; 52de3a9980SAnton Yakovlev struct snd_card *card; 539d45e514SAnton Yakovlev struct list_head ctl_msgs; 54de3a9980SAnton Yakovlev struct virtio_snd_event *event_msgs; 5529b96bf5SAnton Yakovlev struct list_head pcm_list; 56ca61a41fSAnton Yakovlev struct virtio_jack *jacks; 57ca61a41fSAnton Yakovlev u32 njacks; 5829b96bf5SAnton Yakovlev struct virtio_pcm_substream *substreams; 5929b96bf5SAnton Yakovlev u32 nsubstreams; 60*19325fedSAnton Yakovlev struct virtio_snd_chmap_info *chmaps; 61*19325fedSAnton Yakovlev u32 nchmaps; 62de3a9980SAnton Yakovlev }; 63de3a9980SAnton Yakovlev 649d45e514SAnton Yakovlev /* Message completion timeout in milliseconds (module parameter). */ 659d45e514SAnton Yakovlev extern u32 virtsnd_msg_timeout_ms; 669d45e514SAnton Yakovlev 67de3a9980SAnton Yakovlev static inline struct virtio_snd_queue * virtsnd_control_queue(struct virtio_snd * snd)68de3a9980SAnton Yakovlevvirtsnd_control_queue(struct virtio_snd *snd) 69de3a9980SAnton Yakovlev { 70de3a9980SAnton Yakovlev return &snd->queues[VIRTIO_SND_VQ_CONTROL]; 71de3a9980SAnton Yakovlev } 72de3a9980SAnton Yakovlev 73de3a9980SAnton Yakovlev static inline struct virtio_snd_queue * virtsnd_event_queue(struct virtio_snd * snd)74de3a9980SAnton Yakovlevvirtsnd_event_queue(struct virtio_snd *snd) 75de3a9980SAnton Yakovlev { 76de3a9980SAnton Yakovlev return &snd->queues[VIRTIO_SND_VQ_EVENT]; 77de3a9980SAnton Yakovlev } 78de3a9980SAnton Yakovlev 79de3a9980SAnton Yakovlev static inline struct virtio_snd_queue * virtsnd_tx_queue(struct virtio_snd * snd)80de3a9980SAnton Yakovlevvirtsnd_tx_queue(struct virtio_snd *snd) 81de3a9980SAnton Yakovlev { 82de3a9980SAnton Yakovlev return &snd->queues[VIRTIO_SND_VQ_TX]; 83de3a9980SAnton Yakovlev } 84de3a9980SAnton Yakovlev 85de3a9980SAnton Yakovlev static inline struct virtio_snd_queue * virtsnd_rx_queue(struct virtio_snd * snd)86de3a9980SAnton Yakovlevvirtsnd_rx_queue(struct virtio_snd *snd) 87de3a9980SAnton Yakovlev { 88de3a9980SAnton Yakovlev return &snd->queues[VIRTIO_SND_VQ_RX]; 89de3a9980SAnton Yakovlev } 90de3a9980SAnton Yakovlev 91f40a2867SAnton Yakovlev static inline struct virtio_snd_queue * virtsnd_pcm_queue(struct virtio_pcm_substream * vss)92f40a2867SAnton Yakovlevvirtsnd_pcm_queue(struct virtio_pcm_substream *vss) 93f40a2867SAnton Yakovlev { 94f40a2867SAnton Yakovlev if (vss->direction == SNDRV_PCM_STREAM_PLAYBACK) 95f40a2867SAnton Yakovlev return virtsnd_tx_queue(vss->snd); 96f40a2867SAnton Yakovlev else 97f40a2867SAnton Yakovlev return virtsnd_rx_queue(vss->snd); 98f40a2867SAnton Yakovlev } 99f40a2867SAnton Yakovlev 100ca61a41fSAnton Yakovlev int virtsnd_jack_parse_cfg(struct virtio_snd *snd); 101ca61a41fSAnton Yakovlev 102ca61a41fSAnton Yakovlev int virtsnd_jack_build_devs(struct virtio_snd *snd); 103ca61a41fSAnton Yakovlev 104ca61a41fSAnton Yakovlev void virtsnd_jack_event(struct virtio_snd *snd, 105ca61a41fSAnton Yakovlev struct virtio_snd_event *event); 106ca61a41fSAnton Yakovlev 107*19325fedSAnton Yakovlev int virtsnd_chmap_parse_cfg(struct virtio_snd *snd); 108*19325fedSAnton Yakovlev 109*19325fedSAnton Yakovlev int virtsnd_chmap_build_devs(struct virtio_snd *snd); 110*19325fedSAnton Yakovlev 111de3a9980SAnton Yakovlev #endif /* VIRTIO_SND_CARD_H */ 112