1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3  * Copyright (C) 2021 OpenSynergy GmbH
4  */
5 #ifndef VIRTIO_SND_IF_H
6 #define VIRTIO_SND_IF_H
7 
8 #include <linux/virtio_types.h>
9 
10 /*******************************************************************************
11  * CONFIGURATION SPACE
12  */
13 struct virtio_snd_config {
14 	/* # of available physical jacks */
15 	__le32 jacks;
16 	/* # of available PCM streams */
17 	__le32 streams;
18 	/* # of available channel maps */
19 	__le32 chmaps;
20 };
21 
22 enum {
23 	/* device virtqueue indexes */
24 	VIRTIO_SND_VQ_CONTROL = 0,
25 	VIRTIO_SND_VQ_EVENT,
26 	VIRTIO_SND_VQ_TX,
27 	VIRTIO_SND_VQ_RX,
28 	/* # of device virtqueues */
29 	VIRTIO_SND_VQ_MAX
30 };
31 
32 /*******************************************************************************
33  * COMMON DEFINITIONS
34  */
35 
36 /* supported dataflow directions */
37 enum {
38 	VIRTIO_SND_D_OUTPUT = 0,
39 	VIRTIO_SND_D_INPUT
40 };
41 
42 enum {
43 	/* jack control request types */
44 	VIRTIO_SND_R_JACK_INFO = 1,
45 	VIRTIO_SND_R_JACK_REMAP,
46 
47 	/* PCM control request types */
48 	VIRTIO_SND_R_PCM_INFO = 0x0100,
49 	VIRTIO_SND_R_PCM_SET_PARAMS,
50 	VIRTIO_SND_R_PCM_PREPARE,
51 	VIRTIO_SND_R_PCM_RELEASE,
52 	VIRTIO_SND_R_PCM_START,
53 	VIRTIO_SND_R_PCM_STOP,
54 
55 	/* channel map control request types */
56 	VIRTIO_SND_R_CHMAP_INFO = 0x0200,
57 
58 	/* jack event types */
59 	VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000,
60 	VIRTIO_SND_EVT_JACK_DISCONNECTED,
61 
62 	/* PCM event types */
63 	VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100,
64 	VIRTIO_SND_EVT_PCM_XRUN,
65 
66 	/* common status codes */
67 	VIRTIO_SND_S_OK = 0x8000,
68 	VIRTIO_SND_S_BAD_MSG,
69 	VIRTIO_SND_S_NOT_SUPP,
70 	VIRTIO_SND_S_IO_ERR
71 };
72 
73 /* common header */
74 struct virtio_snd_hdr {
75 	__le32 code;
76 };
77 
78 /* event notification */
79 struct virtio_snd_event {
80 	/* VIRTIO_SND_EVT_XXX */
81 	struct virtio_snd_hdr hdr;
82 	/* optional event data */
83 	__le32 data;
84 };
85 
86 /* common control request to query an item information */
87 struct virtio_snd_query_info {
88 	/* VIRTIO_SND_R_XXX_INFO */
89 	struct virtio_snd_hdr hdr;
90 	/* item start identifier */
91 	__le32 start_id;
92 	/* item count to query */
93 	__le32 count;
94 	/* item information size in bytes */
95 	__le32 size;
96 };
97 
98 /* common item information header */
99 struct virtio_snd_info {
100 	/* function group node id (High Definition Audio Specification 7.1.2) */
101 	__le32 hda_fn_nid;
102 };
103 
104 /*******************************************************************************
105  * JACK CONTROL MESSAGES
106  */
107 struct virtio_snd_jack_hdr {
108 	/* VIRTIO_SND_R_JACK_XXX */
109 	struct virtio_snd_hdr hdr;
110 	/* 0 ... virtio_snd_config::jacks - 1 */
111 	__le32 jack_id;
112 };
113 
114 /* supported jack features */
115 enum {
116 	VIRTIO_SND_JACK_F_REMAP = 0
117 };
118 
119 struct virtio_snd_jack_info {
120 	/* common header */
121 	struct virtio_snd_info hdr;
122 	/* supported feature bit map (1 << VIRTIO_SND_JACK_F_XXX) */
123 	__le32 features;
124 	/* pin configuration (High Definition Audio Specification 7.3.3.31) */
125 	__le32 hda_reg_defconf;
126 	/* pin capabilities (High Definition Audio Specification 7.3.4.9) */
127 	__le32 hda_reg_caps;
128 	/* current jack connection status (0: disconnected, 1: connected) */
129 	__u8 connected;
130 
131 	__u8 padding[7];
132 };
133 
134 /* jack remapping control request */
135 struct virtio_snd_jack_remap {
136 	/* .code = VIRTIO_SND_R_JACK_REMAP */
137 	struct virtio_snd_jack_hdr hdr;
138 	/* selected association number */
139 	__le32 association;
140 	/* selected sequence number */
141 	__le32 sequence;
142 };
143 
144 /*******************************************************************************
145  * PCM CONTROL MESSAGES
146  */
147 struct virtio_snd_pcm_hdr {
148 	/* VIRTIO_SND_R_PCM_XXX */
149 	struct virtio_snd_hdr hdr;
150 	/* 0 ... virtio_snd_config::streams - 1 */
151 	__le32 stream_id;
152 };
153 
154 /* supported PCM stream features */
155 enum {
156 	VIRTIO_SND_PCM_F_SHMEM_HOST = 0,
157 	VIRTIO_SND_PCM_F_SHMEM_GUEST,
158 	VIRTIO_SND_PCM_F_MSG_POLLING,
159 	VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS,
160 	VIRTIO_SND_PCM_F_EVT_XRUNS
161 };
162 
163 /* supported PCM sample formats */
164 enum {
165 	/* analog formats (width / physical width) */
166 	VIRTIO_SND_PCM_FMT_IMA_ADPCM = 0,	/*  4 /  4 bits */
167 	VIRTIO_SND_PCM_FMT_MU_LAW,		/*  8 /  8 bits */
168 	VIRTIO_SND_PCM_FMT_A_LAW,		/*  8 /  8 bits */
169 	VIRTIO_SND_PCM_FMT_S8,			/*  8 /  8 bits */
170 	VIRTIO_SND_PCM_FMT_U8,			/*  8 /  8 bits */
171 	VIRTIO_SND_PCM_FMT_S16,			/* 16 / 16 bits */
172 	VIRTIO_SND_PCM_FMT_U16,			/* 16 / 16 bits */
173 	VIRTIO_SND_PCM_FMT_S18_3,		/* 18 / 24 bits */
174 	VIRTIO_SND_PCM_FMT_U18_3,		/* 18 / 24 bits */
175 	VIRTIO_SND_PCM_FMT_S20_3,		/* 20 / 24 bits */
176 	VIRTIO_SND_PCM_FMT_U20_3,		/* 20 / 24 bits */
177 	VIRTIO_SND_PCM_FMT_S24_3,		/* 24 / 24 bits */
178 	VIRTIO_SND_PCM_FMT_U24_3,		/* 24 / 24 bits */
179 	VIRTIO_SND_PCM_FMT_S20,			/* 20 / 32 bits */
180 	VIRTIO_SND_PCM_FMT_U20,			/* 20 / 32 bits */
181 	VIRTIO_SND_PCM_FMT_S24,			/* 24 / 32 bits */
182 	VIRTIO_SND_PCM_FMT_U24,			/* 24 / 32 bits */
183 	VIRTIO_SND_PCM_FMT_S32,			/* 32 / 32 bits */
184 	VIRTIO_SND_PCM_FMT_U32,			/* 32 / 32 bits */
185 	VIRTIO_SND_PCM_FMT_FLOAT,		/* 32 / 32 bits */
186 	VIRTIO_SND_PCM_FMT_FLOAT64,		/* 64 / 64 bits */
187 	/* digital formats (width / physical width) */
188 	VIRTIO_SND_PCM_FMT_DSD_U8,		/*  8 /  8 bits */
189 	VIRTIO_SND_PCM_FMT_DSD_U16,		/* 16 / 16 bits */
190 	VIRTIO_SND_PCM_FMT_DSD_U32,		/* 32 / 32 bits */
191 	VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME	/* 32 / 32 bits */
192 };
193 
194 /* supported PCM frame rates */
195 enum {
196 	VIRTIO_SND_PCM_RATE_5512 = 0,
197 	VIRTIO_SND_PCM_RATE_8000,
198 	VIRTIO_SND_PCM_RATE_11025,
199 	VIRTIO_SND_PCM_RATE_16000,
200 	VIRTIO_SND_PCM_RATE_22050,
201 	VIRTIO_SND_PCM_RATE_32000,
202 	VIRTIO_SND_PCM_RATE_44100,
203 	VIRTIO_SND_PCM_RATE_48000,
204 	VIRTIO_SND_PCM_RATE_64000,
205 	VIRTIO_SND_PCM_RATE_88200,
206 	VIRTIO_SND_PCM_RATE_96000,
207 	VIRTIO_SND_PCM_RATE_176400,
208 	VIRTIO_SND_PCM_RATE_192000,
209 	VIRTIO_SND_PCM_RATE_384000
210 };
211 
212 struct virtio_snd_pcm_info {
213 	/* common header */
214 	struct virtio_snd_info hdr;
215 	/* supported feature bit map (1 << VIRTIO_SND_PCM_F_XXX) */
216 	__le32 features;
217 	/* supported sample format bit map (1 << VIRTIO_SND_PCM_FMT_XXX) */
218 	__le64 formats;
219 	/* supported frame rate bit map (1 << VIRTIO_SND_PCM_RATE_XXX) */
220 	__le64 rates;
221 	/* dataflow direction (VIRTIO_SND_D_XXX) */
222 	__u8 direction;
223 	/* minimum # of supported channels */
224 	__u8 channels_min;
225 	/* maximum # of supported channels */
226 	__u8 channels_max;
227 
228 	__u8 padding[5];
229 };
230 
231 /* set PCM stream format */
232 struct virtio_snd_pcm_set_params {
233 	/* .code = VIRTIO_SND_R_PCM_SET_PARAMS */
234 	struct virtio_snd_pcm_hdr hdr;
235 	/* size of the hardware buffer */
236 	__le32 buffer_bytes;
237 	/* size of the hardware period */
238 	__le32 period_bytes;
239 	/* selected feature bit map (1 << VIRTIO_SND_PCM_F_XXX) */
240 	__le32 features;
241 	/* selected # of channels */
242 	__u8 channels;
243 	/* selected sample format (VIRTIO_SND_PCM_FMT_XXX) */
244 	__u8 format;
245 	/* selected frame rate (VIRTIO_SND_PCM_RATE_XXX) */
246 	__u8 rate;
247 
248 	__u8 padding;
249 };
250 
251 /*******************************************************************************
252  * PCM I/O MESSAGES
253  */
254 
255 /* I/O request header */
256 struct virtio_snd_pcm_xfer {
257 	/* 0 ... virtio_snd_config::streams - 1 */
258 	__le32 stream_id;
259 };
260 
261 /* I/O request status */
262 struct virtio_snd_pcm_status {
263 	/* VIRTIO_SND_S_XXX */
264 	__le32 status;
265 	/* current device latency */
266 	__le32 latency_bytes;
267 };
268 
269 /*******************************************************************************
270  * CHANNEL MAP CONTROL MESSAGES
271  */
272 struct virtio_snd_chmap_hdr {
273 	/* VIRTIO_SND_R_CHMAP_XXX */
274 	struct virtio_snd_hdr hdr;
275 	/* 0 ... virtio_snd_config::chmaps - 1 */
276 	__le32 chmap_id;
277 };
278 
279 /* standard channel position definition */
280 enum {
281 	VIRTIO_SND_CHMAP_NONE = 0,	/* undefined */
282 	VIRTIO_SND_CHMAP_NA,		/* silent */
283 	VIRTIO_SND_CHMAP_MONO,		/* mono stream */
284 	VIRTIO_SND_CHMAP_FL,		/* front left */
285 	VIRTIO_SND_CHMAP_FR,		/* front right */
286 	VIRTIO_SND_CHMAP_RL,		/* rear left */
287 	VIRTIO_SND_CHMAP_RR,		/* rear right */
288 	VIRTIO_SND_CHMAP_FC,		/* front center */
289 	VIRTIO_SND_CHMAP_LFE,		/* low frequency (LFE) */
290 	VIRTIO_SND_CHMAP_SL,		/* side left */
291 	VIRTIO_SND_CHMAP_SR,		/* side right */
292 	VIRTIO_SND_CHMAP_RC,		/* rear center */
293 	VIRTIO_SND_CHMAP_FLC,		/* front left center */
294 	VIRTIO_SND_CHMAP_FRC,		/* front right center */
295 	VIRTIO_SND_CHMAP_RLC,		/* rear left center */
296 	VIRTIO_SND_CHMAP_RRC,		/* rear right center */
297 	VIRTIO_SND_CHMAP_FLW,		/* front left wide */
298 	VIRTIO_SND_CHMAP_FRW,		/* front right wide */
299 	VIRTIO_SND_CHMAP_FLH,		/* front left high */
300 	VIRTIO_SND_CHMAP_FCH,		/* front center high */
301 	VIRTIO_SND_CHMAP_FRH,		/* front right high */
302 	VIRTIO_SND_CHMAP_TC,		/* top center */
303 	VIRTIO_SND_CHMAP_TFL,		/* top front left */
304 	VIRTIO_SND_CHMAP_TFR,		/* top front right */
305 	VIRTIO_SND_CHMAP_TFC,		/* top front center */
306 	VIRTIO_SND_CHMAP_TRL,		/* top rear left */
307 	VIRTIO_SND_CHMAP_TRR,		/* top rear right */
308 	VIRTIO_SND_CHMAP_TRC,		/* top rear center */
309 	VIRTIO_SND_CHMAP_TFLC,		/* top front left center */
310 	VIRTIO_SND_CHMAP_TFRC,		/* top front right center */
311 	VIRTIO_SND_CHMAP_TSL,		/* top side left */
312 	VIRTIO_SND_CHMAP_TSR,		/* top side right */
313 	VIRTIO_SND_CHMAP_LLFE,		/* left LFE */
314 	VIRTIO_SND_CHMAP_RLFE,		/* right LFE */
315 	VIRTIO_SND_CHMAP_BC,		/* bottom center */
316 	VIRTIO_SND_CHMAP_BLC,		/* bottom left center */
317 	VIRTIO_SND_CHMAP_BRC		/* bottom right center */
318 };
319 
320 /* maximum possible number of channels */
321 #define VIRTIO_SND_CHMAP_MAX_SIZE	18
322 
323 struct virtio_snd_chmap_info {
324 	/* common header */
325 	struct virtio_snd_info hdr;
326 	/* dataflow direction (VIRTIO_SND_D_XXX) */
327 	__u8 direction;
328 	/* # of valid channel position values */
329 	__u8 channels;
330 	/* channel position values (VIRTIO_SND_CHMAP_XXX) */
331 	__u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE];
332 };
333 
334 #endif /* VIRTIO_SND_IF_H */
335