/* * Copyright (c) 2018 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief Public API header file for Audio Codec * * This file contains the Audio Codec APIs */ #ifndef ZEPHYR_INCLUDE_AUDIO_CODEC_H_ #define ZEPHYR_INCLUDE_AUDIO_CODEC_H_ /** * @brief Abstraction for audio codecs * * @defgroup audio_codec_interface Audio Codec Interface * @since 1.13 * @version 0.1.0 * @ingroup audio_interface * @{ */ #include #ifdef __cplusplus extern "C" { #endif /** * PCM audio sample rates */ typedef enum { AUDIO_PCM_RATE_8K = 8000, /**< 8 kHz sample rate */ AUDIO_PCM_RATE_11P025K = 11025, /**< 11.025 kHz sample rate */ AUDIO_PCM_RATE_16K = 16000, /**< 16 kHz sample rate */ AUDIO_PCM_RATE_22P05K = 22050, /**< 22.05 kHz sample rate */ AUDIO_PCM_RATE_24K = 24000, /**< 24 kHz sample rate */ AUDIO_PCM_RATE_32K = 32000, /**< 32 kHz sample rate */ AUDIO_PCM_RATE_44P1K = 44100, /**< 44.1 kHz sample rate */ AUDIO_PCM_RATE_48K = 48000, /**< 48 kHz sample rate */ AUDIO_PCM_RATE_96K = 96000, /**< 96 kHz sample rate */ AUDIO_PCM_RATE_192K = 192000, /**< 192 kHz sample rate */ } audio_pcm_rate_t; /** * PCM audio sample bit widths */ typedef enum { AUDIO_PCM_WIDTH_16_BITS = 16, /**< 16-bit sample width */ AUDIO_PCM_WIDTH_20_BITS = 20, /**< 20-bit sample width */ AUDIO_PCM_WIDTH_24_BITS = 24, /**< 24-bit sample width */ AUDIO_PCM_WIDTH_32_BITS = 32, /**< 32-bit sample width */ } audio_pcm_width_t; /** * Digital Audio Interface (DAI) type */ typedef enum { AUDIO_DAI_TYPE_I2S, /**< I2S Interface */ AUDIO_DAI_TYPE_LEFT_JUSTIFIED, /**< I2S Interface, left justified */ AUDIO_DAI_TYPE_RIGHT_JUSTIFIED, /**< I2S Interface, right justified */ AUDIO_DAI_TYPE_PCMA, /**< PCM Interface, variant A */ AUDIO_DAI_TYPE_PCMB, /**< PCM Interface, variant B */ AUDIO_DAI_TYPE_INVALID, /**< Other interfaces can be added here */ } audio_dai_type_t; /** * Codec properties that can be set by audio_codec_set_property(). */ typedef enum { AUDIO_PROPERTY_OUTPUT_VOLUME, /**< Output volume */ AUDIO_PROPERTY_OUTPUT_MUTE, /**< Output mute/unmute */ AUDIO_PROPERTY_INPUT_VOLUME, /**< Input volume */ AUDIO_PROPERTY_INPUT_MUTE /**< Input mute/unmute */ } audio_property_t; /** * Audio channel identifiers to use in audio_codec_set_property(). */ typedef enum { AUDIO_CHANNEL_FRONT_LEFT, /**< Front left channel */ AUDIO_CHANNEL_FRONT_RIGHT, /**< Front right channel */ AUDIO_CHANNEL_LFE, /**< Low frequency effect channel */ AUDIO_CHANNEL_FRONT_CENTER, /**< Front center channel */ AUDIO_CHANNEL_REAR_LEFT, /**< Rear left channel */ AUDIO_CHANNEL_REAR_RIGHT, /**< Rear right channel */ AUDIO_CHANNEL_REAR_CENTER, /**< Rear center channel */ AUDIO_CHANNEL_SIDE_LEFT, /**< Side left channel */ AUDIO_CHANNEL_SIDE_RIGHT, /**< Side right channel */ AUDIO_CHANNEL_HEADPHONE_LEFT, /**< Headphone left */ AUDIO_CHANNEL_HEADPHONE_RIGHT, /**< Headphone right */ AUDIO_CHANNEL_ALL, /**< All channels */ } audio_channel_t; /** * @brief Digital Audio Interface Configuration. * * Configuration is dependent on DAI type */ typedef union { struct i2s_config i2s; /**< I2S configuration */ /* Other DAI types go here */ } audio_dai_cfg_t; /* * DAI Route types */ typedef enum { AUDIO_ROUTE_BYPASS, AUDIO_ROUTE_PLAYBACK, AUDIO_ROUTE_PLAYBACK_CAPTURE, AUDIO_ROUTE_CAPTURE, } audio_route_t; /** * Codec configuration parameters */ struct audio_codec_cfg { uint32_t mclk_freq; /**< MCLK input frequency in Hz */ audio_dai_type_t dai_type; /**< Digital interface type */ audio_dai_cfg_t dai_cfg; /**< DAI configuration info */ audio_route_t dai_route; /**< Codec route type */ }; /** * Codec property values */ typedef union { int vol; /**< Volume level (codec-specific) */ bool mute; /**< Mute if @a true, unmute if @a false */ } audio_property_value_t; /** * @brief Codec error type */ enum audio_codec_error_type { /** Output over-current */ AUDIO_CODEC_ERROR_OVERCURRENT = BIT(0), /** Codec over-temperature */ AUDIO_CODEC_ERROR_OVERTEMPERATURE = BIT(1), /** Power low voltage */ AUDIO_CODEC_ERROR_UNDERVOLTAGE = BIT(2), /** Power high voltage */ AUDIO_CODEC_ERROR_OVERVOLTAGE = BIT(3), /** Output direct-current */ AUDIO_CODEC_ERROR_DC = BIT(4), }; /** * @typedef audio_codec_error_callback_t * @brief Callback for error interrupt * * @param dev Pointer to the codec device * @param errors Device errors (bitmask of @ref audio_codec_error_type values) */ typedef void (*audio_codec_error_callback_t)(const struct device *dev, uint32_t errors); /** * @cond INTERNAL_HIDDEN * * For internal use only, skip these in public documentation. */ struct audio_codec_api { int (*configure)(const struct device *dev, struct audio_codec_cfg *cfg); void (*start_output)(const struct device *dev); void (*stop_output)(const struct device *dev); int (*set_property)(const struct device *dev, audio_property_t property, audio_channel_t channel, audio_property_value_t val); int (*apply_properties)(const struct device *dev); int (*clear_errors)(const struct device *dev); int (*register_error_callback)(const struct device *dev, audio_codec_error_callback_t cb); int (*route_input)(const struct device *dev, audio_channel_t channel, uint32_t input); int (*route_output)(const struct device *dev, audio_channel_t channel, uint32_t output); }; /** * @endcond */ /** * @brief Configure the audio codec * * Configure the audio codec device according to the configuration * parameters provided as input * * @param dev Pointer to the device structure for codec driver instance. * @param cfg Pointer to the structure containing the codec configuration. * * @return 0 on success, negative error code on failure */ static inline int audio_codec_configure(const struct device *dev, struct audio_codec_cfg *cfg) { const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; return api->configure(dev, cfg); } /** * @brief Set codec to start output audio playback * * Setup the audio codec device to start the audio playback * * @param dev Pointer to the device structure for codec driver instance. */ static inline void audio_codec_start_output(const struct device *dev) { const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; api->start_output(dev); } /** * @brief Set codec to stop output audio playback * * Setup the audio codec device to stop the audio playback * * @param dev Pointer to the device structure for codec driver instance. */ static inline void audio_codec_stop_output(const struct device *dev) { const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; api->stop_output(dev); } /** * @brief Set a codec property defined by audio_property_t * * Set a property such as volume level, clock configuration etc. * * @param dev Pointer to the device structure for codec driver instance. * @param property The codec property to set * @param channel The audio channel for which the property has to be set * @param val pointer to a property value of type audio_codec_property_value_t * * @return 0 on success, negative error code on failure */ static inline int audio_codec_set_property(const struct device *dev, audio_property_t property, audio_channel_t channel, audio_property_value_t val) { const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; return api->set_property(dev, property, channel, val); } /** * @brief Atomically apply any cached properties * * Following one or more invocations of audio_codec_set_property, that may have * been cached by the driver, audio_codec_apply_properties can be invoked to * apply all the properties as atomic as possible * * @param dev Pointer to the device structure for codec driver instance. * * @return 0 on success, negative error code on failure */ static inline int audio_codec_apply_properties(const struct device *dev) { const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; return api->apply_properties(dev); } /** * @brief Clear any codec errors * * Clear all codec errors. * If an error interrupt exists, it will be de-asserted. * * @param dev Pointer to the device structure for codec driver instance. * * @return 0 on success, negative error code on failure */ static inline int audio_codec_clear_errors(const struct device *dev) { const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; if (api->clear_errors == NULL) { return -ENOSYS; } return api->clear_errors(dev); } /** * @brief Register a callback function for codec error * * The callback will be called from a thread, so I2C or SPI operations are * safe. However, the thread's stack is limited and defined by the * driver. It is currently up to the caller to ensure that the callback * does not overflow the stack. * * @param dev Pointer to the audio codec device * @param cb The function that should be called when an error is detected * fires * * @return 0 if successful, negative errno code if failure. */ static inline int audio_codec_register_error_callback(const struct device *dev, audio_codec_error_callback_t cb) { const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; if (api->register_error_callback == NULL) { return -ENOSYS; } return api->register_error_callback(dev, cb); } /** * @brief Sets up signal routing for a given input channel. * * Some codecs can do input routing (multiplexing) from a chosen set of * physical inputs. This function maps a given audio (stream) channel to * a given physical input terminal. * * @param dev Pointer to the audio codec device * @param channel The channel to map * @param input The input terminal index, codec-specific * * @return 0 if successful, negative errno code if failure. */ static inline int audio_codec_route_input(const struct device *dev, audio_channel_t channel, uint32_t input) { const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; if (api->route_input == NULL) { return -ENOSYS; } return api->route_input(dev, channel, input); } /** * @brief Sets up signal routing for a given output channel. * * Some codecs can do output routing (multiplexing) from a chosen set of * physical output. This function maps a given audio (stream) channel to * a given physical output terminal. * * @param dev Pointer to the audio codec device * @param channel The channel to map * @param output The output terminal index, codec-specific * * @return 0 if successful, negative errno code if failure. */ static inline int audio_codec_route_output(const struct device *dev, audio_channel_t channel, uint32_t output) { const struct audio_codec_api *api = (const struct audio_codec_api *)dev->api; if (api->route_output == NULL) { return -ENOSYS; } return api->route_output(dev, channel, output); } #ifdef __cplusplus } #endif /** * @} */ #endif /* ZEPHYR_INCLUDE_AUDIO_CODEC_H_ */