summaryrefslogtreecommitdiff
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/Kconfig13
-rw-r--r--sound/pci/hda/hda_auto_parser.c1
-rw-r--r--sound/pci/hda/hda_auto_parser.h10
-rw-r--r--sound/pci/hda/hda_codec.c50
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_intel.c19
-rw-r--r--sound/pci/hda/patch_conexant.c8
-rw-r--r--sound/pci/hda/patch_realtek.c25
-rw-r--r--sound/pci/hda/patch_sigmatel.c7
9 files changed, 95 insertions, 40 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 163b6b5de3eb..d03079764189 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -97,19 +97,6 @@ config SND_HDA_CODEC_REALTEK
snd-hda-codec-realtek.
This module is automatically loaded at probing.
-config SND_HDA_ENABLE_REALTEK_QUIRKS
- bool "Build static quirks for Realtek codecs"
- depends on SND_HDA_CODEC_REALTEK
- default y
- help
- Say Y here to build the static quirks codes for Realtek codecs.
- If you need the "model" preset that the default BIOS auto-parser
- can't handle, turn this option on.
-
- If your device works with model=auto option, basically you don't
- need the quirk code. By turning this off, you can reduce the
- module size quite a lot.
-
config SND_HDA_CODEC_ANALOG
bool "Build Analog Device HD-audio codec support"
default y
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index 6e9ef3e25093..f7520b9f909c 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -618,7 +618,6 @@ int snd_hda_gen_add_verbs(struct hda_gen_spec *spec,
const struct hda_verb *list)
{
const struct hda_verb **v;
- snd_array_init(&spec->verbs, sizeof(struct hda_verb *), 8);
v = snd_array_new(&spec->verbs);
if (!v)
return -ENOMEM;
diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h
index 2a7889dfbd1b..632ad0ad3007 100644
--- a/sound/pci/hda/hda_auto_parser.h
+++ b/sound/pci/hda/hda_auto_parser.h
@@ -157,4 +157,14 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
const struct snd_pci_quirk *quirk,
const struct hda_fixup *fixlist);
+static inline void snd_hda_gen_init(struct hda_gen_spec *spec)
+{
+ snd_array_init(&spec->verbs, sizeof(struct hda_verb *), 8);
+}
+
+static inline void snd_hda_gen_free(struct hda_gen_spec *spec)
+{
+ snd_array_free(&spec->verbs);
+}
+
#endif /* __SOUND_HDA_AUTO_PARSER_H */
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 41ca803a1fff..51cb2a2e4fce 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1184,6 +1184,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
{
if (!codec)
return;
+ snd_hda_jack_tbl_clear(codec);
restore_init_pincfgs(codec);
#ifdef CONFIG_SND_HDA_POWER_SAVE
cancel_delayed_work(&codec->power_work);
@@ -1192,6 +1193,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
list_del(&codec->list);
snd_array_free(&codec->mixers);
snd_array_free(&codec->nids);
+ snd_array_free(&codec->cvt_setups);
snd_array_free(&codec->conn_lists);
snd_array_free(&codec->spdif_out);
codec->bus->caddr_tbl[codec->addr] = NULL;
@@ -2333,6 +2335,8 @@ int snd_hda_codec_reset(struct hda_codec *codec)
/* free only driver_pins so that init_pins + user_pins are restored */
snd_array_free(&codec->driver_pins);
restore_pincfgs(codec);
+ snd_array_free(&codec->cvt_setups);
+ snd_array_free(&codec->spdif_out);
codec->num_pcms = 0;
codec->pcm_info = NULL;
codec->preset = NULL;
@@ -4393,20 +4397,19 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
codec->power_jiffies += delta;
}
-/**
- * snd_hda_power_up - Power-up the codec
- * @codec: HD-audio codec
- *
- * Increment the power-up counter and power up the hardware really when
- * not turned on yet.
- */
-void snd_hda_power_up(struct hda_codec *codec)
+/* Transition to powered up, if wait_power_down then wait for a pending
+ * transition to D3 to complete. A pending D3 transition is indicated
+ * with power_transition == -1. */
+static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
{
struct hda_bus *bus = codec->bus;
spin_lock(&codec->power_lock);
codec->power_count++;
- if (codec->power_on || codec->power_transition > 0) {
+ /* Return if power_on or transitioning to power_on, unless currently
+ * powering down. */
+ if ((codec->power_on || codec->power_transition > 0) &&
+ !(wait_power_down && codec->power_transition < 0)) {
spin_unlock(&codec->power_lock);
return;
}
@@ -4430,8 +4433,37 @@ void snd_hda_power_up(struct hda_codec *codec)
codec->power_transition = 0;
spin_unlock(&codec->power_lock);
}
+
+/**
+ * snd_hda_power_up - Power-up the codec
+ * @codec: HD-audio codec
+ *
+ * Increment the power-up counter and power up the hardware really when
+ * not turned on yet.
+ */
+void snd_hda_power_up(struct hda_codec *codec)
+{
+ __snd_hda_power_up(codec, false);
+}
EXPORT_SYMBOL_HDA(snd_hda_power_up);
+/**
+ * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending
+ * D3 transition to complete. This differs from snd_hda_power_up() when
+ * power_transition == -1. snd_hda_power_up sees this case as a nop,
+ * snd_hda_power_up_d3wait waits for the D3 transition to complete then powers
+ * back up.
+ * @codec: HD-audio codec
+ *
+ * Cancel any power down operation hapenning on the work queue, then power up.
+ */
+void snd_hda_power_up_d3wait(struct hda_codec *codec)
+{
+ /* This will cancel and wait for pending power_work to complete. */
+ __snd_hda_power_up(codec, true);
+}
+EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait);
+
#define power_save(codec) \
((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 4fc3960c8591..2fdaadbb4326 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -1056,10 +1056,12 @@ const char *snd_hda_get_jack_location(u32 cfg);
*/
#ifdef CONFIG_SND_HDA_POWER_SAVE
void snd_hda_power_up(struct hda_codec *codec);
+void snd_hda_power_up_d3wait(struct hda_codec *codec);
void snd_hda_power_down(struct hda_codec *codec);
void snd_hda_update_power_acct(struct hda_codec *codec);
#else
static inline void snd_hda_power_up(struct hda_codec *codec) {}
+static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) {}
static inline void snd_hda_power_down(struct hda_codec *codec) {}
#endif
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 2b6392be451c..7757536b9d5f 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1766,7 +1766,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
buff_step);
snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
buff_step);
- snd_hda_power_up(apcm->codec);
+ snd_hda_power_up_d3wait(apcm->codec);
err = hinfo->ops.open(hinfo, apcm->codec, substream);
if (err < 0) {
azx_release_device(azx_dev);
@@ -2484,9 +2484,9 @@ static void azx_notifier_unregister(struct azx *chip)
static int DELAYED_INIT_MARK azx_first_init(struct azx *chip);
static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip);
+#ifdef SUPPORT_VGA_SWITCHEROO
static struct pci_dev __devinit *get_bound_vga(struct pci_dev *pci);
-#ifdef SUPPORT_VGA_SWITCHEROO
static void azx_vs_set_state(struct pci_dev *pci,
enum vga_switcheroo_state state)
{
@@ -2578,6 +2578,7 @@ static int __devinit register_vga_switcheroo(struct azx *chip)
#else
#define init_vga_switcheroo(chip) /* NOP */
#define register_vga_switcheroo(chip) 0
+#define check_hdmi_disabled(pci) false
#endif /* SUPPORT_VGA_SWITCHER */
/*
@@ -2638,6 +2639,7 @@ static int azx_dev_free(struct snd_device *device)
return azx_free(device->device_data);
}
+#ifdef SUPPORT_VGA_SWITCHEROO
/*
* Check of disabled HDMI controller by vga-switcheroo
*/
@@ -2670,12 +2672,13 @@ static bool __devinit check_hdmi_disabled(struct pci_dev *pci)
struct pci_dev *p = get_bound_vga(pci);
if (p) {
- if (vga_default_device() && p != vga_default_device())
+ if (vga_switcheroo_get_client_state(p) == VGA_SWITCHEROO_OFF)
vga_inactive = true;
pci_dev_put(p);
}
return vga_inactive;
}
+#endif /* SUPPORT_VGA_SWITCHEROO */
/*
* white/black-listing for position_fix
@@ -3351,6 +3354,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
{ PCI_DEVICE(0x6549, 0x1200),
.driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
/* Creative X-Fi (CA0110-IBG) */
+ /* CTHDA chips */
+ { PCI_DEVICE(0x1102, 0x0010),
+ .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
+ { PCI_DEVICE(0x1102, 0x0012),
+ .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE)
/* the following entry conflicts with snd-ctxfi driver,
* as ctxfi driver mutates from HD-audio to native mode with
@@ -3367,11 +3375,6 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
.driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
#endif
- /* CTHDA chips */
- { PCI_DEVICE(0x1102, 0x0010),
- .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
- { PCI_DEVICE(0x1102, 0x0012),
- .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
/* Vortex86MX */
{ PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
/* VMware HDAudio */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 3acb5824ad39..2bf99fc1cbf2 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -445,8 +445,10 @@ static int conexant_init(struct hda_codec *codec)
static void conexant_free(struct hda_codec *codec)
{
+ struct conexant_spec *spec = codec->spec;
+ snd_hda_gen_free(&spec->gen);
snd_hda_detach_beep_device(codec);
- kfree(codec->spec);
+ kfree(spec);
}
static const struct snd_kcontrol_new cxt_capture_mixers[] = {
@@ -4061,7 +4063,7 @@ static void cx_auto_init_digital(struct hda_codec *codec)
static int cx_auto_init(struct hda_codec *codec)
{
struct conexant_spec *spec = codec->spec;
- /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
+ snd_hda_gen_apply_verbs(codec);
cx_auto_init_output(codec);
cx_auto_init_input(codec);
cx_auto_init_digital(codec);
@@ -4466,6 +4468,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
{}
};
@@ -4497,6 +4500,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
if (!spec)
return -ENOMEM;
codec->spec = spec;
+ snd_hda_gen_init(&spec->gen);
switch (codec->vendor_id) {
case 0x14f15045:
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 224410e8e9e7..5ccf10a4d593 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1896,6 +1896,7 @@ static int alc_init(struct hda_codec *codec)
alc_fix_pll(codec);
alc_auto_init_amp(codec, spec->init_amp);
+ snd_hda_gen_apply_verbs(codec);
alc_init_special_input_src(codec);
alc_auto_init_std(codec);
@@ -2288,6 +2289,7 @@ static void alc_free(struct hda_codec *codec)
alc_shutup(codec);
alc_free_kctls(codec);
alc_free_bind_ctls(codec);
+ snd_hda_gen_free(&spec->gen);
kfree(spec);
snd_hda_detach_beep_device(codec);
}
@@ -4252,6 +4254,7 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
return -ENOMEM;
codec->spec = spec;
spec->mixer_nid = mixer_nid;
+ snd_hda_gen_init(&spec->gen);
err = alc_codec_rename_from_preset(codec);
if (err < 0) {
@@ -6439,6 +6442,7 @@ enum {
ALC662_FIXUP_ASUS_MODE7,
ALC662_FIXUP_ASUS_MODE8,
ALC662_FIXUP_NO_JACK_DETECT,
+ ALC662_FIXUP_ZOTAC_Z68,
};
static const struct alc_fixup alc662_fixups[] = {
@@ -6588,6 +6592,13 @@ static const struct alc_fixup alc662_fixups[] = {
.type = ALC_FIXUP_FUNC,
.v.func = alc_fixup_no_jack_detect,
},
+ [ALC662_FIXUP_ZOTAC_Z68] = {
+ .type = ALC_FIXUP_PINS,
+ .v.pins = (const struct alc_pincfg[]) {
+ { 0x1b, 0x02214020 }, /* Front HP */
+ { }
+ }
+ },
};
static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -6601,6 +6612,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
+ SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
#if 0
@@ -6695,6 +6707,12 @@ static int patch_alc662(struct hda_codec *codec)
alc_fix_pll_init(codec, 0x20, 0x04, 15);
+ alc_pick_fixup(codec, alc662_fixup_models,
+ alc662_fixup_tbl, alc662_fixups);
+ alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
+
+ alc_auto_parse_customize_define(codec);
+
if ((alc_get_coef0(codec) & (1 << 14)) &&
codec->bus->pci->subsystem_vendor == 0x1025 &&
spec->cdefine.platform_type == 1) {
@@ -6702,12 +6720,6 @@ static int patch_alc662(struct hda_codec *codec)
goto error;
}
- alc_pick_fixup(codec, alc662_fixup_models,
- alc662_fixup_tbl, alc662_fixups);
- alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
- alc_auto_parse_customize_define(codec);
-
/* automatic parse from the BIOS config */
err = alc662_parse_auto_config(codec);
if (err < 0)
@@ -6790,6 +6802,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
+ { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
.patch = patch_alc861 },
{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7db8228f1b88..07675282015a 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4367,7 +4367,7 @@ static int stac92xx_init(struct hda_codec *codec)
AC_PINCTL_IN_EN);
for (i = 0; i < spec->num_pwrs; i++) {
hda_nid_t nid = spec->pwr_nids[i];
- int pinctl, def_conf;
+ unsigned int pinctl, def_conf;
def_conf = snd_hda_codec_get_pincfg(codec, nid);
def_conf = get_defcfg_connect(def_conf);
@@ -4376,6 +4376,11 @@ static int stac92xx_init(struct hda_codec *codec)
stac_toggle_power_map(codec, nid, 0);
continue;
}
+ if (def_conf == AC_JACK_PORT_FIXED) {
+ /* no need for jack detection for fixed pins */
+ stac_toggle_power_map(codec, nid, 1);
+ continue;
+ }
/* power on when no jack detection is available */
/* or when the VREF is used for controlling LED */
if (!spec->hp_detect ||