1
0

drv_wm8994.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-07-02 thread-liu first version
  9. */
  10. #include "board.h"
  11. #if defined(BSP_USING_AUDIO)
  12. #include <drv_wm8994.h>
  13. #define DRV_DEBUG
  14. #define LOG_TAG "drv.wm8994"
  15. #include <drv_log.h>
  16. #define CHIP_ADDRESS 0x1B /* wm8994 address */
  17. #define I2C_NAME "i2c2"
  18. struct wm8994_dev
  19. {
  20. struct rt_device dev;
  21. struct rt_i2c_bus_device *i2c_bus;
  22. rt_uint16_t id;
  23. rt_uint16_t type;
  24. };
  25. static struct wm8994_dev rt_wm8994 = {0};
  26. /* i2c read reg */
  27. static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint8_t len, rt_uint8_t *buf)
  28. {
  29. struct rt_i2c_msg msg[2] = {0, 0};
  30. static rt_uint8_t i2c_reg[2] = {0, 0};
  31. RT_ASSERT(bus != RT_NULL);
  32. i2c_reg[0] = ((uint16_t)(reg >> 8) & 0xFF);
  33. i2c_reg[1] = ((uint16_t)(reg) & 0xFF);
  34. msg[0].addr = CHIP_ADDRESS;
  35. msg[0].flags = RT_I2C_WR;
  36. msg[0].buf = i2c_reg;
  37. msg[0].len = 2;
  38. msg[1].addr = CHIP_ADDRESS;
  39. msg[1].flags = RT_I2C_RD;
  40. msg[1].len = len;
  41. msg[1].buf = buf;
  42. if (rt_i2c_transfer(bus, msg, 2) == 2)
  43. {
  44. return RT_EOK;
  45. }
  46. return RT_ERROR;
  47. }
  48. /* i2c write reg */
  49. static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint16_t data)
  50. {
  51. rt_uint8_t buf[4];
  52. struct rt_i2c_msg msgs;
  53. RT_ASSERT(bus != RT_NULL);
  54. buf[0] = ((uint16_t)(reg >> 8) & 0xFF);
  55. buf[1] = ((uint16_t)(reg) & 0xFF);
  56. buf[2] = ((uint16_t)(data >> 8) & 0xFF);
  57. buf[3] = ((uint16_t)(data) & 0xFF);
  58. msgs.addr = CHIP_ADDRESS;
  59. msgs.flags = RT_I2C_WR;
  60. msgs.buf = buf;
  61. msgs.len = 4;
  62. if (rt_i2c_transfer(bus, &msgs, 1) == 1)
  63. {
  64. return RT_EOK;
  65. }
  66. return RT_ERROR;
  67. }
  68. static rt_err_t wm8994_set_output_mode(struct rt_i2c_bus_device *bus, rt_uint16_t mode)
  69. {
  70. switch (mode & 0x000F)
  71. {
  72. case OUTPUT_DEVICE_SPEAKER:
  73. /* Enable DAC1 (Left), Enable DAC1 (Right),
  74. * Disable DAC2 (Left), Disable DAC2 (Right) */
  75. write_reg(bus, 0x0005, 0x0C0C);
  76. /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
  77. write_reg(bus, 0x0601, 0x0000);
  78. /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
  79. write_reg(bus, 0x0602, 0x0000);
  80. /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
  81. write_reg(bus, 0x0604, 0x0002);
  82. /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
  83. write_reg(bus, 0x0605, 0x0002);
  84. break;
  85. case OUTPUT_DEVICE_HEADPHONE:
  86. /* Disable DAC1 (Left), Disable DAC1 (Right),
  87. Enable DAC2 (Left), Enable DAC2 (Right)*/
  88. write_reg(bus, 0x05, 0x0303);
  89. /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
  90. write_reg(bus, 0x0601, 0x01);
  91. /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
  92. write_reg(bus, 0x0602, 0x01);
  93. /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
  94. write_reg(bus, 0x0604, 0x00);
  95. /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
  96. write_reg(bus, 0x0605, 0x00);
  97. break;
  98. case OUTPUT_DEVICE_BOTH:
  99. default:
  100. break;
  101. }
  102. return RT_EOK;
  103. }
  104. static rt_err_t wm8994_set_input_mode(struct rt_i2c_bus_device *bus, rt_uint16_t mode)
  105. {
  106. switch (mode & 0x01F0)
  107. {
  108. case INPUT_DEVICE_DIGITAL_MICROPHONE_2:
  109. /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
  110. * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
  111. * Enable Left ADC, Enable Right ADC */
  112. write_reg(bus, 0x04, 0x0C30);
  113. /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
  114. write_reg(bus, 0x0450, 0x00DB);
  115. /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
  116. write_reg(bus, 0x02, 0x6000);
  117. /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
  118. write_reg(bus, 0x0608, 0x0002);
  119. /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
  120. write_reg(bus, 0x0609, 0x0002);
  121. /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
  122. write_reg(bus, 0x0700, 0x000E);
  123. break;
  124. case INPUT_DEVICE_INPUT_LINE_1:
  125. /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
  126. write_reg(bus, 0x28, 0x0011);
  127. /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
  128. write_reg(bus, 0x29, 0x0035);
  129. /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
  130. write_reg(bus, 0x2A, 0x0035);
  131. /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
  132. * Enable Left ADC, Enable Right ADC */
  133. write_reg(bus, 0x04, 0x0303);
  134. /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
  135. write_reg(bus, 0x0440, 0x00DB);
  136. /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
  137. write_reg(bus, 0x02, 0x6350);
  138. /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
  139. write_reg(bus, 0x0606, 0x0002);
  140. /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
  141. write_reg(bus, 0x0607, 0x0002);
  142. /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
  143. write_reg(bus, 0x0700, 0x000D);
  144. break;
  145. case INPUT_DEVICE_DIGITAL_MICROPHONE_1:
  146. /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
  147. * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
  148. * Enable Left ADC, Enable Right ADC */
  149. write_reg(bus, 0x04, 0x030C);
  150. /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
  151. write_reg(bus, 0x0440, 0x00DB);
  152. /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
  153. write_reg(bus, 0x02, 0x6350);
  154. /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
  155. write_reg(bus, 0x0606, 0x0002);
  156. /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
  157. write_reg(bus, 0x0607, 0x0002);
  158. /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
  159. write_reg(bus, 0x0700, 0x000D);
  160. break;
  161. case INPUT_DEVICE_DIGITAL_MIC1_MIC2:
  162. /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
  163. * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
  164. * Enable Left ADC, Enable Right ADC */
  165. write_reg(bus, 0x04, 0x0F3C);
  166. /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
  167. write_reg(bus, 0x0450, 0x00DB);
  168. /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
  169. write_reg(bus, 0x0440, 0x00DB);
  170. /* Disable IN1L, IN1R, Enable IN2L, IN2R, Thermal sensor & shutdown */
  171. write_reg(bus, 0x02, 0x63A0);
  172. /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
  173. write_reg(bus, 0x0606, 0x0002);
  174. /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
  175. write_reg(bus, 0x0607, 0x0002);
  176. /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
  177. write_reg(bus, 0x0608, 0x0002);
  178. /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
  179. write_reg(bus, 0x0609, 0x0002);
  180. /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
  181. write_reg(bus, 0x0700, 0x000D);
  182. break;
  183. case INPUT_DEVICE_INPUT_LINE_2:
  184. default:
  185. /* Actually, no other input devices supported */
  186. break;
  187. }
  188. return RT_EOK;
  189. }
  190. static rt_err_t _wm8994_init(struct wm8994_dev *dev)
  191. {
  192. RT_ASSERT(dev != RT_NULL);
  193. /* wm8994 Errata Work-Arounds */
  194. write_reg(dev->i2c_bus, 0x0102, 0x0003);
  195. write_reg(dev->i2c_bus, 0x0817, 0x0000);
  196. write_reg(dev->i2c_bus, 0x0102, 0x0000);
  197. /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
  198. write_reg(dev->i2c_bus, 0x0039, 0x006C);
  199. /* Enable bias generator, Enable VMID */
  200. if ((dev->type & 0x01F0) != 0)
  201. {
  202. /* audio input */
  203. write_reg(dev->i2c_bus, 0x0001, 0x0013);
  204. }
  205. else
  206. {
  207. /* audio output */
  208. write_reg(dev->i2c_bus, 0x0001, 0x0003);
  209. }
  210. rt_thread_mdelay(50);
  211. if ((dev->type & 0x000F) != 0 )
  212. {
  213. /* Path Configurations for output */
  214. wm8994_set_output_mode(dev->i2c_bus, dev->type);
  215. }
  216. if ((dev->type & 0x01F0) != 0 )
  217. {
  218. /* Path Configurations for input */
  219. wm8994_set_input_mode(dev->i2c_bus, dev->type);
  220. }
  221. if (dev->type & INPUT_DEVICE_DIGITAL_MIC1_MIC2)
  222. {
  223. /* AIF1 Word Length = 16-bits, AIF1 Format = DSP mode */
  224. write_reg(dev->i2c_bus, 0x0300, 0x4018);
  225. }
  226. else
  227. {
  228. /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
  229. write_reg(dev->i2c_bus, 0x0300, 0x4010);
  230. }
  231. /* slave mode */
  232. write_reg(dev->i2c_bus, 0x0302, 0x0000);
  233. /* Enable the DSP processing clock for AIF1, Enable the core clock */
  234. write_reg(dev->i2c_bus, 0x0208, 0x000A);
  235. /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
  236. write_reg(dev->i2c_bus, 0x0200, 0x0001);
  237. /* Audio output selected */
  238. if ((dev->type & 0x000F) != 0 )
  239. {
  240. if (dev->type & OUTPUT_DEVICE_HEADPHONE)
  241. {
  242. /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
  243. write_reg(dev->i2c_bus, 0x2D, 0x0100);
  244. /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
  245. write_reg(dev->i2c_bus, 0x2E, 0x0100);
  246. /* Startup sequence for Headphone */
  247. write_reg(dev->i2c_bus, 0x0110, 0x8100);
  248. rt_thread_mdelay(300);
  249. /* Soft un-Mute the AIF1 Timeslot 0 DAC1 path L&R */
  250. write_reg(dev->i2c_bus, 0x0420, 0x0000);
  251. }
  252. /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
  253. write_reg(dev->i2c_bus, 0x03, 0x0300);
  254. /* Left Speaker Mixer Volume = 0dB */
  255. write_reg(dev->i2c_bus, 0x22, 0x0000);
  256. /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
  257. write_reg(dev->i2c_bus, 0x23, 0x0000);
  258. /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
  259. Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
  260. write_reg(dev->i2c_bus, 0x36, 0x0300);
  261. /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
  262. write_reg(dev->i2c_bus, 0x01, 0x3003);
  263. /* Headphone/Speaker Enable */
  264. if (dev->type & INPUT_DEVICE_DIGITAL_MIC1_MIC2)
  265. {
  266. /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslots 0 and 1 */
  267. write_reg(dev->i2c_bus, 0x51, 0x0205);
  268. }
  269. else
  270. {
  271. /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
  272. write_reg(dev->i2c_bus, 0x51, 0x0005);
  273. }
  274. /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
  275. /* idem for Speaker */
  276. write_reg(dev->i2c_bus, 0x01, 0x3303);
  277. /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
  278. write_reg(dev->i2c_bus, 0x60, 0x0022);
  279. /* Enable Charge Pump */
  280. write_reg(dev->i2c_bus, 0x4C, 0x9F25);
  281. /* Add Delay */
  282. rt_thread_mdelay(15);
  283. /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
  284. write_reg(dev->i2c_bus, 0x2D, 0x0001);
  285. /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
  286. write_reg(dev->i2c_bus, 0x2E, 0x0001);
  287. /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
  288. /* idem for SPKOUTL and SPKOUTR */
  289. write_reg(dev->i2c_bus, 0x03, 0x0330);
  290. /* Enable DC Servo and trigger start-up mode on left and right channels */
  291. write_reg(dev->i2c_bus, 0x54, 0x0033);
  292. /* Add Delay */
  293. rt_thread_mdelay(200);
  294. /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
  295. write_reg(dev->i2c_bus, 0x60, 0x00EE);
  296. /* Unmute DAC 1 (Left) */
  297. write_reg(dev->i2c_bus, 0x0610, 0x00C0);
  298. /* Unmute DAC 1 (Right) */
  299. write_reg(dev->i2c_bus, 0x0611, 0x00C0);
  300. /* Unmute the AIF1 Timeslot 0 DAC path */
  301. write_reg(dev->i2c_bus, 0x0420, 0x0000);
  302. /* Unmute DAC 2 (Left) */
  303. write_reg(dev->i2c_bus, 0x0612, 0x00C0);
  304. /* Unmute DAC 2 (Right) */
  305. write_reg(dev->i2c_bus, 0x0613, 0x00C0);
  306. /* Unmute the AIF1 Timeslot 1 DAC2 path */
  307. write_reg(dev->i2c_bus, 0x0422, 0x0000);
  308. }
  309. /* Audio input selected */
  310. if ((dev->type & 0x01F0) != 0 )
  311. {
  312. if ((dev->type & INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (dev->type & INPUT_DEVICE_DIGITAL_MICROPHONE_2))
  313. {
  314. /* Enable Microphone bias 1 generator, Enable VMID */
  315. write_reg(dev->i2c_bus, 0x01, 0x0013);
  316. /* ADC oversample enable */
  317. write_reg(dev->i2c_bus, 0x0620, 0x0002);
  318. /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
  319. write_reg(dev->i2c_bus, 0x0411, 0x3800);
  320. }
  321. else if (dev->type & INPUT_DEVICE_DIGITAL_MIC1_MIC2)
  322. {
  323. /* Enable Microphone bias 1 generator, Enable VMID */
  324. write_reg(dev->i2c_bus, 0x01, 0x0013);
  325. /* ADC oversample enable */
  326. write_reg(dev->i2c_bus, 0x0620, 0x0002);
  327. /* AIF ADC1 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
  328. write_reg(dev->i2c_bus, 0x0410, 0x1800);
  329. /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
  330. write_reg(dev->i2c_bus, 0x0411, 0x1800);
  331. }
  332. else if ((dev->type & INPUT_DEVICE_INPUT_LINE_1) || (dev->type & INPUT_DEVICE_INPUT_LINE_2))
  333. {
  334. /* Disable mute on IN1L, IN1L Volume = +0dB */
  335. write_reg(dev->i2c_bus, 0x18, 0x000B);
  336. /* Disable mute on IN1R, IN1R Volume = +0dB */
  337. write_reg(dev->i2c_bus, 0x1A, 0x000B);
  338. /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
  339. write_reg(dev->i2c_bus, 0x0410, 0x1800);
  340. }
  341. }
  342. /* Return communication control value */
  343. return RT_EOK;
  344. }
  345. static rt_err_t _read_id(struct rt_i2c_bus_device *bus, rt_uint16_t *id)
  346. {
  347. rt_uint8_t read_value[2];
  348. read_reg(bus, 0x0000, 2, read_value);
  349. *id = ((uint16_t)(read_value[0] << 8) & 0xFF00);
  350. *id |= ((uint16_t)(read_value[1])& 0x00FF);
  351. if (*id != WM8994_ID)
  352. {
  353. LOG_E("error id: 0x%04x", *id);
  354. return RT_ERROR;
  355. }
  356. LOG_I("wm8994 init success, id: %04x", *id);
  357. return RT_EOK;
  358. }
  359. static rt_err_t _set_mute(struct rt_i2c_bus_device *bus, uint32_t cmd)
  360. {
  361. /* Set the Mute mode */
  362. if (cmd == AUDIO_MUTE_ON)
  363. {
  364. /* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */
  365. write_reg(bus, 0x420, 0x0200);
  366. /* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */
  367. write_reg(bus, 0x422, 0x0200);
  368. }
  369. else /* AUDIO_MUTE_OFF Disable the Mute */
  370. {
  371. /* Unmute the AIF1 Timeslot 0 DAC1 path L&R */
  372. write_reg(bus, 0x420, 0x0010);
  373. /* Unmute the AIF1 Timeslot 1 DAC2 path L&R */
  374. write_reg(bus, 0x422, 0x0010);
  375. }
  376. return RT_EOK;
  377. }
  378. static rt_err_t _play(struct rt_i2c_bus_device *bus)
  379. {
  380. _set_mute(bus, AUDIO_MUTE_OFF);
  381. return RT_EOK;
  382. }
  383. static rt_err_t _set_volume(struct rt_i2c_bus_device *bus, rt_uint16_t type, rt_uint8_t volume)
  384. {
  385. rt_uint8_t convertedvol = VOLUME_CONVERT(volume);
  386. if (type & 0x000F)
  387. {
  388. /* Output volume */
  389. if(convertedvol > 0x3E)
  390. {
  391. /* Unmute audio codec */
  392. _set_mute(bus, AUDIO_MUTE_OFF);
  393. /* Left Headphone Volume */
  394. write_reg(bus, 0x1C, 0x3F | 0x140);
  395. /* Right Headphone Volume */
  396. write_reg(bus, 0x1D, 0x3F | 0x140);
  397. /* Left Speaker Volume */
  398. write_reg(bus, 0x26, 0x3F | 0x140);
  399. /* Right Speaker Volume */
  400. write_reg(bus, 0x27, 0x3F | 0x140);
  401. }
  402. else if (volume == 0)
  403. {
  404. /* Mute audio codec */
  405. _set_mute(bus, AUDIO_MUTE_ON);
  406. }
  407. else
  408. {
  409. /* Unmute audio codec */
  410. _set_mute(bus, AUDIO_MUTE_OFF);
  411. /* Left Headphone Volume */
  412. write_reg(bus, 0x1C, convertedvol | 0x140);
  413. /* Right Headphone Volume */
  414. write_reg(bus, 0x1D, convertedvol | 0x140);
  415. /* Left Speaker Volume */
  416. write_reg(bus, 0x26, convertedvol | 0x140);
  417. /* Right Speaker Volume */
  418. write_reg(bus, 0x27, convertedvol | 0x140);
  419. }
  420. }
  421. /* Input volume */
  422. else
  423. {
  424. convertedvol = VOLUME_IN_CONVERT(volume);
  425. /* Left AIF1 ADC1 volume */
  426. write_reg(bus, 0x400, convertedvol | 0x100);
  427. /* Right AIF1 ADC1 volume */
  428. write_reg(bus, 0x401, convertedvol | 0x100);
  429. /* Left AIF1 ADC2 volume */
  430. write_reg(bus, 0x404, convertedvol | 0x100);
  431. /* Right AIF1 ADC2 volume */
  432. write_reg(bus, 0x405, convertedvol | 0x100);
  433. }
  434. return RT_EOK;
  435. }
  436. static rt_err_t _get_volume(struct rt_i2c_bus_device *bus, rt_uint32_t *value)
  437. {
  438. rt_uint8_t read_value[2];
  439. read_reg(bus, 0x001C, 2, read_value);
  440. *value = ((uint16_t)(read_value[0] << 8) & 0xFF00);
  441. *value |= ((uint16_t)(read_value[1])& 0x00FF);
  442. return RT_EOK;
  443. }
  444. static rt_err_t _set_frequency(struct rt_i2c_bus_device *bus, rt_uint32_t freq)
  445. {
  446. switch (freq)
  447. {
  448. case AUDIO_FREQUENCY_8K:
  449. write_reg(bus, 0x210, 0x0003);
  450. break;
  451. case AUDIO_FREQUENCY_16K:
  452. write_reg(bus, 0x210, 0x0033);
  453. break;
  454. case AUDIO_FREQUENCY_32K:
  455. write_reg(bus, 0x210, 0x0063);
  456. break;
  457. case AUDIO_FREQUENCY_48K:
  458. write_reg(bus, 0x210, 0x0083);
  459. break;
  460. case AUDIO_FREQUENCY_96K:
  461. write_reg(bus, 0x210, 0x00A3);
  462. break;
  463. case AUDIO_FREQUENCY_11K:
  464. write_reg(bus, 0x210, 0x0013);
  465. break;
  466. case AUDIO_FREQUENCY_22K:
  467. write_reg(bus, 0x210, 0x0043);
  468. break;
  469. case AUDIO_FREQUENCY_44K:
  470. write_reg(bus, 0x210, 0x0073);
  471. break;
  472. default:
  473. write_reg(bus, 0x210, 0x0083);
  474. break;
  475. }
  476. return RT_EOK;
  477. }
  478. static rt_err_t _reset(struct rt_i2c_bus_device *bus)
  479. {
  480. /* Reset Codec by writing in 0x0000 address register */
  481. write_reg(bus, 0x0000, 0x0000);
  482. return RT_EOK;
  483. }
  484. static rt_err_t rt_wm8994_init(rt_device_t dev)
  485. {
  486. RT_ASSERT(dev != RT_NULL);
  487. rt_err_t result = RT_EOK;
  488. static rt_uint16_t old_type = DEVICE_NONE;
  489. struct wm8994_dev *device = (struct wm8994_dev *)dev;
  490. if (old_type == device->type)
  491. {
  492. return RT_EOK;
  493. }
  494. old_type = device->type;
  495. device->i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
  496. if (device->i2c_bus == RT_NULL)
  497. {
  498. LOG_E("can't find %c deivce", I2C_NAME);
  499. return RT_ERROR;
  500. }
  501. result = _wm8994_init(device);
  502. /* set volume */
  503. _set_volume(device->i2c_bus, device->type, VOLUME_CONVERT(100));
  504. /* set frequency */
  505. _set_frequency(device->i2c_bus, AUDIO_FREQUENCY_44K);
  506. return result;
  507. }
  508. static rt_err_t rt_wm8994_open(rt_device_t dev, rt_uint16_t oflag)
  509. {
  510. RT_ASSERT(dev != RT_NULL);
  511. return RT_EOK;
  512. }
  513. static rt_err_t rt_wm8994_close(rt_device_t dev)
  514. {
  515. RT_ASSERT(dev != RT_NULL);
  516. struct wm8994_dev *device = (struct wm8994_dev *)dev;
  517. _set_mute(device->i2c_bus, AUDIO_MUTE_ON);
  518. /* Mute the AIF1 Timeslot 0 DAC1 path */
  519. write_reg(device->i2c_bus, 0x420, 0x0200);
  520. /* Mute the AIF1 Timeslot 1 DAC2 path */
  521. write_reg(device->i2c_bus, 0x422, 0x0200);
  522. /* Disable DAC1L_TO_HPOUT1L */
  523. write_reg(device->i2c_bus, 0x2D, 0x0000);
  524. /* Disable DAC1R_TO_HPOUT1R */
  525. write_reg(device->i2c_bus, 0x2E, 0x0000);
  526. /* Disable DAC1 and DAC2 */
  527. write_reg(device->i2c_bus, 0x05, 0x0000);
  528. /* Reset Codec by writing in 0x0000 address register */
  529. write_reg(device->i2c_bus, 0x0000, 0x0000);
  530. return RT_EOK;
  531. }
  532. static rt_size_t rt_wm8994_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  533. {
  534. RT_ASSERT(dev != RT_NULL);
  535. return RT_EOK;
  536. }
  537. static rt_size_t rt_wm8994_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  538. {
  539. RT_ASSERT(dev != RT_NULL);
  540. return RT_EOK;
  541. }
  542. static rt_err_t rt_wm8994_control(rt_device_t dev, int cmd, void *args)
  543. {
  544. RT_ASSERT(dev != RT_NULL);
  545. struct wm8994_dev *device = (struct wm8994_dev *)dev;
  546. rt_err_t result = RT_EOK;
  547. switch (cmd)
  548. {
  549. case GET_ID:
  550. result = _read_id(device->i2c_bus, (rt_uint16_t*)args);
  551. break;
  552. case SET_FREQUENCE:
  553. result = _set_frequency(device->i2c_bus, (*(rt_uint32_t *)args));
  554. break;
  555. case SET_VOLUME:
  556. result = _set_volume(device->i2c_bus, device->type, (*(rt_uint8_t*)args));
  557. break;
  558. case GET_VOLUME:
  559. result = _get_volume(device->i2c_bus, (rt_uint32_t *)args);
  560. break;
  561. case SET_MUTE:
  562. result = _set_mute(device->i2c_bus, (*(rt_uint32_t*)args));
  563. break;
  564. case SET_RESET:
  565. result = _reset(device->i2c_bus);
  566. break;
  567. case START_PLAY:
  568. result = _play(device->i2c_bus);
  569. break;
  570. case SET_PLAY_TYPE:
  571. device->type = 0;
  572. device->type = *(rt_uint32_t *)args;
  573. rt_wm8994_init(dev);
  574. break;
  575. default:
  576. LOG_D("not support cmd");
  577. break;
  578. }
  579. return result;
  580. }
  581. int wm8994_init(void)
  582. {
  583. rt_wm8994.dev.type = RT_Device_Class_Sound;
  584. rt_wm8994.dev.init = rt_wm8994_init;
  585. rt_wm8994.dev.open = rt_wm8994_open;
  586. rt_wm8994.dev.close = rt_wm8994_close;
  587. rt_wm8994.dev.read = rt_wm8994_read;
  588. rt_wm8994.dev.write = rt_wm8994_write;
  589. rt_wm8994.dev.control = rt_wm8994_control;
  590. rt_wm8994.dev.user_data = RT_NULL;
  591. rt_device_register(&rt_wm8994.dev, "decoder", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  592. LOG_I("lowlevel decoder device init success!");
  593. return RT_EOK;
  594. }
  595. INIT_DEVICE_EXPORT(wm8994_init);
  596. #endif