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