| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- #include "FreeRTOS.h"
- #include "chip.h"
- #include "board.h"
- #include "audio/audio.h"
- #include "i2s.h"
- int ark_i2s_startup(struct ark_i2s_data *i2s, int stream)
- {
- unsigned int val;
- /* reset */
- /* writel(SACR0_RST, i2s->base + I2S_SACR0);
- udelay(1);
- writel(0, i2s->base + I2S_SACR0); */
- if (stream == AUDIO_STREAM_REPLAY) {
- writel(SACR1_DREC, i2s->base + I2S_SACR1);
- writel(SAIMR_TUR, i2s->base + I2S_SAIMR);
- writel(0x7f, i2s->base + I2S_SAICR);
- writel(0, i2s->base + I2S_SAICR);
- val = SACR0_TLFIRST | SACR0_CH_LOCK | SACR0_TFTH(15) | SACR0_TDMAEN | SACR0_ENB;
- if (i2s->master)
- val |= SACR0_BCKD | SACR0_SYNCD;
- if (i2s->channels == 1)
- val |= SACR0_MOLO_MODE;
- if (i2s->samplebits == 32)
- val |= SACR0_32BIT_MODE;
- writel(val, i2s->base + I2S_SACR0);
- } else if(stream == AUDIO_STREAM_RECORD) {
- writel(SACR1_DRPL, i2s->base + I2S_SACR1);
- val = readl(i2s->base + I2S_ADCR0);
- val &= ~(ADCR0_LVOL_MASK | ADCR0_RVOL_MASK | ADCR0_LFS_MASK |
- ADCR0_RFS_MASK);
- val |= ADCR0_LVOL(2) | ADCR0_RVOL(2) | ADCR0_LFS_1P4 |
- ADCR0_RFS_1P4 | ADCR0_LME | ADCR0_RME;
- writel(val, i2s->base + I2S_ADCR0);
- writel(0, i2s->base + I2S_SAIMR);
- writel(0x7f, i2s->base + I2S_SAICR);
- writel(0, i2s->base + I2S_SAICR);
- val = SACR0_RLFIRST | SACR0_CH_LOCK | SACR0_RFTH(16) | SACR0_RDMAEN | SACR0_ENB;
- if (i2s->master)
- val |= SACR0_BCKD | SACR0_SYNCD;
- writel(val, i2s->base + I2S_SACR0);
- }
- return 0;
- }
- int ark_i2s_set_rate(struct ark_i2s_data *i2s, unsigned int rate)
- {
- u32 step = 256 * 2, modulo;
- u32 val, freq;
- if (!i2s->nco_reg)
- return 0;
- /* mclk = rate * 256, mclk = freq * step / (2 * modulo) */
- freq = ulClkGetRate(i2s->clkid);
- modulo = freq / rate;
- val = (step << 16) | modulo;
- writel(val, i2s->nco_reg);
- return 0;
- }
- int ark_i2s_set_channels(struct ark_i2s_data *i2s, int channels)
- {
- unsigned int val;
- if (channels != 1 && channels != 2) {
- printf("Unsupported i2s channels %d.\n", channels);
- return -1;
- }
- val = readl(i2s->base + I2S_SACR0);
- if (channels == 1)
- val |= SACR0_MOLO_MODE;
- else
- val &= ~SACR0_MOLO_MODE;
- writel(val, i2s->base + I2S_SACR0);
- i2s->channels = channels;
- return 0;
- }
- int ark_i2s_set_samplebits(struct ark_i2s_data *i2s, int bits)
- {
- unsigned int val;
- if (bits != 16 && bits != 32) {
- printf("Unsupported i2s samplebits %d.\n", bits);
- return -1;
- }
- val = readl(i2s->base + I2S_SACR0);
- if (bits == 32)
- val |= SACR0_32BIT_MODE;
- else
- val &= ~SACR0_32BIT_MODE;
- writel(val, i2s->base + I2S_SACR0);
- i2s->samplebits = bits;
- return 0;
- }
- void ark_i2s_stop(struct ark_i2s_data *i2s, int stream)
- {
- if (stream == AUDIO_STREAM_REPLAY)
- writel(readl(i2s->base + I2S_SACR1) | SACR1_DRPL, i2s->base + I2S_SACR1);
- else if (stream == AUDIO_STREAM_RECORD)
- writel(readl(i2s->base + I2S_SACR1) | SACR1_DREC, i2s->base + I2S_SACR1);
- writel(readl(i2s->base + I2S_SACR0) & ~SACR0_ENB, i2s->base + I2S_SACR0);
- }
- void i2s_interrupt_handler(void *param)
- {
- struct ark_i2s_data *i2s = param;
- unsigned int status;
- status = readl(i2s->base + I2S_SASR0);
- writel(0xff, i2s->base + I2S_SAICR);
- if (status & SASR0_TUR) {
- printf("i2s txfifo underrun.\n");
- }
- }
- int ark_i2s_init(struct ark_i2s_data *i2s)
- {
- i2s->dma_ch = dma_request_channel(I2S_DMA_CH);
- if (!i2s->dma_ch) {
- printf("i2s dma_request_channel fail.\n");
- return -1;
- }
- sys_soft_reset(softreset_i2s);
- //request_irq(I2S_IRQn, 0, i2s_interrupt_handler, i2s);
- return 0;
- }
|