sound fixes for 4.0-rc4
This is a round of HD-audio fixes: there are a long-standing regression fix and a few more device/codec-specific quirks. In addition, a couple of FireWire regression fixes, a USB-audio quirk for Roland UA-22 and a sanity check in API for user-defined control elements. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJVApo5AAoJEGwxgFQ9KSmk938P/2DH0ndVhmYqlsmYwJ8K+quw VM5OmV17jM1AfLb1bEFDGzR/bmSgBxQEmJW1OtvEjyzhvprXHXlSphY8nt+VXPpi mkQVfq+AXP1U2SGFsYKxVG+1nHpT28jbvNHE7P5I2uDhKkglXZ07Zpeo9zfQef2U wIZ2cI0OKsUKcUAw+uDk4ZVr8RLuYRKhNSjp604DYcjgi7zCKuPItEKt96/+X8l/ BWZAt0heRB8QtzpJWnSMpt6cNKpjCCSKqhhoA6QfkSNIdDjhjeKF69AO9FKeTRm0 NsdYOXgtT5OoJgNQ6Emdg/Qq0FVap/KuSBl/jun3ufEIwTv8as9N+/syn+E5mcbD hAvmgzcToxEWcIlKS/zn5du4wYdbx8e6RsGKPswXco2O0iWNjH4tFads8BrACfE1 MbWqO5WIunU7woD2R0sN2mg4mS5C+nohGP28aZ1Xme0nSN3/oCuYnHDLK4h/X09O haa+9GZlexix+gdwl1lF8AEUoG7SljaQ/zYbQhzLvkmuRHW2COnB8kZQUaAOeccU Av4igbow50jxTdEtgrtCogowUvepeqX8+wxl79Ahu1gLohQKoKkxEgnjDaz31DZT Ph3yhfU3/DkZzYjMWLVM9v9qsduPbrOIt9dSwO/6IxuuTGRaN4Nvz3CLJpvu9534 BAA8xZui5elKl26n0x69 =FIie -----END PGP SIGNATURE----- Merge tag 'sound-4.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "This is a round of HD-audio fixes: there are a long-standing regression fix and a few more device/codec-specific quirks. In addition, a couple of FireWire regression fixes, a USB-audio quirk for Roland UA-22 and a sanity check in API for user-defined control elements" * tag 'sound-4.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda - Don't access stereo amps for mono channel widgets ALSA: hda - Add workaround for MacBook Air 5,2 built-in mic ALSA: hda - Set single_adc_amp flag for CS420x codecs ALSA: snd-usb: add quirks for Roland UA-22 ALSA: control: Add sanity checks for user ctl id name string ALSA: hda - Fix built-in mic on Compaq Presario CQ60 ALSA: firewire-lib: leave unit reference counting completely Revert "ALSA: dice: fix wrong offsets for Dice interface" ALSA: hda - Fix regression of HD-audio controller fallback modes
This commit is contained in:
commit
bbc54a00d8
|
@ -1170,6 +1170,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||||
|
|
||||||
if (info->count < 1)
|
if (info->count < 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (!*info->id.name)
|
||||||
|
return -EINVAL;
|
||||||
|
if (strnlen(info->id.name, sizeof(info->id.name)) >= sizeof(info->id.name))
|
||||||
|
return -EINVAL;
|
||||||
access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
|
access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
|
||||||
(info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
|
(info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
|
||||||
SNDRV_CTL_ELEM_ACCESS_INACTIVE|
|
SNDRV_CTL_ELEM_ACCESS_INACTIVE|
|
||||||
|
|
|
@ -298,24 +298,24 @@
|
||||||
*/
|
*/
|
||||||
#define RX_ISOCHRONOUS 0x008
|
#define RX_ISOCHRONOUS 0x008
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Index of first quadlet to be interpreted; read/write. If > 0, that many
|
||||||
|
* quadlets at the beginning of each data block will be ignored, and all the
|
||||||
|
* audio and MIDI quadlets will follow.
|
||||||
|
*/
|
||||||
|
#define RX_SEQ_START 0x00c
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of audio channels; read-only. There will be one quadlet per
|
* The number of audio channels; read-only. There will be one quadlet per
|
||||||
* channel.
|
* channel.
|
||||||
*/
|
*/
|
||||||
#define RX_NUMBER_AUDIO 0x00c
|
#define RX_NUMBER_AUDIO 0x010
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of MIDI ports, 0-8; read-only. If > 0, there will be one
|
* The number of MIDI ports, 0-8; read-only. If > 0, there will be one
|
||||||
* additional quadlet in each data block, following the audio quadlets.
|
* additional quadlet in each data block, following the audio quadlets.
|
||||||
*/
|
*/
|
||||||
#define RX_NUMBER_MIDI 0x010
|
#define RX_NUMBER_MIDI 0x014
|
||||||
|
|
||||||
/*
|
|
||||||
* Index of first quadlet to be interpreted; read/write. If > 0, that many
|
|
||||||
* quadlets at the beginning of each data block will be ignored, and all the
|
|
||||||
* audio and MIDI quadlets will follow.
|
|
||||||
*/
|
|
||||||
#define RX_SEQ_START 0x014
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Names of all audio channels; read-only. Quadlets are byte-swapped. Names
|
* Names of all audio channels; read-only. Quadlets are byte-swapped. Names
|
||||||
|
|
|
@ -99,9 +99,9 @@ static void dice_proc_read(struct snd_info_entry *entry,
|
||||||
} tx;
|
} tx;
|
||||||
struct {
|
struct {
|
||||||
u32 iso;
|
u32 iso;
|
||||||
|
u32 seq_start;
|
||||||
u32 number_audio;
|
u32 number_audio;
|
||||||
u32 number_midi;
|
u32 number_midi;
|
||||||
u32 seq_start;
|
|
||||||
char names[RX_NAMES_SIZE];
|
char names[RX_NAMES_SIZE];
|
||||||
u32 ac3_caps;
|
u32 ac3_caps;
|
||||||
u32 ac3_enable;
|
u32 ac3_enable;
|
||||||
|
@ -204,10 +204,10 @@ static void dice_proc_read(struct snd_info_entry *entry,
|
||||||
break;
|
break;
|
||||||
snd_iprintf(buffer, "rx %u:\n", stream);
|
snd_iprintf(buffer, "rx %u:\n", stream);
|
||||||
snd_iprintf(buffer, " iso channel: %d\n", (int)buf.rx.iso);
|
snd_iprintf(buffer, " iso channel: %d\n", (int)buf.rx.iso);
|
||||||
|
snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start);
|
||||||
snd_iprintf(buffer, " audio channels: %u\n",
|
snd_iprintf(buffer, " audio channels: %u\n",
|
||||||
buf.rx.number_audio);
|
buf.rx.number_audio);
|
||||||
snd_iprintf(buffer, " midi ports: %u\n", buf.rx.number_midi);
|
snd_iprintf(buffer, " midi ports: %u\n", buf.rx.number_midi);
|
||||||
snd_iprintf(buffer, " sequence start: %u\n", buf.rx.seq_start);
|
|
||||||
if (quadlets >= 68) {
|
if (quadlets >= 68) {
|
||||||
dice_proc_fixup_string(buf.rx.names, RX_NAMES_SIZE);
|
dice_proc_fixup_string(buf.rx.names, RX_NAMES_SIZE);
|
||||||
snd_iprintf(buffer, " names: %s\n", buf.rx.names);
|
snd_iprintf(buffer, " names: %s\n", buf.rx.names);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
|
int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit)
|
||||||
{
|
{
|
||||||
r->channels_mask = ~0uLL;
|
r->channels_mask = ~0uLL;
|
||||||
r->unit = fw_unit_get(unit);
|
r->unit = unit;
|
||||||
mutex_init(&r->mutex);
|
mutex_init(&r->mutex);
|
||||||
r->allocated = false;
|
r->allocated = false;
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ void fw_iso_resources_destroy(struct fw_iso_resources *r)
|
||||||
{
|
{
|
||||||
WARN_ON(r->allocated);
|
WARN_ON(r->allocated);
|
||||||
mutex_destroy(&r->mutex);
|
mutex_destroy(&r->mutex);
|
||||||
fw_unit_put(r->unit);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fw_iso_resources_destroy);
|
EXPORT_SYMBOL(fw_iso_resources_destroy);
|
||||||
|
|
||||||
|
|
|
@ -1164,7 +1164,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bus->no_response_fallback)
|
if (bus->no_response_fallback)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!chip->polling_mode && chip->poll_count < 2) {
|
if (!chip->polling_mode && chip->poll_count < 2) {
|
||||||
|
|
|
@ -692,7 +692,23 @@ static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx)
|
||||||
{
|
{
|
||||||
unsigned int caps = query_amp_caps(codec, nid, dir);
|
unsigned int caps = query_amp_caps(codec, nid, dir);
|
||||||
int val = get_amp_val_to_activate(codec, nid, dir, caps, false);
|
int val = get_amp_val_to_activate(codec, nid, dir, caps, false);
|
||||||
snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
|
|
||||||
|
if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
|
||||||
|
snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
|
||||||
|
else
|
||||||
|
snd_hda_codec_amp_init(codec, nid, 0, dir, idx, 0xff, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the amp, doing in stereo or mono depending on NID */
|
||||||
|
static int update_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx,
|
||||||
|
unsigned int mask, unsigned int val)
|
||||||
|
{
|
||||||
|
if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
|
||||||
|
return snd_hda_codec_amp_stereo(codec, nid, dir, idx,
|
||||||
|
mask, val);
|
||||||
|
else
|
||||||
|
return snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
|
||||||
|
mask, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate amp value mask we can modify;
|
/* calculate amp value mask we can modify;
|
||||||
|
@ -732,7 +748,7 @@ static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
val &= mask;
|
val &= mask;
|
||||||
snd_hda_codec_amp_stereo(codec, nid, dir, idx, mask, val);
|
update_amp(codec, nid, dir, idx, mask, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void activate_amp_out(struct hda_codec *codec, struct nid_path *path,
|
static void activate_amp_out(struct hda_codec *codec, struct nid_path *path,
|
||||||
|
@ -4424,13 +4440,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix)
|
||||||
has_amp = nid_has_mute(codec, mix, HDA_INPUT);
|
has_amp = nid_has_mute(codec, mix, HDA_INPUT);
|
||||||
for (i = 0; i < nums; i++) {
|
for (i = 0; i < nums; i++) {
|
||||||
if (has_amp)
|
if (has_amp)
|
||||||
snd_hda_codec_amp_stereo(codec, mix,
|
update_amp(codec, mix, HDA_INPUT, i,
|
||||||
HDA_INPUT, i,
|
0xff, HDA_AMP_MUTE);
|
||||||
0xff, HDA_AMP_MUTE);
|
|
||||||
else if (nid_has_volume(codec, conn[i], HDA_OUTPUT))
|
else if (nid_has_volume(codec, conn[i], HDA_OUTPUT))
|
||||||
snd_hda_codec_amp_stereo(codec, conn[i],
|
update_amp(codec, conn[i], HDA_OUTPUT, 0,
|
||||||
HDA_OUTPUT, 0,
|
0xff, HDA_AMP_MUTE);
|
||||||
0xff, HDA_AMP_MUTE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -393,6 +393,7 @@ static const struct snd_pci_quirk cs420x_fixup_tbl[] = {
|
||||||
SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81),
|
SND_PCI_QUIRK(0x106b, 0x1c00, "MacBookPro 8,1", CS420X_MBP81),
|
||||||
SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
|
SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
|
||||||
SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101),
|
SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101),
|
||||||
|
SND_PCI_QUIRK(0x106b, 0x5600, "MacBookAir 5,2", CS420X_MBP81),
|
||||||
SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42),
|
SND_PCI_QUIRK(0x106b, 0x5b00, "MacBookAir 4,2", CS420X_MBA42),
|
||||||
SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
|
SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
|
||||||
{} /* terminator */
|
{} /* terminator */
|
||||||
|
@ -584,6 +585,7 @@ static int patch_cs420x(struct hda_codec *codec)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
spec->gen.automute_hook = cs_automute;
|
spec->gen.automute_hook = cs_automute;
|
||||||
|
codec->single_adc_amp = 1;
|
||||||
|
|
||||||
snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
|
snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
|
||||||
cs420x_fixups);
|
cs420x_fixups);
|
||||||
|
|
|
@ -223,6 +223,7 @@ enum {
|
||||||
CXT_PINCFG_LENOVO_TP410,
|
CXT_PINCFG_LENOVO_TP410,
|
||||||
CXT_PINCFG_LEMOTE_A1004,
|
CXT_PINCFG_LEMOTE_A1004,
|
||||||
CXT_PINCFG_LEMOTE_A1205,
|
CXT_PINCFG_LEMOTE_A1205,
|
||||||
|
CXT_PINCFG_COMPAQ_CQ60,
|
||||||
CXT_FIXUP_STEREO_DMIC,
|
CXT_FIXUP_STEREO_DMIC,
|
||||||
CXT_FIXUP_INC_MIC_BOOST,
|
CXT_FIXUP_INC_MIC_BOOST,
|
||||||
CXT_FIXUP_HEADPHONE_MIC_PIN,
|
CXT_FIXUP_HEADPHONE_MIC_PIN,
|
||||||
|
@ -660,6 +661,15 @@ static const struct hda_fixup cxt_fixups[] = {
|
||||||
.type = HDA_FIXUP_PINS,
|
.type = HDA_FIXUP_PINS,
|
||||||
.v.pins = cxt_pincfg_lemote,
|
.v.pins = cxt_pincfg_lemote,
|
||||||
},
|
},
|
||||||
|
[CXT_PINCFG_COMPAQ_CQ60] = {
|
||||||
|
.type = HDA_FIXUP_PINS,
|
||||||
|
.v.pins = (const struct hda_pintbl[]) {
|
||||||
|
/* 0x17 was falsely set up as a mic, it should 0x1d */
|
||||||
|
{ 0x17, 0x400001f0 },
|
||||||
|
{ 0x1d, 0x97a70120 },
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
},
|
||||||
[CXT_FIXUP_STEREO_DMIC] = {
|
[CXT_FIXUP_STEREO_DMIC] = {
|
||||||
.type = HDA_FIXUP_FUNC,
|
.type = HDA_FIXUP_FUNC,
|
||||||
.v.func = cxt_fixup_stereo_dmic,
|
.v.func = cxt_fixup_stereo_dmic,
|
||||||
|
@ -769,6 +779,7 @@ static const struct hda_model_fixup cxt5047_fixup_models[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_pci_quirk cxt5051_fixups[] = {
|
static const struct snd_pci_quirk cxt5051_fixups[] = {
|
||||||
|
SND_PCI_QUIRK(0x103c, 0x360b, "Compaq CQ60", CXT_PINCFG_COMPAQ_CQ60),
|
||||||
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
|
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1773,6 +1773,36 @@ YAMAHA_DEVICE(0x7010, "UB99"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
USB_DEVICE(0x0582, 0x0159),
|
||||||
|
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
|
||||||
|
/* .vendor_name = "Roland", */
|
||||||
|
/* .product_name = "UA-22", */
|
||||||
|
.ifnum = QUIRK_ANY_INTERFACE,
|
||||||
|
.type = QUIRK_COMPOSITE,
|
||||||
|
.data = (const struct snd_usb_audio_quirk[]) {
|
||||||
|
{
|
||||||
|
.ifnum = 0,
|
||||||
|
.type = QUIRK_AUDIO_STANDARD_INTERFACE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = 1,
|
||||||
|
.type = QUIRK_AUDIO_STANDARD_INTERFACE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = 2,
|
||||||
|
.type = QUIRK_MIDI_FIXED_ENDPOINT,
|
||||||
|
.data = & (const struct snd_usb_midi_endpoint_info) {
|
||||||
|
.out_cables = 0x0001,
|
||||||
|
.in_cables = 0x0001
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.ifnum = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
/* this catches most recent vendor-specific Roland devices */
|
/* this catches most recent vendor-specific Roland devices */
|
||||||
{
|
{
|
||||||
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
||||||
|
|
Loading…
Reference in New Issue