aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2013-04-04 16:55:09 -0400
committerTakashi Iwai <tiwai@suse.de>2013-04-05 01:34:21 -0400
commite8412ca4d62398a84d2e539a464313e948258339 (patch)
tree23bc2cdede07d04b863476563f9e22401da4c012 /sound/pci/hda
parent21229613eff5b6241d27e2588d10588d5656d500 (diff)
ALSA: hda/ca0132 - Update latency based on DSP state.
The DSP in the CA0132 codec adds a variable latency to audio depending on what processing is being done. Add a new patch op to return that latency for capture and playback streams. The latency is determined by which blocks are enabled and knowing how much latency is added by each block. Signed-off-by: Dylan Reid <dgreid@chromium.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_ca0132.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 12eb21aff557..90ff7a3f72df 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -131,6 +131,13 @@ enum {
131/* Effects values size*/ 131/* Effects values size*/
132#define EFFECT_VALS_MAX_COUNT 12 132#define EFFECT_VALS_MAX_COUNT 12
133 133
134/* Latency introduced by DSP blocks in milliseconds. */
135#define DSP_CAPTURE_INIT_LATENCY 0
136#define DSP_CRYSTAL_VOICE_LATENCY 124
137#define DSP_PLAYBACK_INIT_LATENCY 13
138#define DSP_PLAY_ENHANCEMENT_LATENCY 30
139#define DSP_SPEAKER_OUT_LATENCY 7
140
134struct ct_effect { 141struct ct_effect {
135 char name[44]; 142 char name[44];
136 hda_nid_t nid; 143 hda_nid_t nid;
@@ -2743,6 +2750,31 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2743 return 0; 2750 return 0;
2744} 2751}
2745 2752
2753static unsigned int ca0132_playback_pcm_delay(struct hda_pcm_stream *info,
2754 struct hda_codec *codec,
2755 struct snd_pcm_substream *substream)
2756{
2757 struct ca0132_spec *spec = codec->spec;
2758 unsigned int latency = DSP_PLAYBACK_INIT_LATENCY;
2759 struct snd_pcm_runtime *runtime = substream->runtime;
2760
2761 if (spec->dsp_state != DSP_DOWNLOADED)
2762 return 0;
2763
2764 /* Add latency if playback enhancement and either effect is enabled. */
2765 if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]) {
2766 if ((spec->effects_switch[SURROUND - EFFECT_START_NID]) ||
2767 (spec->effects_switch[DIALOG_PLUS - EFFECT_START_NID]))
2768 latency += DSP_PLAY_ENHANCEMENT_LATENCY;
2769 }
2770
2771 /* Applying Speaker EQ adds latency as well. */
2772 if (spec->cur_out_type == SPEAKER_OUT)
2773 latency += DSP_SPEAKER_OUT_LATENCY;
2774
2775 return (latency * runtime->rate) / 1000;
2776}
2777
2746/* 2778/*
2747 * Digital out 2779 * Digital out
2748 */ 2780 */
@@ -2811,6 +2843,23 @@ static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2811 return 0; 2843 return 0;
2812} 2844}
2813 2845
2846static unsigned int ca0132_capture_pcm_delay(struct hda_pcm_stream *info,
2847 struct hda_codec *codec,
2848 struct snd_pcm_substream *substream)
2849{
2850 struct ca0132_spec *spec = codec->spec;
2851 unsigned int latency = DSP_CAPTURE_INIT_LATENCY;
2852 struct snd_pcm_runtime *runtime = substream->runtime;
2853
2854 if (spec->dsp_state != DSP_DOWNLOADED)
2855 return 0;
2856
2857 if (spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID])
2858 latency += DSP_CRYSTAL_VOICE_LATENCY;
2859
2860 return (latency * runtime->rate) / 1000;
2861}
2862
2814/* 2863/*
2815 * Controls stuffs. 2864 * Controls stuffs.
2816 */ 2865 */
@@ -4002,7 +4051,8 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = {
4002 .channels_max = 6, 4051 .channels_max = 6,
4003 .ops = { 4052 .ops = {
4004 .prepare = ca0132_playback_pcm_prepare, 4053 .prepare = ca0132_playback_pcm_prepare,
4005 .cleanup = ca0132_playback_pcm_cleanup 4054 .cleanup = ca0132_playback_pcm_cleanup,
4055 .get_delay = ca0132_playback_pcm_delay,
4006 }, 4056 },
4007}; 4057};
4008 4058
@@ -4012,7 +4062,8 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = {
4012 .channels_max = 2, 4062 .channels_max = 2,
4013 .ops = { 4063 .ops = {
4014 .prepare = ca0132_capture_pcm_prepare, 4064 .prepare = ca0132_capture_pcm_prepare,
4015 .cleanup = ca0132_capture_pcm_cleanup 4065 .cleanup = ca0132_capture_pcm_cleanup,
4066 .get_delay = ca0132_capture_pcm_delay,
4016 }, 4067 },
4017}; 4068};
4018 4069