xref: /openbmc/linux/include/xen/interface/io/sndif.h (revision 92c005a1)
1 /* SPDX-License-Identifier: MIT */
2 /******************************************************************************
3  * sndif.h
4  *
5  * Unified sound-device I/O interface for Xen guest OSes.
6  *
7  * Copyright (C) 2013-2015 GlobalLogic Inc.
8  * Copyright (C) 2016-2017 EPAM Systems Inc.
9  *
10  * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
11  *          Oleksandr Grytsov <oleksandr_grytsov@epam.com>
12  *          Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
13  *          Iurii Konovalenko <iurii.konovalenko@globallogic.com>
14  */
15 
16 #ifndef __XEN_PUBLIC_IO_SNDIF_H__
17 #define __XEN_PUBLIC_IO_SNDIF_H__
18 
19 #include "ring.h"
20 #include "../grant_table.h"
21 
22 /*
23  ******************************************************************************
24  *                           Protocol version
25  ******************************************************************************
26  */
27 #define XENSND_PROTOCOL_VERSION	2
28 
29 /*
30  ******************************************************************************
31  *                  Feature and Parameter Negotiation
32  ******************************************************************************
33  *
34  * Front->back notifications: when enqueuing a new request, sending a
35  * notification can be made conditional on xensnd_req (i.e., the generic
36  * hold-off mechanism provided by the ring macros). Backends must set
37  * xensnd_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
38  *
39  * Back->front notifications: when enqueuing a new response, sending a
40  * notification can be made conditional on xensnd_resp (i.e., the generic
41  * hold-off mechanism provided by the ring macros). Frontends must set
42  * xensnd_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
43  *
44  * The two halves of a para-virtual sound card driver utilize nodes within
45  * XenStore to communicate capabilities and to negotiate operating parameters.
46  * This section enumerates these nodes which reside in the respective front and
47  * backend portions of XenStore, following the XenBus convention.
48  *
49  * All data in XenStore is stored as strings. Nodes specifying numeric
50  * values are encoded in decimal. Integer value ranges listed below are
51  * expressed as fixed sized integer types capable of storing the conversion
52  * of a properly formated node string, without loss of information.
53  *
54  ******************************************************************************
55  *                        Example configuration
56  ******************************************************************************
57  *
58  * Note: depending on the use-case backend can expose more sound cards and
59  * PCM devices/streams than the underlying HW physically has by employing
60  * SW mixers, configuring virtual sound streams, channels etc.
61  *
62  * This is an example of backend and frontend configuration:
63  *
64  *--------------------------------- Backend -----------------------------------
65  *
66  * /local/domain/0/backend/vsnd/1/0/frontend-id = "1"
67  * /local/domain/0/backend/vsnd/1/0/frontend = "/local/domain/1/device/vsnd/0"
68  * /local/domain/0/backend/vsnd/1/0/state = "4"
69  * /local/domain/0/backend/vsnd/1/0/versions = "1,2"
70  *
71  *--------------------------------- Frontend ----------------------------------
72  *
73  * /local/domain/1/device/vsnd/0/backend-id = "0"
74  * /local/domain/1/device/vsnd/0/backend = "/local/domain/0/backend/vsnd/1/0"
75  * /local/domain/1/device/vsnd/0/state = "4"
76  * /local/domain/1/device/vsnd/0/version = "1"
77  *
78  *----------------------------- Card configuration ----------------------------
79  *
80  * /local/domain/1/device/vsnd/0/short-name = "Card short name"
81  * /local/domain/1/device/vsnd/0/long-name = "Card long name"
82  * /local/domain/1/device/vsnd/0/sample-rates = "8000,32000,44100,48000,96000"
83  * /local/domain/1/device/vsnd/0/sample-formats = "s8,u8,s16_le,s16_be"
84  * /local/domain/1/device/vsnd/0/buffer-size = "262144"
85  *
86  *------------------------------- PCM device 0 --------------------------------
87  *
88  * /local/domain/1/device/vsnd/0/0/name = "General analog"
89  * /local/domain/1/device/vsnd/0/0/channels-max = "5"
90  *
91  *----------------------------- Stream 0, playback ----------------------------
92  *
93  * /local/domain/1/device/vsnd/0/0/0/type = "p"
94  * /local/domain/1/device/vsnd/0/0/0/sample-formats = "s8,u8"
95  * /local/domain/1/device/vsnd/0/0/0/unique-id = "0"
96  *
97  * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386"
98  * /local/domain/1/device/vsnd/0/0/0/event-channel = "15"
99  * /local/domain/1/device/vsnd/0/0/0/evt-ring-ref = "1386"
100  * /local/domain/1/device/vsnd/0/0/0/evt-event-channel = "215"
101  *
102  *------------------------------ Stream 1, capture ----------------------------
103  *
104  * /local/domain/1/device/vsnd/0/0/1/type = "c"
105  * /local/domain/1/device/vsnd/0/0/1/channels-max = "2"
106  * /local/domain/1/device/vsnd/0/0/1/unique-id = "1"
107  *
108  * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384"
109  * /local/domain/1/device/vsnd/0/0/1/event-channel = "13"
110  * /local/domain/1/device/vsnd/0/0/1/evt-ring-ref = "1384"
111  * /local/domain/1/device/vsnd/0/0/1/evt-event-channel = "213"
112  *
113  *------------------------------- PCM device 1 --------------------------------
114  *
115  * /local/domain/1/device/vsnd/0/1/name = "HDMI-0"
116  * /local/domain/1/device/vsnd/0/1/sample-rates = "8000,32000,44100"
117  *
118  *------------------------------ Stream 0, capture ----------------------------
119  *
120  * /local/domain/1/device/vsnd/0/1/0/type = "c"
121  * /local/domain/1/device/vsnd/0/1/0/unique-id = "2"
122  *
123  * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387"
124  * /local/domain/1/device/vsnd/0/1/0/event-channel = "151"
125  * /local/domain/1/device/vsnd/0/1/0/evt-ring-ref = "1387"
126  * /local/domain/1/device/vsnd/0/1/0/evt-event-channel = "351"
127  *
128  *------------------------------- PCM device 2 --------------------------------
129  *
130  * /local/domain/1/device/vsnd/0/2/name = "SPDIF"
131  *
132  *----------------------------- Stream 0, playback ----------------------------
133  *
134  * /local/domain/1/device/vsnd/0/2/0/type = "p"
135  * /local/domain/1/device/vsnd/0/2/0/unique-id = "3"
136  *
137  * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389"
138  * /local/domain/1/device/vsnd/0/2/0/event-channel = "152"
139  * /local/domain/1/device/vsnd/0/2/0/evt-ring-ref = "1389"
140  * /local/domain/1/device/vsnd/0/2/0/evt-event-channel = "452"
141  *
142  ******************************************************************************
143  *                            Backend XenBus Nodes
144  ******************************************************************************
145  *
146  *----------------------------- Protocol version ------------------------------
147  *
148  * versions
149  *      Values:         <string>
150  *
151  *      List of XENSND_LIST_SEPARATOR separated protocol versions supported
152  *      by the backend. For example "1,2,3".
153  *
154  ******************************************************************************
155  *                            Frontend XenBus Nodes
156  ******************************************************************************
157  *
158  *-------------------------------- Addressing ---------------------------------
159  *
160  * dom-id
161  *      Values:         <uint16_t>
162  *
163  *      Domain identifier.
164  *
165  * dev-id
166  *      Values:         <uint16_t>
167  *
168  *      Device identifier.
169  *
170  * pcm-dev-idx
171  *      Values:         <uint8_t>
172  *
173  *      Zero based contigous index of the PCM device.
174  *
175  * stream-idx
176  *      Values:         <uint8_t>
177  *
178  *      Zero based contigous index of the stream of the PCM device.
179  *
180  * The following pattern is used for addressing:
181  *   /local/domain/<dom-id>/device/vsnd/<dev-id>/<pcm-dev-idx>/<stream-idx>/...
182  *
183  *----------------------------- Protocol version ------------------------------
184  *
185  * version
186  *      Values:         <string>
187  *
188  *      Protocol version, chosen among the ones supported by the backend.
189  *
190  *------------------------------- PCM settings --------------------------------
191  *
192  * Every virtualized sound frontend has a set of PCM devices and streams, each
193  * could be individually configured. Part of the PCM configuration can be
194  * defined at higher level of the hierarchy and be fully or partially re-used
195  * by the underlying layers. These configuration values are:
196  *  o number of channels (min/max)
197  *  o supported sample rates
198  *  o supported sample formats.
199  * E.g. one can define these values for the whole card, device or stream.
200  * Every underlying layer in turn can re-define some or all of them to better
201  * fit its needs. For example, card may define number of channels to be
202  * in [1; 8] range, and some particular stream may be limited to [1; 2] only.
203  * The rule is that the underlying layer must be a subset of the upper layer
204  * range.
205  *
206  * channels-min
207  *      Values:         <uint8_t>
208  *
209  *      The minimum amount of channels that is supported, [1; channels-max].
210  *      Optional, if not set or omitted a value of 1 is used.
211  *
212  * channels-max
213  *      Values:         <uint8_t>
214  *
215  *      The maximum amount of channels that is supported.
216  *      Must be at least <channels-min>.
217  *
218  * sample-rates
219  *      Values:         <list of uint32_t>
220  *
221  *      List of supported sample rates separated by XENSND_LIST_SEPARATOR.
222  *      Sample rates are expressed as a list of decimal values w/o any
223  *      ordering requirement.
224  *
225  * sample-formats
226  *      Values:         <list of XENSND_PCM_FORMAT_XXX_STR>
227  *
228  *      List of supported sample formats separated by XENSND_LIST_SEPARATOR.
229  *      Items must not exceed XENSND_SAMPLE_FORMAT_MAX_LEN length.
230  *
231  * buffer-size
232  *      Values:         <uint32_t>
233  *
234  *      The maximum size in octets of the buffer to allocate per stream.
235  *
236  *----------------------- Virtual sound card settings -------------------------
237  * short-name
238  *      Values:         <char[32]>
239  *
240  *      Short name of the virtual sound card. Optional.
241  *
242  * long-name
243  *      Values:         <char[80]>
244  *
245  *      Long name of the virtual sound card. Optional.
246  *
247  *----------------------------- Device settings -------------------------------
248  * name
249  *      Values:         <char[80]>
250  *
251  *      Name of the sound device within the virtual sound card. Optional.
252  *
253  *----------------------------- Stream settings -------------------------------
254  *
255  * type
256  *      Values:         "p", "c"
257  *
258  *      Stream type: "p" - playback stream, "c" - capture stream
259  *
260  *      If both capture and playback are needed then two streams need to be
261  *      defined under the same device.
262  *
263  * unique-id
264  *      Values:         <string>
265  *
266  *      After stream initialization it is assigned a unique ID, so every
267  *      stream of the frontend can be identified by the backend by this ID.
268  *      This can be UUID or such.
269  *
270  *-------------------- Stream Request Transport Parameters --------------------
271  *
272  * event-channel
273  *      Values:         <uint32_t>
274  *
275  *      The identifier of the Xen event channel used to signal activity
276  *      in the ring buffer.
277  *
278  * ring-ref
279  *      Values:         <uint32_t>
280  *
281  *      The Xen grant reference granting permission for the backend to map
282  *      a sole page in a single page sized ring buffer.
283  *
284  *--------------------- Stream Event Transport Parameters ---------------------
285  *
286  * This communication path is used to deliver asynchronous events from backend
287  * to frontend, set up per stream.
288  *
289  * evt-event-channel
290  *      Values:         <uint32_t>
291  *
292  *      The identifier of the Xen event channel used to signal activity
293  *      in the ring buffer.
294  *
295  * evt-ring-ref
296  *      Values:         <uint32_t>
297  *
298  *      The Xen grant reference granting permission for the backend to map
299  *      a sole page in a single page sized ring buffer.
300  *
301  ******************************************************************************
302  *                               STATE DIAGRAMS
303  ******************************************************************************
304  *
305  * Tool stack creates front and back state nodes with initial state
306  * XenbusStateInitialising.
307  * Tool stack creates and sets up frontend sound configuration nodes per domain.
308  *
309  * Front                                Back
310  * =================================    =====================================
311  * XenbusStateInitialising              XenbusStateInitialising
312  *                                       o Query backend device identification
313  *                                         data.
314  *                                       o Open and validate backend device.
315  *                                                      |
316  *                                                      |
317  *                                                      V
318  *                                      XenbusStateInitWait
319  *
320  * o Query frontend configuration
321  * o Allocate and initialize
322  *   event channels per configured
323  *   playback/capture stream.
324  * o Publish transport parameters
325  *   that will be in effect during
326  *   this connection.
327  *              |
328  *              |
329  *              V
330  * XenbusStateInitialised
331  *
332  *                                       o Query frontend transport parameters.
333  *                                       o Connect to the event channels.
334  *                                                      |
335  *                                                      |
336  *                                                      V
337  *                                      XenbusStateConnected
338  *
339  *  o Create and initialize OS
340  *    virtual sound device instances
341  *    as per configuration.
342  *              |
343  *              |
344  *              V
345  * XenbusStateConnected
346  *
347  *                                      XenbusStateUnknown
348  *                                      XenbusStateClosed
349  *                                      XenbusStateClosing
350  * o Remove virtual sound device
351  * o Remove event channels
352  *              |
353  *              |
354  *              V
355  * XenbusStateClosed
356  *
357  *------------------------------- Recovery flow -------------------------------
358  *
359  * In case of frontend unrecoverable errors backend handles that as
360  * if frontend goes into the XenbusStateClosed state.
361  *
362  * In case of backend unrecoverable errors frontend tries removing
363  * the virtualized device. If this is possible at the moment of error,
364  * then frontend goes into the XenbusStateInitialising state and is ready for
365  * new connection with backend. If the virtualized device is still in use and
366  * cannot be removed, then frontend goes into the XenbusStateReconfiguring state
367  * until either the virtualized device removed or backend initiates a new
368  * connection. On the virtualized device removal frontend goes into the
369  * XenbusStateInitialising state.
370  *
371  * Note on XenbusStateReconfiguring state of the frontend: if backend has
372  * unrecoverable errors then frontend cannot send requests to the backend
373  * and thus cannot provide functionality of the virtualized device anymore.
374  * After backend is back to normal the virtualized device may still hold some
375  * state: configuration in use, allocated buffers, client application state etc.
376  * So, in most cases, this will require frontend to implement complex recovery
377  * reconnect logic. Instead, by going into XenbusStateReconfiguring state,
378  * frontend will make sure no new clients of the virtualized device are
379  * accepted, allow existing client(s) to exit gracefully by signaling error
380  * state etc.
381  * Once all the clients are gone frontend can reinitialize the virtualized
382  * device and get into XenbusStateInitialising state again signaling the
383  * backend that a new connection can be made.
384  *
385  * There are multiple conditions possible under which frontend will go from
386  * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS
387  * specific. For example:
388  * 1. The underlying OS framework may provide callbacks to signal that the last
389  *    client of the virtualized device has gone and the device can be removed
390  * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue)
391  *    to periodically check if this is the right time to re-try removal of
392  *    the virtualized device.
393  * 3. By any other means.
394  *
395  ******************************************************************************
396  *                             PCM FORMATS
397  ******************************************************************************
398  *
399  * XENSND_PCM_FORMAT_<format>[_<endian>]
400  *
401  * format: <S/U/F><bits> or <name>
402  *     S - signed, U - unsigned, F - float
403  *     bits - 8, 16, 24, 32
404  *     name - MU_LAW, GSM, etc.
405  *
406  * endian: <LE/BE>, may be absent
407  *     LE - Little endian, BE - Big endian
408  */
409 #define XENSND_PCM_FORMAT_S8		0
410 #define XENSND_PCM_FORMAT_U8		1
411 #define XENSND_PCM_FORMAT_S16_LE	2
412 #define XENSND_PCM_FORMAT_S16_BE	3
413 #define XENSND_PCM_FORMAT_U16_LE	4
414 #define XENSND_PCM_FORMAT_U16_BE	5
415 #define XENSND_PCM_FORMAT_S24_LE	6
416 #define XENSND_PCM_FORMAT_S24_BE	7
417 #define XENSND_PCM_FORMAT_U24_LE	8
418 #define XENSND_PCM_FORMAT_U24_BE	9
419 #define XENSND_PCM_FORMAT_S32_LE	10
420 #define XENSND_PCM_FORMAT_S32_BE	11
421 #define XENSND_PCM_FORMAT_U32_LE	12
422 #define XENSND_PCM_FORMAT_U32_BE	13
423 #define XENSND_PCM_FORMAT_F32_LE	14 /* 4-byte float, IEEE-754 32-bit, */
424 #define XENSND_PCM_FORMAT_F32_BE	15 /* range -1.0 to 1.0              */
425 #define XENSND_PCM_FORMAT_F64_LE	16 /* 8-byte float, IEEE-754 64-bit, */
426 #define XENSND_PCM_FORMAT_F64_BE	17 /* range -1.0 to 1.0              */
427 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE 18
428 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE 19
429 #define XENSND_PCM_FORMAT_MU_LAW	20
430 #define XENSND_PCM_FORMAT_A_LAW		21
431 #define XENSND_PCM_FORMAT_IMA_ADPCM	22
432 #define XENSND_PCM_FORMAT_MPEG		23
433 #define XENSND_PCM_FORMAT_GSM		24
434 
435 /*
436  ******************************************************************************
437  *                             REQUEST CODES
438  ******************************************************************************
439  */
440 #define XENSND_OP_OPEN			0
441 #define XENSND_OP_CLOSE			1
442 #define XENSND_OP_READ			2
443 #define XENSND_OP_WRITE			3
444 #define XENSND_OP_SET_VOLUME		4
445 #define XENSND_OP_GET_VOLUME		5
446 #define XENSND_OP_MUTE			6
447 #define XENSND_OP_UNMUTE		7
448 #define XENSND_OP_TRIGGER		8
449 #define XENSND_OP_HW_PARAM_QUERY	9
450 
451 #define XENSND_OP_TRIGGER_START		0
452 #define XENSND_OP_TRIGGER_PAUSE		1
453 #define XENSND_OP_TRIGGER_STOP		2
454 #define XENSND_OP_TRIGGER_RESUME	3
455 
456 /*
457  ******************************************************************************
458  *                                 EVENT CODES
459  ******************************************************************************
460  */
461 #define XENSND_EVT_CUR_POS		0
462 
463 /*
464  ******************************************************************************
465  *               XENSTORE FIELD AND PATH NAME STRINGS, HELPERS
466  ******************************************************************************
467  */
468 #define XENSND_DRIVER_NAME		"vsnd"
469 
470 #define XENSND_LIST_SEPARATOR		","
471 /* Field names */
472 #define XENSND_FIELD_BE_VERSIONS	"versions"
473 #define XENSND_FIELD_FE_VERSION		"version"
474 #define XENSND_FIELD_VCARD_SHORT_NAME	"short-name"
475 #define XENSND_FIELD_VCARD_LONG_NAME	"long-name"
476 #define XENSND_FIELD_RING_REF		"ring-ref"
477 #define XENSND_FIELD_EVT_CHNL		"event-channel"
478 #define XENSND_FIELD_EVT_RING_REF	"evt-ring-ref"
479 #define XENSND_FIELD_EVT_EVT_CHNL	"evt-event-channel"
480 #define XENSND_FIELD_DEVICE_NAME	"name"
481 #define XENSND_FIELD_TYPE		"type"
482 #define XENSND_FIELD_STREAM_UNIQUE_ID	"unique-id"
483 #define XENSND_FIELD_CHANNELS_MIN	"channels-min"
484 #define XENSND_FIELD_CHANNELS_MAX	"channels-max"
485 #define XENSND_FIELD_SAMPLE_RATES	"sample-rates"
486 #define XENSND_FIELD_SAMPLE_FORMATS	"sample-formats"
487 #define XENSND_FIELD_BUFFER_SIZE	"buffer-size"
488 
489 /* Stream type field values. */
490 #define XENSND_STREAM_TYPE_PLAYBACK	"p"
491 #define XENSND_STREAM_TYPE_CAPTURE	"c"
492 /* Sample rate max string length */
493 #define XENSND_SAMPLE_RATE_MAX_LEN	11
494 /* Sample format field values */
495 #define XENSND_SAMPLE_FORMAT_MAX_LEN	24
496 
497 #define XENSND_PCM_FORMAT_S8_STR	"s8"
498 #define XENSND_PCM_FORMAT_U8_STR	"u8"
499 #define XENSND_PCM_FORMAT_S16_LE_STR	"s16_le"
500 #define XENSND_PCM_FORMAT_S16_BE_STR	"s16_be"
501 #define XENSND_PCM_FORMAT_U16_LE_STR	"u16_le"
502 #define XENSND_PCM_FORMAT_U16_BE_STR	"u16_be"
503 #define XENSND_PCM_FORMAT_S24_LE_STR	"s24_le"
504 #define XENSND_PCM_FORMAT_S24_BE_STR	"s24_be"
505 #define XENSND_PCM_FORMAT_U24_LE_STR	"u24_le"
506 #define XENSND_PCM_FORMAT_U24_BE_STR	"u24_be"
507 #define XENSND_PCM_FORMAT_S32_LE_STR	"s32_le"
508 #define XENSND_PCM_FORMAT_S32_BE_STR	"s32_be"
509 #define XENSND_PCM_FORMAT_U32_LE_STR	"u32_le"
510 #define XENSND_PCM_FORMAT_U32_BE_STR	"u32_be"
511 #define XENSND_PCM_FORMAT_F32_LE_STR	"float_le"
512 #define XENSND_PCM_FORMAT_F32_BE_STR	"float_be"
513 #define XENSND_PCM_FORMAT_F64_LE_STR	"float64_le"
514 #define XENSND_PCM_FORMAT_F64_BE_STR	"float64_be"
515 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_LE_STR "iec958_subframe_le"
516 #define XENSND_PCM_FORMAT_IEC958_SUBFRAME_BE_STR "iec958_subframe_be"
517 #define XENSND_PCM_FORMAT_MU_LAW_STR	"mu_law"
518 #define XENSND_PCM_FORMAT_A_LAW_STR	"a_law"
519 #define XENSND_PCM_FORMAT_IMA_ADPCM_STR	"ima_adpcm"
520 #define XENSND_PCM_FORMAT_MPEG_STR	"mpeg"
521 #define XENSND_PCM_FORMAT_GSM_STR	"gsm"
522 
523 
524 /*
525  ******************************************************************************
526  *                          STATUS RETURN CODES
527  ******************************************************************************
528  *
529  * Status return code is zero on success and -XEN_EXX on failure.
530  *
531  ******************************************************************************
532  *                              Assumptions
533  ******************************************************************************
534  * o usage of grant reference 0 as invalid grant reference:
535  *   grant reference 0 is valid, but never exposed to a PV driver,
536  *   because of the fact it is already in use/reserved by the PV console.
537  * o all references in this document to page sizes must be treated
538  *   as pages of size XEN_PAGE_SIZE unless otherwise noted.
539  *
540  ******************************************************************************
541  *       Description of the protocol between frontend and backend driver
542  ******************************************************************************
543  *
544  * The two halves of a Para-virtual sound driver communicate with
545  * each other using shared pages and event channels.
546  * Shared page contains a ring with request/response packets.
547  *
548  * Packets, used for input/output operations, e.g. read/write, set/get volume,
549  * etc., provide offset/length fields in order to allow asynchronous protocol
550  * operation with buffer space sharing: part of the buffer allocated at
551  * XENSND_OP_OPEN can be used for audio samples and part, for example,
552  * for volume control.
553  *
554  * All reserved fields in the structures below must be 0.
555  *
556  *---------------------------------- Requests ---------------------------------
557  *
558  * All request packets have the same length (64 octets)
559  * All request packets have common header:
560  *         0                1                 2               3        octet
561  * +----------------+----------------+----------------+----------------+
562  * |               id                |    operation   |    reserved    | 4
563  * +----------------+----------------+----------------+----------------+
564  * |                             reserved                              | 8
565  * +----------------+----------------+----------------+----------------+
566  *   id - uint16_t, private guest value, echoed in response
567  *   operation - uint8_t, operation code, XENSND_OP_???
568  *
569  * For all packets which use offset and length:
570  *   offset - uint32_t, read or write data offset within the shared buffer,
571  *     passed with XENSND_OP_OPEN request, octets,
572  *     [0; XENSND_OP_OPEN.buffer_sz - 1].
573  *   length - uint32_t, read or write data length, octets
574  *
575  * Request open - open a PCM stream for playback or capture:
576  *
577  *         0                1                 2               3        octet
578  * +----------------+----------------+----------------+----------------+
579  * |               id                | XENSND_OP_OPEN |    reserved    | 4
580  * +----------------+----------------+----------------+----------------+
581  * |                             reserved                              | 8
582  * +----------------+----------------+----------------+----------------+
583  * |                             pcm_rate                              | 12
584  * +----------------+----------------+----------------+----------------+
585  * |  pcm_format    |  pcm_channels  |             reserved            | 16
586  * +----------------+----------------+----------------+----------------+
587  * |                             buffer_sz                             | 20
588  * +----------------+----------------+----------------+----------------+
589  * |                           gref_directory                          | 24
590  * +----------------+----------------+----------------+----------------+
591  * |                             period_sz                             | 28
592  * +----------------+----------------+----------------+----------------+
593  * |                             reserved                              | 32
594  * +----------------+----------------+----------------+----------------+
595  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
596  * +----------------+----------------+----------------+----------------+
597  * |                             reserved                              | 64
598  * +----------------+----------------+----------------+----------------+
599  *
600  * pcm_rate - uint32_t, stream data rate, Hz
601  * pcm_format - uint8_t, XENSND_PCM_FORMAT_XXX value
602  * pcm_channels - uint8_t, number of channels of this stream,
603  *   [channels-min; channels-max]
604  * buffer_sz - uint32_t, buffer size to be allocated, octets
605  * period_sz - uint32_t, event period size, octets
606  *   This is the requested value of the period at which frontend would
607  *   like to receive XENSND_EVT_CUR_POS notifications from the backend when
608  *   stream position advances during playback/capture.
609  *   It shows how many octets are expected to be played/captured before
610  *   sending such an event.
611  *   If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.
612  *
613  * gref_directory - grant_ref_t, a reference to the first shared page
614  *   describing shared buffer references. At least one page exists. If shared
615  *   buffer size  (buffer_sz) exceeds what can be addressed by this single page,
616  *   then reference to the next page must be supplied (see gref_dir_next_page
617  *   below)
618  */
619 
620 struct xensnd_open_req {
621 	uint32_t pcm_rate;
622 	uint8_t pcm_format;
623 	uint8_t pcm_channels;
624 	uint16_t reserved;
625 	uint32_t buffer_sz;
626 	grant_ref_t gref_directory;
627 	uint32_t period_sz;
628 };
629 
630 /*
631  * Shared page for XENSND_OP_OPEN buffer descriptor (gref_directory in the
632  *   request) employs a list of pages, describing all pages of the shared data
633  *   buffer:
634  *         0                1                 2               3        octet
635  * +----------------+----------------+----------------+----------------+
636  * |                        gref_dir_next_page                         | 4
637  * +----------------+----------------+----------------+----------------+
638  * |                              gref[0]                              | 8
639  * +----------------+----------------+----------------+----------------+
640  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
641  * +----------------+----------------+----------------+----------------+
642  * |                              gref[i]                              | i*4+8
643  * +----------------+----------------+----------------+----------------+
644  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
645  * +----------------+----------------+----------------+----------------+
646  * |                             gref[N - 1]                           | N*4+8
647  * +----------------+----------------+----------------+----------------+
648  *
649  * gref_dir_next_page - grant_ref_t, reference to the next page describing
650  *   page directory. Must be 0 if there are no more pages in the list.
651  * gref[i] - grant_ref_t, reference to a shared page of the buffer
652  *   allocated at XENSND_OP_OPEN
653  *
654  * Number of grant_ref_t entries in the whole page directory is not
655  * passed, but instead can be calculated as:
656  *   num_grefs_total = (XENSND_OP_OPEN.buffer_sz + XEN_PAGE_SIZE - 1) /
657  *       XEN_PAGE_SIZE
658  */
659 
660 struct xensnd_page_directory {
661 	grant_ref_t gref_dir_next_page;
662 	grant_ref_t gref[1]; /* Variable length */
663 };
664 
665 /*
666  *  Request close - close an opened pcm stream:
667  *         0                1                 2               3        octet
668  * +----------------+----------------+----------------+----------------+
669  * |               id                | XENSND_OP_CLOSE|    reserved    | 4
670  * +----------------+----------------+----------------+----------------+
671  * |                             reserved                              | 8
672  * +----------------+----------------+----------------+----------------+
673  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
674  * +----------------+----------------+----------------+----------------+
675  * |                             reserved                              | 64
676  * +----------------+----------------+----------------+----------------+
677  *
678  * Request read/write - used for read (for capture) or write (for playback):
679  *         0                1                 2               3        octet
680  * +----------------+----------------+----------------+----------------+
681  * |               id                |   operation    |    reserved    | 4
682  * +----------------+----------------+----------------+----------------+
683  * |                             reserved                              | 8
684  * +----------------+----------------+----------------+----------------+
685  * |                              offset                               | 12
686  * +----------------+----------------+----------------+----------------+
687  * |                              length                               | 16
688  * +----------------+----------------+----------------+----------------+
689  * |                             reserved                              | 20
690  * +----------------+----------------+----------------+----------------+
691  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
692  * +----------------+----------------+----------------+----------------+
693  * |                             reserved                              | 64
694  * +----------------+----------------+----------------+----------------+
695  *
696  * operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write
697  */
698 
699 struct xensnd_rw_req {
700 	uint32_t offset;
701 	uint32_t length;
702 };
703 
704 /*
705  * Request set/get volume - set/get channels' volume of the stream given:
706  *         0                1                 2               3        octet
707  * +----------------+----------------+----------------+----------------+
708  * |               id                |   operation    |    reserved    | 4
709  * +----------------+----------------+----------------+----------------+
710  * |                             reserved                              | 8
711  * +----------------+----------------+----------------+----------------+
712  * |                              offset                               | 12
713  * +----------------+----------------+----------------+----------------+
714  * |                              length                               | 16
715  * +----------------+----------------+----------------+----------------+
716  * |                             reserved                              | 20
717  * +----------------+----------------+----------------+----------------+
718  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
719  * +----------------+----------------+----------------+----------------+
720  * |                             reserved                              | 64
721  * +----------------+----------------+----------------+----------------+
722  *
723  * operation - XENSND_OP_SET_VOLUME for volume set
724  *   or XENSND_OP_GET_VOLUME for volume get
725  * Buffer passed with XENSND_OP_OPEN is used to exchange volume
726  * values:
727  *
728  *         0                1                 2               3        octet
729  * +----------------+----------------+----------------+----------------+
730  * |                             channel[0]                            | 4
731  * +----------------+----------------+----------------+----------------+
732  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
733  * +----------------+----------------+----------------+----------------+
734  * |                             channel[i]                            | i*4
735  * +----------------+----------------+----------------+----------------+
736  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
737  * +----------------+----------------+----------------+----------------+
738  * |                           channel[N - 1]                          | (N-1)*4
739  * +----------------+----------------+----------------+----------------+
740  *
741  * N = XENSND_OP_OPEN.pcm_channels
742  * i - uint8_t, index of a channel
743  * channel[i] - sint32_t, volume of i-th channel
744  * Volume is expressed as a signed value in steps of 0.001 dB,
745  * while 0 being 0 dB.
746  *
747  * Request mute/unmute - mute/unmute stream:
748  *         0                1                 2               3        octet
749  * +----------------+----------------+----------------+----------------+
750  * |               id                |   operation    |    reserved    | 4
751  * +----------------+----------------+----------------+----------------+
752  * |                             reserved                              | 8
753  * +----------------+----------------+----------------+----------------+
754  * |                              offset                               | 12
755  * +----------------+----------------+----------------+----------------+
756  * |                              length                               | 16
757  * +----------------+----------------+----------------+----------------+
758  * |                             reserved                              | 20
759  * +----------------+----------------+----------------+----------------+
760  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
761  * +----------------+----------------+----------------+----------------+
762  * |                             reserved                              | 64
763  * +----------------+----------------+----------------+----------------+
764  *
765  * operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute
766  * Buffer passed with XENSND_OP_OPEN is used to exchange mute/unmute
767  * values:
768  *
769  *                                   0                                 octet
770  * +----------------+----------------+----------------+----------------+
771  * |                             channel[0]                            | 4
772  * +----------------+----------------+----------------+----------------+
773  * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
774  * +----------------+----------------+----------------+----------------+
775  * |                             channel[i]                            | i*4
776  * +----------------+----------------+----------------+----------------+
777  * +/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
778  * +----------------+----------------+----------------+----------------+
779  * |                           channel[N - 1]                          | (N-1)*4
780  * +----------------+----------------+----------------+----------------+
781  *
782  * N = XENSND_OP_OPEN.pcm_channels
783  * i - uint8_t, index of a channel
784  * channel[i] - uint8_t, non-zero if i-th channel needs to be muted/unmuted
785  *
786  *------------------------------------ N.B. -----------------------------------
787  *
788  * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME,
789  * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE.
790  *
791  * Request stream running state change - trigger PCM stream running state
792  * to start, stop, pause or resume:
793  *
794  *         0                1                 2               3        octet
795  * +----------------+----------------+----------------+----------------+
796  * |               id                |   _OP_TRIGGER  |    reserved    | 4
797  * +----------------+----------------+----------------+----------------+
798  * |                             reserved                              | 8
799  * +----------------+----------------+----------------+----------------+
800  * |      type      |                     reserved                     | 12
801  * +----------------+----------------+----------------+----------------+
802  * |                             reserved                              | 16
803  * +----------------+----------------+----------------+----------------+
804  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
805  * +----------------+----------------+----------------+----------------+
806  * |                             reserved                              | 64
807  * +----------------+----------------+----------------+----------------+
808  *
809  * type - uint8_t, XENSND_OP_TRIGGER_XXX value
810  */
811 
812 struct xensnd_trigger_req {
813 	uint8_t type;
814 };
815 
816 /*
817  * Request stream parameter ranges: request intervals and
818  *   masks of supported ranges for stream configuration values.
819  *
820  *   Sound device configuration for a particular stream is a limited subset
821  *   of the multidimensional configuration available on XenStore, e.g.
822  *   once the frame rate has been selected there is a limited supported range
823  *   for sample rates becomes available (which might be the same set configured
824  *   on XenStore or less). For example, selecting 96kHz sample rate may limit
825  *   number of channels available for such configuration from 4 to 2, etc.
826  *   Thus, each call to XENSND_OP_HW_PARAM_QUERY may reduce configuration
827  *   space making it possible to iteratively get the final stream configuration,
828  *   used in XENSND_OP_OPEN request.
829  *
830  *   See response format for this request.
831  *
832  *         0                1                 2               3        octet
833  * +----------------+----------------+----------------+----------------+
834  * |               id                | _HW_PARAM_QUERY|    reserved    | 4
835  * +----------------+----------------+----------------+----------------+
836  * |                             reserved                              | 8
837  * +----------------+----------------+----------------+----------------+
838  * |                     formats mask low 32-bit                       | 12
839  * +----------------+----------------+----------------+----------------+
840  * |                     formats mask high 32-bit                      | 16
841  * +----------------+----------------+----------------+----------------+
842  * |                              min rate                             | 20
843  * +----------------+----------------+----------------+----------------+
844  * |                              max rate                             | 24
845  * +----------------+----------------+----------------+----------------+
846  * |                            min channels                           | 28
847  * +----------------+----------------+----------------+----------------+
848  * |                            max channels                           | 32
849  * +----------------+----------------+----------------+----------------+
850  * |                         min buffer frames                         | 36
851  * +----------------+----------------+----------------+----------------+
852  * |                         max buffer frames                         | 40
853  * +----------------+----------------+----------------+----------------+
854  * |                         min period frames                         | 44
855  * +----------------+----------------+----------------+----------------+
856  * |                         max period frames                         | 48
857  * +----------------+----------------+----------------+----------------+
858  * |                             reserved                              | 52
859  * +----------------+----------------+----------------+----------------+
860  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
861  * +----------------+----------------+----------------+----------------+
862  * |                             reserved                              | 64
863  * +----------------+----------------+----------------+----------------+
864  *
865  * formats - uint64_t, bit mask representing values of the parameter
866  *     made as bitwise OR of (1 << XENSND_PCM_FORMAT_XXX) values
867  *
868  * For interval parameters:
869  *   min - uint32_t, minimum value of the parameter
870  *   max - uint32_t, maximum value of the parameter
871  *
872  * Frame is defined as a product of the number of channels by the
873  * number of octets per one sample.
874  */
875 
876 struct xensnd_query_hw_param {
877 	uint64_t formats;
878 	struct {
879 		uint32_t min;
880 		uint32_t max;
881 	} rates;
882 	struct {
883 		uint32_t min;
884 		uint32_t max;
885 	} channels;
886 	struct {
887 		uint32_t min;
888 		uint32_t max;
889 	} buffer;
890 	struct {
891 		uint32_t min;
892 		uint32_t max;
893 	} period;
894 };
895 
896 /*
897  *---------------------------------- Responses --------------------------------
898  *
899  * All response packets have the same length (64 octets)
900  *
901  * All response packets have common header:
902  *         0                1                 2               3        octet
903  * +----------------+----------------+----------------+----------------+
904  * |               id                |    operation   |    reserved    | 4
905  * +----------------+----------------+----------------+----------------+
906  * |                              status                               | 8
907  * +----------------+----------------+----------------+----------------+
908  *
909  * id - uint16_t, copied from the request
910  * operation - uint8_t, XENSND_OP_* - copied from request
911  * status - int32_t, response status, zero on success and -XEN_EXX on failure
912  *
913  *
914  * HW parameter query response - response for XENSND_OP_HW_PARAM_QUERY:
915  *         0                1                 2               3        octet
916  * +----------------+----------------+----------------+----------------+
917  * |               id                |    operation   |    reserved    | 4
918  * +----------------+----------------+----------------+----------------+
919  * |                              status                               | 8
920  * +----------------+----------------+----------------+----------------+
921  * |                     formats mask low 32-bit                       | 12
922  * +----------------+----------------+----------------+----------------+
923  * |                     formats mask high 32-bit                      | 16
924  * +----------------+----------------+----------------+----------------+
925  * |                              min rate                             | 20
926  * +----------------+----------------+----------------+----------------+
927  * |                              max rate                             | 24
928  * +----------------+----------------+----------------+----------------+
929  * |                            min channels                           | 28
930  * +----------------+----------------+----------------+----------------+
931  * |                            max channels                           | 32
932  * +----------------+----------------+----------------+----------------+
933  * |                         min buffer frames                         | 36
934  * +----------------+----------------+----------------+----------------+
935  * |                         max buffer frames                         | 40
936  * +----------------+----------------+----------------+----------------+
937  * |                         min period frames                         | 44
938  * +----------------+----------------+----------------+----------------+
939  * |                         max period frames                         | 48
940  * +----------------+----------------+----------------+----------------+
941  * |                             reserved                              | 52
942  * +----------------+----------------+----------------+----------------+
943  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
944  * +----------------+----------------+----------------+----------------+
945  * |                             reserved                              | 64
946  * +----------------+----------------+----------------+----------------+
947  *
948  * Meaning of the values in this response is the same as for
949  * XENSND_OP_HW_PARAM_QUERY request.
950  */
951 
952 /*
953  *----------------------------------- Events ----------------------------------
954  *
955  * Events are sent via shared page allocated by the front and propagated by
956  *   evt-event-channel/evt-ring-ref XenStore entries
957  * All event packets have the same length (64 octets)
958  * All event packets have common header:
959  *         0                1                 2               3        octet
960  * +----------------+----------------+----------------+----------------+
961  * |               id                |      type      |   reserved     | 4
962  * +----------------+----------------+----------------+----------------+
963  * |                             reserved                              | 8
964  * +----------------+----------------+----------------+----------------+
965  *
966  * id - uint16_t, event id, may be used by front
967  * type - uint8_t, type of the event
968  *
969  *
970  * Current stream position - event from back to front when stream's
971  *   playback/capture position has advanced:
972  *         0                1                 2               3        octet
973  * +----------------+----------------+----------------+----------------+
974  * |               id                |   _EVT_CUR_POS |   reserved     | 4
975  * +----------------+----------------+----------------+----------------+
976  * |                             reserved                              | 8
977  * +----------------+----------------+----------------+----------------+
978  * |                         position low 32-bit                       | 12
979  * +----------------+----------------+----------------+----------------+
980  * |                         position high 32-bit                      | 16
981  * +----------------+----------------+----------------+----------------+
982  * |                             reserved                              | 20
983  * +----------------+----------------+----------------+----------------+
984  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
985  * +----------------+----------------+----------------+----------------+
986  * |                             reserved                              | 64
987  * +----------------+----------------+----------------+----------------+
988  *
989  * position - current value of stream's playback/capture position, octets
990  *
991  */
992 
993 struct xensnd_cur_pos_evt {
994 	uint64_t position;
995 };
996 
997 struct xensnd_req {
998 	uint16_t id;
999 	uint8_t operation;
1000 	uint8_t reserved[5];
1001 	union {
1002 		struct xensnd_open_req open;
1003 		struct xensnd_rw_req rw;
1004 		struct xensnd_trigger_req trigger;
1005 		struct xensnd_query_hw_param hw_param;
1006 		uint8_t reserved[56];
1007 	} op;
1008 };
1009 
1010 struct xensnd_resp {
1011 	uint16_t id;
1012 	uint8_t operation;
1013 	uint8_t reserved;
1014 	int32_t status;
1015 	union {
1016 		struct xensnd_query_hw_param hw_param;
1017 		uint8_t reserved1[56];
1018 	} resp;
1019 };
1020 
1021 struct xensnd_evt {
1022 	uint16_t id;
1023 	uint8_t type;
1024 	uint8_t reserved[5];
1025 	union {
1026 		struct xensnd_cur_pos_evt cur_pos;
1027 		uint8_t reserved[56];
1028 	} op;
1029 };
1030 
1031 DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp);
1032 
1033 /*
1034  ******************************************************************************
1035  *                        Back to front events delivery
1036  ******************************************************************************
1037  * In order to deliver asynchronous events from back to front a shared page is
1038  * allocated by front and its granted reference propagated to back via
1039  * XenStore entries (evt-ring-ref/evt-event-channel).
1040  * This page has a common header used by both front and back to synchronize
1041  * access and control event's ring buffer, while back being a producer of the
1042  * events and front being a consumer. The rest of the page after the header
1043  * is used for event packets.
1044  *
1045  * Upon reception of an event(s) front may confirm its reception
1046  * for either each event, group of events or none.
1047  */
1048 
1049 struct xensnd_event_page {
1050 	uint32_t in_cons;
1051 	uint32_t in_prod;
1052 	uint8_t reserved[56];
1053 };
1054 
1055 #define XENSND_EVENT_PAGE_SIZE XEN_PAGE_SIZE
1056 #define XENSND_IN_RING_OFFS (sizeof(struct xensnd_event_page))
1057 #define XENSND_IN_RING_SIZE (XENSND_EVENT_PAGE_SIZE - XENSND_IN_RING_OFFS)
1058 #define XENSND_IN_RING_LEN (XENSND_IN_RING_SIZE / sizeof(struct xensnd_evt))
1059 #define XENSND_IN_RING(page) \
1060 	((struct xensnd_evt *)((char *)(page) + XENSND_IN_RING_OFFS))
1061 #define XENSND_IN_RING_REF(page, idx) \
1062 	(XENSND_IN_RING((page))[(idx) % XENSND_IN_RING_LEN])
1063 
1064 #endif /* __XEN_PUBLIC_IO_SNDIF_H__ */
1065