diff options
author | Sumit Bhattacharya <sumitb@nvidia.com> | 2011-05-25 11:55:34 +0530 |
---|---|---|
committer | Manish Tuteja <mtuteja@nvidia.com> | 2011-06-21 05:54:13 -0700 |
commit | 6e7e86e0decb77c7537da44121e20f44beb9b38e (patch) | |
tree | 66a659e426a381718ebcbdadbbfc062e2a2eb9ba | |
parent | 88982e06ac4d0b91828542ec9eaabf6e2c9a03e0 (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.c | 29 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_pcm.c | 34 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_soc.h | 4 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_soc_wm8753.c | 57 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_soc_wm8903.c | 4 |
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, }, |