summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSumit Bhattacharya <sumitb@nvidia.com>2011-05-25 11:55:34 +0530
committerManish Tuteja <mtuteja@nvidia.com>2011-06-21 05:54:13 -0700
commit6e7e86e0decb77c7537da44121e20f44beb9b38e (patch)
tree66a659e426a381718ebcbdadbbfc062e2a2eb9ba
parent88982e06ac4d0b91828542ec9eaabf6e2c9a03e0 (diff)
ASOC: alsa: Add WM8753 voice call routing support
Adding two new dai-links to WM8753 soc layer for voice call and BT voice call. Voice-call dai-link will link between WM8753 voice codec and generic BT codec interface while BT voice-call dai-link will link generic BT codec interface and generic BB codec interface. Also adding error checks in tegra_pcm to handle pcm device related operations on a dummy cpu-dai. Bug 814490 Change-Id: I047171af18432d5932e7e1919d73ac3d483d8f80 Reviewed-on: http://git-master/r/37395 Tested-by: Sumit Bhattacharya <sumitb@nvidia.com> Reviewed-by: Scott Peterson <speterson@nvidia.com>
-rw-r--r--sound/soc/tegra/tegra_generic_codec.c29
-rw-r--r--sound/soc/tegra/tegra_pcm.c34
-rw-r--r--sound/soc/tegra/tegra_soc.h4
-rw-r--r--sound/soc/tegra/tegra_soc_wm8753.c57
-rw-r--r--sound/soc/tegra/tegra_soc_wm8903.c4
5 files changed, 97 insertions, 31 deletions
diff --git a/sound/soc/tegra/tegra_generic_codec.c b/sound/soc/tegra/tegra_generic_codec.c
index ad8209648de8..61db317fd587 100644
--- a/sound/soc/tegra/tegra_generic_codec.c
+++ b/sound/soc/tegra/tegra_generic_codec.c
@@ -75,9 +75,9 @@ static struct snd_soc_dai_ops tegra_generic_codec_stub_ops = {
};
struct snd_soc_dai tegra_generic_codec_dai[] = {
- {
- .name = "tegra_generic_voice_codec",
- .id = 0,
+ [TEGRA_BT_CODEC_ID] = {
+ .name = "tegra_generic_bt_voice_codec",
+ .id = TEGRA_BT_CODEC_ID,
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -94,9 +94,28 @@ struct snd_soc_dai tegra_generic_codec_dai[] = {
},
.ops = &tegra_generic_codec_stub_ops,
},
- {
+ [TEGRA_BB_CODEC_ID] = {
+ .name = "tegra_generic_bb_voice_codec",
+ .id = TEGRA_BB_CODEC_ID,
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 1,
+ .channels_max = 1,
+ .rates = TEGRA_VOICE_SAMPLE_RATES,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ },
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 1,
+ .rates = TEGRA_VOICE_SAMPLE_RATES,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ },
+ .ops = &tegra_generic_codec_stub_ops,
+ },
+ [TEGRA_SPDIF_CODEC_ID] = {
.name = "tegra_generic_spdif_codec",
- .id = 1,
+ .id = TEGRA_SPDIF_CODEC_ID,
.playback = {
.stream_name = "Playback",
.channels_min = 2,
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 83314f23de53..ab618755619f 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -29,7 +29,7 @@ static void tegra_pcm_play(struct tegra_runtime_data *prtd)
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dma_buffer *buf = &substream->dma_buffer;
- if (runtime->dma_addr) {
+ if (runtime->dma_addr && prtd->dma_chan) {
prtd->size = frames_to_bytes(runtime, runtime->period_size);
if (prtd->dma_state != STATE_ABORT) {
prtd->dma_reqid_tail = (prtd->dma_reqid_tail + 1) % DMA_REQ_QCOUNT;
@@ -54,7 +54,7 @@ static void tegra_pcm_capture(struct tegra_runtime_data *prtd)
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dma_buffer *buf = &substream->dma_buffer;
- if (runtime->dma_addr) {
+ if (runtime->dma_addr && prtd->dma_chan) {
prtd->size = frames_to_bytes(runtime, runtime->period_size);
if (prtd->dma_state != STATE_ABORT) {
prtd->dma_reqid_tail = (prtd->dma_reqid_tail + 1) % DMA_REQ_QCOUNT;
@@ -191,11 +191,11 @@ static snd_pcm_uframes_t tegra_pcm_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct tegra_runtime_data *prtd = runtime->private_data;
- int size;
+ int size = prtd->period_index * runtime->period_size;
- size = (prtd->period_index * runtime->period_size) +
- bytes_to_frames(runtime,
- tegra_dma_get_transfer_count(
+ if (prtd->dma_chan)
+ size += bytes_to_frames(runtime,
+ tegra_dma_get_transfer_count(
prtd->dma_chan,
&prtd->dma_req[prtd->dma_reqid_head],
false));
@@ -238,7 +238,7 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
prtd->state = STATE_INVALID;
- if (strcmp(cpu_dai->name, "tegra-spdif") == 0)
+ if (!strcmp(cpu_dai->name, "tegra-spdif"))
{
for (i = 0; i < DMA_REQ_QCOUNT; i++) {
setup_spdif_dma_request(substream,
@@ -247,7 +247,8 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
prtd);
}
}
- else
+ else if (!strcmp(cpu_dai->name, "tegra-i2s-1") ||
+ !strcmp(cpu_dai->name, "tegra-i2s-2"))
{
for (i = 0; i < DMA_REQ_QCOUNT; i++) {
setup_i2s_dma_request(substream,
@@ -257,12 +258,17 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream)
}
}
- prtd->dma_chan = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS_DOUBLE);
- if (IS_ERR(prtd->dma_chan)) {
- pr_err("%s: could not allocate DMA channel for I2S: %ld\n",
- __func__, PTR_ERR(prtd->dma_chan));
- ret = PTR_ERR(prtd->dma_chan);
- goto fail;
+ if (!strcmp(cpu_dai->name, "tegra-spdif") ||
+ !strcmp(cpu_dai->name, "tegra-i2s-1") ||
+ !strcmp(cpu_dai->name, "tegra-i2s-2")) {
+ prtd->dma_chan = tegra_dma_allocate_channel(
+ TEGRA_DMA_MODE_CONTINUOUS_DOUBLE);
+ if (IS_ERR(prtd->dma_chan)) {
+ pr_err("%s: could not allocate DMA channel: %ld\n",
+ __func__, PTR_ERR(prtd->dma_chan));
+ ret = PTR_ERR(prtd->dma_chan);
+ goto fail;
+ }
}
/* Set HW params now that initialization is complete */
diff --git a/sound/soc/tegra/tegra_soc.h b/sound/soc/tegra/tegra_soc.h
index 58e12fb872ab..a1dd3076f4ed 100644
--- a/sound/soc/tegra/tegra_soc.h
+++ b/sound/soc/tegra/tegra_soc.h
@@ -91,6 +91,10 @@
#define TEGRA_HEADSET_OUT 0x80
#define TEGRA_HEADSET_IN 0x100
+#define TEGRA_BT_CODEC_ID 0
+#define TEGRA_BB_CODEC_ID 1
+#define TEGRA_SPDIF_CODEC_ID 2
+
struct tegra_dma_channel;
struct tegra_runtime_data {
diff --git a/sound/soc/tegra/tegra_soc_wm8753.c b/sound/soc/tegra/tegra_soc_wm8753.c
index b8abf99dd87b..4e9c3881b4e0 100644
--- a/sound/soc/tegra/tegra_soc_wm8753.c
+++ b/sound/soc/tegra/tegra_soc_wm8753.c
@@ -323,12 +323,33 @@ static int tegra_voice_hw_params(struct snd_pcm_substream *substream,
int dai_flag = 0, sys_clk;
int err;
- if (tegra_das_is_port_master(tegra_audio_codec_type_bluetooth))
- dai_flag |= SND_SOC_DAIFMT_CBM_CFM;
- else
- dai_flag |= SND_SOC_DAIFMT_CBS_CFS;
-
- data_fmt = tegra_das_get_codec_data_fmt(tegra_audio_codec_type_bluetooth);
+ if (!strcmp(rtd->dai->stream_name, "Tegra BT Voice Call")) {
+ if (tegra_das_is_port_master(tegra_audio_codec_type_bluetooth))
+ dai_flag |= SND_SOC_DAIFMT_CBM_CFM;
+ else
+ dai_flag |= SND_SOC_DAIFMT_CBS_CFS;
+
+ data_fmt = tegra_das_get_codec_data_fmt
+ (tegra_audio_codec_type_bluetooth);
+ }
+ else if (!strcmp(rtd->dai->stream_name, "Tegra Voice Call")) {
+ if (tegra_das_is_port_master(tegra_audio_codec_type_voice))
+ dai_flag |= SND_SOC_DAIFMT_CBM_CFM;
+ else
+ dai_flag |= SND_SOC_DAIFMT_CBS_CFS;
+
+ data_fmt = tegra_das_get_codec_data_fmt
+ (tegra_audio_codec_type_baseband);
+ }
+ else {/* Tegra BT-SCO Voice */
+ if (tegra_das_is_port_master(tegra_audio_codec_type_bluetooth))
+ dai_flag |= SND_SOC_DAIFMT_CBM_CFM;
+ else
+ dai_flag |= SND_SOC_DAIFMT_CBS_CFS;
+
+ data_fmt = tegra_das_get_codec_data_fmt
+ (tegra_audio_codec_type_bluetooth);
+ }
/* We are supporting DSP and I2s format for now */
if (data_fmt & dac_dap_data_format_dsp)
@@ -703,10 +724,10 @@ static struct snd_soc_dai_link tegra_soc_dai[] = {
.ops = &tegra_hifi_ops,
},
{
- .name = "Tegra-generic",
- .stream_name = "Tegra Generic Voice",
+ .name = "Tegra-Voice",
+ .stream_name = "Tegra BT-SCO Voice",
.cpu_dai = &tegra_i2s_dai[1],
- .codec_dai = &tegra_generic_codec_dai[0],
+ .codec_dai = &tegra_generic_codec_dai[TEGRA_BT_CODEC_ID],
.init = tegra_codec_init,
.ops = &tegra_voice_ops,
},
@@ -714,10 +735,26 @@ static struct snd_soc_dai_link tegra_soc_dai[] = {
.name = "Tegra-spdif",
.stream_name = "Tegra Spdif",
.cpu_dai = &tegra_spdif_dai,
- .codec_dai = &tegra_generic_codec_dai[1],
+ .codec_dai = &tegra_generic_codec_dai[TEGRA_SPDIF_CODEC_ID],
.init = tegra_codec_init,
.ops = &tegra_spdif_ops,
},
+ {
+ .name = "Tegra-voice-call",
+ .stream_name = "Tegra Voice Call",
+ .cpu_dai = &tegra_generic_codec_dai[TEGRA_BB_CODEC_ID],
+ .codec_dai = &wm8753_dai[WM8753_DAI_VOICE],
+ .init = tegra_codec_init,
+ .ops = &tegra_voice_ops,
+ },
+ {
+ .name = "Tegra-bt-voice-call",
+ .stream_name = "Tegra BT Voice Call",
+ .cpu_dai = &tegra_generic_codec_dai[TEGRA_BB_CODEC_ID],
+ .codec_dai = &tegra_generic_codec_dai[TEGRA_BT_CODEC_ID],
+ .init = tegra_codec_init,
+ .ops = &tegra_voice_ops,
+ },
};
static struct tegra_audio_data audio_data = {
diff --git a/sound/soc/tegra/tegra_soc_wm8903.c b/sound/soc/tegra/tegra_soc_wm8903.c
index 1c3ed544ddd5..d97f825c51b1 100644
--- a/sound/soc/tegra/tegra_soc_wm8903.c
+++ b/sound/soc/tegra/tegra_soc_wm8903.c
@@ -555,7 +555,7 @@ static struct snd_soc_dai_link tegra_soc_dai[] = {
.name = "Tegra-generic",
.stream_name = "Tegra Generic Voice",
.cpu_dai = &tegra_i2s_dai[1],
- .codec_dai = &tegra_generic_codec_dai[0],
+ .codec_dai = &tegra_generic_codec_dai[TEGRA_BT_CODEC_ID],
.init = tegra_codec_init,
.ops = &tegra_voice_ops,
},
@@ -563,7 +563,7 @@ static struct snd_soc_dai_link tegra_soc_dai[] = {
.name = "Tegra-spdif",
.stream_name = "Tegra Spdif",
.cpu_dai = &tegra_spdif_dai,
- .codec_dai = &tegra_generic_codec_dai[1],
+ .codec_dai = &tegra_generic_codec_dai[TEGRA_SPDIF_CODEC_ID],
.init = tegra_codec_init,
.ops = &tegra_spdif_ops,
},