From: Anton Yakovlev <anton.yakov...@opensynergy.com>
This patch proposes virtio specification for a new virtio sound device,
that may be useful in case when having audio is required but a device
passthrough or emulation is not an option.
Signed-off-by: Anton Yakovlev <anton.yakov...@opensynergy.com>
---
v7->v8 changes:
1. Add a universal control request to query information about any
configuration item (jacks, streams and channel maps). The request
allows to get information in one by one or in a batch manner.
2. Add a common information header that allows to link items together
in a unified way.
3. Rework a jack configuration as a jack information structure.
4. Rework a stream configuration as a stream information structure.
5. Make a channel map as a separate item and add the
"Channel Map Control Messages" section.
conformance.tex | 33 +-
content.tex | 1 +
introduction.tex | 3 +
virtio-sound.tex | 807 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 841 insertions(+), 3 deletions(-)
create mode 100644 virtio-sound.tex
diff --git a/conformance.tex b/conformance.tex
index b6fdec0..ffa1f76 100644
--- a/conformance.tex
+++ b/conformance.tex
@@ -15,7 +15,7 @@ \section{Conformance Targets}\label{sec:Conformance /
Conformance Targets}
\begin{itemize}
\item Clause \ref{sec:Conformance / Driver Conformance}.
\item One of clauses \ref{sec:Conformance / Driver Conformance / PCI
Driver Conformance}, \ref{sec:Conformance / Driver Conformance / MMIO
Driver Conformance} or \ref{sec:Conformance / Driver Conformance / Channel
I/O Driver Conformance}.
- \item One of clauses \ref{sec:Conformance / Driver Conformance /
Network Driver Conformance}, \ref{sec:Conformance / Driver Conformance /
Block Driver Conformance}, \ref{sec:Conformance / Driver Conformance /
Console Driver Conformance}, \ref{sec:Conformance / Driver Conformance /
Entropy Driver Conformance}, \ref{sec:Conformance / Driver Conformance /
Traditional Memory Balloon Driver Conformance}, \ref{sec:Conformance /
Driver Conformance / SCSI Host Driver Conformance}, \ref{sec:Conformance /
Driver Conformance / Input Driver Conformance}, \ref{sec:Conformance /
Driver Conformance / Crypto Driver Conformance}, \ref{sec:Conformance /
Driver Conformance / Socket Driver Conformance} or \ref{sec:Conformance /
Driver Conformance / IOMMU Driver Conformance}.
+ \item One of clauses \ref{sec:Conformance / Driver Conformance /
Network Driver Conformance}, \ref{sec:Conformance / Driver Conformance /
Block Driver Conformance}, \ref{sec:Conformance / Driver Conformance /
Console Driver Conformance}, \ref{sec:Conformance / Driver Conformance /
Entropy Driver Conformance}, \ref{sec:Conformance / Driver Conformance /
Traditional Memory Balloon Driver Conformance}, \ref{sec:Conformance /
Driver Conformance / SCSI Host Driver Conformance}, \ref{sec:Conformance /
Driver Conformance / Input Driver Conformance}, \ref{sec:Conformance /
Driver Conformance / Crypto Driver Conformance}, \ref{sec:Conformance /
Driver Conformance / Socket Driver Conformance}, \ref{sec:Conformance /
Driver Conformance / IOMMU Driver Conformance} or \ref{sec:Conformance /
Driver Conformance / Sound Driver Conformance}.
\item Clause \ref{sec:Conformance / Legacy Interface: Transitional
Device and Transitional Driver Conformance}.
\end{itemize}
\item[Device] A device MUST conform to four conformance clauses:
@@ -32,8 +32,9 @@ \section{Conformance Targets}\label{sec:Conformance /
Conformance Targets}
\ref{sec:Conformance / Device Conformance / Input Device Conformance},
\ref{sec:Conformance / Device Conformance / Crypto Device Conformance},
\ref{sec:Conformance / Device Conformance / Socket Device Conformance},
-\ref{sec:Conformance / Device Conformance / RPMB Device Conformance} or
-\ref{sec:Conformance / Device Conformance / IOMMU Device Conformance}.
+\ref{sec:Conformance / Device Conformance / RPMB Device Conformance},
+\ref{sec:Conformance / Device Conformance / IOMMU Device Conformance} or
+\ref{sec:Conformance / Device Conformance / Sound Device Conformance}.
\item Clause \ref{sec:Conformance / Legacy Interface: Transitional
Device and Transitional Driver Conformance}.
\end{itemize}
\end{description}
@@ -220,6 +221,18 @@ \section{Conformance Targets}\label{sec:Conformance /
Conformance Targets}
\item \ref{drivernormative:Device Types / IOMMU Device / Device
operations / Fault reporting}
\end{itemize}
+\conformance{\subsection}{Sound Driver
Conformance}\label{sec:Conformance / Driver Conformance / Sound Driver
Conformance}
+
+A sound driver MUST conform to the following normative statements:
+
+\begin{itemize}
+\item \ref{drivernormative:Device Types / Sound Device / Device
Initialization}
+\item \ref{drivernormative:Device Types / Sound Device / Item Information
Request}
+\item \ref{drivernormative:Device Types / Sound Device / Device Operation
/ PCM Stream Parameters}
+\item \ref{drivernormative:Device Types / Sound Device / Device Operation
/ PCM Output Stream}
+\item \ref{drivernormative:Device Types / Sound Device / Device Operation
/ PCM Input Stream}
+\end{itemize}
+
\conformance{\section}{Device Conformance}\label{sec:Conformance / Device
Conformance}
A device MUST conform to the following normative statements:
@@ -408,6 +421,20 @@ \section{Conformance Targets}\label{sec:Conformance /
Conformance Targets}
\item \ref{devicenormative:Device Types / IOMMU Device / Device
operations / Fault reporting}
\end{itemize}
+\conformance{\subsection}{Sound Device
Conformance}\label{sec:Conformance / Device Conformance / Sound Device
Conformance}
+
+A sound device MUST conform to the following normative statements:
+
+\begin{itemize}
+\item \ref{devicenormative:Device Types / Sound Device / Device Operation
/ Jack Information}
+\item \ref{devicenormative:Device Types / Sound Device / Device Operation
/ PCM Stream Information}
+\item \ref{devicenormative:Device Types / Sound Device / Device Operation
/ PCM Stream Parameters}
+\item \ref{devicenormative:Device Types / Sound Device / Device Operation
/ PCM Stream Release}
+\item \ref{devicenormative:Device Types / Sound Device / Device Operation
/ PCM Output Stream}
+\item \ref{devicenormative:Device Types / Sound Device / Device Operation
/ PCM Input Stream}
+\item \ref{devicenormative:Device Types / Sound Device / Device Operation
/ Channel Map Information}
+\end{itemize}
+
\conformance{\section}{Legacy Interface: Transitional Device and
Transitional Driver Conformance}\label{sec:Conformance / Legacy Interface:
Transitional Device and Transitional Driver Conformance}
A conformant implementation MUST be either transitional or
non-transitional, see \ref{intro:Legacy
diff --git a/content.tex b/content.tex
index b91a132..edab0ca 100644
--- a/content.tex
+++ b/content.tex
@@ -6062,6 +6062,7 @@ \subsubsection{Legacy Interface: Framing
Requirements}\label{sec:Device
\input{virtio-fs.tex}
\input{virtio-rpmb.tex}
\input{virtio-iommu.tex}
+\input{virtio-sound.tex}
\chapter{Reserved Feature Bits}\label{sec:Reserved Feature Bits}
diff --git a/introduction.tex b/introduction.tex
index 33da3ec..07674f8 100644
--- a/introduction.tex
+++ b/introduction.tex
@@ -66,6 +66,9 @@ \section{Normative References}\label{sec:Normative
References}
\phantomsection\label{intro:eMMC}\textbf{[eMMC]} &
eMMC Electrical Standard (5.1), JESD84-B51,
\newline\url{http://www.jedec.org/sites/default/files/docs/JESD84-B51.pdf}\\
+ \phantomsection\label{intro:HDA}\textbf{[HDA]} &
+ High Definition Audio Specification,
+
\newline\url{https://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf}\\
\end{longtable}
diff --git a/virtio-sound.tex b/virtio-sound.tex
new file mode 100644
index 0000000..195eadd
--- /dev/null
+++ b/virtio-sound.tex
@@ -0,0 +1,807 @@
+\section{Sound Device}\label{sec:Device Types / Sound Device}
+
+The virtio sound card is a virtual audio device supporting input and
output PCM
+streams.
+
+A device is managed by control requests and can send various notifications
+through dedicated queues. A driver can transmit PCM frames using
message-based
+transport or shared memory.
+
+A small part of the specification reuses existing layouts and values from
the
+High Definition Audio specification (\hyperref[intro:HDA]{HDA}). It allows
to
+provide the same functionality and assist in two possible cases:
+
+\begin{enumerate}
+\item implementation of a universal sound driver,
+\item implementation of a sound driver as part of the High Definition
Audio
+subsystem.
+\end{enumerate}
+
+\subsection{Device ID}\label{sec:Device Types / Sound Device / Device ID}
+
+25
+
+\subsection{Virtqueues}\label{sec:Device Types / Sound Device /
Virtqueues}
+
+\begin{description}
+\item[0] controlq
+\item[1] eventq
+\item[2] txq
+\item[3] rxq
+\end{description}
+
+The control queue is used for sending control messages from the driver to
+the device.
+
+The event queue is used for sending notifications from the device to the
driver.
+
+The tx queue is used to send PCM frames for output streams.
+
+The rx queue is used to receive PCM frames from input streams.
+
+\subsection{Feature Bits}\label{sec:Device Types / Sound Device / Feature
Bits}
+
+None currently defined.
+
+\subsection{Device Configuration Layout}\label{sec:Device Types / Sound
Device / Device Configuration Layout}
+
+\begin{lstlisting}
+struct virtio_snd_config {
+ le32 jacks;
+ le32 streams;
+ le32 chmaps;
+};
+\end{lstlisting}
+
+A configuration space contains the following fields:
+
+\begin{description}
+\item[\field{jacks}] (driver-read-only) indicates a total number of all
available
+jacks.
+\item[\field{streams}] (driver-read-only) indicates a total number of all
available
+PCM streams.
+\item[\field{chmaps}] (driver-read-only) indicates a total number of all
available
+channel maps.
+\end{description}
+
+\subsection{Device Initialization}
+
+\begin{enumerate}
+\item Configure the control, event, tx and rx queues.
+\item Read the \field{jacks} field and send a control request to query
information
+about the available jacks.
+\item Read the \field{streams} field and send a control request to query
information
+about the available PCM streams.
+\item Read the \field{chmaps} field and send a control request to query
information
+about the available channel maps.
+\item Populate the event queue with empty buffers.
+\end{enumerate}
+
+\drivernormative{\subsubsection}{Device Initialization}{Device Types /
Sound Device / Device Initialization}
+
+\begin{itemize}
+\item The driver MUST populate the event queue with empty buffers of at
least
+the struct virtio_snd_event size.
+\item The driver MUST NOT put a device-readable buffers in the event
queue.
+\end{itemize}
+
+\subsection{Device Operation}\label{sec:Device Types / Sound Device /
Device Operation}
+
+All control messages are placed into the control queue and all
notifications
+are placed into the event queue. They use the following layout structure
and
+definitions:
+
+\begin{lstlisting}
+enum {
+ /* jack control request types */
+ VIRTIO_SND_R_JACK_INFO = 1,
+ VIRTIO_SND_R_JACK_REMAP,
+
+ /* PCM control request types */
+ VIRTIO_SND_R_PCM_INFO = 0x0100,
+ VIRTIO_SND_R_PCM_SET_PARAMS,
+ VIRTIO_SND_R_PCM_PREPARE,
+ VIRTIO_SND_R_PCM_RELEASE,
+ VIRTIO_SND_R_PCM_START,
+ VIRTIO_SND_R_PCM_STOP,
+
+ /* channel map control request types */
+ VIRTIO_SND_R_CHMAP_INFO = 0x0200,
+
+ /* jack event types */
+ VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000,
+ VIRTIO_SND_EVT_JACK_DISCONNECTED,
+
+ /* PCM event types */
+ VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100,
+ VIRTIO_SND_EVT_PCM_XRUN,
+
+ /* common status codes */
+ VIRTIO_SND_S_OK = 0x8000,
+ VIRTIO_SND_S_BAD_MSG,
+ VIRTIO_SND_S_NOT_SUPP,
+ VIRTIO_SND_S_IO_ERR
+};
+
+/* a common header */
+struct virtio_snd_hdr {
+ le32 code;
+};
+
+/* an event notification */
+struct virtio_snd_event {
+ struct virtio_snd_hdr hdr;
+ le32 data;
+};
+\end{lstlisting}
+
+A generic control message consists of a request part and a response part.
+
+A request part has, or consists of, a common header containing the
following
+device-readable field:
+
+\begin{description}
+\item[\field{code}] specifies a device request type (VIRTIO_SND_R_*).
+\end{description}
+
+A response part has, or consists of, a common header containing the
following
+device-writable field:
+
+\begin{description}
+\item[\field{code}] indicates a device request status (VIRTIO_SND_S_*).
+\end{description}
+
+The status field can take one of the following values:
+
+\begin{itemize}
+\item VIRTIO_SND_S_OK - success.
+\item VIRTIO_SND_S_BAD_MSG - a control message is malformed or contains
invalid
+parameters.
+\item VIRTIO_SND_S_NOT_SUPP - requested operation or parameters are not
supported.
+\item VIRTIO_SND_S_IO_ERR - an I/O error occurred.
+\end{itemize}
+
+The request part may be followed by an additional device-readable payload,
+and the response part may be followed by an additional device-writable
payload.
+
+An event notification contains the following device-writable fields:
+
+\begin{description}
+\item[\field{hdr}] indicates an event type (VIRTIO_SND_EVT_*).
+\item[\field{data}] indicates an optional event data.
+\end{description}
+
+For all entities involved in the exchange of audio data, the device uses
one of
+the following data flow directions:
+
+\begin{lstlisting}
+enum {
+ VIRTIO_SND_D_OUTPUT = 0,
+ VIRTIO_SND_D_INPUT
+};
+\end{lstlisting}
+
+\subsubsection{Item Information Request}\label{sec:Device Types / Sound
Device / Device Operation / Item Information Request}
+
+A special control message is used to request information about any kind of
+configuration item. The request part uses the following structure
definition:
+
+\begin{lstlisting}
+struct virtio_snd_query_info {
+ struct virtio_snd_hdr hdr;
+ le32 start_id;
+ le32 count;
+ le32 size;
+};
+\end{lstlisting}
+
+The request contains the following device-readable fields:
+
+\begin{description}
+\item[\field{hdr}] specifies a particular item request type
(VIRTIO_SND_R_*_INFO).
+\item[\field{start_id}] specifies the starting identifier for the item
(the range
+of available identifiers is limited by the total number of particular
items that
+is indicated in the device configuration space).
+\item[\field{count}] specifies the number of items for which information
is
+requested (the total number of particular items is indicated in the device
+configuration space).
+\item[\field{size}] specifies the size of the structure containing
information
+for one item (used for backward compatibility).
+\end{description}
+
+The response consists of the virtio_snd_hdr structure (contains the
request
+status code), followed by the device-writable information structures of
the
+item. Each information structure begins with the following common header:
+
+\begin{lstlisting}
+struct virtio_snd_info {
+ le32 hda_fn_nid;
+};
+\end{lstlisting}
+
+The header contains the following field:
+
+\begin{description}
+\item[\field{hda_fn_nid}] indicates a function group node identifier
+(see \hyperref[intro:HDA]{HDA}, section 7.1.2). This field can be used to
link
+together different types of resources (e.g. jacks with streams and channel
maps
+with streams).
+\end{description}
+
+\drivernormative{\subsubsection}{Item Information Request}{Device Types /
Sound Device / Item Information Request}
+
+\begin{itemize}
+\item The driver MUST NOT set \field{start_id} and \field{count} such that
+\field{start_id} + \field{count} is greater than the total number of
particular
+items that is indicated in the device configuration space.
+\item The driver MUST provide a buffer of sizeof(struct virtio_snd_hdr) +
+\field{count} * \field{size} bytes for the response.
+\end{itemize}
+
+\subsubsection{Relationships with the High Definition Audio
Specification}\label{sec:Device Types / Sound Device / Device Operation /
Relationships with HDA}
+
+The High Definition Audio specification introduces the codec as part of
the
+hardware that implements some of the functionality. The codec architecture
and
+capabilities are described by tree structure of special nodes each of
which is
+either a function module or a function group (see
\hyperref[intro:HDA]{HDA} for
+details).
+
+The virtio sound specification assumes that a single codec is implemented
in the
+device. Function module nodes are simulated by item information
structures,
+and function group nodes are simulated by the \field{hda_fn_nid} field in
each
+such structure.
+
+\subsubsection{Jack Control Messages}\label{sec:Device Types / Sound
Device / Device Operation / Jack Control Messages}
+
+A jack control request has, or consists of, a common header with the
following
+layout structure:
+
+\begin{lstlisting}
+struct virtio_snd_jack_hdr {
+ struct virtio_snd_hdr hdr;
+ le32 jack_id;
+};
+\end{lstlisting}
+
+The header consists of the following device-readable fields:
+
+\begin{description}
+\item[\field{hdr}] specifies a request type (VIRTIO_SND_R_JACK_*).
+\item[\field{jack_id}] specifies a jack identifier from 0 to \field{jacks}
- 1.
+\end{description}
+
+\paragraph{VIRTIO_SND_R_JACK_INFO}
+
+Query information about the available jacks.
+
+The request consists of the virtio_snd_query_info structure
+(see \nameref{sec:Device Types / Sound Device / Device Operation / Item
Information Request}).
+The response consists of the virtio_snd_hdr structure, followed by the
following
+jack information structures:
+
+\begin{lstlisting}
+/* supported jack features */
+enum {
+ VIRTIO_SND_JACK_F_REMAP = 0
+};
+
+struct virtio_snd_jack_info {
+ struct virtio_snd_info hdr;
+ le32 features; /* 1 << VIRTIO_SND_JACK_F_XXX */
+ le32 hda_reg_defconf;
+ le32 hda_reg_caps;
+ u8 connected;
+
+ u8 padding[7];
+};
+\end{lstlisting}
+
+The structure contains the following device-writable fields:
+
+\begin{description}
+\item[\field{features}] indicates a supported feature bit map:
+\begin{itemize}
+\item VIRTIO_SND_JACK_F_REMAP - jack remapping support.
+\end{itemize}
+\item[\field{hda_reg_defconf}] indicates a pin default configuration value
+(see \hyperref[intro:HDA]{HDA}, section 7.3.3.31).
+\item[\field{hda_reg_caps}] indicates a pin capabilities value
+(see \hyperref[intro:HDA]{HDA}, section 7.3.4.9).
+\item[\field{connected}] indicates the current jack connection status
+(1 - connected, 0 - disconnected).
+\end{description}
+
+\devicenormative{\subparagraph}{Jack Information}{Device Types / Sound
Device / Device Operation / Jack Information}
+
+\begin{itemize}
+\item The device MUST NOT set undefined feature values.
+\item The device MUST initialize the \field{padding} bytes to 0.
+\end{itemize}
+
+\paragraph{VIRTIO_SND_R_JACK_REMAP}
+
+If the VIRTIO_SND_JACK_F_REMAP feature bit is set in the jack information,
+then the driver can send a control request to change the association
and/or
+sequence number for the specified jack ID.
+
+The request uses the following structure and layout definitions:
+
+\begin{lstlisting}
+struct virtio_snd_jack_remap {
+ struct virtio_snd_jack_hdr hdr; /* .code = VIRTIO_SND_R_JACK_REMAP */
+ le32 association;
+ le32 sequence;
+};
+\end{lstlisting}
+
+The request contains the following device-readable fields:
+
+\begin{description}
+\item[\field{association}] specifies the selected association number.
+\item[\field{sequence}] specifies the selected sequence number.
+\end{description}
+
+\subsubsection{Jack Notifications}
+
+Jack notifications consist of a virtio_snd_event structure, which has the
following
+device-writable fields:
+
+\begin{description}
+\item[\field{hdr}] indicates a jack event type:
+\begin{itemize}
+\item VIRTIO_SND_EVT_JACK_CONNECTED - an external device has been
connected to the jack.
+\item VIRTIO_SND_EVT_JACK_DISCONNECTED - an external device has been
disconnected from the jack.
+\end{itemize}
+\item[\field{data}] indicates a jack identifier from 0 to \field{jacks} -
1.
+\end{description}
+
+\subsubsection{PCM Control Messages}\label{sec:Device Types / Sound Device
/ Device Operation / PCM Control Messages}
+
+A PCM control request has, or consists of, a common header with the
following
+layout structure:
+
+\begin{lstlisting}
+struct virtio_snd_pcm_hdr {
+ struct virtio_snd_hdr hdr;
+ le32 stream_id;
+};
+\end{lstlisting}
+
+The header consists of the following device-readable fields:
+
+\begin{description}
+\item[\field{hdr}] specifies request type (VIRTIO_SND_R_PCM_*).
+\item[\field{stream_id}] specifies a PCM stream identifier from 0 to
\field{streams} - 1.
+\end{description}
+
+\paragraph{PCM Command Lifecycle}
+
+A PCM stream has the following command lifecycle:
+
+\begin{enumerate}
+\item SET PARAMETERS
+
+The driver negotiates the stream parameters (format, transport, etc) with
+the device.
+
+Possible valid transitions: set parameters, prepare.
+
+\item PREPARE
+
+The device prepares the stream (allocates resources, etc).
+
+Possible valid transitions: set parameters, prepare, start, release.
+
+\item Output only: the driver transfers data for pre-buffing.
+
+\item START
+
+The device starts the stream (unmute, putting into running state, etc).
+
+Possible valid transitions: stop.
+
+\item The driver transfers data to/from the stream.
+
+\item STOP
+
+The device stops the stream (mute, putting into non-running state, etc).
+
+Possible valid transitions: start, release.
+
+\item RELEASE
+
+The device releases the stream (frees resources, etc).
+
+Possible valid transitions: set parameters, prepare.
+
+\end{enumerate}
+
+\paragraph{VIRTIO_SND_R_PCM_INFO}
+
+Query information about the available streams.
+
+The request consists of the virtio_snd_query_info structure
+(see \nameref{sec:Device Types / Sound Device / Device Operation / Item
Information Request}).
+The response consists of the virtio_snd_hdr structure, followed by the
following
+stream information structures:
+
+\begin{lstlisting}
+/* supported PCM stream features */
+enum {
+ VIRTIO_SND_PCM_F_SHMEM_HOST = 0,
+ VIRTIO_SND_PCM_F_SHMEM_GUEST,
+ VIRTIO_SND_PCM_F_MSG_POLLING,
+ VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS,
+ VIRTIO_SND_PCM_F_EVT_XRUNS
+};
+
+/* supported PCM sample formats */
+enum {
+ /* analog formats (width / physical width) */
+ VIRTIO_SND_PCM_FMT_IMA_ADPCM = 0, /* 4 / 4 bits */
+ VIRTIO_SND_PCM_FMT_MU_LAW, /* 8 / 8 bits */
+ VIRTIO_SND_PCM_FMT_A_LAW, /* 8 / 8 bits */
+ VIRTIO_SND_PCM_FMT_S8, /* 8 / 8 bits */
+ VIRTIO_SND_PCM_FMT_U8, /* 8 / 8 bits */
+ VIRTIO_SND_PCM_FMT_S16, /* 16 / 16 bits */
+ VIRTIO_SND_PCM_FMT_U16, /* 16 / 16 bits */
+ VIRTIO_SND_PCM_FMT_S18_3, /* 18 / 24 bits */
+ VIRTIO_SND_PCM_FMT_U18_3, /* 18 / 24 bits */
+ VIRTIO_SND_PCM_FMT_S20_3, /* 20 / 24 bits */
+ VIRTIO_SND_PCM_FMT_U20_3, /* 20 / 24 bits */
+ VIRTIO_SND_PCM_FMT_S24_3, /* 24 / 24 bits */
+ VIRTIO_SND_PCM_FMT_U24_3, /* 24 / 24 bits */
+ VIRTIO_SND_PCM_FMT_S20, /* 20 / 32 bits */
+ VIRTIO_SND_PCM_FMT_U20, /* 20 / 32 bits */
+ VIRTIO_SND_PCM_FMT_S24, /* 24 / 32 bits */
+ VIRTIO_SND_PCM_FMT_U24, /* 24 / 32 bits */
+ VIRTIO_SND_PCM_FMT_S32, /* 32 / 32 bits */
+ VIRTIO_SND_PCM_FMT_U32, /* 32 / 32 bits */
+ VIRTIO_SND_PCM_FMT_FLOAT, /* 32 / 32 bits */
+ VIRTIO_SND_PCM_FMT_FLOAT64, /* 64 / 64 bits */
+ /* digital formats (width / physical width) */
+ VIRTIO_SND_PCM_FMT_DSD_U8, /* 8 / 8 bits */
+ VIRTIO_SND_PCM_FMT_DSD_U16, /* 16 / 16 bits */
+ VIRTIO_SND_PCM_FMT_DSD_U32, /* 32 / 32 bits */
+ VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME /* 32 / 32 bits */
+};
+
+/* supported PCM frame rates */
+enum {
+ VIRTIO_SND_PCM_RATE_5512 = 0,
+ VIRTIO_SND_PCM_RATE_8000,
+ VIRTIO_SND_PCM_RATE_11025,
+ VIRTIO_SND_PCM_RATE_16000,
+ VIRTIO_SND_PCM_RATE_22050,
+ VIRTIO_SND_PCM_RATE_32000,
+ VIRTIO_SND_PCM_RATE_44100,
+ VIRTIO_SND_PCM_RATE_48000,
+ VIRTIO_SND_PCM_RATE_64000,
+ VIRTIO_SND_PCM_RATE_88200,
+ VIRTIO_SND_PCM_RATE_96000,
+ VIRTIO_SND_PCM_RATE_176400,
+ VIRTIO_SND_PCM_RATE_192000,
+ VIRTIO_SND_PCM_RATE_384000
+};
+
+struct virtio_snd_pcm_info {
+ struct virtio_snd_info hdr;
+ le32 features; /* 1 << VIRTIO_SND_PCM_F_XXX */
+ le64 formats; /* 1 << VIRTIO_SND_PCM_FMT_XXX */
+ le64 rates; /* 1 << VIRTIO_SND_PCM_RATE_XXX */
+ u8 direction;
+ u8 channels_min;
+ u8 channels_max;
+
+ u8 padding[5];
+};
+\end{lstlisting}
+
+The structure contains the following device-writable fields:
+
+\begin{description}
+\item[\field{features}] indicates a bit map of the supported features,
which can
+be negotiated by setting the stream parameters:
+\begin{itemize}
+\item VIRTIO_SND_PCM_F_SHMEM_HOST - supports sharing a host memory with a
guest,
+\item VIRTIO_SND_PCM_F_SHMEM_GUEST - supports sharing a guest memory with
a host,
+\item VIRTIO_SND_PCM_F_MSG_POLLING - supports polling mode for
message-based
+transport,
+\item VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS - supports elapsed period
notifications
+for shared memory transport,
+\item VIRTIO_SND_PCM_F_EVT_XRUNS - supports underrun/overrun
notifications.
+\end{itemize}
+\item[\field{formats}] indicates a supported sample format bit map.
+\item[\field{rates}] indicates a supported frame rate bit map.
+\item[\field{direction}] indicates the direction of data flow
(VIRTIO_SND_D_*).
+\item[\field{channels_min}] indicates a minimum number of supported
channels.
+\item[\field{channels_max}] indicates a maximum number of supported
channels.
+\end{description}
+
+Only interleaved samples are supported.
+
+\devicenormative{\subparagraph}{Stream Information}{Device Types / Sound
Device / Device Operation / PCM Stream Information}
+
+\begin{itemize}
+\item The device MUST NOT set undefined feature, format, rate and
direction
+values.
+\item The device MUST initialize the \field{padding} bytes to 0.
+\end{itemize}
+
+\paragraph{VIRTIO_SND_R_PCM_SET_PARAMS}\label{sec:Device Types / Sound
Device / Device Operation / PCM Stream Parameters}
+
+Set selected stream parameters for the specified stream ID.
+
+The request uses the following structure and layout definitions:
+
+\begin{lstlisting}
+struct virtio_snd_pcm_set_params {
+ struct virtio_snd_pcm_hdr hdr; /* .code = VIRTIO_SND_R_PCM_SET_PARAMS
*/
+ le32 buffer_bytes;
+ le32 period_bytes;
+ le32 features; /* 1 << VIRTIO_SND_PCM_F_XXX */
+ u8 channels;
+ u8 format;
+ u8 rate;
+
+ u8 padding;
+};
+\end{lstlisting}
+
+The request contains the following device-readable fields:
+
+\begin{description}
+\item[\field{buffer_bytes}] specifies the size of the hardware buffer used
by
+the driver.
+\item[\field{period_bytes}] specifies the size of the hardware period used
by
+the driver.
+\item[\field{features}] specifies a selected feature bit map:
+\begin{itemize}
+\item VIRTIO_SND_PCM_F_SHMEM_HOST - use shared memory allocated by the
host
+(is a placeholder and MUST NOT be selected at the moment),
+\item VIRTIO_SND_PCM_F_SHMEM_GUEST - use shared memory allocated by the
guest
+(is a placeholder and MUST NOT be selected at the moment),
+\item VIRTIO_SND_PCM_F_MSG_POLLING - suppress available buffer
notifications
+for tx and rx queues (device should poll virtqueue),
+\item VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS - enable elapsed period
notifications
+for shared memory transport,
+\item VIRTIO_SND_PCM_F_EVT_XRUNS - enable underrun/overrun notifications.
+\end{itemize}
+\item[\field{channels}] specifies a selected number of channels.
+\item[\field{format}] specifies a selected sample format
(VIRTIO_SND_PCM_FMT_*).
+\item[\field{rate}] specifies a selected frame rate
(VIRTIO_SND_PCM_RATE_*).
+\end{description}
+
+\devicenormative{\subparagraph}{Stream Parameters}{Device Types / Sound
Device / Device Operation / PCM Stream Parameters}
+
+\begin{itemize}
+\item If the device has an intermediate buffer, its size MUST be no less
than
+the specified \field{buffer_bytes} value.
+\end{itemize}
+
+\drivernormative{\subparagraph}{Stream Parameters}{Device Types / Sound
Device / Device Operation / PCM Stream Parameters}
+
+\begin{itemize}
+\item \field{period_bytes} MUST be a divider \field{buffer_bytes}, i.e.
\field{buffer_bytes} \% \field{period_bytes} == 0.
+\item The driver MUST NOT set undefined feature, format and rate values.
+\item The driver MUST NOT set the feature, format, and rate that are not
specified
+in the stream configuration.
+\item The driver MUST NOT set the \field{channels} value as less than the
\field{channels_min}
+or greater than the \field{channels_max} values specified in the stream
configuration.
+\item The driver MUST NOT set the VIRTIO_SND_PCM_F_SHMEM_HOST and
VIRTIO_SND_PCM_F_SHMEM_GUEST
+bits at the same time.
+\item The driver MUST initialize the \field{padding} byte to 0.
+\item If the bits associated with the shared memory are not selected, the
driver
+MUST use the tx and rx queues for data transfer
+(see \nameref{sec:Device Types / Sound Device / Device Operation / PCM IO
Messages}).
+\end{itemize}
+
+\paragraph{VIRTIO_SND_R_PCM_PREPARE}
+
+Prepare a stream with specified stream ID.
+
+\paragraph{VIRTIO_SND_R_PCM_RELEASE}
+
+Release a stream with specified stream ID.
+
+\devicenormative{\subparagraph}{Stream Release}{Device Types / Sound
Device / Device Operation / PCM Stream Release}
+
+\begin{itemize}
+\item The device MUST complete all pending I/O messages for the specified
+stream ID.
+\item The device MUST NOT complete the control request while there are
pending
+I/O messages for the specified stream ID.
+\end{itemize}
+
+\paragraph{VIRTIO_SND_R_PCM_START}
+
+Start a stream with specified stream ID.
+
+\paragraph{VIRTIO_SND_R_PCM_STOP}
+
+Stop a stream with specified stream ID.
+
+\subsubsection{PCM Notifications}
+
+The device can announce support for different PCM events using feature
bits
+in the stream information structure. To enable notifications, the driver
+must negotiate these features using the set stream parameters request
+(see \ref{sec:Device Types / Sound Device / Device Operation / PCM Stream
Parameters}).
+
+PCM stream notifications consist of a virtio_snd_event structure, which
has the
+following device-writable fields:
+
+\begin{description}
+\item[\field{hdr}] indicates a PCM stream event type:
+\begin{itemize}
+\item VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED - a hardware buffer period has
elapsed,
+the period size is controlled using the \field{period_bytes} field.
+\item VIRTIO_SND_EVT_PCM_XRUN - an underflow for the output stream or an
overflow
+for the input stream has occurred.
+\end{itemize}
+\item[\field{data}] indicates a PCM stream identifier from 0 to
\field{streams} - 1.
+\end{description}
+
+\subsubsection{PCM I/O Messages}\label{sec:Device Types / Sound Device /
Device Operation / PCM IO Messages}
+
+An I/O message consists of the header part, followed by the buffer, and
then
+the status part.
+
+\begin{lstlisting}
+/* an I/O header */
+struct virtio_snd_pcm_xfer {
+ le32 stream_id;
+};
+
+/* an I/O status */
+struct virtio_snd_pcm_status {
+ le32 status;
+ le32 latency_bytes;
+};
+\end{lstlisting}
+
+The header part consists of the following device-readable field:
+
+\begin{description}
+\item[\field{stream_id}] specifies a PCM stream identifier from 0 to
\field{streams} - 1.
+\end{description}
+
+The status part consists of the following device-writable fields:
+
+\begin{description}
+\item[\field{status}] contains VIRTIO_SND_S_OK if an operation is
successful,
+and VIRTIO_SND_S_IO_ERR otherwise.
+\item[\field{latency_bytes}] indicates the current device latency.
+\end{description}
+
+Since all buffers in the queue (with one exception) should be of the size
+\field{period_bytes}, the completion of such an I/O request can be
considered an
+elapsed period notification.
+
+\paragraph{Output Stream}
+
+In case of an output stream, the header is followed by a device-readable
buffer
+containing PCM frames for writing to the device. All messages are placed
into
+the tx queue.
+
+\devicenormative{\subparagraph}{Output Stream}{Device Types / Sound Device
/ Device Operation / PCM Output Stream}
+
+\begin{itemize}
+\item The device MUST NOT complete the I/O request until the buffer is
totally
+consumed.
+\end{itemize}
+
+\drivernormative{\subparagraph}{Output Stream}{Device Types / Sound Device
/ Device Operation / PCM Output Stream}
+
+\begin{itemize}
+\item The driver SHOULD populate the tx queue with \field{period_bytes}
sized
+buffers. The only exception is the end of the stream.
+\item The driver MUST NOT place device-writable buffers into the tx queue.
+\end{itemize}
+
+\paragraph{Input Stream}
+
+In case of an input stream, the header is followed by a device-writable
buffer
+being populated with PCM frames from the device. All messages are placed
into
+the rx queue.
+
+A used descriptor specifies the length of the buffer that was written by
the
+device. It should be noted that the length value contains the size of the
+virtio_snd_pcm_status structure plus the size of the recorded frames.
+
+\devicenormative{\subparagraph}{Input Stream}{Device Types / Sound Device
/ Device Operation / PCM Input Stream}
+
+\begin{itemize}
+\item The device MUST NOT complete the I/O request until the buffer is
full.
+The only exception is the end of the stream.
+\end{itemize}
+
+\drivernormative{\subparagraph}{Input Stream}{Device Types / Sound Device
/ Device Operation / PCM Input Stream}
+
+\begin{itemize}
+\item The driver SHOULD populate the rx queue with \field{period_bytes}
sized
+empty buffers before starting the stream.
+\item The driver MUST NOT place device-readable buffers into the rx queue.
+\end{itemize}
+
+\subsubsection{Channel Map Control Messages}\label{sec:Device Types /
Sound Device / Device Operation / Channel Map Control Messages}
+
+A device can provide one or more channel maps assigned to all streams with
+the same data flow direction in the same function group.
+
+\paragraph{VIRTIO_SND_R_CHMAP_INFO}
+
+Query information about the available channel maps.
+
+The request consists of the virtio_snd_query_info structure
+(see \nameref{sec:Device Types / Sound Device / Device Operation / Item
Information Request}).
+The response consists of the virtio_snd_hdr structure, followed by the
following
+channel map information structures:
+
+\begin{lstlisting}
+/* standard channel position definition */
+enum {
+ VIRTIO_SND_CHMAP_NONE = 0, /* undefined */
+ VIRTIO_SND_CHMAP_NA, /* silent */
+ VIRTIO_SND_CHMAP_MONO, /* mono stream */
+ VIRTIO_SND_CHMAP_FL, /* front left */
+ VIRTIO_SND_CHMAP_FR, /* front right */
+ VIRTIO_SND_CHMAP_RL, /* rear left */
+ VIRTIO_SND_CHMAP_RR, /* rear right */
+ VIRTIO_SND_CHMAP_FC, /* front center */
+ VIRTIO_SND_CHMAP_LFE, /* low frequency (LFE) */
+ VIRTIO_SND_CHMAP_SL, /* side left */
+ VIRTIO_SND_CHMAP_SR, /* side right */
+ VIRTIO_SND_CHMAP_RC, /* rear center */
+ VIRTIO_SND_CHMAP_FLC, /* front left center */
+ VIRTIO_SND_CHMAP_FRC, /* front right center */
+ VIRTIO_SND_CHMAP_RLC, /* rear left center */
+ VIRTIO_SND_CHMAP_RRC, /* rear right center */
+ VIRTIO_SND_CHMAP_FLW, /* front left wide */
+ VIRTIO_SND_CHMAP_FRW, /* front right wide */
+ VIRTIO_SND_CHMAP_FLH, /* front left high */
+ VIRTIO_SND_CHMAP_FCH, /* front center high */
+ VIRTIO_SND_CHMAP_FRH, /* front right high */
+ VIRTIO_SND_CHMAP_TC, /* top center */
+ VIRTIO_SND_CHMAP_TFL, /* top front left */
+ VIRTIO_SND_CHMAP_TFR, /* top front right */
+ VIRTIO_SND_CHMAP_TFC, /* top front center */
+ VIRTIO_SND_CHMAP_TRL, /* top rear left */
+ VIRTIO_SND_CHMAP_TRR, /* top rear right */
+ VIRTIO_SND_CHMAP_TRC, /* top rear center */
+ VIRTIO_SND_CHMAP_TFLC, /* top front left center */
+ VIRTIO_SND_CHMAP_TFRC, /* top front right center */
+ VIRTIO_SND_CHMAP_TSL, /* top side left */
+ VIRTIO_SND_CHMAP_TSR, /* top side right */
+ VIRTIO_SND_CHMAP_LLFE, /* left LFE */
+ VIRTIO_SND_CHMAP_RLFE, /* right LFE */
+ VIRTIO_SND_CHMAP_BC, /* bottom center */
+ VIRTIO_SND_CHMAP_BLC, /* bottom left center */
+ VIRTIO_SND_CHMAP_BRC /* bottom right center */
+};
+
+/* maximum possible number of channels */
+#define VIRTIO_SND_CHMAP_MAX_SIZE 18
+
+struct virtio_snd_chmap_info {
+ struct virtio_snd_info hdr;
+ u8 direction;
+ u8 channels;
+ u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE];
+};
+\end{lstlisting}
+
+The structure contains the following device-writable fields:
+
+\begin{description}
+\item[\field{direction}] indicates the direction of data flow
(VIRTIO_SND_D_*).
+\item[\field{channels}] indicates the number of valid channel position
values.
+\item[\field{positions}] indicates channel position values
(VIRTIO_SND_CHMAP_*).
+\end{description}
+
+\devicenormative{\subparagraph}{Channel Map Information}{Device Types /
Sound Device / Device Operation / Channel Map Information}
+
+\begin{itemize}
+\item The device MUST NOT set undefined direction values.
+\item The device MUST NOT set the channels value to more than
VIRTIO_SND_CHMAP_MAX_SIZE.
+\end{itemize}