static int __init smdk64xx_audio_init(void) { int ret, div; unsigned int reg; /* Provide 12MHz at Codec's XTI-O from XCLKOUT */ /* Set EPLLout to 4*12MHz */ div = 4; ret = set_epll_rate(SMDK64XX_WM8580_FREQ * div); if (ret < 0) return ret; /* Set XCLK_OUT enable */ reg = __raw_readl(S5P_CLK_OUT); reg &= ~((0x1f<<12) | (0xf<<20)); reg |= ((0x2<<12) | ((div-1)<<20)); __raw_writel(reg, S5P_CLK_OUT); smdk64xx_snd_device = platform_device_alloc("soc-audio", -1); if (!smdk64xx_snd_device) return -ENOMEM; platform_set_drvdata(smdk64xx_snd_device, &smdk64xx_snd_devdata); smdk64xx_snd_devdata.dev = &smdk64xx_snd_device->dev; ret = platform_device_add(smdk64xx_snd_device); if (ret) platform_device_put(smdk64xx_snd_device); return ret; }
static int mehmet_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned long epll_out_rate; int rfs, ret; switch (params_rate(params)) { case 8000: case 16000: epll_out_rate = 49152000; break; default: printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } switch (params_rate(params)) { case 16000: rfs = 128; break; case 8000: rfs = 256; break; break; default: printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } /* Set the cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* Set EPLL clock rate */ ret = set_epll_rate(epll_out_rate); if (ret < 0) return ret; /* 8kHz * 256(16bits * 16slots, frame sync) = 2048kHz Clock Out */ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX, params_rate(params)*rfs, SND_SOC_CLOCK_OUT); /* Set SCLK_DIV for making bclk */ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs); if (ret < 0) return ret; return 0; }
static int smdk4x12_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int rate = params_rate(params); snd_pcm_format_t fmt = params_format( params ); int bclk_div = 0, bfs, psr = 0, rfs = 0, rclk_div = 0, ret = 0; unsigned int mul = 0; unsigned long rclk = 0; dprintk("+%s()\n", __FUNCTION__); switch (fmt){ case SNDRV_PCM_FORMAT_S16: bclk_div = 32; break; case SNDRV_PCM_FORMAT_S20_3LE: case SNDRV_PCM_FORMAT_S24: bclk_div = 48; break; default: dprintk("-%s(): PCM FMT ERROR\n", __FUNCTION__); return -EINVAL; } switch (params_format(params)){ case SNDRV_PCM_FORMAT_U24: case SNDRV_PCM_FORMAT_S24: bfs = 48; break; case SNDRV_PCM_FORMAT_U16_LE: case SNDRV_PCM_FORMAT_S16_LE: bfs = 32; break; default: return -EINVAL; } switch (params_rate(params)) { case 16000: case 22050: case 24000: case 32000: case 44100: case 48000: case 88200: case 96000: if (bfs == 48) rfs = 384; else rfs = 256; break; case 64000: rfs = 384; break; case 8000: case 11025: case 12000: if (bfs == 48) rfs = 768; else rfs = 512; break; default: return -EINVAL; } switch (rate){ case 8000: case 11025: case 12000: if(bclk_div == 48) rclk_div = 768; //0x300 else rclk_div = 512; //0x200 break; case 16000: case 22050: case 24000: case 32000: case 44100: //AC44 case 48000: case 88200: case 96000: if(bclk_div == 48) rclk_div = 384; //0x180 else rclk_div = 256; //0x100 break; case 64000: rclk_div = 384; //0x180 break; default: dprintk("-%s(): SND RATE ERROR\n", __FUNCTION__); return -EINVAL; } rclk = params_rate(params) * rfs; switch (rclk){ case 4096000: case 5644800: case 6144000: case 8467200: case 9216000: psr = 8; break; case 8192000: case 11289600: case 12288000: case 16934400: case 18432000: psr = 4; break; case 22579200: case 24576000: case 33868800: case 36864000: psr = 2; break; case 67737600: case 73728000: psr = 1; break; default: printk("Not yet supported!\n"); return -EINVAL; } set_epll_rate(rclk * psr); dprintk("[zsb] rclk = %ld, psr = %d, bfs = %d\n", rclk, psr, bfs); ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if(ret < 0) { dprintk("-%s(): Codec DAI configuration error, %d\n", __FUNCTION__, ret); return ret; } ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if( ret < 0 ) { dprintk("-%s(): AP DAI configuration error, %d\n", __FUNCTION__, ret); return ret; } ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, 0, SND_SOC_CLOCK_OUT); if(ret < 0) { dprintk("-%s(): AP sycclk CDCLK setting error, %d\n", __FUNCTION__, ret); return ret; } ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_SYSCLKDIV, WM8960_SYSCLK_DIV_1); if( ret < 0 ) { dprintk("-%s(): Codec SYSCLKDIV setting error, %d\n", __FUNCTION__, ret); return ret; } ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, WM8960_DAC_DIV_1); if(ret < 0) { dprintk("-%s(): Codec DACDIV setting error, %d\n", __FUNCTION__, ret); return ret; } mul = rate * rclk_div; ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DCLKDIV, mul); if( ret < 0 ) { dprintk( "-%s(): Codec DCLKDIV setting error, %d\n", __FUNCTION__, ret ); return ret; } ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs); if(ret < 0) { dprintk("-%s(): AP prescalar setting error, %d\n", __FUNCTION__, ret); return ret; } ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_PRESCALER, psr); if(ret < 0) { dprintk("-%s(): AP RFS setting error, %d\n", __FUNCTION__, ret); return ret; } dprintk("-%s()\n", __FUNCTION__); return 0; }
/* Switch the FLL */ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, MIDAS_DEFAULT_MCLK1, pll_out); if (ret < 0) dev_err(codec_dai->dev, "Unable to start FLL1: %d\n", ret); ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, pll_out, SND_SOC_CLOCK_IN); if (ret < 0) { dev_err(codec_dai->dev, "Unable to switch to FLL1: %d\n", ret); return ret; } ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_OPCLK, 0, MOD_OPCLK_PCLK); if (ret < 0) return ret; #else midas_start_fll1(codec_dai); #endif if (ret < 0) return ret; dev_info(codec_dai->dev, "%s --\n", __func__); return 0; } #else /* CONFIG_SND_SAMSUNG_I2S_MASTER */ static int midas_wm1811_aif1_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int bfs, psr, rfs, ret; unsigned long rclk; switch (params_format(params)) { case SNDRV_PCM_FORMAT_U24: case SNDRV_PCM_FORMAT_S24: bfs = 48; break; case SNDRV_PCM_FORMAT_U16_LE: case SNDRV_PCM_FORMAT_S16_LE: bfs = 32; break; default: return -EINVAL; } switch (params_rate(params)) { case 16000: case 22050: case 24000: case 32000: case 44100: case 48000: case 88200: case 96000: if (bfs == 48) rfs = 384; else rfs = 256; break; case 64000: rfs = 384; break; case 8000: case 11025: case 12000: if (bfs == 48) rfs = 768; else rfs = 512; break; default: return -EINVAL; } rclk = params_rate(params) * rfs; switch (rclk) { case 4096000: case 5644800: case 6144000: case 8467200: case 9216000: psr = 8; break; case 8192000: case 11289600: case 12288000: case 16934400: case 18432000: psr = 4; break; case 22579200: case 24576000: case 33868800: case 36864000: psr = 2; break; case 67737600: case 73728000: psr = 1; break; default: printk(KERN_INFO "Not yet supported!\n"); return -EINVAL; } set_epll_rate(rclk * psr); ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, rclk, SND_SOC_CLOCK_IN); if (ret < 0) return ret; ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, 0, SND_SOC_CLOCK_OUT); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs); if (ret < 0) return ret; return 0; }
static int smdk_wm8994_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned long mclk_freq; unsigned long epll_out_rate; int bfs, rfs, ret; bfs = (params_format(params) == SNDRV_PCM_FORMAT_S24_LE) ? 48 : 32; switch(params_rate(params)) { case 8000: epll_out_rate = 49152000; rfs = 512; break; case 44100: epll_out_rate = 67737600; rfs = 256; break; default: dev_err(cpu_dai->dev, "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } mclk_freq = params_rate(params) * rfs; /* Set the codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* Set the cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CONT | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* * Samsung SoCs PCM has no MCLK(rclk) output support, so codec * should have to make its own BCLK with FLL(or PLL) from other * clock source. */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, mclk_freq, SND_SOC_CLOCK_IN); if (ret < 0) return ret; ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_BCLK, mclk_freq, mclk_freq); if (ret < 0) return ret; /* Set EPLL clock rate */ ret = set_epll_rate(epll_out_rate); if (ret < 0) return ret; /* Set SCLK_DIV for making bclk */ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, bfs); if (ret < 0) return ret; return 0; }
static int mango210_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; unsigned int rclk, psr=1; int bfs, rfs, ret; unsigned long epll_out_rate; unsigned int value = 0; unsigned int bit_per_sample, sample_rate; switch (params_format(params)) { case SNDRV_PCM_FORMAT_U24: case SNDRV_PCM_FORMAT_S24: bfs = 48; bit_per_sample = 24; break; case SNDRV_PCM_FORMAT_U16_LE: case SNDRV_PCM_FORMAT_S16_LE: bfs = 32; bit_per_sample = 16; break; default: return -EINVAL; } /* For resample */ value = params_rate(params); if(value != 44100) { printk("%s: sample rate %d --> 44100\n", __func__, value); value = 44100; } sample_rate = value; /* The Fvco for WM8960 PLLs must fall within [90,100]MHz. * This criterion can't be met if we request PLL output * as {8000x256, 64000x256, 11025x256}Hz. * As a wayout, we rather change rfs to a minimum value that * results in (params_rate(params) * rfs), and itself, acceptable * to both - the CODEC and the CPU. */ switch (value) { case 16000: case 22050: case 24000: case 32000: case 44100: case 48000: case 88200: case 96000: if (bfs == 48) rfs = 384; else rfs = 256; break; case 64000: rfs = 384; break; case 8000: case 11025: case 12000: if (bfs == 48) rfs = 768; else rfs = 512; break; default: return -EINVAL; } rclk = value * rfs; switch (rclk) { case 4096000: case 5644800: case 6144000: case 8467200: case 9216000: psr = 8; break; case 8192000: case 11289600: case 12288000: case 16934400: case 18432000: psr = 4; break; case 22579200: case 24576000: case 33868800: case 36864000: psr = 2; break; case 67737600: case 73728000: psr = 1; break; default: printk("Not yet supported!\n"); return -EINVAL; } // printk("IIS Audio: %uBits Stereo %uHz\n", bit_per_sample, sample_rate); epll_out_rate = rclk * psr; /* Set EPLL clock rate */ ret = set_epll_rate(epll_out_rate); if (ret < 0) return ret; ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK, 0, SND_SOC_CLOCK_OUT); if (ret < 0) return ret; /* We use MUX for basic ops in SoC-Master mode */ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_MUX, 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_PRESCALER, psr-1); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs); if (ret < 0) return ret; return 0; }
static int mixtile_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; int bfs, rfs, ret, psr; unsigned long rclk; printa("into mixtile_hw_params\n"); #ifndef ASRC_M /* add by lin, not ASRC */ int sysclk = 256 * params_rate(params); #endif #ifdef ASRC_M /* add by lin, ASRC*/ int sysclk = 512 * params_rate(params); int freq_in = FREQ_IN; int freq_out = sysclk; #endif printa("check 1 sysclk = %d\n" , sysclk); switch (params_format(params)) { case SNDRV_PCM_FORMAT_U24: case SNDRV_PCM_FORMAT_S24: bfs = 48; break; case SNDRV_PCM_FORMAT_U16_LE: case SNDRV_PCM_FORMAT_S16_LE: bfs = 32; break; default: return -EINVAL; } printa("check 2 , bfs = %d\n",bfs); switch (params_rate(params)) { case 16000: case 22050: case 24000: case 32000: case 44100: case 48000: case 88200: case 96000: if (bfs == 48) rfs = 384; else rfs = 256; break; case 64000: rfs = 384; break; case 8000: case 11025: case 12000: if (bfs == 48) rfs = 768; else rfs = 512; break; default: return -EINVAL; } printa("check 3 , rfs = %d\n",rfs); rclk = params_rate(params) * rfs; printa("check 4 , rclk = %d\n",rclk); switch (rclk) { case 4096000: case 5644800: case 6144000: case 8467200: case 9216000: psr = 8; break; case 8192000: case 11289600: case 12288000: case 16934400: case 18432000: psr = 4; break; case 22579200: case 24576000: case 33868800: case 36864000: psr = 2; break; case 67737600: case 73728000: psr = 1; break; default: printk(KERN_ERR "Not yet supported!\n"); return -EINVAL; } printa("check , psr = %d\n",psr); set_epll_rate(rclk * psr); // set_mout_audss_rate(rclk * psr); /* Set the Codec DAI configuration */ //ÉèÖÃоƬģʽ I2S¡¢SLAVE_MODE ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); //by lin ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* ÉèÖÃCPU I2SÄ£¿é MASTER*/ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); //by lin ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* Ñ¡ÔñCPU I2SÄ£¿é ʱÖÓÔ´ I2S_CLK ¼Ä´æÆ÷ IISMOD[10] */ ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0/* SAMSUNG_I2S_RCLKSRC_1 */, 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; /* I2S CDCLK½ÅΪʱÖÓÊä³ö */ ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, 0/* rfs */, SND_SOC_CLOCK_OUT); //ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, rfs , SND_SOC_CLOCK_OUT); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs); if (ret < 0) return ret; #ifdef SEL_PLL /*set pll param*/ printa("PLL INPUT\n"); snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_MCLK, freq_in, freq_out); //end by lin //ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, RT5640_SCLK_S_PLL1); ret = snd_soc_dai_set_sysclk(codec_dai , RT5640_SCLK_S_PLL1 , sysclk, 0); if(ret < 0){ dev_err(codec_dai->dev,"codec_dai clock not set\n"); return ret; } #endif #ifdef SEL_MCLK printa("MCLK INPUT\n"); //ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, RT5640_SCLK_S_MCLK); ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK , sysclk, 0); if(ret < 0){ dev_err(codec_dai->dev,"codec_dai clock not set\n"); return ret; } #endif return 0; }
/* Note that PCM works __only__ in AP-Master mode */ static int smdk_socpcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; int rfs, ret; unsigned long epll_out_rate; switch (params_rate(params)) { case 8000: case 12000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: epll_out_rate = 49152000; break; case 11025: case 22050: case 44100: case 88200: epll_out_rate = 67738000; break; default: printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } switch (params_rate(params)) { case 16000: case 22050: case 22025: case 32000: case 44100: case 48000: case 96000: case 24000: rfs = 256; break; case 64000: rfs = 384; break; case 8000: case 11025: case 12000: rfs = 512; break; case 88200: rfs = 128; break; default: printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } /* Set the Codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* Set the AP DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* Set MUX for PCM clock source to audio-bus */ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX, 0, SND_SOC_CLOCK_OUT); if (ret < 0) return ret; /* Set EPLL clock rate */ ret = set_epll_rate(epll_out_rate); if (ret < 0) return ret; /* Set SCLK_DIV for making bclk */ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs); if (ret < 0) return ret; /* Set WM8580 to drive MCLK from PLLA */ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, WM8580_CLKSRC_PLLA); if (ret < 0) return ret; /* Explicitly set WM8580-DAC to source from MCLK */ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_DAC_CLKSEL, WM8580_CLKSRC_MCLK); if (ret < 0) return ret; /* Explicitly set WM8580-ADC to source from MCLK */ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_ADC_CLKSEL, WM8580_CLKSRC_ADCMCLK); if (ret < 0) return ret; ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0, SMDK_WM8580_XTI_FREQ, params_rate(params) * rfs); if (ret < 0) return ret; return 0; }
static int smdk_voice_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; int rfs, ret; unsigned long epll_out_rate; switch (params_rate(params)) { case 8000: case 12000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: epll_out_rate = 49152000; break; case 11025: case 22050: case 44100: case 88200: epll_out_rate = 67737600; break; default: printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } switch (params_rate(params)) { case 16000: case 22050: case 22025: case 32000: case 44100: case 48000: case 96000: case 24000: rfs = 256; break; case 64000: rfs = 384; break; case 8000: case 11025: case 12000: rfs = 512; break; case 88200: rfs = 128; break; default: printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } /* Set the codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, SMDK_WM8994_OSC_FREQ, SND_SOC_CLOCK_IN); if (ret < 0) return ret; ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, SMDK_WM8994_OSC_FREQ, params_rate(params)*256); if (ret < 0) return ret; /* Set the cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* Set EPLL clock rate */ ret = set_epll_rate(epll_out_rate); if (ret < 0) return ret; /* Set SCLK_DIV for making bclk */ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs); if (ret < 0) return ret; return 0; }
/* SMDK has a 16.9344MHZ crystal attached to WM8994 */ #define SMDK_WM8994_FREQ 16934400 #ifdef CONFIG_SND_SAMSUNG_PCM_USE_EPLL static int set_epll_rate(unsigned long rate) { struct clk *fout_epll; fout_epll = clk_get(NULL, "fout_epll"); if (IS_ERR(fout_epll)) { printk(KERN_ERR "%s: failed to get fout_epll\n", __func__); return PTR_ERR(fout_epll); } if (rate == clk_get_rate(fout_epll)) goto out; clk_set_rate(fout_epll, rate); out: clk_put(fout_epll); return 0; } #endif /* CONFIG_SND_SAMSUNG_PCM_USE_EPLL */ static int smdk_wm8994_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; #ifdef CONFIG_SND_SAMSUNG_PCM_USE_EPLL unsigned long epll_out_rate; #endif /* CONFIG_SND_SAMSUNG_PCM_USE_EPLL */ unsigned long mclk_freq; unsigned long bclk; int rfs, ret , bfs; switch(params_rate(params)) { case 8000: rfs = 512; break; case 44100: /*rfs = 192; clock 16934400/2 , to sync with WM8994-AIF1 clock */ rfs = 384; bfs = 32; break; default: dev_err(cpu_dai->dev, "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } mclk_freq = params_rate(params) * rfs; bclk = params_rate(params) * bfs; /* Set the codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* Set the cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_GATED); if (ret < 0) return ret; #ifndef CONFIG_SND_SAMSUNG_PCM_USE_EPLL ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, SMDK_WM8994_FREQ, mclk_freq); if (ret < 0) return ret; ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, mclk_freq, SND_SOC_CLOCK_IN); if (ret < 0) return ret; /* Set PCM source clock on CPU */ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX, bclk, SND_SOC_CLOCK_IN); if (ret < 0) return ret; #endif #ifdef CONFIG_SND_SAMSUNG_PCM_USE_EPLL switch (params_rate(params)) { case 8000: case 12000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: epll_out_rate = 49152000; break; case 11025: case 22050: case 44100: case 88200: epll_out_rate = 67737600; break; default: printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } /* AIF1CLK should be >=3MHz for optimal performance */ if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE) mclk_freq = params_rate(params) * 384; else if (params_rate(params) == 8000 || params_rate(params) == 11025) mclk_freq = params_rate(params) * 512; else mclk_freq = params_rate(params) * 256; ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, SMDK_WM8994_FREQ, mclk_freq); if (ret < 0) return ret; ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, mclk_freq, SND_SOC_CLOCK_IN); if (ret < 0) return ret; /* Set EPLL clock rate */ ret = set_epll_rate(epll_out_rate); if (ret < 0) return ret; /* Set PCM source clock on CPU */ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX, bclk, SND_SOC_CLOCK_IN); if (ret < 0) return ret; #endif /* CONFIG_SND_SAMSUNG_PCM_USE_EPLL */ /* Set SCLK_DIV for making bclk */ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, bfs); if (ret < 0) return ret; return 0; }
static int smdk64xx_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; unsigned int rclk, psr = 1; int bfs, rfs, ret; switch (params_format(params)) { case SNDRV_PCM_FORMAT_U24: case SNDRV_PCM_FORMAT_S24: bfs = 48; break; case SNDRV_PCM_FORMAT_U16_LE: case SNDRV_PCM_FORMAT_S16_LE: bfs = 32; break; default: return -EINVAL; } /* The Fvco for WM8580 PLLs must fall within [80]MHz. * This criterion can't be met if we request PLL output * as {8000x256, 64000x256, 11025x256}Hz. * As a wayout, we rather change rfs to a minimum value that * results in (params_rate(params) * rfs), and itself, acceptable * to both - the CODEC and the CPU. */ switch (params_rate(params)) { case 16000: case 22050: case 24000: case 32000: case 44100: case 48000: case 88200: case 96000: if (bfs == 48) rfs = 384; else rfs = 256; break; case 64000: rfs = 384; break; case 8000: case 11025: case 12000: if (bfs == 48) rfs = 768; else rfs = 512; break; default: return -EINVAL; } rclk = params_rate(params) * rfs; switch (rclk) { case 4096000: case 5644800: case 6144000: case 8467200: case 9216000: psr = 8; break; case 8192000: case 11289600: case 12288000: case 16934400: case 18432000: psr = 4; break; case 22579200: case 24576000: case 33868800: case 36864000: psr = 2; break; case 67737600: case 73728000: psr = 1; break; default: printk(KERN_ERR "Not yet supported!\n"); return -EINVAL; } set_epll_rate(rclk * psr); ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK, 0, SND_SOC_CLOCK_OUT); if (ret < 0) return ret; /* We use MUX for basic ops in SoC-Master mode */ ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_MUX, 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_PRESCALER, psr-1); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs); if (ret < 0) return ret; ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs); if (ret < 0) return ret; return 0; }
static int mx_wm8958_aif2_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; #ifdef CONFIG_SND_SAMSUNG_PCM_USE_EPLL unsigned long epll_out_rate; #endif /* CONFIG_SND_SAMSUNG_PCM_USE_EPLL */ int rfs, ret; printk("++%s format = %d rate = %d\n", __func__,params_format(params),(params_rate(params))); #ifdef CONFIG_SND_SAMSUNG_PCM_USE_EPLL switch (params_rate(params)) { case 8000: case 12000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: epll_out_rate = 49152000; break; case 11025: case 22050: case 44100: case 88200: epll_out_rate = 67737600; break; default: printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } #endif /* CONFIG_SND_SAMSUNG_PCM_USE_EPLL */ switch (params_rate(params)) { case 16000: case 22050: case 22025: case 32000: case 44100: case 48000: case 96000: case 24000: #ifdef CONFIG_SND_SAMSUNG_PCM_USE_EPLL rfs = 256; #else /* CONFIG_SND_SAMSUNG_PCM_USE_EPLL */ rfs = 384; #endif /* CONFIG_SND_SAMSUNG_PCM_USE_EPLL */ break; case 64000: rfs = 384; break; case 11025: case 12000: rfs = 512; break; case 8000: case 88200: rfs = 128; break; default: printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n", __func__, __LINE__, params_rate(params)); return -EINVAL; } /* Set the codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* Set the cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; #ifdef CONFIG_SND_SAMSUNG_PCM_USE_EPLL /* * Samsung SoCs PCM has no MCLK(rclk) output support, so codec * should have to make its own MCLK with FLL(or PLL) from other * clock source. */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, params_rate(params)*rfs, SND_SOC_CLOCK_IN); if (ret < 0) return ret; if (machine_is_m030()) { ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, WM8994_FLL_SRC_MCLK1, WM8994_FREQ_12000000, params_rate(params)*rfs); } else{ ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, WM8994_FLL_SRC_MCLK1, WM8994_FREQ_24000000, params_rate(params)*rfs); } if (ret < 0) return ret; #else ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2, params_rate(params)*rfs, SND_SOC_CLOCK_IN); if (ret < 0) return ret; #endif /* CONFIG_SND_SAMSUNG_PCM_USE_EPLL */ #ifdef CONFIG_SND_SAMSUNG_PCM_USE_EPLL /* Set EPLL clock rate */ ret = set_epll_rate(epll_out_rate); if (ret < 0) return ret; #endif /* CONFIG_SND_SAMSUNG_PCM_USE_EPLL */ /* Set SCLK_DIV for making bclk */ ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs); if (ret < 0) return ret; printk("--%s\n", __func__); return 0; }