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; }
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; }