/* SPDX-License-Identifier: GPL-2.0+ */1/*2* virtio-snd: Virtio sound device3* Copyright (C) 2021 OpenSynergy GmbH4*/5#ifndef VIRTIO_SND_PCM_H6#define VIRTIO_SND_PCM_H78#include <linux/atomic.h>9#include <linux/virtio_config.h>10#include <sound/pcm.h>11#include <sound/pcm-indirect.h>1213struct virtio_pcm;14struct virtio_pcm_msg;1516/**17* struct virtio_pcm_substream - VirtIO PCM substream.18* @snd: VirtIO sound device.19* @nid: Function group node identifier.20* @sid: Stream identifier.21* @direction: Stream data flow direction (SNDRV_PCM_STREAM_XXX).22* @features: Stream VirtIO feature bit map (1 << VIRTIO_SND_PCM_F_XXX).23* @substream: Kernel ALSA substream.24* @pcm_indirect: Kernel indirect pcm structure.25* @hw: Kernel ALSA substream hardware descriptor.26* @elapsed_period: Kernel work to handle the elapsed period state.27* @lock: Spinlock that protects fields shared by interrupt handlers and28* substream operators.29* @buffer_bytes: Current buffer size in bytes.30* @hw_ptr: Substream hardware pointer value in bytes [0 ... buffer_bytes).31* @xfer_enabled: Data transfer state (0 - off, 1 - on).32* @xfer_xrun: Data underflow/overflow state (0 - no xrun, 1 - xrun).33* @stopped: True if the substream is stopped and must be released on the device34* side.35* @suspended: True if the substream is suspended and must be reconfigured on36* the device side at resume.37* @msgs: Allocated I/O messages.38* @nmsgs: Number of allocated I/O messages.39* @msg_last_enqueued: Index of the last I/O message added to the virtqueue.40* @msg_count: Number of pending I/O messages in the virtqueue.41* @msg_empty: Notify when msg_count is zero.42*/43struct virtio_pcm_substream {44struct virtio_snd *snd;45u32 nid;46u32 sid;47u32 direction;48u32 features;49struct snd_pcm_substream *substream;50struct snd_pcm_indirect pcm_indirect;51struct snd_pcm_hardware hw;52struct work_struct elapsed_period;53spinlock_t lock;54size_t buffer_bytes;55size_t hw_ptr;56bool xfer_enabled;57bool xfer_xrun;58bool stopped;59bool suspended;60struct virtio_pcm_msg **msgs;61unsigned int nmsgs;62unsigned int msg_count;63wait_queue_head_t msg_empty;64};6566/**67* struct virtio_pcm_stream - VirtIO PCM stream.68* @substreams: VirtIO substreams belonging to the stream.69* @nsubstreams: Number of substreams.70* @chmaps: Kernel channel maps belonging to the stream.71* @nchmaps: Number of channel maps.72*/73struct virtio_pcm_stream {74struct virtio_pcm_substream **substreams;75u32 nsubstreams;76struct snd_pcm_chmap_elem *chmaps;77u32 nchmaps;78};7980/**81* struct virtio_pcm - VirtIO PCM device.82* @list: VirtIO PCM list entry.83* @nid: Function group node identifier.84* @pcm: Kernel PCM device.85* @streams: VirtIO PCM streams (playback and capture).86*/87struct virtio_pcm {88struct list_head list;89u32 nid;90struct snd_pcm *pcm;91struct virtio_pcm_stream streams[SNDRV_PCM_STREAM_LAST + 1];92};9394extern const struct snd_pcm_ops virtsnd_pcm_ops[];9596int virtsnd_pcm_validate(struct virtio_device *vdev);9798int virtsnd_pcm_parse_cfg(struct virtio_snd *snd);99100int virtsnd_pcm_build_devs(struct virtio_snd *snd);101102void virtsnd_pcm_event(struct virtio_snd *snd, struct virtio_snd_event *event);103104void virtsnd_pcm_tx_notify_cb(struct virtqueue *vqueue);105106void virtsnd_pcm_rx_notify_cb(struct virtqueue *vqueue);107108struct virtio_pcm *virtsnd_pcm_find(struct virtio_snd *snd, u32 nid);109110struct virtio_pcm *virtsnd_pcm_find_or_create(struct virtio_snd *snd, u32 nid);111112struct virtio_snd_msg *113virtsnd_pcm_ctl_msg_alloc(struct virtio_pcm_substream *vss,114unsigned int command, gfp_t gfp);115116int virtsnd_pcm_msg_alloc(struct virtio_pcm_substream *vss,117unsigned int periods, unsigned int period_bytes);118119void virtsnd_pcm_msg_free(struct virtio_pcm_substream *vss);120121int virtsnd_pcm_msg_send(struct virtio_pcm_substream *vss, unsigned long offset,122unsigned long bytes);123124unsigned int virtsnd_pcm_msg_pending_num(struct virtio_pcm_substream *vss);125126#endif /* VIRTIO_SND_PCM_H */127128129