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 0 = Enable XRUN/jiffies debug messages
|
||||||
bit 1 = Show stack trace at XRUN / jiffies check
|
bit 1 = Show stack trace at XRUN / jiffies check
|
||||||
bit 2 = Enable additional 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
|
When the bit 0 is set, the driver will show the messages to
|
||||||
kernel log when an xrun is detected. The debug message is
|
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.
|
buggy) hardware that doesn't give smooth pointer updates.
|
||||||
This feature is enabled via the bit 2.
|
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
|
card*/pcm*/sub*/info
|
||||||
The general information of this PCM sub-stream.
|
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);
|
xrun(substream);
|
||||||
return -EPIPE;
|
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;
|
hw_base = runtime->hw_ptr_base;
|
||||||
new_hw_ptr = hw_base + pos;
|
new_hw_ptr = hw_base + pos;
|
||||||
hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size;
|
hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size;
|
||||||
@ -244,6 +256,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
|
|||||||
delta = new_hw_ptr - hw_ptr_interrupt;
|
delta = new_hw_ptr - hw_ptr_interrupt;
|
||||||
}
|
}
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
|
if (runtime->periods == 1 || new_hw_ptr < old_hw_ptr)
|
||||||
delta += runtime->buffer_size;
|
delta += runtime->buffer_size;
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
hw_ptr_error(substream,
|
hw_ptr_error(substream,
|
||||||
@ -251,11 +264,19 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
|
|||||||
"(stream=%i, pos=%ld, intr_ptr=%ld)\n",
|
"(stream=%i, pos=%ld, intr_ptr=%ld)\n",
|
||||||
substream->stream, (long)pos,
|
substream->stream, (long)pos,
|
||||||
(long)hw_ptr_interrupt);
|
(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 */
|
/* rebase to interrupt position */
|
||||||
hw_base = new_hw_ptr = hw_ptr_interrupt;
|
hw_base = new_hw_ptr = hw_ptr_interrupt;
|
||||||
/* align hw_base to buffer_size */
|
/* align hw_base to buffer_size */
|
||||||
hw_base -= hw_base % runtime->buffer_size;
|
hw_base -= hw_base % runtime->buffer_size;
|
||||||
delta = 0;
|
delta = 0;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
hw_base += runtime->buffer_size;
|
hw_base += runtime->buffer_size;
|
||||||
if (hw_base >= runtime->boundary)
|
if (hw_base >= runtime->boundary)
|
||||||
@ -344,6 +365,19 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
|
|||||||
xrun(substream);
|
xrun(substream);
|
||||||
return -EPIPE;
|
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;
|
hw_base = runtime->hw_ptr_base;
|
||||||
new_hw_ptr = hw_base + pos;
|
new_hw_ptr = hw_base + pos;
|
||||||
|
|
||||||
|
@ -242,13 +242,12 @@ static int get_amixer_rsc(struct amixer_mgr *mgr,
|
|||||||
|
|
||||||
/* Allocate mem for amixer resource */
|
/* Allocate mem for amixer resource */
|
||||||
amixer = kzalloc(sizeof(*amixer), GFP_KERNEL);
|
amixer = kzalloc(sizeof(*amixer), GFP_KERNEL);
|
||||||
if (NULL == amixer) {
|
if (!amixer)
|
||||||
err = -ENOMEM;
|
return -ENOMEM;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether there are sufficient
|
/* Check whether there are sufficient
|
||||||
* amixer resources to meet request. */
|
* amixer resources to meet request. */
|
||||||
|
err = 0;
|
||||||
spin_lock_irqsave(&mgr->mgr_lock, flags);
|
spin_lock_irqsave(&mgr->mgr_lock, flags);
|
||||||
for (i = 0; i < desc->msr; i++) {
|
for (i = 0; i < desc->msr; i++) {
|
||||||
err = mgr_get_resource(&mgr->mgr, 1, &idx);
|
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 */
|
/* Allocate mem for sum resource */
|
||||||
sum = kzalloc(sizeof(*sum), GFP_KERNEL);
|
sum = kzalloc(sizeof(*sum), GFP_KERNEL);
|
||||||
if (NULL == sum) {
|
if (!sum)
|
||||||
err = -ENOMEM;
|
return -ENOMEM;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether there are sufficient sum resources to meet request. */
|
/* Check whether there are sufficient sum resources to meet request. */
|
||||||
|
err = 0;
|
||||||
spin_lock_irqsave(&mgr->mgr_lock, flags);
|
spin_lock_irqsave(&mgr->mgr_lock, flags);
|
||||||
for (i = 0; i < desc->msr; i++) {
|
for (i = 0; i < desc->msr; i++) {
|
||||||
err = mgr_get_resource(&mgr->mgr, 1, &idx);
|
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 */
|
/* Allocate mem for SRCIMP resource */
|
||||||
srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL);
|
srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL);
|
||||||
if (NULL == srcimp) {
|
if (!srcimp)
|
||||||
err = -ENOMEM;
|
return -ENOMEM;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether there are sufficient SRCIMP resources. */
|
/* Check whether there are sufficient SRCIMP resources. */
|
||||||
|
err = 0;
|
||||||
spin_lock_irqsave(&mgr->mgr_lock, flags);
|
spin_lock_irqsave(&mgr->mgr_lock, flags);
|
||||||
for (i = 0; i < desc->msr; i++) {
|
for (i = 0; i < desc->msr; i++) {
|
||||||
err = mgr_get_resource(&mgr->mgr, 1, &idx);
|
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] &&
|
int mute = (!ucontrol->value.integer.value[0] &&
|
||||||
!ucontrol->value.integer.value[1]);
|
!ucontrol->value.integer.value[1]);
|
||||||
/* toggle GPIO1 according to the mute state */
|
/* 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);
|
mute ? 0x02 : 0x0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -10631,6 +10631,18 @@ static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
|
|||||||
alc262_lenovo_3000_automute(codec, 1);
|
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) */
|
/* bind hp and internal speaker mute (with plug check) */
|
||||||
static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
|
static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
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;
|
long *valp = ucontrol->value.integer.value;
|
||||||
int change;
|
int change;
|
||||||
|
|
||||||
change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
|
change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
|
||||||
HDA_AMP_MUTE,
|
change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
|
||||||
valp ? 0 : HDA_AMP_MUTE);
|
|
||||||
change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
|
|
||||||
HDA_AMP_MUTE,
|
|
||||||
valp ? 0 : HDA_AMP_MUTE);
|
|
||||||
|
|
||||||
if (change)
|
if (change)
|
||||||
alc262_fujitsu_automute(codec, 0);
|
alc262_fujitsu_automute(codec, 0);
|
||||||
return change;
|
return change;
|
||||||
@ -10680,10 +10687,7 @@ static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
|
|||||||
long *valp = ucontrol->value.integer.value;
|
long *valp = ucontrol->value.integer.value;
|
||||||
int change;
|
int change;
|
||||||
|
|
||||||
change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
|
change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
|
||||||
HDA_AMP_MUTE,
|
|
||||||
valp ? 0 : HDA_AMP_MUTE);
|
|
||||||
|
|
||||||
if (change)
|
if (change)
|
||||||
alc262_lenovo_3000_automute(codec, 0);
|
alc262_lenovo_3000_automute(codec, 0);
|
||||||
return change;
|
return change;
|
||||||
@ -11854,12 +11858,7 @@ static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
|
|||||||
long *valp = ucontrol->value.integer.value;
|
long *valp = ucontrol->value.integer.value;
|
||||||
int change;
|
int change;
|
||||||
|
|
||||||
change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
|
change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
|
||||||
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);
|
|
||||||
if (change)
|
if (change)
|
||||||
alc268_acer_automute(codec, 0);
|
alc268_acer_automute(codec, 0);
|
||||||
return change;
|
return change;
|
||||||
|
@ -4066,7 +4066,7 @@ static int stac92xx_add_jack(struct hda_codec *codec,
|
|||||||
jack->nid = nid;
|
jack->nid = nid;
|
||||||
jack->type = type;
|
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_type(def_conf),
|
||||||
snd_hda_get_jack_connectivity(def_conf),
|
snd_hda_get_jack_connectivity(def_conf),
|
||||||
snd_hda_get_jack_location(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;
|
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;
|
u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
|
||||||
u16 pll_d = 1;
|
u16 pll_d = 1;
|
||||||
|
u8 reg;
|
||||||
|
|
||||||
/* select data word length */
|
/* select data word length */
|
||||||
data =
|
data =
|
||||||
@ -801,8 +802,16 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
|
|||||||
pll_q &= 0xf;
|
pll_q &= 0xf;
|
||||||
aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
|
aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
|
||||||
aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
|
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);
|
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
|
/* Route Left DAC to left channel input and
|
||||||
* right DAC to right channel input */
|
* right DAC to right channel input */
|
||||||
|
@ -48,6 +48,7 @@ config SND_USB_CAIAQ
|
|||||||
* Native Instruments Kore Controller
|
* Native Instruments Kore Controller
|
||||||
* Native Instruments Kore Controller 2
|
* Native Instruments Kore Controller 2
|
||||||
* Native Instruments Audio Kontrol 1
|
* Native Instruments Audio Kontrol 1
|
||||||
|
* Native Instruments Audio 2 DJ
|
||||||
* Native Instruments Audio 4 DJ
|
* Native Instruments Audio 4 DJ
|
||||||
* Native Instruments Audio 8 DJ
|
* Native Instruments Audio 8 DJ
|
||||||
* Native Instruments Guitar Rig Session I/O
|
* 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):
|
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_GUITARRIGMOBILE):
|
||||||
dev->samplerates |= SNDRV_PCM_RATE_192000;
|
dev->samplerates |= SNDRV_PCM_RATE_192000;
|
||||||
/* fall thru */
|
/* 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_AUDIO4DJ):
|
||||||
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
|
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
|
||||||
dev->samplerates |= SNDRV_PCM_RATE_88200;
|
dev->samplerates |= SNDRV_PCM_RATE_88200;
|
||||||
|
@ -35,13 +35,14 @@
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
|
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_LICENSE("GPL");
|
||||||
MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
|
MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
|
||||||
"{Native Instruments, RigKontrol3},"
|
"{Native Instruments, RigKontrol3},"
|
||||||
"{Native Instruments, Kore Controller},"
|
"{Native Instruments, Kore Controller},"
|
||||||
"{Native Instruments, Kore Controller 2},"
|
"{Native Instruments, Kore Controller 2},"
|
||||||
"{Native Instruments, Audio Kontrol 1},"
|
"{Native Instruments, Audio Kontrol 1},"
|
||||||
|
"{Native Instruments, Audio 2 DJ},"
|
||||||
"{Native Instruments, Audio 4 DJ},"
|
"{Native Instruments, Audio 4 DJ},"
|
||||||
"{Native Instruments, Audio 8 DJ},"
|
"{Native Instruments, Audio 8 DJ},"
|
||||||
"{Native Instruments, Session I/O},"
|
"{Native Instruments, Session I/O},"
|
||||||
@ -121,6 +122,11 @@ static struct usb_device_id snd_usb_id_table[] = {
|
|||||||
.idVendor = USB_VID_NATIVEINSTRUMENTS,
|
.idVendor = USB_VID_NATIVEINSTRUMENTS,
|
||||||
.idProduct = USB_PID_AUDIO4DJ
|
.idProduct = USB_PID_AUDIO4DJ
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
|
||||||
|
.idVendor = USB_VID_NATIVEINSTRUMENTS,
|
||||||
|
.idProduct = USB_PID_AUDIO2DJ
|
||||||
|
},
|
||||||
{ /* terminator */ }
|
{ /* terminator */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#define USB_PID_KORECONTROLLER 0x4711
|
#define USB_PID_KORECONTROLLER 0x4711
|
||||||
#define USB_PID_KORECONTROLLER2 0x4712
|
#define USB_PID_KORECONTROLLER2 0x4712
|
||||||
#define USB_PID_AK1 0x0815
|
#define USB_PID_AK1 0x0815
|
||||||
|
#define USB_PID_AUDIO2DJ 0x041c
|
||||||
#define USB_PID_AUDIO4DJ 0x0839
|
#define USB_PID_AUDIO4DJ 0x0839
|
||||||
#define USB_PID_AUDIO8DJ 0x1978
|
#define USB_PID_AUDIO8DJ 0x1978
|
||||||
#define USB_PID_SESSIONIO 0x1915
|
#define USB_PID_SESSIONIO 0x1915
|
||||||
|
@ -990,20 +990,35 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* quirk for UDA1321/N101 */
|
/* volume control quirks */
|
||||||
/* 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 */
|
|
||||||
switch (state->chip->usb_id) {
|
switch (state->chip->usb_id) {
|
||||||
case USB_ID(0x0471, 0x0101):
|
case USB_ID(0x0471, 0x0101):
|
||||||
case USB_ID(0x0471, 0x0104):
|
case USB_ID(0x0471, 0x0104):
|
||||||
case USB_ID(0x0471, 0x0105):
|
case USB_ID(0x0471, 0x0105):
|
||||||
case USB_ID(0x0672, 0x1041):
|
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") &&
|
if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
|
||||||
cval->min == -15616) {
|
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;
|
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",
|
snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user