Пример #1
0
static int s3c_i2s_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;

	unsigned long iiscon;
	unsigned long iismod;
	unsigned long iisfcon;
	s3cdbg("Entered %s\n", __FUNCTION__);

	writel((readl(S3C2410_MISCCR) & ~(7<<8))|(1<<8), S3C2410_MISCCR);

	/*Set I2C port to controll WM8753 codec*/
	s3c2410_gpio_pullup(S3C2410_GPE15, 0);
	s3c2410_gpio_pullup(S3C2410_GPE14, 0);
	s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_IICSDA);
	s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_IICSCL);

#if defined CONFIG_SND_SOC_I2S_V40
	/* Configure the I2S pins in correct mode */
	writel(0x0, S3C2450_GPESEL);

	s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK);
	s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK);
	s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
	s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
	s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);

	writel(readl(S3C2410_GPEUP)| 0x3ff, S3C2410_GPEUP);

	writel(readl(S3C2450_GPBSEL)|(0x3<<3), S3C2450_GPBSEL);
	writel(readl(S3C2410_GPBUP)|(0xF<<18), S3C2410_GPBUP);

#elif defined CONFIG_SND_SOC_I2S_V32
	/* Configure the I2S pins in correct mode */
	writel(0x0, S3C2450_GPLSEL);

	s3c2410_gpio_cfgpin(S3C2410_GPL4, S3C2450_GPL4_I2S1_SCLK);
	s3c2410_gpio_cfgpin(S3C2410_GPL5, S3C2450_GPL5_I2S1_CDCLK);
	s3c2410_gpio_cfgpin(S3C2410_GPL6, S3C2450_GPL6_I2S1_SDI);
	s3c2410_gpio_cfgpin(S3C2410_GPL7, S3C2450_GPL7_I2S1_SDO);
	s3c2410_gpio_cfgpin(S3C2443_GPJ13, S3C2450_GPJ13_I2S1_LRCK);

	writel(readl(S3C2410_GPLUP)| (0xf<<4), S3C2410_GPLUP);
	writel(readl(S3C2443_GPJDN)| (0x3<<26), S3C2443_GPJDN);

#else
	printk("Error: S3C2450 I2S configration \n",);
#endif

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out;
	} else {
		rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in;
	}

	/* Working copies of registers */
	iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON);
	iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
	iisfcon = readl(s3c24xx_i2s.regs + S3C2443_IISFIC);

	iiscon |= S3C_IIS0CON_TXDMACTIVE;
	iiscon |= S3C_IIS0CON_RXDMACTIVE;

	iismod &= ~S3C_IIS0MOD_CLK_MASK;
	iismod |= S3C_IIS0MOD_IMS_EXTERNAL_MASTER| S3C_IIS0MOD_INTERNAL_CLK;
	iismod &= ~S3C_IIS0MOD_MODE_MASK;
	iismod |= S3C_IIS0MOD_TXRXMODE;

	/* Multi channel enable */
	iismod &= ~S3C_IIS0MOD_DCE_MASK;
	switch (params_channels(params)) {
	case 6:
		printk("s3c i2s: 5.1channel\n");
		iismod |= S3C_IIS0MOD_DCE_SD1;
		iismod |= S3C_IIS0MOD_DCE_SD2;
		break;
	case 4:
		printk("s3c i2s: 4 channel\n");
		iismod |= S3C_IIS0MOD_DCE_SD1;
		break;
	case 2:
		printk("s3c i2s: 2 channel\n");
		break;
	default:
		printk(KERN_ERR "s3c-i2s-v40: %d channels unsupported\n",
		       params_channels(params));
		return -EINVAL;
	}

	/* Set the bit rate */
#if 0
	iismod &= ~0x6000;
