diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/tegra/tegra_generic_codec.c | 2 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_pcm.c | 68 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_soc.h | 10 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_soc_max98088.c | 132 |
4 files changed, 54 insertions, 158 deletions
diff --git a/sound/soc/tegra/tegra_generic_codec.c b/sound/soc/tegra/tegra_generic_codec.c index 758f046516fd..142a1fba8dec 100644 --- a/sound/soc/tegra/tegra_generic_codec.c +++ b/sound/soc/tegra/tegra_generic_codec.c @@ -100,7 +100,7 @@ struct snd_soc_dai tegra_generic_codec_dai[] = { TEGRA_CREATE_GENERIC_CODEC_DAI("tegra_generic_spdif_codec", 0, 2, 2, TEGRA_SAMPLE_RATES), TEGRA_CREATE_GENERIC_CODEC_DAI("tegra_generic_BB_codec", - 1, 1, 1, TEGRA_VOICE_SAMPLE_RATES), + 1, 1, 2, TEGRA_SAMPLE_RATES), TEGRA_CREATE_GENERIC_CODEC_DAI("tegra_generic_BT_codec", 2, 1, 1, TEGRA_VOICE_SAMPLE_RATES), TEGRA_CREATE_GENERIC_CODEC_DAI("tegra_generic_tdm_codec", diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 860267e6ebe6..66465aa22d56 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -67,7 +67,7 @@ static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd) struct snd_dma_buffer *buf = &substream->dma_buffer; struct tegra_dma_req *dma_req; - 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) { @@ -161,14 +161,14 @@ static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_PUSH: prtd->dma_state = STATE_ABORT; - tegra_dma_cancel(prtd->dma_chan); if (prtd->dma_chan) { + tegra_dma_cancel(prtd->dma_chan); for (i = 0; i < DMA_REQ_QCOUNT; i++) tegra_dma_dequeue_req(prtd->dma_chan, &prtd->dma_req[i]); - prtd->dma_head_idx = 0; - prtd->dma_tail_idx = DMA_REQ_QCOUNT - 1; + prtd->dma_head_idx = 0; + prtd->dma_tail_idx = DMA_REQ_QCOUNT - 1; } #ifdef CONFIG_HAS_WAKELOCK wake_unlock(&prtd->wake_lock); @@ -186,10 +186,10 @@ 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, + if (prtd->dma_chan) + size += bytes_to_frames(runtime, tegra_dma_get_transfer_count( prtd->dma_chan, &prtd->dma_req[prtd->dma_head_idx], @@ -205,13 +205,15 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct tegra_runtime_data *prtd = 0; struct tegra_i2s_info *info = cpu_dai->private_data; - int i, ret=0; + int i, ret = 0; int dma_mode; + int need_dma_ch = 0; - pr_debug("%s: Device %d, Stream %s, substream_name %s\n", __func__, \ - substream->pcm->device, \ - (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)?"Playback": \ - "Capture", substream->name); + pr_debug("%s: cpu_dai %s, codec_dai %s, Device %d, Stream %s\n", + __func__, cpu_dai->name, rtd->dai->codec_dai->name, + substream->pcm->device, + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + "Playback" : "Capture"); /* Ensure period size is multiple of minimum DMA step size */ ret = snd_pcm_hw_constraint_step(runtime, 0, @@ -240,7 +242,7 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) prtd->dma_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, @@ -248,27 +250,30 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) dma_complete_callback, prtd); } - } - else - { + need_dma_ch = 1; + } else if (strstr(cpu_dai->name, "tegra-i2s")) { for (i = 0; i < DMA_REQ_QCOUNT; i++) { setup_i2s_dma_request(substream, &prtd->dma_req[i], dma_complete_callback, prtd); } + need_dma_ch = 1; } - dma_mode = info->pdata->tdm_enable ? TEGRA_DMA_MODE_CONTINUOUS_DOUBLE : - TEGRA_DMA_MODE_CONTINUOUS_SINGLE; + if (need_dma_ch) { + if (info && info->pdata->tdm_enable) + dma_mode = TEGRA_DMA_MODE_CONTINUOUS_DOUBLE; + else + dma_mode = TEGRA_DMA_MODE_CONTINUOUS_SINGLE; - prtd->dma_chan = tegra_dma_allocate_channel( - dma_mode, "pcm"); - if (prtd->dma_chan == NULL) { - pr_err("%s: could not allocate DMA channel for PCM:\n", + prtd->dma_chan = tegra_dma_allocate_channel(dma_mode, "pcm"); + if (prtd->dma_chan == NULL) { + pr_err("%s: could not allocate DMA channel for PCM:\n", __func__); - ret = -ENOMEM; - goto fail; + ret = -ENOMEM; + goto fail; + } } #ifdef CONFIG_HAS_WAKELOCK @@ -281,11 +286,11 @@ static int tegra_pcm_open(struct snd_pcm_substream *substream) #endif /* Set HW params now that initialization is complete */ - if (!info->pdata->tdm_enable) - snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware); - else + if (info && info->pdata->tdm_enable) snd_soc_set_runtime_hwparams(substream, - &tegra_pcm_tdm_hardware); + &tegra_pcm_tdm_hardware); + else + snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware); goto end; @@ -296,6 +301,7 @@ fail: if (prtd->dma_chan) { tegra_dma_flush(prtd->dma_chan); tegra_dma_free_channel(prtd->dma_chan); + prtd->dma_chan = NULL; } kfree(prtd); } @@ -312,6 +318,12 @@ static int tegra_pcm_close(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + pr_debug("%s: cpu_dai %s, codec_dai %s, Device %d, Stream %s\n", + __func__, cpu_dai->name, rtd->dai->codec_dai->name, + substream->pcm->device, + (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + "Playback" : "Capture"); + if (!prtd) { printk(KERN_ERR "tegra_pcm_close called with prtd == NULL\n"); return 0; diff --git a/sound/soc/tegra/tegra_soc.h b/sound/soc/tegra/tegra_soc.h index a2ff63f3d511..b9e72a66c1aa 100644 --- a/sound/soc/tegra/tegra_soc.h +++ b/sound/soc/tegra/tegra_soc.h @@ -78,13 +78,13 @@ #define TEGRA_SAMPLE_RATES (SNDRV_PCM_RATE_8000_96000) #define TEGRA_VOICE_SAMPLE_RATES SNDRV_PCM_RATE_8000 -#define DMA_STEP_SIZE_MIN 8 -#define DMA_REQ_QCOUNT 2 +#define DMA_STEP_SIZE_MIN 8 +#define DMA_REQ_QCOUNT 2 #define TEGRA_AUDIO_OFF 0x0 #define TEGRA_HEADPHONE 0x1 #define TEGRA_LINEOUT 0x2 -#define TEGRA_SPK 0x4 +#define TEGRA_SPK 0x4 #define TEGRA_EAR_SPK 0x8 #define TEGRA_INT_MIC 0x10 #define TEGRA_EXT_MIC 0x20 @@ -92,6 +92,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_max98088.c b/sound/soc/tegra/tegra_soc_max98088.c index e5886893e45c..b19f709b1dc9 100644 --- a/sound/soc/tegra/tegra_soc_max98088.c +++ b/sound/soc/tegra/tegra_soc_max98088.c @@ -133,61 +133,6 @@ static int tegra_hifi_hw_params(struct snd_pcm_substream *substream, static int tegra_voice_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; - int dai_flag = 0, sys_clk; - int err; - enum dac_dap_data_format data_fmt; - struct audio_dev_property dev_prop; - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - if (tegra_das_is_port_master(tegra_audio_codec_type_bluetooth)) -#else - if(tegra_das_is_device_master(tegra_audio_codec_type_bluetooth)) -#endif - dai_flag |= SND_SOC_DAIFMT_CBM_CFM; - else - dai_flag |= SND_SOC_DAIFMT_CBS_CFS; - - -#ifdef CONFIG_ARCH_TEGRA_2x_SOC - data_fmt = tegra_das_get_codec_data_fmt(tegra_audio_codec_type_bluetooth); -#else - tegra_das_get_device_property(tegra_audio_codec_type_bluetooth,&dev_prop); - data_fmt = dev_prop.dac_dap_data_comm_format; -#endif - /* We are supporting DSP and I2s format for now */ - if (data_fmt & dac_dap_data_format_i2s) - dai_flag |= SND_SOC_DAIFMT_I2S; - else - dai_flag |= SND_SOC_DAIFMT_DSP_A; - - err = snd_soc_dai_set_fmt(codec_dai, dai_flag); - if (err < 0) { - pr_err("codec_dai fmt not set\n"); - return err; - } - - err = snd_soc_dai_set_fmt(cpu_dai, dai_flag); - if (err < 0) { - pr_err("cpu_dai fmt not set\n"); - return err; - } - - sys_clk = tegra_das_get_mclk_rate(); - err = snd_soc_dai_set_sysclk(codec_dai, 0, sys_clk, SND_SOC_CLOCK_IN); - if (err < 0) { - pr_err("cpu_dai clock not set\n"); - return err; - } - - err = snd_soc_dai_set_sysclk(cpu_dai, 0, sys_clk, SND_SOC_CLOCK_IN); - if (err < 0) { - pr_err("cpu_dai clock not set\n"); - return err; - } - return 0; } @@ -296,16 +241,6 @@ void tegra_ext_control(struct snd_soc_codec *codec, int new_con) else snd_soc_dapm_disable_pin(codec, "Int Mic"); - if (new_con & TEGRA_EXT_MIC) - snd_soc_dapm_enable_pin(codec, "Ext Mic"); - else - snd_soc_dapm_disable_pin(codec, "Ext Mic"); - - if (new_con & TEGRA_LINEIN) - snd_soc_dapm_enable_pin(codec, "Linein"); - else - snd_soc_dapm_disable_pin(codec, "Linein"); - if (new_con & TEGRA_HEADSET_OUT) snd_soc_dapm_enable_pin(codec, "Headset Out"); else @@ -323,67 +258,13 @@ void tegra_ext_control(struct snd_soc_codec *codec, int new_con) } -static int tegra_dapm_event_int_spk(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - if (tegra_wired_jack_conf.en_spkr != -1) { - if (tegra_wired_jack_conf.amp_reg) { - if (SND_SOC_DAPM_EVENT_ON(event) && - !tegra_wired_jack_conf.amp_reg_enabled) { - regulator_enable(tegra_wired_jack_conf.amp_reg); - tegra_wired_jack_conf.amp_reg_enabled = 1; - } else if (!SND_SOC_DAPM_EVENT_ON(event) && - tegra_wired_jack_conf.amp_reg_enabled) { - regulator_disable(tegra_wired_jack_conf.amp_reg); - tegra_wired_jack_conf.amp_reg_enabled = 0; - } - } - - gpio_set_value_cansleep(tegra_wired_jack_conf.en_spkr, - SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0); - } - - return 0; -} - -static int tegra_dapm_event_int_mic(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - if (tegra_wired_jack_conf.en_mic_int != -1) - gpio_set_value_cansleep(tegra_wired_jack_conf.en_mic_int, - SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0); - - if (tegra_wired_jack_conf.en_mic_ext != -1) - gpio_set_value_cansleep(tegra_wired_jack_conf.en_mic_ext, - SND_SOC_DAPM_EVENT_ON(event) ? 0 : 1); - - return 0; -} - -static int tegra_dapm_event_ext_mic(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - if (tegra_wired_jack_conf.en_mic_ext != -1) - gpio_set_value_cansleep(tegra_wired_jack_conf.en_mic_ext, - SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0); - - if (tegra_wired_jack_conf.en_mic_int != -1) - gpio_set_value_cansleep(tegra_wired_jack_conf.en_mic_int, - SND_SOC_DAPM_EVENT_ON(event) ? 0 : 1); - - return 0; -} - /*tegra machine dapm widgets */ static const struct snd_soc_dapm_widget tegra_dapm_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_HP("Headset Out", NULL), SND_SOC_DAPM_MIC("Headset In", NULL), - SND_SOC_DAPM_SPK("Lineout", NULL), SND_SOC_DAPM_SPK("Int Spk", NULL), - SND_SOC_DAPM_MIC("Ext Mic", NULL), SND_SOC_DAPM_MIC("Int Mic", NULL), - SND_SOC_DAPM_LINE("Linein", NULL), }; static const struct snd_soc_dapm_route audio_map[] = { @@ -513,15 +394,14 @@ static struct snd_soc_dai_link tegra_soc_dai[] = { &tegra_i2s_dai[1], &tegra_generic_codec_dai[2], &tegra_voice_ops), #else - /* - TEGRA_CREATE_SOC_DAI_LINK("Tegra-generic-0", "Tegra BB Voice", - &tegra_i2s_dai[1], &tegra_generic_codec_dai[1], - &tegra_voice_ops), - TEGRA_CREATE_SOC_DAI_LINK("Tegra-generic-1", "Tegra BT Voice", - &tegra_i2s_dai[2], &tegra_generic_codec_dai[2], + TEGRA_CREATE_SOC_DAI_LINK("Tegra-generic", "Tegra Generic Voice", + &tegra_i2s_dai[0], &max98088_dai[0], &tegra_voice_ops), - */ + TEGRA_CREATE_SOC_DAI_LINK("Tegra-voice-call", + "Tegra Voice Call Max HiFi", + &tegra_generic_codec_dai[1], + &max98088_dai[0], &tegra_voice_ops), #endif TEGRA_CREATE_SOC_DAI_LINK("Tegra-spdif", "Tegra Spdif", |