aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/samsung/i2s.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/samsung/i2s.c')
-rw-r--r--sound/soc/samsung/i2s.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 992a732..a779185 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/regulator/consumer.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
@@ -146,6 +147,8 @@ struct i2s_dai {
unsigned rfs, bfs;
/* I2S Controller's core clock */
struct clk *clk;
+ /* I2S Controller's power domain */
+ struct regulator *regulator;
/* Clock for generating I2S signals */
struct clk *op_clk;
/* Array of clock names for op_clk */
@@ -572,9 +575,13 @@ static int i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
{
struct i2s_dai *i2s = to_info(dai);
- u32 mod = readl(i2s->addr + I2SMOD);
+ u32 mod;
u32 tmp = 0;
+ dev_info(&i2s->pdev->dev, "base %p\n", i2s->addr);
+
+ mod = readl(i2s->addr + I2SMOD);
+
/* Format is priority */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_RIGHT_J:
@@ -951,6 +958,9 @@ static int i2s_resume(struct snd_soc_dai *dai)
static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
{
+ struct clk *fout_epll, *mout_epll;
+ struct clk *mout_audss = NULL;
+ struct clk *sclk_audio, *iis_clk, *iis_busclk, *iis_ipclk; /* these belong shomewhere else */
struct i2s_dai *i2s = to_info(dai);
struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
@@ -971,6 +981,59 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
}
clk_enable(i2s->clk);
+ /* Get i2s power domain regulator */
+ i2s->regulator = regulator_get(&i2s->pdev->dev, "pd");
+ if (IS_ERR(i2s->regulator)) {
+ dev_err(&i2s->pdev->dev, "%s: failed to get resource %s\n",
+ __func__, "i2s");
+ return PTR_ERR(i2s->regulator);
+ }
+
+ /* Enable Power domain */
+ regulator_enable(i2s->regulator);
+
+ fout_epll = clk_get(&i2s->pdev->dev, "fout_epll");
+ if (IS_ERR(fout_epll))
+ dev_err(&i2s->pdev->dev, "failed to get fout_epll\n");
+
+ mout_epll = clk_get(&i2s->pdev->dev, "mout_epll");
+ if (IS_ERR(mout_epll))
+ dev_err(&i2s->pdev->dev, "failed to get mout_epll\n");
+ clk_set_parent(mout_epll, fout_epll);
+
+ sclk_audio = clk_get(&i2s->pdev->dev, "sclk_audio");
+ if (IS_ERR(sclk_audio))
+ dev_err(&i2s->pdev->dev, "failed to get sclk_audio\n");
+ clk_set_parent(sclk_audio, mout_epll);
+
+ /* Need not to enable in general */
+ clk_enable(sclk_audio);
+
+ /* When I2S V5.1 used, initialize audio subsystem clock */
+ /* CLKMUX_ASS */
+ if (&i2s->pdev->id == 0) {
+ mout_audss = clk_get(NULL, "mout_audss");
+ if (IS_ERR(mout_audss))
+ dev_err(&i2s->pdev->dev, "failed to get mout_audss\n");
+ clk_set_parent(mout_audss, fout_epll);
+ /*MUX-I2SA*/
+ iis_clk = clk_get(&i2s->pdev->dev, "audio-bus");
+ if (IS_ERR(iis_clk))
+ dev_err(&i2s->pdev->dev, "failed to get audio-bus\n");
+ clk_set_parent(iis_clk, mout_audss);
+ /*getting AUDIO BUS CLK*/
+ iis_busclk = clk_get(NULL, "dout_audio_bus_clk_i2s");
+ if (IS_ERR(iis_busclk))
+ printk(KERN_ERR "failed to get audss_hclk\n");
+ iis_ipclk = clk_get(&i2s->pdev->dev, "i2s_v50");
+ if (IS_ERR(iis_ipclk))
+ dev_err(&i2s->pdev->dev, "failed to get i2s_v50_clock\n");
+ clk_enable(iis_ipclk);
+ clk_enable(iis_clk);
+ clk_enable(iis_busclk);
+ }
+
+
if (other) {
other->addr = i2s->addr;
other->clk = i2s->clk;