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