]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 27 Jul 2009 19:17:29 +0000 (12:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 27 Jul 2009 19:17:29 +0000 (12:17 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: hda - Fix mute control with some ALC262 models
  ALSA: snd_usb_caiaq: add support for Audio2DJ
  ALSA: pcm - Fix hwptr buffer-size overlap bug
  ALSA: pcm - Fix warnings in debug loggings
  ALSA: pcm - Add logging of hwptr updates and interrupt updates
  ASoC: tlv320aic3x: Enable PLL when not bypassed
  ALSA: hda - Restore GPIO1 properly at resume with AD1984A
  ALSA: ctxfi - Fix uninitialized error checks
  ALSA: hda - Use snprintf() to be safer
  ALSA: usb-audio - Volume control quirk for QuickCam E 3500
  ALSA: pcm - Fix regressions with VMware

13 files changed:
Documentation/sound/alsa/Procfile.txt
sound/core/pcm_lib.c
sound/pci/ctxfi/ctamixer.c
sound/pci/ctxfi/ctsrc.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/soc/codecs/tlv320aic3x.c
sound/usb/Kconfig
sound/usb/caiaq/audio.c
sound/usb/caiaq/device.c
sound/usb/caiaq/device.h
sound/usb/usbmixer.c

index 381908d8ca4231dde74f5c138b200782036760c1..719a819f8cc2c0e597e27b2b8bcd7caa17638ea2 100644 (file)
@@ -101,6 +101,8 @@ card*/pcm*/xrun_debug
          bit 0 = Enable XRUN/jiffies debug messages
          bit 1 = Show stack trace at XRUN / jiffies check
          bit 2 = Enable additional jiffies check
+         bit 3 = Log hwptr update at each period interrupt
+         bit 4 = Log hwptr update at each snd_pcm_update_hw_ptr()
 
        When the bit 0 is set, the driver will show the messages to
        kernel log when an xrun is detected.  The debug message is
@@ -117,6 +119,9 @@ card*/pcm*/xrun_debug
        buggy) hardware that doesn't give smooth pointer updates.
        This feature is enabled via the bit 2.
 
+       Bits 3 and 4 are for logging the hwptr records.  Note that
+       these will give flood of kernel messages.
+
 card*/pcm*/sub*/info
        The general information of this PCM sub-stream.
 
index 333e4dd29450c7e9e823ebec46b7af4bcb6c62fc..72cfd47af6b8b4196ba6a77d52002e3a52ab9e18 100644 (file)
@@ -233,6 +233,18 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
                xrun(substream);
                return -EPIPE;
        }
+       if (xrun_debug(substream, 8)) {
+               char name[16];
+               pcm_debug_name(substream, name, sizeof(name));
+               snd_printd("period_update: %s: pos=0x%x/0x%x/0x%x, "
+                          "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n",
+                          name, (unsigned int)pos,
+                          (unsigned int)runtime->period_size,
+                          (unsigned int)runtime->buffer_size,
+                          (unsigned long)old_hw_ptr,
+                          (unsigned long)runtime->hw_ptr_base,
+                          (unsigned long)runtime->hw_ptr_interrupt);
+       }
        hw_base = runtime->hw_ptr_base;
        new_hw_ptr = hw_base + pos;
        hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size;
