Esempio n. 1
0
static int neo1973_hifi_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 pll_out = 0, bclk = 0;
	int ret = 0;
	unsigned long iis_clkrate;

	iis_clkrate = s3c24xx_i2s_get_clockrate();

	switch (params_rate(params)) {
	case 8000:
	case 16000:
		pll_out = 12288000;
		break;
	case 48000:
		bclk = WM8753_BCLK_DIV_4;
		pll_out = 12288000;
		break;
	case 96000:
		bclk = WM8753_BCLK_DIV_2;
		pll_out = 12288000;
		break;
	case 11025:
		bclk = WM8753_BCLK_DIV_16;
		pll_out = 11289600;
		break;
	case 22050:
		bclk = WM8753_BCLK_DIV_8;
		pll_out = 11289600;
		break;
	case 44100:
		bclk = WM8753_BCLK_DIV_4;
		pll_out = 11289600;
		break;
	case 88200:
		bclk = WM8753_BCLK_DIV_2;
		pll_out = 11289600;
		break;
	}

	/* set codec DAI configuration */
	ret = snd_soc_dai_set_fmt(codec_dai,
		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
		SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* set cpu DAI configuration */
	ret = snd_soc_dai_set_fmt(cpu_dai,
		SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
		SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* set the codec system clock for DAC and ADC */
	ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
		SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	/* set MCLK division for sample rate */
	ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
		S3C2410_IISMOD_32FS);
	if (ret < 0)
		return ret;

	/* set codec BCLK division for sample rate */
	ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk);
	if (ret < 0)
		return ret;

	/* set prescaler division for sample rate */
	ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
		S3C24XX_PRESCALE(4, 4));
	if (ret < 0)
		return ret;

	/* codec PLL input is PCLK/4 */
	ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
		iis_clkrate / 4, pll_out);
	if (ret < 0)
		return ret;

	return 0;
}
static int t0_wm1811_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 *codec_dai = rtd->codec_dai;
	int ret;
	int prate;
	int bclk;

	dev_info(codec_dai->dev, "%s ++\n", __func__);
	prate = params_rate(params);
	switch (params_rate(params)) {
	case 8000:
	case 16000:
	       break;
	default:
		dev_warn(codec_dai->dev, "Unsupported LRCLK %d, falling back to 8000Hz\n",
				(int)params_rate(params));
		prate = 8000;
	}

	/* Set the codec DAI configuration, aif2_mode:0 is slave */
#if defined(CONFIG_MACH_T0_CHN_CTC)
	if (aif2_mode == 0)
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A
					| SND_SOC_DAIFMT_IB_NF
					| SND_SOC_DAIFMT_CBS_CFS);
	else
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A
					| SND_SOC_DAIFMT_IB_NF
					| SND_SOC_DAIFMT_CBM_CFM);
#else
	if (aif2_mode == 0)
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
					| SND_SOC_DAIFMT_NB_NF
					| SND_SOC_DAIFMT_CBS_CFS);
	else
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
					| SND_SOC_DAIFMT_NB_NF
					| SND_SOC_DAIFMT_CBM_CFM);
#endif

	if (ret < 0)
		return ret;

	switch (prate) {
	case 8000:
		bclk = 256000;
		break;
	case 16000:
		bclk = 512000;
		break;
	default:
		return -EINVAL;
	}

#if defined(CONFIG_MACH_T0_CHN_CU_DUOS)
	if (modem_mode == 1)
		bclk = 2048000;
#endif

#if defined(CONFIG_MACH_T0_CHN_CTC)
		bclk = 2048000;
#endif

	if (aif2_mode == 0) {
		ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2,
					WM8994_FLL_SRC_BCLK,
					bclk, prate * 256);
	} else {
		ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2,
					  WM8994_FLL_SRC_MCLK1,
					  MIDAS_DEFAULT_MCLK1, prate * 256);
	}

	if (ret < 0)
		dev_err(codec_dai->dev, "Unable to configure FLL2: %d\n", ret);

	ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
				     prate * 256, SND_SOC_CLOCK_IN);
	if (ret < 0)
		dev_err(codec_dai->dev, "Unable to switch to FLL2: %d\n", ret);

	dev_info(codec_dai->dev, "%s --\n", __func__);
	return 0;
}
Esempio n. 3
0
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 *cpu_dai = rtd->cpu_dai;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	unsigned int pll_out;
	int ret;

	dev_info(codec_dai->dev, "%s ++\n", __func__);
	/* AIF1CLK should be >=3MHz for optimal performance */
	if (params_rate(params) == 8000 || params_rate(params) == 11025)
		pll_out = params_rate(params) * 512;
	else
		pll_out = params_rate(params) * 256;

	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
					| SND_SOC_DAIFMT_NB_NF
					| SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* Set the cpu DAI configuration */
	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
					| SND_SOC_DAIFMT_NB_NF
					| SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

