|
@@ -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>
|
|
@@ -158,6 +159,7 @@ enum {
|
|
|
STAC_D965_5ST_NO_FP,
|
|
|
STAC_DELL_3ST,
|
|
|
STAC_DELL_BIOS,
|
|
|
+ STAC_927X_VOLKNOB,
|
|
|
STAC_927X_MODELS
|
|
|
};
|
|
|
|
|
@@ -907,6 +909,16 @@ static struct hda_verb d965_core_init[] = {
|
|
|
{}
|
|
|
};
|
|
|
|
|
|
+static struct hda_verb dell_3st_core_init[] = {
|
|
|
+ /* don't set delta bit */
|
|
|
+ {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
|
|
|
+ /* unmute node 0x1b */
|
|
|
+ {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
|
|
|
+ /* select node 0x03 as DAC */
|
|
|
+ {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
|
|
|
+ {}
|
|
|
+};
|
|
|
+
|
|
|
static struct hda_verb stac927x_core_init[] = {
|
|
|
/* set master volume and direct control */
|
|
|
{ 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
|
|
@@ -915,6 +927,14 @@ static struct hda_verb stac927x_core_init[] = {
|
|
|
{}
|
|
|
};
|
|
|
|
|
|
+static struct hda_verb stac927x_volknob_core_init[] = {
|
|
|
+ /* don't set delta bit */
|
|
|
+ {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
|
|
|
+ /* enable analog pc beep path */
|
|
|
+ {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
|
|
|
+ {}
|
|
|
+};
|
|
|
+
|
|
|
static struct hda_verb stac9205_core_init[] = {
|
|
|
/* set master volume and direct control */
|
|
|
{ 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
|
|
@@ -1674,6 +1694,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,
|
|
@@ -1999,6 +2021,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
|
|
|
[STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs,
|
|
|
[STAC_DELL_3ST] = dell_3st_pin_configs,
|
|
|
[STAC_DELL_BIOS] = NULL,
|
|
|
+ [STAC_927X_VOLKNOB] = NULL,
|
|
|
};
|
|
|
|
|
|
static const char *stac927x_models[STAC_927X_MODELS] = {
|
|
@@ -2010,6 +2033,7 @@ static const char *stac927x_models[STAC_927X_MODELS] = {
|
|
|
[STAC_D965_5ST_NO_FP] = "5stack-no-fp",
|
|
|
[STAC_DELL_3ST] = "dell-3stack",
|
|
|
[STAC_DELL_BIOS] = "dell-bios",
|
|
|
+ [STAC_927X_VOLKNOB] = "volknob",
|
|
|
};
|
|
|
|
|
|
static struct snd_pci_quirk stac927x_cfg_tbl[] = {
|
|
@@ -2045,6 +2069,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
|
|
|
"Intel D965", STAC_D965_5ST),
|
|
|
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
|
|
|
"Intel D965", STAC_D965_5ST),
|
|
|
+ /* volume-knob fixes */
|
|
|
+ SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
|
|
|
{} /* terminator */
|
|
|
};
|
|
|
|
|
@@ -4707,6 +4733,26 @@ static int stac92xx_resume(struct hda_codec *codec)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+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;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* using power check for controlling mute led of HP notebooks
|
|
|
* check for mute state only on Speakers (nid = 0x10)
|
|
@@ -4731,6 +4777,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);
|
|
@@ -5220,6 +5271,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);
|
|
@@ -5403,6 +5455,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;
|
|
@@ -5612,10 +5703,14 @@ static int patch_stac927x(struct hda_codec *codec)
|
|
|
spec->dmic_nids = stac927x_dmic_nids;
|
|
|
spec->num_dmics = STAC927X_NUM_DMICS;
|
|
|
|
|
|
- spec->init = d965_core_init;
|
|
|
+ spec->init = dell_3st_core_init;
|
|
|
spec->dmux_nids = stac927x_dmux_nids;
|
|
|
spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
|
|
|
break;
|
|
|
+ case STAC_927X_VOLKNOB:
|
|
|
+ spec->num_dmics = 0;
|
|
|
+ spec->init = stac927x_volknob_core_init;
|
|
|
+ break;
|
|
|
default:
|
|
|
spec->num_dmics = 0;
|
|
|
spec->init = stac927x_core_init;
|