i2s.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /*******************************************************************************
  2. * File Name : i2s.c
  3. * Author : ZJH
  4. * Date First Issued : 6/24/2024
  5. * Description : i2s drive.
  6. ********************************************************************************
  7. * History:
  8. * 6/24/2024: V0.1
  9. *******************************************************************************/
  10. #include "chip.h"
  11. #include "soc-dai.h"
  12. #include "audio/audio.h"
  13. typedef struct ark_i2s_private_data {
  14. uint32_t adc_fmt;
  15. uint32_t dac_fmt;
  16. struct codec_register_inf *adc_inf;
  17. struct codec_register_inf *dac_inf;
  18. } ark_i2s_pd;
  19. struct ark_i2s_drv i2s_drv_tab[I2S_NUMS] = {
  20. #if ((AUDIO_REPLAY_I2S == I2S_ID0) || (AUDIO_RECORD_I2S == I2S_ID0))
  21. {
  22. .base = REGS_I2S_BASE,
  23. .nco_base = SYS_I2S_NCO_CFG + REGS_SYSCTL_BASE,
  24. .id = I2S_ID0,
  25. .clkid = CLK_I2S,
  26. .irqn = I2S_IRQn,
  27. .dma_tx_req_id = I2S_TX,
  28. .dma_rx_req_id = I2S_RX,
  29. .softreset_id = softreset_i2s,
  30. .dma_tx_chn = I2S_DMA_TXCH,
  31. .dma_rx_chn = I2S_DMA_RXCH,
  32. .type = IIS_BUS,
  33. .sup_func = I2S_SUP_MASTER|I2S_SUP_SLAVER|I2S_SUP_FULL_DUPLEX,
  34. .is_master = 1,
  35. .chn_sum = 2,
  36. .encoder_name = AUDIO_CODEC_ADC_NAME,
  37. .decoder_name = AUDIO_CODEC_DAC_NAME,
  38. },
  39. #endif
  40. #if ((AUDIO_REPLAY_I2S == I2S_ID1) || (AUDIO_RECORD_I2S == I2S_ID1))
  41. {
  42. .base = REGS_I2S1_BASE,
  43. .nco_base = SYS_I2S_NCO_CFG1 + REGS_SYSCTL_BASE,
  44. .id = I2S_ID1,
  45. .clkid = CLK_I2S1,
  46. .irqn = I2S1_IRQn,
  47. .dma_tx_req_id = I2S1_TX,
  48. .dma_rx_req_id = I2S1_RX,
  49. .softreset_id = softreset_i2s1,
  50. .dma_tx_chn = I2S1_DMA_TXCH,
  51. .dma_rx_chn = I2S1_DMA_RXCH,
  52. .type = IIS_BUS,
  53. .sup_func = I2S_SUP_MASTER|I2S_SUP_SLAVER|I2S_SUP_FULL_DUPLEX,
  54. .is_master = 1,
  55. .chn_sum = 2,
  56. .encoder_name = AUDIO_CODEC_ADC_NAME,
  57. .decoder_name = AUDIO_CODEC_DAC_NAME,
  58. },
  59. #endif
  60. };
  61. static void ark_i2s_start_play(struct ark_i2s_drv *i2s)
  62. {
  63. u32 val = readl(i2s->base + I2S_SACR1);
  64. val &= ~SACR1_DRPL;
  65. writel(val, i2s->base + I2S_SACR1);
  66. }
  67. static void ark_i2s_stop_play(struct ark_i2s_drv *i2s)
  68. {
  69. u32 val = readl(i2s->base + I2S_SACR1);
  70. val |= SACR1_DRPL;
  71. writel(val, i2s->base + I2S_SACR1);
  72. }
  73. static void ark_i2s_start_record(struct ark_i2s_drv *i2s)
  74. {
  75. u32 val = readl(i2s->base + I2S_SACR1);
  76. val &= ~SACR1_DREC;
  77. writel(val, i2s->base + I2S_SACR1);
  78. }
  79. static void ark_i2s_stop_record(struct ark_i2s_drv *i2s)
  80. {
  81. u32 val = readl(i2s->base + I2S_SACR1);
  82. val |= SACR1_DREC;
  83. writel(val, i2s->base + I2S_SACR1);
  84. }
  85. static void i2s_interrupt_handler(void *param)
  86. {
  87. struct ark_i2s_drv *i2s = (struct ark_i2s_drv *)param;
  88. unsigned int status;
  89. //unsigned int val;
  90. if(!i2s)
  91. return;
  92. status = readl(i2s->base + I2S_SASR0);
  93. #if 1
  94. writel(0xFF, i2s->base + I2S_SAICR);
  95. if (status & SASR0_TUR) {
  96. //printf("i2s txfifo underrun.\n");
  97. }
  98. #else
  99. val = readl(i2s->base + I2S_SAICR);
  100. if(status & SASR0_TFS)
  101. val |= SAICR_TFS;
  102. if(status & SASR0_TUR)
  103. val |= SAICR_TUR;
  104. if(status & SASR0_RFS)
  105. val |= SAICR_RFS;
  106. if(status & SASR0_ROR)
  107. val |= SAICR_ROR;
  108. writel(val, i2s->base + I2S_SAICR);
  109. #endif
  110. writel(0x0, i2s->base + I2S_SAICR);
  111. }
  112. static int codec_init(struct ark_i2s_drv *i2s, int dir)
  113. {
  114. ark_i2s_pd *pdata = NULL;
  115. int ret = -1;
  116. if(!i2s->extdata) {
  117. pdata = (ark_i2s_pd *)pvPortMalloc(sizeof(struct ark_i2s_private_data));
  118. memset(pdata, 0, sizeof(ark_i2s_pd));
  119. i2s->extdata = (void *)pdata;
  120. } else {
  121. printf("[ERR] %s() codec_init have been called, exit.\n", __func__);
  122. return -1;
  123. }
  124. if(pdata) {
  125. if (i2s->type == IIS_BUS) {
  126. #ifdef AUDIO_RECORD
  127. if (dir & I2S_DIR_INPUT && (i2s->id == AUDIO_RECORD_I2S)) {
  128. pdata->adc_inf = get_codec_register_inf(i2s->encoder_name);
  129. if (pdata->adc_inf) {
  130. if (pdata->adc_inf->ops && pdata->adc_inf->ops->init) {
  131. pdata->adc_inf->ops->init(pdata->adc_inf->codec_prvdata, !i2s->is_master);
  132. }
  133. } else {
  134. printf("[ERR] %s() get adc info fail!\n", __func__);
  135. }
  136. }
  137. #endif
  138. #ifdef AUDIO_REPLAY
  139. if (dir & I2S_DIR_OUTPUT && (i2s->id == AUDIO_REPLAY_I2S)) {
  140. pdata->dac_inf = get_codec_register_inf(i2s->decoder_name);
  141. if (pdata->dac_inf) {
  142. if (pdata->dac_inf->ops && pdata->dac_inf->ops->init) {
  143. pdata->dac_inf->ops->init(pdata->dac_inf->codec_prvdata, !i2s->is_master);
  144. }
  145. } else {
  146. printf("[ERR] %s() get dac info fail!\n", __func__);
  147. }
  148. }
  149. #endif
  150. }
  151. }
  152. return ret;
  153. }
  154. static int i2s_soft_reset(struct ark_i2s_drv *i2s)
  155. {
  156. u32 val;
  157. val = readl(i2s->base + I2S_SACR0);
  158. val |= SACR0_RST;
  159. writel(val, i2s->base + I2S_SACR0);
  160. return 0;
  161. }
  162. static int ark_i2s_set_rfirst(struct ark_i2s_drv *i2s, int enable)
  163. {
  164. if (!i2s->cfg) {
  165. printf("[ERR] %s(), invalid cfg.\n", __func__);
  166. return -ENXIO;
  167. }
  168. i2s->cfg->rfirst = enable;
  169. return 0;
  170. }
  171. int ark_i2s_set_samplerate(struct ark_i2s_drv *i2s, int rates)
  172. {
  173. uint32_t step = 256 * 2, modulo;
  174. uint32_t val, freq;
  175. if (!i2s->cfg) {
  176. printf("[ERR] %s(), invalid cfg.\n", __func__);
  177. return -ENXIO;
  178. }
  179. i2s->cfg->rates = rates;
  180. if (!i2s->nco_base) {
  181. printf("[ERR] %s(), invalid nco_base.\n", __func__);
  182. return 0;
  183. }
  184. /* mclk = rate * 256, mclk = freq * step / (2 * modulo) */
  185. freq = ulClkGetRate(i2s->clkid);
  186. modulo = freq / rates;
  187. val = (step << 16) | modulo;
  188. writel(val, i2s->nco_base);
  189. return 0;
  190. }
  191. int ark_i2s_set_channels(struct ark_i2s_drv *i2s, int channels)
  192. {
  193. if (!i2s->cfg) {
  194. printf("[ERR] %s(), invalid cfg.\n", __func__);
  195. return -ENXIO;
  196. }
  197. i2s->cfg->channels = channels;
  198. return 0;
  199. }
  200. int ark_i2s_set_samplebits(struct ark_i2s_drv *i2s, int bits)
  201. {
  202. if (!i2s->cfg) {
  203. printf("[ERR] %s(), invalid cfg.\n", __func__);
  204. return -ENXIO;
  205. }
  206. if (bits > 16)
  207. i2s->cfg->bits = 32;
  208. else
  209. i2s->cfg->bits = 16;
  210. return 0;
  211. }
  212. int ark_i2s_set_volume(struct ark_i2s_drv *i2s, int dir, int lvol, int rvol)
  213. {
  214. ark_i2s_pd *pdata = i2s->extdata;
  215. struct snd_pcm_substream substream;
  216. u32 val;
  217. if (!i2s->cfg) {
  218. printf("[ERR] %s(), invalid cfg.\n", __func__);
  219. return -ENXIO;
  220. }
  221. if(lvol > I2S_VOL_MAX)
  222. lvol = I2S_VOL_MAX;
  223. if(rvol > I2S_VOL_MAX)
  224. rvol = I2S_VOL_MAX;
  225. if(lvol < I2S_VOL_MIN)
  226. lvol = I2S_VOL_MIN;
  227. if(rvol < I2S_VOL_MIN)
  228. rvol = I2S_VOL_MIN;
  229. if (!pdata) {
  230. printf("[ERR] %s(), invalid pdata.\n", __func__);
  231. return -ENXIO;
  232. }
  233. if (dir & I2S_DIR_OUTPUT) {
  234. substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
  235. if (pdata->dac_inf && pdata->dac_inf->ops && pdata->dac_inf->ops->set_vol) {
  236. pdata->dac_inf->ops->set_vol(pdata->dac_inf->codec_prvdata, &substream, lvol, rvol);
  237. } else {
  238. printf("[ERR] %s(), dac not support volume setting.\n", __func__);
  239. return -ENXIO;
  240. }
  241. i2s->cfg->out_lvol = lvol;
  242. i2s->cfg->out_rvol = rvol;
  243. }
  244. if (dir & I2S_DIR_INPUT) {
  245. substream.stream = SNDRV_PCM_STREAM_CAPTURE;
  246. if (pdata->adc_inf && pdata->adc_inf->ops && pdata->adc_inf->ops->set_vol) {
  247. pdata->adc_inf->ops->set_vol(pdata->adc_inf->codec_prvdata, &substream, lvol, rvol);
  248. } else {
  249. printf("[ERR] %s(), adc not support volume setting.\n", __func__);
  250. return -ENXIO;
  251. }
  252. i2s->cfg->in_lvol = lvol;
  253. i2s->cfg->in_rvol = rvol;
  254. }
  255. return 0;
  256. }
  257. int ark_i2s_set_mute(struct ark_i2s_drv *i2s, int dir, int mute)
  258. {
  259. int in_lvol, in_rvol;
  260. int out_lvol, out_rvol;
  261. if (!i2s->cfg) {
  262. printf("[ERR] %s(), invalid cfg.\n", __func__);
  263. return -ENXIO;
  264. }
  265. if (mute) {
  266. in_lvol = i2s->cfg->in_lvol;
  267. in_rvol = i2s->cfg->in_rvol;
  268. out_lvol = i2s->cfg->out_lvol;
  269. out_rvol = i2s->cfg->out_rvol;
  270. ark_i2s_set_volume(i2s, dir, 0, 0);
  271. i2s->cfg->in_lvol = in_lvol;
  272. i2s->cfg->in_rvol = in_rvol;
  273. i2s->cfg->out_lvol = out_lvol;
  274. i2s->cfg->out_rvol = out_rvol;
  275. } else {
  276. if (dir & I2S_DIR_OUTPUT)
  277. ark_i2s_set_volume(i2s, I2S_DIR_OUTPUT, i2s->cfg->out_lvol, i2s->cfg->out_rvol);
  278. if (dir & I2S_DIR_INPUT)
  279. ark_i2s_set_volume(i2s, I2S_DIR_INPUT, i2s->cfg->in_lvol, i2s->cfg->in_rvol);
  280. }
  281. return 0;
  282. }
  283. int ark_i2s_startup(struct ark_i2s_drv *i2s, int dir)
  284. {
  285. unsigned int val;
  286. struct snd_pcm_substream substream;
  287. unsigned int codec_fmt = 0;
  288. ark_i2s_pd *pdata = NULL;
  289. if (!i2s->cfg) {
  290. printf("[ERR] %s(), invalid cfg.\n", __func__);
  291. return -ENXIO;
  292. }
  293. if (!(i2s->cfg->dir & (I2S_DIR_OUTPUT | I2S_DIR_INPUT))) {
  294. printf("[ERR] %s(), invalid dir.\n", __func__);
  295. return -EPERM;
  296. }
  297. pdata = i2s->extdata;
  298. if ((i2s->cfg->status & (I2S_STA_OUTPUTTING | I2S_STA_INPUTTING)) == 0){
  299. /* reset */
  300. /* stop replay and record */
  301. ark_i2s_stop_play(i2s);
  302. ark_i2s_stop_record(i2s);
  303. val = SACR0_CHANLOCK | SACR0_RFTH(0x10) | SACR0_TFTH(0xF) | SACR0_ENB;
  304. codec_fmt |= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
  305. if (!(i2s->cfg->rfirst))
  306. val |= SACR0_TFIFOFIRSTBIT | SACR0_RFIFIFIRSTBIT;
  307. if (i2s->cfg->channels == 1)
  308. val |= SACR0_SCBIT;
  309. if (i2s->cfg->bits > 16)
  310. val |= SACR0_BITS; //32 Bits.
  311. if (i2s->is_master) {
  312. val |= SACR0_BCKD | SACR0_SYNCD;
  313. codec_fmt |= SND_SOC_DAIFMT_CBS_CFS;
  314. } else {
  315. codec_fmt |= SND_SOC_DAIFMT_CBS_CFM;
  316. }
  317. if (i2s->dma_txch)
  318. val |= SACR0_TDMAEN;
  319. if (i2s->dma_rxch)
  320. val |= SACR0_RDMAEN;
  321. writel(val, i2s->base + I2S_SACR0);
  322. /* interrupt clear */
  323. writel(0xFFFFFFFF, i2s->base + I2S_SAICR);
  324. writel(0, i2s->base + I2S_SAICR);
  325. /* interrupt enable */
  326. val = readl(i2s->base + I2S_SAIMR);
  327. val |= (SAIMR_TFS | SAIMR_TUR | SAIMR_ROR | SAIMR_RFS);
  328. writel(val, i2s->base + I2S_SAIMR);
  329. if (pdata) {
  330. pdata->adc_fmt = codec_fmt;
  331. pdata->dac_fmt = codec_fmt;
  332. }
  333. }
  334. if ((dir & I2S_DIR_OUTPUT) && (i2s->cfg->dir & I2S_DIR_OUTPUT)) {
  335. substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
  336. if (pdata && pdata->dac_inf && pdata->dac_inf->ops) {
  337. if (pdata->dac_inf->ops->set_fmt) {
  338. pdata->dac_inf->ops->set_fmt(pdata->dac_inf->codec_prvdata, pdata->dac_fmt);
  339. }
  340. if (pdata->dac_inf->ops->hw_params) {
  341. struct snd_soc_hw_params params;
  342. params.rates = i2s->cfg->rates;
  343. params.channels = i2s->cfg->channels;
  344. params.bits = i2s->cfg->bits;
  345. pdata->dac_inf->ops->hw_params(pdata->dac_inf->codec_prvdata, &substream, &params);
  346. }
  347. if (pdata->dac_inf->ops->startup) {
  348. pdata->dac_inf->ops->startup(pdata->dac_inf->codec_prvdata, &substream, 1);
  349. }
  350. if(pdata->dac_inf->ops->set_mute){
  351. pdata->dac_inf->ops->set_mute(pdata->dac_inf->codec_prvdata, &substream, 0);
  352. }
  353. }
  354. ark_i2s_start_play(i2s);
  355. i2s->cfg->status |= I2S_STA_OUTPUTTING;
  356. }
  357. if((dir & I2S_DIR_INPUT) && (i2s->cfg->dir & I2S_DIR_INPUT)){
  358. substream.stream = SNDRV_PCM_STREAM_CAPTURE;
  359. if (pdata && pdata->adc_inf && pdata->adc_inf->ops) {
  360. if (pdata->adc_inf->ops->set_fmt) {
  361. pdata->adc_inf->ops->set_fmt(pdata->adc_inf->codec_prvdata, pdata->dac_fmt);
  362. }
  363. if (pdata->adc_inf->ops->hw_params) {
  364. struct snd_soc_hw_params params;
  365. params.rates = i2s->cfg->rates;
  366. params.channels = i2s->cfg->channels;
  367. params.bits = i2s->cfg->bits;
  368. pdata->adc_inf->ops->hw_params(pdata->adc_inf->codec_prvdata, &substream, &params);
  369. }
  370. if (pdata->adc_inf->ops->startup) {
  371. pdata->adc_inf->ops->startup(pdata->adc_inf->codec_prvdata, &substream, 1);
  372. }
  373. if (pdata->adc_inf->ops->set_mute) {
  374. pdata->adc_inf->ops->set_mute(pdata->adc_inf->codec_prvdata, &substream, 0);
  375. }
  376. }
  377. ark_i2s_start_record(i2s);
  378. i2s->cfg->status |= I2S_STA_INPUTTING;
  379. }
  380. return 0;
  381. }
  382. int ark_i2s_stop(struct ark_i2s_drv *i2s, int dir)
  383. {
  384. ark_i2s_pd *pdata = i2s->extdata;
  385. struct snd_pcm_substream substream;
  386. u32 val;
  387. if (!i2s->cfg) {
  388. printf("[ERR] %s(), invalid cfg.\n", __func__);
  389. return -ENXIO;
  390. }
  391. if (dir & I2S_DIR_OUTPUT) {
  392. if ((i2s->cfg->status & I2S_STA_OUTPUTTING) == I2S_STA_OUTPUTTING){
  393. ark_i2s_stop_play(i2s);
  394. /* interrupt disable */
  395. val = readl(i2s->base + I2S_SAIMR);
  396. val &= ~(SAIMR_TFS | SAIMR_TUR);
  397. writel(val, i2s->base + I2S_SAIMR);
  398. }
  399. i2s->cfg->status &= ~I2S_STA_OUTPUTTING;
  400. substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
  401. if (pdata && pdata->dac_inf && pdata->dac_inf->ops && pdata->dac_inf->ops->startup) {
  402. pdata->dac_inf->ops->startup(pdata->dac_inf->codec_prvdata, &substream, 0);
  403. }
  404. }
  405. if (dir & I2S_DIR_INPUT) {
  406. if ((i2s->cfg->status & I2S_STA_INPUTTING) == I2S_STA_INPUTTING){
  407. ark_i2s_stop_record(i2s);
  408. /* interrupt disable */
  409. val = readl(i2s->base + I2S_SAIMR);
  410. val &= ~(SAIMR_ROR | SAIMR_RFS);
  411. writel(val, i2s->base + I2S_SAIMR);
  412. }
  413. i2s->cfg->status &= ~I2S_STA_INPUTTING;
  414. substream.stream = SNDRV_PCM_STREAM_CAPTURE;
  415. if (pdata && pdata->adc_inf && pdata->adc_inf->ops && pdata->adc_inf->ops->startup) {
  416. pdata->adc_inf->ops->startup(pdata->adc_inf->codec_prvdata, &substream, 0);
  417. }
  418. }
  419. if (!(i2s->cfg->status & (I2S_STA_OUTPUTTING | I2S_STA_INPUTTING))) {
  420. writel(readl(i2s->base + I2S_SACR0) & (~SACR0_ENB), i2s->base + I2S_SACR0);
  421. }
  422. return 0;
  423. }
  424. int ark_i2s_init(struct ark_i2s_drv *i2s, int dir)
  425. {
  426. if ((dir & I2S_DIR_FULL_DUPLEX) == 0) {
  427. printf("[ERR] %s(), invalid dir.\n", __func__);
  428. return -EINVAL;
  429. }
  430. if ((dir & I2S_DIR_FULL_DUPLEX) == I2S_DIR_FULL_DUPLEX) {
  431. if (!(i2s->sup_func & I2S_SUP_FULL_DUPLEX)) {
  432. printf("[ERR] %s(), invalid sup_func.\n", __func__);
  433. return -EPERM;
  434. }
  435. }
  436. if (i2s->is_master) {
  437. if (!(i2s->sup_func & I2S_SUP_MASTER)) {
  438. printf("[ERR] %s(), sup_func not support master.\n", __func__);
  439. return -EPERM;
  440. }
  441. } else {
  442. if (!(i2s->sup_func & I2S_SUP_SLAVER)) {
  443. printf("[ERR] %s(), sup_func not support slaver.\n", __func__);
  444. return -EPERM;
  445. }
  446. }
  447. i2s->dma_txch = NULL;
  448. i2s->dma_rxch = NULL;
  449. if (dir & I2S_DIR_OUTPUT) {
  450. if (i2s->sup_func & (I2S_SUP_OUTPUT | I2S_SUP_FULL_DUPLEX)) {
  451. i2s->dma_txch = dma_request_channel(i2s->dma_tx_chn);
  452. if (!i2s->dma_txch) {
  453. printf("[ERR] %s() i2s replay dma_request_channel fail.\n", __func__);
  454. return -ENODEV;
  455. }
  456. } else {
  457. printf("[ERR] %s() The i2s controller does not support output!\n", __func__);
  458. return -EINVAL;
  459. }
  460. }
  461. if (dir & I2S_DIR_INPUT) {
  462. if (i2s->sup_func & (I2S_SUP_INPUT | I2S_SUP_FULL_DUPLEX)) {
  463. i2s->dma_rxch = dma_request_channel(i2s->dma_rx_chn);
  464. if (!i2s->dma_rxch) {
  465. printf("[ERR] %s() i2s record dma_request_channel fail.\n", __func__);
  466. return -ENODEV;
  467. }
  468. } else {
  469. printf("[ERR] %s() The i2s controller does not support input!\n", __func__);
  470. return -EINVAL;
  471. }
  472. }
  473. i2s->cfg = (struct ark_i2s_cfg *)pvPortMalloc(sizeof(struct ark_i2s_cfg));
  474. if (!i2s->cfg) {
  475. printf("[ERR] %s(), malloc fail.\n", __func__);
  476. return -ENOMEM;
  477. }
  478. memset(i2s->cfg, 0, sizeof(struct ark_i2s_cfg));
  479. i2s->cfg->dir = dir;
  480. sys_soft_reset(i2s->softreset_id);
  481. i2s_soft_reset(i2s);
  482. vClkEnable(i2s->clkid);
  483. // request_irq(i2s->irqn, 0, IRQ_TYPE_LEVEL_HIGH, i2s_interrupt_handler, i2s);
  484. codec_init(i2s, dir);
  485. ark_i2s_set_rfirst(i2s, 1);
  486. return 0;
  487. }