#ifndef SND_USE_BIAS_LEVEL
	/* 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;

	midas_micd_set_rate(rtd->codec);
#else
	midas_start_fll1(codec_dai);
#endif

	if (ret < 0)
		return ret;

	dev_info(codec_dai->dev, "%s --\n", __func__);

	return 0;
}
Esempio n. 4
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;
}
Esempio n. 5
0
static int fsl_asoc_card_set_bias_level(struct snd_soc_card *card,
					struct snd_soc_dapm_context *dapm,
					enum snd_soc_bias_level level)
{
	struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
	struct snd_soc_pcm_runtime *rtd;
	struct snd_soc_dai *codec_dai;
	struct codec_priv *codec_priv = &priv->codec_priv;
	struct device *dev = card->dev;
	unsigned int pll_out;
	int ret;

	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
	codec_dai = rtd->codec_dai;
	if (dapm->dev != codec_dai->dev)
		return 0;

	switch (level) {
	case SND_SOC_BIAS_PREPARE:
		if (dapm->bias_level != SND_SOC_BIAS_STANDBY)
			break;

		if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE)
			pll_out = priv->sample_rate * 384;
		else
			pll_out = priv->sample_rate * 256;

		ret = snd_soc_dai_set_pll(codec_dai, codec_priv->pll_id,
					  codec_priv->mclk_id,
					  codec_priv->mclk_freq, pll_out);
		if (ret) {
			dev_err(dev, "failed to start FLL: %d\n", ret);
			return ret;
		}

		ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->fll_id,
					     pll_out, SND_SOC_CLOCK_IN);
		if (ret) {
			dev_err(dev, "failed to set SYSCLK: %d\n", ret);
			return ret;
		}
		break;

	case SND_SOC_BIAS_STANDBY:
		if (dapm->bias_level != SND_SOC_BIAS_PREPARE)
			break;

		ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id,
					     codec_priv->mclk_freq,
					     SND_SOC_CLOCK_IN);
		if (ret) {
			dev_err(dev, "failed to switch away from FLL: %d\n", ret);
			return ret;
		}

		ret = snd_soc_dai_set_pll(codec_dai, codec_priv->pll_id, 0, 0, 0);
		if (ret) {
			dev_err(dev, "failed to stop FLL: %d\n", ret);
			return ret;
		}
		break;

	default:
		break;
	}

	return 0;
}
static int tegra_aic326x_voice_call_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_codec *codec = rtd->codec;
	struct snd_soc_card *card = codec->card;
	struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
	struct tegra_asoc_platform_data *pdata = machine->pdata;
	int srate, mclk, rate, i2s_daifmt;
	int err, pcmdiv, vxclkdiv;

	srate = params_rate(params);
	mclk = tegra_aic326x_get_mclk(srate);
	if (mclk < 0)
		return mclk;

	i2s_daifmt = SND_SOC_DAIFMT_NB_NF;

	i2s_daifmt |= pdata->i2s_param[VOICE_CODEC].is_i2s_master ?
		SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;

	switch (pdata->i2s_param[VOICE_CODEC].i2s_mode) {
	case TEGRA_DAIFMT_I2S:
		i2s_daifmt |= SND_SOC_DAIFMT_I2S;
		break;
	case TEGRA_DAIFMT_DSP_A:
		i2s_daifmt |= SND_SOC_DAIFMT_DSP_A;
		break;
	case TEGRA_DAIFMT_DSP_B:
		i2s_daifmt |= SND_SOC_DAIFMT_DSP_B;
		break;
	case TEGRA_DAIFMT_LEFT_J:
		i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J;
		break;
	case TEGRA_DAIFMT_RIGHT_J:
		i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J;
		break;
	default:
		dev_err(card->dev,
		"Can't configure i2s format\n");
		return -EINVAL;
	}

	err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
	if (err < 0) {
		if (!(machine->util_data.set_mclk % mclk))
			mclk = machine->util_data.set_mclk;
		else {
			dev_err(card->dev, "Can't configure clocks\n");
			return err;
		}
	}

	tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);

	rate = clk_get_rate(machine->util_data.clk_cdev1);

	err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt);
	if (err < 0) {
		dev_err(card->dev, "codec_dai fmt not set\n");
		return err;
	}


	err = snd_soc_dai_set_pll(codec_dai, 0, AIC3262_PLL_CLKIN_MCLK1 , rate,
			params_rate(params));

	if (err < 0) {
		dev_err(card->dev, "codec_dai PLL clock not set\n");
		return err;
	}

	if (!machine_is_tegra_enterprise()) {
		if (params_rate(params) == 8000) {
			/* Change these Settings for 8KHz*/
			pcmdiv = 1;
			/* BB expecting 2048Khz bclk */
			vxclkdiv = 27;
		} else if (params_rate(params) == 16000) {
			pcmdiv = 1;
			/* BB expecting 2048Khz bclk */
			vxclkdiv = 27;
		} else {
			dev_err(card->dev, "codec_dai unsupported voice rate\n");
			return -EINVAL;
		}
	}

	//snd_soc_dai_set_clkdiv(codec_dai, ASI2_BCLK_N, vxclkdiv);
	//snd_soc_dai_set_clkdiv(codec_dai, ASI2_WCLK_N, pcmdiv);

