aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-04-05 01:27:45 -0400
committerTakashi Iwai <tiwai@suse.de>2013-04-05 01:33:32 -0400
commit21229613eff5b6241d27e2588d10588d5656d500 (patch)
tree8caab8a0c5f8c70c52f21d05fb811a7fdf85b0e9
parent1dc669fed61a4ec4270a89e5fb3535802cc45668 (diff)
ALSA: hda - Introduce get_delay codec PCM ops
Add a new codec PCM ops, get_delay(), to obtain the codec/stream- specific PCM delay count. When it's NULL, nothing changes. This new feature was requested for CA0132, which has significant delays in the path depending on the running DSP code. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_intel.c18
2 files changed, 17 insertions, 4 deletions
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 23ca1722aff1..c93f9021f452 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -757,6 +757,9 @@ struct hda_pcm_ops {
757 struct snd_pcm_substream *substream); 757 struct snd_pcm_substream *substream);
758 int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, 758 int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
759 struct snd_pcm_substream *substream); 759 struct snd_pcm_substream *substream);
760 unsigned int (*get_delay)(struct hda_pcm_stream *info,
761 struct hda_codec *codec,
762 struct snd_pcm_substream *substream);
760}; 763};
761 764
762/* PCM information for each substream */ 765/* PCM information for each substream */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 418bfc0eb0a3..735567e86f74 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2349,8 +2349,11 @@ static unsigned int azx_get_position(struct azx *chip,
2349 struct azx_dev *azx_dev, 2349 struct azx_dev *azx_dev,
2350 bool with_check) 2350 bool with_check)
2351{ 2351{
2352 struct snd_pcm_substream *substream = azx_dev->substream;
2353 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
2352 unsigned int pos; 2354 unsigned int pos;
2353 int stream = azx_dev->substream->stream; 2355 int stream = substream->stream;
2356 struct hda_pcm_stream *hinfo = apcm->hinfo[stream];
2354 int delay = 0; 2357 int delay = 0;
2355 2358
2356 switch (chip->position_fix[stream]) { 2359 switch (chip->position_fix[stream]) {
@@ -2381,7 +2384,7 @@ static unsigned int azx_get_position(struct azx *chip,
2381 pos = 0; 2384 pos = 0;
2382 2385
2383 /* calculate runtime delay from LPIB */ 2386 /* calculate runtime delay from LPIB */
2384 if (azx_dev->substream->runtime && 2387 if (substream->runtime &&
2385 chip->position_fix[stream] == POS_FIX_POSBUF && 2388 chip->position_fix[stream] == POS_FIX_POSBUF &&
2386 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) { 2389 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
2387 unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB); 2390 unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB);
@@ -2399,9 +2402,16 @@ static unsigned int azx_get_position(struct azx *chip,
2399 delay = 0; 2402 delay = 0;
2400 chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY; 2403 chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
2401 } 2404 }
2402 azx_dev->substream->runtime->delay = 2405 delay = bytes_to_frames(substream->runtime, delay);
2403 bytes_to_frames(azx_dev->substream->runtime, delay);
2404 } 2406 }
2407
2408 if (substream->runtime) {
2409 if (hinfo->ops.get_delay)
2410 delay += hinfo->ops.get_delay(hinfo, apcm->codec,
2411 substream);
2412 substream->runtime->delay = delay;
2413 }
2414
2405 trace_azx_get_position(chip, azx_dev, pos, delay); 2415 trace_azx_get_position(chip, azx_dev, pos, delay);
2406 return pos; 2416 return pos;
2407} 2417}