summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/dam.c
diff options
context:
space:
mode:
authorRavindra Lokhande <rlokhande@nvidia.com>2011-07-18 16:28:17 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-07-19 16:31:27 -0700
commiteab72ed2f0ef189784e24209009c261022712460 (patch)
treeac8d31df40200591b8942ac5df47fd68112e3b4d /arch/arm/mach-tegra/dam.c
parent0d7cb9bfff778ac9af6bea32b0ea3a3e7b83c90c (diff)
arm: tegra: add voicecall support
add voicecall support in audio driver. DAM is used to upsample and down sample data received from and sent to baseband. Change-Id: Ib92919681b25bd89c1578d983ef3849d4d044065 Reviewed-on: http://git-master/r/41543 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/dam.c')
-rw-r--r--arch/arm/mach-tegra/dam.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/arch/arm/mach-tegra/dam.c b/arch/arm/mach-tegra/dam.c
index 0a1eb41dc961..47510409fd8c 100644
--- a/arch/arm/mach-tegra/dam.c
+++ b/arch/arm/mach-tegra/dam.c
@@ -127,12 +127,14 @@
/* FIXME: move this control to audio_manager later if needed */
struct dam_context {
int outsamplerate;
+ bool ch_alloc[DAM_NUM_INPUT_CHANNELS];
bool ch_inuse[DAM_NUM_INPUT_CHANNELS];
int ch_insamplerate[DAM_NUM_INPUT_CHANNELS];
int ctrlreg_cache[DAM_CTRL_REGINDEX];
- struct clk *dam_clk;
- int clk_refcnt;
+ struct clk *dam_clk;
+ int clk_refcnt;
int dma_ch[dam_ch_maxnum];
+ int in_use;
};
struct dam_context dam_cont_info[NR_DAM_IFC];
@@ -157,12 +159,11 @@ struct dam_src_step_table step_table[] = {
{ 44100, 8000, 441 },
{ 48000, 8000, 6 },
{ 44100, 16000, 441 },
- { 48000, 16000, 3 },
+ { 48000, 16000, 0 },
};
struct dam_module_context {
int refcnt;
- bool inuse[NR_DAM_IFC];
};
static struct dam_module_context *dam_info = NULL;
@@ -188,7 +189,7 @@ void dam_ch1_set_gain(int ifc,int gain);
static inline void dam_writel(int ifc, u32 val, u32 reg)
{
__raw_writel(val, dam_base[ifc] + reg);
- DAM_DEBUG_PRINT("dam write 0x%lx: %08x\n", dam_base[ifc] + reg, val);
+ DAM_DEBUG_PRINT("dam write 0x%p: %08x\n", dam_base[ifc] + reg, val);
}
static inline u32 dam_readl(int ifc, u32 reg)
@@ -234,7 +235,8 @@ void dam_enable(int ifc, int on, int chtype)
val = dam_readl(ifc, DAM_CTRL_0);
val &= ~DAM_CTRL_0_DAM_EN;
- val |= on ? DAM_CTRL_0_DAM_EN : 0;
+ val |= ((ch->ch_inuse[dam_ch_in0] || ch->ch_inuse[dam_ch_in1])) ?
+ DAM_CTRL_0_DAM_EN : 0;
dam_writel(ifc, val, DAM_CTRL_0);
}
@@ -488,9 +490,10 @@ void dam_restore_ctrl_registers(int ifc)
int dam_suspend(int ifc)
{
- if (dam_info->inuse[ifc] == true) {
- dam_save_ctrl_registers(ifc);
- }
+ struct dam_context *ch;
+ ch = &dam_cont_info[ifc];
+
+ dam_save_ctrl_registers(ifc);
dam_disable_clock(ifc);
@@ -499,12 +502,12 @@ int dam_suspend(int ifc)
int dam_resume(int ifc)
{
+ struct dam_context *ch;
+ ch = &dam_cont_info[ifc];
dam_enable_clock(ifc);
- if (dam_info->inuse[ifc] == true) {
- dam_restore_ctrl_registers(ifc);
- }
+ dam_restore_ctrl_registers(ifc);
return 0;
}
@@ -541,7 +544,8 @@ void dam_disable_clock(int ifc)
}
audio_switch_disable_clock();
- DAM_DEBUG_PRINT("%s clk cnt %d\n", __func__, ch->clk_refcnt);
+ DAM_DEBUG_PRINT("%s dev%d clk cnt %d\n", __func__,
+ ifc, ch->clk_refcnt);
}
int dam_enable_clock(int ifc)
@@ -564,7 +568,8 @@ int dam_enable_clock(int ifc)
ch->clk_refcnt++;
- DAM_DEBUG_PRINT(" %s clk cnt %d\n", __func__, ch->clk_refcnt);
+ DAM_DEBUG_PRINT("%s dev%d clk cnt %d\n", __func__,
+ ifc, ch->clk_refcnt);
return err;
fail_dam_clock:
@@ -583,6 +588,8 @@ int dam_set_acif(int ifc, int chtype, struct audio_cif *cifInfo)
reg_addr += DAM_AUDIOCIF_OUT_CTRL_0;
break;
case dam_ch_in0:
+ /*always Mono channel*/
+ cifInfo->client_channels = AUDIO_CHANNEL_1;
reg_addr += DAM_AUDIOCIF_CH0_CTRL_0;
break;
case dam_ch_in1:
@@ -599,29 +606,38 @@ int dam_set_acif(int ifc, int chtype, struct audio_cif *cifInfo)
return 0;
}
-int dam_get_controller(void)
+int dam_get_controller(int chtype)
{
int i = 0, err = 0;
+ struct dam_context *ch = NULL;
if (!dam_info)
return -ENOENT;
for (i = 0; i < NR_DAM_IFC; i++) {
- if (dam_info->inuse[i] == false) {
+ ch = &dam_cont_info[i];
+
+ if (ch->in_use == false) {
err = dam_enable_clock(i);
if (err) {
pr_err("unable to enable the dam channel\n");
return -ENOENT;
}
- dam_info->inuse[i] = true;
+ ch->in_use = true;
+ ch->ch_alloc[chtype] = true;
return i;
+ } else {
+ if (ch->ch_alloc[chtype] == false) {
+ ch->ch_alloc[chtype] = true;
+ return i;
+ }
}
}
return -ENOENT;
}
-int dam_free_controller(int ifc)
+int dam_free_controller(int ifc, int chtype)
{
struct dam_context *ch = NULL;
@@ -633,10 +649,16 @@ int dam_free_controller(int ifc)
if (!dam_info)
return -ENOENT;
- dam_disable_clock(ifc);
+ ch->ch_alloc[chtype] = false;
- if (ch->clk_refcnt == 0)
- dam_info->inuse[ifc] = false;
+ if (ch->ch_alloc[dam_ch_in0] == false &&
+ ch->ch_alloc[dam_ch_in1] == false) {
+
+ dam_disable_clock(ifc);
+
+ if (ch->clk_refcnt == 0)
+ ch->in_use = false;
+ }
return 0;
}
@@ -691,6 +713,7 @@ int dam_open(void)
for (i = 0; i < NR_DAM_IFC; i++) {
ch = &dam_cont_info[i];
+ memset(ch, 0, sizeof(struct dam_context));
ch->dam_clk = tegra_get_clock_by_name(damclk_info[i]);
if (!ch->dam_clk) {
pr_err("unable to get dam%d clock\n", i);