#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	/* codec configuration */
	machine->codec_info[VOICE_CODEC].rate = params_rate(params);
	machine->codec_info[VOICE_CODEC].channels = params_channels(params);
#endif

	machine->is_device_bt = 0;

	return 0;
}
Esempio n. 7
0
static int zylonite_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 *codec_dai = rtd->codec_dai;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	unsigned int pll_out = 0;
	unsigned int wm9713_div = 0;
	int ret = 0;
	int rate = params_rate(params);
	int width = snd_pcm_format_physical_width(params_format(params));

	/* Only support ratios that we can generate neatly from the AC97
	 * based master clock - in particular, this excludes 44.1kHz.
	 * In most applications the voice DAC will be used for telephony
	 * data so multiples of 8kHz will be the common case.
	 */
	switch (rate) {
	case 8000:
		wm9713_div = 12;
		break;
	case 16000:
		wm9713_div = 6;
		break;
	case 48000:
		wm9713_div = 2;
		break;
	default:
		/* Don't support OSS emulation */
		return -EINVAL;
	}

	/* Add 1 to the width for the leading clock cycle */
	pll_out = rate * (width + 1) * 8;

	ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, pll_out);
	if (ret < 0)
		return ret;

	if (clk_pout)
		ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV,
					     WM9713_PCMDIV(wm9713_div));
	else
		ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
					     WM9713_PCMDIV(wm9713_div));
	if (ret < 0)
		return ret;

	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;

	return 0;
}
Esempio n. 8
0
static int playpaq_wm8510_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->dai->codec_dai;
	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
	struct at32_ssc_info *ssc_p = cpu_dai->private_data;
	struct ssc_device *ssc = ssc_p->ssc;
	unsigned int pll_out = 0, bclk = 0, mclk_div = 0;
	int ret;


	/* Due to difficulties with getting the correct clocks from the AT32's
	 * PLL0, we're going to let the CODEC be in charge of all the clocks
	 */
#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
	const unsigned int fmt = (SND_SOC_DAIFMT_I2S |
				  SND_SOC_DAIFMT_NB_NF |
				  SND_SOC_DAIFMT_CBM_CFM);
#else
	struct ssc_clock_data cd;
	const unsigned int fmt = (SND_SOC_DAIFMT_I2S |
				  SND_SOC_DAIFMT_NB_NF |
				  SND_SOC_DAIFMT_CBS_CFS);
#endif

	if (ssc == NULL) {
		pr_warning("playpaq_wm8510_hw_params: ssc is NULL!\n");
		return -EINVAL;
	}


	/*
	 * Figure out PLL and BCLK dividers for WM8510
	 */
	switch (params_rate(params)) {
	case 48000:
		pll_out = 12288000;
		mclk_div = WM8510_MCLKDIV_1;
		bclk = WM8510_BCLKDIV_8;
		break;

	case 44100:
		pll_out = 11289600;
		mclk_div = WM8510_MCLKDIV_1;
		bclk = WM8510_BCLKDIV_8;
		break;

	case 22050:
		pll_out = 11289600;
		mclk_div = WM8510_MCLKDIV_2;
		bclk = WM8510_BCLKDIV_8;
		break;

	case 16000:
		pll_out = 12288000;
		mclk_div = WM8510_MCLKDIV_3;
		bclk = WM8510_BCLKDIV_8;
		break;

	case 11025:
		pll_out = 11289600;
		mclk_div = WM8510_MCLKDIV_4;
		bclk = WM8510_BCLKDIV_8;
		break;

	case 8000:
		pll_out = 12288000;
		mclk_div = WM8510_MCLKDIV_6;
		bclk = WM8510_BCLKDIV_8;
		break;

	default:
		pr_warning("playpaq_wm8510: Unsupported sample rate %d\n",
			   params_rate(params));
		return -EINVAL;
	}


	/*
	 * set CPU and CODEC DAI configuration
	 */
	ret = snd_soc_dai_set_fmt(codec_dai, fmt);
	if (ret < 0) {
		pr_warning("playpaq_wm8510: "
			   "Failed to set CODEC DAI format (%d)\n",
			   ret);
		return ret;
	}
	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
	if (ret < 0) {
		pr_warning("playpaq_wm8510: "
			   "Failed to set CPU DAI format (%d)\n",
			   ret);
		return ret;
	}


	/*
	 * Set CPU clock configuration
	 */
