Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* '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
This commit is contained in:
commit
b54c383546
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -35,13 +35,14 @@
|
|||
#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 */ }
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue