Anton Yakovlev | 29b96bf | 2021-03-02 17:47:04 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
| 2 | /* |
| 3 | * virtio-snd: Virtio sound device |
| 4 | * Copyright (C) 2021 OpenSynergy GmbH |
| 5 | */ |
| 6 | #ifndef VIRTIO_SND_PCM_H |
| 7 | #define VIRTIO_SND_PCM_H |
| 8 | |
| 9 | #include <linux/atomic.h> |
| 10 | #include <linux/virtio_config.h> |
| 11 | #include <sound/pcm.h> |
| 12 | |
| 13 | struct virtio_pcm; |
| 14 | struct virtio_pcm_msg; |
| 15 | |
| 16 | /** |
| 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 | * @hw: Kernel ALSA substream hardware descriptor. |
| 25 | * @elapsed_period: Kernel work to handle the elapsed period state. |
Anton Yakovlev | f40a286 | 2021-03-02 17:47:05 +0100 | [diff] [blame] | 26 | * @lock: Spinlock that protects fields shared by interrupt handlers and |
| 27 | * substream operators. |
| 28 | * @buffer_bytes: Current buffer size in bytes. |
| 29 | * @hw_ptr: Substream hardware pointer value in bytes [0 ... buffer_bytes). |
| 30 | * @xfer_enabled: Data transfer state (0 - off, 1 - on). |
| 31 | * @xfer_xrun: Data underflow/overflow state (0 - no xrun, 1 - xrun). |
Anton Yakovlev | da76e9f | 2021-03-02 17:47:06 +0100 | [diff] [blame] | 32 | * @stopped: True if the substream is stopped and must be released on the device |
| 33 | * side. |
Anton Yakovlev | 575483e | 2021-03-02 17:47:09 +0100 | [diff] [blame] | 34 | * @suspended: True if the substream is suspended and must be reconfigured on |
| 35 | * the device side at resume. |
Anton Yakovlev | f40a286 | 2021-03-02 17:47:05 +0100 | [diff] [blame] | 36 | * @msgs: Allocated I/O messages. |
| 37 | * @nmsgs: Number of allocated I/O messages. |
| 38 | * @msg_last_enqueued: Index of the last I/O message added to the virtqueue. |
| 39 | * @msg_count: Number of pending I/O messages in the virtqueue. |
| 40 | * @msg_empty: Notify when msg_count is zero. |
Anton Yakovlev | 29b96bf | 2021-03-02 17:47:04 +0100 | [diff] [blame] | 41 | */ |
| 42 | struct virtio_pcm_substream { |
| 43 | struct virtio_snd *snd; |
| 44 | u32 nid; |
| 45 | u32 sid; |
| 46 | u32 direction; |
| 47 | u32 features; |
| 48 | struct snd_pcm_substream *substream; |
| 49 | struct snd_pcm_hardware hw; |
| 50 | struct work_struct elapsed_period; |
Anton Yakovlev | f40a286 | 2021-03-02 17:47:05 +0100 | [diff] [blame] | 51 | spinlock_t lock; |
| 52 | size_t buffer_bytes; |
| 53 | size_t hw_ptr; |
| 54 | bool xfer_enabled; |
| 55 | bool xfer_xrun; |
Anton Yakovlev | da76e9f | 2021-03-02 17:47:06 +0100 | [diff] [blame] | 56 | bool stopped; |
Anton Yakovlev | 575483e | 2021-03-02 17:47:09 +0100 | [diff] [blame] | 57 | bool suspended; |
Anton Yakovlev | f40a286 | 2021-03-02 17:47:05 +0100 | [diff] [blame] | 58 | struct virtio_pcm_msg **msgs; |
| 59 | unsigned int nmsgs; |
| 60 | int msg_last_enqueued; |
| 61 | unsigned int msg_count; |
| 62 | wait_queue_head_t msg_empty; |
Anton Yakovlev | 29b96bf | 2021-03-02 17:47:04 +0100 | [diff] [blame] | 63 | }; |
| 64 | |
| 65 | /** |
| 66 | * struct virtio_pcm_stream - VirtIO PCM stream. |
| 67 | * @substreams: VirtIO substreams belonging to the stream. |
| 68 | * @nsubstreams: Number of substreams. |
Anton Yakovlev | 19325fe | 2021-03-02 17:47:08 +0100 | [diff] [blame] | 69 | * @chmaps: Kernel channel maps belonging to the stream. |
| 70 | * @nchmaps: Number of channel maps. |
Anton Yakovlev | 29b96bf | 2021-03-02 17:47:04 +0100 | [diff] [blame] | 71 | */ |
| 72 | struct virtio_pcm_stream { |
| 73 | struct virtio_pcm_substream **substreams; |
| 74 | u32 nsubstreams; |
Anton Yakovlev | 19325fe | 2021-03-02 17:47:08 +0100 | [diff] [blame] | 75 | struct snd_pcm_chmap_elem *chmaps; |
| 76 | u32 nchmaps; |
Anton Yakovlev | 29b96bf | 2021-03-02 17:47:04 +0100 | [diff] [blame] | 77 | }; |
| 78 | |
| 79 | /** |
| 80 | * struct virtio_pcm - VirtIO PCM device. |
| 81 | * @list: VirtIO PCM list entry. |
| 82 | * @nid: Function group node identifier. |
| 83 | * @pcm: Kernel PCM device. |
| 84 | * @streams: VirtIO PCM streams (playback and capture). |
| 85 | */ |
| 86 | struct virtio_pcm { |
| 87 | struct list_head list; |
| 88 | u32 nid; |
| 89 | struct snd_pcm *pcm; |
| 90 | struct virtio_pcm_stream streams[SNDRV_PCM_STREAM_LAST + 1]; |
| 91 | }; |
| 92 | |
Anton Yakovlev | da76e9f | 2021-03-02 17:47:06 +0100 | [diff] [blame] | 93 | extern const struct snd_pcm_ops virtsnd_pcm_ops; |
| 94 | |
Anton Yakovlev | 29b96bf | 2021-03-02 17:47:04 +0100 | [diff] [blame] | 95 | int virtsnd_pcm_validate(struct virtio_device *vdev); |
| 96 | |
| 97 | int virtsnd_pcm_parse_cfg(struct virtio_snd *snd); |
| 98 | |
| 99 | int virtsnd_pcm_build_devs(struct virtio_snd *snd); |
| 100 | |
Anton Yakovlev | f40a286 | 2021-03-02 17:47:05 +0100 | [diff] [blame] | 101 | void virtsnd_pcm_event(struct virtio_snd *snd, struct virtio_snd_event *event); |
| 102 | |
| 103 | void virtsnd_pcm_tx_notify_cb(struct virtqueue *vqueue); |
| 104 | |
| 105 | void virtsnd_pcm_rx_notify_cb(struct virtqueue *vqueue); |
| 106 | |
Anton Yakovlev | 29b96bf | 2021-03-02 17:47:04 +0100 | [diff] [blame] | 107 | struct virtio_pcm *virtsnd_pcm_find(struct virtio_snd *snd, u32 nid); |
| 108 | |
| 109 | struct virtio_pcm *virtsnd_pcm_find_or_create(struct virtio_snd *snd, u32 nid); |
| 110 | |
Anton Yakovlev | f40a286 | 2021-03-02 17:47:05 +0100 | [diff] [blame] | 111 | struct virtio_snd_msg * |
| 112 | virtsnd_pcm_ctl_msg_alloc(struct virtio_pcm_substream *vss, |
| 113 | unsigned int command, gfp_t gfp); |
| 114 | |
| 115 | int virtsnd_pcm_msg_alloc(struct virtio_pcm_substream *vss, |
| 116 | unsigned int periods, unsigned int period_bytes); |
| 117 | |
| 118 | void virtsnd_pcm_msg_free(struct virtio_pcm_substream *vss); |
| 119 | |
| 120 | int virtsnd_pcm_msg_send(struct virtio_pcm_substream *vss); |
| 121 | |
| 122 | unsigned int virtsnd_pcm_msg_pending_num(struct virtio_pcm_substream *vss); |
| 123 | |
Anton Yakovlev | 29b96bf | 2021-03-02 17:47:04 +0100 | [diff] [blame] | 124 | #endif /* VIRTIO_SND_PCM_H */ |