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 <zephyr/drivers/i2s.h>
28 :
29 : #ifdef __cplusplus
30 : extern "C" {
31 : #endif
32 :
33 : /**
34 : * PCM audio sample rates
35 : */
36 1 : 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 1 : 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 1 : 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 1 : 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 1 : 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 1 : typedef union {
105 1 : 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 0 : 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 1 : struct audio_codec_cfg {
123 1 : uint32_t mclk_freq; /**< MCLK input frequency in Hz */
124 1 : audio_dai_type_t dai_type; /**< Digital interface type */
125 1 : audio_dai_cfg_t dai_cfg; /**< DAI configuration info */
126 1 : audio_route_t dai_route; /**< Codec route type */
127 : };
128 :
129 : /**
130 : * Codec property values
131 : */
132 1 : typedef union {
133 1 : int vol; /**< Volume level (codec-specific) */
134 1 : bool mute; /**< Mute if @a true, unmute if @a false */
135 : } audio_property_value_t;
136 :
137 : /**
138 : * @brief Codec error type
139 : */
140 1 : 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 1 : 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 : */
202 1 : 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 : */
218 1 : 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 : */
233 1 : 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 : */
253 1 : 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 : */
275 1 : 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 : */
293 1 : 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 : */
319 1 : 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 : */
345 1 : 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 : */
370 1 : 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_ */
|