1 /*
2 * Copyright (c) 2018 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Public API header file for Audio Codec
10 *
11 * This file contains the Audio Codec APIs
12 */
13
14 #ifndef ZEPHYR_INCLUDE_AUDIO_CODEC_H_
15 #define ZEPHYR_INCLUDE_AUDIO_CODEC_H_
16
17 /**
18 * @brief Abstraction for audio codecs
19 *
20 * @defgroup audio_codec_interface Audio Codec Interface
21 * @since 1.13
22 * @version 0.1.0
23 * @ingroup audio_interface
24 * @{
25 */
26
27 #include <zephyr/drivers/i2s.h>
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 /**
34 * PCM audio sample rates
35 */
36 typedef enum {
37 AUDIO_PCM_RATE_8K = 8000, /**< 8 kHz sample rate */
38 AUDIO_PCM_RATE_11P025K = 11025, /**< 11.025 kHz sample rate */
39 AUDIO_PCM_RATE_16K = 16000, /**< 16 kHz sample rate */
40 AUDIO_PCM_RATE_22P05K = 22050, /**< 22.05 kHz sample rate */
41 AUDIO_PCM_RATE_24K = 24000, /**< 24 kHz sample rate */
42 AUDIO_PCM_RATE_32K = 32000, /**< 32 kHz sample rate */
43 AUDIO_PCM_RATE_44P1K = 44100, /**< 44.1 kHz sample rate */
44 AUDIO_PCM_RATE_48K = 48000, /**< 48 kHz sample rate */
45 AUDIO_PCM_RATE_96K = 96000, /**< 96 kHz sample rate */
46 AUDIO_PCM_RATE_192K = 192000, /**< 192 kHz sample rate */
47 } audio_pcm_rate_t;
48
49 /**
50 * PCM audio sample bit widths
51 */
52 typedef enum {
53 AUDIO_PCM_WIDTH_16_BITS = 16, /**< 16-bit sample width */
54 AUDIO_PCM_WIDTH_20_BITS = 20, /**< 20-bit sample width */
55 AUDIO_PCM_WIDTH_24_BITS = 24, /**< 24-bit sample width */
56 AUDIO_PCM_WIDTH_32_BITS = 32, /**< 32-bit sample width */
57 } audio_pcm_width_t;
58
59 /**
60 * Digital Audio Interface (DAI) type
61 */
62 typedef enum {
63 AUDIO_DAI_TYPE_I2S, /**< I2S Interface */
64 AUDIO_DAI_TYPE_LEFT_JUSTIFIED, /**< I2S Interface, left justified */
65 AUDIO_DAI_TYPE_RIGHT_JUSTIFIED, /**< I2S Interface, right justified */
66 AUDIO_DAI_TYPE_PCMA, /**< PCM Interface, variant A */
67 AUDIO_DAI_TYPE_PCMB, /**< PCM Interface, variant B */
68 AUDIO_DAI_TYPE_INVALID, /**< Other interfaces can be added here */
69 } audio_dai_type_t;
70
71 /**
72 * Codec properties that can be set by audio_codec_set_property().
73 */
74 typedef enum {
75 AUDIO_PROPERTY_OUTPUT_VOLUME, /**< Output volume */
76 AUDIO_PROPERTY_OUTPUT_MUTE, /**< Output mute/unmute */
77 AUDIO_PROPERTY_INPUT_VOLUME, /**< Input volume */
78 AUDIO_PROPERTY_INPUT_MUTE /**< Input mute/unmute */
79 } audio_property_t;
80
81 /**
82 * Audio channel identifiers to use in audio_codec_set_property().
83 */
84 typedef enum {
85 AUDIO_CHANNEL_FRONT_LEFT, /**< Front left channel */
86 AUDIO_CHANNEL_FRONT_RIGHT, /**< Front right channel */
87 AUDIO_CHANNEL_LFE, /**< Low frequency effect channel */
88 AUDIO_CHANNEL_FRONT_CENTER, /**< Front center channel */
89 AUDIO_CHANNEL_REAR_LEFT, /**< Rear left channel */
90 AUDIO_CHANNEL_REAR_RIGHT, /**< Rear right channel */
91 AUDIO_CHANNEL_REAR_CENTER, /**< Rear center channel */
92 AUDIO_CHANNEL_SIDE_LEFT, /**< Side left channel */
93 AUDIO_CHANNEL_SIDE_RIGHT, /**< Side right channel */
94 AUDIO_CHANNEL_HEADPHONE_LEFT, /**< Headphone left */
95 AUDIO_CHANNEL_HEADPHONE_RIGHT, /**< Headphone right */
96 AUDIO_CHANNEL_ALL, /**< All channels */
97 } audio_channel_t;
98
99 /**
100 * @brief Digital Audio Interface Configuration.
101 *
102 * Configuration is dependent on DAI type
103 */
104 typedef union {
105 struct i2s_config i2s; /**< I2S configuration */
106 /* Other DAI types go here */
107 } audio_dai_cfg_t;
108
109 /*
110 * DAI Route types
111 */
112 typedef enum {
113 AUDIO_ROUTE_BYPASS,
114 AUDIO_ROUTE_PLAYBACK,
115 AUDIO_ROUTE_PLAYBACK_CAPTURE,
116 AUDIO_ROUTE_CAPTURE,
117 } audio_route_t;
118
119 /**
120 * Codec configuration parameters
121 */
122 struct audio_codec_cfg {
123 uint32_t mclk_freq; /**< MCLK input frequency in Hz */
124 audio_dai_type_t dai_type; /**< Digital interface type */
125 audio_dai_cfg_t dai_cfg; /**< DAI configuration info */
126 audio_route_t dai_route; /**< Codec route type */
127 };
128
129 /**
130 * Codec property values
131 */
132 typedef union {
133 int vol; /**< Volume level (codec-specific) */
134 bool mute; /**< Mute if @a true, unmute if @a false */
135 } audio_property_value_t;
136
137 /**
138 * @brief Codec error type
139 */
140 enum audio_codec_error_type {
141 /** Output over-current */
142 AUDIO_CODEC_ERROR_OVERCURRENT = BIT(0),
143
144 /** Codec over-temperature */
145 AUDIO_CODEC_ERROR_OVERTEMPERATURE = BIT(1),
146
147 /** Power low voltage */
148 AUDIO_CODEC_ERROR_UNDERVOLTAGE = BIT(2),
149
150 /** Power high voltage */
151 AUDIO_CODEC_ERROR_OVERVOLTAGE = BIT(3),
152
153 /** Output direct-current */
154 AUDIO_CODEC_ERROR_DC = BIT(4),
155 };
156
157 /**
158 * @typedef audio_codec_error_callback_t
159 * @brief Callback for error interrupt
160 *
161 * @param dev Pointer to the codec device
162 * @param errors Device errors (bitmask of @ref audio_codec_error_type values)
163 */
164 typedef void (*audio_codec_error_callback_t)(const struct device *dev, uint32_t errors);
165
166 /**
167 * @cond INTERNAL_HIDDEN
168 *
169 * For internal use only, skip these in public documentation.
170 */
171 struct audio_codec_api {
172 int (*configure)(const struct device *dev,
173 struct audio_codec_cfg *cfg);
174 void (*start_output)(const struct device *dev);
175 void (*stop_output)(const struct device *dev);
176 int (*set_property)(const struct device *dev,
177 audio_property_t property,
178 audio_channel_t channel,
179 audio_property_value_t val);
180 int (*apply_properties)(const struct device *dev);
181 int (*clear_errors)(const struct device *dev);
182 int (*register_error_callback)(const struct device *dev,
183 audio_codec_error_callback_t cb);
184 int (*route_input)(const struct device *dev, audio_channel_t channel, uint32_t input);
185 int (*route_output)(const struct device *dev, audio_channel_t channel, uint32_t output);
186 };
187 /**
188 * @endcond
189 */
190
191 /**
192 * @brief Configure the audio codec
193 *
194 * Configure the audio codec device according to the configuration
195 * parameters provided as input
196 *
197 * @param dev Pointer to the device structure for codec driver instance.
198 * @param cfg Pointer to the structure containing the codec configuration.
199 *
200 * @return 0 on success, negative error code on failure
201 */
audio_codec_configure(const struct device * dev,struct audio_codec_cfg * cfg)202 static inline int audio_codec_configure(const struct device *dev,
203 struct audio_codec_cfg *cfg)
204 {
205 const struct audio_codec_api *api =
206 (const struct audio_codec_api *)dev->api;
207
208 return api->configure(dev, cfg);
209 }
210
211 /**
212 * @brief Set codec to start output audio playback
213 *
214 * Setup the audio codec device to start the audio playback
215 *
216 * @param dev Pointer to the device structure for codec driver instance.
217 */
audio_codec_start_output(const struct device * dev)218 static inline void audio_codec_start_output(const struct device *dev)
219 {
220 const struct audio_codec_api *api =
221 (const struct audio_codec_api *)dev->api;
222
223 api->start_output(dev);
224 }
225
226 /**
227 * @brief Set codec to stop output audio playback
228 *
229 * Setup the audio codec device to stop the audio playback
230 *
231 * @param dev Pointer to the device structure for codec driver instance.
232 */
audio_codec_stop_output(const struct device * dev)233 static inline void audio_codec_stop_output(const struct device *dev)
234 {
235 const struct audio_codec_api *api =
236 (const struct audio_codec_api *)dev->api;
237
238 api->stop_output(dev);
239 }
240
241 /**
242 * @brief Set a codec property defined by audio_property_t
243 *
244 * Set a property such as volume level, clock configuration etc.
245 *
246 * @param dev Pointer to the device structure for codec driver instance.
247 * @param property The codec property to set
248 * @param channel The audio channel for which the property has to be set
249 * @param val pointer to a property value of type audio_codec_property_value_t
250 *
251 * @return 0 on success, negative error code on failure
252 */
audio_codec_set_property(const struct device * dev,audio_property_t property,audio_channel_t channel,audio_property_value_t val)253 static inline int audio_codec_set_property(const struct device *dev,
254 audio_property_t property,
255 audio_channel_t channel,
256 audio_property_value_t val)
257 {
258 const struct audio_codec_api *api =
259 (const struct audio_codec_api *)dev->api;
260
261 return api->set_property(dev, property, channel, val);
262 }
263
264 /**
265 * @brief Atomically apply any cached properties
266 *
267 * Following one or more invocations of audio_codec_set_property, that may have
268 * been cached by the driver, audio_codec_apply_properties can be invoked to
269 * apply all the properties as atomic as possible
270 *
271 * @param dev Pointer to the device structure for codec driver instance.
272 *
273 * @return 0 on success, negative error code on failure
274 */
audio_codec_apply_properties(const struct device * dev)275 static inline int audio_codec_apply_properties(const struct device *dev)
276 {
277 const struct audio_codec_api *api =
278 (const struct audio_codec_api *)dev->api;
279
280 return api->apply_properties(dev);
281 }
282
283 /**
284 * @brief Clear any codec errors
285 *
286 * Clear all codec errors.
287 * If an error interrupt exists, it will be de-asserted.
288 *
289 * @param dev Pointer to the device structure for codec driver instance.
290 *
291 * @return 0 on success, negative error code on failure
292 */
audio_codec_clear_errors(const struct device * dev)293 static inline int audio_codec_clear_errors(const struct device *dev)
294 {
295 const struct audio_codec_api *api =
296 (const struct audio_codec_api *)dev->api;
297
298 if (api->clear_errors == NULL) {
299 return -ENOSYS;
300 }
301
302 return api->clear_errors(dev);
303 }
304
305 /**
306 * @brief Register a callback function for codec error
307 *
308 * The callback will be called from a thread, so I2C or SPI operations are
309 * safe. However, the thread's stack is limited and defined by the
310 * driver. It is currently up to the caller to ensure that the callback
311 * does not overflow the stack.
312 *
313 * @param dev Pointer to the audio codec device
314 * @param cb The function that should be called when an error is detected
315 * fires
316 *
317 * @return 0 if successful, negative errno code if failure.
318 */
audio_codec_register_error_callback(const struct device * dev,audio_codec_error_callback_t cb)319 static inline int audio_codec_register_error_callback(const struct device *dev,
320 audio_codec_error_callback_t cb)
321 {
322 const struct audio_codec_api *api =
323 (const struct audio_codec_api *)dev->api;
324
325 if (api->register_error_callback == NULL) {
326 return -ENOSYS;
327 }
328
329 return api->register_error_callback(dev, cb);
330 }
331
332 /**
333 * @brief Sets up signal routing for a given input channel.
334 *
335 * Some codecs can do input routing (multiplexing) from a chosen set of
336 * physical inputs. This function maps a given audio (stream) channel to
337 * a given physical input terminal.
338 *
339 * @param dev Pointer to the audio codec device
340 * @param channel The channel to map
341 * @param input The input terminal index, codec-specific
342 *
343 * @return 0 if successful, negative errno code if failure.
344 */
audio_codec_route_input(const struct device * dev,audio_channel_t channel,uint32_t input)345 static inline int audio_codec_route_input(const struct device *dev, audio_channel_t channel,
346 uint32_t input)
347 {
348 const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api;
349
350 if (api->route_input == NULL) {
351 return -ENOSYS;
352 }
353
354 return api->route_input(dev, channel, input);
355 }
356
357 /**
358 * @brief Sets up signal routing for a given output channel.
359 *
360 * Some codecs can do output routing (multiplexing) from a chosen set of
361 * physical output. This function maps a given audio (stream) channel to
362 * a given physical output terminal.
363 *
364 * @param dev Pointer to the audio codec device
365 * @param channel The channel to map
366 * @param output The output terminal index, codec-specific
367 *
368 * @return 0 if successful, negative errno code if failure.
369 */
audio_codec_route_output(const struct device * dev,audio_channel_t channel,uint32_t output)370 static inline int audio_codec_route_output(const struct device *dev, audio_channel_t channel,
371 uint32_t output)
372 {
373 const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api;
374
375 if (api->route_output == NULL) {
376 return -ENOSYS;
377 }
378
379 return api->route_output(dev, channel, output);
380 }
381
382 #ifdef __cplusplus
383 }
384 #endif
385
386 /**
387 * @}
388 */
389
390 #endif /* ZEPHYR_INCLUDE_AUDIO_CODEC_H_ */
391