summaryrefslogtreecommitdiff
path: root/sound/pci/hda/hda_intel.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-03 20:10:23 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-03 20:10:23 +0400
commit9992ba72327fa0d8bdc9fb624e80f5cce338a711 (patch)
treee0bf31ae53cb19c44674df7e0d0343a26037ad34 /sound/pci/hda/hda_intel.c
parent00fdffb5131125dce0702bf61e24a806ec3aed80 (diff)
parent4ca231b2e6ed171107c5b21f9e92d1965fd6fd9e (diff)
downloadlinux-9992ba72327fa0d8bdc9fb624e80f5cce338a711.tar.xz
Merge tag 'sound-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "Mostly many small changes spread as seen in diffstat in sound/* directory by this update. A significant change in the subsystem level is the introduction of snd_soc_component, which will help more generic handling of SoC and off-SoC components. Also, snd_BUG_ON() macro is enabled unconditionally now due to its misuses, so people might hit kernel warnings (it's a good thing for us). - compress-offload: support for capture by Charles Keepax - HD-audio: codec delay support by Dylan Reid - HD-audio: improvements/fixes in generic parser: better headphone mic and headset mic support, jack_modes hint consolidation, proper beep attach/detachment, generalized power filter controls by David Henningsson, et al - HD-audio: Improved management of HDMI codec pins/converters - HD-audio: Better pin/DAC assignment for VIA codecs - HD-audio: Haswell HDMI workarounds - HD-audio: ALC268 codec support, a few new quirks for Chromebooks - USB: regression fixes: USB-MIDI autopm fix, the recent ISO latency fix by Clemens Ladisch - USB: support for DSD formats by Daniel Mack - USB: A few UAC2 device endian/cock fixes by Eldad Zack - USB: quirks for Emu 192kHz support, Novation Twitch DJ controller, Yamaha THRxx devices - HDSPM: updates for TCO controls by Adrian Knoth - ASoC: Add a snd_soc_component object type for generic handling of SoC and off-SoC components by Kuninori Morimoto, - dmaengine: a large set of cleanups and conversions by Lars-Peter Clausen - ASoC DAPM: performance optimizations from Ryo Tsutsui - ASoC DAPM: support for mixer control sharing by Stephen Warren - ASoC: multiplatform ARM cleanups from Arnd Bergmann - ASoC: new codec drivers for AK5385 and TAS5086 from Daniel Mack" * tag 'sound-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (315 commits) ALSA: usb-audio: caiaq: fix endianness bug in snd_usb_caiaq_maschine_dispatch ALSA: asihpi: add format support check in snd_card_asihpi_capture_formats ALSA: pcm_format_to_bits strong-typed conversion ALSA: compress: fix the states to check for allowing read ALSA: hda - Move Thinkpad X220 to use auto parser ALSA: USB: adjust for changed 3.8 USB API ALSA: usb - Avoid unnecessary sample rate changes on USB 2.0 clock sources sound: oss/dmabuf: use dma_map_single ALSA: ali5451: use mdelay instead of large udelay constants ALSA: hda - Add the support for ALC286 codec ALSA: usb-audio: USB quirk for Yamaha THR10C ALSA: usb-audio: USB quirk for Yamaha THR5A ALSA: usb-audio: USB quirk for Yamaha THR10 ALSA: usb-audio: Fix autopm error during probing ALSA: snd-usb: try harder to find USB_DT_CS_ENDPOINT ALSA: sound kconfig typo ALSA: emu10k1: Fix dock firmware loading ASoC: ux500: forward declare msp_i2s_platform_data ASoC: davinci-mcasp: Add Support BCLK-to-LRCLK ratio for TDM modes ASoC: davinci-pcm, davinci-mcasp: Clean up active_serializers ...
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r--sound/pci/hda/hda_intel.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index bcd40ee488e3..7b213d589ef6 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1889,6 +1889,26 @@ static void azx_timecounter_init(struct snd_pcm_substream *substream,
tc->cycle_last = last;
}
+static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream,
+ u64 nsec)
+{
+ struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
+ struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
+ u64 codec_frames, codec_nsecs;
+
+ if (!hinfo->ops.get_delay)
+ return nsec;
+
+ codec_frames = hinfo->ops.get_delay(hinfo, apcm->codec, substream);
+ codec_nsecs = div_u64(codec_frames * 1000000000LL,
+ substream->runtime->rate);
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ return nsec + codec_nsecs;
+
+ return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0;
+}
+
static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream,
struct timespec *ts)
{
@@ -1897,6 +1917,7 @@ static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream,
nsec = timecounter_read(&azx_dev->azx_tc);
nsec = div_u64(nsec, 3); /* can be optimized */
+ nsec = azx_adjust_codec_delay(substream, nsec);
*ts = ns_to_timespec(nsec);
@@ -2349,8 +2370,11 @@ static unsigned int azx_get_position(struct azx *chip,
struct azx_dev *azx_dev,
bool with_check)
{
+ struct snd_pcm_substream *substream = azx_dev->substream;
+ struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
unsigned int pos;
- int stream = azx_dev->substream->stream;
+ int stream = substream->stream;
+ struct hda_pcm_stream *hinfo = apcm->hinfo[stream];
int delay = 0;
switch (chip->position_fix[stream]) {
@@ -2381,7 +2405,7 @@ static unsigned int azx_get_position(struct azx *chip,
pos = 0;
/* calculate runtime delay from LPIB */
- if (azx_dev->substream->runtime &&
+ if (substream->runtime &&
chip->position_fix[stream] == POS_FIX_POSBUF &&
(chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB);
@@ -2399,9 +2423,16 @@ static unsigned int azx_get_position(struct azx *chip,
delay = 0;
chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
}
- azx_dev->substream->runtime->delay =
- bytes_to_frames(azx_dev->substream->runtime, delay);
+ delay = bytes_to_frames(substream->runtime, delay);
}
+
+ if (substream->runtime) {
+ if (hinfo->ops.get_delay)
+ delay += hinfo->ops.get_delay(hinfo, apcm->codec,
+ substream);
+ substream->runtime->delay = delay;
+ }
+
trace_azx_get_position(chip, azx_dev, pos, delay);
return pos;
}