void sun4i_snd_txctrl_i2s(struct snd_pcm_substream *substream, int on) { u32 reg_val; reg_val = readl(sun4i_iis.regs + SUN4I_TXCHSEL); reg_val &= ~0x7; reg_val |= SUN4I_TXCHSEL_CHNUM(substream->runtime->channels); writel(reg_val, sun4i_iis.regs + SUN4I_TXCHSEL); reg_val = readl(sun4i_iis.regs + SUN4I_TXCHMAP); reg_val = 0; if(substream->runtime->channels == 1) { reg_val = 0x76543200; } else { reg_val = 0x76543210; } writel(reg_val, sun4i_iis.regs + SUN4I_TXCHMAP); reg_val = readl(sun4i_iis.regs + SUN4I_IISCTL); reg_val &= ~SUN4I_IISCTL_SDO3EN; reg_val &= ~SUN4I_IISCTL_SDO2EN; reg_val &= ~SUN4I_IISCTL_SDO1EN; reg_val &= ~SUN4I_IISCTL_SDO0EN; switch(substream->runtime->channels) { case 1: case 2: reg_val |= SUN4I_IISCTL_SDO0EN; break; #ifdef I2S_COMMUNICATION case 3: case 4: reg_val |= SUN4I_IISCTL_SDO0EN | SUN4I_IISCTL_SDO1EN; break; case 5: case 6: reg_val |= SUN4I_IISCTL_SDO0EN | SUN4I_IISCTL_SDO1EN | SUN4I_IISCTL_SDO2EN; break; case 7: case 8: reg_val |= SUN4I_IISCTL_SDO0EN | SUN4I_IISCTL_SDO1EN | SUN4I_IISCTL_SDO2EN | SUN4I_IISCTL_SDO3EN; break; #endif default: reg_val |= SUN4I_IISCTL_SDO0EN; break; } writel(reg_val, sun4i_iis.regs + SUN4I_IISCTL); //flush TX FIFO reg_val = readl(sun4i_iis.regs + SUN4I_IISFCTL); reg_val |= SUN4I_IISFCTL_FTX; writel(reg_val, sun4i_iis.regs + SUN4I_IISFCTL); //clear TX counter writel(0, sun4i_iis.regs + SUN4I_IISTXCNT); if (on) { /* IIS TX ENABLE */ reg_val = readl(sun4i_iis.regs + SUN4I_IISCTL); reg_val |= SUN4I_IISCTL_TXEN; writel(reg_val, sun4i_iis.regs + SUN4I_IISCTL); /* enable DMA DRQ mode for play */ reg_val = readl(sun4i_iis.regs + SUN4I_IISINT); reg_val |= SUN4I_IISINT_TXDRQEN; writel(reg_val, sun4i_iis.regs + SUN4I_IISINT); //Global Enable Digital Audio Interface reg_val = readl(sun4i_iis.regs + SUN4I_IISCTL); reg_val |= SUN4I_IISCTL_GEN; writel(reg_val, sun4i_iis.regs + SUN4I_IISCTL); } else { /* IIS TX DISABLE */ reg_val = readl(sun4i_iis.regs + SUN4I_IISCTL); reg_val &= ~SUN4I_IISCTL_TXEN; writel(reg_val, sun4i_iis.regs + SUN4I_IISCTL); /* DISBALE dma DRQ mode */ reg_val = readl(sun4i_iis.regs + SUN4I_IISINT); reg_val &= ~SUN4I_IISINT_TXDRQEN; writel(reg_val, sun4i_iis.regs + SUN4I_IISINT); //Global disable Digital Audio Interface reg_val = readl(sun4i_iis.regs + SUN4I_IISCTL); reg_val &= ~SUN4I_IISCTL_GEN; writel(reg_val, sun4i_iis.regs + SUN4I_IISCTL); } }
void sun4i_snd_txctrl_hdmiaudio(struct snd_pcm_substream *substream, int on) { u32 reg_val; hdmi_para.channel_num = substream->runtime->channels; g_hdmi_func.hdmi_set_audio_para(&hdmi_para); reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_TXCHSEL); reg_val &= ~0x7; reg_val |= SUN4I_TXCHSEL_CHNUM(substream->runtime->channels); writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_TXCHSEL); reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_TXCHMAP); reg_val = 0; if(substream->runtime->channels == 1) { reg_val = 0x76543200; } else { reg_val = 0x76543210; } writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_TXCHMAP); reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); reg_val &= ~SUN4I_HDMIAUDIOCTL_SDO3EN; reg_val &= ~SUN4I_HDMIAUDIOCTL_SDO2EN; reg_val &= ~SUN4I_HDMIAUDIOCTL_SDO1EN; reg_val &= ~SUN4I_HDMIAUDIOCTL_SDO0EN; switch(substream->runtime->channels) { case 1: case 2: reg_val |= SUN4I_HDMIAUDIOCTL_SDO0EN; break; case 3: case 4: reg_val |= SUN4I_HDMIAUDIOCTL_SDO0EN | SUN4I_HDMIAUDIOCTL_SDO1EN; break; case 5: case 6: reg_val |= SUN4I_HDMIAUDIOCTL_SDO0EN | SUN4I_HDMIAUDIOCTL_SDO1EN | SUN4I_HDMIAUDIOCTL_SDO2EN; break; case 7: case 8: reg_val |= SUN4I_HDMIAUDIOCTL_SDO0EN | SUN4I_HDMIAUDIOCTL_SDO1EN | SUN4I_HDMIAUDIOCTL_SDO2EN | SUN4I_HDMIAUDIOCTL_SDO3EN; break; default: reg_val |= SUN4I_HDMIAUDIOCTL_SDO0EN; break; } writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); // printk(KERN_WARNING "[HDMIAUDIO] 0x01c22400 = %#x, line= %d\n", *(volatile int*)0xF1C22400, __LINE__); // printk(KERN_WARNING "[HDMIAUDIO] 0x01c22430 = %#x, line= %d\n", *(volatile int*)0xF1C22430, __LINE__); // printk(KERN_WARNING "[HDMIAUDIO] 0x01c22434 = %#x, line= %d\n", *(volatile int*)0xF1C22434, __LINE__); //flush TX FIFO reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOFCTL); reg_val |= SUN4I_HDMIAUDIOFCTL_FTX; writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOFCTL); //clear TX counter writel(0, sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOTXCNT); if(on){ /* hdmiaudio TX ENABLE */ reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); reg_val |= SUN4I_HDMIAUDIOCTL_TXEN; writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); /* enable DMA DRQ mode for play */ reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOINT); reg_val |= SUN4I_HDMIAUDIOINT_TXDRQEN; writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOINT); //Global Enable Digital Audio Interface reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); reg_val |= SUN4I_HDMIAUDIOCTL_GEN; writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); }else{ /* HDMIAUDIO TX DISABLE */ reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); reg_val &= ~SUN4I_HDMIAUDIOCTL_TXEN; writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); /* DISBALE dma DRQ mode */ reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOINT); reg_val &= ~SUN4I_HDMIAUDIOINT_TXDRQEN; writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOINT); //Global disable Digital Audio Interface reg_val = readl(sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); reg_val &= ~SUN4I_HDMIAUDIOCTL_GEN; writel(reg_val, sun4i_hdmiaudio.regs + SUN4I_HDMIAUDIOCTL); } }