@@ -244,18 +256,27 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
                        delta = new_hw_ptr - hw_ptr_interrupt;
        }
        if (delta < 0) {
-               delta += runtime->buffer_size;
+               if (runtime->periods == 1 || new_hw_ptr < old_hw_ptr)
+                       delta += runtime->buffer_size;
                if (delta < 0) {
                        hw_ptr_error(substream, 
                                     "Unexpected hw_pointer value "
                                     "(stream=%i, pos=%ld, intr_ptr=%ld)\n",
                                     substream->stream, (long)pos,
                                     (long)hw_ptr_interrupt);
+#if 1
+                       /* simply skipping the hwptr update seems more
+                        * robust in some cases, e.g. on VMware with
+                        * inaccurate timer source
+                        */
+                       return 0; /* skip this update */
+#else
                        /* rebase to interrupt position */
                        hw_base = new_hw_ptr = hw_ptr_interrupt;
                        /* align hw_base to buffer_size */
                        hw_base -= hw_base % runtime->buffer_size;
                        delta = 0;
+#endif
                } else {
                        hw_base += runtime->buffer_size;
                        if (hw_base >= runtime->boundary)
@@ -344,6 +365,19 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
                xrun(substream);
                return -EPIPE;
        }
+       if (xrun_debug(substream, 16)) {
+               char name[16];
+               pcm_debug_name(substream, name, sizeof(name));
+               snd_printd("hw_update: %s: pos=0x%x/0x%x/0x%x, "
+                          "hwptr=0x%lx, hw_base=0x%lx, hw_intr=0x%lx\n",
+                          name, (unsigned int)pos,
+                          (unsigned int)runtime->period_size,
+                          (unsigned int)runtime->buffer_size,
+                          (unsigned long)old_hw_ptr,
+                          (unsigned long)runtime->hw_ptr_base,
+                          (unsigned long)runtime->hw_ptr_interrupt);
+       }
+
        hw_base = runtime->hw_ptr_base;
        new_hw_ptr = hw_base + pos;
 
index a1db51b3ead82f198483e5b948619ee01d082516..a7f4a671f7b7c51daa84db20e5bb7f4b2336f293 100644 (file)
@@ -242,13 +242,12 @@ static int get_amixer_rsc(struct amixer_mgr *mgr,
 
        /* Allocate mem for amixer resource */
        amixer = kzalloc(sizeof(*amixer), GFP_KERNEL);
-       if (NULL == amixer) {
-               err = -ENOMEM;
-               return err;
-       }
+       if (!amixer)
+               return -ENOMEM;
 
        /* Check whether there are sufficient
         * amixer resources to meet request. */
+       err = 0;
        spin_lock_irqsave(&mgr->mgr_lock, flags);
        for (i = 0; i < desc->msr; i++) {
                err = mgr_get_resource(&mgr->mgr, 1, &idx);
@@ -397,12 +396,11 @@ static int get_sum_rsc(struct sum_mgr *mgr,
 
        /* Allocate mem for sum resource */
        sum = kzalloc(sizeof(*sum), GFP_KERNEL);
-       if (NULL == sum) {
-               err = -ENOMEM;
-               return err;
-       }
+       if (!sum)
+               return -ENOMEM;
 
        /* Check whether there are sufficient sum resources to meet request. */
+       err = 0;
        spin_lock_irqsave(&mgr->mgr_lock, flags);
        for (i = 0; i < desc->msr; i++) {
                err = mgr_get_resource(&mgr->mgr, 1, &idx);
index e1c145d8b702944472abe2a6bcd309a98a16bd90..df43a5cd3938beeb880d564ae3652639b5369770 100644 (file)
@@ -724,12 +724,11 @@ static int get_srcimp_rsc(struct srcimp_mgr *mgr,
 
        /* Allocate mem for SRCIMP resource */
        srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL);
-       if (NULL == srcimp) {
-               err = -ENOMEM;
-               return err;
-       }
+       if (!srcimp)
+               return -ENOMEM;
 
        /* Check whether there are sufficient SRCIMP resources. */
+       err = 0;
        spin_lock_irqsave(&mgr->mgr_lock, flags);
        for (i = 0; i < desc->msr; i++) {
                err = mgr_get_resource(&mgr->mgr, 1, &idx);
index be7d25fa7f35a3e164cf858aa7f5c4b67afd9ac6..3da85caf8af1318c3a3124606e57545d66f1a8ae 100644 (file)
@@ -3754,7 +3754,7 @@ static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
        int mute = (!ucontrol->value.integer.value[0] &&
                    !ucontrol->value.integer.value[1]);
        /* toggle GPIO1 according to the mute state */
-       snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
+       snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
                            mute ? 0x02 : 0x0);
        return ret;
 }
index 7e99763ca527209ad3243e3b0f75228aeb440fce..8c8b273116fbcc71bbe241bd6f9b63c69fbcd2ef 100644 (file)
@@ -10631,6 +10631,18 @@ static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
        alc262_lenovo_3000_automute(codec, 1);
 }
 
+static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
+                                 int dir, int idx, long *valp)
+{
+       int i, change = 0;
+
+       for (i = 0; i < 2; i++, valp++)
+               change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
+                                                  HDA_AMP_MUTE,
+                                                  *valp ? 0 : HDA_AMP_MUTE);
+       return change;
+}
+
 /* bind hp and internal speaker mute (with plug check) */
 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
                                         struct snd_ctl_elem_value *ucontrol)
