fsl_wm8904.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2019 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #ifndef _FSL_WM8904_H_
  9. #define _FSL_WM8904_H_
  10. #include "fsl_common.h"
  11. #include "fsl_codec_i2c.h"
  12. /*!
  13. * @addtogroup wm8904
  14. * @{
  15. */
  16. /*******************************************************************************
  17. * Definitions
  18. ******************************************************************************/
  19. /*! @name Driver version */
  20. /*@{*/
  21. /*! @brief WM8904 driver version 2.1.0. */
  22. #define FSL_WM8904_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
  23. /*@}*/
  24. /*! @brief wm8904 handle size */
  25. #ifndef WM8904_HANDLE_SIZE
  26. #define WM8904_HANDLE_SIZE (100U)
  27. #endif
  28. /*! @brief wm8904 debug macro */
  29. #ifndef WM8904_DEBUG_REGISTER
  30. #define WM8904_DEBUG_REGISTER 0
  31. #endif
  32. /*! @brief WM8904 register map*/
  33. #define WM8904_RESET (0x00)
  34. #define WM8904_ANALOG_ADC_0 (0x0A)
  35. #define WM8904_POWER_MGMT_0 (0x0C)
  36. #define WM8904_POWER_MGMT_2 (0x0E)
  37. #define WM8904_POWER_MGMT_3 (0x0F)
  38. #define WM8904_POWER_MGMT_6 (0x12)
  39. #define WM8904_CLK_RATES_0 (0x14)
  40. #define WM8904_CLK_RATES_1 (0x15)
  41. #define WM8904_CLK_RATES_2 (0x16)
  42. #define WM8904_AUDIO_IF_0 (0x18)
  43. #define WM8904_AUDIO_IF_1 (0x19)
  44. #define WM8904_AUDIO_IF_2 (0x1A)
  45. #define WM8904_AUDIO_IF_3 (0x1B)
  46. #define WM8904_DAC_DIG_1 (0x21)
  47. #define WM8904_DAC_DIG_0 (0x27)
  48. #define WM8904_ANALOG_LEFT_IN_0 (0x2C)
  49. #define WM8904_ANALOG_RIGHT_IN_0 (0x2D)
  50. #define WM8904_ANALOG_LEFT_IN_1 (0x2E)
  51. #define WM8904_ANALOG_RIGHT_IN_1 (0x2F)
  52. #define WM8904_ANALOG_OUT1_LEFT (0x39)
  53. #define WM8904_ANALOG_OUT1_RIGHT (0x3A)
  54. #define WM8904_ANALOG_OUT12_ZC (0x3D)
  55. #define WM8904_DC_SERVO_0 (0x43)
  56. #define WM8904_ANALOG_HP_0 (0x5A)
  57. #define WM8904_CHRG_PUMP_0 (0x62)
  58. #define WM8904_CLS_W_0 (0x68)
  59. #define WM8904_WRT_SEQUENCER_0 (0x6C)
  60. #define WM8904_WRT_SEQUENCER_3 (0x6F)
  61. #define WM8904_WRT_SEQUENCER_4 (0x70)
  62. #define WM8904_DAC_DIGITAL_VOLUME_LEFT (0x1E)
  63. #define WM8904_DAC_DIGITAL_VOLUME_RIGHT (0x1F)
  64. #define WM8904_ADC_DIGITAL_VOLUME_LEFT (0x24)
  65. #define WM8904_ADC_DIGITAL_VOLUME_RIGHT (0x25)
  66. #define WM8904_ANALOG_OUT2_LEFT (0x3B)
  67. #define WM8904_ANALOG_OUT2_RIGHT (0x3C)
  68. /*! @brief WM8904 I2C address. */
  69. #define WM8904_I2C_ADDRESS (0x1A)
  70. /*! @brief WM8904 I2C bit rate. */
  71. #define WM8904_I2C_BITRATE (400000U)
  72. /*! @brief WM8904 status return codes. */
  73. enum _wm8904_status
  74. {
  75. kStatus_WM8904_Success = 0x0, /*!< Success */
  76. kStatus_WM8904_Fail = 0x1 /*!< Failure */
  77. };
  78. /*! @brief WM8904 lrc polarity. */
  79. enum _wm8904_lrc_polarity
  80. {
  81. kWM8904_LRCPolarityNormal = 0U, /*!< LRC polarity normal */
  82. kWM8904_LRCPolarityInverted = 1U << 4U, /*!< LRC polarity inverted */
  83. };
  84. /*! @brief wm8904 module value*/
  85. typedef enum _wm8904_module
  86. {
  87. kWM8904_ModuleADC = 0, /*!< moduel ADC */
  88. kWM8904_ModuleDAC = 1, /*!< module DAC */
  89. kWM8904_ModulePGA = 2, /*!< module PGA */
  90. kWM8904_ModuleHeadphone = 3, /*!< module headphone */
  91. kWM8904_ModuleLineout = 4, /*!< module line out */
  92. } wm8904_module_t;
  93. /*! @brief wm8904 play channel */
  94. enum _wm8904_play_channel
  95. {
  96. kWM8904_HeadphoneLeft = 1U,
  97. kWM8904_HeadphoneRight = 2U,
  98. kWM8904_LineoutLeft = 4U,
  99. kWM8904_LineoutRight = 8U,
  100. };
  101. /*! @brief WM8904 time slot. */
  102. typedef enum _wm8904_timeslot
  103. {
  104. kWM8904_TimeSlot0 = 0U, /*!< time slot0 */
  105. kWM8904_TimeSlot1 = 1U, /*!< time slot1 */
  106. } wm8904_timeslot_t;
  107. /*! @brief The audio data transfer protocol. */
  108. typedef enum _wm8904_protocol
  109. {
  110. kWM8904_ProtocolI2S = 0x2, /*!< I2S type */
  111. kWM8904_ProtocolLeftJustified = 0x1, /*!< Left justified mode */
  112. kWM8904_ProtocolRightJustified = 0x0, /*!< Right justified mode */
  113. kWM8904_ProtocolPCMA = 0x3, /*!< PCM A mode */
  114. kWM8904_ProtocolPCMB = 0x3 | (1 << 4), /*!< PCM B mode */
  115. } wm8904_protocol_t;
  116. /*! @brief The SYSCLK / fs ratio. */
  117. typedef enum _wm8904_fs_ratio
  118. {
  119. kWM8904_FsRatio64X = 0x0, /*!< SYSCLK is 64 * sample rate * frame width */
  120. kWM8904_FsRatio128X = 0x1, /*!< SYSCLK is 128 * sample rate * frame width */
  121. kWM8904_FsRatio192X = 0x2, /*!< SYSCLK is 192 * sample rate * frame width */
  122. kWM8904_FsRatio256X = 0x3, /*!< SYSCLK is 256 * sample rate * frame width */
  123. kWM8904_FsRatio384X = 0x4, /*!< SYSCLK is 384 * sample rate * frame width */
  124. kWM8904_FsRatio512X = 0x5, /*!< SYSCLK is 512 * sample rate * frame width */
  125. kWM8904_FsRatio768X = 0x6, /*!< SYSCLK is 768 * sample rate * frame width */
  126. kWM8904_FsRatio1024X = 0x7, /*!< SYSCLK is 1024 * sample rate * frame width */
  127. kWM8904_FsRatio1408X = 0x8, /*!< SYSCLK is 1408 * sample rate * frame width */
  128. kWM8904_FsRatio1536X = 0x9 /*!< SYSCLK is 1536 * sample rate * frame width */
  129. } wm8904_fs_ratio_t;
  130. /*! @brief Sample rate. */
  131. typedef enum _wm8904_sample_rate
  132. {
  133. kWM8904_SampleRate8kHz = 0x0, /*!< 8 kHz */
  134. kWM8904_SampleRate12kHz = 0x1, /*!< 11.025kHz, 12kHz */
  135. kWM8904_SampleRate16kHz = 0x2, /*!< 16kHz */
  136. kWM8904_SampleRate24kHz = 0x3, /*!< 22.05kHz, 24kHz */
  137. kWM8904_SampleRate32kHz = 0x4, /*!< 32kHz */
  138. kWM8904_SampleRate48kHz = 0x5 /*!< 44.1kHz, 48kHz */
  139. } wm8904_sample_rate_t;
  140. /*! @brief Bit width. */
  141. typedef enum _wm8904_bit_width
  142. {
  143. kWM8904_BitWidth16 = 0x0, /*!< 16 bits */
  144. kWM8904_BitWidth20 = 0x1, /*!< 20 bits */
  145. kWM8904_BitWidth24 = 0x2, /*!< 24 bits */
  146. kWM8904_BitWidth32 = 0x3 /*!< 32 bits */
  147. } wm8904_bit_width_t;
  148. /*! @brief wm8904 record source */
  149. enum _wm8904_record_source
  150. {
  151. kWM8904_RecordSourceDifferentialLine = 1U, /*!< record source from differential line */
  152. kWM8904_RecordSourceLineInput = 2U, /*!< record source from line input */
  153. kWM8904_RecordSourceDifferentialMic = 4U, /*!< record source from differential mic */
  154. kWM8904_RecordSourceDigitalMic = 8U, /*!< record source from digital microphone */
  155. };
  156. /*! @brief wm8904 record channel*/
  157. enum _wm8904_record_channel
  158. {
  159. kWM8904_RecordChannelLeft1 = 1U, /*!< left record channel 1 */
  160. kWM8904_RecordChannelLeft2 = 2U, /*!< left record channel 2 */
  161. kWM8904_RecordChannelLeft3 = 4U, /*!< left record channel 3 */
  162. kWM8904_RecordChannelRight1 = 1U, /*!< right record channel 1 */
  163. kWM8904_RecordChannelRight2 = 2U, /*!< right record channel 2 */
  164. kWM8904_RecordChannelRight3 = 4U, /*!< right record channel 3 */
  165. kWM8904_RecordChannelDifferentialPositive1 = 1U, /*!< differential positive record channel 1 */
  166. kWM8904_RecordChannelDifferentialPositive2 = 2U, /*!< differential positive record channel 2 */
  167. kWM8904_RecordChannelDifferentialPositive3 = 4U, /*!< differential positive record channel 3 */
  168. kWM8904_RecordChannelDifferentialNegative1 = 8U, /*!< differential negative record channel 1 */
  169. kWM8904_RecordChannelDifferentialNegative2 = 16U, /*!< differential negative record channel 2 */
  170. kWM8904_RecordChannelDifferentialNegative3 = 32U, /*!< differential negative record channel 3 */
  171. };
  172. /*! @brief wm8904 play source*/
  173. enum _wm8904_play_source
  174. {
  175. kWM8904_PlaySourcePGA = 1U, /*!< play source PGA, bypass ADC */
  176. kWM8904_PlaySourceDAC = 4U, /*!< play source Input3 */
  177. };
  178. /*! @brief Audio format configuration. */
  179. typedef struct _wm8904_audio_format
  180. {
  181. wm8904_fs_ratio_t fsRatio; /*!< SYSCLK / fs ratio */
  182. wm8904_sample_rate_t sampleRate; /*!< Sample rate */
  183. wm8904_bit_width_t bitWidth; /*!< Bit width */
  184. } wm8904_audio_format_t;
  185. /*! @brief Configuration structure of WM8904.*/
  186. typedef struct _wm8904_config
  187. {
  188. bool master; /*!< Master or slave */
  189. wm8904_protocol_t protocol; /*!< Audio transfer protocol */
  190. wm8904_audio_format_t format; /*!< Audio format */
  191. uint32_t mclk_HZ; /*!< MCLK frequency value */
  192. uint16_t recordSource; /*!< record source */
  193. uint16_t recordChannelLeft; /*!< record channel */
  194. uint16_t recordChannelRight; /*!< record channel */
  195. uint16_t playSource; /*!< play source */
  196. uint8_t slaveAddress; /*!< code device slave address */
  197. codec_i2c_config_t i2cConfig; /*!< i2c bus configuration */
  198. } wm8904_config_t;
  199. /*! @brief wm8904 codec handler
  200. * Applicationi should allocate a buffer with WM8904_HANDLE_SIZE for handle definition, such as
  201. * uint8_t wm8904HandleBuffer[WM8904_HANDLE_SIZE];
  202. * wm8904_handle_t *wm8904Handle = wm8904HandleBuffer;
  203. */
  204. typedef struct _wm8904_handle
  205. {
  206. wm8904_config_t *config; /*!< wm8904 config pointer */
  207. void *i2cHandle; /*!< i2c handle */
  208. } wm8904_handle_t;
  209. /*******************************************************************************
  210. * API
  211. ******************************************************************************/
  212. #if defined(__cplusplus)
  213. extern "C" {
  214. #endif
  215. /*!
  216. * @brief WM8904 write register.
  217. *
  218. * @param handle WM8904 handle structure.
  219. * @param reg register address.
  220. * @param value value to write.
  221. * @return kStatus_Success, else failed.
  222. */
  223. status_t WM8904_WriteRegister(wm8904_handle_t *handle, uint8_t reg, uint16_t value);
  224. /*!
  225. * @brief WM8904 write register.
  226. *
  227. * @param handle WM8904 handle structure.
  228. * @param reg register address.
  229. * @param value value to read.
  230. * @return kStatus_Success, else failed.
  231. */
  232. status_t WM8904_ReadRegister(wm8904_handle_t *handle, uint8_t reg, uint16_t *value);
  233. /*!
  234. * @brief WM8904 modify register.
  235. *
  236. * @param handle WM8904 handle structure.
  237. * @param reg register address.
  238. * @oaram mask register bits mask.
  239. * @param value value to write.
  240. * @return kStatus_Success, else failed.
  241. */
  242. status_t WM8904_ModifyRegister(wm8904_handle_t *handle, uint8_t reg, uint16_t mask, uint16_t value);
  243. /*!
  244. * @brief Initializes WM8904.
  245. *
  246. * @param handle WM8904 handle structure.
  247. * @param codec_config WM8904 configuration structure.
  248. */
  249. status_t WM8904_Init(wm8904_handle_t *handle, wm8904_config_t *wm8904_config);
  250. /*!
  251. * @brief Deinitializes the WM8904 codec.
  252. *
  253. * This function resets WM8904.
  254. *
  255. * @param handle WM8904 handle structure.
  256. *
  257. * @return kStatus_WM8904_Success if successful, different code otherwise.
  258. */
  259. status_t WM8904_Deinit(wm8904_handle_t *handle);
  260. /*!
  261. * @brief Fills the configuration structure with default values.
  262. *
  263. * The default values are:
  264. *
  265. * master = false;
  266. * protocol = kWM8904_ProtocolI2S;
  267. * format.fsRatio = kWM8904_FsRatio64X;
  268. * format.sampleRate = kWM8904_SampleRate48kHz;
  269. * format.bitWidth = kWM8904_BitWidth16;
  270. *
  271. * @param handle WM8904 handle structure to be filled with default values.
  272. */
  273. void WM8904_GetDefaultConfig(wm8904_config_t *config);
  274. /*!
  275. * @brief Sets WM8904 as master or slave.
  276. *
  277. * @param handle WM8904 handle structure.
  278. * @param master true for master, false for slave.
  279. *
  280. * @return kStatus_WM8904_Success if successful, different code otherwise.
  281. */
  282. status_t WM8904_SetMasterSlave(wm8904_handle_t *handle, bool master);
  283. /*!
  284. * @brief Sets the audio data transfer protocol.
  285. *
  286. * @param handle WM8904 handle structure.
  287. * @param protocol Audio transfer protocol.
  288. *
  289. * @return kStatus_WM8904_Success if successful, different code otherwise.
  290. */
  291. status_t WM8904_SetProtocol(wm8904_handle_t *handle, wm8904_protocol_t protocol);
  292. /*!
  293. * @brief Sets the audio data format.
  294. *
  295. * @param handle WM8904 handle structure.
  296. * @param sysclk System clock frequency for codec, user should pay attention to this parater, sysclk is caculate as
  297. * SYSCLK = MCLK / MCLKDIV, MCLKDIV is bit0 of WM8904_CLK_RATES_0.
  298. * @param sampleRate Sample rate frequency in Hz.
  299. * @param bitWidth Audio data bit width.
  300. *
  301. * @return kStatus_WM8904_Success if successful, different code otherwise.
  302. */
  303. status_t WM8904_SetAudioFormat(wm8904_handle_t *handle, uint32_t sysclk, uint32_t sampleRate, uint32_t bitWidth);
  304. /*!
  305. * @brief check and update the audio data format.
  306. * This api is used check the fsRatio setting based on the mclk and sample rate, if fsRatio setting
  307. * is not correct, it will correct it according to mclk and sample rate.
  308. * @param handle WM8904 handle structure.
  309. * @param format audio data format
  310. * @param mclkFreq mclk frequency
  311. *
  312. * @return kStatus_WM8904_Success if successful, different code otherwise.
  313. */
  314. status_t WM8904_CheckAudioFormat(wm8904_handle_t *handle, wm8904_audio_format_t *format, uint32_t mclkFreq);
  315. /*!
  316. * @brief Sets the module output volume.
  317. *
  318. * The parameter should be from 0 to 100.
  319. * The resulting volume will be.
  320. * 0 for mute, 100 for maximum volume value.
  321. *
  322. * @param handle WM8904 handle structure.
  323. * @param module wm8904 module name.
  324. * @param volume volume value.
  325. *
  326. * @return kStatus_WM8904_Success if successful, different code otherwise.
  327. */
  328. status_t WM8904_SetVolume(wm8904_handle_t *handle, uint16_t volumeLeft, uint16_t volumeRight);
  329. /*!
  330. * @brief Sets the headphone output mute.
  331. *
  332. * @param handle WM8904 handle structure.
  333. * @param muteLeft true to mute left channel, false to unmute.
  334. * @param muteRight true to mute right channel, false to unmute.
  335. *
  336. * @return kStatus_WM8904_Success if successful, different code otherwise.
  337. */
  338. status_t WM8904_SetMute(wm8904_handle_t *handle, bool muteLeft, bool muteRight);
  339. /*!
  340. * @brief Select LRC polarity.
  341. *
  342. * @param handle WM8904 handle structure.
  343. * @param polarity LRC clock polarity.
  344. *
  345. * @return kStatus_WM8904_Success if successful, different code otherwise.
  346. */
  347. status_t WM8904_SelectLRCPolarity(wm8904_handle_t *handle, uint32_t polarity);
  348. /*!
  349. * @brief Enable WM8904 DAC time slot.
  350. *
  351. * @param handle WM8904 handle structure.
  352. * @param timeslot timeslot number.
  353. *
  354. * @return kStatus_WM8904_Success if successful, different code otherwise.
  355. */
  356. status_t WM8904_EnableDACTDMMode(wm8904_handle_t *handle, wm8904_timeslot_t timeSlot);
  357. /*!
  358. * @brief Enable WM8904 ADC time slot.
  359. *
  360. * @param handle WM8904 handle structure.
  361. * @param timeslot timeslot number.
  362. *
  363. * @return kStatus_WM8904_Success if successful, different code otherwise.
  364. */
  365. status_t WM8904_EnableADCTDMMode(wm8904_handle_t *handle, wm8904_timeslot_t timeSlot);
  366. #if WM8904_DEBUG_REGISTER
  367. /*!
  368. * @brief Reads content of all WM8904 registers and prints it to debug console.
  369. *
  370. * @param handle WM8904 handle structure.
  371. *
  372. * @return kStatus_WM8904_Success if successful, different code otherwise.
  373. */
  374. status_t WM8904_PrintRegisters(wm8904_handle_t *handle);
  375. #endif
  376. /*!
  377. * brief SET the module output power.
  378. *
  379. * param handle WM8904 handle structure.
  380. * param module wm8904 module.
  381. * param isEnabled, true is power on, false is power down.
  382. *
  383. * return kStatus_WM8904_Success if successful, different code otherwise..
  384. */
  385. status_t WM8904_SetModulePower(wm8904_handle_t *handle, wm8904_module_t module, bool isEnabled);
  386. /*!
  387. * @brief Sets the channel output volume.
  388. *
  389. * The parameter should be from 0 to 100.
  390. * The resulting volume will be.
  391. * 0 for mute, 100 for maximum volume value.
  392. *
  393. * param handle codec handle structure.
  394. * @param channel codec channel.
  395. * @param volume volume value.
  396. *
  397. * @return kStatus_WM8904_Success if successful, different code otherwise.
  398. */
  399. status_t WM8904_SetChannelVolume(wm8904_handle_t *handle, uint32_t channel, uint32_t volume);
  400. /*!
  401. * @brief SET the WM8904 record source.
  402. *
  403. * @param handle WM8904 handle structure.
  404. * @param recordSource record source , can be a value of kCODEC_ModuleRecordSourceDifferentialLine,
  405. * kCODEC_ModuleRecordSourceDifferentialMic, kCODEC_ModuleRecordSourceSingleEndMic, kCODEC_ModuleRecordSourceDigitalMic.
  406. *
  407. * @return kStatus_WM8904_Success if successful, different code otherwise.
  408. */
  409. status_t WM8904_SetRecord(wm8904_handle_t *handle, uint32_t recordSource);
  410. /*!
  411. * @brief SET the WM8904 record source.
  412. *
  413. * @param handle WM8904 handle structure.
  414. * @param leftRecordChannel channel number of left record channel when using differential source, channel number of
  415. * single end left channel when using single end source, channel number of digital mic when using digital mic source.
  416. * @param rightRecordChannel channel number of right record channel when using differential source, channel number
  417. * of single end right channel when using single end source.
  418. *
  419. * @return kStatus_WM8904_Success if successful, different code otherwise..
  420. */
  421. status_t WM8904_SetRecordChannel(wm8904_handle_t *handle, uint32_t leftRecordChannel, uint32_t rightRecordChannel);
  422. /*!
  423. * @brief SET the WM8904 play source.
  424. *
  425. * @param handle WM8904 handle structure.
  426. * @param playSource play source , can be a value of kCODEC_ModuleHeadphoneSourcePGA,
  427. * kCODEC_ModuleHeadphoneSourceDAC, kCODEC_ModuleLineoutSourcePGA, kCODEC_ModuleLineoutSourceDAC.
  428. *
  429. * @return kStatus_WM8904_Success if successful, different code otherwise..
  430. */
  431. status_t WM8904_SetPlay(wm8904_handle_t *handle, uint32_t playSource);
  432. /*!
  433. * @brief Sets the channel mute.
  434. *
  435. * @param handle codec handle structure.
  436. * @param module codec module name.
  437. * @param isMute true is mute, false unmute.
  438. *
  439. * @return kStatus_WM8904_Success if successful, different code otherwise.
  440. */
  441. status_t WM8904_SetChannelMute(wm8904_handle_t *handle, uint32_t channel, bool isMute);
  442. #if defined(__cplusplus)
  443. }
  444. #endif
  445. /*! @} */
  446. #endif /* _FSL_WM8904_H_ */