diff options
author | ScottPeterson <speterson@nvidia.com> | 2011-07-14 11:11:31 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-07-29 15:56:52 -0700 |
commit | a1f23b74282aa5dfdbdef7daabaafcb01b943907 (patch) | |
tree | b43cbda617d26c54c9895a51015f86626ab49c13 /arch/arm/mach-tegra/tegra3_i2s.c | |
parent | d922c50e51312d65797f8dc6f00375e87be46b29 (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.c | 49 |
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; } |