| // |
| // Copyright (C) 2020 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #pragma once |
| |
| #include <atomic> |
| #include <type_traits> |
| |
| #include "common/libs/utils/cf_endian.h" |
| |
| namespace cuttlefish { |
| // TODO (b/175151042): get these from the kernel headers when available |
| |
| enum class AudioCommandType : uint32_t { |
| /* 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, |
| }; |
| |
| enum class AudioStatus : uint32_t { |
| /* common status codes */ |
| VIRTIO_SND_S_OK = 0x8000, |
| VIRTIO_SND_S_BAD_MSG, |
| VIRTIO_SND_S_NOT_SUPP, |
| VIRTIO_SND_S_IO_ERR, |
| // Not a virtio constant, but it's only used internally as an invalid value so |
| // it's safe. |
| NOT_SET = static_cast<uint32_t>(-1), |
| }; |
| |
| enum class AudioStreamDirection : uint8_t { |
| VIRTIO_SND_D_OUTPUT = 0, |
| VIRTIO_SND_D_INPUT |
| }; |
| |
| enum class AudioStreamFormat : uint8_t { |
| /* 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 AudioStreamRate : uint8_t { |
| 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 |
| }; |
| |
| /* standard channel position definition */ |
| enum AudioChannelMap : uint8_t { |
| 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 */ |
| }; |
| |
| struct virtio_snd_hdr { |
| Le32 code; |
| }; |
| |
| struct virtio_snd_query_info { |
| struct virtio_snd_hdr hdr; |
| Le32 start_id; |
| Le32 count; |
| Le32 size; // unused |
| }; |
| |
| struct virtio_snd_info { |
| Le32 hda_fn_nid; |
| }; |
| |
| /* supported jack features */ |
| enum AudioJackFeatures: uint8_t { |
| 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; |
| uint8_t connected; |
| |
| uint8_t padding[7]; |
| }; |
| |
| constexpr uint8_t VIRTIO_SND_CHMAP_MAX_SIZE = 18; |
| struct virtio_snd_chmap_info { |
| struct virtio_snd_info hdr; |
| uint8_t direction; |
| uint8_t channels; |
| uint8_t positions[VIRTIO_SND_CHMAP_MAX_SIZE]; |
| }; |
| |
| 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 */ |
| uint8_t direction; |
| uint8_t channels_min; |
| uint8_t channels_max; |
| |
| uint8_t padding[5]; |
| }; |
| |
| struct virtio_snd_pcm_hdr { |
| struct virtio_snd_hdr hdr; |
| Le32 stream_id; |
| }; |
| |
| struct virtio_snd_pcm_set_params { |
| struct virtio_snd_pcm_hdr hdr; |
| Le32 buffer_bytes; |
| Le32 period_bytes; |
| Le32 features; /* 1 << VIRTIO_SND_PCM_F_XXX */ |
| uint8_t channels; |
| uint8_t format; |
| uint8_t rate; |
| uint8_t padding; |
| }; |
| |
| struct virtio_snd_pcm_xfer { |
| Le32 stream_id; |
| }; |
| |
| struct virtio_snd_pcm_status { |
| Le32 status; |
| Le32 latency_bytes; |
| }; |
| |
| // Update this value when the msg layouts change |
| const uint32_t VIOS_VERSION = 2; |
| |
| struct VioSConfig { |
| uint32_t version; |
| uint32_t jacks; |
| uint32_t streams; |
| uint32_t chmaps; |
| }; |
| |
| struct IoTransferMsg { |
| virtio_snd_pcm_xfer io_xfer; |
| uint32_t buffer_offset; |
| uint32_t buffer_len; |
| }; |
| |
| struct IoStatusMsg { |
| virtio_snd_pcm_status status; |
| uint32_t buffer_offset; |
| uint32_t consumed_length; |
| }; |
| |
| // Ensure all message structs have predictable sizes |
| #define ASSERT_VALID_MSG_TYPE(T, size) \ |
| static_assert(sizeof(T) == (size), #T " has the wrong size") |
| ASSERT_VALID_MSG_TYPE(virtio_snd_query_info, 16); |
| ASSERT_VALID_MSG_TYPE(virtio_snd_jack_info, 24); |
| ASSERT_VALID_MSG_TYPE(virtio_snd_chmap_info, 24); |
| ASSERT_VALID_MSG_TYPE(virtio_snd_pcm_info, 32); |
| ASSERT_VALID_MSG_TYPE(virtio_snd_pcm_set_params, 24); |
| ASSERT_VALID_MSG_TYPE(virtio_snd_pcm_hdr, 8); |
| ASSERT_VALID_MSG_TYPE(IoTransferMsg, 12); |
| ASSERT_VALID_MSG_TYPE(IoStatusMsg, 16); |
| #undef ASSERT_VALID_MSG_TYPE |
| |
| } // namespace cuttlefish |