diff options
author | Vinod G <vinodg@nvidia.com> | 2011-08-26 13:48:05 -0700 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2011-08-29 08:29:55 -0700 |
commit | 906ff91f864f5c2422abe3a70cb6c149e4afd67d (patch) | |
tree | d3c831958f26ac9512d550eec6367c8c649b7a29 | |
parent | 6af4f86efa54a050cf3335dc8f400b72c24909b8 (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.c | 56 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_i2s.c | 16 |
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, |