1 // 2 // Copyright (C) 2020 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 #pragma once 17 18 #include <atomic> 19 #include <type_traits> 20 21 #include "common/libs/utils/cf_endian.h" 22 23 namespace cuttlefish { 24 // TODO (b/175151042): get these from the kernel headers when available 25 26 enum class AudioCommandType : uint32_t { 27 /* jack control request types */ 28 VIRTIO_SND_R_JACK_INFO = 1, 29 VIRTIO_SND_R_JACK_REMAP, 30 31 /* PCM control request types */ 32 VIRTIO_SND_R_PCM_INFO = 0x0100, 33 VIRTIO_SND_R_PCM_SET_PARAMS, 34 VIRTIO_SND_R_PCM_PREPARE, 35 VIRTIO_SND_R_PCM_RELEASE, 36 VIRTIO_SND_R_PCM_START, 37 VIRTIO_SND_R_PCM_STOP, 38 39 /* channel map control request types */ 40 VIRTIO_SND_R_CHMAP_INFO = 0x0200, 41 }; 42 43 enum class AudioStatus : uint32_t { 44 /* common status codes */ 45 VIRTIO_SND_S_OK = 0x8000, 46 VIRTIO_SND_S_BAD_MSG, 47 VIRTIO_SND_S_NOT_SUPP, 48 VIRTIO_SND_S_IO_ERR, 49 // Not a virtio constant, but it's only used internally as an invalid value so 50 // it's safe. 51 NOT_SET = static_cast<uint32_t>(-1), 52 }; 53 54 enum class AudioStreamDirection : uint32_t { 55 VIRTIO_SND_D_OUTPUT = 0, 56 VIRTIO_SND_D_INPUT 57 }; 58 59 enum class AudioStreamFormat : uint8_t { 60 /* analog formats (width / physical width) */ 61 VIRTIO_SND_PCM_FMT_IMA_ADPCM = 0, /* 4 / 4 bits */ 62 VIRTIO_SND_PCM_FMT_MU_LAW, /* 8 / 8 bits */ 63 VIRTIO_SND_PCM_FMT_A_LAW, /* 8 / 8 bits */ 64 VIRTIO_SND_PCM_FMT_S8, /* 8 / 8 bits */ 65 VIRTIO_SND_PCM_FMT_U8, /* 8 / 8 bits */ 66 VIRTIO_SND_PCM_FMT_S16, /* 16 / 16 bits */ 67 VIRTIO_SND_PCM_FMT_U16, /* 16 / 16 bits */ 68 VIRTIO_SND_PCM_FMT_S18_3, /* 18 / 24 bits */ 69 VIRTIO_SND_PCM_FMT_U18_3, /* 18 / 24 bits */ 70 VIRTIO_SND_PCM_FMT_S20_3, /* 20 / 24 bits */ 71 VIRTIO_SND_PCM_FMT_U20_3, /* 20 / 24 bits */ 72 VIRTIO_SND_PCM_FMT_S24_3, /* 24 / 24 bits */ 73 VIRTIO_SND_PCM_FMT_U24_3, /* 24 / 24 bits */ 74 VIRTIO_SND_PCM_FMT_S20, /* 20 / 32 bits */ 75 VIRTIO_SND_PCM_FMT_U20, /* 20 / 32 bits */ 76 VIRTIO_SND_PCM_FMT_S24, /* 24 / 32 bits */ 77 VIRTIO_SND_PCM_FMT_U24, /* 24 / 32 bits */ 78 VIRTIO_SND_PCM_FMT_S32, /* 32 / 32 bits */ 79 VIRTIO_SND_PCM_FMT_U32, /* 32 / 32 bits */ 80 VIRTIO_SND_PCM_FMT_FLOAT, /* 32 / 32 bits */ 81 VIRTIO_SND_PCM_FMT_FLOAT64, /* 64 / 64 bits */ 82 /* digital formats (width / physical width) */ 83 VIRTIO_SND_PCM_FMT_DSD_U8, /* 8 / 8 bits */ 84 VIRTIO_SND_PCM_FMT_DSD_U16, /* 16 / 16 bits */ 85 VIRTIO_SND_PCM_FMT_DSD_U32, /* 32 / 32 bits */ 86 VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME /* 32 / 32 bits */ 87 }; 88 89 /* supported PCM frame rates */ 90 enum AudioStreamRate : uint8_t { 91 VIRTIO_SND_PCM_RATE_5512 = 0, 92 VIRTIO_SND_PCM_RATE_8000, 93 VIRTIO_SND_PCM_RATE_11025, 94 VIRTIO_SND_PCM_RATE_16000, 95 VIRTIO_SND_PCM_RATE_22050, 96 VIRTIO_SND_PCM_RATE_32000, 97 VIRTIO_SND_PCM_RATE_44100, 98 VIRTIO_SND_PCM_RATE_48000, 99 VIRTIO_SND_PCM_RATE_64000, 100 VIRTIO_SND_PCM_RATE_88200, 101 VIRTIO_SND_PCM_RATE_96000, 102 VIRTIO_SND_PCM_RATE_176400, 103 VIRTIO_SND_PCM_RATE_192000, 104 VIRTIO_SND_PCM_RATE_384000 105 }; 106 107 struct virtio_snd_hdr { 108 Le32 code; 109 }; 110 111 struct virtio_snd_query_info { 112 struct virtio_snd_hdr hdr; 113 Le32 start_id; 114 Le32 count; 115 Le32 size; // unused 116 }; 117 118 struct virtio_snd_info { 119 Le32 hda_fn_nid; 120 }; 121 122 struct virtio_snd_pcm_info { 123 struct virtio_snd_info hdr; 124 Le32 features; /* 1 << VIRTIO_SND_PCM_F_XXX */ 125 Le64 formats; /* 1 << VIRTIO_SND_PCM_FMT_XXX */ 126 Le64 rates; /* 1 << VIRTIO_SND_PCM_RATE_XXX */ 127 uint8_t direction; 128 uint8_t channels_min; 129 uint8_t channels_max; 130 131 uint8_t padding[5]; 132 }; 133 134 struct virtio_snd_pcm_hdr { 135 struct virtio_snd_hdr hdr; 136 Le32 stream_id; 137 }; 138 139 struct virtio_snd_pcm_set_params { 140 struct virtio_snd_pcm_hdr hdr; 141 Le32 buffer_bytes; 142 Le32 period_bytes; 143 Le32 features; /* 1 << VIRTIO_SND_PCM_F_XXX */ 144 uint8_t channels; 145 uint8_t format; 146 uint8_t rate; 147 uint8_t padding; 148 }; 149 150 struct virtio_snd_pcm_xfer { 151 Le32 stream_id; 152 }; 153 154 struct virtio_snd_pcm_status { 155 Le32 status; 156 Le32 latency_bytes; 157 }; 158 159 // Update this value when the msg layouts change 160 const uint32_t VIOS_VERSION = 1; 161 162 struct VioSConfig { 163 uint32_t version; 164 uint32_t jacks; 165 uint32_t streams; 166 uint32_t chmaps; 167 }; 168 169 struct IoTransferMsg { 170 virtio_snd_pcm_xfer io_xfer; 171 uint32_t buffer_offset; 172 uint32_t buffer_len; 173 }; 174 175 struct IoStatusMsg { 176 virtio_snd_pcm_status status; 177 uint32_t buffer_offset; 178 uint32_t consumed_length; 179 }; 180 181 // Ensure all message structs have predictable sizes 182 #define ASSERT_VALID_MSG_TYPE(T, size) \ 183 static_assert(sizeof(T) == (size), #T " has the wrong size") 184 ASSERT_VALID_MSG_TYPE(virtio_snd_query_info, 16); 185 ASSERT_VALID_MSG_TYPE(virtio_snd_pcm_info, 32); 186 ASSERT_VALID_MSG_TYPE(virtio_snd_pcm_set_params, 24); 187 ASSERT_VALID_MSG_TYPE(virtio_snd_pcm_hdr, 8); 188 ASSERT_VALID_MSG_TYPE(IoTransferMsg, 12); 189 ASSERT_VALID_MSG_TYPE(IoStatusMsg, 16); 190 #undef ASSERT_VALID_MSG_TYPE 191 192 } // namespace cuttlefish