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