#if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
	cd = playpaq_wm8510_calc_ssc_clock(params, cpu_dai);
	pr_debug("playpaq_wm8510: cmr_div = %d, period = %d\n",
		 cd.cmr_div, cd.period);
	ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_CMR_DIV, cd.cmr_div);
	if (ret < 0) {
		pr_warning("playpaq_wm8510: Failed to set CPU CMR_DIV (%d)\n",
			   ret);
		return ret;
	}
	ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_TCMR_PERIOD,
					  cd.period);
	if (ret < 0) {
		pr_warning("playpaq_wm8510: "
			   "Failed to set CPU transmit period (%d)\n",
			   ret);
		return ret;
	}
#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */


	/*
	 * Set CODEC clock configuration
	 */
	pr_debug("playpaq_wm8510: "
		 "pll_in = %ld, pll_out = %u, bclk = %x, mclk = %x\n",
		 clk_get_rate(CODEC_CLK), pll_out, bclk, mclk_div);


#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE
	ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_BCLKDIV, bclk);
	if (ret < 0) {
		pr_warning
		    ("playpaq_wm8510: Failed to set CODEC DAI BCLKDIV (%d)\n",
		     ret);
		return ret;
	}
#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */


	ret = snd_soc_dai_set_pll(codec_dai, 0,
					 clk_get_rate(CODEC_CLK), pll_out);
	if (ret < 0) {
		pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n",
			   ret);
		return ret;
	}


	ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_MCLKDIV, mclk_div);
	if (ret < 0) {
		pr_warning("playpaq_wm8510: Failed to set CODEC MCLKDIV (%d)\n",
			   ret);
		return ret;
	}


	return 0;
}
Esempio n. 9
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;
}
Esempio n. 10
0
static int rk29_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 pll_out = 0; 
	unsigned int lrclk = 0;
	int ret;
	  
	DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);    

	/*by Vincent Hsiung for EQ Vol Change*/
	#define HW_PARAMS_FLAG_EQVOL_ON 0x21
	#define HW_PARAMS_FLAG_EQVOL_OFF 0x22
	if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF))
	{
		ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); //by Vincent
		DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
	} else {
		/* set codec DAI configuration */
#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) 
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 
#endif
#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) 
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM ); 
#endif
		if (ret < 0)
			return ret; 
		/* set cpu DAI configuration */
#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) 
		ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
#endif
#if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) 
		ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);	
#endif
		if (ret < 0)
			return ret;
	}

	switch(params_rate(params)) {
	case 8000:
	case 16000:
	case 24000:
	case 32000:
	case 48000:
		pll_out = 12288000;
		break;
	case 11025:
	case 22050:
	case 44100:
		pll_out = 11289600;
		break;
	default:
		DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
		return -EINVAL;
		break;
	}
	DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));

#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
#if 0	//use pll from blck
	/*Set the pll of rt5621,the Pll source from BITCLK on CPU is master mode*/
	//bitclk is 64fs           
	ret=snd_soc_dai_set_pll(codec_dai,RT5621_PLL_FR_BCLK,params_rate(params)*64,pll_out);
	if (ret < 0) { 
		DBG("rk29_hw_params_rt5621:failed to set the pll for codec side\n"); 
		return ret;
	}
#endif	    
	/*Set the system clk for codec*/
	ret=snd_soc_dai_set_sysclk(codec_dai, 0,pll_out,SND_SOC_CLOCK_IN);
	if (ret < 0) {
		DBG("rk29_hw_params_rt5621:failed to set the sysclk for codec side\n"); 
		return ret;
	}	    
#endif
  
/*
  #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) 

	if((24576000%params_rate(params))==0)	//for 8k,16k,32k,48k
	{
		snd_soc_dai_set_pll(codec_dai,RT5621_PLL_FR_MCLK,pll_out, 24576000);
		snd_soc_dai_set_sysclk(codec_dai,0, 24576000, SND_SOC_CLOCK_IN);			
	}
	else if((22579200%params_rate(params))==0)	//for 11k,22k,44k
	{
		snd_soc_dai_set_pll(codec_dai,RT5621_PLL_FR_MCLK,pll_out, 22579200);
		snd_soc_dai_set_sysclk(codec_dai,0, 22579200, SND_SOC_CLOCK_IN);			
	}
      
#endif
*/

#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
	snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
	snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1);
	snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3);
