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 resume of GPIO unsol event for STAC/IDT
ALSA: hda - Add quirks for HP Pavilion DV models
ALSA: hda - Fix GPIO initialization in patch_stac92hd71bxx()
ALSA: hda - Check model type instead of SSID in patch_92hd71bxx()
ALSA: sound/pci/pcxhr/pcxhr.c: introduce missing kfree and pci_disable_device
ALSA: hda: STAC_VREF_EVENT value change
ALSA: hda - Missing NULL check in hda_beep.c
ALSA: hda - Add digital beep playback switch for STAC/IDT codecs

+94 -19
+8
sound/pci/hda/hda_beep.c
··· 37 37 container_of(work, struct hda_beep, beep_work); 38 38 struct hda_codec *codec = beep->codec; 39 39 40 + if (!beep->enabled) 41 + return; 42 + 40 43 /* generate tone */ 41 44 snd_hda_codec_write_cache(codec, beep->nid, 0, 42 45 AC_VERB_SET_BEEP_CONTROL, beep->tone); ··· 88 85 snprintf(beep->phys, sizeof(beep->phys), 89 86 "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr); 90 87 input_dev = input_allocate_device(); 88 + if (!input_dev) { 89 + kfree(beep); 90 + return -ENOMEM; 91 + } 91 92 92 93 /* setup digital beep device */ 93 94 input_dev->name = "HDA Digital PCBeep"; ··· 122 115 beep->nid = nid; 123 116 beep->dev = input_dev; 124 117 beep->codec = codec; 118 + beep->enabled = 1; 125 119 codec->beep = beep; 126 120 127 121 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
+1
sound/pci/hda/hda_beep.h
··· 31 31 char phys[32]; 32 32 int tone; 33 33 int nid; 34 + int enabled; 34 35 struct work_struct beep_work; /* scheduled task for beep event */ 35 36 }; 36 37
+81 -18
sound/pci/hda/patch_sigmatel.c
··· 36 36 #include "hda_beep.h" 37 37 38 38 #define NUM_CONTROL_ALLOC 32 39 + 40 + #define STAC_VREF_EVENT 0x00 41 + #define STAC_INSERT_EVENT 0x10 39 42 #define STAC_PWR_EVENT 0x20 40 43 #define STAC_HP_EVENT 0x30 41 - #define STAC_VREF_EVENT 0x40 42 44 43 45 enum { 44 46 STAC_REF, ··· 1688 1686 /* SigmaTel reference board */ 1689 1687 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1690 1688 "DFI LanParty", STAC_92HD71BXX_REF), 1689 + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, 1690 + "HP dv5", STAC_HP_M4), 1691 + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, 1692 + "HP dv7", STAC_HP_M4), 1691 1693 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, 1692 1694 "unknown HP", STAC_HP_M4), 1693 1695 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, ··· 2593 2587 }; 2594 2588 2595 2589 /* add dynamic controls */ 2596 - static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type, 2597 - int idx, const char *name, unsigned long val) 2590 + static int stac92xx_add_control_temp(struct sigmatel_spec *spec, 2591 + struct snd_kcontrol_new *ktemp, 2592 + int idx, const char *name, 2593 + unsigned long val) 2598 2594 { 2599 2595 struct snd_kcontrol_new *knew; 2600 2596 ··· 2615 2607 } 2616 2608 2617 2609 knew = &spec->kctl_alloc[spec->num_kctl_used]; 2618 - *knew = stac92xx_control_templates[type]; 2610 + *knew = *ktemp; 2619 2611 knew->index = idx; 2620 2612 knew->name = kstrdup(name, GFP_KERNEL); 2621 - if (! knew->name) 2613 + if (!knew->name) 2622 2614 return -ENOMEM; 2623 2615 knew->private_value = val; 2624 2616 spec->num_kctl_used++; 2625 2617 return 0; 2626 2618 } 2627 2619 2620 + static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec, 2621 + int type, int idx, const char *name, 2622 + unsigned long val) 2623 + { 2624 + return stac92xx_add_control_temp(spec, 2625 + &stac92xx_control_templates[type], 2626 + idx, name, val); 2627 + } 2628 + 2628 2629 2629 2630 /* add dynamic controls */ 2630 - static int stac92xx_add_control(struct sigmatel_spec *spec, int type, 2631 - const char *name, unsigned long val) 2631 + static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, 2632 + const char *name, unsigned long val) 2632 2633 { 2633 2634 return stac92xx_add_control_idx(spec, type, 0, name, val); 2634 2635 } ··· 3079 3062 return 0; 3080 3063 } 3081 3064 3065 + #ifdef CONFIG_SND_HDA_INPUT_BEEP 3066 + #define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info 3067 + 3068 + static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol, 3069 + struct snd_ctl_elem_value *ucontrol) 3070 + { 3071 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3072 + ucontrol->value.integer.value[0] = codec->beep->enabled; 3073 + return 0; 3074 + } 3075 + 3076 + static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol, 3077 + struct snd_ctl_elem_value *ucontrol) 3078 + { 3079 + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3080 + int enabled = !!ucontrol->value.integer.value[0]; 3081 + if (codec->beep->enabled != enabled) { 3082 + codec->beep->enabled = enabled; 3083 + return 1; 3084 + } 3085 + return 0; 3086 + } 3087 + 3088 + static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { 3089 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 3090 + .info = stac92xx_dig_beep_switch_info, 3091 + .get = stac92xx_dig_beep_switch_get, 3092 + .put = stac92xx_dig_beep_switch_put, 3093 + }; 3094 + 3095 + static int stac92xx_beep_switch_ctl(struct hda_codec *codec) 3096 + { 3097 + return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl, 3098 + 0, "PC Beep Playback Switch", 0); 3099 + } 3100 + #endif 3101 + 3082 3102 static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) 3083 3103 { 3084 3104 struct sigmatel_spec *spec = codec->spec; ··· 3422 3368 #ifdef CONFIG_SND_HDA_INPUT_BEEP 3423 3369 if (spec->digbeep_nid > 0) { 3424 3370 hda_nid_t nid = spec->digbeep_nid; 3371 + unsigned int caps; 3425 3372 3426 3373 err = stac92xx_auto_create_beep_ctls(codec, nid); 3427 3374 if (err < 0) ··· 3430 3375 err = snd_hda_attach_beep_device(codec, nid); 3431 3376 if (err < 0) 3432 3377 return err; 3378 + /* if no beep switch is available, make its own one */ 3379 + caps = query_amp_caps(codec, nid, HDA_OUTPUT); 3380 + if (codec->beep && 3381 + !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) { 3382 + err = stac92xx_beep_switch_ctl(codec); 3383 + if (err < 0) 3384 + return err; 3385 + } 3433 3386 } 3434 3387 #endif 3435 3388 ··· 4482 4419 stac92xx_set_config_regs(codec); 4483 4420 } 4484 4421 4422 + if (spec->board_config > STAC_92HD71BXX_REF) { 4423 + /* GPIO0 = EAPD */ 4424 + spec->gpio_mask = 0x01; 4425 + spec->gpio_dir = 0x01; 4426 + spec->gpio_data = 0x01; 4427 + } 4428 + 4485 4429 switch (codec->vendor_id) { 4486 4430 case 0x111d76b6: /* 4 Port without Analog Mixer */ 4487 4431 case 0x111d76b7: ··· 4499 4429 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 4500 4430 break; 4501 4431 case 0x111d7608: /* 5 Port with Analog Mixer */ 4502 - switch (codec->subsystem_id) { 4503 - case 0x103c361a: 4432 + switch (spec->board_config) { 4433 + case STAC_HP_M4: 4504 4434 /* Enable VREF power saving on GPIO1 detect */ 4505 - snd_hda_codec_write(codec, codec->afg, 0, 4435 + snd_hda_codec_write_cache(codec, codec->afg, 0, 4506 4436 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); 4507 4437 snd_hda_codec_write_cache(codec, codec->afg, 0, 4508 4438 AC_VERB_SET_UNSOLICITED_ENABLE, ··· 4547 4477 4548 4478 spec->aloopback_mask = 0x50; 4549 4479 spec->aloopback_shift = 0; 4550 - 4551 - if (spec->board_config > STAC_92HD71BXX_REF) { 4552 - /* GPIO0 = EAPD */ 4553 - spec->gpio_mask = 0x01; 4554 - spec->gpio_dir = 0x01; 4555 - spec->gpio_data = 0x01; 4556 - } 4557 4480 4558 4481 spec->powerdown_adcs = 1; 4559 4482 spec->digbeep_nid = 0x26; ··· 4895 4832 stac92xx_set_config_reg(codec, 0x20, 0x1c410030); 4896 4833 4897 4834 /* Enable unsol response for GPIO4/Dock HP connection */ 4898 - snd_hda_codec_write(codec, codec->afg, 0, 4835 + snd_hda_codec_write_cache(codec, codec->afg, 0, 4899 4836 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); 4900 4837 snd_hda_codec_write_cache(codec, codec->afg, 0, 4901 4838 AC_VERB_SET_UNSOLICITED_ENABLE,
+4 -1
sound/pci/pcxhr/pcxhr.c
··· 1229 1229 return -ENOMEM; 1230 1230 } 1231 1231 1232 - if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) 1232 + if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) { 1233 + kfree(mgr); 1234 + pci_disable_device(pci); 1233 1235 return -ENODEV; 1236 + } 1234 1237 card_name = pcxhr_board_params[pci_id->driver_data].board_name; 1235 1238 mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips; 1236 1239 mgr->capture_chips = pcxhr_board_params[pci_id->driver_data].capture_chips;