summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorRavindra Lokhande <rlokhande@nvidia.com>2011-04-19 21:14:10 +0530
committerVarun Colbert <vcolbert@nvidia.com>2011-05-03 01:26:25 -0700
commite4053f8cd89cd522b2e111f9501ca1a2ebe91688 (patch)
tree7ec4693f5432621dcef175e71ef37e3e6c52ec0d /arch/arm/mach-tegra
parent66d8ee30496eaab51c8514d52760a8e2e3f90628 (diff)
tegra alsa: Audio BT SCO support
added support for audio BT sco usecase. For BT sco, i2s is programmed in pcm mode. Change-Id: Iffcfb707cd2c025b78b82e70ba35f89d47a21263 Reviewed-on: http://git-master/r/30042 Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com> Tested-by: Ravindra Lokhande <rlokhande@nvidia.com> Reviewed-by: Vinod Gopalakrishnakurup <vinodg@nvidia.com> Reviewed-by: Scott Peterson <speterson@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/audio_switch.c4
-rw-r--r--arch/arm/mach-tegra/board-cardhu.c24
-rw-r--r--arch/arm/mach-tegra/devices.c7
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_i2s.h3
-rw-r--r--arch/arm/mach-tegra/tegra2_i2s.c9
-rw-r--r--arch/arm/mach-tegra/tegra3_i2s.c25
6 files changed, 60 insertions, 12 deletions
diff --git a/arch/arm/mach-tegra/audio_switch.c b/arch/arm/mach-tegra/audio_switch.c
index 5356316b7452..761db91a5d6e 100644
--- a/arch/arm/mach-tegra/audio_switch.c
+++ b/arch/arm/mach-tegra/audio_switch.c
@@ -753,14 +753,14 @@ int audio_apbif_set_acif(int ifc, int fifo_mode, struct audio_cif *cifInfo)
APBIF_AUDIOCIF_TX0_CTRL_0, cifInfo);
/* FIXME: packed mode as default */
- apbif_set_pack_mode(ifc, AUDIO_TX_MODE, AUDIO_FIFO_PACK_16);
+ //apbif_set_pack_mode(ifc, AUDIO_TX_MODE, AUDIO_FIFO_PACK_16);
} else {
audio_switch_set_acif((unsigned int)ch->virt_base +
APBIF_AUDIOCIF_RX0_CTRL_0, cifInfo);
/* FIXME: packed mode as default */
- apbif_set_pack_mode(ifc, AUDIO_RX_MODE, AUDIO_FIFO_PACK_16);
+ //apbif_set_pack_mode(ifc, AUDIO_RX_MODE, AUDIO_FIFO_PACK_16);
}
return 0;
}
diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c
index dc0580f5a474..0037e9a7fcd0 100644
--- a/arch/arm/mach-tegra/board-cardhu.c
+++ b/arch/arm/mach-tegra/board-cardhu.c
@@ -225,6 +225,7 @@ static __initdata struct tegra_clk_init_table cardhu_clk_init_table[] = {
{ "pll_a_out0", NULL, 11289600, false},
{ "i2s1", "pll_a_out0", 11289600, false},
{ "i2s2", "pll_a_out0", 11289600, false},
+ { "i2s3", "pll_a_out0", 11289600, false},
{ "d_audio","pll_a_out0", 11289600, false},
{ NULL, NULL, 0, 0},
};
@@ -303,7 +304,7 @@ static struct tegra_i2c_platform_data cardhu_i2c5_platform_data = {
.bus_clk_rate = { 100000, 0 },
};
-static struct tegra_audio_platform_data tegra_audio_pdata[] = {
+static struct tegra_audio_platform_data tegra_i2s_pdata[] = {
[0] = {
.i2s_master = true,
.dma_on = true, /* use dma by default */
@@ -313,8 +314,19 @@ static struct tegra_audio_platform_data tegra_audio_pdata[] = {
.mode = AUDIO_FRAME_FORMAT_I2S,
.fifo_fmt = AUDIO_FIFO_PACK_16,
.bit_size = AUDIO_BIT_SIZE_16,
- .i2s_bus_width = 32,
- .dsp_bus_width = 16,
+ .i2s_bus_width = 32,
+ .dsp_bus_width = 16,
+ },
+ [1] = {
+ .i2s_master = true,
+ .dma_on = true, /* use dma by default */
+ .i2s_master_clk = 8000,
+ .dev_clk_rate = 1024000,
+ .mode = AUDIO_FRAME_FORMAT_DSP,
+ .fifo_fmt = AUDIO_FIFO_NOP,
+ .bit_size = AUDIO_BIT_SIZE_16,
+ .i2s_bus_width = 32,
+ .dsp_bus_width = 16,
},
};
@@ -393,7 +405,8 @@ static struct platform_device *cardhu_devices[] __initdata = {
&tegra_smmu_device,
#endif
&tegra_wdt_device,
- &tegra_audio_device,
+ &tegra_i2s_device1,
+ &tegra_i2s_device3,
&tegra_spdif_device,
&tegra_avp_device,
&tegra_camera,
@@ -535,7 +548,8 @@ static void __init tegra_cardhu_init(void)
cardhu_usb_init();
snprintf(serial, sizeof(serial), "%llx", tegra_chip_uid());
andusb_plat.serial_number = kstrdup(serial, GFP_KERNEL);
- tegra_audio_device.dev.platform_data = &tegra_audio_pdata[0];
+ tegra_i2s_device1.dev.platform_data = &tegra_i2s_pdata[0];
+ tegra_i2s_device3.dev.platform_data = &tegra_i2s_pdata[1];
tegra_spdif_device.dev.platform_data = &tegra_spdif_pdata;
platform_add_devices(cardhu_devices, ARRAY_SIZE(cardhu_devices));
cardhu_sdhci_init();
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
index 64cb1ab025d0..1f8b9455ac02 100644
--- a/arch/arm/mach-tegra/devices.c
+++ b/arch/arm/mach-tegra/devices.c
@@ -674,13 +674,18 @@ static struct resource audio_resource[] = {
}
};
-struct platform_device tegra_audio_device = {
+struct platform_device tegra_i2s_device1 = {
.name = "audio",
.id = 1,
.resource = audio_resource,
.num_resources = ARRAY_SIZE(audio_resource),
};
+struct platform_device tegra_i2s_device3 = {
+ .name = "audio",
+ .id = 3,
+};
+
/* FIXME : Temporarly adding - find the right solution */
static struct resource spdif_resource[] = {
diff --git a/arch/arm/mach-tegra/include/mach/tegra_i2s.h b/arch/arm/mach-tegra/include/mach/tegra_i2s.h
index 810ea5baa777..25cb32731103 100644
--- a/arch/arm/mach-tegra/include/mach/tegra_i2s.h
+++ b/arch/arm/mach-tegra/include/mach/tegra_i2s.h
@@ -43,6 +43,7 @@ struct tegra_i2s_property {
int bit_size; /* 8/12/16/20/24/28/32 */
int fifo_fmt; /* fifo format */
+ int channels; /* channels */
int sample_rate; /* Sample rate */
unsigned long clk_rate; /* clock rate */
@@ -92,9 +93,11 @@ struct clk *i2s_get_clock_by_name(const char *name);
void i2s_set_fifo_attention(int ifc, int buffersize, int fifo_mode);
int i2s_set_samplerate(int ifc, int samplerate);
+int i2s_set_channels(int ifc, int channels);
int i2s_clock_disable(int ifc);
int i2s_clock_enable(int ifc);
int i2s_close(int ifc);
int i2s_clock_rate(int ifc, int rate);
+
#endif /* __ARCH_ARM_MACH_TEGRA_I2S_H */
diff --git a/arch/arm/mach-tegra/tegra2_i2s.c b/arch/arm/mach-tegra/tegra2_i2s.c
index bc16ebf479fe..ba593203d8ab 100644
--- a/arch/arm/mach-tegra/tegra2_i2s.c
+++ b/arch/arm/mach-tegra/tegra2_i2s.c
@@ -207,6 +207,15 @@ int i2s_set_samplerate(int ifc, int samplerate)
return 0;
}
+int i2s_set_channels(int ifc, int channels)
+{
+ struct i2s_controller_info *info = &i2s_cont_info[ifc];
+
+ info->i2sprop.channels = channels;
+
+ return 0;
+}
+
void i2s_set_fifo_mode(int ifc, int fifo, int tx)
{
u32 val;
diff --git a/arch/arm/mach-tegra/tegra3_i2s.c b/arch/arm/mach-tegra/tegra3_i2s.c
index 70ecb15571fe..68c52ccadf5b 100644
--- a/arch/arm/mach-tegra/tegra3_i2s.c
+++ b/arch/arm/mach-tegra/tegra3_i2s.c
@@ -309,6 +309,11 @@ int i2s_set_bit_format(int ifc, unsigned fmt)
val |= I2S_CTRL_FRAME_FORMAT_LRCK;
} else { /*Dsp,Pcm,Tdm,Nw*/
val |= I2S_CTRL_FRAME_FORMAT_FSYNC;
+
+ i2s_set_fsync_width(ifc, 0);
+ i2s_set_edge_control(ifc, 1);
+ i2s_set_slot_control(ifc, AUDIO_TX_MODE, 0, 0x1);
+ i2s_set_slot_control(ifc, AUDIO_RX_MODE, 0, 0x1);
}
i2s_writel(ifc, val, I2S_CTRL_0);
@@ -389,6 +394,14 @@ int i2s_set_samplerate(int ifc, int samplerate)
return 0;
}
+int i2s_set_channels(int ifc, int channels)
+{
+ struct i2s_controller_info *info = &i2s_cont_info[ifc];
+
+ info->i2sprop.channels = channels;
+
+ return 0;
+}
/*
* I2s data offset
*/
@@ -728,14 +741,15 @@ static struct audio_cif audiocif;
int i2s_set_acif(int ifc, int fifo_mode, struct audio_cif *cifInfo)
{
struct audio_cif *tx_audio_cif = &audiocif;
+ struct i2s_controller_info *info = &i2s_cont_info[ifc];
/* set i2s audiocif */
/* setting base value for acif */
memset(tx_audio_cif, 0 , sizeof(struct audio_cif));
- tx_audio_cif->audio_channels = AUDIO_CHANNEL_2;
- tx_audio_cif->client_channels = AUDIO_CHANNEL_2;
- tx_audio_cif->audio_bits = AUDIO_BIT_SIZE_16;
- tx_audio_cif->client_bits = AUDIO_BIT_SIZE_16;
+ tx_audio_cif->audio_channels = info->i2sprop.channels;
+ tx_audio_cif->client_channels = info->i2sprop.channels;
+ tx_audio_cif->audio_bits = info->i2sprop.bit_size;
+ tx_audio_cif->client_bits = info->i2sprop.bit_size;
if (fifo_mode == AUDIO_TX_MODE)
audio_switch_set_acif((unsigned int)i2s_base[ifc] +
@@ -744,6 +758,9 @@ int i2s_set_acif(int ifc, int fifo_mode, struct audio_cif *cifInfo)
audio_switch_set_acif((unsigned int)i2s_base[ifc] +
I2S_AUDIOCIF_I2SRX_CTRL_0, tx_audio_cif);
+ apbif_set_pack_mode(i2s_get_apbif_channel(ifc, fifo_mode),
+ fifo_mode, info->i2sprop.fifo_fmt);
+
audio_apbif_set_acif(i2s_get_apbif_channel(ifc, fifo_mode),
fifo_mode, tx_audio_cif);