devices/virtio/snd/
layout.rs

1// Copyright 2020 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use data_model::Le32;
6use data_model::Le64;
7use serde::Deserialize;
8use serde::Serialize;
9use zerocopy::FromBytes;
10use zerocopy::Immutable;
11use zerocopy::IntoBytes;
12use zerocopy::KnownLayout;
13
14use crate::virtio::snd::constants::StatusCode;
15use crate::virtio::snd::constants::VIRTIO_SND_CHMAP_MAX_SIZE;
16
17#[derive(
18    Copy, Clone, Default, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize, Deserialize,
19)]
20#[repr(C)]
21pub struct virtio_snd_hdr {
22    pub code: Le32,
23}
24
25#[derive(Copy, Clone, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
26#[repr(C)]
27pub struct virtio_snd_jack_hdr {
28    pub hdr: virtio_snd_hdr,
29    pub jack_id: Le32,
30}
31
32#[derive(Copy, Clone, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
33#[repr(C)]
34pub struct virtio_snd_event {
35    pub hdr: virtio_snd_hdr,
36    pub data: Le32,
37}
38
39#[derive(Copy, Clone, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
40#[repr(C)]
41pub struct virtio_snd_query_info {
42    pub hdr: virtio_snd_hdr,
43    pub start_id: Le32,
44    pub count: Le32,
45    pub size: Le32,
46}
47
48#[derive(
49    Copy,
50    Clone,
51    Default,
52    FromBytes,
53    Immutable,
54    IntoBytes,
55    KnownLayout,
56    Serialize,
57    Deserialize,
58    PartialEq,
59    Eq,
60    Debug,
61)]
62#[repr(C)]
63pub struct virtio_snd_info {
64    pub hda_fn_nid: Le32,
65}
66
67#[derive(
68    Copy,
69    Clone,
70    Default,
71    FromBytes,
72    Immutable,
73    IntoBytes,
74    KnownLayout,
75    Serialize,
76    Deserialize,
77    PartialEq,
78    Eq,
79    Debug,
80)]
81#[repr(C)]
82pub struct virtio_snd_pcm_info {
83    pub hdr: virtio_snd_info,
84    pub features: Le32, /* 1 << VIRTIO_SND_PCM_F_XXX */
85    pub formats: Le64,  /* 1 << VIRTIO_SND_PCM_FMT_XXX */
86    pub rates: Le64,    /* 1 << VIRTIO_SND_PCM_RATE_XXX */
87    pub direction: u8,
88    pub channels_min: u8,
89    pub channels_max: u8,
90
91    pub padding: [u8; 5],
92}
93
94#[derive(
95    Copy, Clone, Default, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize, Deserialize,
96)]
97#[repr(C)]
98pub struct virtio_snd_pcm_hdr {
99    pub hdr: virtio_snd_hdr,
100    pub stream_id: Le32,
101}
102
103#[derive(
104    Copy, Clone, Default, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize, Deserialize,
105)]
106#[repr(C)]
107pub struct virtio_snd_pcm_set_params {
108    pub hdr: virtio_snd_pcm_hdr,
109    pub buffer_bytes: Le32,
110    pub period_bytes: Le32,
111    pub features: Le32, /* 1 << VIRTIO_SND_PCM_F_XXX */
112    pub channels: u8,
113    pub format: u8,
114    pub rate: u8,
115    pub padding: u8,
116}
117
118#[derive(Copy, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
119#[repr(C)]
120pub struct virtio_snd_pcm_xfer {
121    pub stream_id: Le32,
122}
123
124#[derive(Copy, Clone, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
125#[repr(C)]
126pub struct virtio_snd_pcm_status {
127    pub status: Le32,
128    pub latency_bytes: Le32,
129}
130
131impl virtio_snd_pcm_status {
132    pub fn new(status: StatusCode, latency_bytes: u32) -> Self {
133        Self {
134            status: Le32::from(status as u32),
135            latency_bytes: Le32::from(latency_bytes),
136        }
137    }
138}
139
140#[derive(
141    Copy,
142    Clone,
143    Default,
144    FromBytes,
145    Immutable,
146    IntoBytes,
147    KnownLayout,
148    Serialize,
149    Deserialize,
150    PartialEq,
151    Eq,
152    Debug,
153)]
154#[repr(C)]
155pub struct virtio_snd_jack_info {
156    pub hdr: virtio_snd_info,
157    pub features: Le32, /* 1 << VIRTIO_SND_JACK_F_XXX */
158    pub hda_reg_defconf: Le32,
159    pub hda_reg_caps: Le32,
160    pub connected: u8,
161    pub padding: [u8; 7],
162}
163
164#[derive(Copy, Clone, Default, FromBytes, Immutable, IntoBytes, KnownLayout)]
165#[repr(C)]
166pub struct virtio_snd_jack_remap {
167    pub hdr: virtio_snd_jack_hdr, /* .code = VIRTIO_SND_R_JACK_REMAP */
168    pub association: Le32,
169    pub sequence: Le32,
170}
171
172#[derive(
173    Copy,
174    Clone,
175    Default,
176    FromBytes,
177    Immutable,
178    IntoBytes,
179    KnownLayout,
180    Serialize,
181    Deserialize,
182    PartialEq,
183    Eq,
184    Debug,
185)]
186#[repr(C)]
187pub struct virtio_snd_chmap_info {
188    pub hdr: virtio_snd_info,
189    pub direction: u8,
190    pub channels: u8,
191    pub positions: [u8; VIRTIO_SND_CHMAP_MAX_SIZE],
192}
193
194#[derive(Copy, Clone, Default, Immutable, IntoBytes, FromBytes, KnownLayout)]
195#[repr(C)]
196pub struct virtio_snd_ctl_hdr {
197    pub hdr: virtio_snd_hdr,
198    pub control_id: Le32,
199}
200
201#[derive(Copy, Clone, Immutable, FromBytes, IntoBytes, KnownLayout)]
202#[repr(C)]
203pub struct virtio_snd_ctl_info_value_integer64 {
204    pub min: Le64,
205    pub max: Le64,
206    pub step: Le64,
207}
208
209#[derive(Copy, Clone, Immutable, FromBytes, IntoBytes, KnownLayout)]
210#[repr(C)]
211pub struct virtio_snd_ctl_info_value_integer32 {
212    pub min: Le32,
213    pub max: Le32,
214    pub step: Le32,
215    _padding: [u8; 12],
216}
217
218#[derive(Copy, Clone, Immutable, FromBytes, IntoBytes, KnownLayout)]
219#[repr(C)]
220pub struct virtio_snd_ctl_info_value_enumerated {
221    pub items: Le32,
222    _padding: [u8; 20],
223}
224
225#[derive(Copy, Clone, Immutable, FromBytes, IntoBytes, KnownLayout)]
226#[repr(C)]
227pub union virtio_snd_ctl_info_value_union {
228    integer64: virtio_snd_ctl_info_value_integer64,
229    integer: virtio_snd_ctl_info_value_integer32,
230    enumerated: virtio_snd_ctl_info_value_enumerated,
231}
232
233pub mod union_serde {
234    use serde::Deserialize;
235    use serde::Deserializer;
236    use serde::Serializer;
237
238    use super::*;
239
240    pub fn serialize<S>(val: &virtio_snd_ctl_info_value_union, s: S) -> Result<S::Ok, S::Error>
241    where
242        S: Serializer,
243    {
244        let bytes = val.as_bytes();
245        s.serialize_bytes(bytes)
246    }
247
248    pub fn deserialize<'de, D>(d: D) -> Result<virtio_snd_ctl_info_value_union, D::Error>
249    where
250        D: Deserializer<'de>,
251    {
252        let bytes: Vec<u8> = Vec::deserialize(d)?;
253        virtio_snd_ctl_info_value_union::read_from_bytes(&bytes)
254            .map_err(|e| serde::de::Error::custom(format!("Failed to read from bytes: {e}")))
255    }
256}
257
258#[derive(Copy, Clone, Immutable, KnownLayout, IntoBytes, FromBytes, Serialize, Deserialize)]
259#[repr(C)]
260pub struct virtio_snd_ctl_info {
261    pub hdr: virtio_snd_info,
262    pub role: Le32,
263    pub type_: Le32,
264    pub access: Le32, /* 1 << VIRTIO_SND_CTL_ACCESS_XXX */
265    pub count: Le32,
266    pub index: Le32,
267    #[serde(with = "serde_bytes")]
268    pub name: [u8; 44],
269    _padding: [u8; 4],
270    #[serde(with = "union_serde")]
271    pub value: virtio_snd_ctl_info_value_union,
272}
273
274impl Default for virtio_snd_ctl_info {
275    fn default() -> Self {
276        Self {
277            hdr: Default::default(),
278            role: Default::default(),
279            type_: Default::default(),
280            access: Default::default(),
281            count: Default::default(),
282            index: Default::default(),
283            name: [0; 44],
284            _padding: [0; 4],
285            value: virtio_snd_ctl_info_value_union {
286                integer64: virtio_snd_ctl_info_value_integer64 {
287                    min: Le64::from(0),
288                    max: Le64::from(0),
289                    step: Le64::from(0),
290                },
291            },
292        }
293    }
294}
295
296#[derive(Copy, Clone, Immutable, IntoBytes, FromBytes, KnownLayout)]
297#[repr(C)]
298pub union virtio_snd_ctl_value_union {
299    pub integer: [Le32; 128],
300    pub integer64: [Le64; 64],
301    pub enumerated: [Le32; 128],
302    pub bytes: [u8; 512],
303    // TODO: virtio_snd_ctl_iec958
304}
305
306// Manually implement Default for the union
307impl Default for virtio_snd_ctl_value_union {
308    fn default() -> Self {
309        Self {
310            integer64: [Le64::default(); 64],
311        }
312    }
313}
314
315#[derive(Copy, Clone, Immutable, Default, IntoBytes, FromBytes, KnownLayout)]
316#[repr(C)]
317pub struct virtio_snd_ctl_value {
318    pub value: virtio_snd_ctl_value_union,
319}