summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorNikesh Oswal <noswal@nvidia.com>2011-11-08 14:02:09 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:50:08 -0800
commitdd717632cb06bfef0ece42a7e45e8c5712943261 (patch)
treeae00a5ec53642d5a2d71cddc3317a90af28200ea /sound
parent68b8a632b617bba057b404b07d5e61bf4a0f6ade (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.c45
-rw-r--r--sound/soc/tegra/tegra30_i2s.h5
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