@@ -10639,13 +10651,8 @@ static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
        long *valp = ucontrol->value.integer.value;
        int change;
 
-       change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
-                                                HDA_AMP_MUTE,
-                                                valp ? 0 : HDA_AMP_MUTE);
-       change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
-                                                HDA_AMP_MUTE,
-                                                valp ? 0 : HDA_AMP_MUTE);
-
+       change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
+       change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
        if (change)
                alc262_fujitsu_automute(codec, 0);
        return change;
@@ -10680,10 +10687,7 @@ static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
        long *valp = ucontrol->value.integer.value;
        int change;
 
-       change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
-                                                HDA_AMP_MUTE,
-                                                valp ? 0 : HDA_AMP_MUTE);
-
+       change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
        if (change)
                alc262_lenovo_3000_automute(codec, 0);
        return change;
@@ -11854,12 +11858,7 @@ static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
        long *valp = ucontrol->value.integer.value;
        int change;
 
-       change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
-                                         HDA_AMP_MUTE,
-                                         valp[0] ? 0 : HDA_AMP_MUTE);
-       change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
-                                          HDA_AMP_MUTE,
-                                          valp[1] ? 0 : HDA_AMP_MUTE);
+       change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
        if (change)
                alc268_acer_automute(codec, 0);
        return change;
index da7f9f65c04781ab0577cf62af8a05a006909126..512f3b9b9a459e27450efad9cb8c875823a99496 100644 (file)
@@ -4066,7 +4066,7 @@ static int stac92xx_add_jack(struct hda_codec *codec,
        jack->nid = nid;
        jack->type = type;
 
-       sprintf(name, "%s at %s %s Jack",
+       snprintf(name, sizeof(name), "%s at %s %s Jack",
                snd_hda_get_jack_type(def_conf),
                snd_hda_get_jack_connectivity(def_conf),
                snd_hda_get_jack_location(def_conf));
index ab099f482487b7e642d0f3d1372e6001673b3d27..cb0d1bf34b5723b9933ffc023430100b0594511d 100644 (file)
@@ -767,6 +767,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
        int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
        u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
        u16 pll_d = 1;
+       u8 reg;
 
        /* select data word length */
        data =
@@ -801,8 +802,16 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
                pll_q &= 0xf;
                aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
                aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
-       } else
+               /* disable PLL if it is bypassed */
+               reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
+               aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg & ~PLL_ENABLE);
+
+       } else {
                aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
+               /* enable PLL when it is used */
+               reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
+               aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE);
+       }
 
        /* Route Left DAC to left channel input and
         * right DAC to right channel input */
index 523aec188ccf64efa2de3aae90f8550eee77e3aa..73525c048e7f60d7613eef093f850c6d204215e4 100644 (file)
@@ -48,6 +48,7 @@ config SND_USB_CAIAQ
            * Native Instruments Kore Controller
            * Native Instruments Kore Controller 2
            * Native Instruments Audio Kontrol 1
+           * Native Instruments Audio 2 DJ
            * Native Instruments Audio 4 DJ
            * Native Instruments Audio 8 DJ
            * Native Instruments Guitar Rig Session I/O
