1 // Copyright 2017 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <assert.h> 8 #include <zircon/compiler.h> 9 #include <zircon/device/ioctl.h> 10 #include <zircon/device/ioctl-wrapper.h> 11 #include <zircon/types.h> 12 13 #define AUDIO_IOCTL_GET_CHANNEL IOCTL(IOCTL_KIND_GET_HANDLE, 0xFE, 0x00) 14 IOCTL_WRAPPER_OUT(ioctl_audio_get_channel, AUDIO_IOCTL_GET_CHANNEL, zx_handle_t); 15 16 // When communicating with an Audio driver using zx_channel_call, do not use 17 // the AUDIO_INVALID_TRANSACTION_ID as your message's transaction ID. It is 18 // reserved for async notifications sent from the driver to the application. 19 #define AUDIO_INVALID_TRANSACTION_ID ((zx_txid_t)0) 20 21 __BEGIN_CDECLS 22 23 typedef uint32_t audio_cmd_t; 24 25 // Commands sent on the stream channel 26 #define AUDIO_STREAM_CMD_GET_FORMATS ((audio_cmd_t)0x1000) 27 #define AUDIO_STREAM_CMD_SET_FORMAT ((audio_cmd_t)0x1001) 28 #define AUDIO_STREAM_CMD_GET_GAIN ((audio_cmd_t)0x1002) 29 #define AUDIO_STREAM_CMD_SET_GAIN ((audio_cmd_t)0x1003) 30 #define AUDIO_STREAM_CMD_PLUG_DETECT ((audio_cmd_t)0x1004) 31 #define AUDIO_STREAM_CMD_GET_UNIQUE_ID ((audio_cmd_t)0x1005) 32 #define AUDIO_STREAM_CMD_GET_STRING ((audio_cmd_t)0x1006) 33 34 // Async notifications sent on the stream channel. 35 #define AUDIO_STREAM_PLUG_DETECT_NOTIFY ((audio_cmd_t)0x2000) 36 37 // Commands sent on the ring buffer channel 38 #define AUDIO_RB_CMD_GET_FIFO_DEPTH ((audio_cmd_t)0x3000) 39 #define AUDIO_RB_CMD_GET_BUFFER ((audio_cmd_t)0x3001) 40 #define AUDIO_RB_CMD_START ((audio_cmd_t)0x3002) 41 #define AUDIO_RB_CMD_STOP ((audio_cmd_t)0x3003) 42 43 // Async notifications sent on the ring buffer channel. 44 #define AUDIO_RB_POSITION_NOTIFY ((audio_cmd_t)0x4000) 45 46 // Flags used to modify commands. 47 #define AUDIO_FLAG_NO_ACK ((audio_cmd_t)0x80000000) 48 49 typedef struct audio_cmd_hdr { 50 zx_txid_t transaction_id; 51 audio_cmd_t cmd; 52 } audio_cmd_hdr_t; 53 54 static_assert(sizeof(audio_cmd_hdr_t) == 8, 55 "audio_cmd_hdr_t should be 12 bytes!"); 56 57 // audio_sample_format_t 58 // 59 // Bitfield which describes audio sample format as they reside in memory. 60 // 61 typedef uint32_t audio_sample_format_t; 62 #define AUDIO_SAMPLE_FORMAT_BITSTREAM ((audio_sample_format_t)(1u << 0)) 63 #define AUDIO_SAMPLE_FORMAT_8BIT ((audio_sample_format_t)(1u << 1)) 64 #define AUDIO_SAMPLE_FORMAT_16BIT ((audio_sample_format_t)(1u << 2)) 65 #define AUDIO_SAMPLE_FORMAT_20BIT_PACKED ((audio_sample_format_t)(1u << 4)) 66 #define AUDIO_SAMPLE_FORMAT_24BIT_PACKED ((audio_sample_format_t)(1u << 5)) 67 #define AUDIO_SAMPLE_FORMAT_20BIT_IN32 ((audio_sample_format_t)(1u << 6)) 68 #define AUDIO_SAMPLE_FORMAT_24BIT_IN32 ((audio_sample_format_t)(1u << 7)) 69 #define AUDIO_SAMPLE_FORMAT_32BIT ((audio_sample_format_t)(1u << 8)) 70 #define AUDIO_SAMPLE_FORMAT_32BIT_FLOAT ((audio_sample_format_t)(1u << 9)) 71 #define AUDIO_SAMPLE_FORMAT_FLAG_UNSIGNED ((audio_sample_format_t)(1u << 30)) 72 #define AUDIO_SAMPLE_FORMAT_FLAG_INVERT_ENDIAN ((audio_sample_format_t)(1u << 31)) 73 #define AUDIO_SAMPLE_FORMAT_FLAG_MASK \ 74 ((audio_sample_format_t)(AUDIO_SAMPLE_FORMAT_FLAG_UNSIGNED | \ 75 AUDIO_SAMPLE_FORMAT_FLAG_INVERT_ENDIAN)) 76 77 // audio_stream_format_range_t 78 // 79 // A structure used along with the AUDIO_STREAM_CMD_GET_FORMATS command in order 80 // to describe the formats supported by an audio stream. 81 #define ASF_RANGE_FLAG_FPS_CONTINUOUS ((uint16_t)(1u << 0)) 82 #define ASF_RANGE_FLAG_FPS_48000_FAMILY ((uint16_t)(1u << 1)) 83 #define ASF_RANGE_FLAG_FPS_44100_FAMILY ((uint16_t)(1u << 2)) 84 typedef struct audio_stream_format_range { 85 audio_sample_format_t sample_formats; 86 uint32_t min_frames_per_second; 87 uint32_t max_frames_per_second; 88 uint8_t min_channels; 89 uint8_t max_channels; 90 uint16_t flags; 91 } __PACKED audio_stream_format_range_t; 92 93 static_assert(sizeof(audio_stream_format_range_t) == 16, 94 "audio_stream_format_range_t should be 16 bytes!"); 95 96 // audio_set_gain_flags_t 97 // 98 // Flags used by the AUDIO_STREAM_CMD_SET_GAIN message. 99 // 100 typedef uint32_t audio_set_gain_flags_t; 101 #define AUDIO_SGF_MUTE_VALID ((audio_set_gain_flags_t)0x1) // Whether or not the mute flag is valid. 102 #define AUDIO_SGF_AGC_VALID ((audio_set_gain_flags_t)0x2) // Whether or not the agc flag is valid. 103 #define AUDIO_SGF_GAIN_VALID ((audio_set_gain_flags_t)0x4) // Whether or not the gain float is valid. 104 #define AUDIO_SGF_MUTE ((audio_set_gain_flags_t)0x40000000) // Whether or not to mute the stream. 105 #define AUDIO_SGF_AGC ((audio_set_gain_flags_t)0x80000000) // Whether or not enable AGC for the stream. 106 107 // audio_pd_flags_t 108 // 109 // Flags used by AUDIO_STREAM_CMD_PLUG_DETECT commands to enable or disable 110 // asynchronous plug detect notifications. 111 // 112 typedef uint32_t audio_pd_flags_t; 113 #define AUDIO_PDF_NONE ((audio_pd_flags_t)0) 114 #define AUDIO_PDF_ENABLE_NOTIFICATIONS ((audio_pd_flags_t)0x40000000) 115 #define AUDIO_PDF_DISABLE_NOTIFICATIONS ((audio_pd_flags_t)0x80000000) 116 117 // audio_pd_notify_flags_t 118 // 119 // Flags used by responses to the AUDIO_STREAM_CMD_PLUG_DETECT 120 // message, and by AUDIO_STREAM_PLUG_DETECT_NOTIFY messages. 121 // 122 typedef uint32_t audio_pd_notify_flags_t; 123 #define AUDIO_PDNF_HARDWIRED ((audio_pd_notify_flags_t)0x1) // Stream is hardwired (will always be plugged in) 124 #define AUDIO_PDNF_CAN_NOTIFY ((audio_pd_notify_flags_t)0x2) // Stream is able to notify of plug state changes. 125 #define AUDIO_PDNF_PLUGGED ((audio_pd_notify_flags_t)0x80000000) // Stream is currently plugged in. 126 127 // AUDIO_STREAM_CMD_GET_FORMATS 128 // 129 // May not be used with the NO_ACK flag. 130 #define AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE (15u) 131 typedef struct audio_stream_cmd_get_formats_req { 132 audio_cmd_hdr_t hdr; 133 } audio_stream_cmd_get_formats_req_t; 134 135 // TODO(johngro) : Figure out if zx_txid_t is ever going to go up to 8 bytes or 136 // not. If it is, just remove the _pad field below. If not, either keep it as 137 // a _pad field, or repurpose it for some flags of some form. Right now, we use 138 // it to make sure that format_ranges is aligned to a 16 byte boundary. 139 typedef struct audio_stream_cmd_get_formats_resp { 140 audio_cmd_hdr_t hdr; 141 uint32_t _pad; 142 uint16_t format_range_count; 143 uint16_t first_format_range_ndx; 144 audio_stream_format_range_t format_ranges[AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE]; 145 } audio_stream_cmd_get_formats_resp_t; 146 147 static_assert(sizeof(audio_stream_cmd_get_formats_resp_t) == 256, 148 "audio_stream_cmd_get_formats_resp_t must be 256 bytes"); 149 150 // AUDIO_STREAM_CMD_SET_FORMAT 151 // 152 // May not be used with the NO_ACK flag. 153 typedef struct audio_stream_cmd_set_format_req { 154 audio_cmd_hdr_t hdr; 155 uint32_t frames_per_second; 156 audio_sample_format_t sample_format; 157 uint16_t channels; 158 } audio_stream_cmd_set_format_req_t; 159 160 typedef struct audio_stream_cmd_set_format_resp { 161 audio_cmd_hdr_t hdr; 162 zx_status_t result; 163 uint64_t external_delay_nsec; 164 165 // Note: Upon success, a channel used to control the audio buffer will also 166 // be returned. 167 } audio_stream_cmd_set_format_resp_t; 168 169 // AUDIO_STREAM_CMD_GET_GAIN 170 // 171 // Request that a gain notification be sent with the current details of the 172 // streams current gain settings as well as gain setting capabilities. 173 // 174 // May not be used with the NO_ACK flag. 175 typedef struct audio_stream_cmd_get_gain_req { 176 audio_cmd_hdr_t hdr; 177 } audio_stream_cmd_get_gain_req_t; 178 179 typedef struct audio_stream_cmd_get_gain_resp { 180 // TODO(johngro) : Is there value in exposing the gain step to the level 181 // above the lowest level stream interface, or should we have all drivers 182 // behave as if they have continuous control at all times? 183 audio_cmd_hdr_t hdr; 184 185 bool cur_mute; // True if the stream is currently muted. 186 bool cur_agc; // True if the stream has AGC currently enabled. 187 float cur_gain; // The current setting gain of the stream in dB 188 189 bool can_mute; // True if the stream is capable of muting 190 bool can_agc; // True if the stream has support for AGC 191 float min_gain; // The minimum valid gain setting, in dB 192 float max_gain; // The maximum valid gain setting, in dB 193 float gain_step; // The smallest valid gain increment, counted from the minimum gain. 194 } audio_stream_cmd_get_gain_resp_t; 195 196 // AUDIO_STREAM_CMD_SET_GAIN 197 // 198 // Request that a stream change its gain settings to most closely match those 199 // requested. Gain values for Valid requests will be rounded to the nearest 200 // gain step. For example, if a stream can control its gain on the range from 201 // -60.0 to 0.0 dB, a request to set the gain to -33.3 dB will result in a gain 202 // of -33.5 being applied. 203 // 204 // Gain change requests outside of the capabilities of the stream's 205 // amplifier will be rejected with a result of ZX_ERR_INVALID_ARGS. Using the 206 // previous example, requests for gains of -65.0 or +3dB would be rejected. 207 // Similarly, If an amplifier is capable of gain control but cannot mute, a 208 // request to mute will be rejected. 209 // 210 // TODO(johngro) : Is this the correct behavior? Should we just apply sensible 211 // limits instead? IOW - If the user requests a gain of -1000 dB, should we 212 // just set the gain to -60dB? Likewise, if they request mute but the amplifier 213 // has no hard mute feature, should we just set the gain to the minimum 214 // permitted gain? 215 // 216 // May be used with the NO_ACK flag. 217 typedef struct audio_stream_cmd_set_gain_req { 218 audio_cmd_hdr_t hdr; 219 audio_set_gain_flags_t flags; 220 float gain; 221 } audio_stream_cmd_set_gain_req_t; 222 223 typedef struct audio_stream_cmd_set_gain_resp { 224 audio_cmd_hdr_t hdr; 225 zx_status_t result; 226 // The current gain settings observed immediately after processing the set 227 // gain request. 228 bool cur_mute; 229 bool cur_agc; 230 float cur_gain; 231 } audio_stream_cmd_set_gain_resp_t; 232 233 // AUDIO_STREAM_CMD_PLUG_DETECT 234 // 235 // Trigger a plug detect operation and/or enable/disable asynchronous plug 236 // detect notifications. 237 // 238 typedef struct audio_stream_cmd_plug_detect_req { 239 audio_cmd_hdr_t hdr; 240 audio_pd_flags_t flags; // Options used to enable or disable notifications 241 } audio_stream_cmd_plug_detect_req_t; 242 243 typedef struct audio_stream_cmd_plug_detect_resp { 244 audio_cmd_hdr_t hdr; 245 audio_pd_notify_flags_t flags; // The current plug state and capabilities 246 zx_time_t plug_state_time; // The time of the plug state last change. 247 } audio_stream_cmd_plug_detect_resp_t; 248 249 // AUDIO_STREAM_PLUG_DETECT_NOTIFY 250 // 251 // Message asynchronously in response to a plug state change to clients who have 252 // registered for plug state notifications. 253 // 254 // Note: Solicited and unsolicited plug detect messages currently use the same 255 // structure and contain the same information. The difference between the two 256 // is that Solicited messages, use AUDIO_STREAM_CMD_PLUG_DETECT as the value of 257 // the `cmd` field of their header and the transaction ID of the request sent by 258 // the client. Unsolicited messages use AUDIO_STREAM_PLUG_DETECT_NOTIFY as the 259 // value value of the `cmd` field of their header, and 260 // AUDIO_INVALID_TRANSACTION_ID for their transaction ID. 261 typedef audio_stream_cmd_plug_detect_resp_t audio_stream_plug_detect_notify_t; 262 263 // AUDIO_STREAM_CMD_GET_UNIQUE_ID 264 // 265 // Fetch a globally unique, but persistent ID for the stream. 266 // 267 // Drivers should make every effort to return as unique an identifier as 268 // possible for each stream that they publish. This ID must not change between 269 // boots. When available, using a globally unique device serial number is 270 // strongly encouraged. Other possible sources of unique-ness include a 271 // driver's physical connection path, driver binding information, manufacturer 272 // calibration data, and so on. 273 // 274 // Note: a small number of hardcoded unique ID has been provided for built-in 275 // devices. Platform drivers for systems with hardwired audio devices may use 276 // these unique IDs as appropriate to signal which audio streams represent the 277 // built-in devices for the system. Drivers for hot-pluggable audio devices 278 // should *never* use these identifiers. 279 // 280 // Even given this, higher level code should *not* depend on these identifiers 281 // being perfectly unique, and should be prepared to take steps to de-dupe 282 // identifiers when needed. 283 typedef struct audio_stream_cmd_get_unique_id_req { 284 audio_cmd_hdr_t hdr; 285 } audio_stream_cmd_get_unique_id_req_t; 286 287 typedef struct audio_stream_unique_id { 288 uint8_t data[16]; 289 } audio_stream_unique_id_t; 290 291 #define AUDIO_STREAM_UNIQUE_ID_BUILTIN_SPEAKERS { .data = { 0x01, 0x00 } } 292 #define AUDIO_STREAM_UNIQUE_ID_BUILTIN_HEADPHONE_JACK { .data = { 0x02, 0x00 } } 293 #define AUDIO_STREAM_UNIQUE_ID_BUILTIN_MICROPHONE { .data = { 0x03, 0x00 } } 294 #define AUDIO_STREAM_UNIQUE_ID_BUILTIN_HEADSET_JACK { .data = { 0x04, 0x00 } } 295 296 typedef struct audio_stream_cmd_get_unique_id_resp { 297 audio_cmd_hdr_t hdr; 298 audio_stream_unique_id_t unique_id; 299 } audio_stream_cmd_get_unique_id_resp_t; 300 301 // AUDIO_STREAM_CMD_GET_STRING 302 // 303 // Fetch the specified string from a device's static string table. Strings 304 // returned by the device driver... 305 // 306 // ++ Must be encoded using UTF8 307 // ++ May contain embedded NULLs 308 // ++ May not be NULL terminated 309 // 310 // Drivers are encouraged to NULL terminate all of their strings whenever 311 // possible, but are not required to do so if the response buffer is too small. 312 // 313 typedef uint32_t audio_stream_string_id_t; 314 #define AUDIO_STREAM_STR_ID_MANUFACTURER ((audio_stream_string_id_t)0x80000000) 315 #define AUDIO_STREAM_STR_ID_PRODUCT ((audio_stream_string_id_t)0x80000001) 316 317 typedef struct audio_stream_cmd_get_string_req { 318 audio_cmd_hdr_t hdr; 319 audio_stream_string_id_t id; 320 } audio_stream_cmd_get_string_req_t; 321 322 typedef struct audio_stream_cmd_get_string_resp { 323 audio_cmd_hdr_t hdr; 324 zx_status_t result; 325 audio_stream_string_id_t id; 326 uint32_t strlen; 327 uint8_t str[256 - sizeof(audio_cmd_hdr_t) - (3 *sizeof(uint32_t))]; 328 } audio_stream_cmd_get_string_resp_t; 329 330 static_assert(sizeof(audio_stream_cmd_get_string_resp_t) == 256, 331 "audio_stream_cmd_get_string_resp_t must be exactly 256 bytes"); 332 333 // AUDIO_RB_CMD_GET_FIFO_DEPTH 334 // 335 // TODO(johngro) : Is calling this "FIFO" depth appropriate? Should it be some 336 // direction neutral form of something like "max-read-ahead-amount" or something 337 // instead? 338 // 339 // May be not used with the NO_ACK flag. 340 typedef struct audio_rb_cmd_get_fifo_depth_req { 341 audio_cmd_hdr_t hdr; 342 } audio_rb_cmd_get_fifo_depth_req_t; 343 344 typedef struct audio_rb_cmd_get_fifo_depth_resp { 345 audio_cmd_hdr_t hdr; 346 zx_status_t result; 347 348 // A representation (in bytes) of how far ahead audio hardware may read 349 // into the stream (in the case of output) or may hold onto audio before 350 // writing it to memory (in the case of input). 351 uint32_t fifo_depth; 352 } audio_rb_cmd_get_fifo_depth_resp_t; 353 354 // AUDIO_RB_CMD_GET_BUFFER 355 typedef struct audio_rb_cmd_get_buffer_req { 356 audio_cmd_hdr_t hdr; 357 358 uint32_t min_ring_buffer_frames; 359 uint32_t notifications_per_ring; 360 } audio_rb_cmd_get_buffer_req_t; 361 362 typedef struct audio_rb_cmd_get_buffer_resp { 363 audio_cmd_hdr_t hdr; 364 zx_status_t result; 365 uint32_t num_ring_buffer_frames; 366 367 // NOTE: If result == ZX_OK, a VMO handle representing the ring buffer to 368 // be used will be returned as well. Clients may map this buffer with 369 // read-write permissions in the case of an output stream, or read-only 370 // permissions in the case of an input stream. The size of the VMO 371 // indicates where the wrap point of the ring (in bytes) is located in the 372 // VMO. This size *must* always be an integral number of audio frames. 373 // 374 // TODO(johngro) : Should we provide some indication of whether or not this 375 // memory is being used directly for HW DMA and may need explicit cache 376 // flushing/invalidation? 377 } audio_rb_cmd_get_buffer_resp_t; 378 379 // AUDIO_RB_CMD_START 380 typedef struct audio_rb_cmd_start_req { 381 audio_cmd_hdr_t hdr; 382 } audio_rb_cmd_start_req_t; 383 384 typedef struct audio_rb_cmd_start_resp { 385 audio_cmd_hdr_t hdr; 386 zx_status_t result; 387 uint64_t start_time; 388 } audio_rb_cmd_start_resp_t; 389 390 // AUDIO_RB_CMD_STOP 391 typedef struct audio_rb_cmd_stop_req { 392 audio_cmd_hdr_t hdr; 393 } audio_rb_cmd_stop_req_t; 394 395 typedef struct audio_rb_cmd_stop_resp { 396 audio_cmd_hdr_t hdr; 397 zx_status_t result; 398 } audio_rb_cmd_stop_resp_t; 399 400 // AUDIO_RB_POSITION_NOTIFY 401 typedef struct audio_rb_position_notify { 402 audio_cmd_hdr_t hdr; 403 404 // The current position (in bytes) of the driver/hardware's read (output) or 405 // write (input) pointer in the ring buffer. 406 uint32_t ring_buffer_pos; 407 } audio_rb_position_notify_t; 408 409 __END_CDECLS 410