soc: codecs: rt5639: Implement i2c shutdown
[linux-2.6.git] / sound / soc / tegra / tegra30_dam.c
index e2511ed..91ea896 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Author: Nikesh Oswal <noswal@nvidia.com>
  * Copyright (C) 2011 - NVIDIA, Inc.
- * Copyright (C) 2012, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2012-2014, NVIDIA CORPORATION. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -341,7 +341,7 @@ int tegra30_dam_resume(int ifc)
        int i = 0;
        struct tegra30_dam_context *dam;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return -EINVAL;
 
        dam = dams_cont_info[ifc];
@@ -369,7 +369,7 @@ void tegra30_dam_disable_clock(int ifc)
 {
        struct tegra30_dam_context *dam;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return;
 
        dam =  dams_cont_info[ifc];
@@ -381,7 +381,7 @@ int tegra30_dam_enable_clock(int ifc)
 {
        struct tegra30_dam_context *dam;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return -EINVAL;
 
        dam =  dams_cont_info[ifc];
@@ -415,6 +415,7 @@ static int tegra30_dam_show(struct seq_file *s, void *unused)
        struct tegra30_dam_context *dam = s->private;
        int i;
 
+       tegra30_ahub_enable_clocks();
        clk_enable(dam->dam_clk);
 
        for (i = 0; i < ARRAY_SIZE(regs); i++) {
@@ -423,6 +424,7 @@ static int tegra30_dam_show(struct seq_file *s, void *unused)
        }
 
        clk_disable(dam->dam_clk);
+       tegra30_ahub_disable_clocks();
 
        return 0;
 }
@@ -486,7 +488,8 @@ int tegra30_dam_allocate_channel(int ifc, int chid)
 {
        struct tegra30_dam_context *dam = NULL;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC) ||
+               (chid < dam_ch_in0) || (chid >= dam_ch_maxnum))
                return -EINVAL;
 
        dam =  dams_cont_info[ifc];
@@ -503,7 +506,8 @@ int tegra30_dam_free_channel(int ifc, int chid)
 {
        struct tegra30_dam_context *dam = NULL;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC) ||
+               (chid < dam_ch_in0) || (chid >= dam_ch_maxnum))
                return -EINVAL;
 
        dam =  dams_cont_info[ifc];
