summaryrefslogtreecommitdiff
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.c153
1 files changed, 106 insertions, 47 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7f81cc2274f3..fcf4c7142103 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -95,6 +95,7 @@ enum {
STAC_92HD83XXX_PWR_REF,
STAC_DELL_S14,
STAC_92HD83XXX_HP,
+ STAC_92HD83XXX_HP_cNB11_INTQUAD,
STAC_HP_DV7_4000,
STAC_92HD83XXX_MODELS
};
@@ -1112,7 +1113,9 @@ static int stac92xx_build_controls(struct hda_codec *codec)
}
if (spec->multiout.dig_out_nid) {
- err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
+ err = snd_hda_create_spdif_out_ctls(codec,
+ spec->multiout.dig_out_nid,
+ spec->multiout.dig_out_nid);
if (err < 0)
return err;
err = snd_hda_create_spdif_share_sw(codec,
@@ -1634,10 +1637,17 @@ static const unsigned int hp_dv7_4000_pin_configs[10] = {
0x40f000f0, 0x40f000f0,
};
+static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
+ 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
+ 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
+ 0x40f000f0, 0x40f000f0,
+};
+
static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
[STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
[STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
[STAC_DELL_S14] = dell_s14_pin_configs,
+ [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
[STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
};
@@ -1647,6 +1657,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
[STAC_92HD83XXX_PWR_REF] = "mic-ref",
[STAC_DELL_S14] = "dell-s14",
[STAC_92HD83XXX_HP] = "hp",
+ [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
[STAC_HP_DV7_4000] = "hp-dv7-4000",
};
@@ -1659,7 +1670,47 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
"unknown Dell", STAC_DELL_S14),
SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
- "HP", STAC_92HD83XXX_HP),
+ "HP", STAC_92HD83XXX_HP),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
+ "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
{} /* terminator */
};
@@ -3406,30 +3457,9 @@ static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
return 0;
}
-static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
- hda_nid_t nid)
-{
- hda_nid_t conn[HDA_MAX_NUM_INPUTS];
- int i, nums;
-
- if (!(get_wcaps(codec, mux) & AC_WCAP_CONN_LIST))
- return -1;
-
- nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
- for (i = 0; i < nums; i++)
- if (conn[i] == nid)
- return i;
-
- for (i = 0; i < nums; i++) {
- unsigned int wid_caps = get_wcaps(codec, conn[i]);
- unsigned int wid_type = get_wcaps_type(wid_caps);
-
- if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX)
- if (get_connection_index(codec, conn[i], nid) >= 0)
- return i;
- }
- return -1;
-}
+/* look for NID recursively */
+#define get_connection_index(codec, mux, nid) \
+ snd_hda_get_conn_index(codec, mux, nid, 1)
/* create a volume assigned to the given pin (only if supported) */
/* return 1 if the volume control is created */
@@ -4904,7 +4934,18 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
#define stac927x_proc_hook NULL
#endif
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
+static int stac92xx_pre_resume(struct hda_codec *codec)
+{
+ struct sigmatel_spec *spec = codec->spec;
+
+ /* sync mute LED */
+ if (spec->gpio_led)
+ stac_gpio_set(codec, spec->gpio_mask,
+ spec->gpio_dir, spec->gpio_data);
+ return 0;
+}
+
static int stac92xx_resume(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
@@ -4920,29 +4961,19 @@ static int stac92xx_resume(struct hda_codec *codec)
stac_issue_unsol_event(codec,
spec->autocfg.line_out_pins[0]);
}
- /* sync mute LED */
- if (spec->gpio_led)
- hda_call_check_power_status(codec, 0x01);
return 0;
}
+#ifdef CONFIG_SND_HDA_POWER_SAVE
/*
- * using power check for controlling mute led of HP notebooks
- * check for mute state only on Speakers (nid = 0x10)
- *
- * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise
- * the LED is NOT working properly !
- *
- * Changed name to reflect that it now works for any designated
- * model, not just HP HDX.
+ * For this feature CONFIG_SND_HDA_POWER_SAVE is needed
+ * as mute LED state is updated in check_power_status hook
*/
-
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static int stac92xx_hp_check_power_status(struct hda_codec *codec,
- hda_nid_t nid)
+static int stac92xx_update_led_status(struct hda_codec *codec)
{
struct sigmatel_spec *spec = codec->spec;
- int i, muted = 1;
+ int i, num_ext_dacs, muted = 1;
+ hda_nid_t nid;
for (i = 0; i < spec->multiout.num_dacs; i++) {
nid = spec->multiout.dac_nids[i];
@@ -4952,6 +4983,22 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
break;
}
}
+ if (muted && spec->multiout.hp_nid)
+ if (!(snd_hda_codec_amp_read(codec,
+ spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) &
+ HDA_AMP_MUTE)) {
+ muted = 0; /* HP is not muted */
+ }
+ num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid);
+ for (i = 0; muted && i < num_ext_dacs; i++) {
+ nid = spec->multiout.extra_out_nid[i];
+ if (nid == 0)
+ break;
+ if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
+ HDA_AMP_MUTE)) {
+ muted = 0; /* extra output is not muted */
+ }
+ }
if (muted)
spec->gpio_data &= ~spec->gpio_led; /* orange */
else
@@ -4965,6 +5012,17 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
return 0;
}
+
+/*
+ * use power check for controlling mute led of HP notebooks
+ */
+static int stac92xx_check_power_status(struct hda_codec *codec,
+ hda_nid_t nid)
+{
+ stac92xx_update_led_status(codec);
+
+ return 0;
+}
#endif
static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
@@ -4972,7 +5030,7 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
stac92xx_shutup(codec);
return 0;
}
-#endif
+#endif /* CONFIG_PM */
static const struct hda_codec_ops stac92xx_patch_ops = {
.build_controls = stac92xx_build_controls,
@@ -4980,9 +5038,10 @@ static const struct hda_codec_ops stac92xx_patch_ops = {
.init = stac92xx_init,
.free = stac92xx_free,
.unsol_event = stac92xx_unsol_event,
-#ifdef SND_HDA_NEEDS_RESUME
+#ifdef CONFIG_PM
.suspend = stac92xx_suspend,
.resume = stac92xx_resume,
+ .pre_resume = stac92xx_pre_resume,
#endif
.reboot_notify = stac92xx_shutup,
};
@@ -5501,7 +5560,7 @@ again:
spec->gpio_data |= spec->gpio_led;
/* register check_power_status callback. */
codec->patch_ops.check_power_status =
- stac92xx_hp_check_power_status;
+ stac92xx_check_power_status;
}
#endif
@@ -5829,7 +5888,7 @@ again:
spec->gpio_data |= spec->gpio_led;
/* register check_power_status callback. */
codec->patch_ops.check_power_status =
- stac92xx_hp_check_power_status;
+ stac92xx_check_power_status;
}
#endif