#endif
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C_IIS0MOD_8BIT;
		iismod &= ~S3C_IIS0MOD_BFS_MASK;
		iismod |= S3C_IIS0MOD_32FS;
		iismod &= ~S3C_IIS0MOD_FS_MASK;
		iismod |= S3C_IIS0MOD_384FS;
		break;
	case SNDRV_PCM_FORMAT_S16_LE:
		iismod &= ~S3C_IIS0MOD_FS_MASK;
		iismod &= ~S3C_IIS0MOD_BFS_MASK;
		iismod |= S3C_IIS0MOD_384FS | S3C_IIS0MOD_32FS;
		iismod &= ~S3C_IIS0MOD_BLC_MASK;
		iismod |= S3C_IIS0MOD_16BIT;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		iismod &= ~S3C_IIS0MOD_FS_MASK;
		iismod &= ~S3C_IIS0MOD_BFS_MASK;
		iismod |= S3C_IIS0MOD_384FS | S3C_IIS0MOD_48FS;
		iismod &= ~S3C_IIS0MOD_BLC_MASK;
		iismod |= S3C_IIS0MOD_24BIT;
		break;
	default:
		return -EINVAL;
	}


	iisfcon |= S3C_IIS_TX_FLUSH;
	iisfcon |= S3C_IIS_RX_FLUSH;

	writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
	iismod &= ~S3C_IIS0MOD_FM_MASK;
	writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
	writel(iisfcon, s3c24xx_i2s.regs + S3C2443_IISFIC);

	/* Tx, Rx fifo flush bit clear */
	iisfcon  &= ~(S3C_IIS_TX_FLUSH | S3C_IIS_RX_FLUSH);
	writel(iisfcon, s3c24xx_i2s.regs + S3C2443_IISFIC);

	s3cdbg("s3c iis mode: 0x%08x\n", readl(s3c24xx_i2s.regs + S3C2410_IISMOD));
	s3cdbg("s3c: params_channels %d\n", params_channels(params));
	s3cdbg("s3c: params_format %d\n", params_format(params));
	s3cdbg("s3c: params_subformat %d\n", params_subformat(params));
	s3cdbg("s3c: params_period_size %d\n", params_period_size(params));
	s3cdbg("s3c: params_period_bytes %d\n", params_period_bytes(params));
	s3cdbg("s3c: params_periods %d\n", params_periods(params));
	s3cdbg("s3c: params_buffer_size %d\n", params_buffer_size(params));
	s3cdbg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params));
	s3cdbg("s3c: params_tick_time %d\n", params_tick_time(params));

	return 0;
}
Пример #2
0
static int s3c_i2s_v40_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;

	unsigned long iiscon;
	unsigned long iismod;
	unsigned long iisfcon;
	
	s3cdbg("Entered %s\n", __FUNCTION__);

	s3c64xx_i2s.master = 1;
	
	/* Configure the I2S pins in correct mode */
	s3c_gpio_cfgpin(S3C_GPH8,S3C_GPH8_I2S_V40_LRCLK);

	if (s3c64xx_i2s.master && !extclk){
		s3cdbg("Setting Clock Output as we are Master\n");
		s3c_gpio_cfgpin(S3C_GPH6,S3C_GPH6_I2S_V40_BCLK);
	}

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		rtd->dai->cpu_dai->dma_data = &s3c64xx_i2s_pcm_stereo_out;
	} else {
		rtd->dai->cpu_dai->dma_data = &s3c64xx_i2s_pcm_stereo_in;
	}

	/* Working copies of registers */
	iiscon = readl(s3c64xx_i2s.regs + S3C64XX_IIS0CON);
	iismod = readl(s3c64xx_i2s.regs + S3C64XX_IIS0MOD);
	iisfcon = readl(s3c64xx_i2s.regs + S3C64XX_IIS0FIC);

	/* is port used by another stream */
	if (!(iiscon & S3C64XX_IIS0CON_I2SACTIVE)) {

		/* Clear BFS field [2:1] */
		iismod &= ~(0x3<<1);
		iismod |= S3C64XX_IIS0MOD_32FS | S3C64XX_IIS0MOD_INTERNAL_CLK;

		if (!s3c64xx_i2s.master)
			iismod |= S3C64XX_IISMOD_SLAVE;
		else
			iismod |= S3C64XX_IIS0MOD_IMS_EXTERNAL_MASTER;
	}

	iiscon |= S3C64XX_IISCON_FTXURINTEN;
	iiscon |= S3C64XX_IIS0CON_TXDMACTIVE;
	iiscon |= S3C64XX_IIS0CON_RXDMACTIVE;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		iismod |= S3C64XX_IIS0MOD_TXMODE;
		iisfcon |= S3C64XX_IIS_TX_FLUSH;
	} else {
		iismod |= S3C64XX_IIS0MOD_RXMODE;
		iisfcon |= S3C64XX_IIS_RX_FLUSH;
	}

	/* Multi channel enable */
	iismod &= ~S3C64XX_IIS0MOD_DCE_MASK;
	switch (params_channels(params)) {
	case 6:
		printk("s3c i2s: 5.1channel\n");
		iismod |= S3C64XX_IIS0MOD_DCE_SD2;
		iismod |= S3C64XX_IIS0MOD_DCE_SD2;
		break;
	case 4:
		printk("s3c i2s: 4 channel\n");
		iismod |= S3C64XX_IIS0MOD_DCE_SD2;
		break;
	case 2:
		printk("s3c i2s: 2 channel\n");
		break;
	default:
		printk(KERN_ERR "s3c-i2s-v40: %d channels unsupported\n",
		       params_channels(params));
		return -EINVAL;
	}

	/* Set the bit rate */
	iismod &= ~0x6000;
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		iismod &= ~S3C64XX_IIS0MOD_FS_MASK;
		iismod |= S3C64XX_IIS0MOD_256FS | S3C64XX_IIS0MOD_32FS;
		iismod &= ~(0x3<<13);
		iismod |= S3C64XX_IIS0MOD_16BIT;
		break;
	case SNDRV_PCM_FORMAT_S8:
		iismod |= S3C64XX_IIS0MOD_8BIT;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		iismod &= ~S3C64XX_IIS0MOD_FS_MASK;
		iismod |= S3C64XX_IIS0MOD_384FS | S3C64XX_IIS0MOD_48FS;
		iismod &= ~(0x3<<13);
		iismod |= S3C64XX_IIS0MOD_24BIT;
		break;
	default:
		return -EINVAL;
	}

	writel(iisfcon, s3c64xx_i2s.regs + S3C64XX_IIS0FIC);
	writel(iiscon, s3c64xx_i2s.regs + S3C64XX_IIS0CON);
	writel(iismod, s3c64xx_i2s.regs + S3C64XX_IIS0MOD);

	// Tx, Rx fifo flush bit clear
	iisfcon  &= ~(S3C64XX_IIS_TX_FLUSH | S3C64XX_IIS_RX_FLUSH);
	writel(iisfcon, s3c64xx_i2s.regs + S3C64XX_IIS0FIC);

	s3cdbg("s3c iis mode: 0x%08x\n", readl(s3c64xx_i2s.regs + S3C64XX_IIS0MOD));
	s3cdbg("s3c: params_channels %d\n", params_channels(params));
	s3cdbg("s3c: params_format %d\n", params_format(params));
	s3cdbg("s3c: params_subformat %d\n", params_subformat(params));
	s3cdbg("s3c: params_period_size %d\n", params_period_size(params));
	s3cdbg("s3c: params_period_bytes %d\n", params_period_bytes(params));
	s3cdbg("s3c: params_periods %d\n", params_periods(params));
	s3cdbg("s3c: params_buffer_size %d\n", params_buffer_size(params));
	s3cdbg("s3c: params_buffer_bytes %d\n", params_buffer_bytes(params));
	s3cdbg("s3c: params_tick_time %d\n", params_tick_time(params));
	s3cdbg("hw_params: IISCON: %lx IISMOD: %lx\n", iiscon, iismod);

	return 0;

}