@@ -520,7 +524,7 @@ int tegra30_dam_free_controller(int ifc)
 {
        struct tegra30_dam_context *dam = NULL;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return -EINVAL;
 
        dam =  dams_cont_info[ifc];
@@ -538,7 +542,7 @@ void tegra30_dam_set_samplerate(int ifc, int chid, int samplerate)
 {
        struct tegra30_dam_context *dam = dams_cont_info[ifc];
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return;
 
        switch (chid) {
@@ -646,7 +650,7 @@ void tegra30_dam_ch0_set_step(struct tegra30_dam_context *dam, int step)
 int tegra30_dam_set_gain(int ifc, int chid, int gain)
 {
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return -EINVAL;
 
        switch (chid) {
@@ -672,13 +676,17 @@ int tegra30_dam_set_acif(int ifc, int chid, unsigned int audio_channels,
        unsigned int reg;
        unsigned int value = 0;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return -EINVAL;
 
 #ifndef CONFIG_ARCH_TEGRA_3x_SOC
-       /*ch0 takes input as mono/32bit always*/
+       /*ch0 takes input as mono always*/
        if ((chid == dam_ch_in0) &&
-               ((client_channels != 1) || (client_bits != 32)))
+               ((client_channels != 1)))
+               return -EINVAL;
+       /*as per dam spec file chout is fixed to 32 bits*/
+       /*so accept ch0, ch1 and chout as 32bit always*/
+       if (client_bits != 32)
                return -EINVAL;
 #else
        /*ch0 takes input as mono/16bit always*/
@@ -722,7 +730,7 @@ void tegra30_dam_write_coeff_ram(int ifc, int fsin, int fsout)
        u32 val;
        int i, *coefRam = NULL;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return;
 
        tegra30_dam_writel(dams_cont_info[ifc], 0x00002000,
@@ -769,7 +777,7 @@ void tegra30_dam_write_coeff_ram(int ifc, int fsin, int fsout)
                        TEGRA30_DAM_AUDIORAMCTL_DAM_CTRL_0);
 
        for (i = 0; i < 64; i++) {
-               val = coefRam[i];\r
+               val = coefRam[i];
                tegra30_dam_writel(dams_cont_info[ifc], val,
                                TEGRA30_DAM_AUDIORAMCTL_DAM_DATA_0);
        }
@@ -779,7 +787,7 @@ void tegra30_dam_set_farrow_param(int ifc, int fsin, int fsout)
 {
        u32 val = TEGRA30_FARROW_PARAM_RESET;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return;
 
        switch(fsin) {
@@ -827,7 +835,7 @@ void tegra30_dam_set_biquad_fixed_coef(int ifc)
 {
        u32 val = TEGRA30_DAM_CH0_BIQUAD_FIXED_COEF_0_VAL;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return;
 
        tegra30_dam_writel(dams_cont_info[ifc], val,
@@ -838,7 +846,7 @@ void tegra30_dam_enable_coeff_ram(int ifc)
 {
        u32 val;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return;
 
        val = tegra30_dam_readl(dams_cont_info[ifc], TEGRA30_DAM_CH0_CTRL);
@@ -852,7 +860,7 @@ void tegra30_dam_set_filter_stages(int ifc, int fsin, int fsout)
        u32 val;
        int filt_stages = 0;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return;
 
        val = tegra30_dam_readl(dams_cont_info[ifc], TEGRA30_DAM_CH0_CTRL);
@@ -903,7 +911,7 @@ void tegra30_dam_enable_stereo_mixing(int ifc)
 {
        u32 val;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC))
                return;
 
        val = tegra30_dam_readl(dams_cont_info[ifc], TEGRA30_DAM_CTRL);
@@ -918,11 +926,14 @@ void tegra30_dam_enable(int ifc, int on, int chid)
        u32 old_val, val, enreg;
        u32 old_val_dam, val_dam;
        int dcnt = 10;
-       struct tegra30_dam_context *dam = dams_cont_info[ifc];
+       struct tegra30_dam_context *dam;
 
-       if (ifc >= TEGRA30_NR_DAM_IFC)
+       if ((ifc < 0) || (ifc >= TEGRA30_NR_DAM_IFC) ||
+           (chid < dam_ch_in0) || (chid >= dam_ch_maxnum))
                return;
 
+       dam = dams_cont_info[ifc];
+
        if (chid == dam_ch_in0)
                enreg = TEGRA30_DAM_CH0_CTRL;
        else
@@ -952,14 +963,14 @@ void tegra30_dam_enable(int ifc, int on, int chid)
 
                if (!on) {
                        if (chid == dam_ch_in0) {
-                               while (tegra30_ahub_dam_ch0_is_enabled(ifc)
+                               while (!tegra30_ahub_dam_ch0_is_empty(ifc)
                                        && dcnt--)
                                        udelay(100);
 
                                dcnt = 10;
                        }
                        else {
-                               while (tegra30_ahub_dam_ch1_is_enabled(ifc)
+                               while (!tegra30_ahub_dam_ch1_is_empty(ifc)
                                        && dcnt--)
                                        udelay(100);
 
@@ -970,20 +981,20 @@ void tegra30_dam_enable(int ifc, int on, int chid)
 
        if (old_val_dam != val_dam) {
                tegra30_dam_writel(dam, val_dam, TEGRA30_DAM_CTRL);
-
                if (!on) {
-                       while (tegra30_ahub_dam_tx_is_enabled(ifc) && dcnt--)
+                       while (!tegra30_ahub_dam_tx_is_empty(ifc) && dcnt--)
                                udelay(100);
 
                        dcnt = 10;
                }
-
        }
 }
 
-void tegra30_dam_ch0_set_datasync(struct tegra30_dam_context *dam, int datasync)
+void tegra30_dam_ch0_set_datasync(int ifc, int datasync)
 {
        u32 val;
+       struct tegra30_dam_context *dam;
+       dam =  dams_cont_info[ifc];
 
        val = tegra30_dam_readl(dam, TEGRA30_DAM_CH0_CTRL);
        val &= ~TEGRA30_DAM_CH0_CTRL_DATA_SYNC_MASK;
@@ -991,9 +1002,11 @@ void tegra30_dam_ch0_set_datasync(struct tegra30_dam_context *dam, int datasync)
        tegra30_dam_writel(dam, val, TEGRA30_DAM_CH0_CTRL);
 }
 
-void tegra30_dam_ch1_set_datasync(struct tegra30_dam_context *dam, int datasync)
+void tegra30_dam_ch1_set_datasync(int ifc, int datasync)
 {
        u32 val;
+       struct tegra30_dam_context *dam;
+       dam =  dams_cont_info[ifc];
 
        val = tegra30_dam_readl(dam, TEGRA30_DAM_CH1_CTRL);
        val &= ~TEGRA30_DAM_CH1_CTRL_DATA_SYNC_MASK;
@@ -1044,7 +1057,7 @@ static int __devinit tegra30_dam_probe(struct platform_device *pdev)
                goto err_free;
        }
        clkm_rate = clk_get_rate(clk_get_parent(dam->dam_clk));
-       while (clkm_rate > 12000000)
+       while (clkm_rate > 13000000)
                clkm_rate >>= 1;
 
        clk_set_rate(dam->dam_clk,clkm_rate);