Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 May 2009 15:47:53 +0000 (08:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 May 2009 15:47:53 +0000 (08:47 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: hda - Compaq Presario CQ60 patching for Conexant
  sound: usb-audio: make the MotU Fastlane work again
  ALSA: Enable PCM hw_ptr_jiffies check only in xrun_debug mode
  ALSA: Fix invalid jiffies check after pause

Documentation/sound/alsa/Procfile.txt
sound/core/pcm_lib.c
sound/core/pcm_native.c
sound/pci/hda/patch_conexant.c
sound/usb/usbaudio.c
sound/usb/usbaudio.h
sound/usb/usbmidi.c
sound/usb/usbquirks.h

index bba2dbb79d81c10d71bbc5b0879f6d3745d1543d..cfac20cf9e33fa150a6cf69f4e6d624e8116caa9 100644 (file)
@@ -104,6 +104,11 @@ card*/pcm*/xrun_debug
        When this value is greater than 1, the driver will show the
        stack trace additionally.  This may help the debugging.
 
+       Since 2.6.30, this option also enables the hwptr check using
+       jiffies.  This detects spontaneous invalid pointer callback
+       values, but can be lead to too much corrections for a (mostly
+       buggy) hardware that doesn't give smooth pointer updates.
+
 card*/pcm*/sub*/info
        The general information of this PCM sub-stream.
 
index a2a792c18c40e18412ac7e9e015d22c6035b2958..d659995ac3ac7be2f20e488c71b7b3fe405a879e 100644 (file)
@@ -249,6 +249,11 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
                        new_hw_ptr = hw_base + pos;
                }
        }
+
+       /* Do jiffies check only in xrun_debug mode */
+       if (!xrun_debug(substream))
+               goto no_jiffies_check;
+
        /* Skip the jiffies check for hardwares with BATCH flag.
         * Such hardware usually just increases the position at each IRQ,
         * thus it can't give any strange position.
@@ -336,7 +341,9 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
                        hw_base = 0;
                new_hw_ptr = hw_base + pos;
        }
-       if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
+       /* Do jiffies check only in xrun_debug mode */
+       if (xrun_debug(substream) &&
+           ((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
                hw_ptr_error(substream,
                             "hw_ptr skipping! "
                             "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
@@ -1478,7 +1485,6 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
                runtime->status->hw_ptr %= runtime->buffer_size;
        else
                runtime->status->hw_ptr = 0;
-       runtime->hw_ptr_jiffies = jiffies;
        snd_pcm_stream_unlock_irqrestore(substream, flags);
        return 0;
 }
index fc6f98e257df5e27d67a71a092eaa85fd6765ca1..b5da656d1ececa2e41b13dc55ea57b662bcc1b2e 100644 (file)
@@ -848,6 +848,7 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        snd_pcm_trigger_tstamp(substream);
+       runtime->hw_ptr_jiffies = jiffies;
        runtime->status->state = state;
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
            runtime->silence_size > 0)
@@ -961,6 +962,11 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
 {
        if (substream->runtime->trigger_master != substream)
                return 0;
+       /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
+        * a delta betwen the current jiffies, this gives a large enough
+        * delta, effectively to skip the check once.
+        */
+       substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
        return substream->ops->trigger(substream,
                                       push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH :
                                              SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
index 56ce19e68cb5838a24e675828bb990f296717a24..4fcbe21829abfe27104f7dabeed8fb801a301537 100644 (file)
@@ -1848,6 +1848,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
 
 static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
+       SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
        SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
                      CXT5051_LAPTOP),
        SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
index 823296d7d5781cbebb7d2ff4ab37cb8ecfefe74c..a6b88482637be9fbdc9b3c0fa56e2293a73ce0ab 100644 (file)
@@ -3347,7 +3347,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
                [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface,
                [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface,
                [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface,
-               [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface,
+               [QUIRK_MIDI_FASTLANE] = snd_usb_create_midi_interface,
                [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface,
                [QUIRK_MIDI_CME] = snd_usb_create_midi_interface,
                [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
index 36e4f7a29adc5548b05b5366fa0191f13466145b..8e7f78941ba6589407ac5074907ba6217734af60 100644 (file)
@@ -153,7 +153,7 @@ enum quirk_type {
        QUIRK_MIDI_YAMAHA,
        QUIRK_MIDI_MIDIMAN,
        QUIRK_MIDI_NOVATION,
-       QUIRK_MIDI_RAW,
+       QUIRK_MIDI_FASTLANE,
        QUIRK_MIDI_EMAGIC,
        QUIRK_MIDI_CME,
        QUIRK_MIDI_US122L,
index 26bad373fe65c012de152ac4f753076951390330..2fb35cc22a3030b687d1623546196cd6e8e2de27 100644 (file)
@@ -1778,8 +1778,18 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
                umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
                err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
                break;
-       case QUIRK_MIDI_RAW:
+       case QUIRK_MIDI_FASTLANE:
                umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
+               /*
+                * Interface 1 contains isochronous endpoints, but with the same
+                * numbers as in interface 0.  Since it is interface 1 that the
+                * USB core has most recently seen, these descriptors are now
+                * associated with the endpoint numbers.  This will foul up our
+                * attempts to submit bulk/interrupt URBs to the endpoints in
+                * interface 0, so we have to make sure that the USB core looks
+                * again at interface 0 by calling usb_set_interface() on it.
+                */
+               usb_set_interface(umidi->chip->dev, 0, 0);
                err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
                break;
        case QUIRK_MIDI_EMAGIC:
index 647ef502965179ec6f1eec15c042990a950aedf6..5d955aaad85f9a5d2ac96a990e97972a00e48905 100644 (file)
@@ -1868,7 +1868,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
                .data = & (const struct snd_usb_audio_quirk[]) {
                        {
                                .ifnum = 0,
-                               .type = QUIRK_MIDI_RAW
+                               .type = QUIRK_MIDI_FASTLANE
                        },
                        {
                                .ifnum = 1,