#endif

	DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params));
        
	return 0;
}
Esempio n. 11
0
static int smdk_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;
	unsigned int pll_out;
	int bfs, rfs, ret;

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_U8:
	case SNDRV_PCM_FORMAT_S8:
		bfs = 16;
		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 [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 (params_rate(params)) {
	case 16000:
	case 22050:
	case 32000:
	case 44100:
	case 48000:
	case 88200:
	case 96000:
		rfs = 256;
		break;
	case 64000:
		rfs = 384;
		break;
	case 8000:
	case 11025:
		rfs = 512;
		break;
	default:
		return -EINVAL;
	}
	pll_out = params_rate(params) * rfs;

	/* Set the Codec DAI configuration */
	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
					 | SND_SOC_DAIFMT_NB_NF
					 | SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* Set the AP DAI configuration */
	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
					 | SND_SOC_DAIFMT_NB_NF
					 | SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* Set WM8580 to drive MCLK from its PLLA */
	ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
					WM8580_CLKSRC_PLLA);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
					SMDK_WM8580_FREQ, pll_out);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA,
				     pll_out, SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	return 0;
}
Esempio n. 12
0
static int smdk_wm8580_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;
	int rfs, ret;

	switch (params_rate(params)) {
	case 8000:
		break;
	default:
		printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n",
		__func__, __LINE__, params_rate(params));
		return -EINVAL;
	}

	rfs = mclk_freq / params_rate(params) / 2;

	/* 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);
	if (ret < 0)
		return ret;

	if (mclk_freq == xtal_freq) {
		ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK,
						mclk_freq, SND_SOC_CLOCK_IN);
		if (ret < 0)
			return ret;

		ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
						WM8580_CLKSRC_MCLK);
		if (ret < 0)
			return ret;
	} else {
		ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA,
						mclk_freq, SND_SOC_CLOCK_IN);
		if (ret < 0)
			return ret;

		ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
						WM8580_CLKSRC_PLLA);
		if (ret < 0)
			return ret;

		ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
						xtal_freq, mclk_freq);
		if (ret < 0)
			return ret;
	}

	/* Set PCM source clock on CPU */
	ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX,
					mclk_freq, SND_SOC_CLOCK_IN);
	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;
}
Esempio n. 13
0
static int raumfeld_cs4270_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 fmt, clk = 0;
	int ret = 0;

	switch (params_rate(params)) {
	case 44100:
		set_max9485_clk(MAX9485_MCLK_FREQ_112896);
		clk = 11289600;
		break;
	case 48000:
		set_max9485_clk(MAX9485_MCLK_FREQ_122880);
		clk = 12288000;
		break;
	case 88200:
		set_max9485_clk(MAX9485_MCLK_FREQ_225792);
		clk = 22579200;
		break;
	case 96000:
		set_max9485_clk(MAX9485_MCLK_FREQ_245760);
		clk = 24576000;
		break;
	default:
		return -EINVAL;
	}

	fmt = SND_SOC_DAIFMT_I2S |
	      SND_SOC_DAIFMT_NB_NF |
	      SND_SOC_DAIFMT_CBS_CFS;

	/* setup the CODEC DAI */
	ret = snd_soc_dai_set_fmt(codec_dai, fmt);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 0);
	if (ret < 0)
		return ret;

	/* setup the CPU DAI */
	ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
	if (ret < 0)
		return ret;

	return 0;
}
Esempio n. 14
0
static int most2120_codec_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->dai->codec_dai;
    struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
    unsigned int pll_out = 0, ddiv = 0, adiv = 0, bdiv;
    int ret = 0;
    int iis_clk;
#if MOST2120_WM8960_DEBUG
    int i;