index 8f9b60c5d74c9714e13c58a8bf4590b9e727951d..121af0644fd9bc901fbbc62cb676738e9049e0c7 100644 (file)
@@ -646,6 +646,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev)
        case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE):
                dev->samplerates |= SNDRV_PCM_RATE_192000;
                /* fall thru */
+       case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO2DJ):
        case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ):
        case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
                dev->samplerates |= SNDRV_PCM_RATE_88200;
index de38108f0b283ab4653693cbe9ac77698de299a1..83e6c1312d47c47ef1cc32eabab5b411d9dfa6b3 100644 (file)
 #include "input.h"
 
 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("caiaq USB audio, version 1.3.18");
+MODULE_DESCRIPTION("caiaq USB audio, version 1.3.19");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
                         "{Native Instruments, RigKontrol3},"
                         "{Native Instruments, Kore Controller},"
                         "{Native Instruments, Kore Controller 2},"
                         "{Native Instruments, Audio Kontrol 1},"
+                        "{Native Instruments, Audio 2 DJ},"
                         "{Native Instruments, Audio 4 DJ},"
                         "{Native Instruments, Audio 8 DJ},"
                         "{Native Instruments, Session I/O},"
@@ -121,6 +122,11 @@ static struct usb_device_id snd_usb_id_table[] = {
                .idVendor =     USB_VID_NATIVEINSTRUMENTS,
                .idProduct =    USB_PID_AUDIO4DJ
        },
+       {
+               .match_flags =  USB_DEVICE_ID_MATCH_DEVICE,
+               .idVendor =     USB_VID_NATIVEINSTRUMENTS,
+               .idProduct =    USB_PID_AUDIO2DJ
+       },
        { /* terminator */ }
 };
 
index ece73514854e2f302ab88da1d1a857d3f43ee3ec..44e3edf88befab4ce60071a3d9b9da72bd9a727e 100644 (file)
@@ -10,6 +10,7 @@
 #define USB_PID_KORECONTROLLER 0x4711
 #define USB_PID_KORECONTROLLER2        0x4712
 #define USB_PID_AK1            0x0815
+#define USB_PID_AUDIO2DJ       0x041c
 #define USB_PID_AUDIO4DJ       0x0839
 #define USB_PID_AUDIO8DJ       0x1978
 #define USB_PID_SESSIONIO      0x1915
index 4bd3a7a0edc100c2dd6007a98f8247b9084b8969..ec9cdf986928cfd1ce1847b18e111fdb71552fba 100644 (file)
@@ -990,20 +990,35 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
                break;
        }
 
-       /* quirk for UDA1321/N101 */
-       /* note that detection between firmware 2.1.1.7 (N101) and later 2.1.1.21 */
-       /* is not very clear from datasheets */
-       /* I hope that the min value is -15360 for newer firmware --jk */
+       /* volume control quirks */
        switch (state->chip->usb_id) {
        case USB_ID(0x0471, 0x0101):
        case USB_ID(0x0471, 0x0104):
        case USB_ID(0x0471, 0x0105):
        case USB_ID(0x0672, 0x1041):
+       /* quirk for UDA1321/N101.
+        * note that detection between firmware 2.1.1.7 (N101)
+        * and later 2.1.1.21 is not very clear from datasheets.
+        * I hope that the min value is -15360 for newer firmware --jk
+        */
                if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
                    cval->min == -15616) {
-                       snd_printk(KERN_INFO "using volume control quirk for the UDA1321/N101 chip\n");
+                       snd_printk(KERN_INFO
+                                "set volume quirk for UDA1321/N101 chip\n");
                        cval->max = -256;
                }
+               break;
+
+       case USB_ID(0x046d, 0x09a4):
+               if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
+                       snd_printk(KERN_INFO
+                               "set volume quirk for QuickCam E3500\n");
+                       cval->min = 6080;
+                       cval->max = 8768;
+                       cval->res = 192;
+               }
+               break;
+
        }
 
        snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",