162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * virtio-snd: Virtio sound device 462306a36Sopenharmony_ci * Copyright (C) 2021 OpenSynergy GmbH 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci#ifndef VIRTIO_SND_PCM_H 762306a36Sopenharmony_ci#define VIRTIO_SND_PCM_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/atomic.h> 1062306a36Sopenharmony_ci#include <linux/virtio_config.h> 1162306a36Sopenharmony_ci#include <sound/pcm.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistruct virtio_pcm; 1462306a36Sopenharmony_cistruct virtio_pcm_msg; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/** 1762306a36Sopenharmony_ci * struct virtio_pcm_substream - VirtIO PCM substream. 1862306a36Sopenharmony_ci * @snd: VirtIO sound device. 1962306a36Sopenharmony_ci * @nid: Function group node identifier. 2062306a36Sopenharmony_ci * @sid: Stream identifier. 2162306a36Sopenharmony_ci * @direction: Stream data flow direction (SNDRV_PCM_STREAM_XXX). 2262306a36Sopenharmony_ci * @features: Stream VirtIO feature bit map (1 << VIRTIO_SND_PCM_F_XXX). 2362306a36Sopenharmony_ci * @substream: Kernel ALSA substream. 2462306a36Sopenharmony_ci * @hw: Kernel ALSA substream hardware descriptor. 2562306a36Sopenharmony_ci * @elapsed_period: Kernel work to handle the elapsed period state. 2662306a36Sopenharmony_ci * @lock: Spinlock that protects fields shared by interrupt handlers and 2762306a36Sopenharmony_ci * substream operators. 2862306a36Sopenharmony_ci * @buffer_bytes: Current buffer size in bytes. 2962306a36Sopenharmony_ci * @hw_ptr: Substream hardware pointer value in bytes [0 ... buffer_bytes). 3062306a36Sopenharmony_ci * @xfer_enabled: Data transfer state (0 - off, 1 - on). 3162306a36Sopenharmony_ci * @xfer_xrun: Data underflow/overflow state (0 - no xrun, 1 - xrun). 3262306a36Sopenharmony_ci * @stopped: True if the substream is stopped and must be released on the device 3362306a36Sopenharmony_ci * side. 3462306a36Sopenharmony_ci * @suspended: True if the substream is suspended and must be reconfigured on 3562306a36Sopenharmony_ci * the device side at resume. 3662306a36Sopenharmony_ci * @msgs: Allocated I/O messages. 3762306a36Sopenharmony_ci * @nmsgs: Number of allocated I/O messages. 3862306a36Sopenharmony_ci * @msg_last_enqueued: Index of the last I/O message added to the virtqueue. 3962306a36Sopenharmony_ci * @msg_count: Number of pending I/O messages in the virtqueue. 4062306a36Sopenharmony_ci * @msg_empty: Notify when msg_count is zero. 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_cistruct virtio_pcm_substream { 4362306a36Sopenharmony_ci struct virtio_snd *snd; 4462306a36Sopenharmony_ci u32 nid; 4562306a36Sopenharmony_ci u32 sid; 4662306a36Sopenharmony_ci u32 direction; 4762306a36Sopenharmony_ci u32 features; 4862306a36Sopenharmony_ci struct snd_pcm_substream *substream; 4962306a36Sopenharmony_ci struct snd_pcm_hardware hw; 5062306a36Sopenharmony_ci struct work_struct elapsed_period; 5162306a36Sopenharmony_ci spinlock_t lock; 5262306a36Sopenharmony_ci size_t buffer_bytes; 5362306a36Sopenharmony_ci size_t hw_ptr; 5462306a36Sopenharmony_ci bool xfer_enabled; 5562306a36Sopenharmony_ci bool xfer_xrun; 5662306a36Sopenharmony_ci bool stopped; 5762306a36Sopenharmony_ci bool suspended; 5862306a36Sopenharmony_ci struct virtio_pcm_msg **msgs; 5962306a36Sopenharmony_ci unsigned int nmsgs; 6062306a36Sopenharmony_ci int msg_last_enqueued; 6162306a36Sopenharmony_ci unsigned int msg_count; 6262306a36Sopenharmony_ci wait_queue_head_t msg_empty; 6362306a36Sopenharmony_ci}; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/** 6662306a36Sopenharmony_ci * struct virtio_pcm_stream - VirtIO PCM stream. 6762306a36Sopenharmony_ci * @substreams: VirtIO substreams belonging to the stream. 6862306a36Sopenharmony_ci * @nsubstreams: Number of substreams. 6962306a36Sopenharmony_ci * @chmaps: Kernel channel maps belonging to the stream. 7062306a36Sopenharmony_ci * @nchmaps: Number of channel maps. 7162306a36Sopenharmony_ci */ 7262306a36Sopenharmony_cistruct virtio_pcm_stream { 7362306a36Sopenharmony_ci struct virtio_pcm_substream **substreams; 7462306a36Sopenharmony_ci u32 nsubstreams; 7562306a36Sopenharmony_ci struct snd_pcm_chmap_elem *chmaps; 7662306a36Sopenharmony_ci u32 nchmaps; 7762306a36Sopenharmony_ci}; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/** 8062306a36Sopenharmony_ci * struct virtio_pcm - VirtIO PCM device. 8162306a36Sopenharmony_ci * @list: VirtIO PCM list entry. 8262306a36Sopenharmony_ci * @nid: Function group node identifier. 8362306a36Sopenharmony_ci * @pcm: Kernel PCM device. 8462306a36Sopenharmony_ci * @streams: VirtIO PCM streams (playback and capture). 8562306a36Sopenharmony_ci */ 8662306a36Sopenharmony_cistruct virtio_pcm { 8762306a36Sopenharmony_ci struct list_head list; 8862306a36Sopenharmony_ci u32 nid; 8962306a36Sopenharmony_ci struct snd_pcm *pcm; 9062306a36Sopenharmony_ci struct virtio_pcm_stream streams[SNDRV_PCM_STREAM_LAST + 1]; 9162306a36Sopenharmony_ci}; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ciextern const struct snd_pcm_ops virtsnd_pcm_ops; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ciint virtsnd_pcm_validate(struct virtio_device *vdev); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ciint virtsnd_pcm_parse_cfg(struct virtio_snd *snd); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ciint virtsnd_pcm_build_devs(struct virtio_snd *snd); 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_civoid virtsnd_pcm_event(struct virtio_snd *snd, struct virtio_snd_event *event); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_civoid virtsnd_pcm_tx_notify_cb(struct virtqueue *vqueue); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_civoid virtsnd_pcm_rx_notify_cb(struct virtqueue *vqueue); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistruct virtio_pcm *virtsnd_pcm_find(struct virtio_snd *snd, u32 nid); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistruct virtio_pcm *virtsnd_pcm_find_or_create(struct virtio_snd *snd, u32 nid); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistruct virtio_snd_msg * 11262306a36Sopenharmony_civirtsnd_pcm_ctl_msg_alloc(struct virtio_pcm_substream *vss, 11362306a36Sopenharmony_ci unsigned int command, gfp_t gfp); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ciint virtsnd_pcm_msg_alloc(struct virtio_pcm_substream *vss, 11662306a36Sopenharmony_ci unsigned int periods, unsigned int period_bytes); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_civoid virtsnd_pcm_msg_free(struct virtio_pcm_substream *vss); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ciint virtsnd_pcm_msg_send(struct virtio_pcm_substream *vss); 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ciunsigned int virtsnd_pcm_msg_pending_num(struct virtio_pcm_substream *vss); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci#endif /* VIRTIO_SND_PCM_H */ 125