[xburst] Add support for enabling/disabling the aic controllers clock.
authorLars-Peter Clausen <lars@metafoo.de>
Sun, 7 Mar 2010 23:44:58 +0000 (23:44 +0000)
committerLars-Peter Clausen <lars@metafoo.de>
Sun, 7 Mar 2010 23:44:58 +0000 (23:44 +0000)
SVN-Revision: 20043

target/linux/xburst/files-2.6.32/arch/mips/jz4740/clock.c
target/linux/xburst/files-2.6.32/sound/soc/jz4740/jz4740-i2s.c

index 12a54ed9f671a1f63b1594207b743f52877b23e5..a780706befb33612425414532fb407bdc5fad7f3 100644 (file)
@@ -55,8 +55,8 @@
 #define JZ_CLOCK_GATE_RTC      BIT(2)
 #define JZ_CLOCK_GATE_I2C      BIT(3)
 #define JZ_CLOCK_GATE_SPI      BIT(4)
-#define JZ_CLOCK_GATE_AIC_PCLK BIT(5)
-#define JZ_CLOCK_GATE_AIC      BIT(6)
+#define JZ_CLOCK_GATE_AIC      BIT(5)
+#define JZ_CLOCK_GATE_I2S      BIT(6)
 #define JZ_CLOCK_GATE_MMC      BIT(7)
 #define JZ_CLOCK_GATE_ADC      BIT(8)
 #define JZ_CLOCK_GATE_CIM      BIT(9)
@@ -626,7 +626,7 @@ static struct divided_clk jz4740_clock_divided_clks[] = {
                .clk = {
                        .name = "i2s",
                        .parent = &jz_clk_ext.clk,
-                       .gate_bit = JZ_CLOCK_GATE_AIC,
+                       .gate_bit = JZ_CLOCK_GATE_I2S,
                        .ops = &jz_clk_i2s_ops,
                },
                .reg = JZ_REG_CLOCK_I2S,
@@ -721,6 +721,12 @@ static struct clk jz4740_clock_simple_clks[] = {
                .gate_bit = JZ_CLOCK_GATE_I2C,
                .ops = &jz_clk_simple_ops,
        },
+       {
+               .name = "aic",
+               .parent = &jz_clk_ext.clk,
+               .gate_bit = JZ_CLOCK_GATE_AIC,
+               .ops = &jz_clk_simple_ops,
+       },
 };
 
 static struct static_clk jz_clk_rtc = {
index 8853a735c98f35c738c2911b7ff568c757846c8c..edd995e1516fd247dca3a10405d3cbe53e83372f 100644 (file)
@@ -84,7 +84,8 @@ struct jz4740_i2s {
        void __iomem *base;
        dma_addr_t phys_base;
 
-       struct clk *clk;
+       struct clk *clk_aic;
+       struct clk *clk_i2s;
 
        struct jz4740_pcm_config pcm_config;
 };
@@ -141,7 +142,7 @@ static int jz4740_i2s_startup(struct snd_pcm_substream *substream, struct
 
 
        jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
-       clk_enable(i2s->clk);
+       clk_enable(i2s->clk_i2s);
        jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
 
        return 0;
@@ -153,14 +154,14 @@ static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, struct
        struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
        uint32_t conf;
 
-       if (dai->active)
+       if (!dai->active)
                return;
 
        conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
        conf &= ~JZ_AIC_CONF_ENABLE;
        jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
 
-       clk_disable(i2s->clk);
+       clk_disable(i2s->clk_i2s);
 }
 
 
@@ -198,7 +199,7 @@ static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
            return -EINVAL;
        }
 
-       jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL,ctrl);
+       jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
 
        return 0;
 }
@@ -348,12 +349,12 @@ static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
        switch (clk_id) {
        case JZ4740_I2S_CLKSRC_EXT:
                parent = clk_get(NULL, "ext");
-               clk_set_parent(i2s->clk, parent);
+               clk_set_parent(i2s->clk_i2s, parent);
                break;
        case JZ4740_I2S_CLKSRC_PLL:
                parent = clk_get(NULL, "pll half");
-               clk_set_parent(i2s->clk, parent);
-               ret = clk_set_rate(i2s->clk, freq);
+               clk_set_parent(i2s->clk_i2s, parent);
+               ret = clk_set_rate(i2s->clk_i2s, freq);
                break;
        default:
                return -EINVAL;
@@ -368,14 +369,16 @@ static int jz4740_i2s_suspend(struct snd_soc_dai *dai)
        struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
        uint32_t conf;
 
-       if (!dai->active)
-               return 0;
+       if (dai->active) {
+               conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
+               conf &= ~JZ_AIC_CONF_ENABLE;
+               jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
 
-       conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-       conf &= ~JZ_AIC_CONF_ENABLE;
-       jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+               clk_disable(i2s->clk_i2s);
+       }
+
+       clk_disable(i2s->clk_aic);
 
-       clk_disable(i2s->clk);
        return 0;
 }
 
@@ -384,14 +387,16 @@ static int jz4740_i2s_resume(struct snd_soc_dai *dai)
        struct jz4740_i2s *i2s = jz4740_dai_to_i2s(dai);
        uint32_t conf;
 
-       if (!dai->active)
-               return 0;
+       clk_enable(i2s->clk_aic);
 
-       clk_enable(i2s->clk);
+       if (dai->active) {
+               clk_enable(i2s->clk_i2s);
 
-       conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
-       conf |= JZ_AIC_CONF_ENABLE;
-       jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+               conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
+               conf |= JZ_AIC_CONF_ENABLE;
+               jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
+
+       }
 
        return 0;
 }
@@ -487,13 +492,23 @@ static int __devinit jz4740_i2s_dev_probe(struct platform_device *pdev)
 
        ret = snd_soc_register_dai(&jz4740_i2s_dai);
 
-       i2s->clk = clk_get(&pdev->dev, "i2s");
+       i2s->clk_aic = clk_get(&pdev->dev, "aic");
 
-       if (IS_ERR(i2s->clk)) {
-               ret = PTR_ERR(i2s->clk);
+       if (IS_ERR(i2s->clk_aic)) {
+               ret = PTR_ERR(i2s->clk_aic);
                goto err_iounmap;
        }
 
+
+       i2s->clk_i2s = clk_get(&pdev->dev, "i2s");
+
+       if (IS_ERR(i2s->clk_i2s)) {
+               ret = PTR_ERR(i2s->clk_i2s);
+               goto err_iounmap;
+       }
+
+       clk_enable(i2s->clk_aic);
+
        platform_set_drvdata(pdev, i2s);
 
        return 0;
@@ -514,7 +529,9 @@ static int __devexit jz4740_i2s_dev_remove(struct platform_device *pdev)
 
        snd_soc_unregister_dai(&jz4740_i2s_dai);
 
-       clk_put(i2s->clk);
+       clk_disable(i2s->clk_aic);
+       clk_put(i2s->clk_i2s);
+       clk_put(i2s->clk_aic);
 
        iounmap(i2s->base);
        release_mem_region(i2s->mem->start, resource_size(i2s->mem));