LCOV - code coverage report
Current view: top level - zephyr/audio - dmic.h Coverage Total Hit
Test: new.info Lines: 94.4 % 36 34
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2018, Intel Corporation
       3              :  *
       4              :  * Author:      Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
       5              :  *              Sathish Kuttan <sathish.k.kuttan@intel.com>
       6              :  *
       7              :  * SPDX-License-Identifier: Apache-2.0
       8              :  */
       9              : 
      10              : /**
      11              :  * @file
      12              :  * @brief Public API header file for Digital Microphones
      13              :  *
      14              :  * This file contains the Digital Microphone APIs
      15              :  */
      16              : 
      17              : #ifndef ZEPHYR_INCLUDE_AUDIO_DMIC_H_
      18              : #define ZEPHYR_INCLUDE_AUDIO_DMIC_H_
      19              : 
      20              : 
      21              : /**
      22              :  * @defgroup audio_interface Audio
      23              :  * @{
      24              :  * @}
      25              :  */
      26              : 
      27              : /**
      28              :  * @brief Abstraction for digital microphones
      29              :  *
      30              :  * @defgroup audio_dmic_interface Digital Microphone Interface
      31              :  * @since 1.13
      32              :  * @version 0.1.0
      33              :  * @ingroup audio_interface
      34              :  * @{
      35              :  */
      36              : 
      37              : #include <zephyr/kernel.h>
      38              : #include <zephyr/device.h>
      39              : 
      40              : #ifdef __cplusplus
      41              : extern "C" {
      42              : #endif
      43              : 
      44              : /**
      45              :  * DMIC driver states
      46              :  */
      47            1 : enum dmic_state {
      48              :         DMIC_STATE_UNINIT,      /**< Uninitialized */
      49              :         DMIC_STATE_INITIALIZED, /**< Initialized */
      50              :         DMIC_STATE_CONFIGURED,  /**< Configured */
      51              :         DMIC_STATE_ACTIVE,      /**< Active */
      52              :         DMIC_STATE_PAUSED,      /**< Paused */
      53              :         DMIC_STATE_ERROR,       /**< Error */
      54              : };
      55              : 
      56              : /**
      57              :  * DMIC driver trigger commands
      58              :  */
      59            1 : enum dmic_trigger {
      60              :         DMIC_TRIGGER_STOP,      /**< Stop stream */
      61              :         DMIC_TRIGGER_START,     /**< Start stream */
      62              :         DMIC_TRIGGER_PAUSE,     /**< Pause stream */
      63              :         DMIC_TRIGGER_RELEASE,   /**< Release paused stream */
      64              :         DMIC_TRIGGER_RESET,     /**< Reset stream */
      65              : };
      66              : 
      67              : /**
      68              :  * PDM Channels LEFT / RIGHT
      69              :  */
      70            1 : enum pdm_lr {
      71              :         PDM_CHAN_LEFT,  /**< Left channel */
      72              :         PDM_CHAN_RIGHT, /**< Right channel */
      73              : };
      74              : 
      75              : /**
      76              :  * PDM Input/Output signal configuration
      77              :  */
      78            1 : struct pdm_io_cfg {
      79              :         /**
      80              :          * @name Parameters common to all PDM controllers
      81              :          *@{
      82              :          */
      83              :         /** Minimum clock frequency supported by the mic */
      84            1 :         uint32_t        min_pdm_clk_freq;
      85              :         /** Maximum clock frequency supported by the mic */
      86            1 :         uint32_t        max_pdm_clk_freq;
      87              :         /** Minimum duty cycle in % supported by the mic */
      88            1 :         uint8_t min_pdm_clk_dc;
      89              :         /** Maximum duty cycle in % supported by the mic */
      90            1 :         uint8_t max_pdm_clk_dc;
      91              :         /**
      92              :          * @}
      93              :          */
      94              : 
      95              :         /**
      96              :          * @name Parameters unique to each PDM controller
      97              :          * @{
      98              :          */
      99              :         /** Bit mask to optionally invert PDM clock */
     100            1 :         uint8_t pdm_clk_pol;
     101              :         /** Bit mask to optionally invert mic data */
     102            1 :         uint8_t pdm_data_pol;
     103              :         /** Collection of clock skew values for each PDM port */
     104            1 :         uint32_t        pdm_clk_skew;
     105              :         /**
     106              :          * @}
     107              :          */
     108              : };
     109              : 
     110              : /**
     111              :  * Configuration of the PCM streams to be output by the PDM hardware
     112              :  *
     113              :  * @note if either \ref pcm_rate or \ref pcm_width is set to 0 for a stream,
     114              :  * the stream would be disabled
     115              :  */
     116            1 : struct pcm_stream_cfg {
     117              :         /** PCM sample rate of stream */
     118            1 :         uint32_t                        pcm_rate;
     119              :         /** PCM sample width of stream */
     120            1 :         uint8_t                 pcm_width;
     121              :         /** PCM sample block size per transfer */
     122            1 :         uint16_t                        block_size;
     123              :         /** SLAB for DMIC driver to allocate buffers for stream */
     124            1 :         struct k_mem_slab       *mem_slab;
     125              : };
     126              : 
     127              : /**
     128              :  * Mapping/ordering of the PDM channels to logical PCM output channel
     129              :  *
     130              :  * Since each controller can have 2 audio channels (stereo),
     131              :  * there can be a total of 8x2=16 channels. The actual number of channels
     132              :  * shall be described in \ref act_num_chan.
     133              :  *
     134              :  * If 2 streams are enabled, the channel order will be the same for
     135              :  * both streams.
     136              :  *
     137              :  * Each channel is described as a 4-bit number, the least significant
     138              :  * bit indicates LEFT/RIGHT selection of the PDM controller.
     139              :  *
     140              :  * The most significant 3 bits indicate the PDM controller number:
     141              :  *  - bits 0-3 are for channel 0, bit 0 indicates LEFT or RIGHT
     142              :  *  - bits 4-7 are for channel 1, bit 4 indicates LEFT or RIGHT
     143              :  * and so on.
     144              :  *
     145              :  * CONSTRAINT: The LEFT and RIGHT channels of EACH PDM controller needs
     146              :  * to be adjacent to each other.
     147              :  */
     148            1 : struct pdm_chan_cfg {
     149              :         /**
     150              :          * @name Requested channel map
     151              :          * @{
     152              :          */
     153            1 :         uint32_t        req_chan_map_lo;        /**< Channels 0 to 7 */
     154            1 :         uint32_t        req_chan_map_hi;        /**< Channels 8 to 15 */
     155              :         /** @} */
     156              : 
     157              :         /**
     158              :          * @name Actual channel map that the driver could configure
     159              :          * @{
     160              :          */
     161            1 :         uint32_t        act_chan_map_lo;        /**< Channels 0 to 7 */
     162            1 :         uint32_t        act_chan_map_hi;        /**< Channels 8 to 15 */
     163              :         /** @} */
     164              : 
     165              :         /** Requested number of channels */
     166            1 :         uint8_t req_num_chan;
     167              :         /** Actual number of channels that the driver could configure */
     168            1 :         uint8_t act_num_chan;
     169              :         /** Requested number of streams for each channel */
     170            1 :         uint8_t req_num_streams;
     171              :         /** Actual number of streams that the driver could configure */
     172            1 :         uint8_t act_num_streams;
     173              : };
     174              : 
     175              : /**
     176              :  * Input configuration structure for the DMIC configuration API
     177              :  */
     178            1 : struct dmic_cfg {
     179            0 :         struct pdm_io_cfg io;
     180              :         /**
     181              :          * Array of pcm_stream_cfg for application to provide
     182              :          * configuration for each stream
     183              :          */
     184            1 :         struct pcm_stream_cfg *streams;
     185            0 :         struct pdm_chan_cfg channel;
     186              : };
     187              : 
     188              : /**
     189              :  * Function pointers for the DMIC driver operations
     190              :  */
     191              : struct _dmic_ops {
     192              :         int (*configure)(const struct device *dev, struct dmic_cfg *config);
     193              :         int (*trigger)(const struct device *dev, enum dmic_trigger cmd);
     194              :         int (*read)(const struct device *dev, uint8_t stream, void **buffer,
     195              :                         size_t *size, int32_t timeout);
     196              : };
     197              : 
     198              : /**
     199              :  * Build the channel map to populate struct pdm_chan_cfg
     200              :  *
     201              :  * Returns the map of PDM controller and LEFT/RIGHT channel shifted to
     202              :  * the bit position corresponding to the input logical channel value
     203              :  *
     204              :  * @param channel The logical channel number
     205              :  * @param pdm The PDM hardware controller number
     206              :  * @param lr LEFT/RIGHT channel within the chosen PDM hardware controller
     207              :  *
     208              :  * @return Bit-map containing the PDM and L/R channel information
     209              :  */
     210            1 : static inline uint32_t dmic_build_channel_map(uint8_t channel, uint8_t pdm,
     211              :                 enum pdm_lr lr)
     212              : {
     213              :         return ((((pdm & BIT_MASK(3)) << 1) | lr) <<
     214              :                         ((channel & BIT_MASK(3)) * 4U));
     215              : }
     216              : 
     217              : /**
     218              :  * Helper function to parse the channel map in pdm_chan_cfg
     219              :  *
     220              :  * Returns the PDM controller and LEFT/RIGHT channel corresponding to
     221              :  * the channel map and the logical channel provided as input
     222              :  *
     223              :  * @param channel_map_lo Lower order/significant bits of the channel map
     224              :  * @param channel_map_hi Higher order/significant bits of the channel map
     225              :  * @param channel The logical channel number
     226              :  * @param pdm Pointer to the PDM hardware controller number
     227              :  * @param lr Pointer to the LEFT/RIGHT channel within the PDM controller
     228              :  */
     229            1 : static inline void dmic_parse_channel_map(uint32_t channel_map_lo,
     230              :                 uint32_t channel_map_hi, uint8_t channel, uint8_t *pdm, enum pdm_lr *lr)
     231              : {
     232              :         uint32_t channel_map;
     233              : 
     234              :         channel_map = (channel < 8) ? channel_map_lo : channel_map_hi;
     235              :         channel_map >>= ((channel & BIT_MASK(3)) * 4U);
     236              : 
     237              :         *pdm = (channel_map >> 1) & BIT_MASK(3);
     238              :         *lr = (enum pdm_lr) (channel_map & BIT(0));
     239              : }
     240              : 
     241              : /**
     242              :  * Build a bit map of clock skew values for each PDM channel
     243              :  *
     244              :  * Returns the bit-map of clock skew value shifted to the bit position
     245              :  * corresponding to the input PDM controller value
     246              :  *
     247              :  * @param pdm The PDM hardware controller number
     248              :  * @param skew The skew to apply for the clock output from the PDM controller
     249              :  *
     250              :  * @return Bit-map containing the clock skew information
     251              :  */
     252            1 : static inline uint32_t dmic_build_clk_skew_map(uint8_t pdm, uint8_t skew)
     253              : {
     254              :         return ((skew & BIT_MASK(4)) << ((pdm & BIT_MASK(3)) * 4U));
     255              : }
     256              : 
     257              : /**
     258              :  * Configure the DMIC driver and controller(s)
     259              :  *
     260              :  * Configures the DMIC driver device according to the number of channels,
     261              :  * channel mapping, PDM I/O configuration, PCM stream configuration, etc.
     262              :  *
     263              :  * @param dev Pointer to the device structure for DMIC driver instance
     264              :  * @param cfg Pointer to the structure containing the DMIC configuration
     265              :  *
     266              :  * @return 0 on success, a negative error code on failure
     267              :  */
     268            1 : static inline int dmic_configure(const struct device *dev,
     269              :                                  struct dmic_cfg *cfg)
     270              : {
     271              :         const struct _dmic_ops *api =
     272              :                 (const struct _dmic_ops *)dev->api;
     273              : 
     274              :         return api->configure(dev, cfg);
     275              : }
     276              : 
     277              : /**
     278              :  * Send a command to the DMIC driver
     279              :  *
     280              :  * Sends a command to the driver to perform a specific action
     281              :  *
     282              :  * @param dev Pointer to the device structure for DMIC driver instance
     283              :  * @param cmd The command to be sent to the driver instance
     284              :  *
     285              :  * @return 0 on success, a negative error code on failure
     286              :  */
     287            1 : static inline int dmic_trigger(const struct device *dev,
     288              :                                enum dmic_trigger cmd)
     289              : {
     290              :         const struct _dmic_ops *api =
     291              :                 (const struct _dmic_ops *)dev->api;
     292              : 
     293              :         return api->trigger(dev, cmd);
     294              : }
     295              : 
     296              : /**
     297              :  * Read received decimated PCM data stream
     298              :  *
     299              :  * Optionally waits for audio to be received and provides the received
     300              :  * audio buffer from the requested stream
     301              :  *
     302              :  * @param dev Pointer to the device structure for DMIC driver instance
     303              :  * @param stream Stream identifier
     304              :  * @param buffer Pointer to the received buffer address
     305              :  * @param size Pointer to the received buffer size
     306              :  * @param timeout Timeout in milliseconds to wait in case audio is not yet
     307              :  *                received, or @ref SYS_FOREVER_MS
     308              :  *
     309              :  * @return 0 on success, a negative error code on failure
     310              :  */
     311            1 : static inline int dmic_read(const struct device *dev, uint8_t stream,
     312              :                             void **buffer,
     313              :                             size_t *size, int32_t timeout)
     314              : {
     315              :         const struct _dmic_ops *api =
     316              :                 (const struct _dmic_ops *)dev->api;
     317              : 
     318              :         return api->read(dev, stream, buffer, size, timeout);
     319              : }
     320              : 
     321              : #ifdef __cplusplus
     322              : }
     323              : #endif
     324              : 
     325              : /**
     326              :  * @}
     327              :  */
     328              : 
     329              : #endif /* ZEPHYR_INCLUDE_AUDIO_DMIC_H_ */
        

Generated by: LCOV version 2.0-1