summaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.c150
-rw-r--r--sound/pci/hda/hda_codec.h12
-rw-r--r--sound/pci/hda/hda_intel.c6
-rw-r--r--sound/pci/hda/patch_conexant.c3
-rw-r--r--sound/pci/hda/patch_nvhdmi.c61
-rw-r--r--sound/pci/hda/patch_realtek.c41
-rw-r--r--sound/pci/hda/patch_sigmatel.c13
7 files changed, 254 insertions, 32 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index a7802b99436c..720a81d711e3 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -971,6 +971,36 @@ static void restore_init_pincfgs(struct hda_codec *codec)
}
/*
+ * audio-converter setup caches
+ */
+struct hda_cvt_setup {
+ hda_nid_t nid;
+ u8 stream_tag;
+ u8 channel_id;
+ u16 format_id;
+ unsigned char active; /* cvt is currently used */
+ unsigned char dirty; /* setups should be cleared */
+};
+
+/* get or create a cache entry for the given audio converter NID */
+static struct hda_cvt_setup *
+get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
+{
+ struct hda_cvt_setup *p;
+ int i;
+
+ for (i = 0; i < codec->cvt_setups.used; i++) {
+ p = snd_array_elem(&codec->cvt_setups, i);
+ if (p->nid == nid)
+ return p;
+ }
+ p = snd_array_new(&codec->cvt_setups);
+ if (p)
+ p->nid = nid;
+ return p;
+}
+
+/*
* codec destructor
*/
static void snd_hda_codec_free(struct hda_codec *codec)
@@ -1038,12 +1068,14 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
codec->addr = codec_addr;
mutex_init(&codec->spdif_mutex);
mutex_init(&codec->control_mutex);
+ mutex_init(&codec->prepare_mutex);
init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
+ snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
if (codec->bus->modelname) {
codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
if (!codec->modelname) {
@@ -1181,16 +1213,51 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
u32 stream_tag,
int channel_id, int format)
{
+ struct hda_cvt_setup *p;
+ unsigned int oldval, newval;
+ int i;
+
if (!nid)
return;
snd_printdd("hda_codec_setup_stream: "
"NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
nid, stream_tag, channel_id, format);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID,
- (stream_tag << 4) | channel_id);
- msleep(1);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
+ p = get_hda_cvt_setup(codec, nid);
+ if (!p)
+ return;
+ /* update the stream-id if changed */
+ if (p->stream_tag != stream_tag || p->channel_id != channel_id) {
+ oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
+ newval = (stream_tag << 4) | channel_id;
+ if (oldval != newval)
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_CHANNEL_STREAMID,
+ newval);
+ p->stream_tag = stream_tag;
+ p->channel_id = channel_id;
+ }
+ /* update the format-id if changed */
+ if (p->format_id != format) {
+ oldval = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_STREAM_FORMAT, 0);
+ if (oldval != format) {
+ msleep(1);
+ snd_hda_codec_write(codec, nid, 0,
+ AC_VERB_SET_STREAM_FORMAT,
+ format);
+ }
+ p->format_id = format;
+ }
+ p->active = 1;
+ p->dirty = 0;
+
+ /* make other inactive cvts with the same stream-tag dirty */
+ for (i = 0; i < codec->cvt_setups.used; i++) {
+ p = snd_array_elem(&codec->cvt_setups, i);
+ if (!p->active && p->stream_tag == stream_tag)
+ p->dirty = 1;
+ }
}
EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
@@ -1201,17 +1268,54 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
*/
void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
{
+ struct hda_cvt_setup *p;
+
if (!nid)
return;
snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid);
+ /* here we just clear the active flag; actual clean-ups will be done
+ * in purify_inactive_streams()
+ */
+ p = get_hda_cvt_setup(codec, nid);
+ if (p)
+ p->active = 0;
+}
+EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
+
+static void really_cleanup_stream(struct hda_codec *codec,
+ struct hda_cvt_setup *q)
+{
+ hda_nid_t nid = q->nid;
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
-#if 0 /* keep the format */
- msleep(1);
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
-#endif
+ memset(q, 0, sizeof(*q));
+ q->nid = nid;
+}
+
+/* clean up the all conflicting obsolete streams */
+static void purify_inactive_streams(struct hda_codec *codec)
+{
+ int i;
+
+ for (i = 0; i < codec->cvt_setups.used; i++) {
+ struct hda_cvt_setup *p = snd_array_elem(&codec->cvt_setups, i);
+ if (p->dirty)
+ really_cleanup_stream(codec, p);
+ }
+}
+
+/* clean up all streams; called from suspend */
+static void hda_cleanup_all_streams(struct hda_codec *codec)
+{
+ int i;
+
+ for (i = 0; i < codec->cvt_setups.used; i++) {
+ struct hda_cvt_setup *p = snd_array_elem(&codec->cvt_setups, i);
+ if (p->stream_tag)
+ really_cleanup_stream(codec, p);
+ }
}
-EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
/*
* amp access functions
@@ -2928,6 +3032,7 @@ static void hda_call_codec_suspend(struct hda_codec *codec)
{
if (codec->patch_ops.suspend)
codec->patch_ops.suspend(codec, PMSG_SUSPEND);
+ hda_cleanup_all_streams(codec);
hda_set_power_state(codec,
codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D3);
@@ -3377,6 +3482,35 @@ static int set_pcm_default_values(struct hda_codec *codec,
return 0;
}
+/*
+ * codec prepare/cleanup entries
+ */
+int snd_hda_codec_prepare(struct hda_codec *codec,
+ struct hda_pcm_stream *hinfo,
+ unsigned int stream,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ int ret;
+ mutex_lock(&codec->prepare_mutex);
+ ret = hinfo->ops.prepare(hinfo, codec, stream, format, substream);
+ if (ret >= 0)
+ purify_inactive_streams(codec);
+ mutex_unlock(&codec->prepare_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_HDA(snd_hda_codec_prepare);
+
+void snd_hda_codec_cleanup(struct hda_codec *codec,
+ struct hda_pcm_stream *hinfo,
+ struct snd_pcm_substream *substream)
+{
+ mutex_lock(&codec->prepare_mutex);
+ hinfo->ops.cleanup(hinfo, codec, substream);
+ mutex_unlock(&codec->prepare_mutex);
+}
+EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup);
+
/* global */
const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
"Audio", "SPDIF", "HDMI", "Modem"
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 0328cf55cdba..3f7a479881e5 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -826,12 +826,14 @@ struct hda_codec {
struct mutex spdif_mutex;
struct mutex control_mutex;
+ struct mutex prepare_mutex;
unsigned int spdif_status; /* IEC958 status bits */
unsigned short spdif_ctls; /* SPDIF control bits */
unsigned int spdif_in_enable; /* SPDIF input enable? */
hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
struct snd_array init_pins; /* initial (BIOS) pin configurations */
struct snd_array driver_pins; /* pin configs set by codec parser */
+ struct snd_array cvt_setups; /* audio convert setups */
#ifdef CONFIG_SND_HDA_HWDEP
struct snd_hwdep *hwdep; /* assigned hwdep device */
@@ -948,6 +950,16 @@ int snd_hda_codec_build_controls(struct hda_codec *codec);
*/
int snd_hda_build_pcms(struct hda_bus *bus);
int snd_hda_codec_build_pcms(struct hda_codec *codec);
+
+int snd_hda_codec_prepare(struct hda_codec *codec,
+ struct hda_pcm_stream *hinfo,
+ unsigned int stream,
+ unsigned int format,
+ struct snd_pcm_substream *substream);
+void snd_hda_codec_cleanup(struct hda_codec *codec,
+ struct hda_pcm_stream *hinfo,
+ struct snd_pcm_substream *substream);
+
void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
u32 stream_tag,
int channel_id, int format);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 66d420212d9a..1053fff4bd0a 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1634,7 +1634,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
azx_dev->period_bytes = 0;
azx_dev->format_val = 0;
- hinfo->ops.cleanup(hinfo, apcm->codec, substream);
+ snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
return snd_pcm_lib_free_pages(substream);
}
@@ -1688,8 +1688,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
else
azx_dev->fifo_size = 0;
- return hinfo->ops.prepare(hinfo, apcm->codec, azx_dev->stream_tag,
- azx_dev->format_val, substream);
+ return snd_hda_codec_prepare(apcm->codec, hinfo, azx_dev->stream_tag,
+ azx_dev->format_val, substream);
}
static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index df8b19b17308..f7e234e5ee96 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3206,6 +3206,8 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = {
.patch = patch_cxt5066 },
{ .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
.patch = patch_cxt5066 },
+ { .id = 0x14f15068, .name = "CX20584",
+ .patch = patch_cxt5066 },
{ .id = 0x14f15069, .name = "CX20585",
.patch = patch_cxt5066 },
{} /* terminator */
@@ -3216,6 +3218,7 @@ MODULE_ALIAS("snd-hda-codec-id:14f15047");
MODULE_ALIAS("snd-hda-codec-id:14f15051");
MODULE_ALIAS("snd-hda-codec-id:14f15066");
MODULE_ALIAS("snd-hda-codec-id:14f15067");
+MODULE_ALIAS("snd-hda-codec-id:14f15068");
MODULE_ALIAS("snd-hda-codec-id:14f15069");
MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index a281836fd472..77e2b4028b9f 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -540,26 +540,32 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
* patch entries
*/
static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
- { .id = 0x10de0002, .name = "MCP77/78 HDMI",
- .patch = patch_nvhdmi_8ch_7x },
- { .id = 0x10de0003, .name = "MCP77/78 HDMI",
- .patch = patch_nvhdmi_8ch_7x },
- { .id = 0x10de0005, .name = "MCP77/78 HDMI",
- .patch = patch_nvhdmi_8ch_7x },
- { .id = 0x10de0006, .name = "MCP77/78 HDMI",
- .patch = patch_nvhdmi_8ch_7x },
- { .id = 0x10de0007, .name = "MCP79/7A HDMI",
- .patch = patch_nvhdmi_8ch_7x },
- { .id = 0x10de000a, .name = "GT220 HDMI",
- .patch = patch_nvhdmi_8ch_89 },
- { .id = 0x10de000b, .name = "GT21x HDMI",
- .patch = patch_nvhdmi_8ch_89 },
- { .id = 0x10de000c, .name = "MCP89 HDMI",
- .patch = patch_nvhdmi_8ch_89 },
- { .id = 0x10de000d, .name = "GT240 HDMI",
- .patch = patch_nvhdmi_8ch_89 },
- { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
- { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
+ { .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de0003, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x },
+ { .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi_8ch_89 },
+ { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
+ { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
{} /* terminator */
};
@@ -572,6 +578,21 @@ MODULE_ALIAS("snd-hda-codec-id:10de000a");
MODULE_ALIAS("snd-hda-codec-id:10de000b");
MODULE_ALIAS("snd-hda-codec-id:10de000c");
MODULE_ALIAS("snd-hda-codec-id:10de000d");
+MODULE_ALIAS("snd-hda-codec-id:10de0010");
+MODULE_ALIAS("snd-hda-codec-id:10de0011");
+MODULE_ALIAS("snd-hda-codec-id:10de0012");
+MODULE_ALIAS("snd-hda-codec-id:10de0013");
+MODULE_ALIAS("snd-hda-codec-id:10de0014");
+MODULE_ALIAS("snd-hda-codec-id:10de0018");
+MODULE_ALIAS("snd-hda-codec-id:10de0019");
+MODULE_ALIAS("snd-hda-codec-id:10de001a");
+MODULE_ALIAS("snd-hda-codec-id:10de001b");
+MODULE_ALIAS("snd-hda-codec-id:10de001c");
+MODULE_ALIAS("snd-hda-codec-id:10de0040");
+MODULE_ALIAS("snd-hda-codec-id:10de0041");
+MODULE_ALIAS("snd-hda-codec-id:10de0042");
+MODULE_ALIAS("snd-hda-codec-id:10de0043");
+MODULE_ALIAS("snd-hda-codec-id:10de0044");
MODULE_ALIAS("snd-hda-codec-id:10de0067");
MODULE_ALIAS("snd-hda-codec-id:10de8001");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 6ac53f7de549..55d6e5b6bb7d 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -137,6 +137,7 @@ enum {
ALC269VB_DMIC,
ALC269_FUJITSU,
ALC269_LIFEBOOK,
+ ALC271_ACER,
ALC269_AUTO,
ALC269_MODEL_LAST /* last tag */
};
@@ -7041,6 +7042,7 @@ static int patch_alc260(struct hda_codec *codec)
spec->stream_analog_playback = &alc260_pcm_analog_playback;
spec->stream_analog_capture = &alc260_pcm_analog_capture;
+ spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
spec->stream_digital_playback = &alc260_pcm_digital_playback;
spec->stream_digital_capture = &alc260_pcm_digital_capture;
@@ -13475,7 +13477,6 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
- SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
{}
};
@@ -13866,6 +13867,12 @@ static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
{ } /* end */
};
+static struct snd_kcontrol_new alc269_asus_mixer[] = {
+ HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+ HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
+ { } /* end */
+};
+
/* capture mixer elements */
static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
@@ -14086,6 +14093,20 @@ static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
{}
};
+static struct hda_verb alc271_acer_dmic_verbs[] = {
+ {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
+ {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
+ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+ {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+ {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
+ {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+ {0x22, AC_VERB_SET_CONNECT_SEL, 6},
+ { }
+};
+
/* toggle speaker-output according to the hp-jack state */
static void alc269_speaker_automute(struct hda_codec *codec)
{
@@ -14465,6 +14486,7 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
static struct snd_pci_quirk alc269_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
+ SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
ALC269_AMIC),
SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
@@ -14626,6 +14648,23 @@ static struct alc_config_preset alc269_presets[] = {
.unsol_event = alc269_lifebook_unsol_event,
.init_hook = alc269_lifebook_init_hook,
},
+ [ALC271_ACER] = {
+ .mixers = { alc269_asus_mixer },
+ .cap_mixer = alc269vb_laptop_digital_capture_mixer,
+ .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
+ .num_dacs = ARRAY_SIZE(alc269_dac_nids),
+ .dac_nids = alc269_dac_nids,
+ .adc_nids = alc262_dmic_adc_nids,
+ .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
+ .capsrc_nids = alc262_dmic_capsrc_nids,
+ .num_channel_mode = ARRAY_SIZE(alc269_modes),
+ .channel_mode = alc269_modes,
+ .input_mux = &alc269_capture_source,
+ .dig_out_nid = ALC880_DIGOUT_NID,
+ .unsol_event = alc_sku_unsol_event,
+ .setup = alc269vb_laptop_dmic_setup,
+ .init_hook = alc_inithook,
+ },
};
static int patch_alc269(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index b8d730c47df1..f3f861bd1bf8 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -94,6 +94,7 @@ enum {
STAC_92HD83XXX_PWR_REF,
STAC_DELL_S14,
STAC_92HD83XXX_HP,
+ STAC_HP_DV7_4000,
STAC_92HD83XXX_MODELS
};
@@ -1632,10 +1633,17 @@ static unsigned int dell_s14_pin_configs[10] = {
0x40f000f0, 0x40f000f0,
};
+static unsigned int hp_dv7_4000_pin_configs[10] = {
+ 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
+ 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
+ 0x40f000f0, 0x40f000f0,
+};
+
static 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_HP_DV7_4000] = hp_dv7_4000_pin_configs,
};
static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
@@ -1644,6 +1652,7 @@ static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
[STAC_92HD83XXX_PWR_REF] = "mic-ref",
[STAC_DELL_S14] = "dell-s14",
[STAC_92HD83XXX_HP] = "hp",
+ [STAC_HP_DV7_4000] = "hp-dv7-4000",
};
static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -5340,6 +5349,8 @@ again:
case 0x111d7667:
case 0x111d7668:
case 0x111d7669:
+ case 0x111d76d1:
+ case 0x111d76d9:
spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
spec->pin_nids = stac92hd88xxx_pin_nids;
spec->mono_nid = 0;
@@ -6274,6 +6285,8 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
{ .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
{ .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
{ .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d76d1, .name = "92HD87B1/3", .patch = patch_stac92hd83xxx},
+ { .id = 0x111d76d9, .name = "92HD87B2/4", .patch = patch_stac92hd83xxx},
{ .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
{ .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
{ .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},