Example #1
0
static int sunxi_i2s_preapre(struct snd_pcm_substream *substream,
	struct snd_soc_dai *dai)
{
	u32 reg_val = 0;
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		reg_val = SUNXI_TXCHSEL_CHNUM(substream->runtime->channels);
		/*confige i2s ap tx channel */
		codec_wr_control(SUNXI_DA_TXCHSEL, 0x7, TX_CHSEL, reg_val);
		if(substream->runtime->channels == 1) {
			reg_val = 0x00;
		} else {
			reg_val = 0x10;
		}
		/*confige i2s ap tx channel mapping*/
		codec_wr_control(SUNXI_DA_TXCHMAP, 0x7, TX_CH0_MAP, reg_val);
		/*SDO ON*/
		codec_wr_control(SUNXI_DA_CTL, 0x1, SDO_EN, 1);
		/* I2S0 TX ENABLE */
		codec_wr_control(SUNXI_DA_CTL, 0x1, TXEN, 1);
	} else {
		reg_val = SUNXI_RXCHSEL_CHNUM(substream->runtime->channels);
		/*confige i2s ap rx channel */
		codec_wr_control(SUNXI_DA_RXCHSEL, 0x7, RX_CHSEL, reg_val);
		if(substream->runtime->channels == 1) {
			reg_val = 0x00;
		} else {
			reg_val = 0x10;
		}
		/*confige i2s ap rx channel mapping*/
		codec_wr_control(SUNXI_DA_RXCHMAP, 0x7, RX_CH0_MAP, reg_val);
		/* I2S0 RX ENABLE */
		codec_wr_control(SUNXI_DA_CTL, 0x1, RXEN, 1);
	}

	return 0;
}
void sunxi_snd_txctrl_i2s(struct snd_pcm_substream *substream, int on)
{
	u32 reg_val;

	reg_val = readl(sunxi_iis.regs + SUNXI_TXCHSEL);
	reg_val &= ~0x7;
	reg_val |= SUNXI_TXCHSEL_CHNUM(substream->runtime->channels);
	writel(reg_val, sunxi_iis.regs + SUNXI_TXCHSEL);

	reg_val = readl(sunxi_iis.regs + SUNXI_TXCHMAP);
	reg_val = 0;
	if (sunxi_is_sun4i()) {
		if(substream->runtime->channels == 1) {
			reg_val = 0x76543200;
		} else {
			reg_val = 0x76543210;
		}
	} else {
		if(substream->runtime->channels == 1) {
			reg_val = 0x00000000;
		} else {
			reg_val = 0x00000010;
		}
	}
	writel(reg_val, sunxi_iis.regs + SUNXI_TXCHMAP);

	reg_val = readl(sunxi_iis.regs + SUNXI_IISCTL);
	if (sunxi_is_sun4i()) {
		reg_val &= ~SUNXI_IISCTL_SDO3EN;
		reg_val &= ~SUNXI_IISCTL_SDO2EN;
		reg_val &= ~SUNXI_IISCTL_SDO1EN;
		reg_val &= ~SUNXI_IISCTL_SDO0EN;
		switch(substream->runtime->channels) {
			case 1:
			case 2:
				reg_val |= SUNXI_IISCTL_SDO0EN;
				break;
			case 3:
			case 4:
				reg_val |= SUNXI_IISCTL_SDO0EN;
				reg_val |= SUNXI_IISCTL_SDO1EN;
				break;
			case 5:
			case 6:
				reg_val |= SUNXI_IISCTL_SDO0EN;
				reg_val |= SUNXI_IISCTL_SDO1EN;
				reg_val |= SUNXI_IISCTL_SDO2EN;
				break;
			case 7:
			case 8:
				reg_val |= SUNXI_IISCTL_SDO0EN;
				reg_val |= SUNXI_IISCTL_SDO1EN;
				reg_val |= SUNXI_IISCTL_SDO2EN;
				reg_val |= SUNXI_IISCTL_SDO3EN;
				break;
			default:
				reg_val |= SUNXI_IISCTL_SDO0EN;
		}
	} else {
		reg_val |= SUNXI_IISCTL_SDO0EN;
	}
	writel(reg_val, sunxi_iis.regs + SUNXI_IISCTL);

	//flush TX FIFO
	reg_val = readl(sunxi_iis.regs + SUNXI_IISFCTL);
	reg_val |= SUNXI_IISFCTL_FTX;
	writel(reg_val, sunxi_iis.regs + SUNXI_IISFCTL);

	//clear TX counter
	writel(0, sunxi_iis.regs + SUNXI_IISTXCNT);

	if (on) {
		/* IIS TX ENABLE */
		reg_val = readl(sunxi_iis.regs + SUNXI_IISCTL);
		reg_val |= SUNXI_IISCTL_TXEN;
		writel(reg_val, sunxi_iis.regs + SUNXI_IISCTL);

		/* enable DMA DRQ mode for play */
		reg_val = readl(sunxi_iis.regs + SUNXI_IISINT);
		reg_val |= SUNXI_IISINT_TXDRQEN;
		writel(reg_val, sunxi_iis.regs + SUNXI_IISINT);

		//Global Enable Digital Audio Interface
		reg_val = readl(sunxi_iis.regs + SUNXI_IISCTL);
		reg_val |= SUNXI_IISCTL_GEN;
		writel(reg_val, sunxi_iis.regs + SUNXI_IISCTL);

	} else {
		/* IIS TX DISABLE */
		reg_val = readl(sunxi_iis.regs + SUNXI_IISCTL);
		reg_val &= ~SUNXI_IISCTL_TXEN;
		writel(reg_val, sunxi_iis.regs + SUNXI_IISCTL);

		/* DISBALE dma DRQ mode */
		reg_val = readl(sunxi_iis.regs + SUNXI_IISINT);
		reg_val &= ~SUNXI_IISINT_TXDRQEN;
		writel(reg_val, sunxi_iis.regs + SUNXI_IISINT);

		//Global disable Digital Audio Interface
		reg_val = readl(sunxi_iis.regs + SUNXI_IISCTL);
		reg_val &= ~SUNXI_IISCTL_GEN;
		writel(reg_val, sunxi_iis.regs + SUNXI_IISCTL);
	}
}
Example #3
0
static void sunxi_snd_txctrl_i2s1(struct snd_pcm_substream *substream, int on)
{
    u32 reg_val;

    reg_val = readl(sunxi_i2s1.regs + SUNXI_TXCHSEL);
    reg_val &= ~0x7;
    reg_val |= SUNXI_TXCHSEL_CHNUM(substream->runtime->channels);
    writel(reg_val, sunxi_i2s1.regs + SUNXI_TXCHSEL);

    reg_val = readl(sunxi_i2s1.regs + SUNXI_TXCHMAP);
    reg_val = 0;
    if(substream->runtime->channels == 1) {
        reg_val = 0x76543200;
    } else {
        reg_val = 0x76543210;
    }
    writel(reg_val, sunxi_i2s1.regs + SUNXI_TXCHMAP);

    reg_val = readl(sunxi_i2s1.regs + SUNXI_I2S1CTL);
    reg_val &= ~SUNXI_I2S1CTL_SDO3EN;
    reg_val &= ~SUNXI_I2S1CTL_SDO2EN;
    reg_val &= ~SUNXI_I2S1CTL_SDO1EN;
    reg_val &= ~SUNXI_I2S1CTL_SDO0EN;
    switch(substream->runtime->channels) {
    case 1:
    case 2:
        reg_val |= SUNXI_I2S1CTL_SDO0EN;
        break;
    case 3:
    case 4:
        reg_val |= SUNXI_I2S1CTL_SDO0EN | SUNXI_I2S1CTL_SDO1EN;
        break;
    case 5:
    case 6:
        reg_val |= SUNXI_I2S1CTL_SDO0EN | SUNXI_I2S1CTL_SDO1EN | SUNXI_I2S1CTL_SDO2EN;
        break;
    case 7:
    case 8:
        reg_val |= SUNXI_I2S1CTL_SDO0EN | SUNXI_I2S1CTL_SDO1EN | SUNXI_I2S1CTL_SDO2EN | SUNXI_I2S1CTL_SDO3EN;
        break;
    default:
        reg_val |= SUNXI_I2S1CTL_SDO0EN;
        break;
    }
    writel(reg_val, sunxi_i2s1.regs + SUNXI_I2S1CTL);

    /*flush TX FIFO*/
    reg_val = readl(sunxi_i2s1.regs + SUNXI_I2S1FCTL);
    reg_val |= SUNXI_I2S1FCTL_FTX;
    writel(reg_val, sunxi_i2s1.regs + SUNXI_I2S1FCTL);

    /*clear TX counter*/
    writel(0, sunxi_i2s1.regs + SUNXI_I2S1TXCNT);

    if (on) {
        /* I2S1 TX ENABLE */
        reg_val = readl(sunxi_i2s1.regs + SUNXI_I2S1CTL);
        reg_val |= SUNXI_I2S1CTL_TXEN;
        writel(reg_val, sunxi_i2s1.regs + SUNXI_I2S1CTL);

        /* enable DMA DRQ mode for play */
        reg_val = readl(sunxi_i2s1.regs + SUNXI_I2S1INT);
        reg_val |= SUNXI_I2S1INT_TXDRQEN;
        writel(reg_val, sunxi_i2s1.regs + SUNXI_I2S1INT);
    } else {
        /* I2S1 TX DISABLE */
        reg_val = readl(sunxi_i2s1.regs + SUNXI_I2S1CTL);
        reg_val &= ~SUNXI_I2S1CTL_TXEN;
        writel(reg_val, sunxi_i2s1.regs + SUNXI_I2S1CTL);

        /* DISBALE dma DRQ mode */
        reg_val = readl(sunxi_i2s1.regs + SUNXI_I2S1INT);
        reg_val &= ~SUNXI_I2S1INT_TXDRQEN;
        writel(reg_val, sunxi_i2s1.regs + SUNXI_I2S1INT);
    }
}