text: /*
   * Copyright 2021 NXP
   *
   * SPDX-License-Identifier: BSD-3-Clause
   */
  
  #ifndef _FSL_PCM186X_H_
  #define _FSL_PCM186X_H_
  
  #include "fsl_codec_i2c.h"
  #include "fsl_common.h"
  
  /*!
   * @addtogroup pcm186X
   * @ingroup codec
   * @{
   */
  
  /*******************************************************************************
   * Definitions
   ******************************************************************************/
  /*! @name Driver version */
  /*@{*/
  /*! @brief CLOCK driver version 2.2.0 */
  #define FSL_PCM186X_DRIVER_VERSION (MAKE_VERSION(0, 1, 0))
  /*@}*/
  
  /*! @brief PCM186X handle size */
  #ifndef PCM186X_I2C_HANDLER_SIZE
  #define PCM186X_I2C_HANDLER_SIZE CODEC_I2C_MASTER_HANDLER_SIZE
  #endif
  
  /*! @brief Define the register addresses of PCM186X. */
  #define PCM186X_REG_00           (  0)
  #define PCM186X_PCM_CFG          ( 11)
  #define PCM186X_TDM_TX_OFFSET    ( 13)
  #define PCM186X_GPIO1_0_CTRL     ( 16)
  #define PCM186X_GPIO3_2_CTRL     ( 17)
  #define PCM186X_GPIO1_0_DIR_CTRL ( 18)
  #define PCM186X_GPIO3_2_DIR_CTRL ( 19)
  #define PCM186X_GPIO_IN_OUT      ( 20)
  #define PCM186X_CLK_CTRL         ( 32)
  #define PCM186X_POWER_CTRL       (112)
  
  /*! @brief PCM186X_PAGE */
  #define PCM186X_RESET            (0xfe)
  
  /*! @brief Page 0, Register 11 */
  #define PCM186X_RX_WLEN          (3 << 6)
  #define PCM186X_TX_WLEN          (3 << 2)
  #define PCM186X_FMT              (3 << 0)
  #define PCM186X_WLEN_16          (3)
  #define PCM186X_WLEN_24          (1)
  #define PCM186X_WLEN_32          (0)
  #define PCM186X_FMT_I2S          (0)
  
  /*! @brief Page 0, Register 16 */
  #define PCM186X_GPIO0_FUNC       (7 << 0)
  #define PCM186X_GPIO1_FUNC       (7 << 4)
  
  /*! @brief Page 0, Register 17 */
  #define PCM186X_GPIO2_FUNC       (7 << 0)
  #define PCM186X_GPIO3_FUNC       (7 << 4)
  
  /*! @brief Page 0, Register 18 */
  #define PCM186X_GPIO0_DIR        (7 << 0)
  #define PCM186X_GPIO1_DIR        (7 << 4)
  
  /*! @brief Page 0, Register 19 */
  #define PCM186X_GPIO2_DIR        (7 << 0)
  #define PCM186X_GPIO3_DIR        (7 << 4)
  
  /*! @brief Page 0, Register 32 */
  #define PCM186X_SCK_XI_SEL1      (1 << 7)
  #define PCM186X_SCK_XI_SEL0      (1 << 6)
  #define PCM186X_SCK_SRC_PLL      (1 << 5)
  #define PCM186X_MST_MODE         (1 << 4)
  #define PCM186X_ADC_SRC_PLL      (1 << 3)
  #define PCM186X_DSP2_SRC_PLL     (1 << 2)
  #define PCM186X_DSP1_SRC_PLL     (1 << 1)
  #define PCM186X_CLKDET_EN        (1 << 0)
  
  /*! @brief Page 0, Register 112 */
  #define PCM186X_PWRDN            (1 << 2)
  
  /*! @brief PCM186x I2C baudrate */
  #define PCM186X_I2C_BAUDRATE (100000U)
  
  /*! @brief audio bit width
   * @anchor _pcm186x_audio_bit_width
   */
  enum
  {
      kPCM186x_AudioBitWidth16bit = 16U, /*!< audio bit width 16 */
      kPCM186x_AudioBitWidth20bit = 20U, /*!< audio bit width 20 */
      kPCM186x_AudioBitWidth24bit = 24U, /*!< audio bit width 24 */
      kPCM186x_AudioBitWidth32bit = 32U, /*!< audio bit width 32 */
  };
  
  /*! @brief PCM186x audio format */
  typedef struct _pcm186x_audio_format
  {
      uint32_t mclk_HZ;    /*!< master clock frequency */
      uint32_t sampleRate; /*!< sample rate */
      uint32_t bitWidth;   /*!< bit width */
  } pcm186x_audio_format_t;
  
  /*! @brief Initialize structure of PCM186x */
  typedef struct pcm186x_config
  {
      pcm186x_audio_format_t format;              /*!< Audio format */
      bool master_slave;                          /*!< Master or slave. */
      uint8_t slaveAddress;                       /*!< PCM186x device address */
      codec_i2c_config_t i2cConfig;               /*!< i2c configuration */
      uint8_t gpio_led;                           /*!< led gpio number */
  } pcm186x_config_t;
  
  /*! @brief PCM186x codec handler
   */
  typedef struct _pcm186x_handle
  {
      const pcm186x_config_t *config;              /*!< PCM186x config pointer */
      uint8_t i2cHandle[PCM186X_I2C_HANDLER_SIZE]; /*!< i2c handle */
  } pcm186x_handle_t;
  
  /*******************************************************************************
   * API
   ******************************************************************************/
  #if defined(__cplusplus)
  extern "C" {
  #endif
  
  /*!
   * @brief PCM186x initialise function.
   *
   * @param handle PCM186x handle structure.
   * @param config PCM186x configuration structure.
   */
  status_t PCM186x_Init(pcm186x_handle_t *handle, const pcm186x_config_t *config);
  
  /*!
   * @brief Deinit the PCM186x codec.
   *
   * This function close all modules in PCM186x to save power.
   *
   * @param handle PCM186x handle structure pointer.
   */
  status_t PCM186x_Deinit(pcm186x_handle_t *handle);
  
  /*!
   * @brief Configure the data format of audio data.
   *
   * This function would configure the registers about the sample rate, bit depths.
   *
   * @param handle PCM186x handle structure pointer.
   * @param sysclk system clock of the codec which can be generated by MCLK or PLL output.
   * @param sample_rate Sample rate of audio file running in PCM186x.
   * @param bits Bit depth of audio file.
   */
  status_t PCM186x_SetFormat(pcm186x_handle_t *handle, uint32_t sysclk, uint32_t sample_rate, uint32_t bits);
  
  /*!
   * @brief Write register to PCM186x using I2C.
   *
   * @param handle PCM186x handle structure.
   * @param reg The register address in PCM186x.
   * @param val Value needs to write into the register.
   */
  status_t PCM186x_WriteReg(pcm186x_handle_t *handle, uint8_t reg, uint8_t val);
  
  /*!
   * @brief Read register from PCM186x using I2C.
   * @param handle PCM186x handle structure.
   * @param reg The register address in PCM186x.
   * @param val Value written to.
   */
  status_t PCM186x_ReadReg(pcm186x_handle_t *handle, uint8_t reg, uint8_t *val);
  
  /*!
   * @brief Modify some bits in the register using I2C.
   * @param handle PCM186x handle structure.
   * @param reg The register address in PCM186x.
   * @param mask The mask code for the bits want to write. The bit you want to write should be 0.
   * @param val Value needs to write into the register.
   */
  status_t PCM186x_ModifyReg(pcm186x_handle_t *handle, uint8_t reg, uint8_t mask, uint8_t val);
  
  #if defined(__cplusplus)
  }
  #endif
  
  /*! @} */
  
  #endif /* _FSL_PCM186X_H_ */
  
  /*******************************************************************************
   * API
   ******************************************************************************/
  