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