aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r--sound/pci/hda/patch_sigmatel.c99
1 files changed, 81 insertions, 18 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 4300a679cd86..9563b5bbb272 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -36,9 +36,11 @@
36#include "hda_beep.h" 36#include "hda_beep.h"
37 37
38#define NUM_CONTROL_ALLOC 32 38#define NUM_CONTROL_ALLOC 32
39
40#define STAC_VREF_EVENT 0x00
41#define STAC_INSERT_EVENT 0x10
39#define STAC_PWR_EVENT 0x20 42#define STAC_PWR_EVENT 0x20
40#define STAC_HP_EVENT 0x30 43#define STAC_HP_EVENT 0x30
41#define STAC_VREF_EVENT 0x40
42 44
43enum { 45enum {
44 STAC_REF, 46 STAC_REF,
@@ -1686,6 +1688,10 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1686 /* SigmaTel reference board */ 1688 /* SigmaTel reference board */
1687 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1689 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1688 "DFI LanParty", STAC_92HD71BXX_REF), 1690 "DFI LanParty", STAC_92HD71BXX_REF),
1691 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2,
1692 "HP dv5", STAC_HP_M4),
1693 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4,
1694 "HP dv7", STAC_HP_M4),
1689 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, 1695 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
1690 "unknown HP", STAC_HP_M4), 1696 "unknown HP", STAC_HP_M4),
1691 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 1697 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -2587,8 +2593,10 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
2587}; 2593};
2588 2594
2589/* add dynamic controls */ 2595/* add dynamic controls */
2590static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type, 2596static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2591 int idx, const char *name, unsigned long val) 2597 struct snd_kcontrol_new *ktemp,
2598 int idx, const char *name,
2599 unsigned long val)
2592{ 2600{
2593 struct snd_kcontrol_new *knew; 2601 struct snd_kcontrol_new *knew;
2594 2602
@@ -2607,20 +2615,29 @@ static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
2607 } 2615 }
2608 2616
2609 knew = &spec->kctl_alloc[spec->num_kctl_used]; 2617 knew = &spec->kctl_alloc[spec->num_kctl_used];
2610 *knew = stac92xx_control_templates[type]; 2618 *knew = *ktemp;
2611 knew->index = idx; 2619 knew->index = idx;
2612 knew->name = kstrdup(name, GFP_KERNEL); 2620 knew->name = kstrdup(name, GFP_KERNEL);
2613 if (! knew->name) 2621 if (!knew->name)
2614 return -ENOMEM; 2622 return -ENOMEM;
2615 knew->private_value = val; 2623 knew->private_value = val;
2616 spec->num_kctl_used++; 2624 spec->num_kctl_used++;
2617 return 0; 2625 return 0;
2618} 2626}
2619 2627
2628static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
2629 int type, int idx, const char *name,
2630 unsigned long val)
2631{
2632 return stac92xx_add_control_temp(spec,
2633 &stac92xx_control_templates[type],
2634 idx, name, val);
2635}
2636
2620 2637
2621/* add dynamic controls */ 2638/* add dynamic controls */
2622static int stac92xx_add_control(struct sigmatel_spec *spec, int type, 2639static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2623 const char *name, unsigned long val) 2640 const char *name, unsigned long val)
2624{ 2641{
2625 return stac92xx_add_control_idx(spec, type, 0, name, val); 2642 return stac92xx_add_control_idx(spec, type, 0, name, val);
2626} 2643}
@@ -3062,6 +3079,43 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
3062 return 0; 3079 return 0;
3063} 3080}
3064 3081
3082#ifdef CONFIG_SND_HDA_INPUT_BEEP
3083#define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info
3084
3085static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol,
3086 struct snd_ctl_elem_value *ucontrol)
3087{
3088 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3089 ucontrol->value.integer.value[0] = codec->beep->enabled;
3090 return 0;
3091}
3092
3093static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol,
3094 struct snd_ctl_elem_value *ucontrol)
3095{
3096 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3097 int enabled = !!ucontrol->value.integer.value[0];
3098 if (codec->beep->enabled != enabled) {
3099 codec->beep->enabled = enabled;
3100 return 1;
3101 }
3102 return 0;
3103}
3104
3105static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = {
3106 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3107 .info = stac92xx_dig_beep_switch_info,
3108 .get = stac92xx_dig_beep_switch_get,
3109 .put = stac92xx_dig_beep_switch_put,
3110};
3111
3112static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
3113{
3114 return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl,
3115 0, "PC Beep Playback Switch", 0);
3116}
3117#endif
3118
3065static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) 3119static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
3066{ 3120{
3067 struct sigmatel_spec *spec = codec->spec; 3121 struct sigmatel_spec *spec = codec->spec;
@@ -3368,6 +3422,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3368#ifdef CONFIG_SND_HDA_INPUT_BEEP 3422#ifdef CONFIG_SND_HDA_INPUT_BEEP
3369 if (spec->digbeep_nid > 0) { 3423 if (spec->digbeep_nid > 0) {
3370 hda_nid_t nid = spec->digbeep_nid; 3424 hda_nid_t nid = spec->digbeep_nid;
3425 unsigned int caps;
3371 3426
3372 err = stac92xx_auto_create_beep_ctls(codec, nid); 3427 err = stac92xx_auto_create_beep_ctls(codec, nid);
3373 if (err < 0) 3428 if (err < 0)
@@ -3375,6 +3430,14 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3375 err = snd_hda_attach_beep_device(codec, nid); 3430 err = snd_hda_attach_beep_device(codec, nid);
3376 if (err < 0) 3431 if (err < 0)
3377 return err; 3432 return err;
3433 /* if no beep switch is available, make its own one */
3434 caps = query_amp_caps(codec, nid, HDA_OUTPUT);
3435 if (codec->beep &&
3436 !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) {
3437 err = stac92xx_beep_switch_ctl(codec);
3438 if (err < 0)
3439 return err;
3440 }
3378 } 3441 }
3379#endif 3442#endif
3380 3443
@@ -4419,6 +4482,13 @@ again:
4419 stac92xx_set_config_regs(codec); 4482 stac92xx_set_config_regs(codec);
4420 } 4483 }
4421 4484
4485 if (spec->board_config > STAC_92HD71BXX_REF) {
4486 /* GPIO0 = EAPD */
4487 spec->gpio_mask = 0x01;
4488 spec->gpio_dir = 0x01;
4489 spec->gpio_data = 0x01;
4490 }
4491
4422 switch (codec->vendor_id) { 4492 switch (codec->vendor_id) {
4423 case 0x111d76b6: /* 4 Port without Analog Mixer */ 4493 case 0x111d76b6: /* 4 Port without Analog Mixer */
4424 case 0x111d76b7: 4494 case 0x111d76b7:
@@ -4429,10 +4499,10 @@ again:
4429 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 4499 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
4430 break; 4500 break;
4431 case 0x111d7608: /* 5 Port with Analog Mixer */ 4501 case 0x111d7608: /* 5 Port with Analog Mixer */
4432 switch (codec->subsystem_id) { 4502 switch (spec->board_config) {
4433 case 0x103c361a: 4503 case STAC_HP_M4:
4434 /* Enable VREF power saving on GPIO1 detect */ 4504 /* Enable VREF power saving on GPIO1 detect */
4435 snd_hda_codec_write(codec, codec->afg, 0, 4505 snd_hda_codec_write_cache(codec, codec->afg, 0,
4436 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); 4506 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
4437 snd_hda_codec_write_cache(codec, codec->afg, 0, 4507 snd_hda_codec_write_cache(codec, codec->afg, 0,
4438 AC_VERB_SET_UNSOLICITED_ENABLE, 4508 AC_VERB_SET_UNSOLICITED_ENABLE,
@@ -4478,13 +4548,6 @@ again:
4478 spec->aloopback_mask = 0x50; 4548 spec->aloopback_mask = 0x50;
4479 spec->aloopback_shift = 0; 4549 spec->aloopback_shift = 0;
4480 4550
4481 if (spec->board_config > STAC_92HD71BXX_REF) {
4482 /* GPIO0 = EAPD */
4483 spec->gpio_mask = 0x01;
4484 spec->gpio_dir = 0x01;
4485 spec->gpio_data = 0x01;
4486 }
4487
4488 spec->powerdown_adcs = 1; 4551 spec->powerdown_adcs = 1;
4489 spec->digbeep_nid = 0x26; 4552 spec->digbeep_nid = 0x26;
4490 spec->mux_nids = stac92hd71bxx_mux_nids; 4553 spec->mux_nids = stac92hd71bxx_mux_nids;
@@ -4832,7 +4895,7 @@ static int patch_stac9205(struct hda_codec *codec)
4832 stac92xx_set_config_reg(codec, 0x20, 0x1c410030); 4895 stac92xx_set_config_reg(codec, 0x20, 0x1c410030);
4833 4896
4834 /* Enable unsol response for GPIO4/Dock HP connection */ 4897 /* Enable unsol response for GPIO4/Dock HP connection */
4835 snd_hda_codec_write(codec, codec->afg, 0, 4898 snd_hda_codec_write_cache(codec, codec->afg, 0,
4836 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); 4899 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
4837 snd_hda_codec_write_cache(codec, codec->afg, 0, 4900 snd_hda_codec_write_cache(codec, codec->afg, 0,
4838 AC_VERB_SET_UNSOLICITED_ENABLE, 4901 AC_VERB_SET_UNSOLICITED_ENABLE,