hpm_sgtl5000.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2019 NXP
  4. * Copyright (c) 2021 hpmicro
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. *
  8. */
  9. #include <stdio.h>
  10. #include "hpm_sgtl5000.h"
  11. /*******************************************************************************
  12. * Definitations
  13. ******************************************************************************/
  14. /*******************************************************************************
  15. * Prototypes
  16. ******************************************************************************/
  17. /*******************************************************************************
  18. * Variables
  19. ******************************************************************************/
  20. /*******************************************************************************
  21. * Code
  22. ******************************************************************************/
  23. hpm_stat_t sgtl_init(sgtl_context_t *context, sgtl_config_t *config)
  24. {
  25. assert(context != NULL);
  26. assert(config != NULL);
  27. if (sgtl_write_reg(context, CHIP_ANA_POWER, 0x6AFF) != status_success)
  28. {
  29. return status_fail;
  30. }
  31. /* Set the data route */
  32. if (sgtl_set_data_route(context, config->route) != status_success)
  33. {
  34. return status_fail;
  35. }
  36. /* Set sgtl5000 to master or slave */
  37. sgtl_set_master_mode(context, config->master);
  38. /* Input Volume Control
  39. Configure ADC left and right analog volume to desired default.
  40. Example shows volume of 0dB. */
  41. if (sgtl_write_reg(context, CHIP_ANA_ADC_CTRL, 0x0000U) != status_success)
  42. {
  43. return status_fail;
  44. }
  45. /* Volume and Mute Control
  46. Configure HP_OUT left and right volume to minimum, unmute.
  47. HP_OUT and ramp the volume up to desired volume.*/
  48. if (sgtl_write_reg(context, CHIP_ANA_HP_CTRL, 0x1818U) != status_success)
  49. {
  50. return status_fail;
  51. }
  52. if (sgtl_modify_reg(context, CHIP_ANA_CTRL, 0xFFEFU, 0x0000U) != status_success)
  53. {
  54. return status_fail;
  55. }
  56. /* LINEOUT and DAC volume control */
  57. if (sgtl_modify_reg(context, CHIP_ANA_CTRL, 0xFEFFU, 0x0000U) != status_success)
  58. {
  59. return status_fail;
  60. }
  61. /* Configure DAC left and right digital volume */
  62. if (sgtl_write_reg(context, CHIP_DAC_VOL, 0x5C5CU) != status_success)
  63. {
  64. return status_fail;
  65. }
  66. /* Configure ADC volume, reduce 6db. */
  67. if (sgtl_write_reg(context, CHIP_ANA_ADC_CTRL, 0x0100U) != status_success)
  68. {
  69. return status_fail;
  70. }
  71. /* Unmute DAC */
  72. if (sgtl_modify_reg(context, CHIP_ADCDAC_CTRL, 0xFFFBU, 0x0000U) != status_success)
  73. {
  74. return status_fail;
  75. }
  76. if (sgtl_modify_reg(context, CHIP_ADCDAC_CTRL, 0xFFF7U, 0x0000U) != status_success)
  77. {
  78. return status_fail;
  79. }
  80. /* Unmute ADC */
  81. if (sgtl_modify_reg(context, CHIP_ANA_CTRL, 0xFFFEU, 0x0000U) != status_success)
  82. {
  83. return status_fail;
  84. }
  85. /* Set the audio format */
  86. if (sgtl_set_protocol(context, config->bus) != status_success)
  87. {
  88. return status_fail;
  89. }
  90. if (sgtl_config_data_format(context, config->format.mclk_hz, config->format.sample_rate, config->format.bit_width) !=
  91. status_success)
  92. {
  93. return status_fail;
  94. }
  95. /* sclk valid edge */
  96. if (config->format.sclk_edge == sgtl_sclk_valid_edge_rising)
  97. {
  98. if (sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_RISING_EDGE) !=
  99. status_success)
  100. {
  101. return status_fail;
  102. }
  103. }
  104. else
  105. {
  106. if (sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_FALLING_EDGE) !=
  107. status_success)
  108. {
  109. return status_fail;
  110. }
  111. }
  112. return status_success;
  113. }
  114. hpm_stat_t sgtl_deinit(sgtl_context_t *context)
  115. {
  116. hpm_stat_t stat = status_success;
  117. HPM_CHECK_RET(sgtl_disable_module(context, sgtl_module_adc));
  118. HPM_CHECK_RET(sgtl_disable_module(context, sgtl_module_dac));
  119. HPM_CHECK_RET(sgtl_disable_module(context, sgtl_module_dap));
  120. HPM_CHECK_RET(sgtl_disable_module(context, sgtl_module_i2sin));
  121. HPM_CHECK_RET(sgtl_disable_module(context, sgtl_module_i2sout));
  122. HPM_CHECK_RET(sgtl_disable_module(context, sgtl_module_lineout));
  123. return stat;
  124. }
  125. void sgtl_set_master_mode(sgtl_context_t *context, bool master)
  126. {
  127. if (master == true)
  128. {
  129. (void)sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_MS_CLR_MASK, SGTL5000_I2S_MASTER);
  130. }
  131. else
  132. {
  133. (void)sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_MS_CLR_MASK, SGTL5000_I2S_SLAVE);
  134. }
  135. }
  136. hpm_stat_t sgtl_enable_module(sgtl_context_t *context, sgtl_module_t module)
  137. {
  138. hpm_stat_t stat = status_success;
  139. switch (module)
  140. {
  141. case sgtl_module_adc:
  142. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_ADC_ENABLE_CLR_MASK,
  143. ((uint16_t)1U << SGTL5000_ADC_ENABLE_SHIFT)));
  144. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_POWER, SGTL5000_ADC_POWERUP_CLR_MASK,
  145. ((uint16_t)1U << SGTL5000_ADC_POWERUP_SHIFT)));
  146. break;
  147. case sgtl_module_dac:
  148. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_DAC_ENABLE_CLR_MASK,
  149. ((uint16_t)1U << SGTL5000_DAC_ENABLE_SHIFT)));
  150. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_POWER, SGTL5000_DAC_POWERUP_CLR_MASK,
  151. ((uint16_t)1U << SGTL5000_DAC_POWERUP_SHIFT)));
  152. break;
  153. case sgtl_module_dap:
  154. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_DAP_ENABLE_CLR_MASK,
  155. ((uint16_t)1U << SGTL5000_DAP_ENABLE_SHIFT)));
  156. HPM_CHECK_RET(sgtl_modify_reg(context, SGTL5000_DAP_CONTROL, SGTL5000_DAP_CONTROL_DAP_EN_CLR_MASK,
  157. ((uint16_t)1U << SGTL5000_DAP_CONTROL_DAP_EN_SHIFT)));
  158. break;
  159. case sgtl_module_i2sin:
  160. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_I2S_IN_ENABLE_CLR_MASK,
  161. ((uint16_t)1U << SGTL5000_I2S_IN_ENABLE_SHIFT)));
  162. break;
  163. case sgtl_module_i2sout:
  164. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_I2S_OUT_ENABLE_CLR_MASK,
  165. ((uint16_t)1U << SGTL5000_I2S_OUT_ENABLE_SHIFT)));
  166. break;
  167. case sgtl_module_hp:
  168. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_POWER, SGTL5000_HEADPHONE_POWERUP_CLR_MASK,
  169. ((uint16_t)1U << SGTL5000_HEADPHONE_POWERUP_SHIFT)));
  170. break;
  171. case sgtl_module_lineout:
  172. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_POWER, SGTL5000_LINEOUT_POWERUP_CLR_MASK,
  173. ((uint16_t)1U << SGTL5000_LINEOUT_POWERUP_SHIFT)));
  174. break;
  175. default:
  176. stat = status_invalid_argument;
  177. break;
  178. }
  179. return stat;
  180. }
  181. hpm_stat_t sgtl_disable_module(sgtl_context_t *context, sgtl_module_t module)
  182. {
  183. hpm_stat_t stat = status_success;
  184. switch (module)
  185. {
  186. case sgtl_module_adc:
  187. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_ADC_ENABLE_CLR_MASK,
  188. ((uint16_t)0U << SGTL5000_ADC_ENABLE_SHIFT)));
  189. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_POWER, SGTL5000_ADC_POWERUP_CLR_MASK,
  190. ((uint16_t)0U << SGTL5000_ADC_POWERUP_SHIFT)));
  191. break;
  192. case sgtl_module_dac:
  193. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_DAC_ENABLE_CLR_MASK,
  194. ((uint16_t)0U << SGTL5000_DAC_ENABLE_SHIFT)));
  195. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_POWER, SGTL5000_DAC_POWERUP_CLR_MASK,
  196. ((uint16_t)0U << SGTL5000_DAC_POWERUP_SHIFT)));
  197. break;
  198. case sgtl_module_dap:
  199. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_DAP_ENABLE_CLR_MASK,
  200. ((uint16_t)0U << SGTL5000_DAP_ENABLE_SHIFT)));
  201. HPM_CHECK_RET(sgtl_modify_reg(context, SGTL5000_DAP_CONTROL, SGTL5000_DAP_CONTROL_DAP_EN_CLR_MASK,
  202. ((uint16_t)0U << SGTL5000_DAP_CONTROL_DAP_EN_SHIFT)));
  203. break;
  204. case sgtl_module_i2sin:
  205. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_I2S_IN_ENABLE_CLR_MASK,
  206. ((uint16_t)0U << SGTL5000_I2S_IN_ENABLE_SHIFT)));
  207. break;
  208. case sgtl_module_i2sout:
  209. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_DIG_POWER, SGTL5000_I2S_OUT_ENABLE_CLR_MASK,
  210. ((uint16_t)0U << SGTL5000_I2S_OUT_ENABLE_SHIFT)));
  211. break;
  212. case sgtl_module_hp:
  213. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_POWER, SGTL5000_HEADPHONE_POWERUP_CLR_MASK,
  214. ((uint16_t)0U << SGTL5000_HEADPHONE_POWERUP_SHIFT)));
  215. break;
  216. case sgtl_module_lineout:
  217. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_POWER, SGTL5000_LINEOUT_POWERUP_CLR_MASK,
  218. ((uint16_t)0U << SGTL5000_LINEOUT_POWERUP_SHIFT)));
  219. break;
  220. default:
  221. stat = status_invalid_argument;
  222. break;
  223. }
  224. return stat;
  225. }
  226. hpm_stat_t sgtl_set_data_route(sgtl_context_t *context, sgtl_route_t route)
  227. {
  228. hpm_stat_t stat = status_success;
  229. switch (route)
  230. {
  231. case sgtl_route_bypass:
  232. /* Bypass means from line-in to HP*/
  233. HPM_CHECK_RET(sgtl_write_reg(context, CHIP_DIG_POWER, 0x0000));
  234. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_hp));
  235. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_LINEIN));
  236. break;
  237. case sgtl_route_playback:
  238. /* Data route I2S_IN-> DAC-> HP */
  239. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_hp));
  240. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_dac));
  241. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_i2sin));
  242. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_SSS_CTRL, SGTL5000_DAC_SEL_CLR_MASK, SGTL5000_DAC_SEL_I2S_IN));
  243. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_DAC));
  244. break;
  245. case sgtl_route_playback_record:
  246. /* I2S IN->DAC->HP LINE_IN->ADC->I2S_OUT */
  247. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_hp));
  248. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_dac));
  249. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_i2sin));
  250. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_i2sout));
  251. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_adc));
  252. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_SSS_CTRL, SGTL5000_DAC_SEL_CLR_MASK, SGTL5000_DAC_SEL_I2S_IN));
  253. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_DAC));
  254. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_SEL_ADC_CLR_MASK, SGTL5000_SEL_ADC_LINEIN));
  255. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_SSS_CTRL, SGTL5000_I2S_OUT_SEL_CLR_MASK, SGTL5000_I2S_OUT_SEL_ADC));
  256. break;
  257. case sgtl_route_playback_with_dap:
  258. /* I2S_IN->DAP->DAC->HP */
  259. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_hp));
  260. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_dac));
  261. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_i2sin));
  262. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_dap));
  263. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_SSS_CTRL, SGTL5000_DAP_SEL_CLR_MASK, SGTL5000_DAP_SEL_I2S_IN));
  264. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_SSS_CTRL, SGTL5000_DAC_SEL_CLR_MASK, SGTL5000_DAC_SEL_DAP));
  265. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_DAC));
  266. break;
  267. case sgtl_route_playback_with_dap_record:
  268. /* I2S_IN->DAP->DAC->HP, LINE_IN->ADC->I2S_OUT */
  269. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_hp));
  270. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_dac));
  271. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_i2sin));
  272. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_i2sout));
  273. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_adc));
  274. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_dap));
  275. HPM_CHECK_RET(sgtl_modify_reg(context, SGTL5000_DAP_CONTROL, SGTL5000_DAP_CONTROL_DAP_EN_CLR_MASK, 0x0001));
  276. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_SSS_CTRL, SGTL5000_DAP_SEL_CLR_MASK, SGTL5000_DAP_SEL_I2S_IN));
  277. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_SSS_CTRL, SGTL5000_DAC_SEL_CLR_MASK, SGTL5000_DAC_SEL_DAP));
  278. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_SEL_HP_CLR_MASK, SGTL5000_SEL_HP_DAC));
  279. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_SEL_ADC_CLR_MASK, SGTL5000_SEL_ADC_LINEIN));
  280. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_SSS_CTRL, SGTL5000_I2S_OUT_SEL_CLR_MASK, SGTL5000_I2S_OUT_SEL_ADC));
  281. break;
  282. case sgtl_route_record:
  283. /* LINE_IN->ADC->I2S_OUT */
  284. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_i2sout));
  285. HPM_CHECK_RET(sgtl_enable_module(context, sgtl_module_adc));
  286. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_SEL_ADC_CLR_MASK, SGTL5000_SEL_ADC_LINEIN));
  287. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_SSS_CTRL, SGTL5000_I2S_OUT_SEL_CLR_MASK, SGTL5000_I2S_OUT_SEL_ADC));
  288. break;
  289. default:
  290. stat = status_invalid_argument;
  291. break;
  292. }
  293. return stat;
  294. }
  295. hpm_stat_t sgtl_set_protocol(sgtl_context_t *context, sgtl_protocol_t protocol)
  296. {
  297. hpm_stat_t stat = status_success;
  298. switch (protocol)
  299. {
  300. case sgtl_bus_i2s:
  301. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_I2S_LJ));
  302. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_LRALIGN_CLR_MASK, SGTL5000_I2S_ONE_BIT_DELAY));
  303. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_RISING_EDGE));
  304. break;
  305. case sgtl_bus_left_justified:
  306. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_I2S_LJ));
  307. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_LRALIGN_CLR_MASK, SGTL5000_I2S_NO_DELAY));
  308. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_RISING_EDGE));
  309. break;
  310. case sgtl_bus_right_justified:
  311. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_RJ));
  312. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_RISING_EDGE));
  313. break;
  314. case sgtl_bus_pcma:
  315. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_PCM));
  316. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_LRALIGN_CLR_MASK, SGTL5000_I2S_ONE_BIT_DELAY));
  317. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_FALLING_EDGE));
  318. break;
  319. case sgtl_bus_pcmb:
  320. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_MODE_CLR_MASK, SGTL5000_I2S_MODE_PCM));
  321. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_LRALIGN_CLR_MASK, SGTL5000_I2S_NO_DELAY));
  322. HPM_CHECK_RET(sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_SCLK_INV_CLR_MASK, SGTL5000_I2S_VAILD_FALLING_EDGE));
  323. break;
  324. default:
  325. stat = status_invalid_argument;
  326. break;
  327. }
  328. return stat;
  329. }
  330. hpm_stat_t sgtl_set_volume(sgtl_context_t *context, sgtl_module_t module, uint32_t volume)
  331. {
  332. uint16_t vol = 0;
  333. hpm_stat_t stat = status_success;
  334. switch (module)
  335. {
  336. case sgtl_module_adc:
  337. if (volume > SGTL5000_ADC_MAX_VOLUME_VALUE)
  338. {
  339. return status_invalid_argument;
  340. }
  341. vol = (uint16_t)(volume | (volume << 4U));
  342. stat = sgtl_modify_reg(context, CHIP_ANA_ADC_CTRL,
  343. SGTL5000_ADC_VOL_LEFT_CLR_MASK & SGTL5000_ADC_VOL_RIGHT_CLR_MASK, vol);
  344. break;
  345. case sgtl_module_dac:
  346. if ((volume > SGTL5000_DAC_MAX_VOLUME_VALUE) || (volume < SGTL5000_DAC_MIN_VOLUME_VALUE))
  347. {
  348. return status_invalid_argument;
  349. }
  350. vol = (uint16_t)(volume | (volume << 8U));
  351. stat = sgtl_write_reg(context, CHIP_DAC_VOL, vol);
  352. break;
  353. case sgtl_module_hp:
  354. if (volume > SGTL5000_HEADPHONE_MAX_VOLUME_VALUE)
  355. {
  356. return status_invalid_argument;
  357. }
  358. vol = (uint16_t)(volume | (volume << 8U));
  359. stat = sgtl_write_reg(context, CHIP_ANA_HP_CTRL, vol);
  360. break;
  361. case sgtl_module_lineout:
  362. if (volume > SGTL5000_LINE_OUT_MAX_VOLUME_VALUE)
  363. {
  364. return status_invalid_argument;
  365. }
  366. vol = (uint16_t)(volume | (volume << 8U));
  367. stat = sgtl_write_reg(context, CHIP_LINE_OUT_VOL, vol);
  368. break;
  369. default:
  370. stat = status_invalid_argument;
  371. break;
  372. }
  373. return stat;
  374. }
  375. uint32_t sgtl_get_volume(sgtl_context_t *context, sgtl_module_t module)
  376. {
  377. uint16_t vol = 0;
  378. hpm_stat_t stat = status_success;
  379. switch (module)
  380. {
  381. case sgtl_module_adc:
  382. stat = sgtl_read_reg(context, CHIP_ANA_ADC_CTRL, &vol);
  383. vol = (vol & (uint16_t)SGTL5000_ADC_VOL_LEFT_GET_MASK) >> SGTL5000_ADC_VOL_LEFT_SHIFT;
  384. break;
  385. case sgtl_module_dac:
  386. stat = sgtl_read_reg(context, CHIP_DAC_VOL, &vol);
  387. vol = (vol & (uint16_t)SGTL5000_DAC_VOL_LEFT_GET_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT;
  388. break;
  389. case sgtl_module_hp:
  390. stat = sgtl_read_reg(context, CHIP_ANA_HP_CTRL, &vol);
  391. vol = (vol & (uint16_t)SGTL5000_HP_VOL_LEFT_GET_MASK) >> SGTL5000_HP_VOL_LEFT_SHIFT;
  392. break;
  393. case sgtl_module_lineout:
  394. stat = sgtl_read_reg(context, CHIP_LINE_OUT_VOL, &vol);
  395. vol = (vol & (uint16_t)SGTL5000_LINE_OUT_VOL_LEFT_GET_MASK) >> SGTL5000_LINE_OUT_VOL_LEFT_SHIFT;
  396. break;
  397. default:
  398. vol = 0;
  399. break;
  400. }
  401. return stat == status_success ? vol : 0U;
  402. }
  403. hpm_stat_t sgtl_set_mute(sgtl_context_t *context, sgtl_module_t module, bool mute)
  404. {
  405. hpm_stat_t stat = status_success;
  406. switch (module)
  407. {
  408. case sgtl_module_adc:
  409. stat = sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_MUTE_ADC_CLR_MASK, mute ? 1U : 0U);
  410. break;
  411. case sgtl_module_dac:
  412. if (mute)
  413. {
  414. stat = sgtl_modify_reg(context, CHIP_ADCDAC_CTRL,
  415. SGTL5000_DAC_MUTE_LEFT_CLR_MASK & SGTL5000_DAC_MUTE_RIGHT_CLR_MASK, 0x000C);
  416. }
  417. else
  418. {
  419. stat = sgtl_modify_reg(context, CHIP_ADCDAC_CTRL,
  420. SGTL5000_DAC_MUTE_LEFT_CLR_MASK & SGTL5000_DAC_MUTE_RIGHT_CLR_MASK, 0x0000);
  421. }
  422. break;
  423. case sgtl_module_hp:
  424. stat = sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_MUTE_HP_CLR_MASK,
  425. ((uint16_t)mute << SGTL5000_MUTE_HP_SHIFT));
  426. break;
  427. case sgtl_module_lineout:
  428. stat = sgtl_modify_reg(context, CHIP_ANA_CTRL, SGTL5000_MUTE_LO_CLR_MASK,
  429. ((uint16_t)mute << SGTL5000_MUTE_LO_SHIFT));
  430. break;
  431. default:
  432. stat = status_invalid_argument;
  433. break;
  434. }
  435. return stat;
  436. }
  437. hpm_stat_t sgtl_config_data_format(sgtl_context_t *context, uint32_t mclk, uint32_t sample_rate, uint32_t bits)
  438. {
  439. uint16_t val = 0;
  440. uint16_t regVal = 0;
  441. uint16_t mul_clk = 0U;
  442. uint32_t sysFs = 0U;
  443. hpm_stat_t stat = status_success;
  444. /* Over sample rate can only up to 512, the least to 8k */
  445. if ((mclk / (MIN(sample_rate * 6U, 96000U)) > 512U) || (mclk / sample_rate < 256U))
  446. {
  447. return status_invalid_argument;
  448. }
  449. /* Configure the sample rate */
  450. switch (sample_rate)
  451. {
  452. case 8000:
  453. if (mclk > 32000U * 512U)
  454. {
  455. val = 0x0038;
  456. sysFs = 48000;
  457. }
  458. else
  459. {
  460. val = 0x0020;
  461. sysFs = 32000;
  462. }
  463. break;
  464. case 11025:
  465. val = 0x0024;
  466. sysFs = 44100;
  467. break;
  468. case 12000:
  469. val = 0x0028;
  470. sysFs = 48000;
  471. break;
  472. case 16000:
  473. if (mclk > 32000U * 512U)
  474. {
  475. val = 0x003C;
  476. sysFs = 96000;
  477. }
  478. else
  479. {
  480. val = 0x0010;
  481. sysFs = 32000;
  482. }
  483. break;
  484. case 22050:
  485. val = 0x0014;
  486. sysFs = 44100;
  487. break;
  488. case 24000:
  489. if (mclk > 48000U * 512U)
  490. {
  491. val = 0x002C;
  492. sysFs = 96000;
  493. }
  494. else
  495. {
  496. val = 0x0018;
  497. sysFs = 48000;
  498. }
  499. break;
  500. case 32000:
  501. val = 0x0000;
  502. sysFs = 32000;
  503. break;
  504. case 44100:
  505. val = 0x0004;
  506. sysFs = 44100;
  507. break;
  508. case 48000:
  509. if (mclk > 48000U * 512U)
  510. {
  511. val = 0x001C;
  512. sysFs = 96000;
  513. }
  514. else
  515. {
  516. val = 0x0008;
  517. sysFs = 48000;
  518. }
  519. break;
  520. case 96000:
  521. val = 0x000C;
  522. sysFs = 96000;
  523. break;
  524. default:
  525. stat = status_invalid_argument;
  526. break;
  527. }
  528. if (stat != status_success)
  529. {
  530. return stat;
  531. }
  532. if (sgtl_read_reg(context, CHIP_I2S_CTRL, &regVal) != status_success)
  533. {
  534. return status_fail;
  535. }
  536. /* While as slave, Fs is input */
  537. if ((regVal & SGTL5000_I2S_MS_GET_MASK) == 0U)
  538. {
  539. sysFs = sample_rate;
  540. }
  541. mul_clk = (uint16_t)(mclk / sysFs);
  542. /* Configure the mul_clk. Sgtl-5000 only support 256, 384 and 512 oversample rate */
  543. if ((mul_clk / 128U - 2U) > 2U)
  544. {
  545. return status_invalid_argument;
  546. }
  547. else
  548. {
  549. val |= (mul_clk / 128U - 2U);
  550. }
  551. if (sgtl_write_reg(context, CHIP_CLK_CTRL, val) != status_success)
  552. {
  553. return status_fail;
  554. }
  555. /* Data bits configure,sgtl supports 16bit, 20bit 24bit, 32bit */
  556. if (sgtl_modify_reg(context, CHIP_I2S_CTRL, 0xFEFF, SGTL5000_I2S_SCLKFREQ_64FS) != status_success)
  557. {
  558. return status_fail;
  559. }
  560. switch (bits)
  561. {
  562. case 16:
  563. stat = sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_DLEN_CLR_MASK, SGTL5000_I2S_DLEN_16);
  564. break;
  565. case 20:
  566. stat = sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_DLEN_CLR_MASK, SGTL5000_I2S_DLEN_20);
  567. break;
  568. case 24:
  569. stat = sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_DLEN_CLR_MASK, SGTL5000_I2S_DLEN_24);
  570. break;
  571. case 32:
  572. stat = sgtl_modify_reg(context, CHIP_I2S_CTRL, SGTL5000_I2S_DLEN_CLR_MASK, SGTL5000_I2S_DLEN_32);
  573. break;
  574. default:
  575. stat = status_invalid_argument;
  576. break;
  577. }
  578. return stat;
  579. }
  580. hpm_stat_t sgtl_set_play(sgtl_context_t *context, uint32_t playSource)
  581. {
  582. uint16_t regValue = 0U, regBitMask = 0x40U;
  583. /* headphone source form PGA */
  584. if (playSource == (uint32_t)sgtl_play_source_linein)
  585. {
  586. regValue = 0x40U;
  587. }
  588. /* headphone source from DAC */
  589. else
  590. {
  591. regValue = 0U;
  592. }
  593. return sgtl_modify_reg(context, CHIP_ANA_CTRL, regBitMask, regValue);
  594. }
  595. hpm_stat_t sgtl_set_record(sgtl_context_t *context, uint32_t recordSource)
  596. {
  597. uint16_t regValue = 0U, regBitMask = 0x4U;
  598. /* ADC source form LINEIN */
  599. if (recordSource == (uint32_t)sgtl_record_source_linein)
  600. {
  601. regValue = 0x4U;
  602. }
  603. /* ADC source from MIC */
  604. else
  605. {
  606. regValue = 0U;
  607. }
  608. return sgtl_modify_reg(context, CHIP_ANA_CTRL, regBitMask, regValue);
  609. }
  610. hpm_stat_t sgtl_write_reg(sgtl_context_t *context, uint16_t reg, uint16_t val)
  611. {
  612. rt_size_t size;
  613. rt_uint8_t data[4];
  614. data[0] = reg >> 8;
  615. data[1] = reg & 0xFF;
  616. data[2] = (uint8_t) (val>>8);
  617. data[3] = (uint8_t) (val & 0xFF);
  618. size = rt_i2c_master_send(context->i2c_bus, context->slave_address, RT_I2C_WR, data, 4U);
  619. if (size != 4) {
  620. return status_fail;
  621. }
  622. return status_success;
  623. }
  624. hpm_stat_t sgtl_read_reg(sgtl_context_t *context, uint16_t reg, uint16_t *val)
  625. {
  626. rt_size_t size;
  627. rt_uint8_t r[2];
  628. uint8_t d[2];
  629. r[0] = reg >> 8;
  630. r[1] = reg & 0xFF;
  631. size = rt_i2c_master_send(context->i2c_bus, context->slave_address, RT_I2C_WR, r, 2U);
  632. if (size != 2) {
  633. return status_fail;
  634. }
  635. size = rt_i2c_master_recv(context->i2c_bus, context->slave_address, RT_I2C_RD, d, 2U);
  636. if (size != 2) {
  637. return status_fail;
  638. }
  639. *val = (uint16_t)((d[0] << 8) | d[1]);
  640. return status_success;
  641. }
  642. hpm_stat_t sgtl_modify_reg(sgtl_context_t *context, uint16_t reg, uint16_t clr_mask, uint16_t val)
  643. {
  644. hpm_stat_t retval = 0;
  645. uint16_t reg_val;
  646. /* Read the register value out */
  647. retval = sgtl_read_reg(context, reg, &reg_val);
  648. if (retval != status_success)
  649. {
  650. return status_fail;
  651. }
  652. /* Modify the value */
  653. reg_val &= clr_mask;
  654. reg_val |= val;
  655. /* Write the data to register */
  656. retval = sgtl_write_reg(context, reg, reg_val);
  657. if (retval != status_success)
  658. {
  659. return status_fail;
  660. }
  661. return status_success;
  662. }