wm8904.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /****************************************************************************
  2. * include/nuttx/audio/wm8904.h
  3. *
  4. * Copyright (C) 2014 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Reference:
  8. * "WM8904 Ultra Low Power CODEC for Portable Audio Applications, Pre-
  9. * Production", September 2012, Rev 3.3, Wolfson Microelectronics
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in
  19. * the documentation and/or other materials provided with the
  20. * distribution.
  21. * 3. Neither the name NuttX nor the names of its contributors may be
  22. * used to endorse or promote products derived from this software
  23. * without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  28. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  29. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  30. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  31. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  32. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  33. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  35. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. ****************************************************************************/
  39. #ifndef __INCLUDE_NUTTX_AUDIO_WM8904_H
  40. #define __INCLUDE_NUTTX_AUDIO_WM8904_H
  41. /****************************************************************************
  42. * Included Files
  43. ****************************************************************************/
  44. #include <stdint.h>
  45. #include <stdbool.h>
  46. #include <nuttx/irq.h>
  47. #ifdef CONFIG_AUDIO_WM8904
  48. /****************************************************************************
  49. * Pre-processor Definitions
  50. ****************************************************************************/
  51. /* Configuration ************************************************************
  52. *
  53. * CONFIG_AUDIO_WM8904 - Enables WM8904 support
  54. * CONFIG_WM8904_INITVOLUME - The initial volume level in the range {0..1000}
  55. * CONFIG_WM8904_INFLIGHT - Maximum number of buffers that the WM8904 driver
  56. * will send to the I2S driver before any have completed.
  57. * CONFIG_WM8904_MSG_PRIO - Priority of messages sent to the WM8904 worker
  58. * thread.
  59. * CONFIG_WM8904_BUFFER_SIZE - Preferred buffer size
  60. * CONFIG_WM8904_NUM_BUFFERS - Preferred number of buffers
  61. * CONFIG_WM8904_WORKER_STACKSIZE - Stack size to use when creating the
  62. * WM8904 worker thread.
  63. * CONFIG_WM8904_REGDUMP - Enable logic to dump all WM8904 registers to
  64. * the SYSLOG device.
  65. */
  66. /* Pre-requisites */
  67. #ifndef CONFIG_AUDIO
  68. # error CONFIG_AUDIO is required for audio subsystem support
  69. #endif
  70. #ifndef CONFIG_I2S
  71. # error CONFIG_I2S is required by the WM8904 driver
  72. #endif
  73. #ifndef CONFIG_I2C
  74. # error CONFIG_I2C is required by the WM8904 driver
  75. #endif
  76. #ifndef CONFIG_SCHED_WORKQUEUE
  77. # error CONFIG_SCHED_WORKQUEUE is required by the WM8904 driver
  78. #endif
  79. /* Default configuration values */
  80. #ifndef CONFIG_WM8904_INITVOLUME
  81. # define CONFIG_WM8904_INITVOLUME 250
  82. #endif
  83. #ifndef CONFIG_WM8904_INFLIGHT
  84. # define CONFIG_WM8904_INFLIGHT 2
  85. #endif
  86. #if CONFIG_WM8904_INFLIGHT > 255
  87. # error CONFIG_WM8904_INFLIGHT must fit in a uint8_t
  88. #endif
  89. #ifndef CONFIG_WM8904_MSG_PRIO
  90. # define CONFIG_WM8904_MSG_PRIO 1
  91. #endif
  92. #ifndef CONFIG_WM8904_BUFFER_SIZE
  93. # define CONFIG_WM8904_BUFFER_SIZE 8192
  94. #endif
  95. #ifndef CONFIG_WM8904_NUM_BUFFERS
  96. # define CONFIG_WM8904_NUM_BUFFERS 4
  97. #endif
  98. #ifndef CONFIG_WM8904_WORKER_STACKSIZE
  99. # define CONFIG_WM8904_WORKER_STACKSIZE 768
  100. #endif
  101. /* Helper macros ************************************************************/
  102. #define WM8904_ATTACH(s,isr,arg) ((s)->attach(s,isr,arg))
  103. #define WM8904_DETACH(s) ((s)->attach(s,NULL,NULL))
  104. #define WM8904_ENABLE(s) ((s)->enable(s,true))
  105. #define WM8904_DISABLE(s) ((s)->enable(s,false))
  106. #define WM8904_RESTORE(s,e) ((s)->enable(s,e))
  107. /****************************************************************************
  108. * Public Types
  109. ****************************************************************************/
  110. /* This is the type of the WM8904 interrupt handler. The lower level code
  111. * will intercept the interrupt and provide the upper level with the private
  112. * data that was provided when the interrupt was attached.
  113. */
  114. struct wm8904_lower_s; /* Forward reference. Defined below */
  115. typedef CODE int (*wm8904_handler_t)(FAR const struct wm8904_lower_s *lower,
  116. FAR void *arg);
  117. /* A reference to a structure of this type must be passed to the WM8904
  118. * driver. This structure provides information about the configuration
  119. * of the WM8904 and provides some board-specific hooks.
  120. *
  121. * Memory for this structure is provided by the caller. It is not copied
  122. * by the driver and is presumed to persist while the driver is active.
  123. */
  124. struct wm8904_lower_s
  125. {
  126. /* I2C characterization */
  127. uint32_t frequency; /* Initial I2C frequency */
  128. uint8_t address; /* 7-bit I2C address (only bits 0-6 used) */
  129. /* Clocking is provided via MCLK. The WM8904 driver will need to know
  130. * the frequency of MCLK in order to generate the correct bitrates.
  131. */
  132. uint32_t mclk; /* W8904 Master clock frequency */
  133. /* IRQ/GPIO access callbacks. These operations all hidden behind
  134. * callbacks to isolate the WM8904 driver from differences in GPIO
  135. * interrupt handling by varying boards and MCUs. If possible,
  136. * interrupts should be configured on both rising and falling edges
  137. * so that contact and loss-of-contact events can be detected.
  138. *
  139. * attach - Attach or detach the WM8904 interrupt handler to the GPIO
  140. * interrupt
  141. * enable - Enable or disable the GPIO interrupt. Returns the
  142. * previous interrupt state.
  143. */
  144. CODE int (*attach)(FAR const struct wm8904_lower_s *lower,
  145. wm8904_handler_t isr, FAR void *arg);
  146. CODE bool (*enable)(FAR const struct wm8904_lower_s *lower, bool enable);
  147. };
  148. /****************************************************************************
  149. * Public Data
  150. ****************************************************************************/
  151. #ifdef __cplusplus
  152. #define EXTERN extern "C"
  153. extern "C"
  154. {
  155. #else
  156. #define EXTERN extern
  157. #endif
  158. /****************************************************************************
  159. * Public Function Prototypes
  160. ****************************************************************************/
  161. /****************************************************************************
  162. * Name: wm8904_initialize
  163. *
  164. * Description:
  165. * Initialize the WM8904 device.
  166. *
  167. * Input Parameters:
  168. * i2c - An I2C driver instance
  169. * i2s - An I2S driver instance
  170. * lower - Persistent board configuration data
  171. *
  172. * Returned Value:
  173. * A new lower half audio interface for the WM8904 device is returned on
  174. * success; NULL is returned on failure.
  175. *
  176. ****************************************************************************/
  177. struct i2c_master_s; /* Forward reference. Defined in include/nuttx/i2c/i2c_master.h */
  178. struct i2s_dev_s; /* Forward reference. Defined in include/nuttx/audio/i2s.h */
  179. struct audio_lowerhalf_s; /* Forward reference. Defined in nuttx/audio/audio.h */
  180. FAR struct audio_lowerhalf_s *
  181. wm8904_initialize(FAR struct i2c_master_s *i2c, FAR struct i2s_dev_s *i2s,
  182. FAR const struct wm8904_lower_s *lower);
  183. /****************************************************************************
  184. * Name: wm8904_dump_registers
  185. *
  186. * Description:
  187. * Dump the contents of all WM8904 registers to the syslog device
  188. *
  189. * Input Parameters:
  190. * dev - The device instance returned by wm8904_initialize
  191. *
  192. * Returned Value:
  193. * None.
  194. *
  195. ****************************************************************************/
  196. #ifdef CONFIG_WM8904_REGDUMP
  197. void wm8904_dump_registers(FAR struct audio_lowerhalf_s *dev,
  198. FAR const char *msg);
  199. #else
  200. /* This eliminates the need for any conditional compilation in the
  201. * including file.
  202. */
  203. # define wm8904_dump_registers(d,m)
  204. #endif
  205. /****************************************************************************
  206. * Name: wm8904_clock_analysis
  207. *
  208. * Description:
  209. * Analyze the settings in the clock chain and dump to syslog.
  210. *
  211. * Input Parameters:
  212. * dev - The device instance returned by wm8904_initialize
  213. *
  214. * Returned Value:
  215. * None.
  216. *
  217. ****************************************************************************/
  218. #ifdef CONFIG_WM8904_CLKDEBUG
  219. void wm8904_clock_analysis(FAR struct audio_lowerhalf_s *dev,
  220. FAR const char *msg);
  221. #else
  222. /* This eliminates the need for any conditional compilation in the
  223. * including file.
  224. */
  225. # define wm8904_clock_analysis(d,m)
  226. #endif
  227. #undef EXTERN
  228. #ifdef __cplusplus
  229. }
  230. #endif
  231. #endif /* CONFIG_AUDIO_WM8904 */
  232. #endif /* __INCLUDE_NUTTX_AUDIO_WM8904_H */