diff options
author | Nikesh Oswal <noswal@nvidia.com> | 2011-11-08 14:02:09 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:50:08 -0800 |
commit | dd717632cb06bfef0ece42a7e45e8c5712943261 (patch) | |
tree | ae00a5ec53642d5a2d71cddc3317a90af28200ea /sound | |
parent | 68b8a632b617bba057b404b07d5e61bf4a0f6ade (diff) |
ASoC: tegra: configure default playback path for t30
with these changes from the machine driver we can configure
the default playback path to go through the dam or bypass
the dam
Bug: 862023
Change-Id: I0c51dd167c6822c4583240ece14211a82734ee2e
Signed-off-by: Nikesh Oswal <noswal@nvidia.com>
Reviewed-on: http://git-master/r/62891
Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
Rebase-Id: R7e756015a8436841c00295145ec45a23ec3ba8f7
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/tegra/tegra30_i2s.c | 45 | ||||
-rw-r--r-- | sound/soc/tegra/tegra30_i2s.h | 5 |
2 files changed, 35 insertions, 15 deletions
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index 27613f9d1ae9..3e002b69dbb3 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -43,10 +43,13 @@ #include <sound/soc.h> #include "tegra30_ahub.h" +#include "tegra30_dam.h" #include "tegra30_i2s.h" #define DRV_NAME "tegra30-i2s" +static struct tegra30_i2s i2scont[TEGRA30_NR_I2S_IFC]; + static inline void tegra30_i2s_write(struct tegra30_i2s *i2s, u32 reg, u32 val) { __raw_writel(val, i2s->regs + reg); @@ -162,14 +165,19 @@ int tegra30_i2s_startup(struct snd_pcm_substream *substream, tegra30_i2s_enable_clocks(i2s); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /* increment the playback ref count */ + i2s->playback_ref_count++; + ret = tegra30_ahub_allocate_tx_fifo(&i2s->txcif, &i2s->playback_dma_data.addr, &i2s->playback_dma_data.req_sel); i2s->playback_dma_data.wrap = 4; i2s->playback_dma_data.width = 32; - tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_I2S0_RX0 + - i2s->id, - i2s->txcif); + + if (!i2s->is_dam_used) + tegra30_ahub_set_rx_cif_source( + TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id, + i2s->txcif); } else { ret = tegra30_ahub_allocate_rx_fifo(&i2s->rxcif, &i2s->capture_dma_data.addr, @@ -193,9 +201,15 @@ void tegra30_i2s_shutdown(struct snd_pcm_substream *substream, tegra30_i2s_enable_clocks(i2s); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - tegra30_ahub_unset_rx_cif_source( - TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id); + if (i2s->playback_ref_count == 1) + tegra30_ahub_unset_rx_cif_source( + TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id); + + /* free the apbif dma channel*/ tegra30_ahub_free_tx_fifo(i2s->txcif); + + /* decrement the playback ref count */ + i2s->playback_ref_count--; } else { tegra30_ahub_unset_rx_cif_source(i2s->rxcif); tegra30_ahub_free_rx_fifo(i2s->rxcif); @@ -365,15 +379,21 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream, static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) { tegra30_ahub_enable_tx_fifo(i2s->txcif); - i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); + /* if this is the only user of i2s tx then enable it*/ + if (i2s->playback_ref_count == 1) { + i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; + tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); + } } static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) { tegra30_ahub_disable_tx_fifo(i2s->txcif); - i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; - tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); + /* if this is the only user of i2s tx then disable it*/ + if (i2s->playback_ref_count == 1) { + i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; + tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); + } } static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) @@ -479,12 +499,7 @@ static __devinit int tegra30_i2s_platform_probe(struct platform_device *pdev) return -EINVAL; } - i2s = kzalloc(sizeof(struct tegra30_i2s), GFP_KERNEL); - if (!i2s) { - dev_err(&pdev->dev, "Can't allocate tegra30_i2s\n"); - ret = -ENOMEM; - goto exit; - } + i2s = &i2scont[pdev->id]; dev_set_drvdata(&pdev->dev, i2s); i2s->id = pdev->id; diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h index b7835277a037..f5fe090f0100 100644 --- a/sound/soc/tegra/tegra30_i2s.h +++ b/sound/soc/tegra/tegra30_i2s.h @@ -228,6 +228,9 @@ #define TEGRA30_I2S_LCOEF_COEF_MASK_US 0xffff #define TEGRA30_I2S_LCOEF_COEF_MASK (TEGRA30_I2S_LCOEF_COEF_MASK_US << TEGRA30_I2S_LCOEF_COEF_SHIFT) +/* Number of i2s controllers*/ +#define TEGRA30_NR_I2S_IFC 5 + struct tegra30_i2s { int id; struct clk *clk_i2s; @@ -239,6 +242,8 @@ struct tegra30_i2s { struct dentry *debug; u32 reg_ctrl; u32 reg_ch_ctrl; + int playback_ref_count; + bool is_dam_used; }; #endif |