/* SPDX-License-Identifier: GPL-2.0+ */ /* * virtio-snd: Virtio sound device * Copyright (C) 2021 OpenSynergy GmbH */ #ifndef VIRTIO_SND_PCM_H #define VIRTIO_SND_PCM_H #include <linux/atomic.h> #include <linux/virtio_config.h> #include <sound/pcm.h> struct virtio_pcm; struct virtio_pcm_msg; /** * struct virtio_pcm_substream - VirtIO PCM substream. * @snd: VirtIO sound device. * @nid: Function group node identifier. * @sid: Stream identifier. * @direction: Stream data flow direction (SNDRV_PCM_STREAM_XXX). * @features: Stream VirtIO feature bit map (1 << VIRTIO_SND_PCM_F_XXX). * @substream: Kernel ALSA substream. * @hw: Kernel ALSA substream hardware descriptor. * @elapsed_period: Kernel work to handle the elapsed period state. * @lock: Spinlock that protects fields shared by interrupt handlers and * substream operators. * @buffer_bytes: Current buffer size in bytes. * @hw_ptr: Substream hardware pointer value in bytes [0 ... buffer_bytes). * @xfer_enabled: Data transfer state (0 - off, 1 - on). * @xfer_xrun: Data underflow/overflow state (0 - no xrun, 1 - xrun). * @stopped: True if the substream is stopped and must be released on the device * side. * @suspended: True if the substream is suspended and must be reconfigured on * the device side at resume. * @msgs: Allocated I/O messages. * @nmsgs: Number of allocated I/O messages. * @msg_last_enqueued: Index of the last I/O message added to the virtqueue. * @msg_count: Number of pending I/O messages in the virtqueue. * @msg_empty: Notify when msg_count is zero. */ struct virtio_pcm_substream { struct virtio_snd *snd; u32 nid; u32 sid; u32 direction; u32 features; struct snd_pcm_substream *substream; struct snd_pcm_hardware hw; struct work_struct elapsed_period; spinlock_t lock; size_t buffer_bytes; size_t hw_ptr; bool xfer_enabled; bool xfer_xrun; bool stopped; bool suspended; struct virtio_pcm_msg **msgs; unsigned int nmsgs; int msg_last_enqueued; unsigned int msg_count; wait_queue_head_t msg_empty; }; /** * struct virtio_pcm_stream - VirtIO PCM stream. * @substreams: VirtIO substreams belonging to the stream. * @nsubstreams: Number of substreams. * @chmaps: Kernel channel maps belonging to the stream. * @nchmaps: Number of channel maps. */ struct virtio_pcm_stream { struct virtio_pcm_substream **substreams; u32 nsubstreams; struct snd_pcm_chmap_elem *chmaps; u32 nchmaps; }; /** * struct virtio_pcm - VirtIO PCM device. * @list: VirtIO PCM list entry. * @nid: Function group node identifier. * @pcm: Kernel PCM device. * @streams: VirtIO PCM streams (playback and capture). */ struct virtio_pcm { struct list_head list; u32 nid; struct snd_pcm *pcm; struct virtio_pcm_stream streams[SNDRV_PCM_STREAM_LAST + 1]; }; extern const struct snd_pcm_ops virtsnd_pcm_ops; int virtsnd_pcm_validate(struct virtio_device *vdev); int virtsnd_pcm_parse_cfg(struct virtio_snd *snd); int virtsnd_pcm_build_devs(struct virtio_snd *snd); void virtsnd_pcm_event(struct virtio_snd *snd, struct virtio_snd_event *event); void virtsnd_pcm_tx_notify_cb(struct virtqueue *vqueue); void virtsnd_pcm_rx_notify_cb(struct virtqueue *vqueue); struct virtio_pcm *virtsnd_pcm_find(struct virtio_snd *snd, u32 nid); struct virtio_pcm *virtsnd_pcm_find_or_create(struct virtio_snd *snd, u32 nid); struct virtio_snd_msg * virtsnd_pcm_ctl_msg_alloc(struct virtio_pcm_substream *vss, unsigned int command, gfp_t gfp); int virtsnd_pcm_msg_alloc(struct virtio_pcm_substream *vss, unsigned int periods, unsigned int period_bytes); void virtsnd_pcm_msg_free(struct virtio_pcm_substream *vss); int virtsnd_pcm_msg_send(struct virtio_pcm_substream *vss); unsigned int virtsnd_pcm_msg_pending_num(struct virtio_pcm_substream *vss); #endif /* VIRTIO_SND_PCM_H */