#endif

    DBGOUT("Entered %s\n", __func__);

    iis_clk = cpu_get_clock_hz(1); /* Get PLL1 freq */
    
    //printk("iis_clk = %d params_rate = %d\n", iis_clk, params_rate(params));
    switch (params_rate(params)) {
      case 8000:
        ddiv = WM8960_DAC_DIV_6;
        adiv = WM8960_ADC_DIV_6;
        bdiv = WM8960_BCLK_DIV_24;
        pll_out = 12288000;
        break;
      case 16000:
        ddiv = WM8960_DAC_DIV_3;
        adiv = WM8960_ADC_DIV_3;
        bdiv = WM8960_BCLK_DIV_12;
        pll_out = 12288000;
        break;
      case 32000:
        ddiv = WM8960_DAC_DIV_1_5;
        adiv = WM8960_ADC_DIV_1_5;
        bdiv = WM8960_BCLK_DIV_6;
        pll_out = 12288000;
        break;
      case 48000:
        ddiv = WM8960_DAC_DIV_1;
        adiv = WM8960_ADC_DIV_1;
        bdiv = WM8960_BCLK_DIV_4;
        pll_out = 12288000;
        break;
      case 11025:
        ddiv = WM8960_DAC_DIV_4;
        adiv = WM8960_ADC_DIV_4;
        bdiv = WM8960_BCLK_DIV_16;
        pll_out = 11289600;
        break;
      case 22050:
        ddiv = WM8960_DAC_DIV_2;
        adiv = WM8960_ADC_DIV_2;
        bdiv = WM8960_BCLK_DIV_8;
        pll_out = 11289600;
        break;
      case 44100:
        ddiv = WM8960_DAC_DIV_1;
        adiv = WM8960_ADC_DIV_1;
        bdiv = WM8960_BCLK_DIV_4;
        pll_out = 11289600;
        break;
      default :
        ddiv = WM8960_DAC_DIV_1;
        adiv = WM8960_ADC_DIV_1;
        bdiv = WM8960_BCLK_DIV_4;
        pll_out = 11289600;
    }

    /* NEXELL's nxp2120 has limited clock generation function, so it would be better
       Nxp2120 only generate reference clock from PLL1, 192MHz / 16 = 12 MHz...
       And then let WM8960 generate required clock for itself. */

    /* set codec DAI configuration */
    ret = snd_soc_dai_set_fmt(codec_dai,
        SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
        SND_SOC_DAIFMT_CBM_CFM); /* Set master mode for generate bitclk and fs(lrclk) */
    if (ret < 0)
        return ret;

    /* set cpu DAI configuration */
    ret = snd_soc_dai_set_fmt(cpu_dai,
        SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
        SND_SOC_DAIFMT_CBS_CFS); /* Set slave mode for bitclk, and fs(lrclk) */
    if (ret < 0)
        return ret;

    /* set CPU generate reference clock for Codec's PLL. So Set PLL1 as clock source.  */
    ret = snd_soc_dai_set_sysclk(cpu_dai, NX_I2S_CLKSRC_0, NX_I2S_CLKSRC0_PLL1, SND_SOC_CLOCK_OUT);
    if (ret < 0)
        return ret;
    
    /* Our I2S is Slave, So Set to EXT_BIT.  */
    ret = snd_soc_dai_set_sysclk(cpu_dai, NX_I2S_CLKSRC_1, NX_I2S_CLKSRC1_EXT_BIT, SND_SOC_CLOCK_IN);
    if (ret < 0)
        return ret;
    
    /* Set prescaler set to 16 to generate 12MHz around clock */
    ret = snd_soc_dai_set_clkdiv(cpu_dai, NX_I2S_CLKDIV_0, 16 - 1); /* PLL1 192MHz -> 12MHz with 1/16 */
    if (ret < 0)
        return ret;
    
    /* Use Bitclk as Clock Source and no division. */
    ret = snd_soc_dai_set_clkdiv(cpu_dai, NX_I2S_CLKDIV_1, 1 - 1); /* No div as BITCLK */
    if (ret < 0)
        return ret;

    /* Set fs as 64fs(256fs). */
    ret = snd_soc_dai_set_clkdiv(cpu_dai, NX_I2S_CLKDIV_SYNC_PERIOD, NX_I2S_PERDIV_64);
    if (ret < 0)
        return ret;
   
    /* set codec sysclock from PLL source */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_SYSCLKSEL, WM8960_SYSCLK_PLL);
    if (ret < 0)
        return ret;

    /* Now All the bit rate and rootclock should be set. */
    /* set codec sysclock from PLL source */
    ret = snd_soc_dai_set_pll(codec_dai, 0, 0, iis_clk / 16, pll_out);
    if (ret < 0)
        return ret;
   
    /* set codec speaker DCLK for SYSCLK/2. -> SYSCLK/16 */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DCLKDIV, WM8960_DCLK_DIV_16);
    if (ret < 0)
        return ret;

    /* set codec DAC div factor to ddiv. */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, ddiv);
    if (ret < 0)
        return ret;
    
    /* set codec ADC div factor to adiv. */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_ADCDIV, adiv);
    if (ret < 0)
        return ret;
    
    /* Bit Clock should be devided for NEXELL 256fs machine  */
    ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_BCLKDIV, bdiv);
    if (ret < 0)
        return ret;

    
#if MOST2120_WM8960_DEBUG
    for (i=0; i<56;i++) {
        printk("codec addr = 0x%x(%d) val= %x\n", i, i, snd_soc_read(codec_dai->codec, i));
    }
#endif
	return 0;
}
Esempio n. 15
0
static int midas_set_bias_level_post(struct snd_soc_card *card,
				     struct snd_soc_dapm_context *dapm,
				     enum snd_soc_bias_level level)
{
	struct snd_soc_codec *codec = card->rtd->codec;
	struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
	struct snd_soc_dai *aif2_dai = card->rtd[1].codec_dai;
	int ret;

	if (dapm->dev != aif1_dai->dev)
		return 0;

