drv_es8388.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Date Author Notes
  7. * 2019-07-31 Zero-Free first implementation
  8. */
  9. #include <rtthread.h>
  10. #include <rtdevice.h>
  11. #include "drv_es8388.h"
  12. /* ES8388 address */
  13. #define ES8388_ADDR 0x10 /*0x11:CE=1;0x10:CE=0*/
  14. struct es8388_device
  15. {
  16. struct rt_i2c_bus_device *i2c;
  17. rt_uint16_t pin;
  18. };
  19. static struct es8388_device es_dev = {0};
  20. static rt_uint16_t reg_read(rt_uint8_t addr)
  21. {
  22. struct rt_i2c_msg msg[2] = {0};
  23. rt_uint8_t val = 0xff;
  24. RT_ASSERT(es_dev.i2c != RT_NULL);
  25. msg[0].addr = ES8388_ADDR;
  26. msg[0].flags = RT_I2C_WR;
  27. msg[0].len = 1;
  28. msg[0].buf = &addr;
  29. msg[1].addr = ES8388_ADDR;
  30. msg[1].flags = RT_I2C_RD;
  31. msg[1].len = 1;
  32. msg[1].buf = &val;
  33. if (rt_i2c_transfer(es_dev.i2c, msg, 2) != 2)
  34. {
  35. rt_kprintf("I2C read data failed, reg = 0x%02x. \n", addr);
  36. return 0xff;
  37. }
  38. return val;
  39. }
  40. static void reg_write(rt_uint8_t addr, rt_uint8_t val)
  41. {
  42. struct rt_i2c_msg msgs[1] = {0};
  43. rt_uint8_t buff[2] = {0};
  44. RT_ASSERT(es_dev.i2c != RT_NULL);
  45. buff[0] = addr;
  46. buff[1] = val;
  47. msgs[0].addr = ES8388_ADDR;
  48. msgs[0].flags = RT_I2C_WR;
  49. msgs[0].buf = buff;
  50. msgs[0].len = 2;
  51. if (rt_i2c_transfer(es_dev.i2c, msgs, 1) != 1)
  52. {
  53. rt_kprintf("I2C write data failed, reg = 0x%2x. \n", addr);
  54. return;
  55. }
  56. }
  57. static int es8388_set_adc_dac_volume(int mode, int volume, int dot)
  58. {
  59. int res = 0;
  60. if (volume < -96 || volume > 0)
  61. {
  62. if (volume < -96)
  63. volume = -96;
  64. else
  65. volume = 0;
  66. }
  67. dot = (dot >= 5 ? 1 : 0);
  68. volume = (-volume << 1) + dot;
  69. if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC)
  70. {
  71. reg_write(ES8388_ADCCONTROL8, volume);
  72. reg_write(ES8388_ADCCONTROL9, volume); //ADC Right Volume=0db
  73. }
  74. if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC)
  75. {
  76. reg_write(ES8388_DACCONTROL5, volume);
  77. reg_write(ES8388_DACCONTROL4, volume);
  78. }
  79. return res;
  80. }
  81. void es8388_set_voice_mute(rt_bool_t enable)
  82. {
  83. rt_uint8_t reg = 0;
  84. reg = reg_read(ES8388_DACCONTROL3);
  85. reg = reg & 0xFB;
  86. reg_write(ES8388_DACCONTROL3, reg | (((int)enable) << 2));
  87. }
  88. rt_err_t es8388_init(const char *i2c_name, rt_uint16_t pin)
  89. {
  90. es_dev.i2c = rt_i2c_bus_device_find(i2c_name);
  91. if (es_dev.i2c == RT_NULL)
  92. {
  93. rt_kprintf("%s bus not found\n", i2c_name);
  94. return -RT_ERROR;
  95. }
  96. es_dev.pin = pin;
  97. reg_write(ES8388_DACCONTROL3, 0x04); // 0x04 mute/0x00 unmute&ramp;DAC unmute and disabled digital volume control soft ramp
  98. /* Chip Control and Power Management */
  99. reg_write(ES8388_CONTROL2, 0x50);
  100. reg_write(ES8388_CHIPPOWER, 0x00); //normal all and power up all
  101. reg_write(ES8388_MASTERMODE, 0x00); //TODO:CODEC IN I2S SLAVE MODE
  102. /* dac */
  103. reg_write(ES8388_DACPOWER, 0xC0); //disable DAC and disable Lout/Rout/1/2
  104. reg_write(ES8388_CONTROL1, 0x12); //Enfr=0,Play&Record Mode,(0x17-both of mic&paly)
  105. // reg_write(ES8388_CONTROL2, 0); //LPVrefBuf=0,Pdn_ana=0
  106. reg_write(ES8388_DACCONTROL1, 0x18);//1a 0x18:16bit iis , 0x00:24
  107. reg_write(ES8388_DACCONTROL2, 0x02); //DACFsMode,SINGLE SPEED; DACFsRatio,256
  108. reg_write(ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
  109. reg_write(ES8388_DACCONTROL17, 0x9C); // only left DAC to left mixer enable 0db
  110. reg_write(ES8388_DACCONTROL20, 0x9C); // only right DAC to right mixer enable 0db
  111. reg_write(ES8388_DACCONTROL21, 0x80); //set internal ADC and DAC use the same LRCK clock, ADC LRCK as internal LRCK
  112. reg_write(ES8388_DACCONTROL23, 0x00); //vroi=0
  113. es8388_set_adc_dac_volume(ES_MODE_DAC, 0, 0); // 0db
  114. reg_write(ES8388_DACPOWER, 0x3c); //0x3c Enable DAC and Enable Lout/Rout/1/2
  115. /* adc */
  116. reg_write(ES8388_ADCPOWER, 0xFF);
  117. reg_write(ES8388_ADCCONTROL1, 0xbb); // MIC Left and Right channel PGA gain
  118. reg_write(ES8388_ADCCONTROL2, 0x00); //0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input; DSSEL,use one DS Reg11; DSR, LINPUT1-RINPUT1
  119. reg_write(ES8388_ADCCONTROL3, 0x02);
  120. reg_write(ES8388_ADCCONTROL4, 0x0d); // Left/Right data, Left/Right justified mode, Bits length, I2S format
  121. reg_write(ES8388_ADCCONTROL5, 0x02); //ADCFsMode,singel SPEED,RATIO=256
  122. //ALC for Microphone
  123. es8388_set_adc_dac_volume(ES_MODE_ADC, 0, 0); // 0db
  124. reg_write(ES8388_ADCPOWER, 0x09); //Power on ADC, Enable LIN&RIN, Power off MICBIAS, set int1lp to low power mode
  125. /* enable es8388 PA */
  126. es8388_pa_power(RT_TRUE);
  127. reg_write(ES8388_DACCONTROL24, 0x1E); // LOUT1VOL balanced noise: 0x18
  128. reg_write(ES8388_DACCONTROL25, 0x1E); // ROUT1VOL balanced noise: 0x18
  129. return RT_EOK;
  130. }
  131. rt_err_t es8388_start(enum es8388_mode mode)
  132. {
  133. int res = 0;
  134. rt_uint8_t prev_data = 0, data = 0;
  135. prev_data = reg_read(ES8388_DACCONTROL21);
  136. if (mode == ES_MODE_LINE)
  137. {
  138. reg_write(ES8388_DACCONTROL16, 0x09); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 by pass enable
  139. reg_write(ES8388_DACCONTROL17, 0x50); // left DAC to left mixer enable and LIN signal to left mixer enable 0db : bupass enable
  140. reg_write(ES8388_DACCONTROL20, 0x50); // right DAC to right mixer enable and LIN signal to right mixer enable 0db : bupass enable
  141. reg_write(ES8388_DACCONTROL21, 0xC0); //enable adc
  142. }
  143. else
  144. {
  145. reg_write(ES8388_DACCONTROL21, 0x80); //enable dac
  146. }
  147. data = reg_read(ES8388_DACCONTROL21);
  148. if (prev_data != data)
  149. {
  150. reg_write(ES8388_CHIPPOWER, 0xF0); //start state machine
  151. // reg_write(ES8388_ADDR, ES8388_CONTROL1, 0x16);
  152. // reg_write(ES8388_ADDR, ES8388_CONTROL2, 0x50);
  153. reg_write(ES8388_CHIPPOWER, 0x00); //start state machine
  154. }
  155. if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC || mode == ES_MODE_LINE)
  156. {
  157. reg_write(ES8388_ADCPOWER, 0x00); //power up adc and line in
  158. }
  159. if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC || mode == ES_MODE_LINE)
  160. {
  161. reg_write(ES8388_DACPOWER, 0x3c); //power up dac and line out
  162. es8388_set_voice_mute(RT_FALSE);
  163. }
  164. return res;
  165. }
  166. rt_err_t es8388_stop(enum es8388_mode mode)
  167. {
  168. int res = 0;
  169. if (mode == ES_MODE_LINE)
  170. {
  171. reg_write(ES8388_DACCONTROL21, 0x80); //enable dac
  172. reg_write(ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
  173. reg_write(ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db
  174. reg_write(ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db
  175. return res;
  176. }
  177. if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC)
  178. {
  179. reg_write(ES8388_DACPOWER, 0x00);
  180. es8388_set_voice_mute(RT_TRUE); //res |= Es8388SetAdcDacVolume(ES_MODULE_DAC, -96, 5); // 0db
  181. // reg_write(ES8388_ADDR, ES8388_DACPOWER, 0xC0); //power down dac and line out
  182. }
  183. if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC)
  184. {
  185. // Es8388SetAdcDacVolume(ES_MODULE_ADC, -96, 5); // 0db
  186. reg_write(ES8388_ADCPOWER, 0xFF); //power down adc and line in
  187. }
  188. if (mode == ES_MODE_DAC_ADC)
  189. {
  190. reg_write(ES8388_DACCONTROL21, 0x9C); //disable mclk
  191. // reg_write(ES8388_CONTROL1, 0x00);
  192. // reg_write(ES8388_CONTROL2, 0x58);
  193. // reg_write(ES8388_CHIPPOWER, 0xF3); //stop state machine
  194. }
  195. return RT_EOK;
  196. }
  197. rt_err_t es8388_fmt_set(enum es8388_mode mode, enum es8388_format fmt)
  198. {
  199. rt_uint8_t reg = 0;
  200. if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC)
  201. {
  202. reg = reg_read(ES8388_ADCCONTROL4);
  203. reg = reg & 0xfc;
  204. reg_write(ES8388_ADCCONTROL4, reg | fmt);
  205. }
  206. if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC)
  207. {
  208. reg = reg_read(ES8388_DACCONTROL1);
  209. reg = reg & 0xf9;
  210. reg_write(ES8388_DACCONTROL1, reg | (fmt << 1));
  211. }
  212. return RT_EOK;
  213. }
  214. void es8388_volume_set(rt_uint8_t volume)
  215. {
  216. uint32_t real_vol = 0;
  217. volume = 100 - volume;
  218. if (volume > 100)
  219. volume = 100;
  220. real_vol = 192 * volume / 100;
  221. reg_write(ES8388_DACCONTROL4, (rt_uint8_t)real_vol); // DAC L
  222. reg_write(ES8388_DACCONTROL5, (rt_uint8_t)real_vol); // DAC R
  223. }
  224. rt_uint8_t es8388_volume_get(void)
  225. {
  226. rt_uint8_t volume;
  227. volume = reg_read(ES8388_DACCONTROL24);
  228. if (volume == 0xff)
  229. {
  230. volume = 0;
  231. }
  232. else
  233. {
  234. volume *= 3;
  235. if (volume == 99)
  236. volume = 100;
  237. }
  238. return volume;
  239. }
  240. void es8388_pa_power(rt_bool_t enable)
  241. {
  242. rt_pin_mode(es_dev.pin, PIN_MODE_OUTPUT);
  243. if (enable)
  244. {
  245. rt_pin_write(es_dev.pin, PIN_HIGH);
  246. }
  247. else
  248. {
  249. rt_pin_write(es_dev.pin, PIN_LOW);
  250. }
  251. }
  252. void estest()
  253. {
  254. // reg_write(ES8388_DACCONTROL24, volume);
  255. reg_write(ES8388_ADCCONTROL1, 0x88); /* R9,左右通道PGA增益设置 */
  256. reg_write(ES8388_ADCCONTROL2, 0x10); // 使用板载麦克风
  257. // reg_write(ES8388_ADCCONTROL2,0x50); // 使用耳机麦克风
  258. // reg_write(ES8388_ADCCONTROL3, 0xC0);
  259. reg_write(ES8388_ADCCONTROL8, 0x00); // LADCVOL
  260. reg_write(ES8388_ADCCONTROL9, 0x00); // RADCVOL
  261. reg_write(ES8388_DACCONTROL16, 0x1B); // LMIXSEL RMIXSEL
  262. reg_write(ES8388_DACCONTROL17, 0x40); // LI2LOVOL
  263. reg_write(ES8388_DACCONTROL24, 0x21); // LOUT1VOL
  264. reg_write(ES8388_DACCONTROL25, 0x21); // ROUT1VOL
  265. reg_write(ES8388_DACCONTROL24, 33); // LOUT1VOL balanced noise: 0x18
  266. reg_write(ES8388_DACCONTROL25, 33); // ROUT1VOL balanced noise: 0x18
  267. }
  268. MSH_CMD_EXPORT(estest, test mic loop)