static int mxc_spdif_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct mxc_spdif_priv *spdif_priv = snd_soc_codec_get_drvdata(codec); struct mxc_spdif_platform_data *plat_data = spdif_priv->plat_data; int err = 0; unsigned long regval; spdif_priv->tx_active = true; err = clk_enable(plat_data->spdif_clk); if (err < 0) goto hw_failed_clk; spdif_softreset(); /* disable all the interrupts */ spdif_intr_enable(0xffffff, 0); regval = __raw_readl(spdif_base_addr + SPDIF_REG_SCR); regval &= 0xfc33e3; regval &= ~SCR_LOW_POWER; regval = SCR_TXFIFO_ZERO | SCR_TXSEL_NORMAL; __raw_writel(regval, SPDIF_REG_SCR + spdif_base_addr); spdif_set_sample_rate(codec, params_rate(params)); return 0; hw_failed_clk: spdif_priv->tx_active = false; clk_disable(plat_data->spdif_clk); return err; }