i2s.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "FreeRTOS.h"
  2. #include "chip.h"
  3. #include "board.h"
  4. #include "audio/audio.h"
  5. #include "i2s.h"
  6. int ark_i2s_startup(struct ark_i2s_data *i2s, int stream)
  7. {
  8. unsigned int val;
  9. /* reset */
  10. /* writel(SACR0_RST, i2s->base + I2S_SACR0);
  11. udelay(1);
  12. writel(0, i2s->base + I2S_SACR0); */
  13. if (stream == AUDIO_STREAM_REPLAY) {
  14. writel(SACR1_DREC, i2s->base + I2S_SACR1);
  15. writel(SAIMR_TUR, i2s->base + I2S_SAIMR);
  16. writel(0x7f, i2s->base + I2S_SAICR);
  17. writel(0, i2s->base + I2S_SAICR);
  18. val = SACR0_TLFIRST | SACR0_CH_LOCK | SACR0_TFTH(15) | SACR0_TDMAEN | SACR0_ENB;
  19. if (i2s->master)
  20. val |= SACR0_BCKD | SACR0_SYNCD;
  21. if (i2s->channels == 1)
  22. val |= SACR0_MOLO_MODE;
  23. if (i2s->samplebits == 32)
  24. val |= SACR0_32BIT_MODE;
  25. writel(val, i2s->base + I2S_SACR0);
  26. } else if(stream == AUDIO_STREAM_RECORD) {
  27. writel(SACR1_DRPL, i2s->base + I2S_SACR1);
  28. val = readl(i2s->base + I2S_ADCR0);
  29. val &= ~(ADCR0_LVOL_MASK | ADCR0_RVOL_MASK | ADCR0_LFS_MASK |
  30. ADCR0_RFS_MASK);
  31. val |= ADCR0_LVOL(2) | ADCR0_RVOL(2) | ADCR0_LFS_1P4 |
  32. ADCR0_RFS_1P4 | ADCR0_LME | ADCR0_RME;
  33. writel(val, i2s->base + I2S_ADCR0);
  34. writel(0, i2s->base + I2S_SAIMR);
  35. writel(0x7f, i2s->base + I2S_SAICR);
  36. writel(0, i2s->base + I2S_SAICR);
  37. val = SACR0_RLFIRST | SACR0_CH_LOCK | SACR0_RFTH(16) | SACR0_RDMAEN | SACR0_ENB;
  38. if (i2s->master)
  39. val |= SACR0_BCKD | SACR0_SYNCD;
  40. writel(val, i2s->base + I2S_SACR0);
  41. }
  42. return 0;
  43. }
  44. int ark_i2s_set_rate(struct ark_i2s_data *i2s, unsigned int rate)
  45. {
  46. u32 step = 256 * 2, modulo;
  47. u32 val, freq;
  48. if (!i2s->nco_reg)
  49. return 0;
  50. /* mclk = rate * 256, mclk = freq * step / (2 * modulo) */
  51. freq = ulClkGetRate(i2s->clkid);
  52. modulo = freq / rate;
  53. val = (step << 16) | modulo;
  54. writel(val, i2s->nco_reg);
  55. return 0;
  56. }
  57. int ark_i2s_set_channels(struct ark_i2s_data *i2s, int channels)
  58. {
  59. unsigned int val;
  60. if (channels != 1 && channels != 2) {
  61. printf("Unsupported i2s channels %d.\n", channels);
  62. return -1;
  63. }
  64. val = readl(i2s->base + I2S_SACR0);
  65. if (channels == 1)
  66. val |= SACR0_MOLO_MODE;
  67. else
  68. val &= ~SACR0_MOLO_MODE;
  69. writel(val, i2s->base + I2S_SACR0);
  70. i2s->channels = channels;
  71. return 0;
  72. }
  73. int ark_i2s_set_samplebits(struct ark_i2s_data *i2s, int bits)
  74. {
  75. unsigned int val;
  76. if (bits != 16 && bits != 32) {
  77. printf("Unsupported i2s samplebits %d.\n", bits);
  78. return -1;
  79. }
  80. val = readl(i2s->base + I2S_SACR0);
  81. if (bits == 32)
  82. val |= SACR0_32BIT_MODE;
  83. else
  84. val &= ~SACR0_32BIT_MODE;
  85. writel(val, i2s->base + I2S_SACR0);
  86. i2s->samplebits = bits;
  87. return 0;
  88. }
  89. void ark_i2s_stop(struct ark_i2s_data *i2s, int stream)
  90. {
  91. if (stream == AUDIO_STREAM_REPLAY)
  92. writel(readl(i2s->base + I2S_SACR1) | SACR1_DRPL, i2s->base + I2S_SACR1);
  93. else if (stream == AUDIO_STREAM_RECORD)
  94. writel(readl(i2s->base + I2S_SACR1) | SACR1_DREC, i2s->base + I2S_SACR1);
  95. writel(readl(i2s->base + I2S_SACR0) & ~SACR0_ENB, i2s->base + I2S_SACR0);
  96. }
  97. void i2s_interrupt_handler(void *param)
  98. {
  99. struct ark_i2s_data *i2s = param;
  100. unsigned int status;
  101. status = readl(i2s->base + I2S_SASR0);
  102. writel(0xff, i2s->base + I2S_SAICR);
  103. if (status & SASR0_TUR) {
  104. printf("i2s txfifo underrun.\n");
  105. }
  106. }
  107. int ark_i2s_init(struct ark_i2s_data *i2s)
  108. {
  109. i2s->dma_ch = dma_request_channel(I2S_DMA_CH);
  110. if (!i2s->dma_ch) {
  111. printf("i2s dma_request_channel fail.\n");
  112. return -1;
  113. }
  114. sys_soft_reset(softreset_i2s);
  115. //request_irq(I2S_IRQn, 0, i2s_interrupt_handler, i2s);
  116. return 0;
  117. }