summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra3_i2s.c
diff options
context:
space:
mode:
authorScottPeterson <speterson@nvidia.com>2011-07-14 11:11:31 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-07-29 15:56:52 -0700
commita1f23b74282aa5dfdbdef7daabaafcb01b943907 (patch)
treeb43cbda617d26c54c9895a51015f86626ab49c13 /arch/arm/mach-tegra/tegra3_i2s.c
parentd922c50e51312d65797f8dc6f00375e87be46b29 (diff)
arm:tegra: Support I2S slave mode
Add support for I2S slave mode by correctly setting audio_sync clocks. Change-Id: I2338b376be80ae76f43524be223395b01e697f82 Reviewed-on: http://git-master/r/43089 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra3_i2s.c')
-rw-r--r--arch/arm/mach-tegra/tegra3_i2s.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/arch/arm/mach-tegra/tegra3_i2s.c b/arch/arm/mach-tegra/tegra3_i2s.c
index 2220982de25f..98fc661b2311 100644
--- a/arch/arm/mach-tegra/tegra3_i2s.c
+++ b/arch/arm/mach-tegra/tegra3_i2s.c
@@ -340,15 +340,14 @@ int i2s_set_bit_format(int ifc, unsigned fmt)
(fmt == AUDIO_FRAME_FORMAT_RJM) ||
(fmt == AUDIO_FRAME_FORMAT_LJM)) {
val |= I2S_CTRL_FRAME_FORMAT_LRCK;
+ i2s_set_edge_control(ifc, 0);
} else { /*Dsp,Pcm,Tdm,Nw*/
val |= I2S_CTRL_FRAME_FORMAT_FSYNC;
-
i2s_set_fsync_width(ifc, 0);
i2s_set_edge_control(ifc, 1);
i2s_set_slot_control(ifc, AUDIO_TX_MODE, 0, 0x1);
i2s_set_slot_control(ifc, AUDIO_RX_MODE, 0, 0x1);
}
-
i2s_writel(ifc, val, I2S_CTRL_0);
return 0;
}
@@ -950,7 +949,39 @@ int i2s_clock_enable(int ifc, int fifo_mode)
}
info->clk_refs++;
} else {
-
+ if (!info->clk_refs) {
+ if (clk_enable(info->i2sprop.i2s_clk))
+ {
+ err = PTR_ERR(info->i2sprop.i2s_clk);
+ return err;
+ }
+ if (info->i2sprop.i2s_sync_clk) {
+ if (clk_enable(info->i2sprop.i2s_sync_clk))
+ {
+ err = PTR_ERR(info->i2sprop.i2s_sync_clk);
+ I2S_DEBUG_PRINT("i2s enable i2s_sync_clk failed \n");
+ return err;
+ }
+ clk_set_rate(info->i2sprop.i2s_sync_clk,info->i2sprop.clk_rate);
+ }
+ if (info->i2sprop.audio_clk) {
+ if (clk_enable(info->i2sprop.audio_clk))
+ {
+ err = PTR_ERR(info->i2sprop.audio_clk);
+ I2S_DEBUG_PRINT("i2s enable audio_clk failed \n");
+ return err;
+ }
+ }
+ if (info->i2sprop.audio2x_clk) {
+ if (clk_enable(info->i2sprop.audio2x_clk))
+ {
+ err = PTR_ERR(info->i2sprop.audio2x_clk);
+ I2S_DEBUG_PRINT("i2s enable audio2x_clk failed \n");
+ return err;
+ }
+ clk_set_rate(info->i2sprop.audio2x_clk,info->i2sprop.clk_rate);
+ }
+ }
info->clk_refs++;
}
@@ -980,7 +1011,8 @@ int i2s_clock_disable(int ifc, int fifo_mode)
info->clk_refs--;
if (info->clk_refs == 0) {
-
+ clk_disable(info->i2sprop.i2s_clk);
+ info->clk_refs = 0;
if (info->i2sprop.i2s_sync_clk) {
clk_disable(info->i2sprop.i2s_sync_clk);
}
@@ -1015,9 +1047,16 @@ int i2s_clock_set_parent(int ifc, int mode, int parent)
struct clk *pll_a_out0_clk = clk_get_sys(NULL, "pll_a_out0");
struct i2s_controller_info *info = &i2s_cont_info[ifc];
- if (info->i2sprop.i2s_clk)
+ if (info->i2sprop.i2s_clk &&
+ (info->i2sprop.master_mode == true)) {
clk_set_parent(info->i2sprop.i2s_clk,
pll_a_out0_clk);
+ } else {
+ clk_set_parent(info->i2sprop.audio_clk,
+ info->i2sprop.i2s_sync_clk);
+ clk_set_parent(info->i2sprop.i2s_clk,
+ info->i2sprop.audio2x_clk);
+ }
return 0;
}