static int tegra_spdif_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_card *card = rtd->card; struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, min_mclk; int err; srate = params_rate(params); switch (srate) { case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; case 8000: case 16000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; default: return -EINVAL; } min_mclk = 128 * srate; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % min_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); return 0; }
static int tegra_wm8903_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 = codec_dai->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); int srate, mclk; int err; srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 256 * srate; break; } /* FIXME: Codec only requires >= 3MHz if OSR==0 */ while (mclk < 6000000) mclk *= 2; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { dev_err(card->dev, "Can't configure clocks\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } return 0; }
static int tegra_wm8753_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 = codec_dai->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); int srate, mclk; int err; srate = params_rate(params); switch (srate) { case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; default: mclk = 12288000; break; } err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { dev_err(card->dev, "Can't configure clocks\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } return 0; }
static int tegra_aic326x_bt_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_card *card = rtd->card; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); int err, srate, mclk, min_mclk; srate = params_rate(params); mclk = tegra_aic326x_get_mclk(srate); if (mclk < 0) return mclk; min_mclk = 64 * srate; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % min_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); #ifndef CONFIG_ARCH_TEGRA_2x_SOC /* codec configuration */ machine->codec_info[BT_SCO].rate = params_rate(params); machine->codec_info[BT_SCO].channels = params_channels(params); #endif machine->is_device_bt = 1; return 0; }
static int seaboard_spdif_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_card *card = codec->card; struct tegra_seaboard *seaboard = snd_soc_card_get_drvdata(card); int srate, mclk, mclk_change; int err; /* * FIXME: Refactor mclk into PCM-specific function; SPDIF doesn't * need it */ srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 256 * srate; break; } /* FIXME: Codec only requires >= 3MHz if OSR==0 */ while (mclk < 6000000) mclk *= 2; err = tegra_asoc_utils_set_rate(&seaboard->util_data, srate, mclk, &mclk_change); if (err < 0) { dev_err(card->dev, "Can't configure clocks\n"); return err; } 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; }
static int tegra_aic326x_bt_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_card *card = rtd->card; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); int err, srate, mclk, min_mclk, sample_size; 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; min_mclk = 64 * srate; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % min_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); err = snd_soc_dai_set_fmt(rtd->cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(rtd->codec->card->dev, "cpu_dai fmt not set\n"); return err; } #ifdef CONFIG_ARCH_TEGRA_2x_SOC err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC2, TEGRA20_DAS_DAP_ID_4); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_4, TEGRA20_DAS_DAP_SEL_DAC2); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } #endif return 0; }
static int tegra_wm8753_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 = codec_dai->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; int srate, mclk, i2s_daifmt; int err, rate; srate = params_rate(params); switch (srate) { case 8000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; default: mclk = 12000000; break; } 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); 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; /* Use DSP mode for mono on Tegra20 */ if ((params_channels(params) != 2) && machine_is_whistler()) { i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; } else { 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 = 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_sysclk(codec_dai, 0, rate, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } #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; }
int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev, struct snd_soc_card *card) { int ret; data->dev = dev; data->card = card; data->clk_pll_p_out1 = clk_get_sys(NULL, "pll_p_out1"); if (IS_ERR(data->clk_pll_p_out1)) { dev_err(data->dev, "Can't retrieve clk pll_p_out1\n"); ret = PTR_ERR(data->clk_pll_p_out1); goto err; } if (of_machine_is_compatible("nvidia,tegra20")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; else if (of_machine_is_compatible("nvidia,tegra30")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; else if (of_machine_is_compatible("nvidia,tegra114")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA11x; else if (of_machine_is_compatible("nvidia,tegra148")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA14x; else if (of_machine_is_compatible("nvidia,tegra124")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA12x; else if (!dev->of_node) { /* non-DT is always Tegra20 */ #if defined(CONFIG_ARCH_TEGRA_2x_SOC) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; #elif defined(CONFIG_ARCH_TEGRA_3x_SOC) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; #elif defined(CONFIG_ARCH_TEGRA_11x_SOC) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA11x; #elif defined(CONFIG_ARCH_TEGRA_14x_SOC) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA14x; #elif defined(CONFIG_ARCH_TEGRA_12x_SOC) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA12x; #endif } else /* DT boot, but unknown SoC */ return -EINVAL; data->clk_pll_a = clk_get_sys(NULL, "pll_a"); if (IS_ERR(data->clk_pll_a)) { dev_err(data->dev, "Can't retrieve clk pll_a\n"); ret = PTR_ERR(data->clk_pll_a); goto err_put_pll_p_out1; } data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); if (IS_ERR(data->clk_pll_a_out0)) { dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); ret = PTR_ERR(data->clk_pll_a_out0); goto err_put_pll_a; } data->clk_m = clk_get_sys(NULL, "clk_m"); if (IS_ERR(data->clk_m)) { dev_err(data->dev, "Can't retrieve clk clk_m\n"); ret = PTR_ERR(data->clk_m); goto err; } if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); else data->clk_cdev1 = clk_get_sys("extern1", NULL); if (IS_ERR(data->clk_cdev1)) { dev_err(data->dev, "Can't retrieve clk cdev1\n"); ret = PTR_ERR(data->clk_cdev1); goto err_put_pll_a_out0; } if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) data->clk_out1 = ERR_PTR(-ENOENT); else { data->clk_out1 = clk_get_sys("clk_out_1", "extern1"); if (IS_ERR(data->clk_out1)) { dev_err(data->dev, "Can't retrieve clk out1\n"); ret = PTR_ERR(data->clk_out1); goto err_put_cdev1; } } ret = clk_prepare_enable(data->clk_cdev1); if (ret) { dev_err(data->dev, "Can't enable clk cdev1/extern1"); goto err_put_out1; } if (!IS_ERR(data->clk_out1)) { ret = clk_prepare_enable(data->clk_out1); if (ret) { dev_err(data->dev, "Can't enable clk out1"); goto err_put_out1; } } ret = tegra_asoc_utils_set_rate(data, 48000, 256 * 48000); if (ret) goto err_put_out1; return 0; err_put_out1: if (!IS_ERR(data->clk_out1)) clk_put(data->clk_out1); err_put_cdev1: clk_put(data->clk_cdev1); err_put_pll_a_out0: clk_put(data->clk_pll_a_out0); err_put_pll_a: clk_put(data->clk_pll_a); err_put_pll_p_out1: clk_put(data->clk_pll_p_out1); err: return ret; }
static int tegra_bt_sco_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_card *card = rtd->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, min_mclk; int err; srate = params_rate(params); switch (srate) { case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; case 8000: case 16000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; default: return -EINVAL; } min_mclk = 64 * srate; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % min_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); err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } #ifdef CONFIG_ARCH_TEGRA_2x_SOC err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC2, TEGRA20_DAS_DAP_ID_4); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_4, TEGRA20_DAS_DAP_SEL_DAC2); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } #endif return 0; }
int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev) { int ret; int rate; data->dev = dev; data->clk_pll_p_out1 = clk_get_sys(NULL, "pll_p_out1"); if (IS_ERR(data->clk_pll_p_out1)) { dev_err(data->dev, "Can't retrieve clk pll_p_out1\n"); ret = PTR_ERR(data->clk_pll_p_out1); goto err; } data->clk_pll_a = clk_get_sys(NULL, "pll_a"); if (IS_ERR(data->clk_pll_a)) { dev_err(data->dev, "Can't retrieve clk pll_a\n"); ret = PTR_ERR(data->clk_pll_a); goto err_put_pll_p_out1; } data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); if (IS_ERR(data->clk_pll_a_out0)) { dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); ret = PTR_ERR(data->clk_pll_a_out0); goto err_put_pll_a; } data->clk_m = clk_get_sys(NULL, "clk_m"); if (IS_ERR(data->clk_m)) { dev_err(data->dev, "Can't retrieve clk clk_m\n"); ret = PTR_ERR(data->clk_m); goto err; } #if defined(CONFIG_ARCH_TEGRA_2x_SOC) data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); #else data->clk_cdev1 = clk_get_sys("extern1", NULL); #endif if (IS_ERR(data->clk_cdev1)) { dev_err(data->dev, "Can't retrieve clk cdev1\n"); ret = PTR_ERR(data->clk_cdev1); goto err_put_pll_a_out0; } #if defined(CONFIG_ARCH_TEGRA_2x_SOC) data->clk_out1 = ERR_PTR(-ENOENT); #else data->clk_out1 = clk_get_sys("clk_out_1", "extern1"); if (IS_ERR(data->clk_out1)) { dev_err(data->dev, "Can't retrieve clk out1\n"); ret = PTR_ERR(data->clk_out1); goto err_put_cdev1; } #endif #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) #if TEGRA30_I2S_MASTER_PLAYBACK ret = clk_set_parent(data->clk_cdev1, data->clk_pll_a_out0); if (ret) { dev_err(data->dev, "Can't set clk cdev1/extern1 parent"); goto err_put_out1; } #else rate = clk_get_rate(data->clk_m); if(rate == 26000000) clk_set_rate(data->clk_cdev1, 13000000); ret = clk_set_parent(data->clk_cdev1, data->clk_m); if (ret) { dev_err(data->dev, "Can't set clk cdev1/extern1 parent"); goto err_put_out1; } #endif #endif #if 0 //remove clk_enable clk_cdev1, move it to fm34.c enable ret = clk_enable(data->clk_cdev1); if (ret) { dev_err(data->dev, "Can't enable clk cdev1/extern1"); goto err_put_out1; } #endif if (!IS_ERR(data->clk_out1)) { ret = clk_enable(data->clk_out1); if (ret) { dev_err(data->dev, "Can't enable clk out1"); goto err_put_out1; } } ret = tegra_asoc_utils_set_rate(data, 48000, 256 * 48000); if (ret) goto err_put_out1; return 0; err_put_out1: if (!IS_ERR(data->clk_out1)) clk_put(data->clk_out1); #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) err_put_cdev1: #endif clk_put(data->clk_cdev1); err_put_pll_a_out0: clk_put(data->clk_pll_a_out0); err_put_pll_a: clk_put(data->clk_pll_a); err_put_pll_p_out1: clk_put(data->clk_pll_p_out1); err: return ret; }
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; }
static int tegra_aic326x_bt_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_card *card = rtd->card; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; int err, srate, mclk, min_mclk, sample_size, i2s_daifmt; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai); #endif 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; min_mclk = 64 * srate; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % min_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); i2s_daifmt = SND_SOC_DAIFMT_NB_NF; i2s_daifmt |= pdata->i2s_param[BT_SCO].is_i2s_master ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM; switch (pdata->i2s_param[BT_SCO].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 = snd_soc_dai_set_fmt(rtd->cpu_dai, i2s_daifmt); if (err < 0) { dev_err(rtd->codec->card->dev, "cpu_dai fmt not set\n"); return err; } #ifdef CONFIG_ARCH_TEGRA_2x_SOC err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC2, TEGRA20_DAS_DAP_ID_4); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_4, TEGRA20_DAS_DAP_SEL_DAC2); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } #else if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && i2s->is_dam_used) tegra_aic326x_set_dam_cif(i2s->dam_ifc, params_rate(params), params_channels(params), sample_size, 0, 0, 0, 0); #endif return 0; }
int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev, struct snd_soc_card *card) { int ret; data->dev = dev; data->card = card; data->clk_pll_p_out1 = clk_get_sys(NULL, "pll_p_out1"); if (IS_ERR(data->clk_pll_p_out1)) { dev_err(data->dev, "Can't retrieve clk pll_p_out1\n"); ret = PTR_ERR(data->clk_pll_p_out1); goto err; } data->clk_pll_a = clk_get_sys(NULL, "pll_a"); if (IS_ERR(data->clk_pll_a)) { dev_err(data->dev, "Can't retrieve clk pll_a\n"); ret = PTR_ERR(data->clk_pll_a); goto err_put_pll_p_out1; } data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); if (IS_ERR(data->clk_pll_a_out0)) { dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); ret = PTR_ERR(data->clk_pll_a_out0); goto err_put_pll_a; } data->clk_m = clk_get_sys(NULL, "clk_m"); if (IS_ERR(data->clk_m)) { dev_err(data->dev, "Can't retrieve clk clk_m\n"); ret = PTR_ERR(data->clk_m); goto err; } #if defined(CONFIG_ARCH_TEGRA_2x_SOC) data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); #else data->clk_cdev1 = clk_get_sys("extern1", NULL); #endif if (IS_ERR(data->clk_cdev1)) { dev_err(data->dev, "Can't retrieve clk cdev1\n"); ret = PTR_ERR(data->clk_cdev1); goto err_put_pll_a_out0; } #if defined(CONFIG_ARCH_TEGRA_2x_SOC) data->clk_out1 = ERR_PTR(-ENOENT); #else data->clk_out1 = clk_get_sys("clk_out_1", "extern1"); if (IS_ERR(data->clk_out1)) { dev_err(data->dev, "Can't retrieve clk out1\n"); ret = PTR_ERR(data->clk_out1); goto err_put_cdev1; } #endif ret = clk_enable(data->clk_cdev1); if (ret) { dev_err(data->dev, "Can't enable clk cdev1/extern1"); goto err_put_out1; } if (!IS_ERR(data->clk_out1)) { ret = clk_enable(data->clk_out1); if (ret) { dev_err(data->dev, "Can't enable clk out1"); goto err_put_out1; } } ret = tegra_asoc_utils_set_rate(data, 48000, 256 * 48000); if (ret) goto err_put_out1; return 0; err_put_out1: if (!IS_ERR(data->clk_out1)) clk_put(data->clk_out1); #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) err_put_cdev1: #endif clk_put(data->clk_cdev1); err_put_pll_a_out0: clk_put(data->clk_pll_a_out0); err_put_pll_a: clk_put(data->clk_pll_a); err_put_pll_p_out1: clk_put(data->clk_pll_p_out1); err: return ret; }
int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data, struct device *dev) { int ret; bool new_clocks = false; data->dev = dev; if (of_machine_is_compatible("nvidia,tegra20")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20; else if (of_machine_is_compatible("nvidia,tegra30")) data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30; else if (of_machine_is_compatible("nvidia,tegra114")) { data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA114; new_clocks = true; } else { dev_err(data->dev, "SoC unknown to Tegra ASoC utils\n"); return -EINVAL; } if (new_clocks) data->clk_pll_a = clk_get(dev, "pll_a"); else data->clk_pll_a = clk_get_sys(NULL, "pll_a"); if (IS_ERR(data->clk_pll_a)) { dev_err(data->dev, "Can't retrieve clk pll_a\n"); ret = PTR_ERR(data->clk_pll_a); goto err; } if (new_clocks) data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0"); else data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0"); if (IS_ERR(data->clk_pll_a_out0)) { dev_err(data->dev, "Can't retrieve clk pll_a_out0\n"); ret = PTR_ERR(data->clk_pll_a_out0); goto err_put_pll_a; } if (new_clocks) data->clk_cdev1 = clk_get(dev, "mclk"); else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20) data->clk_cdev1 = clk_get_sys(NULL, "cdev1"); else data->clk_cdev1 = clk_get_sys("extern1", NULL); if (IS_ERR(data->clk_cdev1)) { dev_err(data->dev, "Can't retrieve clk cdev1\n"); ret = PTR_ERR(data->clk_cdev1); goto err_put_pll_a_out0; } ret = tegra_asoc_utils_set_rate(data, 44100, 256 * 44100); if (ret) goto err_put_cdev1; return 0; err_put_cdev1: clk_put(data->clk_cdev1); err_put_pll_a_out0: clk_put(data->clk_pll_a_out0); err_put_pll_a: clk_put(data->clk_pll_a); err: return ret; }
static int tegra_wm8903_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_wm8903 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, i2s_daifmt; int err; struct clk *clk_m; int rate; srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 256 * srate; break; } clk_m = clk_get_sys(NULL, "clk_m"); if (IS_ERR(clk_m)) { dev_err(card->dev, "Can't retrieve clk clk_m\n"); err = PTR_ERR(clk_m); return err; } rate = clk_get_rate(clk_m); printk("extern1 rate=%d\n",rate); #if TEGRA30_I2S_MASTER_PLAYBACK /* FIXME: Codec only requires >= 3MHz if OSR==0 */ while (mclk < 6000000) mclk *= 2; i2s_daifmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; #else mclk = rate; i2s_daifmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM; #endif 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); /* Use DSP mode for mono on Tegra20 */ if ((params_channels(params) != 2) && (machine_is_ventana() || machine_is_harmony() || machine_is_kaen() || machine_is_aebl())) i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; else i2s_daifmt |= SND_SOC_DAIFMT_I2S; 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_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } #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 #if defined(CONFIG_ARCH_ACER_T20) acer_volume_setting(codec, substream); #endif return 0; }
static int tegra_max98088_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_max98088 *machine = snd_soc_card_get_drvdata(card); #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai); #endif int srate, mclk, sample_size, i2s_daifmt; int err; struct clk *clk; int rate; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: sample_size = 16; break; default: return -EINVAL; } srate = params_rate(params); switch (srate) { case 8000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; default: mclk = 12000000; break; } #if defined(CONFIG_ARCH_TEGRA_2x_SOC) clk = clk_get_sys(NULL, "cdev1"); #else clk = clk_get_sys("extern1", NULL); #endif if (IS_ERR(clk)) { dev_err(card->dev, "Can't retrieve clk cdev1\n"); err = PTR_ERR(clk); return err; } rate = clk_get_rate(clk); printk("extern1 rate=%d\n",rate); #if TEGRA30_I2S_MASTER_PLAYBACK i2s_daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; #else i2s_daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM; mclk = rate; #endif 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); 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_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) tegra_max98088_set_dam_cif(i2s->dam_ifc, srate, params_channels(params), sample_size, 0, 0, 0, 0); #endif return 0; }
static int tegra_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_max98088 *machine = snd_soc_card_get_drvdata(card); int srate, mclk; int err; srate = params_rate(params); switch (srate) { case 8000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; default: return -EINVAL; break; } 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); err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } #ifndef CONFIG_ARCH_TEGRA_2x_SOC /* codec configuration */ machine->codec_info[HIFI_CODEC].rate = params_rate(params); machine->codec_info[HIFI_CODEC].channels = params_channels(params); machine->codec_info[HIFI_CODEC].bitsize = 16; machine->codec_info[HIFI_CODEC].is_i2smaster = 1; machine->codec_info[HIFI_CODEC].is_format_dsp = 0; /* baseband configuration */ machine->codec_info[BASEBAND].bitsize = 16; machine->codec_info[BASEBAND].is_i2smaster = 1; machine->codec_info[BASEBAND].is_format_dsp = 1; #endif machine->is_device_bt = 0; return 0; }
static int tegra_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; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_aic3008 *machine = snd_soc_card_get_drvdata(card); int dai_flag = 0, mclk, srate; int err; AUD_DBG("Start tegra_hifi_hw_params()\n"); AUD_DBG("set I2S Master\n"); dai_flag |= SND_SOC_DAIFMT_I2S; // i2s mode dai_flag |= SND_SOC_DAIFMT_CBM_CFM; // bclk and frame master srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 256 * srate; break; } /* FIXME: Codec only requires >= 3MHz if OSR==0 */ while (mclk < 6000000) mclk *= 2; mclk = 12288000; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { dev_err(card->dev, "Can't configure clocks\n"); return err; } // eventually calls audio codec to set dai format, which sets slave err = snd_soc_dai_set_fmt(codec_dai, dai_flag); if (err < 0) { AUD_ERR("codec_dai fmt not set \n"); return err; } AUD_DBG("*** snd_soc_dai_set_fmt(codec_dai, dai_flag) ok ***\n"); // eventually calls t2s driver to set dai format, which sets master err = snd_soc_dai_set_fmt(cpu_dai, dai_flag); if (err < 0) { AUD_ERR("cpu_dai fmt not set \n"); return err; } AUD_DBG("*** snd_soc_dai_set_fmt(cpu_dai, dai_flag) ok ***\n"); // FIXME: not sure this is the right way. // Sets the audio codec clks. // This should be sample rate times 256 or 128 based on codec need err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { AUD_ERR("codec_dai clock not set\n"); return err; } AUD_DBG("*** snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN) ok ***\n"); return 0; }
static int seaboard_asoc_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_seaboard *seaboard = snd_soc_card_get_drvdata(card); int srate, mclk, mclk_change; int err; srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 256 * srate; break; } /* FIXME: Codec only requires >= 3MHz if OSR==0 */ while (mclk < 6000000) mclk *= 2; err = tegra_asoc_utils_set_rate(&seaboard->util_data, srate, mclk, &mclk_change); if (err < 0) { dev_err(card->dev, "Can't configure clocks\n"); return err; } err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } if (mclk_change) { err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } } return 0; }
static int tegra_rt5631_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_rt5631 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, i2s_daifmt; int err; srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 384 * srate; break; } /* FIXME: Codec only requires >= 3MHz if OSR==0 */ while (mclk < 6000000) mclk *= 2; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { dev_err(card->dev, "Can't configure clocks\n"); return err; } i2s_daifmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; /* Use DSP mode for mono on Tegra20 */ if ((params_channels(params) != 2) && (machine_is_ventana() || machine_is_harmony() || machine_is_kaen() || machine_is_aebl())) i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; else i2s_daifmt |= SND_SOC_DAIFMT_I2S; 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_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } return 0; }
static int tegra_bt_sco_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_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; int srate, mclk, min_mclk, i2s_daifmt; int err; srate = params_rate(params); switch (srate) { case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; case 8000: case 16000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; default: return -EINVAL; } min_mclk = 64 * srate; err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk); if (err < 0) { if (!(machine->util_data.set_mclk % min_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); i2s_daifmt = SND_SOC_DAIFMT_NB_NF; i2s_daifmt |= pdata->i2s_param[BT_SCO].is_i2s_master ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM; switch (pdata->i2s_param[BT_SCO].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 = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } #ifdef CONFIG_ARCH_TEGRA_2x_SOC err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC2, TEGRA20_DAS_DAP_ID_4); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_4, TEGRA20_DAS_DAP_SEL_DAC2); if (err < 0) { dev_err(card->dev, "failed to set dac-dap path\n"); return err; } #endif 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); int srate, mclk, sample_size, daifmt; int err; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai); #endif 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; daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS; 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); err = snd_soc_dai_set_fmt(codec_dai, daifmt); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_fmt(cpu_dai, daifmt); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } #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; } #else /*assumes tegra3*/ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && i2s->is_dam_used) tegra_aic326x_set_dam_cif(i2s->dam_ifc, srate, params_channels(params), sample_size, 0, 0, 0, 0); #endif return 0; }
static int tegra_wm8753_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_codec *codec = rtd->codec; struct snd_soc_card *card = codec->card; struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); int srate, mclk, i2s_daifmt, sys_clk; int err, pcmdiv, vxclkdiv; srate = params_rate(params); switch (srate) { case 8000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; default: mclk = 12000000; break; } 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); i2s_daifmt = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM; i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; 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; } sys_clk = machine->util_data.set_mclk; err = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, sys_clk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } err = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, sys_clk, 12288000); if (err < 0) { dev_err(card->dev, "codec_dai pll not set\n"); return err; } if (params_rate(params) == 8000) { pcmdiv = WM8753_PCM_DIV_6; /* BB expecting 2048Khz bclk */ vxclkdiv = WM8753_VXCLK_DIV_1; } else if (params_rate(params) == 16000) { pcmdiv = WM8753_PCM_DIV_3; /* BB expecting 2048Khz bclk */ vxclkdiv = WM8753_VXCLK_DIV_2; } else { dev_err(card->dev, "codec_dai unsupported voice rate\n"); return -EINVAL; } snd_soc_dai_set_clkdiv(codec_dai, WM8753_VXCLKDIV, vxclkdiv); snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); machine->is_call_mode_bt = 0; 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); int srate, mclk; int err, pcmdiv, vxclkdiv;; srate = params_rate(params); mclk = tegra_aic326x_get_mclk(srate); if (mclk < 0) return mclk; 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); if(machine_is_tegra_enterprise()) { err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); } else { err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); } if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai 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[HIFI_CODEC].rate = params_rate(params); machine->codec_info[HIFI_CODEC].channels = params_channels(params); machine->codec_info[HIFI_CODEC].bitsize = 16; machine->codec_info[HIFI_CODEC].is_i2smaster = 1; machine->codec_info[HIFI_CODEC].is_format_dsp = 0; /* baseband configuration */ machine->codec_info[BASEBAND].bitsize = 16; machine->codec_info[BASEBAND].is_i2smaster = 1; machine->codec_info[BASEBAND].is_format_dsp = 1; #endif machine->is_device_bt = 0; return 0; }
static int tegra_max98095_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_max98095 *machine = snd_soc_card_get_drvdata(card); #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai); #endif unsigned int srate, mclk, sample_size; int err; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: sample_size = 16; break; default: return -EINVAL; } srate = params_rate(params); switch (srate) { case 8000: case 16000: case 24000: case 32000: case 48000: case 64000: case 96000: mclk = 12288000; break; case 11025: case 22050: case 44100: case 88200: mclk = 11289600; break; default: mclk = 12000000; break; } 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); err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(card->dev, "cpu_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) tegra_max98095_set_dam_cif(i2s->dam_ifc, srate, params_channels(params), sample_size); #endif return 0; }
static int tegra_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; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_card* card = codec->card; struct tegra_alc5623* machine = snd_soc_card_get_drvdata(card); int sys_clk; int err; int i; /* Get the requested sampling rate */ unsigned int srate = params_rate(params); #ifdef USE_ORG_DAS /* I2S <-> DAC <-> DAS <-> DAP <-> CODEC -If DAP is master, codec will be slave */ int codec_is_master = !tegra_das_is_port_master(tegra_audio_codec_type_hifi); /* Get DAS dataformat - DAP is connecting to codec */ enum dac_dap_data_format data_fmt = tegra_das_get_codec_data_fmt(tegra_audio_codec_type_hifi); /* We are supporting DSP and I2s format for now */ int dai_flag = 0; if (data_fmt & dac_dap_data_format_i2s) dai_flag |= SND_SOC_DAIFMT_I2S; else dai_flag |= SND_SOC_DAIFMT_DSP_A; if (codec_is_master) dai_flag |= SND_SOC_DAIFMT_CBM_CFM; /* codec is master */ else dai_flag |= SND_SOC_DAIFMT_CBS_CFS; #else /* I2S <-> DAC <-> DAS <-> DAP <-> CODEC -If DAP is master, codec will be slave */ bool codec_is_master = machine->hifi_codec_master; /* Get DAS dataformat - DAP is connecting to codec */ int dai_flag = machine->hifi_codec_datafmt; /* Depending on the number of channels, we must select the mode - I2S only supports stereo operation, DSP_A can support mono with the ALC5624 */ /*t dai_flag = (params_channels(params) == 1) ? SND_SOC_DAIFMT_DSP_A : SND_SOC_DAIFMT_I2S;*/ dev_dbg(card->dev,"%s(): cpu_dai:'%s'\n", __FUNCTION__,cpu_dai->name); dev_dbg(card->dev,"%s(): codec_dai:'%s'\n", __FUNCTION__,codec_dai->name); if (codec_is_master) dai_flag |= SND_SOC_DAIFMT_CBM_CFM; /* codec is master */ else dai_flag |= SND_SOC_DAIFMT_CBS_CFS; #endif dev_dbg(card->dev,"%s(): format: 0x%08x, channels:%d, srate:%d\n", __FUNCTION__, params_format(params),params_channels(params),params_rate(params)); /* Set the CPU dai format. This will also set the clock rate in master mode */ err = snd_soc_dai_set_fmt(cpu_dai, dai_flag); if (err < 0) { dev_err(card->dev,"cpu_dai fmt not set \n"); return err; } err = snd_soc_dai_set_fmt(codec_dai, dai_flag); if (err < 0) { dev_err(card->dev,"codec_dai fmt not set \n"); return err; } /* Get system clock */ sys_clk = clk_get_rate(machine->util_data.clk_cdev1); if (codec_is_master) { dev_dbg(card->dev,"%s(): codec in master mode\n",__FUNCTION__); /* If using port as slave (=codec as master), then we can use the codec PLL to get the other sampling rates */ /* Try each one until success */ for (i = 0; i < ARRAY_SIZE(clocktab); i++) { if (clocktab[i].srate != srate) continue; if (snd_soc_dai_set_pll(codec_dai, 0, 0, sys_clk, clocktab[i].mclk) >= 0) { /* Codec PLL is synthetizing this new clock */ sys_clk = clocktab[i].mclk; break; } } if (i >= ARRAY_SIZE(clocktab)) { dev_err(card->dev,"%s(): unable to set required MCLK for SYSCLK of %d, sampling rate: %d\n",__FUNCTION__,sys_clk,srate); return -EINVAL; } } else { dev_dbg(card->dev,"%s(): codec in slave mode\n",__FUNCTION__); /* Disable codec PLL */ err = snd_soc_dai_set_pll(codec_dai, 0, 0, sys_clk, sys_clk); if (err < 0) { dev_err(card->dev,"%s(): unable to disable codec PLL\n",__FUNCTION__); return err; } /* Check this sampling rate can be achieved with this sysclk */ for (i = 0; i < ARRAY_SIZE(clocktab); i++) { if (clocktab[i].srate != srate) continue; if (sys_clk == clocktab[i].mclk) break; } if (i >= ARRAY_SIZE(clocktab)) { dev_err(card->dev,"%s(): unable to get required %d hz sampling rate of %d hz SYSCLK\n",__FUNCTION__,srate,sys_clk); return -EINVAL; } } err = tegra_asoc_utils_set_rate(&machine->util_data, srate, sys_clk); if (err < 0) { dev_err(card->dev, "Can't configure clocks\n"); return err; } /* Set CODEC sysclk */ err = snd_soc_dai_set_sysclk(codec_dai, 0, sys_clk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev,"codec_dai clock not set\n"); return err; } 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); int srate, mclk; int err, pcmdiv, vxclkdiv;; srate = params_rate(params); mclk = tegra_aic326x_get_mclk(srate); if (mclk < 0) return mclk; 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); err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (err < 0) { dev_err(card->dev, "codec_dai fmt not set\n"); return err; } err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) { dev_err(card->dev, "codec_dai clock not set\n"); return err; } 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; } /*Uncomment this when TI codec driver updated for configuring plls*/ //snd_soc_dai_set_clkdiv(codec_dai, ASI2_BCLK_N, vxclkdiv); //snd_soc_dai_set_clkdiv(codec_dai, ASI2_WCLK_N, pcmdiv); machine->is_device_bt = 0; return 0; }
static int tegra_p1852_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_p1852 *machine = snd_soc_card_get_drvdata(card); int srate, mclk; int i2s_daifmt = 0; int err; struct tegra_p1852_platform_data *pdata; int codec_id = codec_dai->id; pdata = machine->pdata; srate = params_rate(params); switch (srate) { case 64000: case 88200: case 96000: mclk = 128 * srate; break; default: mclk = 256 * srate; break; } 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); if (pdata->codec_info[codec_id].master) i2s_daifmt |= SND_SOC_DAIFMT_CBM_CFM; else i2s_daifmt |= SND_SOC_DAIFMT_CBS_CFS; switch (pdata->codec_info[codec_id].i2s_format) { case format_tdm: i2s_daifmt |= SND_SOC_DAIFMT_DSP_A; break; case format_i2s: i2s_daifmt |= SND_SOC_DAIFMT_I2S; break; case format_rjm: i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J; break; case format_ljm: i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J; break; default: break; } err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt); if (err < 0) dev_info(card->dev, "codec_dai fmt not set\n"); 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_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN); if (err < 0) dev_info(card->dev, "codec_dai clock not set\n"); return 0; }