summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinod G <vinodg@nvidia.com>2011-08-26 13:48:05 -0700
committerRohan Somvanshi <rsomvanshi@nvidia.com>2011-08-29 08:29:55 -0700
commit906ff91f864f5c2422abe3a70cb6c149e4afd67d (patch)
treed3c831958f26ac9512d550eec6367c8c649b7a29
parent6af4f86efa54a050cf3335dc8f400b72c24909b8 (diff)
arm: tegra: Fix i2s mono recording
bug 864482 Fix the acif setting based on stream format change Added support of i2s mono recording to set acif properly. Change-Id: Ia1cb93e9f606064da48293411b861df6914e7e9c Reviewed-on: http://git-master/r/49515 Reviewed-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com> Tested-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com> Reviewed-by: Scott Peterson <speterson@nvidia.com> Reviewed-by: Harry Hong <hhong@nvidia.com> Tested-by: Harry Hong <hhong@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/audio_manager.c56
-rw-r--r--arch/arm/mach-tegra/tegra3_i2s.c16
2 files changed, 48 insertions, 24 deletions
diff --git a/arch/arm/mach-tegra/audio_manager.c b/arch/arm/mach-tegra/audio_manager.c
index a0cbe11dbd2c..0cdff90c968d 100644
--- a/arch/arm/mach-tegra/audio_manager.c
+++ b/arch/arm/mach-tegra/audio_manager.c
@@ -381,6 +381,29 @@ int tegra_das_get_device_property(enum tegra_audio_codec_type codec_type,
}
EXPORT_SYMBOL_GPL(tegra_das_get_device_property);
+static int set_channel_acif(struct am_ch_info *ch, aud_dev_info* devinfo)
+{
+ ch->inacif.audio_channels = ch->sfmt.channels;
+ ch->inacif.client_channels = ch->sfmt.channels;
+ ch->inacif.audio_bits = ch->sfmt.bitsize;
+ ch->inacif.client_bits = ch->sfmt.bitsize;
+ if (devinfo->fifo_mode == AUDIO_TX_MODE) {
+ /* playback involves dam */
+ if (ch->damch[dam_ch_in1] >= 0) {
+ dam_set_acif(ch->damch[dam_ch_in1],
+ dam_ch_out, &ch->inacif);
+ dam_set_acif(ch->damch[dam_ch_in1],
+ dam_ch_in1, &ch->inacif);
+ }
+ }
+ if (devinfo->dev_type == AUDIO_I2S_DEVICE)
+ i2s_set_acif(devinfo->dev_id, devinfo->fifo_mode, &ch->inacif);
+ else if (devinfo->dev_type == AUDIO_SPDIF_DEVICE)
+ spdif_set_acif(devinfo->dev_id,
+ devinfo->fifo_mode, (void *)&ch->inacif);
+ return 0;
+}
+
int default_record_connection(aud_dev_info *devinfo)
{
struct am_dev_fns *am_fn = &init_am_dev_fns[devinfo->dev_type];
@@ -389,10 +412,12 @@ int default_record_connection(aud_dev_info *devinfo)
}
-int default_playback_connection(struct am_ch_info *ch, int ifc, int fifo_mode)
+int default_playback_connection(struct am_ch_info *ch, aud_dev_info *devinfo)
{
/* get unused dam channel first */
int damch = -1;
+ int fifo_mode = devinfo->fifo_mode;
+
AM_DEBUG_PRINT("%s++\n", __func__);
damch = dam_get_controller(dam_ch_in1);
@@ -422,13 +447,7 @@ int default_playback_connection(struct am_ch_info *ch, int ifc, int fifo_mode)
audio_switch_set_rx_port(ch->ahubrx_index, ch->ahubtx_index);
- ch->inacif.audio_channels = ch->sfmt.channels;
- ch->inacif.client_channels = ch->sfmt.channels;
- ch->inacif.audio_bits = ch->sfmt.bitsize;
- ch->inacif.client_bits = ch->sfmt.bitsize;
-
- dam_set_acif(damch, dam_ch_out, &ch->inacif);
- dam_set_acif(damch, dam_ch_in1, &ch->inacif);
+ set_channel_acif(ch, devinfo);
/* set unity gain to damch1 */
dam_set_gain(damch, dam_ch_in1, LINEAR_UNITY_GAIN);
@@ -443,7 +462,6 @@ conn_fail:
return -ENOENT;
}
-
int free_dam_connection(aud_dev_info *devinfo)
{
int damch = 0;
@@ -533,23 +551,17 @@ int am_get_dma_requestor(aud_dev_info* devinfo)
ch->ahubtx_index = ahubindex;
if (fifo_mode == AUDIO_TX_MODE) {
- err = default_playback_connection(ch,
- dev_id, fifo_mode);
+
+ err = default_playback_connection(ch, devinfo);
if (err)
goto fail_conn;
- if (devinfo->dev_type == AUDIO_I2S_DEVICE) {
+ if (devinfo->dev_type == AUDIO_I2S_DEVICE)
i2s_set_dma_channel(dev_id,
- fifo_mode, (ch->dmach[fifo_mode] - 1));
- i2s_set_acif(dev_id, fifo_mode,
- &ch->inacif);
- } else if (devinfo->dev_type
- == AUDIO_SPDIF_DEVICE) {
+ fifo_mode, (ch->dmach[fifo_mode] - 1));
+ else if (devinfo->dev_type == AUDIO_SPDIF_DEVICE)
spdif_set_dma_channel(dev_id,
- fifo_mode, (ch->dmach[fifo_mode] - 1));
- spdif_set_acif(dev_id,
- fifo_mode, (void *)&ch->inacif);
- }
+ fifo_mode, (ch->dmach[fifo_mode] - 1));
} else {
struct am_dev_fns *am_fn =
&init_am_dev_fns[devinfo->dev_type];
@@ -710,6 +722,8 @@ int am_set_stream_format(aud_dev_info* devinfo, am_stream_format_info *format)
ch->sfmt.bitsize = get_spdif_bit_size(format->bitsize);
}
+ set_channel_acif(ch, devinfo);
+
AM_DEBUG_PRINT("%s--\n", __func__);
return 0;
}
diff --git a/arch/arm/mach-tegra/tegra3_i2s.c b/arch/arm/mach-tegra/tegra3_i2s.c
index 98fc661b2311..1bdfc5cd05d7 100644
--- a/arch/arm/mach-tegra/tegra3_i2s.c
+++ b/arch/arm/mach-tegra/tegra3_i2s.c
@@ -325,7 +325,7 @@ int i2s_set_bit_code(int ifc, unsigned int bitcode)
int i2s_set_bit_format(int ifc, unsigned fmt)
{
u32 val;
-
+ struct i2s_controller_info *info = &i2s_cont_info[ifc];
check_i2s_ifc(ifc, -EINVAL);
if (fmt >= AUDIO_FRAME_FORMAT_UNKNOWN) {
@@ -348,6 +348,7 @@ int i2s_set_bit_format(int ifc, unsigned fmt)
i2s_set_slot_control(ifc, AUDIO_TX_MODE, 0, 0x1);
i2s_set_slot_control(ifc, AUDIO_RX_MODE, 0, 0x1);
}
+ info->i2sprop.audio_mode = fmt;
i2s_writel(ifc, val, I2S_CTRL_0);
return 0;
}
@@ -795,9 +796,18 @@ int i2s_set_acif(int ifc, int fifo_mode, struct audio_cif *cifInfo)
if (fifo_mode == AUDIO_TX_MODE)
audio_switch_set_acif((unsigned int)i2s_base[ifc] +
I2S_AUDIOCIF_I2STX_CTRL_0, cifInfo);
- else
+ else {
+ struct audio_cif reccifInfo;
+ memcpy(&reccifInfo, cifInfo, sizeof(struct audio_cif));
+
+ /* mono record support in i2s mode */
+ if ((info->i2sprop.audio_mode == AUDIO_FRAME_FORMAT_I2S) &&
+ (cifInfo->client_channels == AUDIO_CHANNEL_1))
+ reccifInfo.client_channels = AUDIO_CHANNEL_2;
+
audio_switch_set_acif((unsigned int)i2s_base[ifc] +
- I2S_AUDIOCIF_I2SRX_CTRL_0, cifInfo);
+ I2S_AUDIOCIF_I2SRX_CTRL_0, &reccifInfo);
+ }
if (apbif_ifc >= 0) {
apbif_set_pack_mode(apbif_ifc,