1/* SPDX-License-Identifier: BSD-3-Clause */ 2/* 3 * Copyright (C) 2021 OpenSynergy GmbH 4 */ 5#ifndef VIRTIO_SND_IF_H 6#define VIRTIO_SND_IF_H 7 8#include <linux/virtio_types.h> 9 10/******************************************************************************* 11 * FEATURE BITS 12 */ 13enum { 14 /* device supports control elements */ 15 VIRTIO_SND_F_CTLS = 0 16}; 17 18/******************************************************************************* 19 * CONFIGURATION SPACE 20 */ 21struct virtio_snd_config { 22 /* # of available physical jacks */ 23 __le32 jacks; 24 /* # of available PCM streams */ 25 __le32 streams; 26 /* # of available channel maps */ 27 __le32 chmaps; 28 /* # of available control elements */ 29 __le32 controls; 30}; 31 32enum { 33 /* device virtqueue indexes */ 34 VIRTIO_SND_VQ_CONTROL = 0, 35 VIRTIO_SND_VQ_EVENT, 36 VIRTIO_SND_VQ_TX, 37 VIRTIO_SND_VQ_RX, 38 /* # of device virtqueues */ 39 VIRTIO_SND_VQ_MAX 40}; 41 42/******************************************************************************* 43 * COMMON DEFINITIONS 44 */ 45 46/* supported dataflow directions */ 47enum { 48 VIRTIO_SND_D_OUTPUT = 0, 49 VIRTIO_SND_D_INPUT 50}; 51 52enum { 53 /* jack control request types */ 54 VIRTIO_SND_R_JACK_INFO = 1, 55 VIRTIO_SND_R_JACK_REMAP, 56 57 /* PCM control request types */ 58 VIRTIO_SND_R_PCM_INFO = 0x0100, 59 VIRTIO_SND_R_PCM_SET_PARAMS, 60 VIRTIO_SND_R_PCM_PREPARE, 61 VIRTIO_SND_R_PCM_RELEASE, 62 VIRTIO_SND_R_PCM_START, 63 VIRTIO_SND_R_PCM_STOP, 64 65 /* channel map control request types */ 66 VIRTIO_SND_R_CHMAP_INFO = 0x0200, 67 68 /* control element request types */ 69 VIRTIO_SND_R_CTL_INFO = 0x0300, 70 VIRTIO_SND_R_CTL_ENUM_ITEMS, 71 VIRTIO_SND_R_CTL_READ, 72 VIRTIO_SND_R_CTL_WRITE, 73 VIRTIO_SND_R_CTL_TLV_READ, 74 VIRTIO_SND_R_CTL_TLV_WRITE, 75 VIRTIO_SND_R_CTL_TLV_COMMAND, 76 77 /* jack event types */ 78 VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000, 79 VIRTIO_SND_EVT_JACK_DISCONNECTED, 80 81 /* PCM event types */ 82 VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100, 83 VIRTIO_SND_EVT_PCM_XRUN, 84 85 /* control element event types */ 86 VIRTIO_SND_EVT_CTL_NOTIFY = 0x1200, 87 88 /* common status codes */ 89 VIRTIO_SND_S_OK = 0x8000, 90 VIRTIO_SND_S_BAD_MSG, 91 VIRTIO_SND_S_NOT_SUPP, 92 VIRTIO_SND_S_IO_ERR 93}; 94 95/* common header */ 96struct virtio_snd_hdr { 97 __le32 code; 98}; 99 100/* event notification */ 101struct virtio_snd_event { 102 /* VIRTIO_SND_EVT_XXX */ 103 struct virtio_snd_hdr hdr; 104 /* optional event data */ 105 __le32 data; 106}; 107 108/* common control request to query an item information */ 109struct virtio_snd_query_info { 110 /* VIRTIO_SND_R_XXX_INFO */ 111 struct virtio_snd_hdr hdr; 112 /* item start identifier */ 113 __le32 start_id; 114 /* item count to query */ 115 __le32 count; 116 /* item information size in bytes */ 117 __le32 size; 118}; 119 120/* common item information header */ 121struct virtio_snd_info { 122 /* function group node id (High Definition Audio Specification 7.1.2) */ 123 __le32 hda_fn_nid; 124}; 125 126/******************************************************************************* 127 * JACK CONTROL MESSAGES 128 */ 129struct virtio_snd_jack_hdr { 130 /* VIRTIO_SND_R_JACK_XXX */ 131 struct virtio_snd_hdr hdr; 132 /* 0 ... virtio_snd_config::jacks - 1 */ 133 __le32 jack_id; 134}; 135 136/* supported jack features */ 137enum { 138 VIRTIO_SND_JACK_F_REMAP = 0 139}; 140 141struct virtio_snd_jack_info { 142 /* common header */ 143 struct virtio_snd_info hdr; 144 /* supported feature bit map (1 << VIRTIO_SND_JACK_F_XXX) */ 145 __le32 features; 146 /* pin configuration (High Definition Audio Specification 7.3.3.31) */ 147 __le32 hda_reg_defconf; 148 /* pin capabilities (High Definition Audio Specification 7.3.4.9) */ 149 __le32 hda_reg_caps; 150 /* current jack connection status (0: disconnected, 1: connected) */ 151 __u8 connected; 152 153 __u8 padding[7]; 154}; 155 156/* jack remapping control request */ 157struct virtio_snd_jack_remap { 158 /* .code = VIRTIO_SND_R_JACK_REMAP */ 159 struct virtio_snd_jack_hdr hdr; 160 /* selected association number */ 161 __le32 association; 162 /* selected sequence number */ 163 __le32 sequence; 164}; 165 166/******************************************************************************* 167 * PCM CONTROL MESSAGES 168 */ 169struct virtio_snd_pcm_hdr { 170 /* VIRTIO_SND_R_PCM_XXX */ 171 struct virtio_snd_hdr hdr; 172 /* 0 ... virtio_snd_config::streams - 1 */ 173 __le32 stream_id; 174}; 175 176/* supported PCM stream features */ 177enum { 178 VIRTIO_SND_PCM_F_SHMEM_HOST = 0, 179 VIRTIO_SND_PCM_F_SHMEM_GUEST, 180 VIRTIO_SND_PCM_F_MSG_POLLING, 181 VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS, 182 VIRTIO_SND_PCM_F_EVT_XRUNS 183}; 184 185/* supported PCM sample formats */ 186enum { 187 /* analog formats (width / physical width) */ 188 VIRTIO_SND_PCM_FMT_IMA_ADPCM = 0, /* 4 / 4 bits */ 189 VIRTIO_SND_PCM_FMT_MU_LAW, /* 8 / 8 bits */ 190 VIRTIO_SND_PCM_FMT_A_LAW, /* 8 / 8 bits */ 191 VIRTIO_SND_PCM_FMT_S8, /* 8 / 8 bits */ 192 VIRTIO_SND_PCM_FMT_U8, /* 8 / 8 bits */ 193 VIRTIO_SND_PCM_FMT_S16, /* 16 / 16 bits */ 194 VIRTIO_SND_PCM_FMT_U16, /* 16 / 16 bits */ 195 VIRTIO_SND_PCM_FMT_S18_3, /* 18 / 24 bits */ 196 VIRTIO_SND_PCM_FMT_U18_3, /* 18 / 24 bits */ 197 VIRTIO_SND_PCM_FMT_S20_3, /* 20 / 24 bits */ 198 VIRTIO_SND_PCM_FMT_U20_3, /* 20 / 24 bits */ 199 VIRTIO_SND_PCM_FMT_S24_3, /* 24 / 24 bits */ 200 VIRTIO_SND_PCM_FMT_U24_3, /* 24 / 24 bits */ 201 VIRTIO_SND_PCM_FMT_S20, /* 20 / 32 bits */ 202 VIRTIO_SND_PCM_FMT_U20, /* 20 / 32 bits */ 203 VIRTIO_SND_PCM_FMT_S24, /* 24 / 32 bits */ 204 VIRTIO_SND_PCM_FMT_U24, /* 24 / 32 bits */ 205 VIRTIO_SND_PCM_FMT_S32, /* 32 / 32 bits */ 206 VIRTIO_SND_PCM_FMT_U32, /* 32 / 32 bits */ 207 VIRTIO_SND_PCM_FMT_FLOAT, /* 32 / 32 bits */ 208 VIRTIO_SND_PCM_FMT_FLOAT64, /* 64 / 64 bits */ 209 /* digital formats (width / physical width) */ 210 VIRTIO_SND_PCM_FMT_DSD_U8, /* 8 / 8 bits */ 211 VIRTIO_SND_PCM_FMT_DSD_U16, /* 16 / 16 bits */ 212 VIRTIO_SND_PCM_FMT_DSD_U32, /* 32 / 32 bits */ 213 VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME /* 32 / 32 bits */ 214}; 215 216/* supported PCM frame rates */ 217enum { 218 VIRTIO_SND_PCM_RATE_5512 = 0, 219 VIRTIO_SND_PCM_RATE_8000, 220 VIRTIO_SND_PCM_RATE_11025, 221 VIRTIO_SND_PCM_RATE_16000, 222 VIRTIO_SND_PCM_RATE_22050, 223 VIRTIO_SND_PCM_RATE_32000, 224 VIRTIO_SND_PCM_RATE_44100, 225 VIRTIO_SND_PCM_RATE_48000, 226 VIRTIO_SND_PCM_RATE_64000, 227 VIRTIO_SND_PCM_RATE_88200, 228 VIRTIO_SND_PCM_RATE_96000, 229 VIRTIO_SND_PCM_RATE_176400, 230 VIRTIO_SND_PCM_RATE_192000, 231 VIRTIO_SND_PCM_RATE_384000 232}; 233 234struct virtio_snd_pcm_info { 235 /* common header */ 236 struct virtio_snd_info hdr; 237 /* supported feature bit map (1 << VIRTIO_SND_PCM_F_XXX) */ 238 __le32 features; 239 /* supported sample format bit map (1 << VIRTIO_SND_PCM_FMT_XXX) */ 240 __le64 formats; 241 /* supported frame rate bit map (1 << VIRTIO_SND_PCM_RATE_XXX) */ 242 __le64 rates; 243 /* dataflow direction (VIRTIO_SND_D_XXX) */ 244 __u8 direction; 245 /* minimum # of supported channels */ 246 __u8 channels_min; 247 /* maximum # of supported channels */ 248 __u8 channels_max; 249 250 __u8 padding[5]; 251}; 252 253/* set PCM stream format */ 254struct virtio_snd_pcm_set_params { 255 /* .code = VIRTIO_SND_R_PCM_SET_PARAMS */ 256 struct virtio_snd_pcm_hdr hdr; 257 /* size of the hardware buffer */ 258 __le32 buffer_bytes; 259 /* size of the hardware period */ 260 __le32 period_bytes; 261 /* selected feature bit map (1 << VIRTIO_SND_PCM_F_XXX) */ 262 __le32 features; 263 /* selected # of channels */ 264 __u8 channels; 265 /* selected sample format (VIRTIO_SND_PCM_FMT_XXX) */ 266 __u8 format; 267 /* selected frame rate (VIRTIO_SND_PCM_RATE_XXX) */ 268 __u8 rate; 269 270 __u8 padding; 271}; 272 273/******************************************************************************* 274 * PCM I/O MESSAGES 275 */ 276 277/* I/O request header */ 278struct virtio_snd_pcm_xfer { 279 /* 0 ... virtio_snd_config::streams - 1 */ 280 __le32 stream_id; 281}; 282 283/* I/O request status */ 284struct virtio_snd_pcm_status { 285 /* VIRTIO_SND_S_XXX */ 286 __le32 status; 287 /* current device latency */ 288 __le32 latency_bytes; 289}; 290 291/******************************************************************************* 292 * CHANNEL MAP CONTROL MESSAGES 293 */ 294struct virtio_snd_chmap_hdr { 295 /* VIRTIO_SND_R_CHMAP_XXX */ 296 struct virtio_snd_hdr hdr; 297 /* 0 ... virtio_snd_config::chmaps - 1 */ 298 __le32 chmap_id; 299}; 300 301/* standard channel position definition */ 302enum { 303 VIRTIO_SND_CHMAP_NONE = 0, /* undefined */ 304 VIRTIO_SND_CHMAP_NA, /* silent */ 305 VIRTIO_SND_CHMAP_MONO, /* mono stream */ 306 VIRTIO_SND_CHMAP_FL, /* front left */ 307 VIRTIO_SND_CHMAP_FR, /* front right */ 308 VIRTIO_SND_CHMAP_RL, /* rear left */ 309 VIRTIO_SND_CHMAP_RR, /* rear right */ 310 VIRTIO_SND_CHMAP_FC, /* front center */ 311 VIRTIO_SND_CHMAP_LFE, /* low frequency (LFE) */ 312 VIRTIO_SND_CHMAP_SL, /* side left */ 313 VIRTIO_SND_CHMAP_SR, /* side right */ 314 VIRTIO_SND_CHMAP_RC, /* rear center */ 315 VIRTIO_SND_CHMAP_FLC, /* front left center */ 316 VIRTIO_SND_CHMAP_FRC, /* front right center */ 317 VIRTIO_SND_CHMAP_RLC, /* rear left center */ 318 VIRTIO_SND_CHMAP_RRC, /* rear right center */ 319 VIRTIO_SND_CHMAP_FLW, /* front left wide */ 320 VIRTIO_SND_CHMAP_FRW, /* front right wide */ 321 VIRTIO_SND_CHMAP_FLH, /* front left high */ 322 VIRTIO_SND_CHMAP_FCH, /* front center high */ 323 VIRTIO_SND_CHMAP_FRH, /* front right high */ 324 VIRTIO_SND_CHMAP_TC, /* top center */ 325 VIRTIO_SND_CHMAP_TFL, /* top front left */ 326 VIRTIO_SND_CHMAP_TFR, /* top front right */ 327 VIRTIO_SND_CHMAP_TFC, /* top front center */ 328 VIRTIO_SND_CHMAP_TRL, /* top rear left */ 329 VIRTIO_SND_CHMAP_TRR, /* top rear right */ 330 VIRTIO_SND_CHMAP_TRC, /* top rear center */ 331 VIRTIO_SND_CHMAP_TFLC, /* top front left center */ 332 VIRTIO_SND_CHMAP_TFRC, /* top front right center */ 333 VIRTIO_SND_CHMAP_TSL, /* top side left */ 334 VIRTIO_SND_CHMAP_TSR, /* top side right */ 335 VIRTIO_SND_CHMAP_LLFE, /* left LFE */ 336 VIRTIO_SND_CHMAP_RLFE, /* right LFE */ 337 VIRTIO_SND_CHMAP_BC, /* bottom center */ 338 VIRTIO_SND_CHMAP_BLC, /* bottom left center */ 339 VIRTIO_SND_CHMAP_BRC /* bottom right center */ 340}; 341 342/* maximum possible number of channels */ 343#define VIRTIO_SND_CHMAP_MAX_SIZE 18 344 345struct virtio_snd_chmap_info { 346 /* common header */ 347 struct virtio_snd_info hdr; 348 /* dataflow direction (VIRTIO_SND_D_XXX) */ 349 __u8 direction; 350 /* # of valid channel position values */ 351 __u8 channels; 352 /* channel position values (VIRTIO_SND_CHMAP_XXX) */ 353 __u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE]; 354}; 355 356/******************************************************************************* 357 * CONTROL ELEMENTS MESSAGES 358 */ 359struct virtio_snd_ctl_hdr { 360 /* VIRTIO_SND_R_CTL_XXX */ 361 struct virtio_snd_hdr hdr; 362 /* 0 ... virtio_snd_config::controls - 1 */ 363 __le32 control_id; 364}; 365 366/* supported roles for control elements */ 367enum { 368 VIRTIO_SND_CTL_ROLE_UNDEFINED = 0, 369 VIRTIO_SND_CTL_ROLE_VOLUME, 370 VIRTIO_SND_CTL_ROLE_MUTE, 371 VIRTIO_SND_CTL_ROLE_GAIN 372}; 373 374/* supported value types for control elements */ 375enum { 376 VIRTIO_SND_CTL_TYPE_BOOLEAN = 0, 377 VIRTIO_SND_CTL_TYPE_INTEGER, 378 VIRTIO_SND_CTL_TYPE_INTEGER64, 379 VIRTIO_SND_CTL_TYPE_ENUMERATED, 380 VIRTIO_SND_CTL_TYPE_BYTES, 381 VIRTIO_SND_CTL_TYPE_IEC958 382}; 383 384/* supported access rights for control elements */ 385enum { 386 VIRTIO_SND_CTL_ACCESS_READ = 0, 387 VIRTIO_SND_CTL_ACCESS_WRITE, 388 VIRTIO_SND_CTL_ACCESS_VOLATILE, 389 VIRTIO_SND_CTL_ACCESS_INACTIVE, 390 VIRTIO_SND_CTL_ACCESS_TLV_READ, 391 VIRTIO_SND_CTL_ACCESS_TLV_WRITE, 392 VIRTIO_SND_CTL_ACCESS_TLV_COMMAND 393}; 394 395struct virtio_snd_ctl_info { 396 /* common header */ 397 struct virtio_snd_info hdr; 398 /* element role (VIRTIO_SND_CTL_ROLE_XXX) */ 399 __le32 role; 400 /* element value type (VIRTIO_SND_CTL_TYPE_XXX) */ 401 __le32 type; 402 /* element access right bit map (1 << VIRTIO_SND_CTL_ACCESS_XXX) */ 403 __le32 access; 404 /* # of members in the element value */ 405 __le32 count; 406 /* index for an element with a non-unique name */ 407 __le32 index; 408 /* name identifier string for the element */ 409 __u8 name[44]; 410 /* additional information about the element's value */ 411 union { 412 /* VIRTIO_SND_CTL_TYPE_INTEGER */ 413 struct { 414 /* minimum supported value */ 415 __le32 min; 416 /* maximum supported value */ 417 __le32 max; 418 /* fixed step size for value (0 = variable size) */ 419 __le32 step; 420 } integer; 421 /* VIRTIO_SND_CTL_TYPE_INTEGER64 */ 422 struct { 423 /* minimum supported value */ 424 __le64 min; 425 /* maximum supported value */ 426 __le64 max; 427 /* fixed step size for value (0 = variable size) */ 428 __le64 step; 429 } integer64; 430 /* VIRTIO_SND_CTL_TYPE_ENUMERATED */ 431 struct { 432 /* # of options supported for value */ 433 __le32 items; 434 } enumerated; 435 } value; 436}; 437 438struct virtio_snd_ctl_enum_item { 439 /* option name */ 440 __u8 item[64]; 441}; 442 443struct virtio_snd_ctl_iec958 { 444 /* AES/IEC958 channel status bits */ 445 __u8 status[24]; 446 /* AES/IEC958 subcode bits */ 447 __u8 subcode[147]; 448 /* nothing */ 449 __u8 pad; 450 /* AES/IEC958 subframe bits */ 451 __u8 dig_subframe[4]; 452}; 453 454struct virtio_snd_ctl_value { 455 union { 456 /* VIRTIO_SND_CTL_TYPE_BOOLEAN|INTEGER value */ 457 __le32 integer[128]; 458 /* VIRTIO_SND_CTL_TYPE_INTEGER64 value */ 459 __le64 integer64[64]; 460 /* VIRTIO_SND_CTL_TYPE_ENUMERATED value (option indexes) */ 461 __le32 enumerated[128]; 462 /* VIRTIO_SND_CTL_TYPE_BYTES value */ 463 __u8 bytes[512]; 464 /* VIRTIO_SND_CTL_TYPE_IEC958 value */ 465 struct virtio_snd_ctl_iec958 iec958; 466 } value; 467}; 468 469/* supported event reason types */ 470enum { 471 /* element's value has changed */ 472 VIRTIO_SND_CTL_EVT_MASK_VALUE = 0, 473 /* element's information has changed */ 474 VIRTIO_SND_CTL_EVT_MASK_INFO, 475 /* element's metadata has changed */ 476 VIRTIO_SND_CTL_EVT_MASK_TLV 477}; 478 479struct virtio_snd_ctl_event { 480 /* VIRTIO_SND_EVT_CTL_NOTIFY */ 481 struct virtio_snd_hdr hdr; 482 /* 0 ... virtio_snd_config::controls - 1 */ 483 __le16 control_id; 484 /* event reason bit map (1 << VIRTIO_SND_CTL_EVT_MASK_XXX) */ 485 __le16 mask; 486}; 487 488#endif /* VIRTIO_SND_IF_H */ 489