	switch (level) {
	case SND_SOC_BIAS_STANDBY:

		/* When going idle stop FLL1 and revert to using MCLK2
		 * directly for minimum power consumptin for accessory
		 * detection.
		 */
		if (card->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
			dev_info(aif1_dai->dev, "Moving to STANDBY\n");

			ret = snd_soc_dai_set_sysclk(aif2_dai,
						     WM8994_SYSCLK_MCLK2,
						     MIDAS_DEFAULT_MCLK2,
						     SND_SOC_CLOCK_IN);
			if (ret < 0)
				dev_err(codec->dev, "Failed to switch to MCLK2\n");

			ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
						  0, 0, 0);

			if (ret < 0)
				dev_err(codec->dev,
					"Failed to change FLL2\n");

			ret = snd_soc_dai_set_sysclk(aif1_dai,
						     WM8994_SYSCLK_MCLK2,
						     MIDAS_DEFAULT_MCLK2,
						     SND_SOC_CLOCK_IN);
			if (ret < 0)
				dev_err(codec->dev,
					"Failed to switch to MCLK2\n");

			ret = snd_soc_dai_set_pll(aif1_dai, WM8994_FLL1,
						  0, 0, 0);
			if (ret < 0)
				dev_err(codec->dev,
					"Failed to stop FLL1\n");


			midas_fll1_active = false;
			midas_snd_set_mclk(false, false);
		}

		break;
	default:
		break;
	}

	card->dapm.bias_level = level;

	return 0;
}
Esempio n. 16
0
static int mx_wm8958_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;

	unsigned long rclk;
	int bfs, rfs, ret;

	printk("++%s format = %d rate = %d\n", __func__,params_format(params),(params_rate(params)));

	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;

	/* Set the codec DAI configuration */
	ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
				| SND_SOC_DAIFMT_NB_NF
				| SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	/* Set the cpu DAI configuration */
	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
				| SND_SOC_DAIFMT_NB_NF
				| SND_SOC_DAIFMT_CBM_CFM);
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, rclk,
					SND_SOC_CLOCK_IN);
	if (ret < 0)
		return ret;

	if (machine_is_m030()) {
		ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
						WM8994_FREQ_12000000, rclk);
		if (ret < 0)
			return ret;
	} else {
		ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
						WM8994_FREQ_24000000, rclk);
		if (ret < 0)
			return ret;
	}

	ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_OPCLK,
					rclk, MOD_OPCLK_PCLK);//select audio bus clock
	if (ret < 0)
		return ret;

	ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,//SAMSUNG_I2S_RCLKSRC_0 = Using BUSCLK,SAMSUNG_I2S_RCLKSRC_1 = Using I2SCLK
					rclk, 0);
	if (ret < 0)
		return ret;
	
	ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,//RCLK supply to codec, set RFS
					rfs, SND_SOC_CLOCK_OUT);
	if (ret < 0)
		return ret;
	
	ret = snd_soc_dai_set_clkdiv(cpu_dai, SAMSUNG_I2S_DIV_BCLK, bfs);//set BFS
	if (ret < 0)
		return ret;

	printk("--%s\n", __func__);

	return 0;
}
Esempio n. 17
0
static int midas_wm1811_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_codec *codec = rtd->codec;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	int ret;
	int prate;
	int bclk;

	dev_info(codec_dai->dev, "%s ++\n", __func__);
	prate = params_rate(params);
	switch (params_rate(params)) {
	case 8000:
	case 16000:
	       break;
	default:
		dev_warn(codec_dai->dev, "Unsupported LRCLK %d, falling back to 8000Hz\n",
				(int)params_rate(params));
		prate = 8000;
	}

#if defined(CONFIG_LTE_MODEM_CMC221) || defined(CONFIG_MACH_M0_CTC)
#if defined(CONFIG_MACH_C1_KOR_LGT) || defined(CONFIG_MACH_BAFFIN_KOR_LGT)
	/* Set the codec DAI configuration */
	if (aif2_mode == 0) {
		if (kpcs_mode == 1)
			ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
				| SND_SOC_DAIFMT_NB_NF
				| SND_SOC_DAIFMT_CBS_CFS);
		else
			ret = snd_soc_dai_set_fmt(codec_dai,
				SND_SOC_DAIFMT_DSP_A
				| SND_SOC_DAIFMT_IB_NF
				| SND_SOC_DAIFMT_CBS_CFS);
	} else
#if defined(CONFIG_MACH_C1_KOR_LGT)
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A
				| SND_SOC_DAIFMT_IB_NF
				| SND_SOC_DAIFMT_CBM_CFM);
#else
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
				| SND_SOC_DAIFMT_NB_NF
				| SND_SOC_DAIFMT_CBM_CFM);
