Example #1
0
static int byt_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;
	int ret;

	snd_soc_dai_set_bclk_ratio(codec_dai, 50);

	ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
				     params_rate(params) * 512,
				     SND_SOC_CLOCK_IN);
	if (ret < 0) {
		dev_err(rtd->dev, "can't set codec clock %d\n", ret);
		return ret;
	}

	ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1,
				  params_rate(params) * 50,
				  params_rate(params) * 512);
	if (ret < 0) {
		dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
		return ret;
	}

	return 0;
}
static int snd_rpi_hifiberry_dacplus_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;
	return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
}
Example #3
0
static int snd_rpi_proto_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;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	int sysclk = 12288000; /* This is fixed on this board */

	/* Set proto bclk */
	int ret = snd_soc_dai_set_bclk_ratio(cpu_dai,32*2);
	if (ret < 0){
		dev_err(codec->dev,
				"Failed to set BCLK ratio %d\n", ret);
		return ret;
	}

	/* Set proto sysclk */
	ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
			sysclk, SND_SOC_CLOCK_IN);
	if (ret < 0) {
		dev_err(codec->dev,
				"Failed to set WM8731 SYSCLK: %d\n", ret);
		return ret;
	}

	return 0;
}
static int snd_rpi_hifiberry_digi_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_dai *cpu_dai = rtd->cpu_dai;
	
	int sysclk = 27000000; /* This is fixed on this board */

	long mclk_freq=0;
	int mclk_div=1;
	
	int ret;

	samplerate = params_rate(params);

	switch (samplerate) {
		case 44100:	
		case 48000:
		case 88200:
		case 96000:
			mclk_freq=samplerate*256;
			mclk_div=WM8804_MCLKDIV_256FS;
			break;
		case 176400:
		case 192000:
			mclk_freq=samplerate*128;
			mclk_div=WM8804_MCLKDIV_128FS;
			break;
		default:
			dev_err(substream->pcm->dev, 
			"Failed to set WM8804 SYSCLK, unsupported samplerate\n");
	}

	snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div);
	snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq);

	ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL,
					sysclk, SND_SOC_CLOCK_OUT);
	if (ret < 0) {
		dev_err(substream->pcm->dev,
		"Failed to set WM8804 SYSCLK: %d\n", ret);
		return ret;
	}

	/* Enable TX output */
	snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0);
	
	/* Power on */
	snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);

	return snd_soc_dai_set_bclk_ratio(cpu_dai,64);
}
Example #5
0
static int snd_rpi_iqaudio_dac_hw_params(struct snd_pcm_substream *substream,
				       struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
// NOT USED	struct snd_soc_dai *codec_dai = rtd->codec_dai;
// NOT USED	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

	unsigned int sample_bits =
		snd_pcm_format_physical_width(params_format(params));

	return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
}
Example #6
0
static int tau_dac_hw_params(struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *params)
{
	int ret, i;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_card_drvdata *drvdata =
			snd_soc_card_get_drvdata(rtd->card);
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct snd_soc_dai **codec_dais = rtd->codec_dais;
	int num_codecs = rtd->num_codecs;

	unsigned int fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
	unsigned int mclk_rate, bclk_rate;
	unsigned int lrclk_rate = params_rate(params);
	int width = params_width(params);
	u16 osr;

	if (width == 24)
		width = 25;

	switch (lrclk_rate) {
	case 44100:
	case 88200:
	case 176400:
		mclk_rate = 22579200;
		break;
	case 32000:
	case 48000:
	case 96000:
	case 192000:
		mclk_rate = 24576000;
		break;
	default:
		dev_err(rtd->card->dev, "Sample rate not supported: %d",
				lrclk_rate);
		return -EINVAL;
	}

	bclk_rate = 2 * width * lrclk_rate;

	/* set cpu DAI configuration */
	ret = snd_soc_dai_set_bclk_ratio(cpu_dai, 2 * width);
	if (ret < 0)
		return ret;

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

	/* calculate oversampling rate */
	if (lrclk_rate <= 48000)
		osr = 0; /* TODO: define WM8741_OSR_LOW etc. in wm8741.h */
	else if (lrclk_rate <= 96000)
		osr = 1;
	else
		osr = 2;

	for (i = 0; i < num_codecs; i++) {
		/* set codec sysclk */
		ret = snd_soc_dai_set_sysclk(codec_dais[i],
				WM8741_SYSCLK, mclk_rate, SND_SOC_CLOCK_IN);
		if (ret < 0)
			return ret;

		/* set codec DAI configuration */
		ret = snd_soc_dai_set_fmt(codec_dais[i],
				SND_SOC_DAIFMT_CBS_CFS | fmt);
		if (ret < 0)
			return ret;

		/* set codec oversampling rate */
		ret = snd_soc_update_bits(codec_dais[i]->codec,
				WM8741_MODE_CONTROL_1,
				WM8741_OSR_MASK, osr << WM8741_OSR_SHIFT);
		if (ret < 0)
			return ret;
	}

	/* enable clocks */
	ret = tau_dac_clk_enable(drvdata, mclk_rate, bclk_rate);
	if (ret < 0) {
		dev_err(rtd->card->dev, "Starting clocks failed: %d\n", ret);
		return ret;
	}

	ret = tau_dac_clk_prepare(drvdata);
	if (ret < 0) {
		dev_err(rtd->card->dev, "Preparing clocks failed: %d\n", ret);
		return ret;
	}

	/* enable codecs */
	/* TODO: TBC: powering down the codes is probably not required if we
	 * use the AVMID reference.
	 */
	for (i = 0; i < num_codecs; i++) {
		snd_soc_update_bits(codec_dais[i]->codec, WM8741_FORMAT_CONTROL,
				WM8741_PWDN_MASK, 0);
	}

	dev_dbg(rtd->card->dev, "%s: mclk = %u, bclk = %u, lrclk = %u, width = %d, fmt = 0x%x",
			__func__, mclk_rate, bclk_rate, lrclk_rate, width, fmt);

	return 0;
}