diff options
-rw-r--r-- | sound/core/rawmidi.c | 42 | ||||
-rw-r--r-- | sound/oss/dmasound/dmasound_core.c | 4 | ||||
-rw-r--r-- | sound/oss/sb_common.c | 4 | ||||
-rw-r--r-- | sound/oss/sb_ess.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 12 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_nvhdmi.c | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 17 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 70 | ||||
-rw-r--r-- | sound/pci/ice1712/ice1712.h | 4 | ||||
-rw-r--r-- | sound/pci/ice1712/prodigy_hifi.c | 2 | ||||
-rw-r--r-- | sound/pci/intel8x0.c | 6 | ||||
-rw-r--r-- | sound/sh/aica.c | 1 | ||||
-rw-r--r-- | sound/usb/usbaudio.h | 2 | ||||
-rw-r--r-- | sound/usb/usbmixer.c | 9 |
15 files changed, 149 insertions, 44 deletions
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index c0adc14c91f..70d6f25ba52 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -248,7 +248,8 @@ static int assign_substream(struct snd_rawmidi *rmidi, int subdevice, list_for_each_entry(substream, &s->substreams, list) { if (substream->opened) { if (stream == SNDRV_RAWMIDI_STREAM_INPUT || - !(mode & SNDRV_RAWMIDI_LFLG_APPEND)) + !(mode & SNDRV_RAWMIDI_LFLG_APPEND) || + !substream->append) continue; } if (subdevice < 0 || subdevice == substream->number) { @@ -266,17 +267,21 @@ static int open_substream(struct snd_rawmidi *rmidi, { int err; - err = snd_rawmidi_runtime_create(substream); - if (err < 0) - return err; - err = substream->ops->open(substream); - if (err < 0) - return err; - substream->opened = 1; - if (substream->use_count++ == 0) + if (substream->use_count == 0) { + err = snd_rawmidi_runtime_create(substream); + if (err < 0) + return err; + err = substream->ops->open(substream); + if (err < 0) { + snd_rawmidi_runtime_free(substream); + return err; + } + substream->opened = 1; substream->active_sensing = 0; - if (mode & SNDRV_RAWMIDI_LFLG_APPEND) - substream->append = 1; + if (mode & SNDRV_RAWMIDI_LFLG_APPEND) + substream->append = 1; + } + substream->use_count++; rmidi->streams[substream->stream].substream_opened++; return 0; } @@ -297,27 +302,27 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode, SNDRV_RAWMIDI_STREAM_INPUT, mode, &sinput); if (err < 0) - goto __error; + return err; } if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) { err = assign_substream(rmidi, subdevice, SNDRV_RAWMIDI_STREAM_OUTPUT, mode, &soutput); if (err < 0) - goto __error; + return err; } if (sinput) { err = open_substream(rmidi, sinput, mode); if (err < 0) - goto __error; + return err; } if (soutput) { err = open_substream(rmidi, soutput, mode); if (err < 0) { if (sinput) close_substream(rmidi, sinput, 0); - goto __error; + return err; } } @@ -325,13 +330,6 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode, rfile->input = sinput; rfile->output = soutput; return 0; - - __error: - if (sinput && sinput->runtime) - snd_rawmidi_runtime_free(sinput); - if (soutput && soutput->runtime) - snd_rawmidi_runtime_free(soutput); - return err; } /* called from sound/core/seq/seq_midi.c */ diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index 793b7f47843..3f3c3f71db4 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -219,7 +219,9 @@ static int shared_resources_initialised; * Mid level stuff */ -struct sound_settings dmasound = { .lock = SPIN_LOCK_UNLOCKED }; +struct sound_settings dmasound = { + .lock = __SPIN_LOCK_UNLOCKED(dmasound.lock) +}; static inline void sound_silence(void) { diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c index 77d0e5efda7..ce4db49291f 100644 --- a/sound/oss/sb_common.c +++ b/sound/oss/sb_common.c @@ -157,7 +157,7 @@ static void sb_intr (sb_devc *devc) break; default: - /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */ + /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */ ; } } @@ -177,7 +177,7 @@ static void sb_intr (sb_devc *devc) break; default: - /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */ + /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */ ; } } diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c index 180e95c87e3..51a3d381a59 100644 --- a/sound/oss/sb_ess.c +++ b/sound/oss/sb_ess.c @@ -782,7 +782,7 @@ printk(KERN_INFO "FKS: ess_handle_channel %s irq_mode=%d\n", channel, irq_mode); break; default:; - /* printk(KERN_WARN "ESS: Unexpected interrupt\n"); */ + /* printk(KERN_WARNING "ESS: Unexpected interrupt\n"); */ } } diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e340792f6cb..6517f589d01 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -722,9 +722,10 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, chip->last_cmd[addr]); chip->single_cmd = 1; bus->response_reset = 0; - /* re-initialize CORB/RIRB */ + /* release CORB/RIRB */ azx_free_cmd_io(chip); - azx_init_cmd_io(chip); + /* disable unsolicited responses */ + azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_UNSOL); return -1; } @@ -865,7 +866,9 @@ static int azx_reset(struct azx *chip) } /* Accept unsolicited responses */ - azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL); + if (!chip->single_cmd) + azx_writel(chip, GCTL, azx_readl(chip, GCTL) | + ICH6_GCTL_UNSOL); /* detect codecs */ if (!chip->codec_mask) { @@ -980,7 +983,8 @@ static void azx_init_chip(struct azx *chip) azx_int_enable(chip); /* initialize the codec command I/O */ - azx_init_cmd_io(chip); + if (!chip->single_cmd) + azx_init_cmd_io(chip); /* program the position buffer */ azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 3fbbc8c01e7..905859d4f4d 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -110,6 +110,7 @@ struct conexant_spec { unsigned int dell_automute; unsigned int port_d_mode; + unsigned char ext_mic_bias; }; static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, @@ -1927,6 +1928,11 @@ static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; #define CXT5066_SPDIF_OUT 0x21 +/* OLPC's microphone port is DC coupled for use with external sensors, + * therefore we use a 50% mic bias in order to center the input signal with + * the DC input range of the codec. */ +#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50 + static struct hda_channel_mode cxt5066_modes[1] = { { 2, NULL }, }; @@ -1980,9 +1986,10 @@ static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol, /* toggle input of built-in and mic jack appropriately */ static void cxt5066_automic(struct hda_codec *codec) { - static struct hda_verb ext_mic_present[] = { + struct conexant_spec *spec = codec->spec; + struct hda_verb ext_mic_present[] = { /* enable external mic, port B */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias}, /* switch to external mic input */ {0x17, AC_VERB_SET_CONNECT_SEL, 0}, @@ -2235,7 +2242,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = { {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ /* Port B: external microphone */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS}, /* Port C: internal microphone */ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, @@ -2325,6 +2332,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { CXT5066_LAPTOP), SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", CXT5066_DELL_LAPTOP), + SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), {} }; @@ -2352,6 +2360,7 @@ static int patch_cxt5066(struct hda_codec *codec) spec->input_mux = &cxt5066_capture_source; spec->port_d_mode = PIN_HP; + spec->ext_mic_bias = PIN_VREF80; spec->num_init_verbs = 1; spec->init_verbs[0] = cxt5066_init_verbs; @@ -2383,6 +2392,7 @@ static int patch_cxt5066(struct hda_codec *codec) spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc; spec->mixers[spec->num_mixers++] = cxt5066_mixers; spec->port_d_mode = 0; + spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS; /* no S/PDIF out */ spec->multiout.dig_out_nid = 0; diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 9fb60276f5c..6afdab09bab 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c @@ -397,6 +397,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, { .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, + { .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch }, { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, @@ -406,6 +407,7 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { MODULE_ALIAS("snd-hda-codec-id:10de0002"); MODULE_ALIAS("snd-hda-codec-id:10de0003"); +MODULE_ALIAS("snd-hda-codec-id:10de0005"); MODULE_ALIAS("snd-hda-codec-id:10de0006"); MODULE_ALIAS("snd-hda-codec-id:10de0007"); MODULE_ALIAS("snd-hda-codec-id:10de0067"); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ff20048504b..70583719282 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4684,9 +4684,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec) spec->multiout.dig_out_nid = dig_nid; else { spec->multiout.slave_dig_outs = spec->slave_dig_outs; - spec->slave_dig_outs[i - 1] = dig_nid; - if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1) + if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) break; + spec->slave_dig_outs[i - 1] = dig_nid; } } if (spec->autocfg.dig_in_pin) @@ -6249,7 +6249,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), - SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), + SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), @@ -8911,10 +8911,11 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), - /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently - * no perfect solution yet + /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, + * so apparently no perfect solution yet */ SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), + SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), {} /* terminator */ }; @@ -9813,9 +9814,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec) spec->multiout.dig_out_nid = dig_nid; else { spec->multiout.slave_dig_outs = spec->slave_dig_outs; - spec->slave_dig_outs[i - 1] = dig_nid; - if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1) + if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) break; + spec->slave_dig_outs[i - 1] = dig_nid; } } if (spec->autocfg.dig_in_pin) @@ -11460,6 +11461,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), + SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), + SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 66c0876bf73..86de305fc9f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -28,6 +28,7 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/pci.h> +#include <linux/dmi.h> #include <sound/core.h> #include <sound/asoundef.h> #include <sound/jack.h> @@ -1589,6 +1590,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { "Dell Studio 17", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be, "Dell Studio 1555", STAC_DELL_M6_DMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd, + "Dell Studio 1557", STAC_DELL_M6_DMIC), {} /* terminator */ }; @@ -1693,6 +1696,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { "DFI LanParty", STAC_92HD71BXX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fb, "HP dv4-1222nr", STAC_HP_DV4_1222NR), + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x1720, + "HP", STAC_HP_DV5), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, "HP", STAC_HP_DV5), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, @@ -4665,6 +4670,26 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) } } +static int hp_bseries_system(u32 subsystem_id) +{ + switch (subsystem_id) { + case 0x103c307e: + case 0x103c307f: + case 0x103c3080: + case 0x103c3081: + case 0x103c1722: + case 0x103c1723: + case 0x103c1724: + case 0x103c1725: + case 0x103c1726: + case 0x103c1727: + case 0x103c1728: + case 0x103c1729: + return 1; + } + return 0; +} + #ifdef CONFIG_PROC_FS static void stac92hd_proc_hook(struct snd_info_buffer *buffer, struct hda_codec *codec, hda_nid_t nid) @@ -4754,6 +4779,11 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec, else spec->gpio_data |= spec->gpio_led; /* white */ + if (hp_bseries_system(codec->subsystem_id)) { + /* LED state is inverted on these systems */ + spec->gpio_data ^= spec->gpio_led; + } + stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); @@ -5243,6 +5273,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) { struct sigmatel_spec *spec; struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; + unsigned int pin_cfg; int err = 0; spec = kzalloc(sizeof(*spec), GFP_KERNEL); @@ -5426,6 +5457,45 @@ again: break; } + if (hp_bseries_system(codec->subsystem_id)) { + pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); + if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || + get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || + get_defcfg_device(pin_cfg) == AC_JACK_HP_OUT) { + /* It was changed in the BIOS to just satisfy MS DTM. + * Lets turn it back into slaved HP + */ + pin_cfg = (pin_cfg & (~AC_DEFCFG_DEVICE)) + | (AC_JACK_HP_OUT << + AC_DEFCFG_DEVICE_SHIFT); + pin_cfg = (pin_cfg & (~(AC_DEFCFG_DEF_ASSOC + | AC_DEFCFG_SEQUENCE))) + | 0x1f; + snd_hda_codec_set_pincfg(codec, 0x0f, pin_cfg); + } + } + + if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { + const struct dmi_device *dev = NULL; + while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, + NULL, dev))) { + if (strcmp(dev->name, "HP_Mute_LED_1")) { + switch (codec->vendor_id) { + case 0x111d7608: + spec->gpio_led = 0x01; + break; + case 0x111d7600: + case 0x111d7601: + case 0x111d7602: + case 0x111d7603: + spec->gpio_led = 0x08; + break; + } + break; + } + } + } + #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { spec->gpio_mask |= spec->gpio_led; diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index 9da2dae64c5..d063149e704 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -382,8 +382,8 @@ struct snd_ice1712 { #ifdef CONFIG_PM int (*pm_suspend)(struct snd_ice1712 *); int (*pm_resume)(struct snd_ice1712 *); - int pm_suspend_enabled:1; - int pm_saved_is_spdif_master:1; + unsigned int pm_suspend_enabled:1; + unsigned int pm_saved_is_spdif_master:1; unsigned int pm_saved_spdif_ctrl; unsigned char pm_saved_spdif_cfg; unsigned int pm_saved_route; diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index c75515f5be6..6a9fee3ee78 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c @@ -1100,7 +1100,7 @@ static void ak4396_init(struct snd_ice1712 *ice) } #ifdef CONFIG_PM -static int __devinit prodigy_hd2_resume(struct snd_ice1712 *ice) +static int prodigy_hd2_resume(struct snd_ice1712 *ice) { /* initialize ak4396 codec and restore previous mixer volumes */ struct prodigy_hifi_spec *spec = ice->spec; diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 754867ed478..aac20fb4aad 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1950,6 +1950,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { }, { .subvendor = 0x104d, + .subdevice = 0x8144, + .name = "Sony", + .type = AC97_TUNE_INV_EAPD + }, + { + .subvendor = 0x104d, .subdevice = 0x8197, .name = "Sony S1XP", .type = AC97_TUNE_INV_EAPD diff --git a/sound/sh/aica.c b/sound/sh/aica.c index 583a3693df7..a0df401ebb9 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c @@ -49,6 +49,7 @@ MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>"); MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}"); +MODULE_FIRMWARE("aica_firmware.bin"); /* module parameters */ #define CARD_NAME "AICA" diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 8e7f78941ba..e9a3a9dca15 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -210,7 +210,7 @@ struct snd_usb_midi_endpoint_info { /* */ -#define combine_word(s) ((*s) | ((unsigned int)(s)[1] << 8)) +#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8)) #define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16)) #define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24)) diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 9efcfd08d74..c998220b99c 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c @@ -1071,6 +1071,15 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig channels = (ftr[0] - 7) / csize - 1; master_bits = snd_usb_combine_bytes(ftr + 6, csize); + /* master configuration quirks */ + switch (state->chip->usb_id) { + case USB_ID(0x08bb, 0x2702): + snd_printk(KERN_INFO + "usbmixer: master volume quirk for PCM2702 chip\n"); + /* disable non-functional volume control */ + master_bits &= ~(1 << (USB_FEATURE_VOLUME - 1)); + break; + } if (channels > 0) first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize); else |