#endif
#else
	if (aif2_mode == 0)
		/* 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);
	else
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A
				| SND_SOC_DAIFMT_IB_NF
				| SND_SOC_DAIFMT_CBM_CFM);
#endif
#else
	/* Set the codec DAI configuration, aif2_mode:0 is slave */
	if (aif2_mode == 0)
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
					| SND_SOC_DAIFMT_NB_NF
					| SND_SOC_DAIFMT_CBS_CFS);
	else
		ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
					| SND_SOC_DAIFMT_NB_NF
					| SND_SOC_DAIFMT_CBM_CFM);
#endif

	if (ret < 0)
		return ret;

#if defined(CONFIG_LTE_MODEM_CMC221)
	if (kpcs_mode == 1) {
		switch (prate) {
		case 8000:
			bclk = 256000;
			break;
		case 16000:
			bclk = 512000;
			break;
		default:
			return -EINVAL;
		}
	} else {
	bclk = 2048000;
	}
#elif defined(CONFIG_MACH_M0_CTC)
	bclk = 2048000;
#else
	switch (prate) {
	case 8000:
		bclk = 256000;
		break;
	case 16000:
		bclk = 512000;
		break;
	default:
		return -EINVAL;
	}
#endif

#ifdef SND_USE_BIAS_LEVEL
	if (!midas_fll1_active)
		midas_start_fll1(midas_aif1_dai);
#endif

	if (aif2_mode == 0) {
		ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2,
					WM8994_FLL_SRC_BCLK,
					bclk, prate * 256);
	} else {
		ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2,
					  WM8994_FLL_SRC_MCLK1,
					  MIDAS_DEFAULT_MCLK1, prate * 256);
	}

	if (ret < 0)
		dev_err(codec_dai->dev, "Unable to configure FLL2: %d\n", ret);

	ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
				     prate * 256, SND_SOC_CLOCK_IN);
	if (ret < 0)
		dev_err(codec_dai->dev, "Unable to switch to FLL2: %d\n", ret);

	if (!(snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2)
		& WM8994_FLL2_LOCK_STS)) {
		dev_info(codec_dai->dev, "%s: use mclk1 for FLL2\n", __func__);
		ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2,
			WM8994_FLL_SRC_MCLK1,
			MIDAS_DEFAULT_MCLK1, prate * 256);
	}

	dev_info(codec_dai->dev, "%s --\n", __func__);
	return 0;
}
static int tegra_aic326x_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;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_card *card = codec->card;
	struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
	struct tegra_asoc_platform_data *pdata = machine->pdata;
	int srate, mclk, sample_size, i2s_daifmt;
	int err, rate;

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		sample_size = 16;
		break;
	default:
		return -EINVAL;
	}

	srate = params_rate(params);

	mclk = tegra_aic326x_get_mclk(srate);
	if (mclk < 0)
		return mclk;

	i2s_daifmt = SND_SOC_DAIFMT_NB_NF;
	i2s_daifmt |= pdata->i2s_param[HIFI_CODEC].is_i2s_master ?
			SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;

	switch (pdata->i2s_param[HIFI_CODEC].i2s_mode) {
		case TEGRA_DAIFMT_I2S :
			i2s_daifmt |= SND_SOC_DAIFMT_I2S;
			break;
		case TEGRA_DAIFMT_DSP_A :
			i2s_daifmt |= SND_SOC_DAIFMT_DSP_A;
			break;
		case TEGRA_DAIFMT_DSP_B :
			i2s_daifmt |= SND_SOC_DAIFMT_DSP_B;
			break;
		case TEGRA_DAIFMT_LEFT_J :
			i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J;
			break;
		case TEGRA_DAIFMT_RIGHT_J :
			i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J;
			break;
		default :
			dev_err(card->dev, "Can't configure i2s format\n");
			return -EINVAL;
	}

	err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
	if (err < 0) {
		if (!(machine->util_data.set_mclk % mclk))
			mclk = machine->util_data.set_mclk;
		else {
			dev_err(card->dev, "Can't configure clocks\n");
			return err;
		}
	}

	tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);

	rate = clk_get_rate(machine->util_data.clk_cdev1);

	err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt);
	if (err < 0) {
		dev_err(card->dev, "codec_dai fmt not set\n");
		return err;
	}

	err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt);
	if (err < 0) {
		dev_err(card->dev, "cpu_dai fmt not set\n");
		return err;
	}

	err = snd_soc_dai_set_pll(codec_dai, 0, AIC3262_PLL_CLKIN_MCLK1 , rate,
		params_rate(params));

#ifdef CONFIG_ARCH_TEGRA_2x_SOC
	err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC1,
					TEGRA20_DAS_DAP_ID_1);
	if (err < 0) {
		dev_err(card->dev, "failed to set dap-dac path\n");
		return err;
	}

	err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1,
					TEGRA20_DAS_DAP_SEL_DAC1);
	if (err < 0) {
		dev_err(card->dev, "failed to set dac-dap path\n");
		return err;
	}
#endif
	return 0;
}