Linux Audio

Check our new training course

Loading...
v3.15
   1/*
   2 * Universal Interface for Intel High Definition Audio Codec
   3 *
   4 * HD audio interface patch for Realtek ALC codecs
   5 *
   6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
   7 *                    PeiSen Hou <pshou@realtek.com.tw>
   8 *                    Takashi Iwai <tiwai@suse.de>
   9 *                    Jonathan Woithe <jwoithe@just42.net>
  10 *
  11 *  This driver is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License as published by
  13 *  the Free Software Foundation; either version 2 of the License, or
  14 *  (at your option) any later version.
  15 *
  16 *  This driver is distributed in the hope that it will be useful,
  17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 *  GNU General Public License for more details.
  20 *
  21 *  You should have received a copy of the GNU General Public License
  22 *  along with this program; if not, write to the Free Software
  23 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  24 */
  25
  26#include <linux/init.h>
  27#include <linux/delay.h>
  28#include <linux/slab.h>
  29#include <linux/pci.h>
  30#include <linux/dmi.h>
  31#include <linux/module.h>
  32#include <sound/core.h>
  33#include <sound/jack.h>
  34#include "hda_codec.h"
  35#include "hda_local.h"
  36#include "hda_auto_parser.h"
 
  37#include "hda_jack.h"
  38#include "hda_generic.h"
  39
  40/* keep halting ALC5505 DSP, for power saving */
  41#define HALT_REALTEK_ALC5505
  42
  43/* unsol event tags */
  44#define ALC_DCVOL_EVENT		0x08
 
 
 
  45
  46/* for GPIO Poll */
  47#define GPIO_MASK	0x03
  48
  49/* extra amp-initialization sequence types */
  50enum {
  51	ALC_INIT_NONE,
  52	ALC_INIT_DEFAULT,
  53	ALC_INIT_GPIO1,
  54	ALC_INIT_GPIO2,
  55	ALC_INIT_GPIO3,
  56};
  57
  58enum {
  59	ALC_HEADSET_MODE_UNKNOWN,
  60	ALC_HEADSET_MODE_UNPLUGGED,
  61	ALC_HEADSET_MODE_HEADSET,
  62	ALC_HEADSET_MODE_MIC,
  63	ALC_HEADSET_MODE_HEADPHONE,
  64};
  65
  66enum {
  67	ALC_HEADSET_TYPE_UNKNOWN,
  68	ALC_HEADSET_TYPE_CTIA,
  69	ALC_HEADSET_TYPE_OMTP,
  70};
  71
  72struct alc_customize_define {
  73	unsigned int  sku_cfg;
  74	unsigned char port_connectivity;
  75	unsigned char check_sum;
  76	unsigned char customization;
  77	unsigned char external_amp;
  78	unsigned int  enable_pcbeep:1;
  79	unsigned int  platform_type:1;
  80	unsigned int  swap:1;
  81	unsigned int  override:1;
  82	unsigned int  fixup:1; /* Means that this sku is set by driver, not read from hw */
  83};
  84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  85struct alc_spec {
  86	struct hda_gen_spec gen; /* must be at head */
  87
  88	/* codec parameterization */
  89	const struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
  90	unsigned int num_mixers;
 
  91	unsigned int beep_amp;	/* beep amp value, set via set_beep_amp() */
  92
  93	struct alc_customize_define cdefine;
  94	unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  95
  96	/* inverted dmic fix */
  97	unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */
  98	unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */
  99	hda_nid_t inv_dmic_pin;
 100
 101	/* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
 102	int mute_led_polarity;
 103	hda_nid_t mute_led_nid;
 104
 105	unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
 106
 107	hda_nid_t headset_mic_pin;
 108	hda_nid_t headphone_mic_pin;
 109	int current_headset_mode;
 110	int current_headset_type;
 111
 112	/* hooks */
 113	void (*init_hook)(struct hda_codec *codec);
 114#ifdef CONFIG_PM
 
 115	void (*power_hook)(struct hda_codec *codec);
 116#endif
 117	void (*shutup)(struct hda_codec *codec);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 118
 119	int init_amp;
 120	int codec_variant;	/* flag for other variants */
 121	unsigned int has_alc5505_dsp:1;
 122	unsigned int no_depop_delay:1;
 
 
 
 
 
 
 
 123
 124	/* for PLL fix */
 125	hda_nid_t pll_nid;
 126	unsigned int pll_coef_idx, pll_coef_bit;
 127	unsigned int coef0;
 
 
 
 
 
 
 
 128};
 129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 130/*
 131 * Append the given mixer and verb elements for the later use
 132 * The mixer array is referred in build_controls(), and init_verbs are
 133 * called in init().
 134 */
 135static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
 136{
 137	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
 138		return;
 139	spec->mixers[spec->num_mixers++] = mix;
 140}
 141
 142/*
 143 * GPIO setup tables, used in initialization
 144 */
 145/* Enable GPIO mask and set output */
 146static const struct hda_verb alc_gpio1_init_verbs[] = {
 147	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
 148	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
 149	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
 150	{ }
 151};
 152
 153static const struct hda_verb alc_gpio2_init_verbs[] = {
 154	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
 155	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
 156	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
 157	{ }
 158};
 159
 160static const struct hda_verb alc_gpio3_init_verbs[] = {
 161	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
 162	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
 163	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
 164	{ }
 165};
 166
 167/*
 168 * Fix hardware PLL issue
 169 * On some codecs, the analog PLL gating control must be off while
 170 * the default value is 1.
 171 */
 172static void alc_fix_pll(struct hda_codec *codec)
 173{
 174	struct alc_spec *spec = codec->spec;
 175	unsigned int val;
 176
 177	if (!spec->pll_nid)
 178		return;
 179	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
 180			    spec->pll_coef_idx);
 181	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
 182				 AC_VERB_GET_PROC_COEF, 0);
 183	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
 184			    spec->pll_coef_idx);
 185	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
 186			    val & ~(1 << spec->pll_coef_bit));
 187}
 188
 189static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
 190			     unsigned int coef_idx, unsigned int coef_bit)
 191{
 192	struct alc_spec *spec = codec->spec;
 193	spec->pll_nid = nid;
 194	spec->pll_coef_idx = coef_idx;
 195	spec->pll_coef_bit = coef_bit;
 196	alc_fix_pll(codec);
 197}
 198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 199/* update the master volume per volume-knob's unsol event */
 200static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack)
 201{
 202	unsigned int val;
 203	struct snd_kcontrol *kctl;
 204	struct snd_ctl_elem_value *uctl;
 205
 206	kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
 207	if (!kctl)
 208		return;
 209	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 210	if (!uctl)
 211		return;
 212	val = snd_hda_codec_read(codec, jack->nid, 0,
 213				 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
 214	val &= HDA_AMP_VOLMASK;
 215	uctl->value.integer.value[0] = val;
 216	uctl->value.integer.value[1] = val;
 217	kctl->put(kctl, uctl);
 218	kfree(uctl);
 219}
 220
 221static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 222{
 223	/* For some reason, the res given from ALC880 is broken.
 224	   Here we adjust it properly. */
 225	snd_hda_jack_unsol_event(codec, res >> 2);
 226}
 227
 228/* additional initialization for ALC888 variants */
 229static void alc888_coef_init(struct hda_codec *codec)
 230{
 231	unsigned int tmp;
 232
 233	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
 234	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
 235	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
 236	if ((tmp & 0xf0) == 0x20)
 237		/* alc888S-VC */
 238		snd_hda_codec_read(codec, 0x20, 0,
 239				   AC_VERB_SET_PROC_COEF, 0x830);
 240	 else
 241		 /* alc888-VB */
 242		 snd_hda_codec_read(codec, 0x20, 0,
 243				    AC_VERB_SET_PROC_COEF, 0x3030);
 244}
 245
 246/* additional initialization for ALC889 variants */
 247static void alc889_coef_init(struct hda_codec *codec)
 248{
 249	unsigned int tmp;
 250
 251	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
 252	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
 253	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
 254	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
 255}
 256
 257/* turn on/off EAPD control (only if available) */
 258static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
 259{
 260	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
 261		return;
 262	if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
 263		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
 264				    on ? 2 : 0);
 265}
 266
 267/* turn on/off EAPD controls of the codec */
 268static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
 269{
 270	/* We currently only handle front, HP */
 271	static hda_nid_t pins[] = {
 272		0x0f, 0x10, 0x14, 0x15, 0
 273	};
 274	hda_nid_t *p;
 275	for (p = pins; *p; p++)
 276		set_eapd(codec, *p, on);
 277}
 278
 279/* generic shutup callback;
 280 * just turning off EPAD and a little pause for avoiding pop-noise
 281 */
 282static void alc_eapd_shutup(struct hda_codec *codec)
 283{
 284	struct alc_spec *spec = codec->spec;
 285
 286	alc_auto_setup_eapd(codec, false);
 287	if (!spec->no_depop_delay)
 288		msleep(200);
 289	snd_hda_shutup_pins(codec);
 290}
 291
 292/* generic EAPD initialization */
 293static void alc_auto_init_amp(struct hda_codec *codec, int type)
 294{
 295	unsigned int tmp;
 296
 297	alc_auto_setup_eapd(codec, true);
 298	switch (type) {
 299	case ALC_INIT_GPIO1:
 300		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
 301		break;
 302	case ALC_INIT_GPIO2:
 303		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
 304		break;
 305	case ALC_INIT_GPIO3:
 306		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
 307		break;
 308	case ALC_INIT_DEFAULT:
 309		switch (codec->vendor_id) {
 310		case 0x10ec0260:
 311			snd_hda_codec_write(codec, 0x1a, 0,
 312					    AC_VERB_SET_COEF_INDEX, 7);
 313			tmp = snd_hda_codec_read(codec, 0x1a, 0,
 314						 AC_VERB_GET_PROC_COEF, 0);
 315			snd_hda_codec_write(codec, 0x1a, 0,
 316					    AC_VERB_SET_COEF_INDEX, 7);
 317			snd_hda_codec_write(codec, 0x1a, 0,
 318					    AC_VERB_SET_PROC_COEF,
 319					    tmp | 0x2010);
 320			break;
 321		case 0x10ec0262:
 322		case 0x10ec0880:
 323		case 0x10ec0882:
 324		case 0x10ec0883:
 325		case 0x10ec0885:
 326		case 0x10ec0887:
 327		/*case 0x10ec0889:*/ /* this causes an SPDIF problem */
 328			alc889_coef_init(codec);
 329			break;
 330		case 0x10ec0888:
 331			alc888_coef_init(codec);
 332			break;
 333#if 0 /* XXX: This may cause the silent output on speaker on some machines */
 334		case 0x10ec0267:
 335		case 0x10ec0268:
 336			snd_hda_codec_write(codec, 0x20, 0,
 337					    AC_VERB_SET_COEF_INDEX, 7);
 338			tmp = snd_hda_codec_read(codec, 0x20, 0,
 339						 AC_VERB_GET_PROC_COEF, 0);
 340			snd_hda_codec_write(codec, 0x20, 0,
 341					    AC_VERB_SET_COEF_INDEX, 7);
 342			snd_hda_codec_write(codec, 0x20, 0,
 343					    AC_VERB_SET_PROC_COEF,
 344					    tmp | 0x3000);
 345			break;
 346#endif /* XXX */
 347		}
 348		break;
 349	}
 350}
 351
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 352
 353/*
 354 * Realtek SSID verification
 355 */
 356
 357/* Could be any non-zero and even value. When used as fixup, tells
 358 * the driver to ignore any present sku defines.
 359 */
 360#define ALC_FIXUP_SKU_IGNORE (2)
 361
 362static void alc_fixup_sku_ignore(struct hda_codec *codec,
 363				 const struct hda_fixup *fix, int action)
 364{
 365	struct alc_spec *spec = codec->spec;
 366	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
 367		spec->cdefine.fixup = 1;
 368		spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
 369	}
 370}
 371
 372static void alc_fixup_no_depop_delay(struct hda_codec *codec,
 373				    const struct hda_fixup *fix, int action)
 374{
 375	struct alc_spec *spec = codec->spec;
 376
 377	if (action == HDA_FIXUP_ACT_PROBE) {
 378		spec->no_depop_delay = 1;
 379		codec->depop_delay = 0;
 380	}
 381}
 382
 383static int alc_auto_parse_customize_define(struct hda_codec *codec)
 384{
 385	unsigned int ass, tmp, i;
 386	unsigned nid = 0;
 387	struct alc_spec *spec = codec->spec;
 388
 389	spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
 390
 391	if (spec->cdefine.fixup) {
 392		ass = spec->cdefine.sku_cfg;
 393		if (ass == ALC_FIXUP_SKU_IGNORE)
 394			return -1;
 395		goto do_sku;
 396	}
 397
 398	if (!codec->bus->pci)
 399		return -1;
 400	ass = codec->subsystem_id & 0xffff;
 401	if (ass != codec->bus->pci->subsystem_device && (ass & 1))
 402		goto do_sku;
 403
 404	nid = 0x1d;
 405	if (codec->vendor_id == 0x10ec0260)
 406		nid = 0x17;
 407	ass = snd_hda_codec_get_pincfg(codec, nid);
 408
 409	if (!(ass & 1)) {
 410		codec_info(codec, "%s: SKU not ready 0x%08x\n",
 411			   codec->chip_name, ass);
 412		return -1;
 413	}
 414
 415	/* check sum */
 416	tmp = 0;
 417	for (i = 1; i < 16; i++) {
 418		if ((ass >> i) & 1)
 419			tmp++;
 420	}
 421	if (((ass >> 16) & 0xf) != tmp)
 422		return -1;
 423
 424	spec->cdefine.port_connectivity = ass >> 30;
 425	spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
 426	spec->cdefine.check_sum = (ass >> 16) & 0xf;
 427	spec->cdefine.customization = ass >> 8;
 428do_sku:
 429	spec->cdefine.sku_cfg = ass;
 430	spec->cdefine.external_amp = (ass & 0x38) >> 3;
 431	spec->cdefine.platform_type = (ass & 0x4) >> 2;
 432	spec->cdefine.swap = (ass & 0x2) >> 1;
 433	spec->cdefine.override = ass & 0x1;
 434
 435	codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
 436		   nid, spec->cdefine.sku_cfg);
 437	codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
 438		   spec->cdefine.port_connectivity);
 439	codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
 440	codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
 441	codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
 442	codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
 443	codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
 444	codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
 445	codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
 446
 447	return 0;
 448}
 449
 450/* return the position of NID in the list, or -1 if not found */
 451static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
 452{
 453	int i;
 454	for (i = 0; i < nums; i++)
 455		if (list[i] == nid)
 456			return i;
 457	return -1;
 458}
 459/* return true if the given NID is found in the list */
 460static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
 461{
 462	return find_idx_in_nid_list(nid, list, nums) >= 0;
 463}
 464
 465/* check subsystem ID and set up device-specific initialization;
 466 * return 1 if initialized, 0 if invalid SSID
 467 */
 468/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
 469 *	31 ~ 16 :	Manufacture ID
 470 *	15 ~ 8	:	SKU ID
 471 *	7  ~ 0	:	Assembly ID
 472 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
 473 */
 474static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
 
 
 475{
 476	unsigned int ass, tmp, i;
 477	unsigned nid;
 478	struct alc_spec *spec = codec->spec;
 479
 480	if (spec->cdefine.fixup) {
 481		ass = spec->cdefine.sku_cfg;
 482		if (ass == ALC_FIXUP_SKU_IGNORE)
 483			return 0;
 484		goto do_sku;
 485	}
 486
 487	ass = codec->subsystem_id & 0xffff;
 488	if (codec->bus->pci &&
 489	    ass != codec->bus->pci->subsystem_device && (ass & 1))
 490		goto do_sku;
 491
 492	/* invalid SSID, check the special NID pin defcfg instead */
 493	/*
 494	 * 31~30	: port connectivity
 495	 * 29~21	: reserve
 496	 * 20		: PCBEEP input
 497	 * 19~16	: Check sum (15:1)
 498	 * 15~1		: Custom
 499	 * 0		: override
 500	*/
 501	nid = 0x1d;
 502	if (codec->vendor_id == 0x10ec0260)
 503		nid = 0x17;
 504	ass = snd_hda_codec_get_pincfg(codec, nid);
 505	codec_dbg(codec,
 506		  "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
 507		   ass, nid);
 508	if (!(ass & 1))
 509		return 0;
 510	if ((ass >> 30) != 1)	/* no physical connection */
 511		return 0;
 512
 513	/* check sum */
 514	tmp = 0;
 515	for (i = 1; i < 16; i++) {
 516		if ((ass >> i) & 1)
 517			tmp++;
 518	}
 519	if (((ass >> 16) & 0xf) != tmp)
 520		return 0;
 521do_sku:
 522	codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
 523		   ass & 0xffff, codec->vendor_id);
 524	/*
 525	 * 0 : override
 526	 * 1 :	Swap Jack
 527	 * 2 : 0 --> Desktop, 1 --> Laptop
 528	 * 3~5 : External Amplifier control
 529	 * 7~6 : Reserved
 530	*/
 531	tmp = (ass & 0x38) >> 3;	/* external Amp control */
 532	switch (tmp) {
 533	case 1:
 534		spec->init_amp = ALC_INIT_GPIO1;
 535		break;
 536	case 3:
 537		spec->init_amp = ALC_INIT_GPIO2;
 538		break;
 539	case 7:
 540		spec->init_amp = ALC_INIT_GPIO3;
 541		break;
 542	case 5:
 543	default:
 544		spec->init_amp = ALC_INIT_DEFAULT;
 545		break;
 546	}
 547
 548	/* is laptop or Desktop and enable the function "Mute internal speaker
 549	 * when the external headphone out jack is plugged"
 550	 */
 551	if (!(ass & 0x8000))
 552		return 1;
 553	/*
 554	 * 10~8 : Jack location
 555	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
 556	 * 14~13: Resvered
 557	 * 15   : 1 --> enable the function "Mute internal speaker
 558	 *	        when the external headphone out jack is plugged"
 559	 */
 560	if (!spec->gen.autocfg.hp_pins[0] &&
 561	    !(spec->gen.autocfg.line_out_pins[0] &&
 562	      spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
 563		hda_nid_t nid;
 564		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
 565		nid = ports[tmp];
 566		if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
 567				      spec->gen.autocfg.line_outs))
 
 
 
 
 
 
 
 
 
 568			return 1;
 569		spec->gen.autocfg.hp_pins[0] = nid;
 570	}
 571	return 1;
 572}
 573
 574/* Check the validity of ALC subsystem-id
 575 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
 576static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
 577{
 578	if (!alc_subsystem_id(codec, ports)) {
 579		struct alc_spec *spec = codec->spec;
 580		codec_dbg(codec,
 581			  "realtek: Enable default setup for auto mode as fallback\n");
 582		spec->init_amp = ALC_INIT_DEFAULT;
 583	}
 584}
 585
 586/*
 587 * COEF access helper functions
 588 */
 589
 590static int alc_read_coefex_idx(struct hda_codec *codec,
 591					hda_nid_t nid,
 592					unsigned int coef_idx)
 593{
 594	unsigned int val;
 595	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX,
 596		    		coef_idx);
 597	val = snd_hda_codec_read(codec, nid, 0,
 598			 	AC_VERB_GET_PROC_COEF, 0);
 599	return val;
 600}
 601
 602#define alc_read_coef_idx(codec, coef_idx) \
 603	alc_read_coefex_idx(codec, 0x20, coef_idx)
 604
 605static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
 606							unsigned int coef_idx,
 607							unsigned int coef_val)
 608{
 609	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX,
 610			    coef_idx);
 611	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF,
 612			    coef_val);
 613}
 614
 615#define alc_write_coef_idx(codec, coef_idx, coef_val) \
 616	alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
 617
 618/* a special bypass for COEF 0; read the cached value at the second time */
 619static unsigned int alc_get_coef0(struct hda_codec *codec)
 620{
 621	struct alc_spec *spec = codec->spec;
 622	if (!spec->coef0)
 623		spec->coef0 = alc_read_coef_idx(codec, 0);
 624	return spec->coef0;
 625}
 626
 627/*
 
 628 */
 629
 630static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx)
 631{
 632	struct hda_gen_spec *spec = codec->spec;
 633	if (spec->dyn_adc_switch)
 634		adc_idx = spec->dyn_adc_idx[imux_idx];
 635	return spec->adc_nids[adc_idx];
 636}
 637
 638static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx)
 639{
 640	struct alc_spec *spec = codec->spec;
 641	struct hda_input_mux *imux = &spec->gen.input_mux;
 642	struct nid_path *path;
 643	hda_nid_t nid;
 644	int i, dir, parm;
 645	unsigned int val;
 646
 647	for (i = 0; i < imux->num_items; i++) {
 648		if (spec->gen.imux_pins[i] == spec->inv_dmic_pin)
 649			break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 650	}
 651	if (i >= imux->num_items)
 652		return;
 653
 654	path = snd_hda_get_nid_path(codec, spec->inv_dmic_pin,
 655				    get_adc_nid(codec, adc_idx, i));
 656	val = path->ctls[NID_PATH_MUTE_CTL];
 657	if (!val)
 658		return;
 659	nid = get_amp_nid_(val);
 660	dir = get_amp_direction_(val);
 661	parm = AC_AMP_SET_RIGHT |
 662		(dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT);
 663
 664	/* flush all cached amps at first */
 665	snd_hda_codec_flush_cache(codec);
 666
 667	/* we care only right channel */
 668	val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0);
 669	if (val & 0x80) /* if already muted, we don't need to touch */
 670		return;
 671	val |= 0x80;
 672	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
 673			    parm | val);
 674}
 675
 676/*
 677 * Inverted digital-mic handling
 678 *
 679 * First off, it's a bit tricky.  The "Inverted Internal Mic Capture Switch"
 680 * gives the additional mute only to the right channel of the digital mic
 681 * capture stream.  This is a workaround for avoiding the almost silence
 682 * by summing the stereo stream from some (known to be ForteMedia)
 683 * digital mic unit.
 684 *
 685 * The logic is to call alc_inv_dmic_sync() after each action (possibly)
 686 * modifying ADC amp.  When the mute flag is set, it mutes the R-channel
 687 * without caching so that the cache can still keep the original value.
 688 * The cached value is then restored when the flag is set off or any other
 689 * than d-mic is used as the current input source.
 690 */
 691static void alc_inv_dmic_sync(struct hda_codec *codec, bool force)
 
 692{
 
 693	struct alc_spec *spec = codec->spec;
 694	int src, nums;
 695
 696	if (!spec->inv_dmic_fixup)
 697		return;
 698	if (!spec->inv_dmic_muted && !force)
 699		return;
 700	nums = spec->gen.dyn_adc_switch ? 1 : spec->gen.num_adc_nids;
 701	for (src = 0; src < nums; src++) {
 702		bool dmic_fixup = false;
 703
 704		if (spec->inv_dmic_muted &&
 705		    spec->gen.imux_pins[spec->gen.cur_mux[src]] == spec->inv_dmic_pin)
 706			dmic_fixup = true;
 707		if (!dmic_fixup && !force)
 708			continue;
 709		alc_inv_dmic_sync_adc(codec, src);
 710	}
 711}
 712
 713static void alc_inv_dmic_hook(struct hda_codec *codec,
 714			      struct snd_kcontrol *kcontrol,
 715			      struct snd_ctl_elem_value *ucontrol)
 716{
 717	alc_inv_dmic_sync(codec, false);
 
 
 
 
 718}
 719
 720static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol,
 721			       struct snd_ctl_elem_value *ucontrol)
 722{
 723	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 724	struct alc_spec *spec = codec->spec;
 
 
 725
 726	ucontrol->value.integer.value[0] = !spec->inv_dmic_muted;
 727	return 0;
 
 
 
 
 
 
 
 728}
 729
 730static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol,
 731			       struct snd_ctl_elem_value *ucontrol)
 
 
 
 
 732{
 733	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 734	struct alc_spec *spec = codec->spec;
 735	unsigned int val = !ucontrol->value.integer.value[0];
 736
 737	if (val == spec->inv_dmic_muted)
 738		return 0;
 739	spec->inv_dmic_muted = val;
 740	alc_inv_dmic_sync(codec, true);
 741	return 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 742}
 743
 744static const struct snd_kcontrol_new alc_inv_dmic_sw = {
 745	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 746	.name = "Inverted Internal Mic Capture Switch",
 747	.info = snd_ctl_boolean_mono_info,
 748	.get = alc_inv_dmic_sw_get,
 749	.put = alc_inv_dmic_sw_put,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 750};
 751
 752static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid)
 753{
 754	struct alc_spec *spec = codec->spec;
 755
 756	if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &alc_inv_dmic_sw))
 757		return -ENOMEM;
 758	spec->inv_dmic_fixup = 1;
 759	spec->inv_dmic_muted = 0;
 760	spec->inv_dmic_pin = nid;
 761	spec->gen.cap_sync_hook = alc_inv_dmic_hook;
 762	return 0;
 763}
 764
 765/* typically the digital mic is put at node 0x12 */
 766static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec,
 767				    const struct hda_fixup *fix, int action)
 768{
 769	if (action == HDA_FIXUP_ACT_PROBE)
 770		alc_add_inv_dmic_mixer(codec, 0x12);
 771}
 772
 
 773
 774#ifdef CONFIG_SND_HDA_INPUT_BEEP
 775/* additional beep mixers; the actual parameters are overwritten at build */
 776static const struct snd_kcontrol_new alc_beep_mixer[] = {
 777	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
 778	HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
 779	{ } /* end */
 780};
 781#endif
 782
 783static int alc_build_controls(struct hda_codec *codec)
 784{
 785	struct alc_spec *spec = codec->spec;
 786	int i, err;
 787
 788	err = snd_hda_gen_build_controls(codec);
 789	if (err < 0)
 790		return err;
 791
 792	for (i = 0; i < spec->num_mixers; i++) {
 793		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
 794		if (err < 0)
 795			return err;
 796	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 797
 798#ifdef CONFIG_SND_HDA_INPUT_BEEP
 799	/* create beep controls if needed */
 800	if (spec->beep_amp) {
 801		const struct snd_kcontrol_new *knew;
 802		for (knew = alc_beep_mixer; knew->name; knew++) {
 803			struct snd_kcontrol *kctl;
 804			kctl = snd_ctl_new1(knew, codec);
 805			if (!kctl)
 806				return -ENOMEM;
 807			kctl->private_value = spec->beep_amp;
 808			err = snd_hda_ctl_add(codec, 0, kctl);
 809			if (err < 0)
 810				return err;
 811		}
 812	}
 813#endif
 814
 815	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 816	return 0;
 817}
 818
 819
 820/*
 821 * Common callbacks
 822 */
 823
 
 
 
 824static int alc_init(struct hda_codec *codec)
 825{
 826	struct alc_spec *spec = codec->spec;
 827
 828	if (spec->init_hook)
 829		spec->init_hook(codec);
 830
 831	alc_fix_pll(codec);
 832	alc_auto_init_amp(codec, spec->init_amp);
 833
 834	snd_hda_gen_init(codec);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 835
 836	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 837
 838	return 0;
 839}
 840
 841static inline void alc_shutup(struct hda_codec *codec)
 842{
 843	struct alc_spec *spec = codec->spec;
 844
 845	if (spec && spec->shutup)
 846		spec->shutup(codec);
 847	else
 848		snd_hda_shutup_pins(codec);
 849}
 850
 851#define alc_free	snd_hda_gen_free
 
 
 
 
 
 
 
 
 
 
 
 852
 853#ifdef CONFIG_PM
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 854static void alc_power_eapd(struct hda_codec *codec)
 855{
 856	alc_auto_setup_eapd(codec, false);
 857}
 858
 859static int alc_suspend(struct hda_codec *codec)
 860{
 861	struct alc_spec *spec = codec->spec;
 862	alc_shutup(codec);
 863	if (spec && spec->power_hook)
 864		spec->power_hook(codec);
 865	return 0;
 866}
 867#endif
 868
 869#ifdef CONFIG_PM
 870static int alc_resume(struct hda_codec *codec)
 871{
 872	struct alc_spec *spec = codec->spec;
 873
 874	if (!spec->no_depop_delay)
 875		msleep(150); /* to avoid pop noise */
 876	codec->patch_ops.init(codec);
 877	snd_hda_codec_resume_amp(codec);
 878	snd_hda_codec_resume_cache(codec);
 879	alc_inv_dmic_sync(codec, true);
 880	hda_call_check_power_status(codec, 0x01);
 881	return 0;
 882}
 883#endif
 884
 885/*
 886 */
 887static const struct hda_codec_ops alc_patch_ops = {
 888	.build_controls = alc_build_controls,
 889	.build_pcms = snd_hda_gen_build_pcms,
 890	.init = alc_init,
 891	.free = alc_free,
 892	.unsol_event = snd_hda_jack_unsol_event,
 893#ifdef CONFIG_PM
 894	.resume = alc_resume,
 
 
 895	.suspend = alc_suspend,
 896	.check_power_status = snd_hda_gen_check_power_status,
 897#endif
 898	.reboot_notify = alc_shutup,
 899};
 900
 901
 902/* replace the codec chip_name with the given string */
 903static int alc_codec_rename(struct hda_codec *codec, const char *name)
 904{
 905	kfree(codec->chip_name);
 906	codec->chip_name = kstrdup(name, GFP_KERNEL);
 907	if (!codec->chip_name) {
 908		alc_free(codec);
 909		return -ENOMEM;
 910	}
 911	return 0;
 912}
 913
 914/*
 915 * Rename codecs appropriately from COEF value or subvendor id
 916 */
 917struct alc_codec_rename_table {
 918	unsigned int vendor_id;
 919	unsigned short coef_mask;
 920	unsigned short coef_bits;
 921	const char *name;
 922};
 923
 924struct alc_codec_rename_pci_table {
 925	unsigned int codec_vendor_id;
 926	unsigned short pci_subvendor;
 927	unsigned short pci_subdevice;
 928	const char *name;
 929};
 930
 931static struct alc_codec_rename_table rename_tbl[] = {
 932	{ 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
 933	{ 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
 934	{ 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
 935	{ 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
 936	{ 0x10ec0269, 0xffff, 0xa023, "ALC259" },
 937	{ 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
 938	{ 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
 939	{ 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
 940	{ 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
 941	{ 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
 942	{ 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
 943	{ 0x10ec0899, 0x2000, 0x2000, "ALC899" },
 944	{ 0x10ec0892, 0xffff, 0x8020, "ALC661" },
 945	{ 0x10ec0892, 0xffff, 0x8011, "ALC661" },
 946	{ 0x10ec0892, 0xffff, 0x4011, "ALC656" },
 947	{ } /* terminator */
 948};
 949
 950static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
 951	{ 0x10ec0280, 0x1028, 0, "ALC3220" },
 952	{ 0x10ec0282, 0x1028, 0, "ALC3221" },
 953	{ 0x10ec0283, 0x1028, 0, "ALC3223" },
 954	{ 0x10ec0292, 0x1028, 0, "ALC3226" },
 955	{ 0x10ec0255, 0x1028, 0, "ALC3234" },
 956	{ 0x10ec0668, 0x1028, 0, "ALC3661" },
 957	{ } /* terminator */
 958};
 959
 960static int alc_codec_rename_from_preset(struct hda_codec *codec)
 961{
 962	const struct alc_codec_rename_table *p;
 963	const struct alc_codec_rename_pci_table *q;
 964
 965	for (p = rename_tbl; p->vendor_id; p++) {
 966		if (p->vendor_id != codec->vendor_id)
 967			continue;
 968		if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
 969			return alc_codec_rename(codec, p->name);
 970	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 971
 972	if (!codec->bus->pci)
 
 
 
 
 
 
 
 
 
 
 
 
 973		return 0;
 974	for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
 975		if (q->codec_vendor_id != codec->vendor_id)
 
 
 
 
 
 976			continue;
 977		if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 978			continue;
 979		if (!q->pci_subdevice ||
 980		    q->pci_subdevice == codec->bus->pci->subsystem_device)
 981			return alc_codec_rename(codec, q->name);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 982	}
 983
 984	return 0;
 985}
 986
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 987
 988/*
 989 * Digital-beep handlers
 990 */
 991#ifdef CONFIG_SND_HDA_INPUT_BEEP
 992#define set_beep_amp(spec, nid, idx, dir) \
 993	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
 994
 995static const struct snd_pci_quirk beep_white_list[] = {
 996	SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
 997	SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
 998	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
 999	SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
1000	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
1001	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
1002	SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
1003	SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
1004	SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
1005	{}
1006};
1007
1008static inline int has_cdefine_beep(struct hda_codec *codec)
1009{
1010	struct alc_spec *spec = codec->spec;
1011	const struct snd_pci_quirk *q;
1012	q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
1013	if (q)
1014		return q->value;
1015	return spec->cdefine.enable_pcbeep;
1016}
1017#else
1018#define set_beep_amp(spec, nid, idx, dir) /* NOP */
1019#define has_cdefine_beep(codec)		0
1020#endif
1021
1022/* parse the BIOS configuration and set up the alc_spec */
1023/* return 1 if successful, 0 if the proper config is not found,
1024 * or a negative error code
1025 */
1026static int alc_parse_auto_config(struct hda_codec *codec,
1027				 const hda_nid_t *ignore_nids,
1028				 const hda_nid_t *ssid_nids)
1029{
1030	struct alc_spec *spec = codec->spec;
1031	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
1032	int err;
1033
1034	err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
1035				       spec->parse_flags);
1036	if (err < 0)
1037		return err;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1038
1039	if (ssid_nids)
1040		alc_ssid_check(codec, ssid_nids);
1041
1042	err = snd_hda_gen_parse_auto_config(codec, cfg);
1043	if (err < 0)
1044		return err;
 
 
 
 
 
 
 
 
 
1045
1046	return 1;
1047}
1048
1049/* common preparation job for alc_spec */
1050static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
1051{
1052	struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1053	int err;
1054
1055	if (!spec)
1056		return -ENOMEM;
1057	codec->spec = spec;
1058	snd_hda_gen_spec_init(&spec->gen);
1059	spec->gen.mixer_nid = mixer_nid;
1060	spec->gen.own_eapd_ctl = 1;
1061	codec->single_adc_amp = 1;
1062	/* FIXME: do we need this for all Realtek codec models? */
1063	codec->spdif_status_reset = 1;
1064
1065	err = alc_codec_rename_from_preset(codec);
1066	if (err < 0) {
1067		kfree(spec);
1068		return err;
1069	}
1070	return 0;
1071}
1072
1073static int alc880_parse_auto_config(struct hda_codec *codec)
1074{
1075	static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
1076	static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
1077	return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1078}
1079
1080/*
1081 * ALC880 fix-ups
1082 */
1083enum {
1084	ALC880_FIXUP_GPIO1,
1085	ALC880_FIXUP_GPIO2,
1086	ALC880_FIXUP_MEDION_RIM,
1087	ALC880_FIXUP_LG,
1088	ALC880_FIXUP_LG_LW25,
1089	ALC880_FIXUP_W810,
1090	ALC880_FIXUP_EAPD_COEF,
1091	ALC880_FIXUP_TCL_S700,
1092	ALC880_FIXUP_VOL_KNOB,
1093	ALC880_FIXUP_FUJITSU,
1094	ALC880_FIXUP_F1734,
1095	ALC880_FIXUP_UNIWILL,
1096	ALC880_FIXUP_UNIWILL_DIG,
1097	ALC880_FIXUP_Z71V,
1098	ALC880_FIXUP_ASUS_W5A,
1099	ALC880_FIXUP_3ST_BASE,
1100	ALC880_FIXUP_3ST,
1101	ALC880_FIXUP_3ST_DIG,
1102	ALC880_FIXUP_5ST_BASE,
1103	ALC880_FIXUP_5ST,
1104	ALC880_FIXUP_5ST_DIG,
1105	ALC880_FIXUP_6ST_BASE,
1106	ALC880_FIXUP_6ST,
1107	ALC880_FIXUP_6ST_DIG,
1108	ALC880_FIXUP_6ST_AUTOMUTE,
1109};
1110
1111/* enable the volume-knob widget support on NID 0x21 */
1112static void alc880_fixup_vol_knob(struct hda_codec *codec,
1113				  const struct hda_fixup *fix, int action)
1114{
1115	if (action == HDA_FIXUP_ACT_PROBE)
1116		snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master);
1117}
1118
1119static const struct hda_fixup alc880_fixups[] = {
1120	[ALC880_FIXUP_GPIO1] = {
1121		.type = HDA_FIXUP_VERBS,
1122		.v.verbs = alc_gpio1_init_verbs,
1123	},
1124	[ALC880_FIXUP_GPIO2] = {
1125		.type = HDA_FIXUP_VERBS,
1126		.v.verbs = alc_gpio2_init_verbs,
1127	},
1128	[ALC880_FIXUP_MEDION_RIM] = {
1129		.type = HDA_FIXUP_VERBS,
1130		.v.verbs = (const struct hda_verb[]) {
1131			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1132			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
1133			{ }
1134		},
1135		.chained = true,
1136		.chain_id = ALC880_FIXUP_GPIO2,
1137	},
1138	[ALC880_FIXUP_LG] = {
1139		.type = HDA_FIXUP_PINS,
1140		.v.pins = (const struct hda_pintbl[]) {
1141			/* disable bogus unused pins */
1142			{ 0x16, 0x411111f0 },
1143			{ 0x18, 0x411111f0 },
1144			{ 0x1a, 0x411111f0 },
1145			{ }
1146		}
1147	},
1148	[ALC880_FIXUP_LG_LW25] = {
1149		.type = HDA_FIXUP_PINS,
1150		.v.pins = (const struct hda_pintbl[]) {
1151			{ 0x1a, 0x0181344f }, /* line-in */
1152			{ 0x1b, 0x0321403f }, /* headphone */
1153			{ }
1154		}
1155	},
1156	[ALC880_FIXUP_W810] = {
1157		.type = HDA_FIXUP_PINS,
1158		.v.pins = (const struct hda_pintbl[]) {
1159			/* disable bogus unused pins */
1160			{ 0x17, 0x411111f0 },
1161			{ }
1162		},
1163		.chained = true,
1164		.chain_id = ALC880_FIXUP_GPIO2,
1165	},
1166	[ALC880_FIXUP_EAPD_COEF] = {
1167		.type = HDA_FIXUP_VERBS,
1168		.v.verbs = (const struct hda_verb[]) {
1169			/* change to EAPD mode */
1170			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1171			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
1172			{}
1173		},
1174	},
1175	[ALC880_FIXUP_TCL_S700] = {
1176		.type = HDA_FIXUP_VERBS,
1177		.v.verbs = (const struct hda_verb[]) {
1178			/* change to EAPD mode */
1179			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1180			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3070 },
1181			{}
1182		},
1183		.chained = true,
1184		.chain_id = ALC880_FIXUP_GPIO2,
1185	},
1186	[ALC880_FIXUP_VOL_KNOB] = {
1187		.type = HDA_FIXUP_FUNC,
1188		.v.func = alc880_fixup_vol_knob,
1189	},
1190	[ALC880_FIXUP_FUJITSU] = {
1191		/* override all pins as BIOS on old Amilo is broken */
1192		.type = HDA_FIXUP_PINS,
1193		.v.pins = (const struct hda_pintbl[]) {
1194			{ 0x14, 0x0121411f }, /* HP */
1195			{ 0x15, 0x99030120 }, /* speaker */
1196			{ 0x16, 0x99030130 }, /* bass speaker */
1197			{ 0x17, 0x411111f0 }, /* N/A */
1198			{ 0x18, 0x411111f0 }, /* N/A */
1199			{ 0x19, 0x01a19950 }, /* mic-in */
1200			{ 0x1a, 0x411111f0 }, /* N/A */
1201			{ 0x1b, 0x411111f0 }, /* N/A */
1202			{ 0x1c, 0x411111f0 }, /* N/A */
1203			{ 0x1d, 0x411111f0 }, /* N/A */
1204			{ 0x1e, 0x01454140 }, /* SPDIF out */
1205			{ }
1206		},
1207		.chained = true,
1208		.chain_id = ALC880_FIXUP_VOL_KNOB,
1209	},
1210	[ALC880_FIXUP_F1734] = {
1211		/* almost compatible with FUJITSU, but no bass and SPDIF */
1212		.type = HDA_FIXUP_PINS,
1213		.v.pins = (const struct hda_pintbl[]) {
1214			{ 0x14, 0x0121411f }, /* HP */
1215			{ 0x15, 0x99030120 }, /* speaker */
1216			{ 0x16, 0x411111f0 }, /* N/A */
1217			{ 0x17, 0x411111f0 }, /* N/A */
1218			{ 0x18, 0x411111f0 }, /* N/A */
1219			{ 0x19, 0x01a19950 }, /* mic-in */
1220			{ 0x1a, 0x411111f0 }, /* N/A */
1221			{ 0x1b, 0x411111f0 }, /* N/A */
1222			{ 0x1c, 0x411111f0 }, /* N/A */
1223			{ 0x1d, 0x411111f0 }, /* N/A */
1224			{ 0x1e, 0x411111f0 }, /* N/A */
1225			{ }
1226		},
1227		.chained = true,
1228		.chain_id = ALC880_FIXUP_VOL_KNOB,
1229	},
1230	[ALC880_FIXUP_UNIWILL] = {
1231		/* need to fix HP and speaker pins to be parsed correctly */
1232		.type = HDA_FIXUP_PINS,
1233		.v.pins = (const struct hda_pintbl[]) {
1234			{ 0x14, 0x0121411f }, /* HP */
1235			{ 0x15, 0x99030120 }, /* speaker */
1236			{ 0x16, 0x99030130 }, /* bass speaker */
1237			{ }
1238		},
1239	},
1240	[ALC880_FIXUP_UNIWILL_DIG] = {
1241		.type = HDA_FIXUP_PINS,
1242		.v.pins = (const struct hda_pintbl[]) {
1243			/* disable bogus unused pins */
1244			{ 0x17, 0x411111f0 },
1245			{ 0x19, 0x411111f0 },
1246			{ 0x1b, 0x411111f0 },
1247			{ 0x1f, 0x411111f0 },
1248			{ }
1249		}
1250	},
1251	[ALC880_FIXUP_Z71V] = {
1252		.type = HDA_FIXUP_PINS,
1253		.v.pins = (const struct hda_pintbl[]) {
1254			/* set up the whole pins as BIOS is utterly broken */
1255			{ 0x14, 0x99030120 }, /* speaker */
1256			{ 0x15, 0x0121411f }, /* HP */
1257			{ 0x16, 0x411111f0 }, /* N/A */
1258			{ 0x17, 0x411111f0 }, /* N/A */
1259			{ 0x18, 0x01a19950 }, /* mic-in */
1260			{ 0x19, 0x411111f0 }, /* N/A */
1261			{ 0x1a, 0x01813031 }, /* line-in */
1262			{ 0x1b, 0x411111f0 }, /* N/A */
1263			{ 0x1c, 0x411111f0 }, /* N/A */
1264			{ 0x1d, 0x411111f0 }, /* N/A */
1265			{ 0x1e, 0x0144111e }, /* SPDIF */
1266			{ }
1267		}
1268	},
1269	[ALC880_FIXUP_ASUS_W5A] = {
1270		.type = HDA_FIXUP_PINS,
1271		.v.pins = (const struct hda_pintbl[]) {
1272			/* set up the whole pins as BIOS is utterly broken */
1273			{ 0x14, 0x0121411f }, /* HP */
1274			{ 0x15, 0x411111f0 }, /* N/A */
1275			{ 0x16, 0x411111f0 }, /* N/A */
1276			{ 0x17, 0x411111f0 }, /* N/A */
1277			{ 0x18, 0x90a60160 }, /* mic */
1278			{ 0x19, 0x411111f0 }, /* N/A */
1279			{ 0x1a, 0x411111f0 }, /* N/A */
1280			{ 0x1b, 0x411111f0 }, /* N/A */
1281			{ 0x1c, 0x411111f0 }, /* N/A */
1282			{ 0x1d, 0x411111f0 }, /* N/A */
1283			{ 0x1e, 0xb743111e }, /* SPDIF out */
1284			{ }
1285		},
1286		.chained = true,
1287		.chain_id = ALC880_FIXUP_GPIO1,
1288	},
1289	[ALC880_FIXUP_3ST_BASE] = {
1290		.type = HDA_FIXUP_PINS,
1291		.v.pins = (const struct hda_pintbl[]) {
1292			{ 0x14, 0x01014010 }, /* line-out */
1293			{ 0x15, 0x411111f0 }, /* N/A */
1294			{ 0x16, 0x411111f0 }, /* N/A */
1295			{ 0x17, 0x411111f0 }, /* N/A */
1296			{ 0x18, 0x01a19c30 }, /* mic-in */
1297			{ 0x19, 0x0121411f }, /* HP */
1298			{ 0x1a, 0x01813031 }, /* line-in */
1299			{ 0x1b, 0x02a19c40 }, /* front-mic */
1300			{ 0x1c, 0x411111f0 }, /* N/A */
1301			{ 0x1d, 0x411111f0 }, /* N/A */
1302			/* 0x1e is filled in below */
1303			{ 0x1f, 0x411111f0 }, /* N/A */
1304			{ }
1305		}
1306	},
1307	[ALC880_FIXUP_3ST] = {
1308		.type = HDA_FIXUP_PINS,
1309		.v.pins = (const struct hda_pintbl[]) {
1310			{ 0x1e, 0x411111f0 }, /* N/A */
1311			{ }
1312		},
1313		.chained = true,
1314		.chain_id = ALC880_FIXUP_3ST_BASE,
1315	},
1316	[ALC880_FIXUP_3ST_DIG] = {
1317		.type = HDA_FIXUP_PINS,
1318		.v.pins = (const struct hda_pintbl[]) {
1319			{ 0x1e, 0x0144111e }, /* SPDIF */
1320			{ }
1321		},
1322		.chained = true,
1323		.chain_id = ALC880_FIXUP_3ST_BASE,
1324	},
1325	[ALC880_FIXUP_5ST_BASE] = {
1326		.type = HDA_FIXUP_PINS,
1327		.v.pins = (const struct hda_pintbl[]) {
1328			{ 0x14, 0x01014010 }, /* front */
1329			{ 0x15, 0x411111f0 }, /* N/A */
1330			{ 0x16, 0x01011411 }, /* CLFE */
1331			{ 0x17, 0x01016412 }, /* surr */
1332			{ 0x18, 0x01a19c30 }, /* mic-in */
1333			{ 0x19, 0x0121411f }, /* HP */
1334			{ 0x1a, 0x01813031 }, /* line-in */
1335			{ 0x1b, 0x02a19c40 }, /* front-mic */
1336			{ 0x1c, 0x411111f0 }, /* N/A */
1337			{ 0x1d, 0x411111f0 }, /* N/A */
1338			/* 0x1e is filled in below */
1339			{ 0x1f, 0x411111f0 }, /* N/A */
1340			{ }
1341		}
1342	},
1343	[ALC880_FIXUP_5ST] = {
1344		.type = HDA_FIXUP_PINS,
1345		.v.pins = (const struct hda_pintbl[]) {
1346			{ 0x1e, 0x411111f0 }, /* N/A */
1347			{ }
1348		},
1349		.chained = true,
1350		.chain_id = ALC880_FIXUP_5ST_BASE,
1351	},
1352	[ALC880_FIXUP_5ST_DIG] = {
1353		.type = HDA_FIXUP_PINS,
1354		.v.pins = (const struct hda_pintbl[]) {
1355			{ 0x1e, 0x0144111e }, /* SPDIF */
1356			{ }
1357		},
1358		.chained = true,
1359		.chain_id = ALC880_FIXUP_5ST_BASE,
1360	},
1361	[ALC880_FIXUP_6ST_BASE] = {
1362		.type = HDA_FIXUP_PINS,
1363		.v.pins = (const struct hda_pintbl[]) {
1364			{ 0x14, 0x01014010 }, /* front */
1365			{ 0x15, 0x01016412 }, /* surr */
1366			{ 0x16, 0x01011411 }, /* CLFE */
1367			{ 0x17, 0x01012414 }, /* side */
1368			{ 0x18, 0x01a19c30 }, /* mic-in */
1369			{ 0x19, 0x02a19c40 }, /* front-mic */
1370			{ 0x1a, 0x01813031 }, /* line-in */
1371			{ 0x1b, 0x0121411f }, /* HP */
1372			{ 0x1c, 0x411111f0 }, /* N/A */
1373			{ 0x1d, 0x411111f0 }, /* N/A */
1374			/* 0x1e is filled in below */
1375			{ 0x1f, 0x411111f0 }, /* N/A */
1376			{ }
1377		}
1378	},
1379	[ALC880_FIXUP_6ST] = {
1380		.type = HDA_FIXUP_PINS,
1381		.v.pins = (const struct hda_pintbl[]) {
1382			{ 0x1e, 0x411111f0 }, /* N/A */
1383			{ }
1384		},
1385		.chained = true,
1386		.chain_id = ALC880_FIXUP_6ST_BASE,
1387	},
1388	[ALC880_FIXUP_6ST_DIG] = {
1389		.type = HDA_FIXUP_PINS,
1390		.v.pins = (const struct hda_pintbl[]) {
1391			{ 0x1e, 0x0144111e }, /* SPDIF */
1392			{ }
1393		},
1394		.chained = true,
1395		.chain_id = ALC880_FIXUP_6ST_BASE,
1396	},
1397	[ALC880_FIXUP_6ST_AUTOMUTE] = {
1398		.type = HDA_FIXUP_PINS,
1399		.v.pins = (const struct hda_pintbl[]) {
1400			{ 0x1b, 0x0121401f }, /* HP with jack detect */
1401			{ }
1402		},
1403		.chained_before = true,
1404		.chain_id = ALC880_FIXUP_6ST_BASE,
1405	},
1406};
1407
1408static const struct snd_pci_quirk alc880_fixup_tbl[] = {
1409	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
1410	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
1411	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
1412	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
1413	SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
1414	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
1415	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
1416	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
1417	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
1418	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
1419	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
1420	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
1421	SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
1422	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
1423	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
1424	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
1425	SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
1426	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1427	SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1428	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
1429	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
1430	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
1431
1432	/* Below is the copied entries from alc880_quirks.c.
1433	 * It's not quite sure whether BIOS sets the correct pin-config table
1434	 * on these machines, thus they are kept to be compatible with
1435	 * the old static quirks.  Once when it's confirmed to work without
1436	 * these overrides, it'd be better to remove.
1437	 */
1438	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1439	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1440	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1441	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1442	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1443	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1444	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1445	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1446	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1447	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1448	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1449	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1450	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1451	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1452	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1453	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1454	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1455	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1456	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1457	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1458	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1459	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1460	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1461	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1462	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1463	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1464	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1465	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1466	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1467	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1468	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1469	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1470	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1471	/* default Intel */
1472	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1473	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1474	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1475	{}
1476};
1477
1478static const struct hda_model_fixup alc880_fixup_models[] = {
1479	{.id = ALC880_FIXUP_3ST, .name = "3stack"},
1480	{.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1481	{.id = ALC880_FIXUP_5ST, .name = "5stack"},
1482	{.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1483	{.id = ALC880_FIXUP_6ST, .name = "6stack"},
1484	{.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
1485	{.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
1486	{}
1487};
1488
1489
1490/*
1491 * OK, here we have finally the patch for ALC880
1492 */
1493static int patch_alc880(struct hda_codec *codec)
1494{
1495	struct alc_spec *spec;
1496	int err;
1497
1498	err = alc_alloc_spec(codec, 0x0b);
1499	if (err < 0)
1500		return err;
1501
1502	spec = codec->spec;
1503	spec->gen.need_dac_fix = 1;
1504	spec->gen.beep_nid = 0x01;
1505
1506	snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
1507		       alc880_fixups);
1508	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1509
1510	/* automatic parse from the BIOS config */
1511	err = alc880_parse_auto_config(codec);
1512	if (err < 0)
1513		goto error;
1514
1515	if (!spec->gen.no_analog)
 
 
 
1516		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 
1517
1518	codec->patch_ops = alc_patch_ops;
1519	codec->patch_ops.unsol_event = alc880_unsol_event;
1520
1521
1522	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1523
1524	return 0;
1525
1526 error:
1527	alc_free(codec);
1528	return err;
1529}
1530
1531
1532/*
1533 * ALC260 support
1534 */
1535static int alc260_parse_auto_config(struct hda_codec *codec)
1536{
1537	static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
1538	static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1539	return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
1540}
1541
1542/*
1543 * Pin config fixes
1544 */
1545enum {
1546	ALC260_FIXUP_HP_DC5750,
1547	ALC260_FIXUP_HP_PIN_0F,
1548	ALC260_FIXUP_COEF,
1549	ALC260_FIXUP_GPIO1,
1550	ALC260_FIXUP_GPIO1_TOGGLE,
1551	ALC260_FIXUP_REPLACER,
1552	ALC260_FIXUP_HP_B1900,
1553	ALC260_FIXUP_KN1,
1554	ALC260_FIXUP_FSC_S7020,
1555	ALC260_FIXUP_FSC_S7020_JWSE,
1556	ALC260_FIXUP_VAIO_PINS,
1557};
1558
1559static void alc260_gpio1_automute(struct hda_codec *codec)
1560{
1561	struct alc_spec *spec = codec->spec;
1562	snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
1563			    spec->gen.hp_jack_present);
1564}
1565
1566static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
1567				      const struct hda_fixup *fix, int action)
1568{
1569	struct alc_spec *spec = codec->spec;
1570	if (action == HDA_FIXUP_ACT_PROBE) {
1571		/* although the machine has only one output pin, we need to
1572		 * toggle GPIO1 according to the jack state
1573		 */
1574		spec->gen.automute_hook = alc260_gpio1_automute;
1575		spec->gen.detect_hp = 1;
1576		spec->gen.automute_speaker = 1;
1577		spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
1578		snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT,
1579						    snd_hda_gen_hp_automute);
1580		snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
1581	}
1582}
1583
1584static void alc260_fixup_kn1(struct hda_codec *codec,
1585			     const struct hda_fixup *fix, int action)
1586{
1587	struct alc_spec *spec = codec->spec;
1588	static const struct hda_pintbl pincfgs[] = {
1589		{ 0x0f, 0x02214000 }, /* HP/speaker */
1590		{ 0x12, 0x90a60160 }, /* int mic */
1591		{ 0x13, 0x02a19000 }, /* ext mic */
1592		{ 0x18, 0x01446000 }, /* SPDIF out */
1593		/* disable bogus I/O pins */
1594		{ 0x10, 0x411111f0 },
1595		{ 0x11, 0x411111f0 },
1596		{ 0x14, 0x411111f0 },
1597		{ 0x15, 0x411111f0 },
1598		{ 0x16, 0x411111f0 },
1599		{ 0x17, 0x411111f0 },
1600		{ 0x19, 0x411111f0 },
1601		{ }
1602	};
1603
1604	switch (action) {
1605	case HDA_FIXUP_ACT_PRE_PROBE:
1606		snd_hda_apply_pincfgs(codec, pincfgs);
1607		break;
1608	case HDA_FIXUP_ACT_PROBE:
1609		spec->init_amp = ALC_INIT_NONE;
1610		break;
1611	}
1612}
1613
1614static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1615				   const struct hda_fixup *fix, int action)
1616{
1617	struct alc_spec *spec = codec->spec;
1618	if (action == HDA_FIXUP_ACT_PROBE)
1619		spec->init_amp = ALC_INIT_NONE;
1620}
1621
1622static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1623				   const struct hda_fixup *fix, int action)
1624{
1625	struct alc_spec *spec = codec->spec;
1626	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1627		spec->gen.add_jack_modes = 1;
1628		spec->gen.hp_mic = 1;
1629	}
1630}
1631
1632static const struct hda_fixup alc260_fixups[] = {
1633	[ALC260_FIXUP_HP_DC5750] = {
1634		.type = HDA_FIXUP_PINS,
1635		.v.pins = (const struct hda_pintbl[]) {
1636			{ 0x11, 0x90130110 }, /* speaker */
1637			{ }
1638		}
1639	},
1640	[ALC260_FIXUP_HP_PIN_0F] = {
1641		.type = HDA_FIXUP_PINS,
1642		.v.pins = (const struct hda_pintbl[]) {
1643			{ 0x0f, 0x01214000 }, /* HP */
1644			{ }
1645		}
1646	},
1647	[ALC260_FIXUP_COEF] = {
1648		.type = HDA_FIXUP_VERBS,
1649		.v.verbs = (const struct hda_verb[]) {
1650			{ 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1651			{ 0x1a, AC_VERB_SET_PROC_COEF,  0x3040 },
1652			{ }
1653		},
 
 
1654	},
1655	[ALC260_FIXUP_GPIO1] = {
1656		.type = HDA_FIXUP_VERBS,
1657		.v.verbs = alc_gpio1_init_verbs,
1658	},
1659	[ALC260_FIXUP_GPIO1_TOGGLE] = {
1660		.type = HDA_FIXUP_FUNC,
1661		.v.func = alc260_fixup_gpio1_toggle,
1662		.chained = true,
1663		.chain_id = ALC260_FIXUP_HP_PIN_0F,
1664	},
1665	[ALC260_FIXUP_REPLACER] = {
1666		.type = HDA_FIXUP_VERBS,
1667		.v.verbs = (const struct hda_verb[]) {
1668			{ 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1669			{ 0x1a, AC_VERB_SET_PROC_COEF,  0x3050 },
1670			{ }
1671		},
1672		.chained = true,
1673		.chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1674	},
1675	[ALC260_FIXUP_HP_B1900] = {
1676		.type = HDA_FIXUP_FUNC,
1677		.v.func = alc260_fixup_gpio1_toggle,
1678		.chained = true,
1679		.chain_id = ALC260_FIXUP_COEF,
1680	},
1681	[ALC260_FIXUP_KN1] = {
1682		.type = HDA_FIXUP_FUNC,
1683		.v.func = alc260_fixup_kn1,
1684	},
1685	[ALC260_FIXUP_FSC_S7020] = {
1686		.type = HDA_FIXUP_FUNC,
1687		.v.func = alc260_fixup_fsc_s7020,
1688	},
1689	[ALC260_FIXUP_FSC_S7020_JWSE] = {
1690		.type = HDA_FIXUP_FUNC,
1691		.v.func = alc260_fixup_fsc_s7020_jwse,
1692		.chained = true,
1693		.chain_id = ALC260_FIXUP_FSC_S7020,
1694	},
1695	[ALC260_FIXUP_VAIO_PINS] = {
1696		.type = HDA_FIXUP_PINS,
1697		.v.pins = (const struct hda_pintbl[]) {
1698			/* Pin configs are missing completely on some VAIOs */
1699			{ 0x0f, 0x01211020 },
1700			{ 0x10, 0x0001003f },
1701			{ 0x11, 0x411111f0 },
1702			{ 0x12, 0x01a15930 },
1703			{ 0x13, 0x411111f0 },
1704			{ 0x14, 0x411111f0 },
1705			{ 0x15, 0x411111f0 },
1706			{ 0x16, 0x411111f0 },
1707			{ 0x17, 0x411111f0 },
1708			{ 0x18, 0x411111f0 },
1709			{ 0x19, 0x411111f0 },
1710			{ }
1711		}
1712	},
1713};
1714
1715static const struct snd_pci_quirk alc260_fixup_tbl[] = {
1716	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
1717	SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
1718	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
1719	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
1720	SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
1721	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
1722	SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
1723	SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
1724	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
1725	SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
1726	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
1727	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
1728	{}
1729};
1730
1731static const struct hda_model_fixup alc260_fixup_models[] = {
1732	{.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1733	{.id = ALC260_FIXUP_COEF, .name = "coef"},
1734	{.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1735	{.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1736	{}
1737};
1738
1739/*
1740 */
1741static int patch_alc260(struct hda_codec *codec)
1742{
1743	struct alc_spec *spec;
1744	int err;
1745
1746	err = alc_alloc_spec(codec, 0x07);
1747	if (err < 0)
1748		return err;
1749
1750	spec = codec->spec;
1751	/* as quite a few machines require HP amp for speaker outputs,
1752	 * it's easier to enable it unconditionally; even if it's unneeded,
1753	 * it's almost harmless.
1754	 */
1755	spec->gen.prefer_hp_amp = 1;
1756	spec->gen.beep_nid = 0x01;
1757
1758	snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1759			   alc260_fixups);
1760	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1761
1762	/* automatic parse from the BIOS config */
1763	err = alc260_parse_auto_config(codec);
1764	if (err < 0)
1765		goto error;
1766
1767	if (!spec->gen.no_analog)
 
 
 
1768		set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
 
1769
1770	codec->patch_ops = alc_patch_ops;
1771	spec->shutup = alc_eapd_shutup;
1772
1773	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1774
1775	return 0;
1776
1777 error:
1778	alc_free(codec);
1779	return err;
1780}
1781
1782
1783/*
1784 * ALC882/883/885/888/889 support
1785 *
1786 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1787 * configuration.  Each pin widget can choose any input DACs and a mixer.
1788 * Each ADC is connected from a mixer of all inputs.  This makes possible
1789 * 6-channel independent captures.
1790 *
1791 * In addition, an independent DAC for the multi-playback (not used in this
1792 * driver yet).
1793 */
1794
1795/*
1796 * Pin config fixes
1797 */
1798enum {
1799	ALC882_FIXUP_ABIT_AW9D_MAX,
1800	ALC882_FIXUP_LENOVO_Y530,
1801	ALC882_FIXUP_PB_M5210,
1802	ALC882_FIXUP_ACER_ASPIRE_7736,
1803	ALC882_FIXUP_ASUS_W90V,
1804	ALC889_FIXUP_CD,
1805	ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
1806	ALC889_FIXUP_VAIO_TT,
1807	ALC888_FIXUP_EEE1601,
1808	ALC882_FIXUP_EAPD,
1809	ALC883_FIXUP_EAPD,
1810	ALC883_FIXUP_ACER_EAPD,
1811	ALC882_FIXUP_GPIO1,
1812	ALC882_FIXUP_GPIO2,
1813	ALC882_FIXUP_GPIO3,
1814	ALC889_FIXUP_COEF,
1815	ALC882_FIXUP_ASUS_W2JC,
1816	ALC882_FIXUP_ACER_ASPIRE_4930G,
1817	ALC882_FIXUP_ACER_ASPIRE_8930G,
1818	ALC882_FIXUP_ASPIRE_8930G_VERBS,
1819	ALC885_FIXUP_MACPRO_GPIO,
1820	ALC889_FIXUP_DAC_ROUTE,
1821	ALC889_FIXUP_MBP_VREF,
1822	ALC889_FIXUP_IMAC91_VREF,
1823	ALC889_FIXUP_MBA11_VREF,
1824	ALC889_FIXUP_MBA21_VREF,
1825	ALC889_FIXUP_MP11_VREF,
1826	ALC882_FIXUP_INV_DMIC,
1827	ALC882_FIXUP_NO_PRIMARY_HP,
1828	ALC887_FIXUP_ASUS_BASS,
1829	ALC887_FIXUP_BASS_CHMAP,
1830};
1831
1832static void alc889_fixup_coef(struct hda_codec *codec,
1833			      const struct hda_fixup *fix, int action)
1834{
1835	if (action != HDA_FIXUP_ACT_INIT)
1836		return;
1837	alc889_coef_init(codec);
1838}
1839
1840/* toggle speaker-output according to the hp-jack state */
1841static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1842{
1843	unsigned int gpiostate, gpiomask, gpiodir;
1844
1845	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
1846				       AC_VERB_GET_GPIO_DATA, 0);
1847
1848	if (!muted)
1849		gpiostate |= (1 << pin);
1850	else
1851		gpiostate &= ~(1 << pin);
1852
1853	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
1854				      AC_VERB_GET_GPIO_MASK, 0);
1855	gpiomask |= (1 << pin);
1856
1857	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
1858				     AC_VERB_GET_GPIO_DIRECTION, 0);
1859	gpiodir |= (1 << pin);
1860
1861
1862	snd_hda_codec_write(codec, codec->afg, 0,
1863			    AC_VERB_SET_GPIO_MASK, gpiomask);
1864	snd_hda_codec_write(codec, codec->afg, 0,
1865			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1866
1867	msleep(1);
1868
1869	snd_hda_codec_write(codec, codec->afg, 0,
1870			    AC_VERB_SET_GPIO_DATA, gpiostate);
1871}
1872
1873/* set up GPIO at initialization */
1874static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
1875				     const struct hda_fixup *fix, int action)
1876{
1877	if (action != HDA_FIXUP_ACT_INIT)
1878		return;
1879	alc882_gpio_mute(codec, 0, 0);
1880	alc882_gpio_mute(codec, 1, 0);
1881}
1882
1883/* Fix the connection of some pins for ALC889:
1884 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1885 * work correctly (bko#42740)
1886 */
1887static void alc889_fixup_dac_route(struct hda_codec *codec,
1888				   const struct hda_fixup *fix, int action)
1889{
1890	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1891		/* fake the connections during parsing the tree */
1892		hda_nid_t conn1[2] = { 0x0c, 0x0d };
1893		hda_nid_t conn2[2] = { 0x0e, 0x0f };
1894		snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1895		snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1896		snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1897		snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
1898	} else if (action == HDA_FIXUP_ACT_PROBE) {
1899		/* restore the connections */
1900		hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1901		snd_hda_override_conn_list(codec, 0x14, 5, conn);
1902		snd_hda_override_conn_list(codec, 0x15, 5, conn);
1903		snd_hda_override_conn_list(codec, 0x18, 5, conn);
1904		snd_hda_override_conn_list(codec, 0x1a, 5, conn);
1905	}
1906}
1907
1908/* Set VREF on HP pin */
1909static void alc889_fixup_mbp_vref(struct hda_codec *codec,
1910				  const struct hda_fixup *fix, int action)
1911{
1912	struct alc_spec *spec = codec->spec;
1913	static hda_nid_t nids[2] = { 0x14, 0x15 };
1914	int i;
1915
1916	if (action != HDA_FIXUP_ACT_INIT)
1917		return;
1918	for (i = 0; i < ARRAY_SIZE(nids); i++) {
1919		unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1920		if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1921			continue;
1922		val = snd_hda_codec_get_pin_target(codec, nids[i]);
 
1923		val |= AC_PINCTL_VREF_80;
1924		snd_hda_set_pin_ctl(codec, nids[i], val);
1925		spec->gen.keep_vref_in_automute = 1;
1926		break;
1927	}
1928}
1929
1930static void alc889_fixup_mac_pins(struct hda_codec *codec,
1931				  const hda_nid_t *nids, int num_nids)
 
1932{
1933	struct alc_spec *spec = codec->spec;
 
1934	int i;
1935
1936	for (i = 0; i < num_nids; i++) {
 
 
1937		unsigned int val;
1938		val = snd_hda_codec_get_pin_target(codec, nids[i]);
 
1939		val |= AC_PINCTL_VREF_50;
1940		snd_hda_set_pin_ctl(codec, nids[i], val);
1941	}
1942	spec->gen.keep_vref_in_automute = 1;
1943}
1944
1945/* Set VREF on speaker pins on imac91 */
1946static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1947				     const struct hda_fixup *fix, int action)
1948{
1949	static hda_nid_t nids[2] = { 0x18, 0x1a };
1950
1951	if (action == HDA_FIXUP_ACT_INIT)
1952		alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1953}
1954
1955/* Set VREF on speaker pins on mba11 */
1956static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1957				    const struct hda_fixup *fix, int action)
1958{
1959	static hda_nid_t nids[1] = { 0x18 };
1960
1961	if (action == HDA_FIXUP_ACT_INIT)
1962		alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1963}
1964
1965/* Set VREF on speaker pins on mba21 */
1966static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1967				    const struct hda_fixup *fix, int action)
1968{
1969	static hda_nid_t nids[2] = { 0x18, 0x19 };
1970
1971	if (action == HDA_FIXUP_ACT_INIT)
1972		alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1973}
1974
1975/* Don't take HP output as primary
1976 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1977 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
1978 */
1979static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1980				       const struct hda_fixup *fix, int action)
1981{
1982	struct alc_spec *spec = codec->spec;
1983	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1984		spec->gen.no_primary_hp = 1;
1985		spec->gen.no_multi_io = 1;
1986	}
1987}
1988
1989static void alc_fixup_bass_chmap(struct hda_codec *codec,
1990				 const struct hda_fixup *fix, int action);
1991
1992static const struct hda_fixup alc882_fixups[] = {
1993	[ALC882_FIXUP_ABIT_AW9D_MAX] = {
1994		.type = HDA_FIXUP_PINS,
1995		.v.pins = (const struct hda_pintbl[]) {
1996			{ 0x15, 0x01080104 }, /* side */
1997			{ 0x16, 0x01011012 }, /* rear */
1998			{ 0x17, 0x01016011 }, /* clfe */
1999			{ }
2000		}
2001	},
2002	[ALC882_FIXUP_LENOVO_Y530] = {
2003		.type = HDA_FIXUP_PINS,
2004		.v.pins = (const struct hda_pintbl[]) {
2005			{ 0x15, 0x99130112 }, /* rear int speakers */
2006			{ 0x16, 0x99130111 }, /* subwoofer */
2007			{ }
2008		}
2009	},
2010	[ALC882_FIXUP_PB_M5210] = {
2011		.type = HDA_FIXUP_PINCTLS,
2012		.v.pins = (const struct hda_pintbl[]) {
2013			{ 0x19, PIN_VREF50 },
2014			{}
2015		}
2016	},
2017	[ALC882_FIXUP_ACER_ASPIRE_7736] = {
2018		.type = HDA_FIXUP_FUNC,
2019		.v.func = alc_fixup_sku_ignore,
2020	},
2021	[ALC882_FIXUP_ASUS_W90V] = {
2022		.type = HDA_FIXUP_PINS,
2023		.v.pins = (const struct hda_pintbl[]) {
2024			{ 0x16, 0x99130110 }, /* fix sequence for CLFE */
2025			{ }
2026		}
2027	},
2028	[ALC889_FIXUP_CD] = {
2029		.type = HDA_FIXUP_PINS,
2030		.v.pins = (const struct hda_pintbl[]) {
2031			{ 0x1c, 0x993301f0 }, /* CD */
2032			{ }
2033		}
2034	},
2035	[ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
2036		.type = HDA_FIXUP_PINS,
2037		.v.pins = (const struct hda_pintbl[]) {
2038			{ 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
2039			{ }
2040		},
2041		.chained = true,
2042		.chain_id = ALC889_FIXUP_CD,
2043	},
2044	[ALC889_FIXUP_VAIO_TT] = {
2045		.type = HDA_FIXUP_PINS,
2046		.v.pins = (const struct hda_pintbl[]) {
2047			{ 0x17, 0x90170111 }, /* hidden surround speaker */
2048			{ }
2049		}
2050	},
2051	[ALC888_FIXUP_EEE1601] = {
2052		.type = HDA_FIXUP_VERBS,
2053		.v.verbs = (const struct hda_verb[]) {
2054			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2055			{ 0x20, AC_VERB_SET_PROC_COEF,  0x0838 },
2056			{ }
2057		}
2058	},
2059	[ALC882_FIXUP_EAPD] = {
2060		.type = HDA_FIXUP_VERBS,
2061		.v.verbs = (const struct hda_verb[]) {
2062			/* change to EAPD mode */
2063			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2064			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2065			{ }
2066		}
2067	},
2068	[ALC883_FIXUP_EAPD] = {
2069		.type = HDA_FIXUP_VERBS,
2070		.v.verbs = (const struct hda_verb[]) {
2071			/* change to EAPD mode */
2072			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2073			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2074			{ }
2075		}
2076	},
2077	[ALC883_FIXUP_ACER_EAPD] = {
2078		.type = HDA_FIXUP_VERBS,
2079		.v.verbs = (const struct hda_verb[]) {
2080			/* eanable EAPD on Acer laptops */
2081			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2082			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2083			{ }
2084		}
2085	},
2086	[ALC882_FIXUP_GPIO1] = {
2087		.type = HDA_FIXUP_VERBS,
2088		.v.verbs = alc_gpio1_init_verbs,
2089	},
2090	[ALC882_FIXUP_GPIO2] = {
2091		.type = HDA_FIXUP_VERBS,
2092		.v.verbs = alc_gpio2_init_verbs,
2093	},
2094	[ALC882_FIXUP_GPIO3] = {
2095		.type = HDA_FIXUP_VERBS,
2096		.v.verbs = alc_gpio3_init_verbs,
2097	},
2098	[ALC882_FIXUP_ASUS_W2JC] = {
2099		.type = HDA_FIXUP_VERBS,
2100		.v.verbs = alc_gpio1_init_verbs,
2101		.chained = true,
2102		.chain_id = ALC882_FIXUP_EAPD,
2103	},
2104	[ALC889_FIXUP_COEF] = {
2105		.type = HDA_FIXUP_FUNC,
2106		.v.func = alc889_fixup_coef,
2107	},
2108	[ALC882_FIXUP_ACER_ASPIRE_4930G] = {
2109		.type = HDA_FIXUP_PINS,
2110		.v.pins = (const struct hda_pintbl[]) {
2111			{ 0x16, 0x99130111 }, /* CLFE speaker */
2112			{ 0x17, 0x99130112 }, /* surround speaker */
2113			{ }
2114		},
2115		.chained = true,
2116		.chain_id = ALC882_FIXUP_GPIO1,
2117	},
2118	[ALC882_FIXUP_ACER_ASPIRE_8930G] = {
2119		.type = HDA_FIXUP_PINS,
2120		.v.pins = (const struct hda_pintbl[]) {
2121			{ 0x16, 0x99130111 }, /* CLFE speaker */
2122			{ 0x1b, 0x99130112 }, /* surround speaker */
2123			{ }
2124		},
2125		.chained = true,
2126		.chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2127	},
2128	[ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2129		/* additional init verbs for Acer Aspire 8930G */
2130		.type = HDA_FIXUP_VERBS,
2131		.v.verbs = (const struct hda_verb[]) {
2132			/* Enable all DACs */
2133			/* DAC DISABLE/MUTE 1? */
2134			/*  setting bits 1-5 disables DAC nids 0x02-0x06
2135			 *  apparently. Init=0x38 */
2136			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2137			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2138			/* DAC DISABLE/MUTE 2? */
2139			/*  some bit here disables the other DACs.
2140			 *  Init=0x4900 */
2141			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2142			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2143			/* DMIC fix
2144			 * This laptop has a stereo digital microphone.
2145			 * The mics are only 1cm apart which makes the stereo
2146			 * useless. However, either the mic or the ALC889
2147			 * makes the signal become a difference/sum signal
2148			 * instead of standard stereo, which is annoying.
2149			 * So instead we flip this bit which makes the
2150			 * codec replicate the sum signal to both channels,
2151			 * turning it into a normal mono mic.
2152			 */
2153			/* DMIC_CONTROL? Init value = 0x0001 */
2154			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2155			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2156			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2157			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2158			{ }
2159		},
2160		.chained = true,
2161		.chain_id = ALC882_FIXUP_GPIO1,
2162	},
2163	[ALC885_FIXUP_MACPRO_GPIO] = {
2164		.type = HDA_FIXUP_FUNC,
2165		.v.func = alc885_fixup_macpro_gpio,
2166	},
2167	[ALC889_FIXUP_DAC_ROUTE] = {
2168		.type = HDA_FIXUP_FUNC,
2169		.v.func = alc889_fixup_dac_route,
2170	},
2171	[ALC889_FIXUP_MBP_VREF] = {
2172		.type = HDA_FIXUP_FUNC,
2173		.v.func = alc889_fixup_mbp_vref,
2174		.chained = true,
2175		.chain_id = ALC882_FIXUP_GPIO1,
2176	},
2177	[ALC889_FIXUP_IMAC91_VREF] = {
2178		.type = HDA_FIXUP_FUNC,
2179		.v.func = alc889_fixup_imac91_vref,
2180		.chained = true,
2181		.chain_id = ALC882_FIXUP_GPIO1,
2182	},
2183	[ALC889_FIXUP_MBA11_VREF] = {
2184		.type = HDA_FIXUP_FUNC,
2185		.v.func = alc889_fixup_mba11_vref,
2186		.chained = true,
2187		.chain_id = ALC889_FIXUP_MBP_VREF,
2188	},
2189	[ALC889_FIXUP_MBA21_VREF] = {
2190		.type = HDA_FIXUP_FUNC,
2191		.v.func = alc889_fixup_mba21_vref,
2192		.chained = true,
2193		.chain_id = ALC889_FIXUP_MBP_VREF,
2194	},
2195	[ALC889_FIXUP_MP11_VREF] = {
2196		.type = HDA_FIXUP_FUNC,
2197		.v.func = alc889_fixup_mba11_vref,
2198		.chained = true,
2199		.chain_id = ALC885_FIXUP_MACPRO_GPIO,
2200	},
2201	[ALC882_FIXUP_INV_DMIC] = {
2202		.type = HDA_FIXUP_FUNC,
2203		.v.func = alc_fixup_inv_dmic_0x12,
2204	},
2205	[ALC882_FIXUP_NO_PRIMARY_HP] = {
2206		.type = HDA_FIXUP_FUNC,
2207		.v.func = alc882_fixup_no_primary_hp,
2208	},
2209	[ALC887_FIXUP_ASUS_BASS] = {
2210		.type = HDA_FIXUP_PINS,
2211		.v.pins = (const struct hda_pintbl[]) {
2212			{0x16, 0x99130130}, /* bass speaker */
2213			{}
2214		},
2215		.chained = true,
2216		.chain_id = ALC887_FIXUP_BASS_CHMAP,
2217	},
2218	[ALC887_FIXUP_BASS_CHMAP] = {
2219		.type = HDA_FIXUP_FUNC,
2220		.v.func = alc_fixup_bass_chmap,
2221	},
2222};
2223
2224static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2225	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2226	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2227	SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2228	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2229	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2230	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
2231	SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2232		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2233	SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2234		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2235	SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2236		      ALC882_FIXUP_ACER_ASPIRE_8930G),
2237	SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2238		      ALC882_FIXUP_ACER_ASPIRE_8930G),
2239	SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2240		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2241	SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2242		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2243	SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2244		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2245	SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
2246	SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2247		      ALC882_FIXUP_ACER_ASPIRE_4930G),
2248	SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
2249	SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
2250	SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
2251	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
2252	SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
2253	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
2254	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
2255	SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
2256	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
2257	SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
2258	SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
2259
2260	/* All Apple entries are in codec SSIDs */
2261	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2262	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2263	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2264	SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
2265	SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2266	SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
2267	SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2268	SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
2269	SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
2270	SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
2271	SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
2272	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2273	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2274	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
2275	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2276	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2277	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
2278	SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
2279	SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
2280	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2281	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
2282	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
2283
2284	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
2285	SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2286	SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2287	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2288	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2289	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2290	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
2291	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
2292	SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
2293	{}
2294};
2295
2296static const struct hda_model_fixup alc882_fixup_models[] = {
2297	{.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2298	{.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2299	{.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
2300	{.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
2301	{.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
2302	{}
2303};
2304
2305/*
2306 * BIOS auto configuration
2307 */
2308/* almost identical with ALC880 parser... */
2309static int alc882_parse_auto_config(struct hda_codec *codec)
2310{
2311	static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
2312	static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2313	return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
2314}
2315
2316/*
2317 */
2318static int patch_alc882(struct hda_codec *codec)
2319{
2320	struct alc_spec *spec;
2321	int err;
2322
2323	err = alc_alloc_spec(codec, 0x0b);
2324	if (err < 0)
2325		return err;
2326
2327	spec = codec->spec;
2328
2329	switch (codec->vendor_id) {
2330	case 0x10ec0882:
2331	case 0x10ec0885:
2332		break;
2333	default:
2334		/* ALC883 and variants */
2335		alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2336		break;
2337	}
2338
2339	snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
2340		       alc882_fixups);
2341	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2342
2343	alc_auto_parse_customize_define(codec);
2344
2345	if (has_cdefine_beep(codec))
2346		spec->gen.beep_nid = 0x01;
2347
2348	/* automatic parse from the BIOS config */
2349	err = alc882_parse_auto_config(codec);
2350	if (err < 0)
2351		goto error;
2352
2353	if (!spec->gen.no_analog && spec->gen.beep_nid)
 
 
 
2354		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 
2355
2356	codec->patch_ops = alc_patch_ops;
2357
2358	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2359
2360	return 0;
2361
2362 error:
2363	alc_free(codec);
2364	return err;
2365}
2366
2367
2368/*
2369 * ALC262 support
2370 */
2371static int alc262_parse_auto_config(struct hda_codec *codec)
2372{
2373	static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
2374	static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2375	return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
2376}
2377
2378/*
2379 * Pin config fixes
2380 */
2381enum {
2382	ALC262_FIXUP_FSC_H270,
2383	ALC262_FIXUP_FSC_S7110,
2384	ALC262_FIXUP_HP_Z200,
2385	ALC262_FIXUP_TYAN,
2386	ALC262_FIXUP_LENOVO_3000,
2387	ALC262_FIXUP_BENQ,
2388	ALC262_FIXUP_BENQ_T31,
2389	ALC262_FIXUP_INV_DMIC,
2390	ALC262_FIXUP_INTEL_BAYLEYBAY,
2391};
2392
2393static const struct hda_fixup alc262_fixups[] = {
2394	[ALC262_FIXUP_FSC_H270] = {
2395		.type = HDA_FIXUP_PINS,
2396		.v.pins = (const struct hda_pintbl[]) {
2397			{ 0x14, 0x99130110 }, /* speaker */
2398			{ 0x15, 0x0221142f }, /* front HP */
2399			{ 0x1b, 0x0121141f }, /* rear HP */
2400			{ }
2401		}
2402	},
2403	[ALC262_FIXUP_FSC_S7110] = {
2404		.type = HDA_FIXUP_PINS,
2405		.v.pins = (const struct hda_pintbl[]) {
2406			{ 0x15, 0x90170110 }, /* speaker */
2407			{ }
2408		},
2409		.chained = true,
2410		.chain_id = ALC262_FIXUP_BENQ,
2411	},
2412	[ALC262_FIXUP_HP_Z200] = {
2413		.type = HDA_FIXUP_PINS,
2414		.v.pins = (const struct hda_pintbl[]) {
2415			{ 0x16, 0x99130120 }, /* internal speaker */
2416			{ }
2417		}
2418	},
2419	[ALC262_FIXUP_TYAN] = {
2420		.type = HDA_FIXUP_PINS,
2421		.v.pins = (const struct hda_pintbl[]) {
2422			{ 0x14, 0x1993e1f0 }, /* int AUX */
2423			{ }
2424		}
2425	},
2426	[ALC262_FIXUP_LENOVO_3000] = {
2427		.type = HDA_FIXUP_PINCTLS,
2428		.v.pins = (const struct hda_pintbl[]) {
2429			{ 0x19, PIN_VREF50 },
2430			{}
2431		},
2432		.chained = true,
2433		.chain_id = ALC262_FIXUP_BENQ,
2434	},
2435	[ALC262_FIXUP_BENQ] = {
2436		.type = HDA_FIXUP_VERBS,
2437		.v.verbs = (const struct hda_verb[]) {
2438			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2439			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2440			{}
2441		}
2442	},
2443	[ALC262_FIXUP_BENQ_T31] = {
2444		.type = HDA_FIXUP_VERBS,
2445		.v.verbs = (const struct hda_verb[]) {
2446			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2447			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2448			{}
2449		}
2450	},
2451	[ALC262_FIXUP_INV_DMIC] = {
2452		.type = HDA_FIXUP_FUNC,
2453		.v.func = alc_fixup_inv_dmic_0x12,
2454	},
2455	[ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2456		.type = HDA_FIXUP_FUNC,
2457		.v.func = alc_fixup_no_depop_delay,
2458	},
2459};
2460
2461static const struct snd_pci_quirk alc262_fixup_tbl[] = {
2462	SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
2463	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
2464	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
2465	SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2466	SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
2467	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
2468	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2469	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
2470	SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
2471	{}
2472};
2473
2474static const struct hda_model_fixup alc262_fixup_models[] = {
2475	{.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2476	{}
2477};
2478
2479/*
2480 */
2481static int patch_alc262(struct hda_codec *codec)
2482{
2483	struct alc_spec *spec;
2484	int err;
2485
2486	err = alc_alloc_spec(codec, 0x0b);
2487	if (err < 0)
2488		return err;
2489
2490	spec = codec->spec;
2491	spec->gen.shared_mic_vref_pin = 0x18;
2492
2493#if 0
2494	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
2495	 * under-run
2496	 */
2497	{
2498	int tmp;
2499	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
2500	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
2501	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
2502	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
2503	}
2504#endif
2505	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2506
2507	snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
2508		       alc262_fixups);
2509	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2510
2511	alc_auto_parse_customize_define(codec);
2512
2513	if (has_cdefine_beep(codec))
2514		spec->gen.beep_nid = 0x01;
2515
2516	/* automatic parse from the BIOS config */
2517	err = alc262_parse_auto_config(codec);
2518	if (err < 0)
2519		goto error;
2520
2521	if (!spec->gen.no_analog && spec->gen.beep_nid)
 
 
 
2522		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 
2523
2524	codec->patch_ops = alc_patch_ops;
2525	spec->shutup = alc_eapd_shutup;
2526
2527	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2528
2529	return 0;
2530
2531 error:
2532	alc_free(codec);
2533	return err;
2534}
2535
2536/*
2537 *  ALC268
2538 */
2539/* bind Beep switches of both NID 0x0f and 0x10 */
2540static const struct hda_bind_ctls alc268_bind_beep_sw = {
2541	.ops = &snd_hda_bind_sw,
2542	.values = {
2543		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
2544		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
2545		0
2546	},
2547};
2548
2549static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2550	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
2551	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
2552	{ }
2553};
2554
2555/* set PCBEEP vol = 0, mute connections */
2556static const struct hda_verb alc268_beep_init_verbs[] = {
2557	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2558	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2559	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2560	{ }
2561};
2562
2563enum {
2564	ALC268_FIXUP_INV_DMIC,
2565	ALC268_FIXUP_HP_EAPD,
2566	ALC268_FIXUP_SPDIF,
2567};
2568
2569static const struct hda_fixup alc268_fixups[] = {
2570	[ALC268_FIXUP_INV_DMIC] = {
2571		.type = HDA_FIXUP_FUNC,
2572		.v.func = alc_fixup_inv_dmic_0x12,
2573	},
2574	[ALC268_FIXUP_HP_EAPD] = {
2575		.type = HDA_FIXUP_VERBS,
2576		.v.verbs = (const struct hda_verb[]) {
2577			{0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2578			{}
2579		}
2580	},
2581	[ALC268_FIXUP_SPDIF] = {
2582		.type = HDA_FIXUP_PINS,
2583		.v.pins = (const struct hda_pintbl[]) {
2584			{ 0x1e, 0x014b1180 }, /* enable SPDIF out */
2585			{}
2586		}
2587	},
2588};
2589
2590static const struct hda_model_fixup alc268_fixup_models[] = {
2591	{.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
2592	{.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2593	{}
2594};
2595
2596static const struct snd_pci_quirk alc268_fixup_tbl[] = {
2597	SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
2598	SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
2599	/* below is codec SSID since multiple Toshiba laptops have the
2600	 * same PCI SSID 1179:ff00
2601	 */
2602	SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
2603	{}
2604};
2605
2606/*
2607 * BIOS auto configuration
2608 */
2609static int alc268_parse_auto_config(struct hda_codec *codec)
2610{
2611	static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2612	return alc_parse_auto_config(codec, NULL, alc268_ssids);
 
 
 
 
 
 
 
 
2613}
2614
2615/*
2616 */
2617static int patch_alc268(struct hda_codec *codec)
2618{
2619	struct alc_spec *spec;
2620	int err;
2621
2622	/* ALC268 has no aa-loopback mixer */
2623	err = alc_alloc_spec(codec, 0);
2624	if (err < 0)
2625		return err;
2626
2627	spec = codec->spec;
2628	spec->gen.beep_nid = 0x01;
2629
2630	snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2631	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2632
2633	/* automatic parse from the BIOS config */
2634	err = alc268_parse_auto_config(codec);
2635	if (err < 0)
2636		goto error;
2637
2638	if (err > 0 && !spec->gen.no_analog &&
2639	    spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2640		add_mixer(spec, alc268_beep_mixer);
2641		snd_hda_add_verbs(codec, alc268_beep_init_verbs);
 
 
 
 
 
 
 
 
2642		if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2643			/* override the amp caps for beep generator */
2644			snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2645					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2646					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2647					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2648					  (0 << AC_AMPCAP_MUTE_SHIFT));
2649	}
2650
2651	codec->patch_ops = alc_patch_ops;
2652	spec->shutup = alc_eapd_shutup;
2653
2654	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2655
2656	return 0;
2657
2658 error:
2659	alc_free(codec);
2660	return err;
2661}
2662
2663/*
2664 * ALC269
2665 */
2666
2667static int playback_pcm_open(struct hda_pcm_stream *hinfo,
2668			     struct hda_codec *codec,
2669			     struct snd_pcm_substream *substream)
2670{
2671	struct hda_gen_spec *spec = codec->spec;
2672	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2673					     hinfo);
2674}
2675
2676static int playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2677				struct hda_codec *codec,
2678				unsigned int stream_tag,
2679				unsigned int format,
2680				struct snd_pcm_substream *substream)
2681{
2682	struct hda_gen_spec *spec = codec->spec;
2683	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2684						stream_tag, format, substream);
2685}
2686
2687static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2688				struct hda_codec *codec,
2689				struct snd_pcm_substream *substream)
2690{
2691	struct hda_gen_spec *spec = codec->spec;
2692	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2693}
2694
2695static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
2696	.substreams = 1,
2697	.channels_min = 2,
2698	.channels_max = 8,
2699	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2700	/* NID is set in alc_build_pcms */
2701	.ops = {
2702		.open = playback_pcm_open,
2703		.prepare = playback_pcm_prepare,
2704		.cleanup = playback_pcm_cleanup
2705	},
2706};
2707
2708static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
2709	.substreams = 1,
2710	.channels_min = 2,
2711	.channels_max = 2,
2712	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2713	/* NID is set in alc_build_pcms */
2714};
2715
2716/* different alc269-variants */
2717enum {
2718	ALC269_TYPE_ALC269VA,
2719	ALC269_TYPE_ALC269VB,
2720	ALC269_TYPE_ALC269VC,
2721	ALC269_TYPE_ALC269VD,
2722	ALC269_TYPE_ALC280,
2723	ALC269_TYPE_ALC282,
2724	ALC269_TYPE_ALC283,
2725	ALC269_TYPE_ALC284,
2726	ALC269_TYPE_ALC285,
2727	ALC269_TYPE_ALC286,
2728	ALC269_TYPE_ALC255,
2729};
2730
2731/*
2732 * BIOS auto configuration
2733 */
2734static int alc269_parse_auto_config(struct hda_codec *codec)
2735{
2736	static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
2737	static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2738	static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2739	struct alc_spec *spec = codec->spec;
2740	const hda_nid_t *ssids;
2741
2742	switch (spec->codec_variant) {
2743	case ALC269_TYPE_ALC269VA:
2744	case ALC269_TYPE_ALC269VC:
2745	case ALC269_TYPE_ALC280:
2746	case ALC269_TYPE_ALC284:
2747	case ALC269_TYPE_ALC285:
2748		ssids = alc269va_ssids;
2749		break;
2750	case ALC269_TYPE_ALC269VB:
2751	case ALC269_TYPE_ALC269VD:
2752	case ALC269_TYPE_ALC282:
2753	case ALC269_TYPE_ALC283:
2754	case ALC269_TYPE_ALC286:
2755	case ALC269_TYPE_ALC255:
2756		ssids = alc269_ssids;
2757		break;
2758	default:
2759		ssids = alc269_ssids;
2760		break;
2761	}
2762
2763	return alc_parse_auto_config(codec, alc269_ignore, ssids);
2764}
2765
2766static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
2767{
2768	int val = alc_read_coef_idx(codec, 0x04);
2769	if (power_up)
2770		val |= 1 << 11;
2771	else
2772		val &= ~(1 << 11);
2773	alc_write_coef_idx(codec, 0x04, val);
2774}
2775
2776static void alc269_shutup(struct hda_codec *codec)
2777{
2778	struct alc_spec *spec = codec->spec;
2779
2780	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2781		alc269vb_toggle_power_output(codec, 0);
2782	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2783			(alc_get_coef0(codec) & 0x00ff) == 0x018) {
2784		msleep(150);
2785	}
2786	snd_hda_shutup_pins(codec);
2787}
2788
2789static void alc282_restore_default_value(struct hda_codec *codec)
2790{
2791	int val;
2792
2793	/* Power Down Control */
2794	alc_write_coef_idx(codec, 0x03, 0x0002);
2795	/* FIFO and filter clock */
2796	alc_write_coef_idx(codec, 0x05, 0x0700);
2797	/* DMIC control */
2798	alc_write_coef_idx(codec, 0x07, 0x0200);
2799	/* Analog clock */
2800	val = alc_read_coef_idx(codec, 0x06);
2801	alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0);
2802	/* JD */
2803	val = alc_read_coef_idx(codec, 0x08);
2804	alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c);
2805	/* JD offset1 */
2806	alc_write_coef_idx(codec, 0x0a, 0xcccc);
2807	/* JD offset2 */
2808	alc_write_coef_idx(codec, 0x0b, 0xcccc);
2809	/* LDO1/2/3, DAC/ADC */
2810	alc_write_coef_idx(codec, 0x0e, 0x6e00);
2811	/* JD */
2812	val = alc_read_coef_idx(codec, 0x0f);
2813	alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000);
2814	/* Capless */
2815	val = alc_read_coef_idx(codec, 0x10);
2816	alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00);
2817	/* Class D test 4 */
2818	alc_write_coef_idx(codec, 0x6f, 0x0);
2819	/* IO power down directly */
2820	val = alc_read_coef_idx(codec, 0x0c);
2821	alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0);
2822	/* ANC */
2823	alc_write_coef_idx(codec, 0x34, 0xa0c0);
2824	/* AGC MUX */
2825	val = alc_read_coef_idx(codec, 0x16);
2826	alc_write_coef_idx(codec, 0x16, (val & ~0x0008) | 0x0);
2827	/* DAC simple content protection */
2828	val = alc_read_coef_idx(codec, 0x1d);
2829	alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0);
2830	/* ADC simple content protection */
2831	val = alc_read_coef_idx(codec, 0x1f);
2832	alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0);
2833	/* DAC ADC Zero Detection */
2834	alc_write_coef_idx(codec, 0x21, 0x8804);
2835	/* PLL */
2836	alc_write_coef_idx(codec, 0x63, 0x2902);
2837	/* capless control 2 */
2838	alc_write_coef_idx(codec, 0x68, 0xa080);
2839	/* capless control 3 */
2840	alc_write_coef_idx(codec, 0x69, 0x3400);
2841	/* capless control 4 */
2842	alc_write_coef_idx(codec, 0x6a, 0x2f3e);
2843	/* capless control 5 */
2844	alc_write_coef_idx(codec, 0x6b, 0x0);
2845	/* class D test 2 */
2846	val = alc_read_coef_idx(codec, 0x6d);
2847	alc_write_coef_idx(codec, 0x6d, (val & ~0x0fff) | 0x0900);
2848	/* class D test 3 */
2849	alc_write_coef_idx(codec, 0x6e, 0x110a);
2850	/* class D test 5 */
2851	val = alc_read_coef_idx(codec, 0x70);
2852	alc_write_coef_idx(codec, 0x70, (val & ~0x00f8) | 0x00d8);
2853	/* class D test 6 */
2854	alc_write_coef_idx(codec, 0x71, 0x0014);
2855	/* classD OCP */
2856	alc_write_coef_idx(codec, 0x72, 0xc2ba);
2857	/* classD pure DC test */
2858	val = alc_read_coef_idx(codec, 0x77);
2859	alc_write_coef_idx(codec, 0x77, (val & ~0x0f80) | 0x0);
2860	/* Class D amp control */
2861	alc_write_coef_idx(codec, 0x6c, 0xfc06);
2862}
2863
2864static void alc282_init(struct hda_codec *codec)
2865{
2866	struct alc_spec *spec = codec->spec;
2867	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2868	bool hp_pin_sense;
2869	int coef78;
2870
2871	alc282_restore_default_value(codec);
2872
2873	if (!hp_pin)
2874		return;
2875	hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2876	coef78 = alc_read_coef_idx(codec, 0x78);
2877
2878	/* Index 0x78 Direct Drive HP AMP LPM Control 1 */
2879	/* Headphone capless set to high power mode */
2880	alc_write_coef_idx(codec, 0x78, 0x9004);
2881
2882	if (hp_pin_sense)
2883		msleep(2);
2884
2885	snd_hda_codec_write(codec, hp_pin, 0,
2886			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2887
2888	if (hp_pin_sense)
2889		msleep(85);
2890
2891	snd_hda_codec_write(codec, hp_pin, 0,
2892			    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2893
2894	if (hp_pin_sense)
2895		msleep(100);
2896
2897	/* Headphone capless set to normal mode */
2898	alc_write_coef_idx(codec, 0x78, coef78);
2899}
2900
2901static void alc282_shutup(struct hda_codec *codec)
2902{
2903	struct alc_spec *spec = codec->spec;
2904	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2905	bool hp_pin_sense;
2906	int coef78;
2907
2908	if (!hp_pin) {
2909		alc269_shutup(codec);
2910		return;
2911	}
2912
2913	hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2914	coef78 = alc_read_coef_idx(codec, 0x78);
2915	alc_write_coef_idx(codec, 0x78, 0x9004);
2916
2917	if (hp_pin_sense)
2918		msleep(2);
2919
2920	snd_hda_codec_write(codec, hp_pin, 0,
2921			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2922
2923	if (hp_pin_sense)
2924		msleep(85);
2925
2926	snd_hda_codec_write(codec, hp_pin, 0,
2927			    AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2928
2929	if (hp_pin_sense)
2930		msleep(100);
2931
2932	alc_auto_setup_eapd(codec, false);
2933	snd_hda_shutup_pins(codec);
2934	alc_write_coef_idx(codec, 0x78, coef78);
2935}
2936
2937static void alc283_restore_default_value(struct hda_codec *codec)
2938{
2939	int val;
2940
2941	/* Power Down Control */
2942	alc_write_coef_idx(codec, 0x03, 0x0002);
2943	/* FIFO and filter clock */
2944	alc_write_coef_idx(codec, 0x05, 0x0700);
2945	/* DMIC control */
2946	alc_write_coef_idx(codec, 0x07, 0x0200);
2947	/* Analog clock */
2948	val = alc_read_coef_idx(codec, 0x06);
2949	alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0);
2950	/* JD */
2951	val = alc_read_coef_idx(codec, 0x08);
2952	alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c);
2953	/* JD offset1 */
2954	alc_write_coef_idx(codec, 0x0a, 0xcccc);
2955	/* JD offset2 */
2956	alc_write_coef_idx(codec, 0x0b, 0xcccc);
2957	/* LDO1/2/3, DAC/ADC */
2958	alc_write_coef_idx(codec, 0x0e, 0x6fc0);
2959	/* JD */
2960	val = alc_read_coef_idx(codec, 0x0f);
2961	alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000);
2962	/* Capless */
2963	val = alc_read_coef_idx(codec, 0x10);
2964	alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00);
2965	/* Class D test 4 */
2966	alc_write_coef_idx(codec, 0x3a, 0x0);
2967	/* IO power down directly */
2968	val = alc_read_coef_idx(codec, 0x0c);
2969	alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0);
2970	/* ANC */
2971	alc_write_coef_idx(codec, 0x22, 0xa0c0);
2972	/* AGC MUX */
2973	val = alc_read_coefex_idx(codec, 0x53, 0x01);
2974	alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008);
2975	/* DAC simple content protection */
2976	val = alc_read_coef_idx(codec, 0x1d);
2977	alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0);
2978	/* ADC simple content protection */
2979	val = alc_read_coef_idx(codec, 0x1f);
2980	alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0);
2981	/* DAC ADC Zero Detection */
2982	alc_write_coef_idx(codec, 0x21, 0x8804);
2983	/* PLL */
2984	alc_write_coef_idx(codec, 0x2e, 0x2902);
2985	/* capless control 2 */
2986	alc_write_coef_idx(codec, 0x33, 0xa080);
2987	/* capless control 3 */
2988	alc_write_coef_idx(codec, 0x34, 0x3400);
2989	/* capless control 4 */
2990	alc_write_coef_idx(codec, 0x35, 0x2f3e);
2991	/* capless control 5 */
2992	alc_write_coef_idx(codec, 0x36, 0x0);
2993	/* class D test 2 */
2994	val = alc_read_coef_idx(codec, 0x38);
2995	alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900);
2996	/* class D test 3 */
2997	alc_write_coef_idx(codec, 0x39, 0x110a);
2998	/* class D test 5 */
2999	val = alc_read_coef_idx(codec, 0x3b);
3000	alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8);
3001	/* class D test 6 */
3002	alc_write_coef_idx(codec, 0x3c, 0x0014);
3003	/* classD OCP */
3004	alc_write_coef_idx(codec, 0x3d, 0xc2ba);
3005	/* classD pure DC test */
3006	val = alc_read_coef_idx(codec, 0x42);
3007	alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0);
3008	/* test mode */
3009	alc_write_coef_idx(codec, 0x49, 0x0);
3010	/* Class D DC enable */
3011	val = alc_read_coef_idx(codec, 0x40);
3012	alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800);
3013	/* DC offset */
3014	val = alc_read_coef_idx(codec, 0x42);
3015	alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000);
3016	/* Class D amp control */
3017	alc_write_coef_idx(codec, 0x37, 0xfc06);
3018}
3019
3020static void alc283_init(struct hda_codec *codec)
3021{
3022	struct alc_spec *spec = codec->spec;
3023	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3024	bool hp_pin_sense;
3025	int val;
3026
3027	if (!spec->gen.autocfg.hp_outs) {
3028		if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
3029			hp_pin = spec->gen.autocfg.line_out_pins[0];
3030	}
3031
3032	alc283_restore_default_value(codec);
3033
3034	if (!hp_pin)
3035		return;
3036	hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3037
3038	/* Index 0x43 Direct Drive HP AMP LPM Control 1 */
3039	/* Headphone capless set to high power mode */
3040	alc_write_coef_idx(codec, 0x43, 0x9004);
3041
3042	snd_hda_codec_write(codec, hp_pin, 0,
3043			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3044
3045	if (hp_pin_sense)
3046		msleep(85);
3047
3048	snd_hda_codec_write(codec, hp_pin, 0,
3049			    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3050
3051	if (hp_pin_sense)
3052		msleep(85);
3053	/* Index 0x46 Combo jack auto switch control 2 */
3054	/* 3k pull low control for Headset jack. */
3055	val = alc_read_coef_idx(codec, 0x46);
3056	alc_write_coef_idx(codec, 0x46, val & ~(3 << 12));
3057	/* Headphone capless set to normal mode */
3058	alc_write_coef_idx(codec, 0x43, 0x9614);
3059}
3060
3061static void alc283_shutup(struct hda_codec *codec)
3062{
3063	struct alc_spec *spec = codec->spec;
3064	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3065	bool hp_pin_sense;
3066	int val;
3067
3068	if (!spec->gen.autocfg.hp_outs) {
3069		if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
3070			hp_pin = spec->gen.autocfg.line_out_pins[0];
3071	}
3072
3073	if (!hp_pin) {
3074		alc269_shutup(codec);
3075		return;
3076	}
3077
3078	hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
3079
3080	alc_write_coef_idx(codec, 0x43, 0x9004);
3081
3082	snd_hda_codec_write(codec, hp_pin, 0,
3083			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
3084
3085	if (hp_pin_sense)
3086		msleep(100);
3087
3088	snd_hda_codec_write(codec, hp_pin, 0,
3089			    AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
3090
3091	val = alc_read_coef_idx(codec, 0x46);
3092	alc_write_coef_idx(codec, 0x46, val | (3 << 12));
3093
3094	if (hp_pin_sense)
3095		msleep(100);
3096	alc_auto_setup_eapd(codec, false);
3097	snd_hda_shutup_pins(codec);
3098	alc_write_coef_idx(codec, 0x43, 0x9614);
3099}
3100
3101static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
3102			     unsigned int val)
3103{
3104	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3105	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
3106	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
3107}
3108
3109static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
3110{
3111	unsigned int val;
3112
3113	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
3114	val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3115		& 0xffff;
3116	val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
3117		<< 16;
3118	return val;
3119}
3120
3121static void alc5505_dsp_halt(struct hda_codec *codec)
3122{
3123	unsigned int val;
3124
3125	alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
3126	alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
3127	alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
3128	alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
3129	alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
3130	alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
3131	alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
3132	val = alc5505_coef_get(codec, 0x6220);
3133	alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
3134}
3135
3136static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
3137{
3138	alc5505_coef_set(codec, 0x61b8, 0x04133302);
3139	alc5505_coef_set(codec, 0x61b0, 0x00005b16);
3140	alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
3141	alc5505_coef_set(codec, 0x6230, 0xf80d4011);
3142	alc5505_coef_set(codec, 0x6220, 0x2002010f);
3143	alc5505_coef_set(codec, 0x880c, 0x00000004);
3144}
3145
3146static void alc5505_dsp_init(struct hda_codec *codec)
3147{
3148	unsigned int val;
3149
3150	alc5505_dsp_halt(codec);
3151	alc5505_dsp_back_from_halt(codec);
3152	alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
3153	alc5505_coef_set(codec, 0x61b0, 0x5b16);
3154	alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
3155	alc5505_coef_set(codec, 0x61b4, 0x04132b02);
3156	alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
3157	alc5505_coef_set(codec, 0x61b8, 0x041f3302);
3158	snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
3159	alc5505_coef_set(codec, 0x61b8, 0x041b3302);
3160	alc5505_coef_set(codec, 0x61b8, 0x04173302);
3161	alc5505_coef_set(codec, 0x61b8, 0x04163302);
3162	alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
3163	alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3164	alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3165
3166	val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3167	if (val <= 3)
3168		alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3169	else
3170		alc5505_coef_set(codec, 0x6220, 0x6002018f);
3171
3172	alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3173	alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3174	alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3175	alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3176	alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3177	alc5505_coef_set(codec, 0x880c, 0x00000003);
3178	alc5505_coef_set(codec, 0x880c, 0x00000010);
3179
3180#ifdef HALT_REALTEK_ALC5505
3181	alc5505_dsp_halt(codec);
3182#endif
3183}
3184
3185#ifdef HALT_REALTEK_ALC5505
3186#define alc5505_dsp_suspend(codec)	/* NOP */
3187#define alc5505_dsp_resume(codec)	/* NOP */
3188#else
3189#define alc5505_dsp_suspend(codec)	alc5505_dsp_halt(codec)
3190#define alc5505_dsp_resume(codec)	alc5505_dsp_back_from_halt(codec)
3191#endif
3192
3193#ifdef CONFIG_PM
3194static int alc269_suspend(struct hda_codec *codec)
3195{
3196	struct alc_spec *spec = codec->spec;
3197
3198	if (spec->has_alc5505_dsp)
3199		alc5505_dsp_suspend(codec);
3200	return alc_suspend(codec);
3201}
3202
3203static int alc269_resume(struct hda_codec *codec)
3204{
3205	struct alc_spec *spec = codec->spec;
3206
3207	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3208		alc269vb_toggle_power_output(codec, 0);
3209	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3210			(alc_get_coef0(codec) & 0x00ff) == 0x018) {
 
3211		msleep(150);
3212	}
3213
3214	codec->patch_ops.init(codec);
3215
3216	if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3217		alc269vb_toggle_power_output(codec, 1);
3218	if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3219			(alc_get_coef0(codec) & 0x00ff) == 0x017) {
 
3220		msleep(200);
3221	}
3222
 
 
 
 
3223	snd_hda_codec_resume_amp(codec);
3224	snd_hda_codec_resume_cache(codec);
3225	alc_inv_dmic_sync(codec, true);
3226	hda_call_check_power_status(codec, 0x01);
3227	if (spec->has_alc5505_dsp)
3228		alc5505_dsp_resume(codec);
3229
3230	return 0;
3231}
3232#endif /* CONFIG_PM */
3233
3234static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
3235						 const struct hda_fixup *fix, int action)
3236{
3237	struct alc_spec *spec = codec->spec;
3238
3239	if (action == HDA_FIXUP_ACT_PRE_PROBE)
3240		spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3241}
3242
3243static void alc269_fixup_hweq(struct hda_codec *codec,
3244			       const struct hda_fixup *fix, int action)
3245{
3246	int coef;
3247
3248	if (action != HDA_FIXUP_ACT_INIT)
3249		return;
3250	coef = alc_read_coef_idx(codec, 0x1e);
3251	alc_write_coef_idx(codec, 0x1e, coef | 0x80);
3252}
3253
3254static void alc269_fixup_headset_mic(struct hda_codec *codec,
3255				       const struct hda_fixup *fix, int action)
3256{
3257	struct alc_spec *spec = codec->spec;
3258
3259	if (action == HDA_FIXUP_ACT_PRE_PROBE)
3260		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3261}
3262
3263static void alc271_fixup_dmic(struct hda_codec *codec,
3264			      const struct hda_fixup *fix, int action)
3265{
3266	static const struct hda_verb verbs[] = {
3267		{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3268		{0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3269		{}
3270	};
3271	unsigned int cfg;
3272
3273	if (strcmp(codec->chip_name, "ALC271X") &&
3274	    strcmp(codec->chip_name, "ALC269VB"))
3275		return;
3276	cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3277	if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3278		snd_hda_sequence_write(codec, verbs);
3279}
3280
3281static void alc269_fixup_pcm_44k(struct hda_codec *codec,
3282				 const struct hda_fixup *fix, int action)
3283{
3284	struct alc_spec *spec = codec->spec;
3285
3286	if (action != HDA_FIXUP_ACT_PROBE)
3287		return;
3288
3289	/* Due to a hardware problem on Lenovo Ideadpad, we need to
3290	 * fix the sample rate of analog I/O to 44.1kHz
3291	 */
3292	spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3293	spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
3294}
3295
3296static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
3297				     const struct hda_fixup *fix, int action)
3298{
3299	int coef;
3300
3301	if (action != HDA_FIXUP_ACT_INIT)
3302		return;
3303	/* The digital-mic unit sends PDM (differential signal) instead of
3304	 * the standard PCM, thus you can't record a valid mono stream as is.
3305	 * Below is a workaround specific to ALC269 to control the dmic
3306	 * signal source as mono.
3307	 */
3308	coef = alc_read_coef_idx(codec, 0x07);
3309	alc_write_coef_idx(codec, 0x07, coef | 0x80);
3310}
3311
3312static void alc269_quanta_automute(struct hda_codec *codec)
3313{
3314	snd_hda_gen_update_outputs(codec);
3315
3316	snd_hda_codec_write(codec, 0x20, 0,
3317			AC_VERB_SET_COEF_INDEX, 0x0c);
3318	snd_hda_codec_write(codec, 0x20, 0,
3319			AC_VERB_SET_PROC_COEF, 0x680);
3320
3321	snd_hda_codec_write(codec, 0x20, 0,
3322			AC_VERB_SET_COEF_INDEX, 0x0c);
3323	snd_hda_codec_write(codec, 0x20, 0,
3324			AC_VERB_SET_PROC_COEF, 0x480);
3325}
3326
3327static void alc269_fixup_quanta_mute(struct hda_codec *codec,
3328				     const struct hda_fixup *fix, int action)
3329{
3330	struct alc_spec *spec = codec->spec;
3331	if (action != HDA_FIXUP_ACT_PROBE)
3332		return;
3333	spec->gen.automute_hook = alc269_quanta_automute;
3334}
3335
3336static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
3337					 struct hda_jack_tbl *jack)
3338{
3339	struct alc_spec *spec = codec->spec;
3340	int vref;
3341	msleep(200);
3342	snd_hda_gen_hp_automute(codec, jack);
3343
3344	vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3345	msleep(100);
3346	snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3347			    vref);
3348	msleep(500);
3349	snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3350			    vref);
3351}
3352
3353static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3354				     const struct hda_fixup *fix, int action)
3355{
3356	struct alc_spec *spec = codec->spec;
3357	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3358		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3359		spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3360	}
3361}
3362
3363
3364/* update mute-LED according to the speaker mute state via mic VREF pin */
3365static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
3366{
3367	struct hda_codec *codec = private_data;
3368	struct alc_spec *spec = codec->spec;
3369	unsigned int pinval;
3370
3371	if (spec->mute_led_polarity)
3372		enabled = !enabled;
3373	pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3374	pinval &= ~AC_PINCTL_VREFEN;
3375	pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
3376	if (spec->mute_led_nid)
3377		snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
3378}
3379
3380/* Make sure the led works even in runtime suspend */
3381static unsigned int led_power_filter(struct hda_codec *codec,
3382						  hda_nid_t nid,
3383						  unsigned int power_state)
3384{
3385	struct alc_spec *spec = codec->spec;
3386
3387	if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid)
3388		return power_state;
3389
3390	/* Set pin ctl again, it might have just been set to 0 */
3391	snd_hda_set_pin_ctl(codec, nid,
3392			    snd_hda_codec_get_pin_target(codec, nid));
3393
3394	return AC_PWRST_D0;
3395}
3396
3397static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3398				     const struct hda_fixup *fix, int action)
3399{
3400	struct alc_spec *spec = codec->spec;
3401	const struct dmi_device *dev = NULL;
3402
3403	if (action != HDA_FIXUP_ACT_PRE_PROBE)
3404		return;
3405
3406	while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3407		int pol, pin;
3408		if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3409			continue;
3410		if (pin < 0x0a || pin >= 0x10)
3411			break;
3412		spec->mute_led_polarity = pol;
3413		spec->mute_led_nid = pin - 0x0a + 0x18;
3414		spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3415		spec->gen.vmaster_mute_enum = 1;
3416		codec->power_filter = led_power_filter;
3417		codec_dbg(codec,
3418			  "Detected mute LED for %x:%d\n", spec->mute_led_nid,
3419			   spec->mute_led_polarity);
3420		break;
3421	}
3422}
3423
3424static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3425				const struct hda_fixup *fix, int action)
3426{
3427	struct alc_spec *spec = codec->spec;
3428	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3429		spec->mute_led_polarity = 0;
3430		spec->mute_led_nid = 0x18;
3431		spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3432		spec->gen.vmaster_mute_enum = 1;
3433		codec->power_filter = led_power_filter;
3434	}
3435}
3436
3437static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3438				const struct hda_fixup *fix, int action)
3439{
3440	struct alc_spec *spec = codec->spec;
3441	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3442		spec->mute_led_polarity = 0;
3443		spec->mute_led_nid = 0x19;
3444		spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3445		spec->gen.vmaster_mute_enum = 1;
3446		codec->power_filter = led_power_filter;
3447	}
3448}
3449
3450/* turn on/off mute LED per vmaster hook */
3451static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled)
3452{
3453	struct hda_codec *codec = private_data;
3454	struct alc_spec *spec = codec->spec;
3455	unsigned int oldval = spec->gpio_led;
3456
3457	if (enabled)
3458		spec->gpio_led &= ~0x08;
3459	else
3460		spec->gpio_led |= 0x08;
3461	if (spec->gpio_led != oldval)
3462		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3463				    spec->gpio_led);
3464}
3465
3466/* turn on/off mic-mute LED per capture hook */
3467static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec,
3468					       struct snd_kcontrol *kcontrol,
3469					       struct snd_ctl_elem_value *ucontrol)
3470{
3471	struct alc_spec *spec = codec->spec;
3472	unsigned int oldval = spec->gpio_led;
3473
3474	if (!ucontrol)
3475		return;
3476
3477	if (ucontrol->value.integer.value[0] ||
3478	    ucontrol->value.integer.value[1])
3479		spec->gpio_led &= ~0x10;
3480	else
3481		spec->gpio_led |= 0x10;
3482	if (spec->gpio_led != oldval)
3483		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3484				    spec->gpio_led);
3485}
3486
3487static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3488				const struct hda_fixup *fix, int action)
3489{
3490	struct alc_spec *spec = codec->spec;
3491	static const struct hda_verb gpio_init[] = {
3492		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3493		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3494		{}
3495	};
3496
3497	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3498		spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook;
3499		spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook;
3500		spec->gpio_led = 0;
3501		snd_hda_add_verbs(codec, gpio_init);
3502	}
3503}
3504
3505static void alc_headset_mode_unplugged(struct hda_codec *codec)
3506{
3507	int val;
3508
3509	switch (codec->vendor_id) {
3510	case 0x10ec0255:
3511		/* LDO and MISC control */
3512		alc_write_coef_idx(codec, 0x1b, 0x0c0b);
3513		/* UAJ function set to menual mode */
3514		alc_write_coef_idx(codec, 0x45, 0xd089);
3515		/* Direct Drive HP Amp control(Set to verb control)*/
3516		val = alc_read_coefex_idx(codec, 0x57, 0x05);
3517		alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14));
3518		/* Set MIC2 Vref gate with HP */
3519		alc_write_coef_idx(codec, 0x06, 0x6104);
3520		/* Direct Drive HP Amp control */
3521		alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6);
3522		break;
3523	case 0x10ec0283:
3524		alc_write_coef_idx(codec, 0x1b, 0x0c0b);
3525		alc_write_coef_idx(codec, 0x45, 0xc429);
3526		val = alc_read_coef_idx(codec, 0x35);
3527		alc_write_coef_idx(codec, 0x35, val & 0xbfff);
3528		alc_write_coef_idx(codec, 0x06, 0x2104);
3529		alc_write_coef_idx(codec, 0x1a, 0x0001);
3530		alc_write_coef_idx(codec, 0x26, 0x0004);
3531		alc_write_coef_idx(codec, 0x32, 0x42a3);
3532		break;
3533	case 0x10ec0292:
3534		alc_write_coef_idx(codec, 0x76, 0x000e);
3535		alc_write_coef_idx(codec, 0x6c, 0x2400);
3536		alc_write_coef_idx(codec, 0x18, 0x7308);
3537		alc_write_coef_idx(codec, 0x6b, 0xc429);
3538		break;
3539	case 0x10ec0668:
3540		alc_write_coef_idx(codec, 0x15, 0x0d40);
3541		alc_write_coef_idx(codec, 0xb7, 0x802b);
3542		break;
3543	}
3544	codec_dbg(codec, "Headset jack set to unplugged mode.\n");
3545}
3546
3547
3548static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3549				    hda_nid_t mic_pin)
3550{
3551	int val;
3552
3553	switch (codec->vendor_id) {
3554	case 0x10ec0255:
3555		alc_write_coef_idx(codec, 0x45, 0xc489);
3556		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3557		alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6);
3558		/* Set MIC2 Vref gate to normal */
3559		alc_write_coef_idx(codec, 0x06, 0x6100);
3560		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3561		break;
3562	case 0x10ec0283:
3563		alc_write_coef_idx(codec, 0x45, 0xc429);
3564		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3565		val = alc_read_coef_idx(codec, 0x35);
3566		alc_write_coef_idx(codec, 0x35, val | 1<<14);
3567		alc_write_coef_idx(codec, 0x06, 0x2100);
3568		alc_write_coef_idx(codec, 0x1a, 0x0021);
3569		alc_write_coef_idx(codec, 0x26, 0x008c);
3570		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3571		break;
3572	case 0x10ec0292:
3573		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3574		alc_write_coef_idx(codec, 0x19, 0xa208);
3575		alc_write_coef_idx(codec, 0x2e, 0xacf0);
3576		break;
3577	case 0x10ec0668:
3578		alc_write_coef_idx(codec, 0x11, 0x0001);
3579		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3580		alc_write_coef_idx(codec, 0xb7, 0x802b);
3581		alc_write_coef_idx(codec, 0xb5, 0x1040);
3582		val = alc_read_coef_idx(codec, 0xc3);
3583		alc_write_coef_idx(codec, 0xc3, val | 1<<12);
3584		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3585		break;
3586	}
3587	codec_dbg(codec, "Headset jack set to mic-in mode.\n");
3588}
3589
3590static void alc_headset_mode_default(struct hda_codec *codec)
3591{
3592	switch (codec->vendor_id) {
3593	case 0x10ec0255:
3594		alc_write_coef_idx(codec, 0x45, 0xc089);
3595		alc_write_coef_idx(codec, 0x45, 0xc489);
3596		alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6);
3597		alc_write_coef_idx(codec, 0x49, 0x0049);
3598		break;
3599	case 0x10ec0283:
3600		alc_write_coef_idx(codec, 0x06, 0x2100);
3601		alc_write_coef_idx(codec, 0x32, 0x4ea3);
3602		break;
3603	case 0x10ec0292:
3604		alc_write_coef_idx(codec, 0x76, 0x000e);
3605		alc_write_coef_idx(codec, 0x6c, 0x2400);
3606		alc_write_coef_idx(codec, 0x6b, 0xc429);
3607		alc_write_coef_idx(codec, 0x18, 0x7308);
3608		break;
3609	case 0x10ec0668:
3610		alc_write_coef_idx(codec, 0x11, 0x0041);
3611		alc_write_coef_idx(codec, 0x15, 0x0d40);
3612		alc_write_coef_idx(codec, 0xb7, 0x802b);
3613		break;
3614	}
3615	codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
3616}
3617
3618/* Iphone type */
3619static void alc_headset_mode_ctia(struct hda_codec *codec)
3620{
3621	switch (codec->vendor_id) {
3622	case 0x10ec0255:
3623		/* Set to CTIA type */
3624		alc_write_coef_idx(codec, 0x45, 0xd489);
3625		alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3626		alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6);
3627		break;
3628	case 0x10ec0283:
3629		alc_write_coef_idx(codec, 0x45, 0xd429);
3630		alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3631		alc_write_coef_idx(codec, 0x32, 0x4ea3);
3632		break;
3633	case 0x10ec0292:
3634		alc_write_coef_idx(codec, 0x6b, 0xd429);
3635		alc_write_coef_idx(codec, 0x76, 0x0008);
3636		alc_write_coef_idx(codec, 0x18, 0x7388);
3637		break;
3638	case 0x10ec0668:
3639		alc_write_coef_idx(codec, 0x11, 0x0001);
3640		alc_write_coef_idx(codec, 0x15, 0x0d60);
3641		alc_write_coef_idx(codec, 0xc3, 0x0000);
3642		break;
3643	}
3644	codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
3645}
3646
3647/* Nokia type */
3648static void alc_headset_mode_omtp(struct hda_codec *codec)
3649{
3650	switch (codec->vendor_id) {
3651	case 0x10ec0255:
3652		/* Set to OMTP Type */
3653		alc_write_coef_idx(codec, 0x45, 0xe489);
3654		alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3655		alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6);
3656		break;
3657	case 0x10ec0283:
3658		alc_write_coef_idx(codec, 0x45, 0xe429);
3659		alc_write_coef_idx(codec, 0x1b, 0x0c2b);
3660		alc_write_coef_idx(codec, 0x32, 0x4ea3);
3661		break;
3662	case 0x10ec0292:
3663		alc_write_coef_idx(codec, 0x6b, 0xe429);
3664		alc_write_coef_idx(codec, 0x76, 0x0008);
3665		alc_write_coef_idx(codec, 0x18, 0x7388);
3666		break;
3667	case 0x10ec0668:
3668		alc_write_coef_idx(codec, 0x11, 0x0001);
3669		alc_write_coef_idx(codec, 0x15, 0x0d50);
3670		alc_write_coef_idx(codec, 0xc3, 0x0000);
3671		break;
3672	}
3673	codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
3674}
3675
3676static void alc_determine_headset_type(struct hda_codec *codec)
3677{
3678	int val;
3679	bool is_ctia = false;
3680	struct alc_spec *spec = codec->spec;
3681
3682	switch (codec->vendor_id) {
3683	case 0x10ec0255:
3684		/* combo jack auto switch control(Check type)*/
3685		alc_write_coef_idx(codec, 0x45, 0xd089);
3686		/* combo jack auto switch control(Vref conteol) */
3687		alc_write_coef_idx(codec, 0x49, 0x0149);
3688		msleep(300);
3689		val = alc_read_coef_idx(codec, 0x46);
3690		is_ctia = (val & 0x0070) == 0x0070;
3691		break;
3692	case 0x10ec0283:
3693		alc_write_coef_idx(codec, 0x45, 0xd029);
3694		msleep(300);
3695		val = alc_read_coef_idx(codec, 0x46);
3696		is_ctia = (val & 0x0070) == 0x0070;
3697		break;
3698	case 0x10ec0292:
3699		alc_write_coef_idx(codec, 0x6b, 0xd429);
3700		msleep(300);
3701		val = alc_read_coef_idx(codec, 0x6c);
3702		is_ctia = (val & 0x001c) == 0x001c;
3703		break;
3704	case 0x10ec0668:
3705		alc_write_coef_idx(codec, 0x11, 0x0001);
3706		alc_write_coef_idx(codec, 0xb7, 0x802b);
3707		alc_write_coef_idx(codec, 0x15, 0x0d60);
3708		alc_write_coef_idx(codec, 0xc3, 0x0c00);
3709		msleep(300);
3710		val = alc_read_coef_idx(codec, 0xbe);
3711		is_ctia = (val & 0x1c02) == 0x1c02;
3712		break;
3713	}
3714
3715	codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
3716		    is_ctia ? "yes" : "no");
3717	spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
3718}
3719
3720static void alc_update_headset_mode(struct hda_codec *codec)
3721{
3722	struct alc_spec *spec = codec->spec;
3723
3724	hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
3725	hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3726
3727	int new_headset_mode;
3728
3729	if (!snd_hda_jack_detect(codec, hp_pin))
3730		new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
3731	else if (mux_pin == spec->headset_mic_pin)
3732		new_headset_mode = ALC_HEADSET_MODE_HEADSET;
3733	else if (mux_pin == spec->headphone_mic_pin)
3734		new_headset_mode = ALC_HEADSET_MODE_MIC;
3735	else
3736		new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
3737
3738	if (new_headset_mode == spec->current_headset_mode) {
3739		snd_hda_gen_update_outputs(codec);
3740		return;
3741	}
3742
3743	switch (new_headset_mode) {
3744	case ALC_HEADSET_MODE_UNPLUGGED:
3745		alc_headset_mode_unplugged(codec);
3746		spec->gen.hp_jack_present = false;
3747		break;
3748	case ALC_HEADSET_MODE_HEADSET:
3749		if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
3750			alc_determine_headset_type(codec);
3751		if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
3752			alc_headset_mode_ctia(codec);
3753		else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
3754			alc_headset_mode_omtp(codec);
3755		spec->gen.hp_jack_present = true;
3756		break;
3757	case ALC_HEADSET_MODE_MIC:
3758		alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
3759		spec->gen.hp_jack_present = false;
3760		break;
3761	case ALC_HEADSET_MODE_HEADPHONE:
3762		alc_headset_mode_default(codec);
3763		spec->gen.hp_jack_present = true;
3764		break;
3765	}
3766	if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
3767		snd_hda_set_pin_ctl_cache(codec, hp_pin,
3768					  AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
3769		if (spec->headphone_mic_pin)
3770			snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
3771						  PIN_VREFHIZ);
3772	}
3773	spec->current_headset_mode = new_headset_mode;
3774
3775	snd_hda_gen_update_outputs(codec);
3776}
3777
3778static void alc_update_headset_mode_hook(struct hda_codec *codec,
3779					 struct snd_kcontrol *kcontrol,
3780					 struct snd_ctl_elem_value *ucontrol)
3781{
3782	alc_update_headset_mode(codec);
3783}
3784
3785static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack)
3786{
3787	struct alc_spec *spec = codec->spec;
3788	spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
3789	snd_hda_gen_hp_automute(codec, jack);
3790}
3791
3792static void alc_probe_headset_mode(struct hda_codec *codec)
3793{
3794	int i;
3795	struct alc_spec *spec = codec->spec;
3796	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3797
3798	/* Find mic pins */
3799	for (i = 0; i < cfg->num_inputs; i++) {
3800		if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
3801			spec->headset_mic_pin = cfg->inputs[i].pin;
3802		if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
3803			spec->headphone_mic_pin = cfg->inputs[i].pin;
3804	}
3805
3806	spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
3807	spec->gen.automute_hook = alc_update_headset_mode;
3808	spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
3809}
3810
3811static void alc_fixup_headset_mode(struct hda_codec *codec,
3812				const struct hda_fixup *fix, int action)
3813{
3814	struct alc_spec *spec = codec->spec;
3815
3816	switch (action) {
3817	case HDA_FIXUP_ACT_PRE_PROBE:
3818		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
3819		break;
3820	case HDA_FIXUP_ACT_PROBE:
3821		alc_probe_headset_mode(codec);
 
3822		break;
3823	case HDA_FIXUP_ACT_INIT:
3824		spec->current_headset_mode = 0;
3825		alc_update_headset_mode(codec);
3826		break;
3827	}
3828}
3829
3830static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
3831				const struct hda_fixup *fix, int action)
3832{
3833	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3834		struct alc_spec *spec = codec->spec;
3835		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3836	}
3837	else
3838		alc_fixup_headset_mode(codec, fix, action);
3839}
3840
3841static void alc255_set_default_jack_type(struct hda_codec *codec)
3842{
3843	/* Set to iphone type */
3844	alc_write_coef_idx(codec, 0x1b, 0x880b);
3845	alc_write_coef_idx(codec, 0x45, 0xd089);
3846	alc_write_coef_idx(codec, 0x1b, 0x080b);
3847	alc_write_coef_idx(codec, 0x46, 0x0004);
3848	alc_write_coef_idx(codec, 0x1b, 0x0c0b);
3849	msleep(30);
3850}
3851
3852static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
3853				const struct hda_fixup *fix, int action)
3854{
3855	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3856		alc255_set_default_jack_type(codec);
3857	}
3858	alc_fixup_headset_mode(codec, fix, action);
3859}
3860
3861static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
3862				const struct hda_fixup *fix, int action)
3863{
3864	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3865		struct alc_spec *spec = codec->spec;
3866		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3867		alc255_set_default_jack_type(codec);
3868	} 
3869	else
3870		alc_fixup_headset_mode(codec, fix, action);
3871}
3872
3873static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
3874					const struct hda_fixup *fix, int action)
3875{
3876	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3877		struct alc_spec *spec = codec->spec;
3878		spec->gen.auto_mute_via_amp = 1;
3879	}
3880}
3881
3882static void alc_no_shutup(struct hda_codec *codec)
3883{
3884}
3885
3886static void alc_fixup_no_shutup(struct hda_codec *codec,
3887				const struct hda_fixup *fix, int action)
3888{
3889	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3890		struct alc_spec *spec = codec->spec;
3891		spec->shutup = alc_no_shutup;
3892	}
3893}
3894
3895static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
3896				const struct hda_fixup *fix, int action)
3897{
3898	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3899		int val;
3900		alc_write_coef_idx(codec, 0xc4, 0x8000);
3901		val = alc_read_coef_idx(codec, 0xc2);
3902		alc_write_coef_idx(codec, 0xc2, val & 0xfe);
3903		snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
3904	}
3905	alc_fixup_headset_mode(codec, fix, action);
3906}
3907
3908/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
3909static int find_ext_mic_pin(struct hda_codec *codec)
3910{
3911	struct alc_spec *spec = codec->spec;
3912	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3913	hda_nid_t nid;
3914	unsigned int defcfg;
3915	int i;
3916
3917	for (i = 0; i < cfg->num_inputs; i++) {
3918		if (cfg->inputs[i].type != AUTO_PIN_MIC)
3919			continue;
3920		nid = cfg->inputs[i].pin;
3921		defcfg = snd_hda_codec_get_pincfg(codec, nid);
3922		if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
3923			continue;
3924		return nid;
3925	}
3926
3927	return 0;
3928}
3929
3930static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
3931				    const struct hda_fixup *fix,
3932				    int action)
3933{
3934	struct alc_spec *spec = codec->spec;
3935
3936	if (action == HDA_FIXUP_ACT_PROBE) {
3937		int mic_pin = find_ext_mic_pin(codec);
3938		int hp_pin = spec->gen.autocfg.hp_pins[0];
3939
3940		if (snd_BUG_ON(!mic_pin || !hp_pin))
3941			return;
3942		snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
3943	}
3944}
3945
3946static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
3947					     const struct hda_fixup *fix,
3948					     int action)
3949{
3950	struct alc_spec *spec = codec->spec;
3951	struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3952	int i;
3953
3954	/* The mic boosts on level 2 and 3 are too noisy
3955	   on the internal mic input.
3956	   Therefore limit the boost to 0 or 1. */
3957
3958	if (action != HDA_FIXUP_ACT_PROBE)
3959		return;
3960
3961	for (i = 0; i < cfg->num_inputs; i++) {
3962		hda_nid_t nid = cfg->inputs[i].pin;
3963		unsigned int defcfg;
3964		if (cfg->inputs[i].type != AUTO_PIN_MIC)
3965			continue;
3966		defcfg = snd_hda_codec_get_pincfg(codec, nid);
3967		if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
3968			continue;
3969
3970		snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
3971					  (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
3972					  (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3973					  (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
3974					  (0 << AC_AMPCAP_MUTE_SHIFT));
3975	}
3976}
3977
3978static void alc283_hp_automute_hook(struct hda_codec *codec,
3979				    struct hda_jack_tbl *jack)
3980{
3981	struct alc_spec *spec = codec->spec;
3982	int vref;
3983
3984	msleep(200);
3985	snd_hda_gen_hp_automute(codec, jack);
3986
3987	vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3988
3989	msleep(600);
3990	snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3991			    vref);
3992}
3993
3994static void alc283_fixup_chromebook(struct hda_codec *codec,
3995				    const struct hda_fixup *fix, int action)
3996{
3997	struct alc_spec *spec = codec->spec;
3998	int val;
3999
4000	switch (action) {
4001	case HDA_FIXUP_ACT_PRE_PROBE:
4002		snd_hda_override_wcaps(codec, 0x03, 0);
4003		/* Disable AA-loopback as it causes white noise */
4004		spec->gen.mixer_nid = 0;
4005		break;
4006	case HDA_FIXUP_ACT_INIT:
4007		/* MIC2-VREF control */
4008		/* Set to manual mode */
4009		val = alc_read_coef_idx(codec, 0x06);
4010		alc_write_coef_idx(codec, 0x06, val & ~0x000c);
4011		/* Enable Line1 input control by verb */
4012		val = alc_read_coef_idx(codec, 0x1a);
4013		alc_write_coef_idx(codec, 0x1a, val | (1 << 4));
4014		break;
4015	}
4016}
4017
4018static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
4019				    const struct hda_fixup *fix, int action)
4020{
4021	struct alc_spec *spec = codec->spec;
4022	int val;
4023
4024	switch (action) {
4025	case HDA_FIXUP_ACT_PRE_PROBE:
4026		spec->gen.hp_automute_hook = alc283_hp_automute_hook;
4027		break;
4028	case HDA_FIXUP_ACT_INIT:
4029		/* MIC2-VREF control */
4030		/* Set to manual mode */
4031		val = alc_read_coef_idx(codec, 0x06);
4032		alc_write_coef_idx(codec, 0x06, val & ~0x000c);
4033		break;
4034	}
4035}
4036
4037/* mute tablet speaker pin (0x14) via dock plugging in addition */
4038static void asus_tx300_automute(struct hda_codec *codec)
4039{
4040	struct alc_spec *spec = codec->spec;
4041	snd_hda_gen_update_outputs(codec);
4042	if (snd_hda_jack_detect(codec, 0x1b))
4043		spec->gen.mute_bits |= (1ULL << 0x14);
4044}
4045
4046static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4047				    const struct hda_fixup *fix, int action)
4048{
4049	struct alc_spec *spec = codec->spec;
4050	/* TX300 needs to set up GPIO2 for the speaker amp */
4051	static const struct hda_verb gpio2_verbs[] = {
4052		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
4053		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
4054		{ 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
4055		{}
4056	};
4057	static const struct hda_pintbl dock_pins[] = {
4058		{ 0x1b, 0x21114000 }, /* dock speaker pin */
4059		{}
4060	};
4061	struct snd_kcontrol *kctl;
4062
4063	switch (action) {
4064	case HDA_FIXUP_ACT_PRE_PROBE:
4065		snd_hda_add_verbs(codec, gpio2_verbs);
4066		snd_hda_apply_pincfgs(codec, dock_pins);
4067		spec->gen.auto_mute_via_amp = 1;
4068		spec->gen.automute_hook = asus_tx300_automute;
4069		snd_hda_jack_detect_enable_callback(codec, 0x1b,
4070						    HDA_GEN_HP_EVENT,
4071						    snd_hda_gen_hp_automute);
4072		break;
4073	case HDA_FIXUP_ACT_BUILD:
4074		/* this is a bit tricky; give more sane names for the main
4075		 * (tablet) speaker and the dock speaker, respectively
4076		 */
4077		kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
4078		if (kctl)
4079			strcpy(kctl->id.name, "Dock Speaker Playback Switch");
4080		kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
4081		if (kctl)
4082			strcpy(kctl->id.name, "Speaker Playback Switch");
4083		break;
4084	}
4085}
4086
4087static void alc290_fixup_mono_speakers(struct hda_codec *codec,
4088				       const struct hda_fixup *fix, int action)
4089{
4090	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4091		/* DAC node 0x03 is giving mono output. We therefore want to
4092		   make sure 0x14 (front speaker) and 0x15 (headphones) use the
4093		   stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
4094		hda_nid_t conn1[2] = { 0x0c };
4095		snd_hda_override_conn_list(codec, 0x14, 1, conn1);
4096		snd_hda_override_conn_list(codec, 0x15, 1, conn1);
4097	}
4098}
4099
4100/* for hda_fixup_thinkpad_acpi() */
4101#include "thinkpad_helper.c"
4102
4103enum {
4104	ALC269_FIXUP_SONY_VAIO,
4105	ALC275_FIXUP_SONY_VAIO_GPIO2,
4106	ALC269_FIXUP_DELL_M101Z,
4107	ALC269_FIXUP_SKU_IGNORE,
4108	ALC269_FIXUP_ASUS_G73JW,
4109	ALC269_FIXUP_LENOVO_EAPD,
4110	ALC275_FIXUP_SONY_HWEQ,
4111	ALC271_FIXUP_DMIC,
4112	ALC269_FIXUP_PCM_44K,
4113	ALC269_FIXUP_STEREO_DMIC,
4114	ALC269_FIXUP_HEADSET_MIC,
4115	ALC269_FIXUP_QUANTA_MUTE,
4116	ALC269_FIXUP_LIFEBOOK,
4117	ALC269_FIXUP_AMIC,
4118	ALC269_FIXUP_DMIC,
4119	ALC269VB_FIXUP_AMIC,
4120	ALC269VB_FIXUP_DMIC,
4121	ALC269_FIXUP_HP_MUTE_LED,
4122	ALC269_FIXUP_HP_MUTE_LED_MIC1,
4123	ALC269_FIXUP_HP_MUTE_LED_MIC2,
4124	ALC269_FIXUP_HP_GPIO_LED,
4125	ALC269_FIXUP_INV_DMIC,
4126	ALC269_FIXUP_LENOVO_DOCK,
4127	ALC269_FIXUP_NO_SHUTUP,
4128	ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
4129	ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
4130	ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
4131	ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
4132	ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
4133	ALC269_FIXUP_HEADSET_MODE,
4134	ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
4135	ALC269_FIXUP_ASUS_X101_FUNC,
4136	ALC269_FIXUP_ASUS_X101_VERB,
4137	ALC269_FIXUP_ASUS_X101,
4138	ALC271_FIXUP_AMIC_MIC2,
4139	ALC271_FIXUP_HP_GATE_MIC_JACK,
4140	ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
4141	ALC269_FIXUP_ACER_AC700,
4142	ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
4143	ALC269VB_FIXUP_ASUS_ZENBOOK,
4144	ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
4145	ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
4146	ALC269VB_FIXUP_ORDISSIMO_EVE2,
4147	ALC283_FIXUP_CHROME_BOOK,
4148	ALC283_FIXUP_SENSE_COMBO_JACK,
4149	ALC282_FIXUP_ASUS_TX300,
4150	ALC283_FIXUP_INT_MIC,
4151	ALC290_FIXUP_MONO_SPEAKERS,
4152	ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4153	ALC290_FIXUP_SUBWOOFER,
4154	ALC290_FIXUP_SUBWOOFER_HSJACK,
4155	ALC269_FIXUP_THINKPAD_ACPI,
4156	ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
4157	ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
4158	ALC255_FIXUP_HEADSET_MODE,
4159	ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
4160};
4161
4162static const struct hda_fixup alc269_fixups[] = {
4163	[ALC269_FIXUP_SONY_VAIO] = {
4164		.type = HDA_FIXUP_PINCTLS,
4165		.v.pins = (const struct hda_pintbl[]) {
4166			{0x19, PIN_VREFGRD},
4167			{}
4168		}
4169	},
4170	[ALC275_FIXUP_SONY_VAIO_GPIO2] = {
4171		.type = HDA_FIXUP_VERBS,
4172		.v.verbs = (const struct hda_verb[]) {
4173			{0x01, AC_VERB_SET_GPIO_MASK, 0x04},
4174			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
4175			{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4176			{ }
4177		},
4178		.chained = true,
4179		.chain_id = ALC269_FIXUP_SONY_VAIO
4180	},
4181	[ALC269_FIXUP_DELL_M101Z] = {
4182		.type = HDA_FIXUP_VERBS,
4183		.v.verbs = (const struct hda_verb[]) {
4184			/* Enables internal speaker */
4185			{0x20, AC_VERB_SET_COEF_INDEX, 13},
4186			{0x20, AC_VERB_SET_PROC_COEF, 0x4040},
4187			{}
4188		}
4189	},
4190	[ALC269_FIXUP_SKU_IGNORE] = {
4191		.type = HDA_FIXUP_FUNC,
4192		.v.func = alc_fixup_sku_ignore,
4193	},
4194	[ALC269_FIXUP_ASUS_G73JW] = {
4195		.type = HDA_FIXUP_PINS,
4196		.v.pins = (const struct hda_pintbl[]) {
4197			{ 0x17, 0x99130111 }, /* subwoofer */
4198			{ }
4199		}
4200	},
4201	[ALC269_FIXUP_LENOVO_EAPD] = {
4202		.type = HDA_FIXUP_VERBS,
4203		.v.verbs = (const struct hda_verb[]) {
4204			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
4205			{}
4206		}
4207	},
4208	[ALC275_FIXUP_SONY_HWEQ] = {
4209		.type = HDA_FIXUP_FUNC,
4210		.v.func = alc269_fixup_hweq,
4211		.chained = true,
4212		.chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
4213	},
4214	[ALC271_FIXUP_DMIC] = {
4215		.type = HDA_FIXUP_FUNC,
4216		.v.func = alc271_fixup_dmic,
4217	},
4218	[ALC269_FIXUP_PCM_44K] = {
4219		.type = HDA_FIXUP_FUNC,
4220		.v.func = alc269_fixup_pcm_44k,
4221		.chained = true,
4222		.chain_id = ALC269_FIXUP_QUANTA_MUTE
4223	},
4224	[ALC269_FIXUP_STEREO_DMIC] = {
4225		.type = HDA_FIXUP_FUNC,
4226		.v.func = alc269_fixup_stereo_dmic,
4227	},
4228	[ALC269_FIXUP_HEADSET_MIC] = {
4229		.type = HDA_FIXUP_FUNC,
4230		.v.func = alc269_fixup_headset_mic,
4231	},
4232	[ALC269_FIXUP_QUANTA_MUTE] = {
4233		.type = HDA_FIXUP_FUNC,
4234		.v.func = alc269_fixup_quanta_mute,
4235	},
4236	[ALC269_FIXUP_LIFEBOOK] = {
4237		.type = HDA_FIXUP_PINS,
4238		.v.pins = (const struct hda_pintbl[]) {
4239			{ 0x1a, 0x2101103f }, /* dock line-out */
4240			{ 0x1b, 0x23a11040 }, /* dock mic-in */
4241			{ }
4242		},
4243		.chained = true,
4244		.chain_id = ALC269_FIXUP_QUANTA_MUTE
4245	},
4246	[ALC269_FIXUP_AMIC] = {
4247		.type = HDA_FIXUP_PINS,
4248		.v.pins = (const struct hda_pintbl[]) {
4249			{ 0x14, 0x99130110 }, /* speaker */
4250			{ 0x15, 0x0121401f }, /* HP out */
4251			{ 0x18, 0x01a19c20 }, /* mic */
4252			{ 0x19, 0x99a3092f }, /* int-mic */
4253			{ }
4254		},
4255	},
4256	[ALC269_FIXUP_DMIC] = {
4257		.type = HDA_FIXUP_PINS,
4258		.v.pins = (const struct hda_pintbl[]) {
4259			{ 0x12, 0x99a3092f }, /* int-mic */
4260			{ 0x14, 0x99130110 }, /* speaker */
4261			{ 0x15, 0x0121401f }, /* HP out */
4262			{ 0x18, 0x01a19c20 }, /* mic */
4263			{ }
4264		},
4265	},
4266	[ALC269VB_FIXUP_AMIC] = {
4267		.type = HDA_FIXUP_PINS,
4268		.v.pins = (const struct hda_pintbl[]) {
4269			{ 0x14, 0x99130110 }, /* speaker */
4270			{ 0x18, 0x01a19c20 }, /* mic */
4271			{ 0x19, 0x99a3092f }, /* int-mic */
4272			{ 0x21, 0x0121401f }, /* HP out */
4273			{ }
4274		},
4275	},
4276	[ALC269VB_FIXUP_DMIC] = {
4277		.type = HDA_FIXUP_PINS,
4278		.v.pins = (const struct hda_pintbl[]) {
4279			{ 0x12, 0x99a3092f }, /* int-mic */
4280			{ 0x14, 0x99130110 }, /* speaker */
4281			{ 0x18, 0x01a19c20 }, /* mic */
4282			{ 0x21, 0x0121401f }, /* HP out */
4283			{ }
4284		},
4285	},
4286	[ALC269_FIXUP_HP_MUTE_LED] = {
4287		.type = HDA_FIXUP_FUNC,
4288		.v.func = alc269_fixup_hp_mute_led,
4289	},
4290	[ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
4291		.type = HDA_FIXUP_FUNC,
4292		.v.func = alc269_fixup_hp_mute_led_mic1,
4293	},
4294	[ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
4295		.type = HDA_FIXUP_FUNC,
4296		.v.func = alc269_fixup_hp_mute_led_mic2,
4297	},
4298	[ALC269_FIXUP_HP_GPIO_LED] = {
4299		.type = HDA_FIXUP_FUNC,
4300		.v.func = alc269_fixup_hp_gpio_led,
4301	},
4302	[ALC269_FIXUP_INV_DMIC] = {
4303		.type = HDA_FIXUP_FUNC,
4304		.v.func = alc_fixup_inv_dmic_0x12,
4305	},
4306	[ALC269_FIXUP_NO_SHUTUP] = {
4307		.type = HDA_FIXUP_FUNC,
4308		.v.func = alc_fixup_no_shutup,
4309	},
4310	[ALC269_FIXUP_LENOVO_DOCK] = {
4311		.type = HDA_FIXUP_PINS,
4312		.v.pins = (const struct hda_pintbl[]) {
4313			{ 0x19, 0x23a11040 }, /* dock mic */
4314			{ 0x1b, 0x2121103f }, /* dock headphone */
4315			{ }
4316		},
4317		.chained = true,
4318		.chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
4319	},
4320	[ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
4321		.type = HDA_FIXUP_FUNC,
4322		.v.func = alc269_fixup_pincfg_no_hp_to_lineout,
4323		.chained = true,
4324		.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
4325	},
4326	[ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4327		.type = HDA_FIXUP_PINS,
4328		.v.pins = (const struct hda_pintbl[]) {
4329			{ 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4330			{ 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4331			{ }
4332		},
4333		.chained = true,
4334		.chain_id = ALC269_FIXUP_HEADSET_MODE
4335	},
4336	[ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
4337		.type = HDA_FIXUP_PINS,
4338		.v.pins = (const struct hda_pintbl[]) {
4339			{ 0x16, 0x21014020 }, /* dock line out */
4340			{ 0x19, 0x21a19030 }, /* dock mic */
4341			{ 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4342			{ }
4343		},
4344		.chained = true,
4345		.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4346	},
4347	[ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
4348		.type = HDA_FIXUP_PINS,
4349		.v.pins = (const struct hda_pintbl[]) {
4350			{ 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4351			{ }
4352		},
4353		.chained = true,
4354		.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4355	},
4356	[ALC269_FIXUP_HEADSET_MODE] = {
4357		.type = HDA_FIXUP_FUNC,
4358		.v.func = alc_fixup_headset_mode,
4359	},
4360	[ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
4361		.type = HDA_FIXUP_FUNC,
4362		.v.func = alc_fixup_headset_mode_no_hp_mic,
4363	},
4364	[ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
4365		.type = HDA_FIXUP_PINS,
4366		.v.pins = (const struct hda_pintbl[]) {
4367			{ 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4368			{ }
4369		},
4370		.chained = true,
4371		.chain_id = ALC269_FIXUP_HEADSET_MIC
4372	},
4373	[ALC269_FIXUP_ASUS_X101_FUNC] = {
4374		.type = HDA_FIXUP_FUNC,
4375		.v.func = alc269_fixup_x101_headset_mic,
4376	},
4377	[ALC269_FIXUP_ASUS_X101_VERB] = {
4378		.type = HDA_FIXUP_VERBS,
4379		.v.verbs = (const struct hda_verb[]) {
4380			{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4381			{0x20, AC_VERB_SET_COEF_INDEX, 0x08},
4382			{0x20, AC_VERB_SET_PROC_COEF,  0x0310},
4383			{ }
4384		},
4385		.chained = true,
4386		.chain_id = ALC269_FIXUP_ASUS_X101_FUNC
4387	},
4388	[ALC269_FIXUP_ASUS_X101] = {
4389		.type = HDA_FIXUP_PINS,
4390		.v.pins = (const struct hda_pintbl[]) {
4391			{ 0x18, 0x04a1182c }, /* Headset mic */
4392			{ }
4393		},
4394		.chained = true,
4395		.chain_id = ALC269_FIXUP_ASUS_X101_VERB
4396	},
4397	[ALC271_FIXUP_AMIC_MIC2] = {
4398		.type = HDA_FIXUP_PINS,
4399		.v.pins = (const struct hda_pintbl[]) {
4400			{ 0x14, 0x99130110 }, /* speaker */
4401			{ 0x19, 0x01a19c20 }, /* mic */
4402			{ 0x1b, 0x99a7012f }, /* int-mic */
4403			{ 0x21, 0x0121401f }, /* HP out */
4404			{ }
4405		},
4406	},
4407	[ALC271_FIXUP_HP_GATE_MIC_JACK] = {
4408		.type = HDA_FIXUP_FUNC,
4409		.v.func = alc271_hp_gate_mic_jack,
4410		.chained = true,
4411		.chain_id = ALC271_FIXUP_AMIC_MIC2,
4412	},
4413	[ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
4414		.type = HDA_FIXUP_FUNC,
4415		.v.func = alc269_fixup_limit_int_mic_boost,
4416		.chained = true,
4417		.chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
4418	},
4419	[ALC269_FIXUP_ACER_AC700] = {
4420		.type = HDA_FIXUP_PINS,
4421		.v.pins = (const struct hda_pintbl[]) {
4422			{ 0x12, 0x99a3092f }, /* int-mic */
4423			{ 0x14, 0x99130110 }, /* speaker */
4424			{ 0x18, 0x03a11c20 }, /* mic */
4425			{ 0x1e, 0x0346101e }, /* SPDIF1 */
4426			{ 0x21, 0x0321101f }, /* HP out */
4427			{ }
4428		},
4429		.chained = true,
4430		.chain_id = ALC271_FIXUP_DMIC,
4431	},
4432	[ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
4433		.type = HDA_FIXUP_FUNC,
4434		.v.func = alc269_fixup_limit_int_mic_boost,
4435		.chained = true,
4436		.chain_id = ALC269_FIXUP_THINKPAD_ACPI,
4437	},
4438	[ALC269VB_FIXUP_ASUS_ZENBOOK] = {
4439		.type = HDA_FIXUP_FUNC,
4440		.v.func = alc269_fixup_limit_int_mic_boost,
4441		.chained = true,
4442		.chain_id = ALC269VB_FIXUP_DMIC,
4443	},
4444	[ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
4445		.type = HDA_FIXUP_VERBS,
4446		.v.verbs = (const struct hda_verb[]) {
4447			/* class-D output amp +5dB */
4448			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
4449			{ 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
4450			{}
4451		},
4452		.chained = true,
4453		.chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
4454	},
4455	[ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
4456		.type = HDA_FIXUP_FUNC,
4457		.v.func = alc269_fixup_limit_int_mic_boost,
4458		.chained = true,
4459		.chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
4460	},
4461	[ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
4462		.type = HDA_FIXUP_PINS,
4463		.v.pins = (const struct hda_pintbl[]) {
4464			{ 0x12, 0x99a3092f }, /* int-mic */
4465			{ 0x18, 0x03a11d20 }, /* mic */
4466			{ 0x19, 0x411111f0 }, /* Unused bogus pin */
4467			{ }
4468		},
4469	},
4470	[ALC283_FIXUP_CHROME_BOOK] = {
4471		.type = HDA_FIXUP_FUNC,
4472		.v.func = alc283_fixup_chromebook,
4473	},
4474	[ALC283_FIXUP_SENSE_COMBO_JACK] = {
4475		.type = HDA_FIXUP_FUNC,
4476		.v.func = alc283_fixup_sense_combo_jack,
4477		.chained = true,
4478		.chain_id = ALC283_FIXUP_CHROME_BOOK,
4479	},
4480	[ALC282_FIXUP_ASUS_TX300] = {
4481		.type = HDA_FIXUP_FUNC,
4482		.v.func = alc282_fixup_asus_tx300,
4483	},
4484	[ALC283_FIXUP_INT_MIC] = {
4485		.type = HDA_FIXUP_VERBS,
4486		.v.verbs = (const struct hda_verb[]) {
4487			{0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
4488			{0x20, AC_VERB_SET_PROC_COEF, 0x0011},
4489			{ }
4490		},
4491		.chained = true,
4492		.chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
4493	},
4494	[ALC290_FIXUP_SUBWOOFER_HSJACK] = {
4495		.type = HDA_FIXUP_PINS,
4496		.v.pins = (const struct hda_pintbl[]) {
4497			{ 0x17, 0x90170112 }, /* subwoofer */
4498			{ }
4499		},
4500		.chained = true,
4501		.chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4502	},
4503	[ALC290_FIXUP_SUBWOOFER] = {
4504		.type = HDA_FIXUP_PINS,
4505		.v.pins = (const struct hda_pintbl[]) {
4506			{ 0x17, 0x90170112 }, /* subwoofer */
4507			{ }
4508		},
4509		.chained = true,
4510		.chain_id = ALC290_FIXUP_MONO_SPEAKERS,
4511	},
4512	[ALC290_FIXUP_MONO_SPEAKERS] = {
4513		.type = HDA_FIXUP_FUNC,
4514		.v.func = alc290_fixup_mono_speakers,
4515	},
4516	[ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
4517		.type = HDA_FIXUP_FUNC,
4518		.v.func = alc290_fixup_mono_speakers,
4519		.chained = true,
4520		.chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
4521	},
4522	[ALC269_FIXUP_THINKPAD_ACPI] = {
4523		.type = HDA_FIXUP_FUNC,
4524		.v.func = hda_fixup_thinkpad_acpi,
4525	},
4526	[ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4527		.type = HDA_FIXUP_PINS,
4528		.v.pins = (const struct hda_pintbl[]) {
4529			{ 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4530			{ 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4531			{ }
4532		},
4533		.chained = true,
4534		.chain_id = ALC255_FIXUP_HEADSET_MODE
4535	},
4536	[ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
4537		.type = HDA_FIXUP_PINS,
4538		.v.pins = (const struct hda_pintbl[]) {
4539			{ 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4540			{ }
4541		},
4542		.chained = true,
4543		.chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
4544	},
4545	[ALC255_FIXUP_HEADSET_MODE] = {
4546		.type = HDA_FIXUP_FUNC,
4547		.v.func = alc_fixup_headset_mode_alc255,
4548	},
4549	[ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
4550		.type = HDA_FIXUP_FUNC,
4551		.v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
4552	},
4553};
4554
4555static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4556	SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
4557	SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
4558	SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
4559	SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
4560	SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
4561	SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
4562	SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
4563	SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
4564	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
4565	SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4566	SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4567	SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4568	SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4569	SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4570	SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4571	SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4572	SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4573	SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4574	SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4575	SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4576	SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4577	SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
4578	SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4579	SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4580	SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4581	SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4582	SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4583	SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4584	SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4585	SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4586	SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4587	SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4588	SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4589	SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4590	SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4591	SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4592	SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4593	SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4594	SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4595	SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4596	SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE),
4597	SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE),
4598	SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4599	SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4600	SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
4601	SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
4602	SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4603	SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4604	SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4605	SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4606	SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4607	SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
4608	SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4609	SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4610	SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4611	SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4612	SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4613	SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4614	SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4615	SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4616	SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4617	SND_PCI_QUIRK(0x1028, 0x065c, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4618	SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4619	SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4620	SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
4621	SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
4622	SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
4623	SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4624	SND_PCI_QUIRK(0x1028, 0x067e, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4625	SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4626	SND_PCI_QUIRK(0x1028, 0x0680, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
4627	SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4628	SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4629	SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
4630	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
4631	SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
4632	SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4633	SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4634	SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
4635	/* ALC282 */
4636	SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4637	SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4638	SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4639	SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4640	SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4641	SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4642	SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4643	SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4644	SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4645	SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4646	SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4647	SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4648	SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4649	SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4650	SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4651	SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4652	SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4653	SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4654	SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4655	SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4656	SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4657	SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4658	/* ALC290 */
4659	SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4660	SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4661	SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4662	SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4663	SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4664	SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4665	SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4666	SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4667	SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4668	SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4669	SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4670	SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4671	SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4672	SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4673	SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4674	SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4675	SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4676	SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4677	SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4678	SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4679	SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4680	SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4681	SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4682	SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
4683	SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
4684	SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
4685	SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4686	SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4687	SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
4688	SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
4689	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
4690	SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
4691	SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
4692	SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4693	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
4694	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
4695	SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
4696	SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
4697	SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
4698	SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
4699	SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
4700	SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
4701	SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
4702	SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
4703	SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
 
 
4704	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
4705	SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
4706	SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
4707	SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
4708	SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
4709	SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
4710	SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
4711	SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
4712	SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
4713	SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
4714	SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
4715	SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
4716	SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4717	SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4718	SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4719	SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4720	SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
4721	SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4722	SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
4723	SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4724	SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
4725	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
4726	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
4727	SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
4728	SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
4729
4730#if 0
4731	/* Below is a quirk table taken from the old code.
4732	 * Basically the device should work as is without the fixup table.
4733	 * If BIOS doesn't give a proper info, enable the corresponding
4734	 * fixup entry.
4735	 */
4736	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
4737		      ALC269_FIXUP_AMIC),
4738	SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
4739	SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
4740	SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
4741	SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
4742	SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
4743	SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
4744	SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
4745	SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
4746	SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
4747	SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
4748	SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
4749	SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
4750	SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
4751	SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
4752	SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
4753	SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
4754	SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
4755	SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
4756	SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
4757	SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
4758	SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
4759	SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
4760	SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
4761	SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
4762	SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
4763	SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
4764	SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
4765	SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
4766	SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
4767	SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
4768	SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
4769	SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
4770	SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
4771	SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
4772	SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
4773	SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
4774	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
4775	SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
4776	SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
4777#endif
4778	{}
4779};
4780
4781static const struct hda_model_fixup alc269_fixup_models[] = {
4782	{.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
4783	{.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
4784	{.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
4785	{.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
4786	{.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
4787	{.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
4788	{.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
4789	{.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
4790	{.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
4791	{.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
4792	{.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
4793	{.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
4794	{}
4795};
4796
4797
4798static void alc269_fill_coef(struct hda_codec *codec)
4799{
4800	struct alc_spec *spec = codec->spec;
4801	int val;
4802
4803	if (spec->codec_variant != ALC269_TYPE_ALC269VB)
4804		return;
4805
4806	if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
4807		alc_write_coef_idx(codec, 0xf, 0x960b);
4808		alc_write_coef_idx(codec, 0xe, 0x8817);
4809	}
4810
4811	if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
4812		alc_write_coef_idx(codec, 0xf, 0x960b);
4813		alc_write_coef_idx(codec, 0xe, 0x8814);
4814	}
4815
4816	if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
4817		val = alc_read_coef_idx(codec, 0x04);
4818		/* Power up output pin */
4819		alc_write_coef_idx(codec, 0x04, val | (1<<11));
4820	}
4821
4822	if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
4823		val = alc_read_coef_idx(codec, 0xd);
4824		if ((val & 0x0c00) >> 10 != 0x1) {
4825			/* Capless ramp up clock control */
4826			alc_write_coef_idx(codec, 0xd, val | (1<<10));
4827		}
4828		val = alc_read_coef_idx(codec, 0x17);
4829		if ((val & 0x01c0) >> 6 != 0x4) {
4830			/* Class D power on reset */
4831			alc_write_coef_idx(codec, 0x17, val | (1<<7));
4832		}
4833	}
4834
4835	val = alc_read_coef_idx(codec, 0xd); /* Class D */
4836	alc_write_coef_idx(codec, 0xd, val | (1<<14));
4837
4838	val = alc_read_coef_idx(codec, 0x4); /* HP */
4839	alc_write_coef_idx(codec, 0x4, val | (1<<11));
4840}
4841
4842/*
4843 */
4844static int patch_alc269(struct hda_codec *codec)
4845{
4846	struct alc_spec *spec;
4847	int err;
4848
4849	err = alc_alloc_spec(codec, 0x0b);
4850	if (err < 0)
4851		return err;
4852
4853	spec = codec->spec;
4854	spec->gen.shared_mic_vref_pin = 0x18;
4855
4856	snd_hda_pick_fixup(codec, alc269_fixup_models,
4857		       alc269_fixup_tbl, alc269_fixups);
4858	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
4859
4860	alc_auto_parse_customize_define(codec);
4861
4862	if (has_cdefine_beep(codec))
4863		spec->gen.beep_nid = 0x01;
4864
4865	switch (codec->vendor_id) {
4866	case 0x10ec0269:
4867		spec->codec_variant = ALC269_TYPE_ALC269VA;
4868		switch (alc_get_coef0(codec) & 0x00f0) {
4869		case 0x0010:
4870			if (codec->bus->pci &&
4871			    codec->bus->pci->subsystem_vendor == 0x1025 &&
4872			    spec->cdefine.platform_type == 1)
4873				err = alc_codec_rename(codec, "ALC271X");
4874			spec->codec_variant = ALC269_TYPE_ALC269VB;
4875			break;
4876		case 0x0020:
4877			if (codec->bus->pci &&
4878			    codec->bus->pci->subsystem_vendor == 0x17aa &&
4879			    codec->bus->pci->subsystem_device == 0x21f3)
4880				err = alc_codec_rename(codec, "ALC3202");
4881			spec->codec_variant = ALC269_TYPE_ALC269VC;
4882			break;
4883		case 0x0030:
4884			spec->codec_variant = ALC269_TYPE_ALC269VD;
4885			break;
4886		default:
4887			alc_fix_pll_init(codec, 0x20, 0x04, 15);
4888		}
4889		if (err < 0)
4890			goto error;
4891		spec->init_hook = alc269_fill_coef;
4892		alc269_fill_coef(codec);
4893		break;
4894
4895	case 0x10ec0280:
4896	case 0x10ec0290:
4897		spec->codec_variant = ALC269_TYPE_ALC280;
4898		break;
4899	case 0x10ec0282:
4900		spec->codec_variant = ALC269_TYPE_ALC282;
4901		spec->shutup = alc282_shutup;
4902		spec->init_hook = alc282_init;
4903		break;
4904	case 0x10ec0233:
4905	case 0x10ec0283:
4906		spec->codec_variant = ALC269_TYPE_ALC283;
4907		spec->shutup = alc283_shutup;
4908		spec->init_hook = alc283_init;
4909		break;
4910	case 0x10ec0284:
4911	case 0x10ec0292:
4912		spec->codec_variant = ALC269_TYPE_ALC284;
4913		break;
4914	case 0x10ec0285:
4915	case 0x10ec0293:
4916		spec->codec_variant = ALC269_TYPE_ALC285;
4917		break;
4918	case 0x10ec0286:
4919	case 0x10ec0288:
4920		spec->codec_variant = ALC269_TYPE_ALC286;
4921		break;
4922	case 0x10ec0255:
4923		spec->codec_variant = ALC269_TYPE_ALC255;
4924		break;
4925	}
4926
4927	if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
4928		spec->has_alc5505_dsp = 1;
4929		spec->init_hook = alc5505_dsp_init;
4930	}
 
4931
4932	/* automatic parse from the BIOS config */
4933	err = alc269_parse_auto_config(codec);
4934	if (err < 0)
4935		goto error;
4936
4937	if (!spec->gen.no_analog && spec->gen.beep_nid)
 
 
 
4938		set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
 
4939
4940	codec->patch_ops = alc_patch_ops;
4941#ifdef CONFIG_PM
4942	codec->patch_ops.suspend = alc269_suspend;
4943	codec->patch_ops.resume = alc269_resume;
4944#endif
4945	if (!spec->shutup)
4946		spec->shutup = alc269_shutup;
4947
4948	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
4949
4950	return 0;
4951
4952 error:
4953	alc_free(codec);
4954	return err;
4955}
4956
4957/*
4958 * ALC861
4959 */
4960
4961static int alc861_parse_auto_config(struct hda_codec *codec)
4962{
4963	static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
4964	static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
4965	return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
4966}
4967
4968/* Pin config fixes */
4969enum {
4970	ALC861_FIXUP_FSC_AMILO_PI1505,
4971	ALC861_FIXUP_AMP_VREF_0F,
4972	ALC861_FIXUP_NO_JACK_DETECT,
4973	ALC861_FIXUP_ASUS_A6RP,
4974	ALC660_FIXUP_ASUS_W7J,
4975};
4976
4977/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
4978static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
4979			const struct hda_fixup *fix, int action)
4980{
4981	struct alc_spec *spec = codec->spec;
4982	unsigned int val;
4983
4984	if (action != HDA_FIXUP_ACT_INIT)
4985		return;
4986	val = snd_hda_codec_get_pin_target(codec, 0x0f);
 
4987	if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
4988		val |= AC_PINCTL_IN_EN;
4989	val |= AC_PINCTL_VREF_50;
4990	snd_hda_set_pin_ctl(codec, 0x0f, val);
4991	spec->gen.keep_vref_in_automute = 1;
4992}
4993
4994/* suppress the jack-detection */
4995static void alc_fixup_no_jack_detect(struct hda_codec *codec,
4996				     const struct hda_fixup *fix, int action)
4997{
4998	if (action == HDA_FIXUP_ACT_PRE_PROBE)
4999		codec->no_jack_detect = 1;
5000}
5001
5002static const struct hda_fixup alc861_fixups[] = {
5003	[ALC861_FIXUP_FSC_AMILO_PI1505] = {
5004		.type = HDA_FIXUP_PINS,
5005		.v.pins = (const struct hda_pintbl[]) {
5006			{ 0x0b, 0x0221101f }, /* HP */
5007			{ 0x0f, 0x90170310 }, /* speaker */
5008			{ }
5009		}
5010	},
5011	[ALC861_FIXUP_AMP_VREF_0F] = {
5012		.type = HDA_FIXUP_FUNC,
5013		.v.func = alc861_fixup_asus_amp_vref_0f,
5014	},
5015	[ALC861_FIXUP_NO_JACK_DETECT] = {
5016		.type = HDA_FIXUP_FUNC,
5017		.v.func = alc_fixup_no_jack_detect,
5018	},
5019	[ALC861_FIXUP_ASUS_A6RP] = {
5020		.type = HDA_FIXUP_FUNC,
5021		.v.func = alc861_fixup_asus_amp_vref_0f,
5022		.chained = true,
5023		.chain_id = ALC861_FIXUP_NO_JACK_DETECT,
5024	},
5025	[ALC660_FIXUP_ASUS_W7J] = {
5026		.type = HDA_FIXUP_VERBS,
5027		.v.verbs = (const struct hda_verb[]) {
5028			/* ASUS W7J needs a magic pin setup on unused NID 0x10
5029			 * for enabling outputs
5030			 */
5031			{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5032			{ }
5033		},
5034	}
5035};
5036
5037static const struct snd_pci_quirk alc861_fixup_tbl[] = {
5038	SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
5039	SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
5040	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
5041	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
5042	SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
5043	SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
5044	SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
5045	SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
5046	{}
5047};
5048
5049/*
5050 */
5051static int patch_alc861(struct hda_codec *codec)
5052{
5053	struct alc_spec *spec;
5054	int err;
5055
5056	err = alc_alloc_spec(codec, 0x15);
5057	if (err < 0)
5058		return err;
5059
5060	spec = codec->spec;
5061	spec->gen.beep_nid = 0x23;
5062
5063	snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
5064	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5065
5066	/* automatic parse from the BIOS config */
5067	err = alc861_parse_auto_config(codec);
5068	if (err < 0)
5069		goto error;
5070
5071	if (!spec->gen.no_analog)
 
 
 
5072		set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
 
5073
5074	codec->patch_ops = alc_patch_ops;
5075#ifdef CONFIG_PM
5076	spec->power_hook = alc_power_eapd;
5077#endif
5078
5079	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5080
5081	return 0;
5082
5083 error:
5084	alc_free(codec);
5085	return err;
5086}
5087
5088/*
5089 * ALC861-VD support
5090 *
5091 * Based on ALC882
5092 *
5093 * In addition, an independent DAC
5094 */
5095static int alc861vd_parse_auto_config(struct hda_codec *codec)
5096{
5097	static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
5098	static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5099	return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
5100}
5101
5102enum {
5103	ALC660VD_FIX_ASUS_GPIO1,
5104	ALC861VD_FIX_DALLAS,
5105};
5106
5107/* exclude VREF80 */
5108static void alc861vd_fixup_dallas(struct hda_codec *codec,
5109				  const struct hda_fixup *fix, int action)
5110{
5111	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5112		snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
5113		snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
5114	}
5115}
5116
5117static const struct hda_fixup alc861vd_fixups[] = {
5118	[ALC660VD_FIX_ASUS_GPIO1] = {
5119		.type = HDA_FIXUP_VERBS,
5120		.v.verbs = (const struct hda_verb[]) {
5121			/* reset GPIO1 */
5122			{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5123			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5124			{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5125			{ }
5126		}
5127	},
5128	[ALC861VD_FIX_DALLAS] = {
5129		.type = HDA_FIXUP_FUNC,
5130		.v.func = alc861vd_fixup_dallas,
5131	},
5132};
5133
5134static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
5135	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
5136	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
5137	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
5138	{}
5139};
5140
 
 
 
 
 
 
5141/*
5142 */
5143static int patch_alc861vd(struct hda_codec *codec)
5144{
5145	struct alc_spec *spec;
5146	int err;
5147
5148	err = alc_alloc_spec(codec, 0x0b);
5149	if (err < 0)
5150		return err;
5151
5152	spec = codec->spec;
5153	spec->gen.beep_nid = 0x23;
5154
5155	snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
5156	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5157
5158	/* automatic parse from the BIOS config */
5159	err = alc861vd_parse_auto_config(codec);
5160	if (err < 0)
5161		goto error;
5162
5163	if (!spec->gen.no_analog)
 
 
 
 
 
 
 
 
5164		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 
5165
5166	codec->patch_ops = alc_patch_ops;
5167
5168	spec->shutup = alc_eapd_shutup;
5169
5170	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5171
5172	return 0;
5173
5174 error:
5175	alc_free(codec);
5176	return err;
5177}
5178
5179/*
5180 * ALC662 support
5181 *
5182 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
5183 * configuration.  Each pin widget can choose any input DACs and a mixer.
5184 * Each ADC is connected from a mixer of all inputs.  This makes possible
5185 * 6-channel independent captures.
5186 *
5187 * In addition, an independent DAC for the multi-playback (not used in this
5188 * driver yet).
5189 */
5190
5191/*
5192 * BIOS auto configuration
5193 */
5194
5195static int alc662_parse_auto_config(struct hda_codec *codec)
5196{
5197	static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
5198	static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
5199	static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5200	const hda_nid_t *ssids;
5201
5202	if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
5203	    codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 ||
5204	    codec->vendor_id == 0x10ec0671)
5205		ssids = alc663_ssids;
5206	else
5207		ssids = alc662_ssids;
5208	return alc_parse_auto_config(codec, alc662_ignore, ssids);
5209}
5210
5211static void alc272_fixup_mario(struct hda_codec *codec,
5212			       const struct hda_fixup *fix, int action)
5213{
5214	if (action != HDA_FIXUP_ACT_PRE_PROBE)
5215		return;
5216	if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
5217				      (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
5218				      (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
5219				      (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
5220				      (0 << AC_AMPCAP_MUTE_SHIFT)))
5221		codec_warn(codec, "failed to override amp caps for NID 0x2\n");
5222}
5223
5224static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
5225	{ .channels = 2,
5226	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
5227	{ .channels = 4,
5228	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
5229		   SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
5230	{ }
5231};
5232
5233/* override the 2.1 chmap */
5234static void alc_fixup_bass_chmap(struct hda_codec *codec,
5235				    const struct hda_fixup *fix, int action)
5236{
5237	if (action == HDA_FIXUP_ACT_BUILD) {
5238		struct alc_spec *spec = codec->spec;
5239		spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps;
5240	}
5241}
5242
5243/* turn on/off mute LED per vmaster hook */
5244static void alc662_led_gpio1_mute_hook(void *private_data, int enabled)
5245{
5246	struct hda_codec *codec = private_data;
5247	struct alc_spec *spec = codec->spec;
5248	unsigned int oldval = spec->gpio_led;
5249
5250	if (enabled)
5251		spec->gpio_led &= ~0x01;
5252	else
5253		spec->gpio_led |= 0x01;
5254	if (spec->gpio_led != oldval)
5255		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
5256				    spec->gpio_led);
5257}
5258
5259/* avoid D3 for keeping GPIO up */
5260static unsigned int gpio_led_power_filter(struct hda_codec *codec,
5261					  hda_nid_t nid,
5262					  unsigned int power_state)
5263{
5264	struct alc_spec *spec = codec->spec;
5265	if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led)
5266		return AC_PWRST_D0;
5267	return power_state;
5268}
5269
5270static void alc662_fixup_led_gpio1(struct hda_codec *codec,
5271				   const struct hda_fixup *fix, int action)
5272{
5273	struct alc_spec *spec = codec->spec;
5274	static const struct hda_verb gpio_init[] = {
5275		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
5276		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
5277		{}
5278	};
5279
5280	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5281		spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook;
5282		spec->gpio_led = 0;
5283		snd_hda_add_verbs(codec, gpio_init);
5284		codec->power_filter = gpio_led_power_filter;
5285	}
5286}
5287
5288enum {
5289	ALC662_FIXUP_ASPIRE,
5290	ALC662_FIXUP_LED_GPIO1,
5291	ALC662_FIXUP_IDEAPAD,
5292	ALC272_FIXUP_MARIO,
5293	ALC662_FIXUP_CZC_P10T,
5294	ALC662_FIXUP_SKU_IGNORE,
5295	ALC662_FIXUP_HP_RP5800,
5296	ALC662_FIXUP_ASUS_MODE1,
5297	ALC662_FIXUP_ASUS_MODE2,
5298	ALC662_FIXUP_ASUS_MODE3,
5299	ALC662_FIXUP_ASUS_MODE4,
5300	ALC662_FIXUP_ASUS_MODE5,
5301	ALC662_FIXUP_ASUS_MODE6,
5302	ALC662_FIXUP_ASUS_MODE7,
5303	ALC662_FIXUP_ASUS_MODE8,
5304	ALC662_FIXUP_NO_JACK_DETECT,
5305	ALC662_FIXUP_ZOTAC_Z68,
5306	ALC662_FIXUP_INV_DMIC,
5307	ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
5308	ALC668_FIXUP_HEADSET_MODE,
5309	ALC662_FIXUP_BASS_MODE4_CHMAP,
5310	ALC662_FIXUP_BASS_16,
5311	ALC662_FIXUP_BASS_1A,
5312	ALC662_FIXUP_BASS_CHMAP,
5313	ALC668_FIXUP_AUTO_MUTE,
5314};
5315
5316static const struct hda_fixup alc662_fixups[] = {
5317	[ALC662_FIXUP_ASPIRE] = {
5318		.type = HDA_FIXUP_PINS,
5319		.v.pins = (const struct hda_pintbl[]) {
5320			{ 0x15, 0x99130112 }, /* subwoofer */
5321			{ }
5322		}
5323	},
5324	[ALC662_FIXUP_LED_GPIO1] = {
5325		.type = HDA_FIXUP_FUNC,
5326		.v.func = alc662_fixup_led_gpio1,
5327	},
5328	[ALC662_FIXUP_IDEAPAD] = {
5329		.type = HDA_FIXUP_PINS,
5330		.v.pins = (const struct hda_pintbl[]) {
5331			{ 0x17, 0x99130112 }, /* subwoofer */
5332			{ }
5333		},
5334		.chained = true,
5335		.chain_id = ALC662_FIXUP_LED_GPIO1,
5336	},
5337	[ALC272_FIXUP_MARIO] = {
5338		.type = HDA_FIXUP_FUNC,
5339		.v.func = alc272_fixup_mario,
5340	},
5341	[ALC662_FIXUP_CZC_P10T] = {
5342		.type = HDA_FIXUP_VERBS,
5343		.v.verbs = (const struct hda_verb[]) {
5344			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5345			{}
5346		}
5347	},
5348	[ALC662_FIXUP_SKU_IGNORE] = {
5349		.type = HDA_FIXUP_FUNC,
5350		.v.func = alc_fixup_sku_ignore,
5351	},
5352	[ALC662_FIXUP_HP_RP5800] = {
5353		.type = HDA_FIXUP_PINS,
5354		.v.pins = (const struct hda_pintbl[]) {
5355			{ 0x14, 0x0221201f }, /* HP out */
5356			{ }
5357		},
5358		.chained = true,
5359		.chain_id = ALC662_FIXUP_SKU_IGNORE
5360	},
5361	[ALC662_FIXUP_ASUS_MODE1] = {
5362		.type = HDA_FIXUP_PINS,
5363		.v.pins = (const struct hda_pintbl[]) {
5364			{ 0x14, 0x99130110 }, /* speaker */
5365			{ 0x18, 0x01a19c20 }, /* mic */
5366			{ 0x19, 0x99a3092f }, /* int-mic */
5367			{ 0x21, 0x0121401f }, /* HP out */
5368			{ }
5369		},
5370		.chained = true,
5371		.chain_id = ALC662_FIXUP_SKU_IGNORE
5372	},
5373	[ALC662_FIXUP_ASUS_MODE2] = {
5374		.type = HDA_FIXUP_PINS,
5375		.v.pins = (const struct hda_pintbl[]) {
5376			{ 0x14, 0x99130110 }, /* speaker */
5377			{ 0x18, 0x01a19820 }, /* mic */
5378			{ 0x19, 0x99a3092f }, /* int-mic */
5379			{ 0x1b, 0x0121401f }, /* HP out */
5380			{ }
5381		},
5382		.chained = true,
5383		.chain_id = ALC662_FIXUP_SKU_IGNORE
5384	},
5385	[ALC662_FIXUP_ASUS_MODE3] = {
5386		.type = HDA_FIXUP_PINS,
5387		.v.pins = (const struct hda_pintbl[]) {
5388			{ 0x14, 0x99130110 }, /* speaker */
5389			{ 0x15, 0x0121441f }, /* HP */
5390			{ 0x18, 0x01a19840 }, /* mic */
5391			{ 0x19, 0x99a3094f }, /* int-mic */
5392			{ 0x21, 0x01211420 }, /* HP2 */
5393			{ }
5394		},
5395		.chained = true,
5396		.chain_id = ALC662_FIXUP_SKU_IGNORE
5397	},
5398	[ALC662_FIXUP_ASUS_MODE4] = {
5399		.type = HDA_FIXUP_PINS,
5400		.v.pins = (const struct hda_pintbl[]) {
5401			{ 0x14, 0x99130110 }, /* speaker */
5402			{ 0x16, 0x99130111 }, /* speaker */
5403			{ 0x18, 0x01a19840 }, /* mic */
5404			{ 0x19, 0x99a3094f }, /* int-mic */
5405			{ 0x21, 0x0121441f }, /* HP */
5406			{ }
5407		},
5408		.chained = true,
5409		.chain_id = ALC662_FIXUP_SKU_IGNORE
5410	},
5411	[ALC662_FIXUP_ASUS_MODE5] = {
5412		.type = HDA_FIXUP_PINS,
5413		.v.pins = (const struct hda_pintbl[]) {
5414			{ 0x14, 0x99130110 }, /* speaker */
5415			{ 0x15, 0x0121441f }, /* HP */
5416			{ 0x16, 0x99130111 }, /* speaker */
5417			{ 0x18, 0x01a19840 }, /* mic */
5418			{ 0x19, 0x99a3094f }, /* int-mic */
5419			{ }
5420		},
5421		.chained = true,
5422		.chain_id = ALC662_FIXUP_SKU_IGNORE
5423	},
5424	[ALC662_FIXUP_ASUS_MODE6] = {
5425		.type = HDA_FIXUP_PINS,
5426		.v.pins = (const struct hda_pintbl[]) {
5427			{ 0x14, 0x99130110 }, /* speaker */
5428			{ 0x15, 0x01211420 }, /* HP2 */
5429			{ 0x18, 0x01a19840 }, /* mic */
5430			{ 0x19, 0x99a3094f }, /* int-mic */
5431			{ 0x1b, 0x0121441f }, /* HP */
5432			{ }
5433		},
5434		.chained = true,
5435		.chain_id = ALC662_FIXUP_SKU_IGNORE
5436	},
5437	[ALC662_FIXUP_ASUS_MODE7] = {
5438		.type = HDA_FIXUP_PINS,
5439		.v.pins = (const struct hda_pintbl[]) {
5440			{ 0x14, 0x99130110 }, /* speaker */
5441			{ 0x17, 0x99130111 }, /* speaker */
5442			{ 0x18, 0x01a19840 }, /* mic */
5443			{ 0x19, 0x99a3094f }, /* int-mic */
5444			{ 0x1b, 0x01214020 }, /* HP */
5445			{ 0x21, 0x0121401f }, /* HP */
5446			{ }
5447		},
5448		.chained = true,
5449		.chain_id = ALC662_FIXUP_SKU_IGNORE
5450	},
5451	[ALC662_FIXUP_ASUS_MODE8] = {
5452		.type = HDA_FIXUP_PINS,
5453		.v.pins = (const struct hda_pintbl[]) {
5454			{ 0x14, 0x99130110 }, /* speaker */
5455			{ 0x12, 0x99a30970 }, /* int-mic */
5456			{ 0x15, 0x01214020 }, /* HP */
5457			{ 0x17, 0x99130111 }, /* speaker */
5458			{ 0x18, 0x01a19840 }, /* mic */
5459			{ 0x21, 0x0121401f }, /* HP */
5460			{ }
5461		},
5462		.chained = true,
5463		.chain_id = ALC662_FIXUP_SKU_IGNORE
5464	},
5465	[ALC662_FIXUP_NO_JACK_DETECT] = {
5466		.type = HDA_FIXUP_FUNC,
5467		.v.func = alc_fixup_no_jack_detect,
5468	},
5469	[ALC662_FIXUP_ZOTAC_Z68] = {
5470		.type = HDA_FIXUP_PINS,
5471		.v.pins = (const struct hda_pintbl[]) {
5472			{ 0x1b, 0x02214020 }, /* Front HP */
5473			{ }
5474		}
5475	},
5476	[ALC662_FIXUP_INV_DMIC] = {
5477		.type = HDA_FIXUP_FUNC,
5478		.v.func = alc_fixup_inv_dmic_0x12,
5479	},
5480	[ALC668_FIXUP_AUTO_MUTE] = {
5481		.type = HDA_FIXUP_FUNC,
5482		.v.func = alc_fixup_auto_mute_via_amp,
5483		.chained = true,
5484		.chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
5485	},
5486	[ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
5487		.type = HDA_FIXUP_PINS,
5488		.v.pins = (const struct hda_pintbl[]) {
5489			{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
5490			{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
5491			{ }
5492		},
5493		.chained = true,
5494		.chain_id = ALC668_FIXUP_HEADSET_MODE
5495	},
5496	[ALC668_FIXUP_HEADSET_MODE] = {
5497		.type = HDA_FIXUP_FUNC,
5498		.v.func = alc_fixup_headset_mode_alc668,
5499	},
5500	[ALC662_FIXUP_BASS_MODE4_CHMAP] = {
5501		.type = HDA_FIXUP_FUNC,
5502		.v.func = alc_fixup_bass_chmap,
5503		.chained = true,
5504		.chain_id = ALC662_FIXUP_ASUS_MODE4
5505	},
5506	[ALC662_FIXUP_BASS_16] = {
5507		.type = HDA_FIXUP_PINS,
5508		.v.pins = (const struct hda_pintbl[]) {
5509			{0x16, 0x80106111}, /* bass speaker */
5510			{}
5511		},
5512		.chained = true,
5513		.chain_id = ALC662_FIXUP_BASS_CHMAP,
5514	},
5515	[ALC662_FIXUP_BASS_1A] = {
5516		.type = HDA_FIXUP_PINS,
5517		.v.pins = (const struct hda_pintbl[]) {
5518			{0x1a, 0x80106111}, /* bass speaker */
5519			{}
5520		},
5521		.chained = true,
5522		.chain_id = ALC662_FIXUP_BASS_CHMAP,
5523	},
5524	[ALC662_FIXUP_BASS_CHMAP] = {
5525		.type = HDA_FIXUP_FUNC,
5526		.v.func = alc_fixup_bass_chmap,
5527	},
5528};
5529
5530static const struct snd_pci_quirk alc662_fixup_tbl[] = {
5531	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
5532	SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
5533	SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
5534	SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
5535	SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
5536	SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
5537	SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
5538	SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5539	SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5540	SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5541	SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE),
5542	SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE),
5543	SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5544	SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5545	SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
5546	SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE),
5547	SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5548	SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
5549	SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
5550	SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
5551	SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
5552	SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
5553	SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
5554	SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
5555	SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
5556	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
5557	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
5558	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
5559	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
5560	SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
5561	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
5562
5563#if 0
5564	/* Below is a quirk table taken from the old code.
5565	 * Basically the device should work as is without the fixup table.
5566	 * If BIOS doesn't give a proper info, enable the corresponding
5567	 * fixup entry.
5568	 */
5569	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
5570	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
5571	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
5572	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
5573	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5574	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5575	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5576	SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
5577	SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
5578	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5579	SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
5580	SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
5581	SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
5582	SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
5583	SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
5584	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5585	SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
5586	SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
5587	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5588	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5589	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5590	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5591	SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
5592	SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
5593	SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
5594	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5595	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
5596	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
5597	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5598	SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
5599	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5600	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5601	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
5602	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
5603	SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
5604	SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
5605	SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
5606	SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
5607	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
5608	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
5609	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
5610	SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
5611	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5612	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
5613	SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
5614	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
5615	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
5616	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
5617	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
5618	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
5619#endif
5620	{}
5621};
5622
5623static const struct hda_model_fixup alc662_fixup_models[] = {
5624	{.id = ALC272_FIXUP_MARIO, .name = "mario"},
5625	{.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
5626	{.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
5627	{.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
5628	{.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
5629	{.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
5630	{.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
5631	{.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
5632	{.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
5633	{.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
5634	{.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
5635	{}
5636};
5637
5638static void alc662_fill_coef(struct hda_codec *codec)
5639{
5640	int val, coef;
5641
5642	coef = alc_get_coef0(codec);
5643
5644	switch (codec->vendor_id) {
5645	case 0x10ec0662:
5646		if ((coef & 0x00f0) == 0x0030) {
5647			val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */
5648			alc_write_coef_idx(codec, 0x4, val & ~(1<<10));
5649		}
5650		break;
5651	case 0x10ec0272:
5652	case 0x10ec0273:
5653	case 0x10ec0663:
5654	case 0x10ec0665:
5655	case 0x10ec0670:
5656	case 0x10ec0671:
5657	case 0x10ec0672:
5658		val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */
5659		alc_write_coef_idx(codec, 0xd, val | (1<<14));
5660		break;
5661	}
5662}
5663
5664/*
5665 */
5666static int patch_alc662(struct hda_codec *codec)
5667{
5668	struct alc_spec *spec;
5669	int err;
5670
5671	err = alc_alloc_spec(codec, 0x0b);
5672	if (err < 0)
5673		return err;
5674
5675	spec = codec->spec;
5676
5677	/* handle multiple HPs as is */
5678	spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5679
5680	alc_fix_pll_init(codec, 0x20, 0x04, 15);
5681
5682	spec->init_hook = alc662_fill_coef;
5683	alc662_fill_coef(codec);
5684
5685	snd_hda_pick_fixup(codec, alc662_fixup_models,
5686		       alc662_fixup_tbl, alc662_fixups);
5687	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5688
5689	alc_auto_parse_customize_define(codec);
5690
5691	if (has_cdefine_beep(codec))
5692		spec->gen.beep_nid = 0x01;
5693
5694	if ((alc_get_coef0(codec) & (1 << 14)) &&
5695	    codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
5696	    spec->cdefine.platform_type == 1) {
5697		err = alc_codec_rename(codec, "ALC272X");
5698		if (err < 0)
5699			goto error;
5700	}
5701
5702	/* automatic parse from the BIOS config */
5703	err = alc662_parse_auto_config(codec);
5704	if (err < 0)
5705		goto error;
5706
5707	if (!spec->gen.no_analog && spec->gen.beep_nid) {
 
 
 
5708		switch (codec->vendor_id) {
5709		case 0x10ec0662:
5710			set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5711			break;
5712		case 0x10ec0272:
5713		case 0x10ec0663:
5714		case 0x10ec0665:
5715		case 0x10ec0668:
5716			set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
5717			break;
5718		case 0x10ec0273:
5719			set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
5720			break;
5721		}
5722	}
5723
5724	codec->patch_ops = alc_patch_ops;
5725	spec->shutup = alc_eapd_shutup;
5726
5727	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5728
5729	return 0;
5730
5731 error:
5732	alc_free(codec);
5733	return err;
5734}
5735
5736/*
5737 * ALC680 support
5738 */
5739
5740static int alc680_parse_auto_config(struct hda_codec *codec)
5741{
5742	return alc_parse_auto_config(codec, NULL, NULL);
5743}
5744
5745/*
5746 */
5747static int patch_alc680(struct hda_codec *codec)
5748{
5749	int err;
5750
5751	/* ALC680 has no aa-loopback mixer */
5752	err = alc_alloc_spec(codec, 0);
5753	if (err < 0)
5754		return err;
5755
5756	/* automatic parse from the BIOS config */
5757	err = alc680_parse_auto_config(codec);
5758	if (err < 0) {
5759		alc_free(codec);
5760		return err;
5761	}
5762
5763	codec->patch_ops = alc_patch_ops;
5764
5765	return 0;
5766}
5767
5768/*
5769 * patch entries
5770 */
5771static const struct hda_codec_preset snd_hda_preset_realtek[] = {
5772	{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
5773	{ .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
5774	{ .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
5775	{ .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 },
5776	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
5777	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
5778	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
5779	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
5780	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
5781	{ .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
5782	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
5783	{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
5784	{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
5785	{ .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
5786	{ .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
5787	{ .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
5788	{ .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
5789	{ .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
5790	{ .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
5791	{ .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 },
5792	{ .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
5793	{ .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
5794	{ .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
5795	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
5796	  .patch = patch_alc861 },
5797	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
5798	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
5799	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
5800	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
5801	  .patch = patch_alc882 },
5802	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
5803	  .patch = patch_alc662 },
5804	{ .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
5805	  .patch = patch_alc662 },
5806	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
5807	{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
5808	{ .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
5809	{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
5810	{ .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
5811	{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
5812	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
5813	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
5814	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
5815	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
5816	  .patch = patch_alc882 },
5817	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
5818	  .patch = patch_alc882 },
5819	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
5820	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
5821	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
5822	  .patch = patch_alc882 },
5823	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
5824	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
5825	{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
5826	{ .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
5827	{ .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
5828	{} /* terminator */
5829};
5830
5831MODULE_ALIAS("snd-hda-codec-id:10ec*");
5832
5833MODULE_LICENSE("GPL");
5834MODULE_DESCRIPTION("Realtek HD-audio codec");
5835
5836static struct hda_codec_preset_list realtek_list = {
5837	.preset = snd_hda_preset_realtek,
5838	.owner = THIS_MODULE,
5839};
5840
5841static int __init patch_realtek_init(void)
5842{
5843	return snd_hda_add_codec_preset(&realtek_list);
5844}
5845
5846static void __exit patch_realtek_exit(void)
5847{
5848	snd_hda_delete_codec_preset(&realtek_list);
5849}
5850
5851module_init(patch_realtek_init)
5852module_exit(patch_realtek_exit)
v3.5.6
   1/*
   2 * Universal Interface for Intel High Definition Audio Codec
   3 *
   4 * HD audio interface patch for Realtek ALC codecs
   5 *
   6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
   7 *                    PeiSen Hou <pshou@realtek.com.tw>
   8 *                    Takashi Iwai <tiwai@suse.de>
   9 *                    Jonathan Woithe <jwoithe@just42.net>
  10 *
  11 *  This driver is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License as published by
  13 *  the Free Software Foundation; either version 2 of the License, or
  14 *  (at your option) any later version.
  15 *
  16 *  This driver is distributed in the hope that it will be useful,
  17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 *  GNU General Public License for more details.
  20 *
  21 *  You should have received a copy of the GNU General Public License
  22 *  along with this program; if not, write to the Free Software
  23 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  24 */
  25
  26#include <linux/init.h>
  27#include <linux/delay.h>
  28#include <linux/slab.h>
  29#include <linux/pci.h>
 
  30#include <linux/module.h>
  31#include <sound/core.h>
  32#include <sound/jack.h>
  33#include "hda_codec.h"
  34#include "hda_local.h"
  35#include "hda_auto_parser.h"
  36#include "hda_beep.h"
  37#include "hda_jack.h"
 
 
 
 
  38
  39/* unsol event tags */
  40#define ALC_FRONT_EVENT		0x01
  41#define ALC_DCVOL_EVENT		0x02
  42#define ALC_HP_EVENT		0x04
  43#define ALC_MIC_EVENT		0x08
  44
  45/* for GPIO Poll */
  46#define GPIO_MASK	0x03
  47
  48/* extra amp-initialization sequence types */
  49enum {
  50	ALC_INIT_NONE,
  51	ALC_INIT_DEFAULT,
  52	ALC_INIT_GPIO1,
  53	ALC_INIT_GPIO2,
  54	ALC_INIT_GPIO3,
  55};
  56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  57struct alc_customize_define {
  58	unsigned int  sku_cfg;
  59	unsigned char port_connectivity;
  60	unsigned char check_sum;
  61	unsigned char customization;
  62	unsigned char external_amp;
  63	unsigned int  enable_pcbeep:1;
  64	unsigned int  platform_type:1;
  65	unsigned int  swap:1;
  66	unsigned int  override:1;
  67	unsigned int  fixup:1; /* Means that this sku is set by driver, not read from hw */
  68};
  69
  70struct alc_multi_io {
  71	hda_nid_t pin;		/* multi-io widget pin NID */
  72	hda_nid_t dac;		/* DAC to be connected */
  73	unsigned int ctl_in;	/* cached input-pin control value */
  74};
  75
  76enum {
  77	ALC_AUTOMUTE_PIN,	/* change the pin control */
  78	ALC_AUTOMUTE_AMP,	/* mute/unmute the pin AMP */
  79	ALC_AUTOMUTE_MIXER,	/* mute/unmute mixer widget AMP */
  80};
  81
  82#define MAX_VOL_NIDS	0x40
  83
  84/* make compatible with old code */
  85#define alc_apply_pincfgs	snd_hda_apply_pincfgs
  86#define alc_apply_fixup		snd_hda_apply_fixup
  87#define alc_pick_fixup		snd_hda_pick_fixup
  88#define alc_fixup		hda_fixup
  89#define alc_pincfg		hda_pintbl
  90#define alc_model_fixup		hda_model_fixup
  91
  92#define ALC_FIXUP_PINS	HDA_FIXUP_PINS
  93#define ALC_FIXUP_VERBS	HDA_FIXUP_VERBS
  94#define ALC_FIXUP_FUNC	HDA_FIXUP_FUNC
  95
  96#define ALC_FIXUP_ACT_PRE_PROBE	HDA_FIXUP_ACT_PRE_PROBE
  97#define ALC_FIXUP_ACT_PROBE	HDA_FIXUP_ACT_PROBE
  98#define ALC_FIXUP_ACT_INIT	HDA_FIXUP_ACT_INIT
  99#define ALC_FIXUP_ACT_BUILD	HDA_FIXUP_ACT_BUILD
 100
 101
 102struct alc_spec {
 103	struct hda_gen_spec gen;
 104
 105	/* codec parameterization */
 106	const struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
 107	unsigned int num_mixers;
 108	const struct snd_kcontrol_new *cap_mixer;	/* capture mixer */
 109	unsigned int beep_amp;	/* beep amp value, set via set_beep_amp() */
 110
 111	char stream_name_analog[32];	/* analog PCM stream */
 112	const struct hda_pcm_stream *stream_analog_playback;
 113	const struct hda_pcm_stream *stream_analog_capture;
 114	const struct hda_pcm_stream *stream_analog_alt_playback;
 115	const struct hda_pcm_stream *stream_analog_alt_capture;
 116
 117	char stream_name_digital[32];	/* digital PCM stream */
 118	const struct hda_pcm_stream *stream_digital_playback;
 119	const struct hda_pcm_stream *stream_digital_capture;
 120
 121	/* playback */
 122	struct hda_multi_out multiout;	/* playback set-up
 123					 * max_channels, dacs must be set
 124					 * dig_out_nid and hp_nid are optional
 125					 */
 126	hda_nid_t alt_dac_nid;
 127	hda_nid_t slave_dig_outs[3];	/* optional - for auto-parsing */
 128	int dig_out_type;
 129
 130	/* capture */
 131	unsigned int num_adc_nids;
 132	const hda_nid_t *adc_nids;
 133	const hda_nid_t *capsrc_nids;
 134	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
 135	hda_nid_t mixer_nid;		/* analog-mixer NID */
 136	DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1);
 137	DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1);
 138
 139	/* capture setup for dynamic dual-adc switch */
 140	hda_nid_t cur_adc;
 141	unsigned int cur_adc_stream_tag;
 142	unsigned int cur_adc_format;
 143
 144	/* capture source */
 145	unsigned int num_mux_defs;
 146	const struct hda_input_mux *input_mux;
 147	unsigned int cur_mux[3];
 148	hda_nid_t ext_mic_pin;
 149	hda_nid_t dock_mic_pin;
 150	hda_nid_t int_mic_pin;
 151
 152	/* channel model */
 153	const struct hda_channel_mode *channel_mode;
 154	int num_channel_mode;
 155	int need_dac_fix;
 156	int const_channel_count;
 157	int ext_channel_count;
 158
 159	/* PCM information */
 160	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
 161
 162	/* dynamic controls, init_verbs and input_mux */
 163	struct auto_pin_cfg autocfg;
 164	struct alc_customize_define cdefine;
 165	struct snd_array kctls;
 166	struct hda_input_mux private_imux[3];
 167	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 168	hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
 169	hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
 170	hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
 171	unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
 172	int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */
 
 
 
 
 173
 174	/* hooks */
 175	void (*init_hook)(struct hda_codec *codec);
 176	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
 177#ifdef CONFIG_SND_HDA_POWER_SAVE
 178	void (*power_hook)(struct hda_codec *codec);
 179#endif
 180	void (*shutup)(struct hda_codec *codec);
 181	void (*automute_hook)(struct hda_codec *codec);
 182
 183	/* for pin sensing */
 184	unsigned int hp_jack_present:1;
 185	unsigned int line_jack_present:1;
 186	unsigned int master_mute:1;
 187	unsigned int auto_mic:1;
 188	unsigned int auto_mic_valid_imux:1;	/* valid imux for auto-mic */
 189	unsigned int automute_speaker:1; /* automute speaker outputs */
 190	unsigned int automute_lo:1; /* automute LO outputs */
 191	unsigned int detect_hp:1;	/* Headphone detection enabled */
 192	unsigned int detect_lo:1;	/* Line-out detection enabled */
 193	unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */
 194	unsigned int automute_lo_possible:1;	  /* there are line outs and HP */
 195	unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */
 196
 197	/* other flags */
 198	unsigned int no_analog :1; /* digital I/O only */
 199	unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
 200	unsigned int single_input_src:1;
 201	unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
 202	unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
 203	unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
 204	unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */
 205
 206	/* auto-mute control */
 207	int automute_mode;
 208	hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
 209
 210	int init_amp;
 211	int codec_variant;	/* flag for other variants */
 212
 213	/* for virtual master */
 214	hda_nid_t vmaster_nid;
 215	struct hda_vmaster_mute_hook vmaster_mute;
 216#ifdef CONFIG_SND_HDA_POWER_SAVE
 217	struct hda_loopback_check loopback;
 218	int num_loopbacks;
 219	struct hda_amp_list loopback_list[8];
 220#endif
 221
 222	/* for PLL fix */
 223	hda_nid_t pll_nid;
 224	unsigned int pll_coef_idx, pll_coef_bit;
 225	unsigned int coef0;
 226
 227	/* multi-io */
 228	int multi_ios;
 229	struct alc_multi_io multi_io[4];
 230
 231	/* bind volumes */
 232	struct snd_array bind_ctls;
 233};
 234
 235static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
 236			   int dir, unsigned int bits)
 237{
 238	if (!nid)
 239		return false;
 240	if (get_wcaps(codec, nid) & (1 << (dir + 1)))
 241		if (query_amp_caps(codec, nid, dir) & bits)
 242			return true;
 243	return false;
 244}
 245
 246#define nid_has_mute(codec, nid, dir) \
 247	check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
 248#define nid_has_volume(codec, nid, dir) \
 249	check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
 250
 251/*
 252 * input MUX handling
 253 */
 254static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
 255			     struct snd_ctl_elem_info *uinfo)
 256{
 257	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 258	struct alc_spec *spec = codec->spec;
 259	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
 260	if (mux_idx >= spec->num_mux_defs)
 261		mux_idx = 0;
 262	if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
 263		mux_idx = 0;
 264	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
 265}
 266
 267static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
 268			    struct snd_ctl_elem_value *ucontrol)
 269{
 270	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 271	struct alc_spec *spec = codec->spec;
 272	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 273
 274	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
 275	return 0;
 276}
 277
 278static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
 279{
 280	struct alc_spec *spec = codec->spec;
 281	hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]];
 282
 283	if (spec->cur_adc && spec->cur_adc != new_adc) {
 284		/* stream is running, let's swap the current ADC */
 285		__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
 286		spec->cur_adc = new_adc;
 287		snd_hda_codec_setup_stream(codec, new_adc,
 288					   spec->cur_adc_stream_tag, 0,
 289					   spec->cur_adc_format);
 290		return true;
 291	}
 292	return false;
 293}
 294
 295static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx)
 296{
 297	return spec->capsrc_nids ?
 298		spec->capsrc_nids[idx] : spec->adc_nids[idx];
 299}
 300
 301static void call_update_outputs(struct hda_codec *codec);
 302
 303/* select the given imux item; either unmute exclusively or select the route */
 304static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
 305			  unsigned int idx, bool force)
 306{
 307	struct alc_spec *spec = codec->spec;
 308	const struct hda_input_mux *imux;
 309	unsigned int mux_idx;
 310	int i, type, num_conns;
 311	hda_nid_t nid;
 312
 313	if (!spec->input_mux)
 314		return 0;
 315
 316	mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
 317	imux = &spec->input_mux[mux_idx];
 318	if (!imux->num_items && mux_idx > 0)
 319		imux = &spec->input_mux[0];
 320	if (!imux->num_items)
 321		return 0;
 322
 323	if (idx >= imux->num_items)
 324		idx = imux->num_items - 1;
 325	if (spec->cur_mux[adc_idx] == idx && !force)
 326		return 0;
 327	spec->cur_mux[adc_idx] = idx;
 328
 329	/* for shared I/O, change the pin-control accordingly */
 330	if (spec->shared_mic_hp) {
 331		unsigned int val;
 332		hda_nid_t pin = spec->autocfg.inputs[1].pin;
 333		/* NOTE: this assumes that there are only two inputs, the
 334		 * first is the real internal mic and the second is HP jack.
 335		 */
 336		if (spec->cur_mux[adc_idx])
 337			val = snd_hda_get_default_vref(codec, pin) | PIN_IN;
 338		else
 339			val = PIN_HP;
 340		snd_hda_set_pin_ctl(codec, pin, val);
 341		spec->automute_speaker = !spec->cur_mux[adc_idx];
 342		call_update_outputs(codec);
 343	}
 344
 345	if (spec->dyn_adc_switch) {
 346		alc_dyn_adc_pcm_resetup(codec, idx);
 347		adc_idx = spec->dyn_adc_idx[idx];
 348	}
 349
 350	nid = get_capsrc(spec, adc_idx);
 351
 352	/* no selection? */
 353	num_conns = snd_hda_get_num_conns(codec, nid);
 354	if (num_conns <= 1)
 355		return 1;
 356
 357	type = get_wcaps_type(get_wcaps(codec, nid));
 358	if (type == AC_WID_AUD_MIX) {
 359		/* Matrix-mixer style (e.g. ALC882) */
 360		int active = imux->items[idx].index;
 361		for (i = 0; i < num_conns; i++) {
 362			unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE;
 363			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i,
 364						 HDA_AMP_MUTE, v);
 365		}
 366	} else {
 367		/* MUX style (e.g. ALC880) */
 368		snd_hda_codec_write_cache(codec, nid, 0,
 369					  AC_VERB_SET_CONNECT_SEL,
 370					  imux->items[idx].index);
 371	}
 372	return 1;
 373}
 374
 375static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
 376			    struct snd_ctl_elem_value *ucontrol)
 377{
 378	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 379	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 380	return alc_mux_select(codec, adc_idx,
 381			      ucontrol->value.enumerated.item[0], false);
 382}
 383
 384/*
 385 * set up the input pin config (depending on the given auto-pin type)
 386 */
 387static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
 388			      int auto_pin_type)
 389{
 390	unsigned int val = PIN_IN;
 391	if (auto_pin_type == AUTO_PIN_MIC)
 392		val |= snd_hda_get_default_vref(codec, nid);
 393	snd_hda_set_pin_ctl(codec, nid, val);
 394}
 395
 396/*
 397 * Append the given mixer and verb elements for the later use
 398 * The mixer array is referred in build_controls(), and init_verbs are
 399 * called in init().
 400 */
 401static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
 402{
 403	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
 404		return;
 405	spec->mixers[spec->num_mixers++] = mix;
 406}
 407
 408/*
 409 * GPIO setup tables, used in initialization
 410 */
 411/* Enable GPIO mask and set output */
 412static const struct hda_verb alc_gpio1_init_verbs[] = {
 413	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
 414	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
 415	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
 416	{ }
 417};
 418
 419static const struct hda_verb alc_gpio2_init_verbs[] = {
 420	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
 421	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
 422	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
 423	{ }
 424};
 425
 426static const struct hda_verb alc_gpio3_init_verbs[] = {
 427	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
 428	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
 429	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
 430	{ }
 431};
 432
 433/*
 434 * Fix hardware PLL issue
 435 * On some codecs, the analog PLL gating control must be off while
 436 * the default value is 1.
 437 */
 438static void alc_fix_pll(struct hda_codec *codec)
 439{
 440	struct alc_spec *spec = codec->spec;
 441	unsigned int val;
 442
 443	if (!spec->pll_nid)
 444		return;
 445	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
 446			    spec->pll_coef_idx);
 447	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
 448				 AC_VERB_GET_PROC_COEF, 0);
 449	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
 450			    spec->pll_coef_idx);
 451	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
 452			    val & ~(1 << spec->pll_coef_bit));
 453}
 454
 455static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
 456			     unsigned int coef_idx, unsigned int coef_bit)
 457{
 458	struct alc_spec *spec = codec->spec;
 459	spec->pll_nid = nid;
 460	spec->pll_coef_idx = coef_idx;
 461	spec->pll_coef_bit = coef_bit;
 462	alc_fix_pll(codec);
 463}
 464
 465/*
 466 * Jack detections for HP auto-mute and mic-switch
 467 */
 468
 469/* check each pin in the given array; returns true if any of them is plugged */
 470static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
 471{
 472	int i, present = 0;
 473
 474	for (i = 0; i < num_pins; i++) {
 475		hda_nid_t nid = pins[i];
 476		if (!nid)
 477			break;
 478		present |= snd_hda_jack_detect(codec, nid);
 479	}
 480	return present;
 481}
 482
 483/* standard HP/line-out auto-mute helper */
 484static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
 485			bool mute, bool hp_out)
 486{
 487	struct alc_spec *spec = codec->spec;
 488	unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
 489	unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
 490	int i;
 491
 492	for (i = 0; i < num_pins; i++) {
 493		hda_nid_t nid = pins[i];
 494		unsigned int val;
 495		if (!nid)
 496			break;
 497		switch (spec->automute_mode) {
 498		case ALC_AUTOMUTE_PIN:
 499			/* don't reset VREF value in case it's controlling
 500			 * the amp (see alc861_fixup_asus_amp_vref_0f())
 501			 */
 502			if (spec->keep_vref_in_automute) {
 503				val = snd_hda_codec_read(codec, nid, 0,
 504					AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
 505				val &= ~PIN_HP;
 506			} else
 507				val = 0;
 508			val |= pin_bits;
 509			snd_hda_set_pin_ctl(codec, nid, val);
 510			break;
 511		case ALC_AUTOMUTE_AMP:
 512			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
 513						 HDA_AMP_MUTE, mute_bits);
 514			break;
 515		case ALC_AUTOMUTE_MIXER:
 516			nid = spec->automute_mixer_nid[i];
 517			if (!nid)
 518				break;
 519			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
 520						 HDA_AMP_MUTE, mute_bits);
 521			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
 522						 HDA_AMP_MUTE, mute_bits);
 523			break;
 524		}
 525	}
 526}
 527
 528/* Toggle outputs muting */
 529static void update_outputs(struct hda_codec *codec)
 530{
 531	struct alc_spec *spec = codec->spec;
 532	int on;
 533
 534	/* Control HP pins/amps depending on master_mute state;
 535	 * in general, HP pins/amps control should be enabled in all cases,
 536	 * but currently set only for master_mute, just to be safe
 537	 */
 538	if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */
 539		do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
 540		    spec->autocfg.hp_pins, spec->master_mute, true);
 541
 542	if (!spec->automute_speaker)
 543		on = 0;
 544	else
 545		on = spec->hp_jack_present | spec->line_jack_present;
 546	on |= spec->master_mute;
 547	do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
 548		    spec->autocfg.speaker_pins, on, false);
 549
 550	/* toggle line-out mutes if needed, too */
 551	/* if LO is a copy of either HP or Speaker, don't need to handle it */
 552	if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
 553	    spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
 554		return;
 555	if (!spec->automute_lo)
 556		on = 0;
 557	else
 558		on = spec->hp_jack_present;
 559	on |= spec->master_mute;
 560	do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
 561		    spec->autocfg.line_out_pins, on, false);
 562}
 563
 564static void call_update_outputs(struct hda_codec *codec)
 565{
 566	struct alc_spec *spec = codec->spec;
 567	if (spec->automute_hook)
 568		spec->automute_hook(codec);
 569	else
 570		update_outputs(codec);
 571}
 572
 573/* standard HP-automute helper */
 574static void alc_hp_automute(struct hda_codec *codec)
 575{
 576	struct alc_spec *spec = codec->spec;
 577
 578	spec->hp_jack_present =
 579		detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
 580			     spec->autocfg.hp_pins);
 581	if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo))
 582		return;
 583	call_update_outputs(codec);
 584}
 585
 586/* standard line-out-automute helper */
 587static void alc_line_automute(struct hda_codec *codec)
 588{
 589	struct alc_spec *spec = codec->spec;
 590
 591	/* check LO jack only when it's different from HP */
 592	if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0])
 593		return;
 594
 595	spec->line_jack_present =
 596		detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
 597			     spec->autocfg.line_out_pins);
 598	if (!spec->automute_speaker || !spec->detect_lo)
 599		return;
 600	call_update_outputs(codec);
 601}
 602
 603#define get_connection_index(codec, mux, nid) \
 604	snd_hda_get_conn_index(codec, mux, nid, 0)
 605
 606/* standard mic auto-switch helper */
 607static void alc_mic_automute(struct hda_codec *codec)
 608{
 609	struct alc_spec *spec = codec->spec;
 610	hda_nid_t *pins = spec->imux_pins;
 611
 612	if (!spec->auto_mic || !spec->auto_mic_valid_imux)
 613		return;
 614	if (snd_BUG_ON(!spec->adc_nids))
 615		return;
 616	if (snd_BUG_ON(spec->int_mic_idx < 0 || spec->ext_mic_idx < 0))
 617		return;
 618
 619	if (snd_hda_jack_detect(codec, pins[spec->ext_mic_idx]))
 620		alc_mux_select(codec, 0, spec->ext_mic_idx, false);
 621	else if (spec->dock_mic_idx >= 0 &&
 622		   snd_hda_jack_detect(codec, pins[spec->dock_mic_idx]))
 623		alc_mux_select(codec, 0, spec->dock_mic_idx, false);
 624	else
 625		alc_mux_select(codec, 0, spec->int_mic_idx, false);
 626}
 627
 628/* handle the specified unsol action (ALC_XXX_EVENT) */
 629static void alc_exec_unsol_event(struct hda_codec *codec, int action)
 630{
 631	switch (action) {
 632	case ALC_HP_EVENT:
 633		alc_hp_automute(codec);
 634		break;
 635	case ALC_FRONT_EVENT:
 636		alc_line_automute(codec);
 637		break;
 638	case ALC_MIC_EVENT:
 639		alc_mic_automute(codec);
 640		break;
 641	}
 642	snd_hda_jack_report_sync(codec);
 643}
 644
 645/* update the master volume per volume-knob's unsol event */
 646static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
 647{
 648	unsigned int val;
 649	struct snd_kcontrol *kctl;
 650	struct snd_ctl_elem_value *uctl;
 651
 652	kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
 653	if (!kctl)
 654		return;
 655	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 656	if (!uctl)
 657		return;
 658	val = snd_hda_codec_read(codec, nid, 0,
 659				 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
 660	val &= HDA_AMP_VOLMASK;
 661	uctl->value.integer.value[0] = val;
 662	uctl->value.integer.value[1] = val;
 663	kctl->put(kctl, uctl);
 664	kfree(uctl);
 665}
 666
 667/* unsolicited event for HP jack sensing */
 668static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
 669{
 670	int action;
 671
 672	if (codec->vendor_id == 0x10ec0880)
 673		res >>= 28;
 674	else
 675		res >>= 26;
 676	action = snd_hda_jack_get_action(codec, res);
 677	if (action == ALC_DCVOL_EVENT) {
 678		/* Execute the dc-vol event here as it requires the NID
 679		 * but we don't pass NID to alc_exec_unsol_event().
 680		 * Once when we convert all static quirks to the auto-parser,
 681		 * this can be integerated into there.
 682		 */
 683		struct hda_jack_tbl *jack;
 684		jack = snd_hda_jack_tbl_get_from_tag(codec, res);
 685		if (jack)
 686			alc_update_knob_master(codec, jack->nid);
 687		return;
 688	}
 689	alc_exec_unsol_event(codec, action);
 690}
 691
 692/* call init functions of standard auto-mute helpers */
 693static void alc_inithook(struct hda_codec *codec)
 694{
 695	alc_hp_automute(codec);
 696	alc_line_automute(codec);
 697	alc_mic_automute(codec);
 698}
 699
 700/* additional initialization for ALC888 variants */
 701static void alc888_coef_init(struct hda_codec *codec)
 702{
 703	unsigned int tmp;
 704
 705	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
 706	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
 707	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
 708	if ((tmp & 0xf0) == 0x20)
 709		/* alc888S-VC */
 710		snd_hda_codec_read(codec, 0x20, 0,
 711				   AC_VERB_SET_PROC_COEF, 0x830);
 712	 else
 713		 /* alc888-VB */
 714		 snd_hda_codec_read(codec, 0x20, 0,
 715				    AC_VERB_SET_PROC_COEF, 0x3030);
 716}
 717
 718/* additional initialization for ALC889 variants */
 719static void alc889_coef_init(struct hda_codec *codec)
 720{
 721	unsigned int tmp;
 722
 723	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
 724	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
 725	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
 726	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
 727}
 728
 729/* turn on/off EAPD control (only if available) */
 730static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
 731{
 732	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
 733		return;
 734	if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
 735		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
 736				    on ? 2 : 0);
 737}
 738
 739/* turn on/off EAPD controls of the codec */
 740static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
 741{
 742	/* We currently only handle front, HP */
 743	static hda_nid_t pins[] = {
 744		0x0f, 0x10, 0x14, 0x15, 0
 745	};
 746	hda_nid_t *p;
 747	for (p = pins; *p; p++)
 748		set_eapd(codec, *p, on);
 749}
 750
 751/* generic shutup callback;
 752 * just turning off EPAD and a little pause for avoiding pop-noise
 753 */
 754static void alc_eapd_shutup(struct hda_codec *codec)
 755{
 
 
 756	alc_auto_setup_eapd(codec, false);
 757	msleep(200);
 
 
 758}
 759
 760/* generic EAPD initialization */
 761static void alc_auto_init_amp(struct hda_codec *codec, int type)
 762{
 763	unsigned int tmp;
 764
 765	alc_auto_setup_eapd(codec, true);
 766	switch (type) {
 767	case ALC_INIT_GPIO1:
 768		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
 769		break;
 770	case ALC_INIT_GPIO2:
 771		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
 772		break;
 773	case ALC_INIT_GPIO3:
 774		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
 775		break;
 776	case ALC_INIT_DEFAULT:
 777		switch (codec->vendor_id) {
 778		case 0x10ec0260:
 779			snd_hda_codec_write(codec, 0x1a, 0,
 780					    AC_VERB_SET_COEF_INDEX, 7);
 781			tmp = snd_hda_codec_read(codec, 0x1a, 0,
 782						 AC_VERB_GET_PROC_COEF, 0);
 783			snd_hda_codec_write(codec, 0x1a, 0,
 784					    AC_VERB_SET_COEF_INDEX, 7);
 785			snd_hda_codec_write(codec, 0x1a, 0,
 786					    AC_VERB_SET_PROC_COEF,
 787					    tmp | 0x2010);
 788			break;
 789		case 0x10ec0262:
 790		case 0x10ec0880:
 791		case 0x10ec0882:
 792		case 0x10ec0883:
 793		case 0x10ec0885:
 794		case 0x10ec0887:
 795		/*case 0x10ec0889:*/ /* this causes an SPDIF problem */
 796			alc889_coef_init(codec);
 797			break;
 798		case 0x10ec0888:
 799			alc888_coef_init(codec);
 800			break;
 801#if 0 /* XXX: This may cause the silent output on speaker on some machines */
 802		case 0x10ec0267:
 803		case 0x10ec0268:
 804			snd_hda_codec_write(codec, 0x20, 0,
 805					    AC_VERB_SET_COEF_INDEX, 7);
 806			tmp = snd_hda_codec_read(codec, 0x20, 0,
 807						 AC_VERB_GET_PROC_COEF, 0);
 808			snd_hda_codec_write(codec, 0x20, 0,
 809					    AC_VERB_SET_COEF_INDEX, 7);
 810			snd_hda_codec_write(codec, 0x20, 0,
 811					    AC_VERB_SET_PROC_COEF,
 812					    tmp | 0x3000);
 813			break;
 814#endif /* XXX */
 815		}
 816		break;
 817	}
 818}
 819
 820/*
 821 * Auto-Mute mode mixer enum support
 822 */
 823static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
 824				  struct snd_ctl_elem_info *uinfo)
 825{
 826	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 827	struct alc_spec *spec = codec->spec;
 828	static const char * const texts2[] = {
 829		"Disabled", "Enabled"
 830	};
 831	static const char * const texts3[] = {
 832		"Disabled", "Speaker Only", "Line Out+Speaker"
 833	};
 834	const char * const *texts;
 835
 836	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 837	uinfo->count = 1;
 838	if (spec->automute_speaker_possible && spec->automute_lo_possible) {
 839		uinfo->value.enumerated.items = 3;
 840		texts = texts3;
 841	} else {
 842		uinfo->value.enumerated.items = 2;
 843		texts = texts2;
 844	}
 845	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
 846		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
 847	strcpy(uinfo->value.enumerated.name,
 848	       texts[uinfo->value.enumerated.item]);
 849	return 0;
 850}
 851
 852static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
 853				 struct snd_ctl_elem_value *ucontrol)
 854{
 855	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 856	struct alc_spec *spec = codec->spec;
 857	unsigned int val = 0;
 858	if (spec->automute_speaker)
 859		val++;
 860	if (spec->automute_lo)
 861		val++;
 862
 863	ucontrol->value.enumerated.item[0] = val;
 864	return 0;
 865}
 866
 867static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
 868				 struct snd_ctl_elem_value *ucontrol)
 869{
 870	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 871	struct alc_spec *spec = codec->spec;
 872
 873	switch (ucontrol->value.enumerated.item[0]) {
 874	case 0:
 875		if (!spec->automute_speaker && !spec->automute_lo)
 876			return 0;
 877		spec->automute_speaker = 0;
 878		spec->automute_lo = 0;
 879		break;
 880	case 1:
 881		if (spec->automute_speaker_possible) {
 882			if (!spec->automute_lo && spec->automute_speaker)
 883				return 0;
 884			spec->automute_speaker = 1;
 885			spec->automute_lo = 0;
 886		} else if (spec->automute_lo_possible) {
 887			if (spec->automute_lo)
 888				return 0;
 889			spec->automute_lo = 1;
 890		} else
 891			return -EINVAL;
 892		break;
 893	case 2:
 894		if (!spec->automute_lo_possible || !spec->automute_speaker_possible)
 895			return -EINVAL;
 896		if (spec->automute_speaker && spec->automute_lo)
 897			return 0;
 898		spec->automute_speaker = 1;
 899		spec->automute_lo = 1;
 900		break;
 901	default:
 902		return -EINVAL;
 903	}
 904	call_update_outputs(codec);
 905	return 1;
 906}
 907
 908static const struct snd_kcontrol_new alc_automute_mode_enum = {
 909	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 910	.name = "Auto-Mute Mode",
 911	.info = alc_automute_mode_info,
 912	.get = alc_automute_mode_get,
 913	.put = alc_automute_mode_put,
 914};
 915
 916static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
 917{
 918	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
 919	return snd_array_new(&spec->kctls);
 920}
 921
 922static int alc_add_automute_mode_enum(struct hda_codec *codec)
 923{
 924	struct alc_spec *spec = codec->spec;
 925	struct snd_kcontrol_new *knew;
 926
 927	knew = alc_kcontrol_new(spec);
 928	if (!knew)
 929		return -ENOMEM;
 930	*knew = alc_automute_mode_enum;
 931	knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
 932	if (!knew->name)
 933		return -ENOMEM;
 934	return 0;
 935}
 936
 937/*
 938 * Check the availability of HP/line-out auto-mute;
 939 * Set up appropriately if really supported
 940 */
 941static void alc_init_automute(struct hda_codec *codec)
 942{
 943	struct alc_spec *spec = codec->spec;
 944	struct auto_pin_cfg *cfg = &spec->autocfg;
 945	int present = 0;
 946	int i;
 947
 948	if (cfg->hp_pins[0])
 949		present++;
 950	if (cfg->line_out_pins[0])
 951		present++;
 952	if (cfg->speaker_pins[0])
 953		present++;
 954	if (present < 2) /* need two different output types */
 955		return;
 956
 957	if (!cfg->speaker_pins[0] &&
 958	    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
 959		memcpy(cfg->speaker_pins, cfg->line_out_pins,
 960		       sizeof(cfg->speaker_pins));
 961		cfg->speaker_outs = cfg->line_outs;
 962	}
 963
 964	if (!cfg->hp_pins[0] &&
 965	    cfg->line_out_type == AUTO_PIN_HP_OUT) {
 966		memcpy(cfg->hp_pins, cfg->line_out_pins,
 967		       sizeof(cfg->hp_pins));
 968		cfg->hp_outs = cfg->line_outs;
 969	}
 970
 971	spec->automute_mode = ALC_AUTOMUTE_PIN;
 972
 973	for (i = 0; i < cfg->hp_outs; i++) {
 974		hda_nid_t nid = cfg->hp_pins[i];
 975		if (!is_jack_detectable(codec, nid))
 976			continue;
 977		snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
 978			    nid);
 979		snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT);
 980		spec->detect_hp = 1;
 981	}
 982
 983	if (cfg->line_out_type == AUTO_PIN_LINE_OUT && cfg->line_outs) {
 984		if (cfg->speaker_outs)
 985			for (i = 0; i < cfg->line_outs; i++) {
 986				hda_nid_t nid = cfg->line_out_pins[i];
 987				if (!is_jack_detectable(codec, nid))
 988					continue;
 989				snd_printdd("realtek: Enable Line-Out "
 990					    "auto-muting on NID 0x%x\n", nid);
 991				snd_hda_jack_detect_enable(codec, nid,
 992							   ALC_FRONT_EVENT);
 993				spec->detect_lo = 1;
 994		}
 995		spec->automute_lo_possible = spec->detect_hp;
 996	}
 997
 998	spec->automute_speaker_possible = cfg->speaker_outs &&
 999		(spec->detect_hp || spec->detect_lo);
1000
1001	spec->automute_lo = spec->automute_lo_possible;
1002	spec->automute_speaker = spec->automute_speaker_possible;
1003
1004	if (spec->automute_speaker_possible || spec->automute_lo_possible) {
1005		/* create a control for automute mode */
1006		alc_add_automute_mode_enum(codec);
1007		spec->unsol_event = alc_sku_unsol_event;
1008	}
1009}
1010
1011/* return the position of NID in the list, or -1 if not found */
1012static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1013{
1014	int i;
1015	for (i = 0; i < nums; i++)
1016		if (list[i] == nid)
1017			return i;
1018	return -1;
1019}
1020
1021/* check whether dynamic ADC-switching is available */
1022static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
1023{
1024	struct alc_spec *spec = codec->spec;
1025	struct hda_input_mux *imux = &spec->private_imux[0];
1026	int i, n, idx;
1027	hda_nid_t cap, pin;
1028
1029	if (imux != spec->input_mux) /* no dynamic imux? */
1030		return false;
1031
1032	for (n = 0; n < spec->num_adc_nids; n++) {
1033		cap = spec->private_capsrc_nids[n];
1034		for (i = 0; i < imux->num_items; i++) {
1035			pin = spec->imux_pins[i];
1036			if (!pin)
1037				return false;
1038			if (get_connection_index(codec, cap, pin) < 0)
1039				break;
1040		}
1041		if (i >= imux->num_items)
1042			return true; /* no ADC-switch is needed */
1043	}
1044
1045	for (i = 0; i < imux->num_items; i++) {
1046		pin = spec->imux_pins[i];
1047		for (n = 0; n < spec->num_adc_nids; n++) {
1048			cap = spec->private_capsrc_nids[n];
1049			idx = get_connection_index(codec, cap, pin);
1050			if (idx >= 0) {
1051				imux->items[i].index = idx;
1052				spec->dyn_adc_idx[i] = n;
1053				break;
1054			}
1055		}
1056	}
1057
1058	snd_printdd("realtek: enabling ADC switching\n");
1059	spec->dyn_adc_switch = 1;
1060	return true;
1061}
1062
1063/* check whether all auto-mic pins are valid; setup indices if OK */
1064static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1065{
1066	struct alc_spec *spec = codec->spec;
1067	const struct hda_input_mux *imux;
1068
1069	if (!spec->auto_mic)
1070		return false;
1071	if (spec->auto_mic_valid_imux)
1072		return true; /* already checked */
1073
1074	/* fill up imux indices */
1075	if (!alc_check_dyn_adc_switch(codec)) {
1076		spec->auto_mic = 0;
1077		return false;
1078	}
1079
1080	imux = spec->input_mux;
1081	spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin,
1082					spec->imux_pins, imux->num_items);
1083	spec->int_mic_idx = find_idx_in_nid_list(spec->int_mic_pin,
1084					spec->imux_pins, imux->num_items);
1085	spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin,
1086					spec->imux_pins, imux->num_items);
1087	if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) {
1088		spec->auto_mic = 0;
1089		return false; /* no corresponding imux */
1090	}
1091
1092	snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT);
1093	if (spec->dock_mic_pin)
1094		snd_hda_jack_detect_enable(codec, spec->dock_mic_pin,
1095					   ALC_MIC_EVENT);
1096
1097	spec->auto_mic_valid_imux = 1;
1098	spec->auto_mic = 1;
1099	return true;
1100}
1101
1102/*
1103 * Check the availability of auto-mic switch;
1104 * Set up if really supported
1105 */
1106static void alc_init_auto_mic(struct hda_codec *codec)
1107{
1108	struct alc_spec *spec = codec->spec;
1109	struct auto_pin_cfg *cfg = &spec->autocfg;
1110	hda_nid_t fixed, ext, dock;
1111	int i;
1112
1113	if (spec->shared_mic_hp)
1114		return; /* no auto-mic for the shared I/O */
1115
1116	spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1;
1117
1118	fixed = ext = dock = 0;
1119	for (i = 0; i < cfg->num_inputs; i++) {
1120		hda_nid_t nid = cfg->inputs[i].pin;
1121		unsigned int defcfg;
1122		defcfg = snd_hda_codec_get_pincfg(codec, nid);
1123		switch (snd_hda_get_input_pin_attr(defcfg)) {
1124		case INPUT_PIN_ATTR_INT:
1125			if (fixed)
1126				return; /* already occupied */
1127			if (cfg->inputs[i].type != AUTO_PIN_MIC)
1128				return; /* invalid type */
1129			fixed = nid;
1130			break;
1131		case INPUT_PIN_ATTR_UNUSED:
1132			return; /* invalid entry */
1133		case INPUT_PIN_ATTR_DOCK:
1134			if (dock)
1135				return; /* already occupied */
1136			if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1137				return; /* invalid type */
1138			dock = nid;
1139			break;
1140		default:
1141			if (ext)
1142				return; /* already occupied */
1143			if (cfg->inputs[i].type != AUTO_PIN_MIC)
1144				return; /* invalid type */
1145			ext = nid;
1146			break;
1147		}
1148	}
1149	if (!ext && dock) {
1150		ext = dock;
1151		dock = 0;
1152	}
1153	if (!ext || !fixed)
1154		return;
1155	if (!is_jack_detectable(codec, ext))
1156		return; /* no unsol support */
1157	if (dock && !is_jack_detectable(codec, dock))
1158		return; /* no unsol support */
1159
1160	/* check imux indices */
1161	spec->ext_mic_pin = ext;
1162	spec->int_mic_pin = fixed;
1163	spec->dock_mic_pin = dock;
1164
1165	spec->auto_mic = 1;
1166	if (!alc_auto_mic_check_imux(codec))
1167		return;
1168
1169	snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1170		    ext, fixed, dock);
1171	spec->unsol_event = alc_sku_unsol_event;
1172}
1173
1174/* check the availabilities of auto-mute and auto-mic switches */
1175static void alc_auto_check_switches(struct hda_codec *codec)
1176{
1177	alc_init_automute(codec);
1178	alc_init_auto_mic(codec);
1179}
1180
1181/*
1182 * Realtek SSID verification
1183 */
1184
1185/* Could be any non-zero and even value. When used as fixup, tells
1186 * the driver to ignore any present sku defines.
1187 */
1188#define ALC_FIXUP_SKU_IGNORE (2)
1189
1190static void alc_fixup_sku_ignore(struct hda_codec *codec,
1191				 const struct hda_fixup *fix, int action)
1192{
1193	struct alc_spec *spec = codec->spec;
1194	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1195		spec->cdefine.fixup = 1;
1196		spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
1197	}
1198}
1199
 
 
 
 
 
 
 
 
 
 
 
1200static int alc_auto_parse_customize_define(struct hda_codec *codec)
1201{
1202	unsigned int ass, tmp, i;
1203	unsigned nid = 0;
1204	struct alc_spec *spec = codec->spec;
1205
1206	spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1207
1208	if (spec->cdefine.fixup) {
1209		ass = spec->cdefine.sku_cfg;
1210		if (ass == ALC_FIXUP_SKU_IGNORE)
1211			return -1;
1212		goto do_sku;
1213	}
1214
 
 
1215	ass = codec->subsystem_id & 0xffff;
1216	if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1217		goto do_sku;
1218
1219	nid = 0x1d;
1220	if (codec->vendor_id == 0x10ec0260)
1221		nid = 0x17;
1222	ass = snd_hda_codec_get_pincfg(codec, nid);
1223
1224	if (!(ass & 1)) {
1225		printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1226		       codec->chip_name, ass);
1227		return -1;
1228	}
1229
1230	/* check sum */
1231	tmp = 0;
1232	for (i = 1; i < 16; i++) {
1233		if ((ass >> i) & 1)
1234			tmp++;
1235	}
1236	if (((ass >> 16) & 0xf) != tmp)
1237		return -1;
1238
1239	spec->cdefine.port_connectivity = ass >> 30;
1240	spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1241	spec->cdefine.check_sum = (ass >> 16) & 0xf;
1242	spec->cdefine.customization = ass >> 8;
1243do_sku:
1244	spec->cdefine.sku_cfg = ass;
1245	spec->cdefine.external_amp = (ass & 0x38) >> 3;
1246	spec->cdefine.platform_type = (ass & 0x4) >> 2;
1247	spec->cdefine.swap = (ass & 0x2) >> 1;
1248	spec->cdefine.override = ass & 0x1;
1249
1250	snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1251		   nid, spec->cdefine.sku_cfg);
1252	snd_printd("SKU: port_connectivity=0x%x\n",
1253		   spec->cdefine.port_connectivity);
1254	snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1255	snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1256	snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1257	snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1258	snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1259	snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1260	snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1261
1262	return 0;
1263}
1264
 
 
 
 
 
 
 
 
 
1265/* return true if the given NID is found in the list */
1266static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1267{
1268	return find_idx_in_nid_list(nid, list, nums) >= 0;
1269}
1270
1271/* check subsystem ID and set up device-specific initialization;
1272 * return 1 if initialized, 0 if invalid SSID
1273 */
1274/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1275 *	31 ~ 16 :	Manufacture ID
1276 *	15 ~ 8	:	SKU ID
1277 *	7  ~ 0	:	Assembly ID
1278 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1279 */
1280static int alc_subsystem_id(struct hda_codec *codec,
1281			    hda_nid_t porta, hda_nid_t porte,
1282			    hda_nid_t portd, hda_nid_t porti)
1283{
1284	unsigned int ass, tmp, i;
1285	unsigned nid;
1286	struct alc_spec *spec = codec->spec;
1287
1288	if (spec->cdefine.fixup) {
1289		ass = spec->cdefine.sku_cfg;
1290		if (ass == ALC_FIXUP_SKU_IGNORE)
1291			return 0;
1292		goto do_sku;
1293	}
1294
1295	ass = codec->subsystem_id & 0xffff;
1296	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
 
1297		goto do_sku;
1298
1299	/* invalid SSID, check the special NID pin defcfg instead */
1300	/*
1301	 * 31~30	: port connectivity
1302	 * 29~21	: reserve
1303	 * 20		: PCBEEP input
1304	 * 19~16	: Check sum (15:1)
1305	 * 15~1		: Custom
1306	 * 0		: override
1307	*/
1308	nid = 0x1d;
1309	if (codec->vendor_id == 0x10ec0260)
1310		nid = 0x17;
1311	ass = snd_hda_codec_get_pincfg(codec, nid);
1312	snd_printd("realtek: No valid SSID, "
1313		   "checking pincfg 0x%08x for NID 0x%x\n",
1314		   ass, nid);
1315	if (!(ass & 1))
1316		return 0;
1317	if ((ass >> 30) != 1)	/* no physical connection */
1318		return 0;
1319
1320	/* check sum */
1321	tmp = 0;
1322	for (i = 1; i < 16; i++) {
1323		if ((ass >> i) & 1)
1324			tmp++;
1325	}
1326	if (((ass >> 16) & 0xf) != tmp)
1327		return 0;
1328do_sku:
1329	snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1330		   ass & 0xffff, codec->vendor_id);
1331	/*
1332	 * 0 : override
1333	 * 1 :	Swap Jack
1334	 * 2 : 0 --> Desktop, 1 --> Laptop
1335	 * 3~5 : External Amplifier control
1336	 * 7~6 : Reserved
1337	*/
1338	tmp = (ass & 0x38) >> 3;	/* external Amp control */
1339	switch (tmp) {
1340	case 1:
1341		spec->init_amp = ALC_INIT_GPIO1;
1342		break;
1343	case 3:
1344		spec->init_amp = ALC_INIT_GPIO2;
1345		break;
1346	case 7:
1347		spec->init_amp = ALC_INIT_GPIO3;
1348		break;
1349	case 5:
1350	default:
1351		spec->init_amp = ALC_INIT_DEFAULT;
1352		break;
1353	}
1354
1355	/* is laptop or Desktop and enable the function "Mute internal speaker
1356	 * when the external headphone out jack is plugged"
1357	 */
1358	if (!(ass & 0x8000))
1359		return 1;
1360	/*
1361	 * 10~8 : Jack location
1362	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1363	 * 14~13: Resvered
1364	 * 15   : 1 --> enable the function "Mute internal speaker
1365	 *	        when the external headphone out jack is plugged"
1366	 */
1367	if (!spec->autocfg.hp_pins[0] &&
1368	    !(spec->autocfg.line_out_pins[0] &&
1369	      spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
1370		hda_nid_t nid;
1371		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
1372		if (tmp == 0)
1373			nid = porta;
1374		else if (tmp == 1)
1375			nid = porte;
1376		else if (tmp == 2)
1377			nid = portd;
1378		else if (tmp == 3)
1379			nid = porti;
1380		else
1381			return 1;
1382		if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1383				      spec->autocfg.line_outs))
1384			return 1;
1385		spec->autocfg.hp_pins[0] = nid;
1386	}
1387	return 1;
1388}
1389
1390/* Check the validity of ALC subsystem-id
1391 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
1392static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
1393{
1394	if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) {
1395		struct alc_spec *spec = codec->spec;
1396		snd_printd("realtek: "
1397			   "Enable default setup for auto mode as fallback\n");
1398		spec->init_amp = ALC_INIT_DEFAULT;
1399	}
1400}
1401
1402/*
1403 * COEF access helper functions
1404 */
1405static int alc_read_coef_idx(struct hda_codec *codec,
1406			unsigned int coef_idx)
 
 
1407{
1408	unsigned int val;
1409	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1410		    		coef_idx);
1411	val = snd_hda_codec_read(codec, 0x20, 0,
1412			 	AC_VERB_GET_PROC_COEF, 0);
1413	return val;
1414}
1415
1416static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
 
 
 
 
1417							unsigned int coef_val)
1418{
1419	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1420			    coef_idx);
1421	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1422			    coef_val);
1423}
1424
 
 
 
1425/* a special bypass for COEF 0; read the cached value at the second time */
1426static unsigned int alc_get_coef0(struct hda_codec *codec)
1427{
1428	struct alc_spec *spec = codec->spec;
1429	if (!spec->coef0)
1430		spec->coef0 = alc_read_coef_idx(codec, 0);
1431	return spec->coef0;
1432}
1433
1434/*
1435 * Digital I/O handling
1436 */
1437
1438/* set right pin controls for digital I/O */
1439static void alc_auto_init_digital(struct hda_codec *codec)
 
 
 
 
 
 
 
1440{
1441	struct alc_spec *spec = codec->spec;
1442	int i;
1443	hda_nid_t pin, dac;
 
 
 
1444
1445	for (i = 0; i < spec->autocfg.dig_outs; i++) {
1446		pin = spec->autocfg.dig_out_pins[i];
1447		if (!pin)
1448			continue;
1449		snd_hda_set_pin_ctl(codec, pin, PIN_OUT);
1450		if (!i)
1451			dac = spec->multiout.dig_out_nid;
1452		else
1453			dac = spec->slave_dig_outs[i - 1];
1454		if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
1455			continue;
1456		snd_hda_codec_write(codec, dac, 0,
1457				    AC_VERB_SET_AMP_GAIN_MUTE,
1458				    AMP_OUT_UNMUTE);
1459	}
1460	pin = spec->autocfg.dig_in_pin;
1461	if (pin)
1462		snd_hda_set_pin_ctl(codec, pin, PIN_IN);
1463}
1464
1465/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1466static void alc_auto_parse_digital(struct hda_codec *codec)
1467{
1468	struct alc_spec *spec = codec->spec;
1469	int i, err, nums;
1470	hda_nid_t dig_nid;
1471
1472	/* support multiple SPDIFs; the secondary is set up as a slave */
1473	nums = 0;
1474	for (i = 0; i < spec->autocfg.dig_outs; i++) {
1475		hda_nid_t conn[4];
1476		err = snd_hda_get_connections(codec,
1477					      spec->autocfg.dig_out_pins[i],
1478					      conn, ARRAY_SIZE(conn));
1479		if (err <= 0)
1480			continue;
1481		dig_nid = conn[0]; /* assume the first element is audio-out */
1482		if (!nums) {
1483			spec->multiout.dig_out_nid = dig_nid;
1484			spec->dig_out_type = spec->autocfg.dig_out_type[0];
1485		} else {
1486			spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1487			if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1488				break;
1489			spec->slave_dig_outs[nums - 1] = dig_nid;
1490		}
1491		nums++;
1492	}
1493
1494	if (spec->autocfg.dig_in_pin) {
1495		dig_nid = codec->start_nid;
1496		for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1497			unsigned int wcaps = get_wcaps(codec, dig_nid);
1498			if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1499				continue;
1500			if (!(wcaps & AC_WCAP_DIGITAL))
1501				continue;
1502			if (!(wcaps & AC_WCAP_CONN_LIST))
1503				continue;
1504			err = get_connection_index(codec, dig_nid,
1505						   spec->autocfg.dig_in_pin);
1506			if (err >= 0) {
1507				spec->dig_in_nid = dig_nid;
1508				break;
1509			}
1510		}
1511	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1512}
1513
1514/*
1515 * capture mixer elements
 
 
 
 
 
 
 
 
 
 
 
 
1516 */
1517static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1518			    struct snd_ctl_elem_info *uinfo)
1519{
1520	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1521	struct alc_spec *spec = codec->spec;
1522	unsigned long val;
1523	int err;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1524
1525	mutex_lock(&codec->control_mutex);
1526	if (spec->vol_in_capsrc)
1527		val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
1528	else
1529		val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
1530	kcontrol->private_value = val;
1531	err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1532	mutex_unlock(&codec->control_mutex);
1533	return err;
1534}
1535
1536static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1537			   unsigned int size, unsigned int __user *tlv)
1538{
1539	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1540	struct alc_spec *spec = codec->spec;
1541	unsigned long val;
1542	int err;
1543
1544	mutex_lock(&codec->control_mutex);
1545	if (spec->vol_in_capsrc)
1546		val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
1547	else
1548		val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
1549	kcontrol->private_value = val;
1550	err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1551	mutex_unlock(&codec->control_mutex);
1552	return err;
1553}
1554
1555typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1556			     struct snd_ctl_elem_value *ucontrol);
1557
1558static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1559				 struct snd_ctl_elem_value *ucontrol,
1560				 getput_call_t func, bool check_adc_switch)
1561{
1562	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1563	struct alc_spec *spec = codec->spec;
1564	int i, err = 0;
1565
1566	mutex_lock(&codec->control_mutex);
1567	if (check_adc_switch && spec->dyn_adc_switch) {
1568		for (i = 0; i < spec->num_adc_nids; i++) {
1569			kcontrol->private_value =
1570				HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
1571						    3, 0, HDA_INPUT);
1572			err = func(kcontrol, ucontrol);
1573			if (err < 0)
1574				goto error;
1575		}
1576	} else {
1577		i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1578		if (spec->vol_in_capsrc)
1579			kcontrol->private_value =
1580				HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
1581						    3, 0, HDA_OUTPUT);
1582		else
1583			kcontrol->private_value =
1584				HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
1585						    3, 0, HDA_INPUT);
1586		err = func(kcontrol, ucontrol);
1587	}
1588 error:
1589	mutex_unlock(&codec->control_mutex);
1590	return err;
1591}
1592
1593static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1594			   struct snd_ctl_elem_value *ucontrol)
1595{
1596	return alc_cap_getput_caller(kcontrol, ucontrol,
1597				     snd_hda_mixer_amp_volume_get, false);
1598}
1599
1600static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1601			   struct snd_ctl_elem_value *ucontrol)
1602{
1603	return alc_cap_getput_caller(kcontrol, ucontrol,
1604				     snd_hda_mixer_amp_volume_put, true);
1605}
1606
1607/* capture mixer elements */
1608#define alc_cap_sw_info		snd_ctl_boolean_stereo_info
1609
1610static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1611			  struct snd_ctl_elem_value *ucontrol)
1612{
1613	return alc_cap_getput_caller(kcontrol, ucontrol,
1614				     snd_hda_mixer_amp_switch_get, false);
1615}
1616
1617static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1618			  struct snd_ctl_elem_value *ucontrol)
1619{
1620	return alc_cap_getput_caller(kcontrol, ucontrol,
1621				     snd_hda_mixer_amp_switch_put, true);
1622}
1623
1624#define _DEFINE_CAPMIX(num) \
1625	{ \
1626		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1627		.name = "Capture Switch", \
1628		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1629		.count = num, \
1630		.info = alc_cap_sw_info, \
1631		.get = alc_cap_sw_get, \
1632		.put = alc_cap_sw_put, \
1633	}, \
1634	{ \
1635		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1636		.name = "Capture Volume", \
1637		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1638			   SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1639			   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1640		.count = num, \
1641		.info = alc_cap_vol_info, \
1642		.get = alc_cap_vol_get, \
1643		.put = alc_cap_vol_put, \
1644		.tlv = { .c = alc_cap_vol_tlv }, \
1645	}
1646
1647#define _DEFINE_CAPSRC(num) \
1648	{ \
1649		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1650		/* .name = "Capture Source", */ \
1651		.name = "Input Source", \
1652		.count = num, \
1653		.info = alc_mux_enum_info, \
1654		.get = alc_mux_enum_get, \
1655		.put = alc_mux_enum_put, \
1656	}
1657
1658#define DEFINE_CAPMIX(num) \
1659static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1660	_DEFINE_CAPMIX(num),				      \
1661	_DEFINE_CAPSRC(num),				      \
1662	{ } /* end */					      \
1663}
1664
1665#define DEFINE_CAPMIX_NOSRC(num) \
1666static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1667	_DEFINE_CAPMIX(num),					    \
1668	{ } /* end */						    \
1669}
1670
1671/* up to three ADCs */
1672DEFINE_CAPMIX(1);
1673DEFINE_CAPMIX(2);
1674DEFINE_CAPMIX(3);
1675DEFINE_CAPMIX_NOSRC(1);
1676DEFINE_CAPMIX_NOSRC(2);
1677DEFINE_CAPMIX_NOSRC(3);
1678
1679/*
1680 * virtual master controls
1681 */
1682
1683/*
1684 * slave controls for virtual master
1685 */
1686static const char * const alc_slave_pfxs[] = {
1687	"Front", "Surround", "Center", "LFE", "Side",
1688	"Headphone", "Speaker", "Mono", "Line Out",
1689	"CLFE", "Bass Speaker", "PCM",
1690	NULL,
1691};
1692
1693/*
1694 * build control elements
1695 */
1696
1697#define NID_MAPPING		(-1)
 
 
 
 
 
 
 
1698
1699#define SUBDEV_SPEAKER_		(0 << 6)
1700#define SUBDEV_HP_		(1 << 6)
1701#define SUBDEV_LINE_		(2 << 6)
1702#define SUBDEV_SPEAKER(x)	(SUBDEV_SPEAKER_ | ((x) & 0x3f))
1703#define SUBDEV_HP(x)		(SUBDEV_HP_ | ((x) & 0x3f))
1704#define SUBDEV_LINE(x)		(SUBDEV_LINE_ | ((x) & 0x3f))
 
1705
1706static void alc_free_kctls(struct hda_codec *codec);
1707
1708#ifdef CONFIG_SND_HDA_INPUT_BEEP
1709/* additional beep mixers; the actual parameters are overwritten at build */
1710static const struct snd_kcontrol_new alc_beep_mixer[] = {
1711	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
1712	HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
1713	{ } /* end */
1714};
1715#endif
1716
1717static int __alc_build_controls(struct hda_codec *codec)
1718{
1719	struct alc_spec *spec = codec->spec;
1720	struct snd_kcontrol *kctl = NULL;
1721	const struct snd_kcontrol_new *knew;
1722	int i, j, err;
1723	unsigned int u;
1724	hda_nid_t nid;
1725
1726	for (i = 0; i < spec->num_mixers; i++) {
1727		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1728		if (err < 0)
1729			return err;
1730	}
1731	if (spec->cap_mixer) {
1732		err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
1733		if (err < 0)
1734			return err;
1735	}
1736	if (spec->multiout.dig_out_nid) {
1737		err = snd_hda_create_spdif_out_ctls(codec,
1738						    spec->multiout.dig_out_nid,
1739						    spec->multiout.dig_out_nid);
1740		if (err < 0)
1741			return err;
1742		if (!spec->no_analog) {
1743			err = snd_hda_create_spdif_share_sw(codec,
1744							    &spec->multiout);
1745			if (err < 0)
1746				return err;
1747			spec->multiout.share_spdif = 1;
1748		}
1749	}
1750	if (spec->dig_in_nid) {
1751		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1752		if (err < 0)
1753			return err;
1754	}
1755
1756#ifdef CONFIG_SND_HDA_INPUT_BEEP
1757	/* create beep controls if needed */
1758	if (spec->beep_amp) {
1759		const struct snd_kcontrol_new *knew;
1760		for (knew = alc_beep_mixer; knew->name; knew++) {
1761			struct snd_kcontrol *kctl;
1762			kctl = snd_ctl_new1(knew, codec);
1763			if (!kctl)
1764				return -ENOMEM;
1765			kctl->private_value = spec->beep_amp;
1766			err = snd_hda_ctl_add(codec, 0, kctl);
1767			if (err < 0)
1768				return err;
1769		}
1770	}
1771#endif
1772
1773	/* if we have no master control, let's create it */
1774	if (!spec->no_analog &&
1775	    !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1776		unsigned int vmaster_tlv[4];
1777		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1778					HDA_OUTPUT, vmaster_tlv);
1779		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1780					  vmaster_tlv, alc_slave_pfxs,
1781					  "Playback Volume");
1782		if (err < 0)
1783			return err;
1784	}
1785	if (!spec->no_analog &&
1786	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1787		err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
1788					    NULL, alc_slave_pfxs,
1789					    "Playback Switch",
1790					    true, &spec->vmaster_mute.sw_kctl);
1791		if (err < 0)
1792			return err;
1793	}
1794
1795	/* assign Capture Source enums to NID */
1796	if (spec->capsrc_nids || spec->adc_nids) {
1797		kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
1798		if (!kctl)
1799			kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1800		for (i = 0; kctl && i < kctl->count; i++) {
1801			err = snd_hda_add_nid(codec, kctl, i,
1802					      get_capsrc(spec, i));
1803			if (err < 0)
1804				return err;
1805		}
1806	}
1807	if (spec->cap_mixer && spec->adc_nids) {
1808		const char *kname = kctl ? kctl->id.name : NULL;
1809		for (knew = spec->cap_mixer; knew->name; knew++) {
1810			if (kname && strcmp(knew->name, kname) == 0)
1811				continue;
1812			kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1813			for (i = 0; kctl && i < kctl->count; i++) {
1814				err = snd_hda_add_nid(codec, kctl, i,
1815						      spec->adc_nids[i]);
1816				if (err < 0)
1817					return err;
1818			}
1819		}
1820	}
1821
1822	/* other nid->control mapping */
1823	for (i = 0; i < spec->num_mixers; i++) {
1824		for (knew = spec->mixers[i]; knew->name; knew++) {
1825			if (knew->iface != NID_MAPPING)
1826				continue;
1827			kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1828			if (kctl == NULL)
1829				continue;
1830			u = knew->subdevice;
1831			for (j = 0; j < 4; j++, u >>= 8) {
1832				nid = u & 0x3f;
1833				if (nid == 0)
1834					continue;
1835				switch (u & 0xc0) {
1836				case SUBDEV_SPEAKER_:
1837					nid = spec->autocfg.speaker_pins[nid];
1838					break;
1839				case SUBDEV_LINE_:
1840					nid = spec->autocfg.line_out_pins[nid];
1841					break;
1842				case SUBDEV_HP_:
1843					nid = spec->autocfg.hp_pins[nid];
1844					break;
1845				default:
1846					continue;
1847				}
1848				err = snd_hda_add_nid(codec, kctl, 0, nid);
1849				if (err < 0)
1850					return err;
1851			}
1852			u = knew->private_value;
1853			for (j = 0; j < 4; j++, u >>= 8) {
1854				nid = u & 0xff;
1855				if (nid == 0)
1856					continue;
1857				err = snd_hda_add_nid(codec, kctl, 0, nid);
1858				if (err < 0)
1859					return err;
1860			}
1861		}
1862	}
1863
1864	alc_free_kctls(codec); /* no longer needed */
1865
1866	return 0;
1867}
1868
1869static int alc_build_controls(struct hda_codec *codec)
1870{
1871	struct alc_spec *spec = codec->spec;
1872	int err = __alc_build_controls(codec);
1873	if (err < 0)
1874		return err;
1875	err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
1876	if (err < 0)
1877		return err;
1878	alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
1879	return 0;
1880}
1881
1882
1883/*
1884 * Common callbacks
1885 */
1886
1887static void alc_init_special_input_src(struct hda_codec *codec);
1888static void alc_auto_init_std(struct hda_codec *codec);
1889
1890static int alc_init(struct hda_codec *codec)
1891{
1892	struct alc_spec *spec = codec->spec;
1893
1894	if (spec->init_hook)
1895		spec->init_hook(codec);
1896
1897	alc_fix_pll(codec);
1898	alc_auto_init_amp(codec, spec->init_amp);
1899
1900	snd_hda_gen_apply_verbs(codec);
1901	alc_init_special_input_src(codec);
1902	alc_auto_init_std(codec);
1903
1904	alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
1905
1906	snd_hda_jack_report_sync(codec);
1907
1908	hda_call_check_power_status(codec, 0x01);
1909	return 0;
1910}
1911
1912static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
1913{
1914	struct alc_spec *spec = codec->spec;
1915
1916	if (spec->unsol_event)
1917		spec->unsol_event(codec, res);
1918}
1919
1920#ifdef CONFIG_SND_HDA_POWER_SAVE
1921static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1922{
1923	struct alc_spec *spec = codec->spec;
1924	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
1925}
1926#endif
1927
1928/*
1929 * Analog playback callbacks
1930 */
1931static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo,
1932				    struct hda_codec *codec,
1933				    struct snd_pcm_substream *substream)
1934{
1935	struct alc_spec *spec = codec->spec;
1936	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1937					     hinfo);
1938}
1939
1940static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1941				       struct hda_codec *codec,
1942				       unsigned int stream_tag,
1943				       unsigned int format,
1944				       struct snd_pcm_substream *substream)
1945{
1946	struct alc_spec *spec = codec->spec;
1947	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
1948						stream_tag, format, substream);
1949}
1950
1951static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1952				       struct hda_codec *codec,
1953				       struct snd_pcm_substream *substream)
1954{
1955	struct alc_spec *spec = codec->spec;
1956	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1957}
1958
1959/*
1960 * Digital out
1961 */
1962static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1963					struct hda_codec *codec,
1964					struct snd_pcm_substream *substream)
1965{
1966	struct alc_spec *spec = codec->spec;
1967	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1968}
1969
1970static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1971					   struct hda_codec *codec,
1972					   unsigned int stream_tag,
1973					   unsigned int format,
1974					   struct snd_pcm_substream *substream)
1975{
1976	struct alc_spec *spec = codec->spec;
1977	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1978					     stream_tag, format, substream);
1979}
1980
1981static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1982					   struct hda_codec *codec,
1983					   struct snd_pcm_substream *substream)
1984{
1985	struct alc_spec *spec = codec->spec;
1986	return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1987}
1988
1989static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1990					 struct hda_codec *codec,
1991					 struct snd_pcm_substream *substream)
1992{
1993	struct alc_spec *spec = codec->spec;
1994	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1995}
1996
1997/*
1998 * Analog capture
1999 */
2000static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2001				      struct hda_codec *codec,
2002				      unsigned int stream_tag,
2003				      unsigned int format,
2004				      struct snd_pcm_substream *substream)
2005{
2006	struct alc_spec *spec = codec->spec;
2007
2008	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2009				   stream_tag, 0, format);
2010	return 0;
2011}
2012
2013static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2014				      struct hda_codec *codec,
2015				      struct snd_pcm_substream *substream)
2016{
2017	struct alc_spec *spec = codec->spec;
2018
2019	snd_hda_codec_cleanup_stream(codec,
2020				     spec->adc_nids[substream->number + 1]);
2021	return 0;
2022}
2023
2024/* analog capture with dynamic dual-adc changes */
2025static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2026				       struct hda_codec *codec,
2027				       unsigned int stream_tag,
2028				       unsigned int format,
2029				       struct snd_pcm_substream *substream)
2030{
2031	struct alc_spec *spec = codec->spec;
2032	spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]];
2033	spec->cur_adc_stream_tag = stream_tag;
2034	spec->cur_adc_format = format;
2035	snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
2036	return 0;
2037}
2038
2039static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2040				       struct hda_codec *codec,
2041				       struct snd_pcm_substream *substream)
2042{
2043	struct alc_spec *spec = codec->spec;
2044	snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
2045	spec->cur_adc = 0;
2046	return 0;
2047}
2048
2049static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = {
2050	.substreams = 1,
2051	.channels_min = 2,
2052	.channels_max = 2,
2053	.nid = 0, /* fill later */
2054	.ops = {
2055		.prepare = dyn_adc_capture_pcm_prepare,
2056		.cleanup = dyn_adc_capture_pcm_cleanup
2057	},
2058};
2059
2060/*
2061 */
2062static const struct hda_pcm_stream alc_pcm_analog_playback = {
2063	.substreams = 1,
2064	.channels_min = 2,
2065	.channels_max = 8,
2066	/* NID is set in alc_build_pcms */
2067	.ops = {
2068		.open = alc_playback_pcm_open,
2069		.prepare = alc_playback_pcm_prepare,
2070		.cleanup = alc_playback_pcm_cleanup
2071	},
2072};
2073
2074static const struct hda_pcm_stream alc_pcm_analog_capture = {
2075	.substreams = 1,
2076	.channels_min = 2,
2077	.channels_max = 2,
2078	/* NID is set in alc_build_pcms */
2079};
2080
2081static const struct hda_pcm_stream alc_pcm_analog_alt_playback = {
2082	.substreams = 1,
2083	.channels_min = 2,
2084	.channels_max = 2,
2085	/* NID is set in alc_build_pcms */
2086};
2087
2088static const struct hda_pcm_stream alc_pcm_analog_alt_capture = {
2089	.substreams = 2, /* can be overridden */
2090	.channels_min = 2,
2091	.channels_max = 2,
2092	/* NID is set in alc_build_pcms */
2093	.ops = {
2094		.prepare = alc_alt_capture_pcm_prepare,
2095		.cleanup = alc_alt_capture_pcm_cleanup
2096	},
2097};
2098
2099static const struct hda_pcm_stream alc_pcm_digital_playback = {
2100	.substreams = 1,
2101	.channels_min = 2,
2102	.channels_max = 2,
2103	/* NID is set in alc_build_pcms */
2104	.ops = {
2105		.open = alc_dig_playback_pcm_open,
2106		.close = alc_dig_playback_pcm_close,
2107		.prepare = alc_dig_playback_pcm_prepare,
2108		.cleanup = alc_dig_playback_pcm_cleanup
2109	},
2110};
2111
2112static const struct hda_pcm_stream alc_pcm_digital_capture = {
2113	.substreams = 1,
2114	.channels_min = 2,
2115	.channels_max = 2,
2116	/* NID is set in alc_build_pcms */
2117};
2118
2119/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2120static const struct hda_pcm_stream alc_pcm_null_stream = {
2121	.substreams = 0,
2122	.channels_min = 0,
2123	.channels_max = 0,
2124};
2125
2126static int alc_build_pcms(struct hda_codec *codec)
2127{
2128	struct alc_spec *spec = codec->spec;
2129	struct hda_pcm *info = spec->pcm_rec;
2130	const struct hda_pcm_stream *p;
2131	bool have_multi_adcs;
2132	int i;
2133
2134	codec->num_pcms = 1;
2135	codec->pcm_info = info;
2136
2137	if (spec->no_analog)
2138		goto skip_analog;
2139
2140	snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
2141		 "%s Analog", codec->chip_name);
2142	info->name = spec->stream_name_analog;
2143
2144	if (spec->multiout.num_dacs > 0) {
2145		p = spec->stream_analog_playback;
2146		if (!p)
2147			p = &alc_pcm_analog_playback;
2148		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
2149		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2150	}
2151	if (spec->adc_nids) {
2152		p = spec->stream_analog_capture;
2153		if (!p) {
2154			if (spec->dyn_adc_switch)
2155				p = &dyn_adc_pcm_analog_capture;
2156			else
2157				p = &alc_pcm_analog_capture;
2158		}
2159		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
2160		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2161	}
2162
2163	if (spec->channel_mode) {
2164		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2165		for (i = 0; i < spec->num_channel_mode; i++) {
2166			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2167				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2168			}
2169		}
2170	}
2171
2172 skip_analog:
2173	/* SPDIF for stream index #1 */
2174	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2175		snprintf(spec->stream_name_digital,
2176			 sizeof(spec->stream_name_digital),
2177			 "%s Digital", codec->chip_name);
2178		codec->num_pcms = 2;
2179	        codec->slave_dig_outs = spec->multiout.slave_dig_outs;
2180		info = spec->pcm_rec + 1;
2181		info->name = spec->stream_name_digital;
2182		if (spec->dig_out_type)
2183			info->pcm_type = spec->dig_out_type;
2184		else
2185			info->pcm_type = HDA_PCM_TYPE_SPDIF;
2186		if (spec->multiout.dig_out_nid) {
2187			p = spec->stream_digital_playback;
2188			if (!p)
2189				p = &alc_pcm_digital_playback;
2190			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
2191			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2192		}
2193		if (spec->dig_in_nid) {
2194			p = spec->stream_digital_capture;
2195			if (!p)
2196				p = &alc_pcm_digital_capture;
2197			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
2198			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2199		}
2200		/* FIXME: do we need this for all Realtek codec models? */
2201		codec->spdif_status_reset = 1;
2202	}
2203
2204	if (spec->no_analog)
2205		return 0;
2206
2207	/* If the use of more than one ADC is requested for the current
2208	 * model, configure a second analog capture-only PCM.
2209	 */
2210	have_multi_adcs = (spec->num_adc_nids > 1) &&
2211		!spec->dyn_adc_switch && !spec->auto_mic &&
2212		(!spec->input_mux || spec->input_mux->num_items > 1);
2213	/* Additional Analaog capture for index #2 */
2214	if (spec->alt_dac_nid || have_multi_adcs) {
2215		codec->num_pcms = 3;
2216		info = spec->pcm_rec + 2;
2217		info->name = spec->stream_name_analog;
2218		if (spec->alt_dac_nid) {
2219			p = spec->stream_analog_alt_playback;
2220			if (!p)
2221				p = &alc_pcm_analog_alt_playback;
2222			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
2223			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2224				spec->alt_dac_nid;
2225		} else {
2226			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2227				alc_pcm_null_stream;
2228			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2229		}
2230		if (have_multi_adcs) {
2231			p = spec->stream_analog_alt_capture;
2232			if (!p)
2233				p = &alc_pcm_analog_alt_capture;
2234			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
2235			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2236				spec->adc_nids[1];
2237			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2238				spec->num_adc_nids - 1;
2239		} else {
2240			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2241				alc_pcm_null_stream;
2242			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2243		}
2244	}
2245
2246	return 0;
2247}
2248
2249static inline void alc_shutup(struct hda_codec *codec)
2250{
2251	struct alc_spec *spec = codec->spec;
2252
2253	if (spec && spec->shutup)
2254		spec->shutup(codec);
2255	snd_hda_shutup_pins(codec);
 
2256}
2257
2258static void alc_free_kctls(struct hda_codec *codec)
2259{
2260	struct alc_spec *spec = codec->spec;
2261
2262	if (spec->kctls.list) {
2263		struct snd_kcontrol_new *kctl = spec->kctls.list;
2264		int i;
2265		for (i = 0; i < spec->kctls.used; i++)
2266			kfree(kctl[i].name);
2267	}
2268	snd_array_free(&spec->kctls);
2269}
2270
2271static void alc_free_bind_ctls(struct hda_codec *codec)
2272{
2273	struct alc_spec *spec = codec->spec;
2274	if (spec->bind_ctls.list) {
2275		struct hda_bind_ctls **ctl = spec->bind_ctls.list;
2276		int i;
2277		for (i = 0; i < spec->bind_ctls.used; i++)
2278			kfree(ctl[i]);
2279	}
2280	snd_array_free(&spec->bind_ctls);
2281}
2282
2283static void alc_free(struct hda_codec *codec)
2284{
2285	struct alc_spec *spec = codec->spec;
2286
2287	if (!spec)
2288		return;
2289
2290	alc_shutup(codec);
2291	alc_free_kctls(codec);
2292	alc_free_bind_ctls(codec);
2293	snd_hda_gen_free(&spec->gen);
2294	kfree(spec);
2295	snd_hda_detach_beep_device(codec);
2296}
2297
2298#ifdef CONFIG_SND_HDA_POWER_SAVE
2299static void alc_power_eapd(struct hda_codec *codec)
2300{
2301	alc_auto_setup_eapd(codec, false);
2302}
2303
2304static int alc_suspend(struct hda_codec *codec, pm_message_t state)
2305{
2306	struct alc_spec *spec = codec->spec;
2307	alc_shutup(codec);
2308	if (spec && spec->power_hook)
2309		spec->power_hook(codec);
2310	return 0;
2311}
2312#endif
2313
2314#ifdef CONFIG_PM
2315static int alc_resume(struct hda_codec *codec)
2316{
2317	msleep(150); /* to avoid pop noise */
 
 
 
2318	codec->patch_ops.init(codec);
2319	snd_hda_codec_resume_amp(codec);
2320	snd_hda_codec_resume_cache(codec);
 
2321	hda_call_check_power_status(codec, 0x01);
2322	return 0;
2323}
2324#endif
2325
2326/*
2327 */
2328static const struct hda_codec_ops alc_patch_ops = {
2329	.build_controls = alc_build_controls,
2330	.build_pcms = alc_build_pcms,
2331	.init = alc_init,
2332	.free = alc_free,
2333	.unsol_event = alc_unsol_event,
2334#ifdef CONFIG_PM
2335	.resume = alc_resume,
2336#endif
2337#ifdef CONFIG_SND_HDA_POWER_SAVE
2338	.suspend = alc_suspend,
2339	.check_power_status = alc_check_power_status,
2340#endif
2341	.reboot_notify = alc_shutup,
2342};
2343
 
2344/* replace the codec chip_name with the given string */
2345static int alc_codec_rename(struct hda_codec *codec, const char *name)
2346{
2347	kfree(codec->chip_name);
2348	codec->chip_name = kstrdup(name, GFP_KERNEL);
2349	if (!codec->chip_name) {
2350		alc_free(codec);
2351		return -ENOMEM;
2352	}
2353	return 0;
2354}
2355
2356/*
2357 * Rename codecs appropriately from COEF value
2358 */
2359struct alc_codec_rename_table {
2360	unsigned int vendor_id;
2361	unsigned short coef_mask;
2362	unsigned short coef_bits;
2363	const char *name;
2364};
2365
 
 
 
 
 
 
 
2366static struct alc_codec_rename_table rename_tbl[] = {
2367	{ 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
2368	{ 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
2369	{ 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
2370	{ 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
2371	{ 0x10ec0269, 0xffff, 0xa023, "ALC259" },
2372	{ 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
2373	{ 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
2374	{ 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
2375	{ 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
2376	{ 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
2377	{ 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
2378	{ 0x10ec0899, 0x2000, 0x2000, "ALC899" },
2379	{ 0x10ec0892, 0xffff, 0x8020, "ALC661" },
2380	{ 0x10ec0892, 0xffff, 0x8011, "ALC661" },
2381	{ 0x10ec0892, 0xffff, 0x4011, "ALC656" },
2382	{ } /* terminator */
2383};
2384
 
 
 
 
 
 
 
 
 
 
2385static int alc_codec_rename_from_preset(struct hda_codec *codec)
2386{
2387	const struct alc_codec_rename_table *p;
 
2388
2389	for (p = rename_tbl; p->vendor_id; p++) {
2390		if (p->vendor_id != codec->vendor_id)
2391			continue;
2392		if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
2393			return alc_codec_rename(codec, p->name);
2394	}
2395	return 0;
2396}
2397
2398/*
2399 * Automatic parse of I/O pins from the BIOS configuration
2400 */
2401
2402enum {
2403	ALC_CTL_WIDGET_VOL,
2404	ALC_CTL_WIDGET_MUTE,
2405	ALC_CTL_BIND_MUTE,
2406	ALC_CTL_BIND_VOL,
2407	ALC_CTL_BIND_SW,
2408};
2409static const struct snd_kcontrol_new alc_control_templates[] = {
2410	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2411	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2412	HDA_BIND_MUTE(NULL, 0, 0, 0),
2413	HDA_BIND_VOL(NULL, 0),
2414	HDA_BIND_SW(NULL, 0),
2415};
2416
2417/* add dynamic controls */
2418static int add_control(struct alc_spec *spec, int type, const char *name,
2419		       int cidx, unsigned long val)
2420{
2421	struct snd_kcontrol_new *knew;
2422
2423	knew = alc_kcontrol_new(spec);
2424	if (!knew)
2425		return -ENOMEM;
2426	*knew = alc_control_templates[type];
2427	knew->name = kstrdup(name, GFP_KERNEL);
2428	if (!knew->name)
2429		return -ENOMEM;
2430	knew->index = cidx;
2431	if (get_amp_nid_(val))
2432		knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2433	knew->private_value = val;
2434	return 0;
2435}
2436
2437static int add_control_with_pfx(struct alc_spec *spec, int type,
2438				const char *pfx, const char *dir,
2439				const char *sfx, int cidx, unsigned long val)
2440{
2441	char name[32];
2442	snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
2443	return add_control(spec, type, name, cidx, val);
2444}
2445
2446#define add_pb_vol_ctrl(spec, type, pfx, val)			\
2447	add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
2448#define add_pb_sw_ctrl(spec, type, pfx, val)			\
2449	add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
2450#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val)			\
2451	add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
2452#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val)			\
2453	add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
2454
2455static const char * const channel_name[4] = {
2456	"Front", "Surround", "CLFE", "Side"
2457};
2458
2459static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
2460					bool can_be_master, int *index)
2461{
2462	struct auto_pin_cfg *cfg = &spec->autocfg;
2463
2464	*index = 0;
2465	if (cfg->line_outs == 1 && !spec->multi_ios &&
2466	    !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
2467		return "Master";
2468
2469	switch (cfg->line_out_type) {
2470	case AUTO_PIN_SPEAKER_OUT:
2471		if (cfg->line_outs == 1)
2472			return "Speaker";
2473		if (cfg->line_outs == 2)
2474			return ch ? "Bass Speaker" : "Speaker";
2475		break;
2476	case AUTO_PIN_HP_OUT:
2477		/* for multi-io case, only the primary out */
2478		if (ch && spec->multi_ios)
2479			break;
2480		*index = ch;
2481		return "Headphone";
2482	default:
2483		if (cfg->line_outs == 1 && !spec->multi_ios)
2484			return "PCM";
2485		break;
2486	}
2487	if (snd_BUG_ON(ch >= ARRAY_SIZE(channel_name)))
2488		return "PCM";
2489
2490	return channel_name[ch];
2491}
2492
2493#ifdef CONFIG_SND_HDA_POWER_SAVE
2494/* add the powersave loopback-list entry */
2495static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx)
2496{
2497	struct hda_amp_list *list;
2498
2499	if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
2500		return;
2501	list = spec->loopback_list + spec->num_loopbacks;
2502	list->nid = mix;
2503	list->dir = HDA_INPUT;
2504	list->idx = idx;
2505	spec->num_loopbacks++;
2506	spec->loopback.amplist = spec->loopback_list;
2507}
2508#else
2509#define add_loopback_list(spec, mix, idx) /* NOP */
2510#endif
2511
2512/* create input playback/capture controls for the given pin */
2513static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
2514			    const char *ctlname, int ctlidx,
2515			    int idx, hda_nid_t mix_nid)
2516{
2517	int err;
2518
2519	err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
2520			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
2521	if (err < 0)
2522		return err;
2523	err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
2524			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
2525	if (err < 0)
2526		return err;
2527	add_loopback_list(spec, mix_nid, idx);
2528	return 0;
2529}
2530
2531static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
2532{
2533	unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2534	return (pincap & AC_PINCAP_IN) != 0;
2535}
2536
2537/* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */
2538static int alc_auto_fill_adc_caps(struct hda_codec *codec)
2539{
2540	struct alc_spec *spec = codec->spec;
2541	hda_nid_t nid;
2542	hda_nid_t *adc_nids = spec->private_adc_nids;
2543	hda_nid_t *cap_nids = spec->private_capsrc_nids;
2544	int max_nums = ARRAY_SIZE(spec->private_adc_nids);
2545	int i, nums = 0;
2546
2547	nid = codec->start_nid;
2548	for (i = 0; i < codec->num_nodes; i++, nid++) {
2549		hda_nid_t src;
2550		unsigned int caps = get_wcaps(codec, nid);
2551		int type = get_wcaps_type(caps);
2552
2553		if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
2554			continue;
2555		adc_nids[nums] = nid;
2556		cap_nids[nums] = nid;
2557		src = nid;
2558		for (;;) {
2559			int n;
2560			type = get_wcaps_type(get_wcaps(codec, src));
2561			if (type == AC_WID_PIN)
2562				break;
2563			if (type == AC_WID_AUD_SEL) {
2564				cap_nids[nums] = src;
2565				break;
2566			}
2567			n = snd_hda_get_num_conns(codec, src);
2568			if (n > 1) {
2569				cap_nids[nums] = src;
2570				break;
2571			} else if (n != 1)
2572				break;
2573			if (snd_hda_get_connections(codec, src, &src, 1) != 1)
2574				break;
2575		}
2576		if (++nums >= max_nums)
2577			break;
2578	}
2579	spec->adc_nids = spec->private_adc_nids;
2580	spec->capsrc_nids = spec->private_capsrc_nids;
2581	spec->num_adc_nids = nums;
2582	return nums;
2583}
2584
2585/* create playback/capture controls for input pins */
2586static int alc_auto_create_input_ctls(struct hda_codec *codec)
2587{
2588	struct alc_spec *spec = codec->spec;
2589	const struct auto_pin_cfg *cfg = &spec->autocfg;
2590	hda_nid_t mixer = spec->mixer_nid;
2591	struct hda_input_mux *imux = &spec->private_imux[0];
2592	int num_adcs;
2593	int i, c, err, idx, type_idx = 0;
2594	const char *prev_label = NULL;
2595
2596	num_adcs = alc_auto_fill_adc_caps(codec);
2597	if (num_adcs < 0)
2598		return 0;
2599
2600	for (i = 0; i < cfg->num_inputs; i++) {
2601		hda_nid_t pin;
2602		const char *label;
2603
2604		pin = cfg->inputs[i].pin;
2605		if (!alc_is_input_pin(codec, pin))
2606			continue;
2607
2608		label = hda_get_autocfg_input_label(codec, cfg, i);
2609		if (spec->shared_mic_hp && !strcmp(label, "Misc"))
2610			label = "Headphone Mic";
2611		if (prev_label && !strcmp(label, prev_label))
2612			type_idx++;
2613		else
2614			type_idx = 0;
2615		prev_label = label;
2616
2617		if (mixer) {
2618			idx = get_connection_index(codec, mixer, pin);
2619			if (idx >= 0) {
2620				err = new_analog_input(spec, pin,
2621						       label, type_idx,
2622						       idx, mixer);
2623				if (err < 0)
2624					return err;
2625			}
2626		}
2627
2628		for (c = 0; c < num_adcs; c++) {
2629			hda_nid_t cap = get_capsrc(spec, c);
2630			idx = get_connection_index(codec, cap, pin);
2631			if (idx >= 0) {
2632				spec->imux_pins[imux->num_items] = pin;
2633				snd_hda_add_imux_item(imux, label, idx, NULL);
2634				break;
2635			}
2636		}
2637	}
2638
2639	spec->num_mux_defs = 1;
2640	spec->input_mux = imux;
2641
2642	return 0;
2643}
2644
2645/* create a shared input with the headphone out */
2646static int alc_auto_create_shared_input(struct hda_codec *codec)
2647{
2648	struct alc_spec *spec = codec->spec;
2649	struct auto_pin_cfg *cfg = &spec->autocfg;
2650	unsigned int defcfg;
2651	hda_nid_t nid;
2652
2653	/* only one internal input pin? */
2654	if (cfg->num_inputs != 1)
2655		return 0;
2656	defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin);
2657	if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
2658		return 0;
2659
2660	if (cfg->hp_outs == 1 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
2661		nid = cfg->hp_pins[0]; /* OK, we have a single HP-out */
2662	else if (cfg->line_outs == 1 && cfg->line_out_type == AUTO_PIN_HP_OUT)
2663		nid = cfg->line_out_pins[0]; /* OK, we have a single line-out */
2664	else
2665		return 0; /* both not available */
2666
2667	if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN))
2668		return 0; /* no input */
2669
2670	cfg->inputs[1].pin = nid;
2671	cfg->inputs[1].type = AUTO_PIN_MIC;
2672	cfg->num_inputs = 2;
2673	spec->shared_mic_hp = 1;
2674	snd_printdd("realtek: Enable shared I/O jack on NID 0x%x\n", nid);
2675	return 0;
2676}
2677
2678static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
2679			       unsigned int pin_type)
2680{
2681	snd_hda_set_pin_ctl(codec, nid, pin_type);
2682	/* unmute pin */
2683	if (nid_has_mute(codec, nid, HDA_OUTPUT))
2684		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2685			    AMP_OUT_UNMUTE);
2686}
2687
2688static int get_pin_type(int line_out_type)
2689{
2690	if (line_out_type == AUTO_PIN_HP_OUT)
2691		return PIN_HP;
2692	else
2693		return PIN_OUT;
2694}
2695
2696static void alc_auto_init_analog_input(struct hda_codec *codec)
2697{
2698	struct alc_spec *spec = codec->spec;
2699	struct auto_pin_cfg *cfg = &spec->autocfg;
2700	int i;
2701
2702	for (i = 0; i < cfg->num_inputs; i++) {
2703		hda_nid_t nid = cfg->inputs[i].pin;
2704		if (alc_is_input_pin(codec, nid)) {
2705			alc_set_input_pin(codec, nid, cfg->inputs[i].type);
2706			if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
2707				snd_hda_codec_write(codec, nid, 0,
2708						    AC_VERB_SET_AMP_GAIN_MUTE,
2709						    AMP_OUT_MUTE);
2710		}
2711	}
2712
2713	/* mute all loopback inputs */
2714	if (spec->mixer_nid) {
2715		int nums = snd_hda_get_num_conns(codec, spec->mixer_nid);
2716		for (i = 0; i < nums; i++)
2717			snd_hda_codec_write(codec, spec->mixer_nid, 0,
2718					    AC_VERB_SET_AMP_GAIN_MUTE,
2719					    AMP_IN_MUTE(i));
2720	}
2721}
2722
2723/* convert from MIX nid to DAC */
2724static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
2725{
2726	hda_nid_t list[5];
2727	int i, num;
2728
2729	if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_AUD_OUT)
2730		return nid;
2731	num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
2732	for (i = 0; i < num; i++) {
2733		if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
2734			return list[i];
2735	}
2736	return 0;
2737}
2738
2739/* go down to the selector widget before the mixer */
2740static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
2741{
2742	hda_nid_t srcs[5];
2743	int num = snd_hda_get_connections(codec, pin, srcs,
2744					  ARRAY_SIZE(srcs));
2745	if (num != 1 ||
2746	    get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
2747		return pin;
2748	return srcs[0];
2749}
2750
2751/* get MIX nid connected to the given pin targeted to DAC */
2752static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
2753				   hda_nid_t dac)
2754{
2755	hda_nid_t mix[5];
2756	int i, num;
2757
2758	pin = alc_go_down_to_selector(codec, pin);
2759	num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2760	for (i = 0; i < num; i++) {
2761		if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
2762			return mix[i];
2763	}
2764	return 0;
2765}
2766
2767/* select the connection from pin to DAC if needed */
2768static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2769			       hda_nid_t dac)
2770{
2771	hda_nid_t mix[5];
2772	int i, num;
2773
2774	pin = alc_go_down_to_selector(codec, pin);
2775	num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2776	if (num < 2)
2777		return 0;
2778	for (i = 0; i < num; i++) {
2779		if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
2780			snd_hda_codec_update_cache(codec, pin, 0,
2781						   AC_VERB_SET_CONNECT_SEL, i);
2782			return 0;
2783		}
2784	}
2785	return 0;
2786}
2787
2788static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
2789{
2790	struct alc_spec *spec = codec->spec;
2791	int i;
2792	if (found_in_nid_list(nid, spec->multiout.dac_nids,
2793			      ARRAY_SIZE(spec->private_dac_nids)) ||
2794	    found_in_nid_list(nid, spec->multiout.hp_out_nid,
2795			      ARRAY_SIZE(spec->multiout.hp_out_nid)) ||
2796	    found_in_nid_list(nid, spec->multiout.extra_out_nid,
2797			      ARRAY_SIZE(spec->multiout.extra_out_nid)))
2798		return true;
2799	for (i = 0; i < spec->multi_ios; i++) {
2800		if (spec->multi_io[i].dac == nid)
2801			return true;
2802	}
2803	return false;
2804}
2805
2806/* look for an empty DAC slot */
2807static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2808{
2809	hda_nid_t srcs[5];
2810	int i, num;
2811
2812	pin = alc_go_down_to_selector(codec, pin);
2813	num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
2814	for (i = 0; i < num; i++) {
2815		hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
2816		if (!nid)
2817			continue;
2818		if (!alc_is_dac_already_used(codec, nid))
2819			return nid;
2820	}
2821	return 0;
2822}
2823
2824/* check whether the DAC is reachable from the pin */
2825static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
2826				      hda_nid_t pin, hda_nid_t dac)
2827{
2828	hda_nid_t srcs[5];
2829	int i, num;
2830
2831	if (!pin || !dac)
2832		return false;
2833	pin = alc_go_down_to_selector(codec, pin);
2834	num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
2835	for (i = 0; i < num; i++) {
2836		hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
2837		if (nid == dac)
2838			return true;
2839	}
2840	return false;
2841}
2842
2843static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
2844{
2845	struct alc_spec *spec = codec->spec;
2846	hda_nid_t sel = alc_go_down_to_selector(codec, pin);
2847	hda_nid_t nid, nid_found, srcs[5];
2848	int i, num = snd_hda_get_connections(codec, sel, srcs,
2849					  ARRAY_SIZE(srcs));
2850	if (num == 1)
2851		return alc_auto_look_for_dac(codec, pin);
2852	nid_found = 0;
2853	for (i = 0; i < num; i++) {
2854		if (srcs[i] == spec->mixer_nid)
2855			continue;
2856		nid = alc_auto_mix_to_dac(codec, srcs[i]);
2857		if (nid && !alc_is_dac_already_used(codec, nid)) {
2858			if (nid_found)
2859				return 0;
2860			nid_found = nid;
2861		}
2862	}
2863	return nid_found;
2864}
2865
2866/* mark up volume and mute control NIDs: used during badness parsing and
2867 * at creating actual controls
2868 */
2869static inline unsigned int get_ctl_pos(unsigned int data)
2870{
2871	hda_nid_t nid = get_amp_nid_(data);
2872	unsigned int dir;
2873	if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
2874		return 0;
2875	dir = get_amp_direction_(data);
2876	return (nid << 1) | dir;
2877}
2878
2879#define is_ctl_used(bits, data) \
2880	test_bit(get_ctl_pos(data), bits)
2881#define mark_ctl_usage(bits, data) \
2882	set_bit(get_ctl_pos(data), bits)
2883
2884static void clear_vol_marks(struct hda_codec *codec)
2885{
2886	struct alc_spec *spec = codec->spec;
2887	memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls));
2888	memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls));
2889}
2890
2891/* badness definition */
2892enum {
2893	/* No primary DAC is found for the main output */
2894	BAD_NO_PRIMARY_DAC = 0x10000,
2895	/* No DAC is found for the extra output */
2896	BAD_NO_DAC = 0x4000,
2897	/* No possible multi-ios */
2898	BAD_MULTI_IO = 0x103,
2899	/* No individual DAC for extra output */
2900	BAD_NO_EXTRA_DAC = 0x102,
2901	/* No individual DAC for extra surrounds */
2902	BAD_NO_EXTRA_SURR_DAC = 0x101,
2903	/* Primary DAC shared with main surrounds */
2904	BAD_SHARED_SURROUND = 0x100,
2905	/* Primary DAC shared with main CLFE */
2906	BAD_SHARED_CLFE = 0x10,
2907	/* Primary DAC shared with extra surrounds */
2908	BAD_SHARED_EXTRA_SURROUND = 0x10,
2909	/* Volume widget is shared */
2910	BAD_SHARED_VOL = 0x10,
2911};
2912
2913static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
2914					   hda_nid_t pin, hda_nid_t dac);
2915static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
2916					  hda_nid_t pin, hda_nid_t dac);
2917
2918static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
2919				   hda_nid_t dac)
2920{
2921	struct alc_spec *spec = codec->spec;
2922	hda_nid_t nid;
2923	unsigned int val;
2924	int badness = 0;
2925
2926	nid = alc_look_for_out_vol_nid(codec, pin, dac);
2927	if (nid) {
2928		val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
2929		if (is_ctl_used(spec->vol_ctls, nid))
2930			badness += BAD_SHARED_VOL;
2931		else
2932			mark_ctl_usage(spec->vol_ctls, val);
2933	} else
2934		badness += BAD_SHARED_VOL;
2935	nid = alc_look_for_out_mute_nid(codec, pin, dac);
2936	if (nid) {
2937		unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
2938		if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT)
2939			val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
2940		else
2941			val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
2942		if (is_ctl_used(spec->sw_ctls, val))
2943			badness += BAD_SHARED_VOL;
2944		else
2945			mark_ctl_usage(spec->sw_ctls, val);
2946	} else
2947		badness += BAD_SHARED_VOL;
2948	return badness;
2949}
2950
2951struct badness_table {
2952	int no_primary_dac;	/* no primary DAC */
2953	int no_dac;		/* no secondary DACs */
2954	int shared_primary;	/* primary DAC is shared with main output */
2955	int shared_surr;	/* secondary DAC shared with main or primary */
2956	int shared_clfe;	/* third DAC shared with main or primary */
2957	int shared_surr_main;	/* secondary DAC sahred with main/DAC0 */
2958};
2959
2960static struct badness_table main_out_badness = {
2961	.no_primary_dac = BAD_NO_PRIMARY_DAC,
2962	.no_dac = BAD_NO_DAC,
2963	.shared_primary = BAD_NO_PRIMARY_DAC,
2964	.shared_surr = BAD_SHARED_SURROUND,
2965	.shared_clfe = BAD_SHARED_CLFE,
2966	.shared_surr_main = BAD_SHARED_SURROUND,
2967};
2968
2969static struct badness_table extra_out_badness = {
2970	.no_primary_dac = BAD_NO_DAC,
2971	.no_dac = BAD_NO_DAC,
2972	.shared_primary = BAD_NO_EXTRA_DAC,
2973	.shared_surr = BAD_SHARED_EXTRA_SURROUND,
2974	.shared_clfe = BAD_SHARED_EXTRA_SURROUND,
2975	.shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
2976};
2977
2978/* try to assign DACs to pins and return the resultant badness */
2979static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
2980			      const hda_nid_t *pins, hda_nid_t *dacs,
2981			      const struct badness_table *bad)
2982{
2983	struct alc_spec *spec = codec->spec;
2984	struct auto_pin_cfg *cfg = &spec->autocfg;
2985	int i, j;
2986	int badness = 0;
2987	hda_nid_t dac;
2988
2989	if (!num_outs)
2990		return 0;
2991
2992	for (i = 0; i < num_outs; i++) {
2993		hda_nid_t pin = pins[i];
2994		if (!dacs[i])
2995			dacs[i] = alc_auto_look_for_dac(codec, pin);
2996		if (!dacs[i] && !i) {
2997			for (j = 1; j < num_outs; j++) {
2998				if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) {
2999					dacs[0] = dacs[j];
3000					dacs[j] = 0;
3001					break;
3002				}
3003			}
3004		}
3005		dac = dacs[i];
3006		if (!dac) {
3007			if (alc_auto_is_dac_reachable(codec, pin, dacs[0]))
3008				dac = dacs[0];
3009			else if (cfg->line_outs > i &&
3010				 alc_auto_is_dac_reachable(codec, pin,
3011					spec->private_dac_nids[i]))
3012				dac = spec->private_dac_nids[i];
3013			if (dac) {
3014				if (!i)
3015					badness += bad->shared_primary;
3016				else if (i == 1)
3017					badness += bad->shared_surr;
3018				else
3019					badness += bad->shared_clfe;
3020			} else if (alc_auto_is_dac_reachable(codec, pin,
3021					spec->private_dac_nids[0])) {
3022				dac = spec->private_dac_nids[0];
3023				badness += bad->shared_surr_main;
3024			} else if (!i)
3025				badness += bad->no_primary_dac;
3026			else
3027				badness += bad->no_dac;
3028		}
3029		if (dac)
3030			badness += eval_shared_vol_badness(codec, pin, dac);
3031	}
3032
3033	return badness;
3034}
3035
3036static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3037				   hda_nid_t reference_pin,
3038				   bool hardwired, int offset);
3039
3040static bool alc_map_singles(struct hda_codec *codec, int outs,
3041			    const hda_nid_t *pins, hda_nid_t *dacs)
3042{
3043	int i;
3044	bool found = false;
3045	for (i = 0; i < outs; i++) {
3046		if (dacs[i])
3047			continue;
3048		dacs[i] = get_dac_if_single(codec, pins[i]);
3049		if (dacs[i])
3050			found = true;
3051	}
3052	return found;
3053}
3054
3055/* fill in the dac_nids table from the parsed pin configuration */
3056static int fill_and_eval_dacs(struct hda_codec *codec,
3057			      bool fill_hardwired,
3058			      bool fill_mio_first)
3059{
3060	struct alc_spec *spec = codec->spec;
3061	struct auto_pin_cfg *cfg = &spec->autocfg;
3062	int i, err, badness;
3063
3064	/* set num_dacs once to full for alc_auto_look_for_dac() */
3065	spec->multiout.num_dacs = cfg->line_outs;
3066	spec->multiout.dac_nids = spec->private_dac_nids;
3067	memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
3068	memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid));
3069	memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid));
3070	spec->multi_ios = 0;
3071	clear_vol_marks(codec);
3072	badness = 0;
3073
3074	/* fill hard-wired DACs first */
3075	if (fill_hardwired) {
3076		bool mapped;
3077		do {
3078			mapped = alc_map_singles(codec, cfg->line_outs,
3079						 cfg->line_out_pins,
3080						 spec->private_dac_nids);
3081			mapped |= alc_map_singles(codec, cfg->hp_outs,
3082						  cfg->hp_pins,
3083						  spec->multiout.hp_out_nid);
3084			mapped |= alc_map_singles(codec, cfg->speaker_outs,
3085						  cfg->speaker_pins,
3086						  spec->multiout.extra_out_nid);
3087			if (fill_mio_first && cfg->line_outs == 1 &&
3088			    cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3089				err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], true, 0);
3090				if (!err)
3091					mapped = true;
3092			}
3093		} while (mapped);
3094	}
3095
3096	badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins,
3097				      spec->private_dac_nids,
3098				      &main_out_badness);
3099
3100	/* re-count num_dacs and squash invalid entries */
3101	spec->multiout.num_dacs = 0;
3102	for (i = 0; i < cfg->line_outs; i++) {
3103		if (spec->private_dac_nids[i])
3104			spec->multiout.num_dacs++;
3105		else {
3106			memmove(spec->private_dac_nids + i,
3107				spec->private_dac_nids + i + 1,
3108				sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
3109			spec->private_dac_nids[cfg->line_outs - 1] = 0;
3110		}
3111	}
3112
3113	if (fill_mio_first &&
3114	    cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3115		/* try to fill multi-io first */
3116		err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
3117		if (err < 0)
3118			return err;
3119		/* we don't count badness at this stage yet */
3120	}
3121
3122	if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
3123		err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins,
3124					 spec->multiout.hp_out_nid,
3125					 &extra_out_badness);
3126		if (err < 0)
3127			return err;
3128		badness += err;
3129	}
3130	if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3131		err = alc_auto_fill_dacs(codec, cfg->speaker_outs,
3132					 cfg->speaker_pins,
3133					 spec->multiout.extra_out_nid,
3134					 &extra_out_badness);
3135		if (err < 0)
3136			return err;
3137		badness += err;
3138	}
3139	if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3140		err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
3141		if (err < 0)
3142			return err;
3143		badness += err;
3144	}
3145	if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
3146		/* try multi-ios with HP + inputs */
3147		int offset = 0;
3148		if (cfg->line_outs >= 3)
3149			offset = 1;
3150		err = alc_auto_fill_multi_ios(codec, cfg->hp_pins[0], false,
3151					      offset);
3152		if (err < 0)
3153			return err;
3154		badness += err;
3155	}
3156
3157	if (spec->multi_ios == 2) {
3158		for (i = 0; i < 2; i++)
3159			spec->private_dac_nids[spec->multiout.num_dacs++] =
3160				spec->multi_io[i].dac;
3161		spec->ext_channel_count = 2;
3162	} else if (spec->multi_ios) {
3163		spec->multi_ios = 0;
3164		badness += BAD_MULTI_IO;
3165	}
3166
3167	return badness;
3168}
3169
3170#define DEBUG_BADNESS
3171
3172#ifdef DEBUG_BADNESS
3173#define debug_badness	snd_printdd
3174#else
3175#define debug_badness(...)
3176#endif
3177
3178static void debug_show_configs(struct alc_spec *spec, struct auto_pin_cfg *cfg)
3179{
3180	debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3181		      cfg->line_out_pins[0], cfg->line_out_pins[1],
3182		      cfg->line_out_pins[2], cfg->line_out_pins[2],
3183		      spec->multiout.dac_nids[0],
3184		      spec->multiout.dac_nids[1],
3185		      spec->multiout.dac_nids[2],
3186		      spec->multiout.dac_nids[3]);
3187	if (spec->multi_ios > 0)
3188		debug_badness("multi_ios(%d) = %x/%x : %x/%x\n",
3189			      spec->multi_ios,
3190			      spec->multi_io[0].pin, spec->multi_io[1].pin,
3191			      spec->multi_io[0].dac, spec->multi_io[1].dac);
3192	debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3193		      cfg->hp_pins[0], cfg->hp_pins[1],
3194		      cfg->hp_pins[2], cfg->hp_pins[2],
3195		      spec->multiout.hp_out_nid[0],
3196		      spec->multiout.hp_out_nid[1],
3197		      spec->multiout.hp_out_nid[2],
3198		      spec->multiout.hp_out_nid[3]);
3199	debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3200		      cfg->speaker_pins[0], cfg->speaker_pins[1],
3201		      cfg->speaker_pins[2], cfg->speaker_pins[3],
3202		      spec->multiout.extra_out_nid[0],
3203		      spec->multiout.extra_out_nid[1],
3204		      spec->multiout.extra_out_nid[2],
3205		      spec->multiout.extra_out_nid[3]);
3206}
3207
3208static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3209{
3210	struct alc_spec *spec = codec->spec;
3211	struct auto_pin_cfg *cfg = &spec->autocfg;
3212	struct auto_pin_cfg *best_cfg;
3213	int best_badness = INT_MAX;
3214	int badness;
3215	bool fill_hardwired = true, fill_mio_first = true;
3216	bool best_wired = true, best_mio = true;
3217	bool hp_spk_swapped = false;
3218
3219	best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL);
3220	if (!best_cfg)
3221		return -ENOMEM;
3222	*best_cfg = *cfg;
3223
3224	for (;;) {
3225		badness = fill_and_eval_dacs(codec, fill_hardwired,
3226					     fill_mio_first);
3227		if (badness < 0) {
3228			kfree(best_cfg);
3229			return badness;
3230		}
3231		debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
3232			      cfg->line_out_type, fill_hardwired, fill_mio_first,
3233			      badness);
3234		debug_show_configs(spec, cfg);
3235		if (badness < best_badness) {
3236			best_badness = badness;
3237			*best_cfg = *cfg;
3238			best_wired = fill_hardwired;
3239			best_mio = fill_mio_first;
3240		}
3241		if (!badness)
3242			break;
3243		fill_mio_first = !fill_mio_first;
3244		if (!fill_mio_first)
3245			continue;
3246		fill_hardwired = !fill_hardwired;
3247		if (!fill_hardwired)
3248			continue;
3249		if (hp_spk_swapped)
3250			break;
3251		hp_spk_swapped = true;
3252		if (cfg->speaker_outs > 0 &&
3253		    cfg->line_out_type == AUTO_PIN_HP_OUT) {
3254			cfg->hp_outs = cfg->line_outs;
3255			memcpy(cfg->hp_pins, cfg->line_out_pins,
3256			       sizeof(cfg->hp_pins));
3257			cfg->line_outs = cfg->speaker_outs;
3258			memcpy(cfg->line_out_pins, cfg->speaker_pins,
3259			       sizeof(cfg->speaker_pins));
3260			cfg->speaker_outs = 0;
3261			memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
3262			cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
3263			fill_hardwired = true;
3264			continue;
3265		}
3266		if (cfg->hp_outs > 0 &&
3267		    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
3268			cfg->speaker_outs = cfg->line_outs;
3269			memcpy(cfg->speaker_pins, cfg->line_out_pins,
3270			       sizeof(cfg->speaker_pins));
3271			cfg->line_outs = cfg->hp_outs;
3272			memcpy(cfg->line_out_pins, cfg->hp_pins,
3273			       sizeof(cfg->hp_pins));
3274			cfg->hp_outs = 0;
3275			memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3276			cfg->line_out_type = AUTO_PIN_HP_OUT;
3277			fill_hardwired = true;
3278			continue;
3279		}
3280		break;
3281	}
3282
3283	if (badness) {
3284		*cfg = *best_cfg;
3285		fill_and_eval_dacs(codec, best_wired, best_mio);
3286	}
3287	debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n",
3288		      cfg->line_out_type, best_wired, best_mio);
3289	debug_show_configs(spec, cfg);
3290
3291	if (cfg->line_out_pins[0])
3292		spec->vmaster_nid =
3293			alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
3294						 spec->multiout.dac_nids[0]);
3295
3296	/* clear the bitmap flags for creating controls */
3297	clear_vol_marks(codec);
3298	kfree(best_cfg);
3299	return 0;
3300}
3301
3302static int alc_auto_add_vol_ctl(struct hda_codec *codec,
3303			      const char *pfx, int cidx,
3304			      hda_nid_t nid, unsigned int chs)
3305{
3306	struct alc_spec *spec = codec->spec;
3307	unsigned int val;
3308	if (!nid)
3309		return 0;
3310	val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
3311	if (is_ctl_used(spec->vol_ctls, val) && chs != 2) /* exclude LFE */
3312		return 0;
3313	mark_ctl_usage(spec->vol_ctls, val);
3314	return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
3315				 val);
3316}
3317
3318static int alc_auto_add_stereo_vol(struct hda_codec *codec,
3319				   const char *pfx, int cidx,
3320				   hda_nid_t nid)
3321{
3322	int chs = 1;
3323	if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
3324		chs = 3;
3325	return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs);
3326}
3327
3328/* create a mute-switch for the given mixer widget;
3329 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
3330 */
3331static int alc_auto_add_sw_ctl(struct hda_codec *codec,
3332			     const char *pfx, int cidx,
3333			     hda_nid_t nid, unsigned int chs)
3334{
3335	struct alc_spec *spec = codec->spec;
3336	int wid_type;
3337	int type;
3338	unsigned long val;
3339	if (!nid)
3340		return 0;
3341	wid_type = get_wcaps_type(get_wcaps(codec, nid));
3342	if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) {
3343		type = ALC_CTL_WIDGET_MUTE;
3344		val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
3345	} else if (snd_hda_get_num_conns(codec, nid) == 1) {
3346		type = ALC_CTL_WIDGET_MUTE;
3347		val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
3348	} else {
3349		type = ALC_CTL_BIND_MUTE;
3350		val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
3351	}
3352	if (is_ctl_used(spec->sw_ctls, val) && chs != 2) /* exclude LFE */
3353		return 0;
3354	mark_ctl_usage(spec->sw_ctls, val);
3355	return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
3356}
3357
3358static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx,
3359				  int cidx, hda_nid_t nid)
3360{
3361	int chs = 1;
3362	if (get_wcaps(codec, nid) & AC_WCAP_STEREO)
3363		chs = 3;
3364	return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs);
3365}
3366
3367static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
3368					   hda_nid_t pin, hda_nid_t dac)
3369{
3370	hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
3371	if (nid_has_mute(codec, pin, HDA_OUTPUT))
3372		return pin;
3373	else if (mix && nid_has_mute(codec, mix, HDA_INPUT))
3374		return mix;
3375	else if (nid_has_mute(codec, dac, HDA_OUTPUT))
3376		return dac;
3377	return 0;
3378}
3379
3380static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
3381					  hda_nid_t pin, hda_nid_t dac)
3382{
3383	hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
3384	if (nid_has_volume(codec, dac, HDA_OUTPUT))
3385		return dac;
3386	else if (nid_has_volume(codec, mix, HDA_OUTPUT))
3387		return mix;
3388	else if (nid_has_volume(codec, pin, HDA_OUTPUT))
3389		return pin;
3390	return 0;
3391}
3392
3393/* add playback controls from the parsed DAC table */
3394static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
3395					     const struct auto_pin_cfg *cfg)
3396{
3397	struct alc_spec *spec = codec->spec;
3398	int i, err, noutputs;
3399
3400	noutputs = cfg->line_outs;
3401	if (spec->multi_ios > 0 && cfg->line_outs < 3)
3402		noutputs += spec->multi_ios;
3403
3404	for (i = 0; i < noutputs; i++) {
3405		const char *name;
3406		int index;
3407		hda_nid_t dac, pin;
3408		hda_nid_t sw, vol;
3409
3410		dac = spec->multiout.dac_nids[i];
3411		if (!dac)
3412			continue;
3413		if (i >= cfg->line_outs) {
3414			pin = spec->multi_io[i - 1].pin;
3415			index = 0;
3416			name = channel_name[i];
3417		} else {
3418			pin = cfg->line_out_pins[i];
3419			name = alc_get_line_out_pfx(spec, i, true, &index);
3420		}
3421
3422		sw = alc_look_for_out_mute_nid(codec, pin, dac);
3423		vol = alc_look_for_out_vol_nid(codec, pin, dac);
3424		if (!name || !strcmp(name, "CLFE")) {
3425			/* Center/LFE */
3426			err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
3427			if (err < 0)
3428				return err;
3429			err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2);
3430			if (err < 0)
3431				return err;
3432			err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1);
3433			if (err < 0)
3434				return err;
3435			err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2);
3436			if (err < 0)
3437				return err;
3438		} else {
3439			err = alc_auto_add_stereo_vol(codec, name, index, vol);
3440			if (err < 0)
3441				return err;
3442			err = alc_auto_add_stereo_sw(codec, name, index, sw);
3443			if (err < 0)
3444				return err;
3445		}
3446	}
3447	return 0;
3448}
3449
3450static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3451				     hda_nid_t dac, const char *pfx,
3452				     int cidx)
3453{
3454	struct alc_spec *spec = codec->spec;
3455	hda_nid_t sw, vol;
3456	int err;
3457
3458	if (!dac) {
3459		unsigned int val;
3460		/* the corresponding DAC is already occupied */
3461		if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
3462			return 0; /* no way */
3463		/* create a switch only */
3464		val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT);
3465		if (is_ctl_used(spec->sw_ctls, val))
3466			return 0; /* already created */
3467		mark_ctl_usage(spec->sw_ctls, val);
3468		return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val);
3469	}
3470
3471	sw = alc_look_for_out_mute_nid(codec, pin, dac);
3472	vol = alc_look_for_out_vol_nid(codec, pin, dac);
3473	err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol);
3474	if (err < 0)
3475		return err;
3476	err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw);
3477	if (err < 0)
3478		return err;
3479	return 0;
3480}
3481
3482static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec,
3483					  unsigned int nums,
3484					  struct hda_ctl_ops *ops)
3485{
3486	struct alc_spec *spec = codec->spec;
3487	struct hda_bind_ctls **ctlp, *ctl;
3488	snd_array_init(&spec->bind_ctls, sizeof(ctl), 8);
3489	ctlp = snd_array_new(&spec->bind_ctls);
3490	if (!ctlp)
3491		return NULL;
3492	ctl = kzalloc(sizeof(*ctl) + sizeof(long) * (nums + 1), GFP_KERNEL);
3493	*ctlp = ctl;
3494	if (ctl)
3495		ctl->ops = ops;
3496	return ctl;
3497}
3498
3499/* add playback controls for speaker and HP outputs */
3500static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
3501				      const hda_nid_t *pins,
3502				      const hda_nid_t *dacs,
3503				      const char *pfx)
3504{
3505	struct alc_spec *spec = codec->spec;
3506	struct hda_bind_ctls *ctl;
3507	char name[32];
3508	int i, n, err;
3509
3510	if (!num_pins || !pins[0])
3511		return 0;
3512
3513	if (num_pins == 1) {
3514		hda_nid_t dac = *dacs;
3515		if (!dac)
3516			dac = spec->multiout.dac_nids[0];
3517		return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
3518	}
3519
3520	for (i = 0; i < num_pins; i++) {
3521		hda_nid_t dac;
3522		if (dacs[num_pins - 1])
3523			dac = dacs[i]; /* with individual volumes */
3524		else
3525			dac = 0;
3526		if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) {
3527			err = alc_auto_create_extra_out(codec, pins[i], dac,
3528							"Bass Speaker", 0);
3529		} else if (num_pins >= 3) {
3530			snprintf(name, sizeof(name), "%s %s",
3531				 pfx, channel_name[i]);
3532			err = alc_auto_create_extra_out(codec, pins[i], dac,
3533							name, 0);
3534		} else {
3535			err = alc_auto_create_extra_out(codec, pins[i], dac,
3536							pfx, i);
3537		}
3538		if (err < 0)
3539			return err;
3540	}
3541	if (dacs[num_pins - 1])
3542		return 0;
3543
3544	/* Let's create a bind-controls for volumes */
3545	ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
3546	if (!ctl)
3547		return -ENOMEM;
3548	n = 0;
3549	for (i = 0; i < num_pins; i++) {
3550		hda_nid_t vol;
3551		if (!pins[i] || !dacs[i])
3552			continue;
3553		vol = alc_look_for_out_vol_nid(codec, pins[i], dacs[i]);
3554		if (vol)
3555			ctl->values[n++] =
3556				HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT);
3557	}
3558	if (n) {
3559		snprintf(name, sizeof(name), "%s Playback Volume", pfx);
3560		err = add_control(spec, ALC_CTL_BIND_VOL, name, 0, (long)ctl);
3561		if (err < 0)
3562			return err;
3563	}
3564	return 0;
3565}
3566
3567static int alc_auto_create_hp_out(struct hda_codec *codec)
3568{
3569	struct alc_spec *spec = codec->spec;
3570	return alc_auto_create_extra_outs(codec, spec->autocfg.hp_outs,
3571					  spec->autocfg.hp_pins,
3572					  spec->multiout.hp_out_nid,
3573					  "Headphone");
3574}
3575
3576static int alc_auto_create_speaker_out(struct hda_codec *codec)
3577{
3578	struct alc_spec *spec = codec->spec;
3579	return alc_auto_create_extra_outs(codec, spec->autocfg.speaker_outs,
3580					  spec->autocfg.speaker_pins,
3581					  spec->multiout.extra_out_nid,
3582					  "Speaker");
3583}
3584
3585static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
3586					      hda_nid_t pin, int pin_type,
3587					      hda_nid_t dac)
3588{
3589	int i, num;
3590	hda_nid_t nid, mix = 0;
3591	hda_nid_t srcs[HDA_MAX_CONNECTIONS];
3592
3593	alc_set_pin_output(codec, pin, pin_type);
3594	nid = alc_go_down_to_selector(codec, pin);
3595	num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
3596	for (i = 0; i < num; i++) {
3597		if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
3598			continue;
3599		mix = srcs[i];
3600		break;
3601	}
3602	if (!mix)
3603		return;
3604
3605	/* need the manual connection? */
3606	if (num > 1)
3607		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
3608	/* unmute mixer widget inputs */
3609	if (nid_has_mute(codec, mix, HDA_INPUT)) {
3610		snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3611			    AMP_IN_UNMUTE(0));
3612		snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3613			    AMP_IN_UNMUTE(1));
3614	}
3615	/* initialize volume */
3616	nid = alc_look_for_out_vol_nid(codec, pin, dac);
3617	if (nid)
3618		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3619				    AMP_OUT_ZERO);
3620
3621	/* unmute DAC if it's not assigned to a mixer */
3622	nid = alc_look_for_out_mute_nid(codec, pin, dac);
3623	if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT))
3624		snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3625				    AMP_OUT_ZERO);
3626}
3627
3628static void alc_auto_init_multi_out(struct hda_codec *codec)
3629{
3630	struct alc_spec *spec = codec->spec;
3631	int pin_type = get_pin_type(spec->autocfg.line_out_type);
3632	int i;
3633
3634	for (i = 0; i <= HDA_SIDE; i++) {
3635		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3636		if (nid)
3637			alc_auto_set_output_and_unmute(codec, nid, pin_type,
3638					spec->multiout.dac_nids[i]);
3639	}
3640}
3641
3642static void alc_auto_init_extra_out(struct hda_codec *codec)
3643{
3644	struct alc_spec *spec = codec->spec;
3645	int i;
3646	hda_nid_t pin, dac;
3647
3648	for (i = 0; i < spec->autocfg.hp_outs; i++) {
3649		if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
3650			break;
3651		pin = spec->autocfg.hp_pins[i];
3652		if (!pin)
3653			break;
3654		dac = spec->multiout.hp_out_nid[i];
3655		if (!dac) {
3656			if (i > 0 && spec->multiout.hp_out_nid[0])
3657				dac = spec->multiout.hp_out_nid[0];
3658			else
3659				dac = spec->multiout.dac_nids[0];
3660		}
3661		alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
3662	}
3663	for (i = 0; i < spec->autocfg.speaker_outs; i++) {
3664		if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
3665			break;
3666		pin = spec->autocfg.speaker_pins[i];
3667		if (!pin)
3668			break;
3669		dac = spec->multiout.extra_out_nid[i];
3670		if (!dac) {
3671			if (i > 0 && spec->multiout.extra_out_nid[0])
3672				dac = spec->multiout.extra_out_nid[0];
3673			else
3674				dac = spec->multiout.dac_nids[0];
3675		}
3676		alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
3677	}
3678}
3679
3680/* check whether the given pin can be a multi-io pin */
3681static bool can_be_multiio_pin(struct hda_codec *codec,
3682			       unsigned int location, hda_nid_t nid)
3683{
3684	unsigned int defcfg, caps;
3685
3686	defcfg = snd_hda_codec_get_pincfg(codec, nid);
3687	if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3688		return false;
3689	if (location && get_defcfg_location(defcfg) != location)
3690		return false;
3691	caps = snd_hda_query_pin_caps(codec, nid);
3692	if (!(caps & AC_PINCAP_OUT))
3693		return false;
3694	return true;
3695}
3696
3697/*
3698 * multi-io helper
3699 *
3700 * When hardwired is set, try to fill ony hardwired pins, and returns
3701 * zero if any pins are filled, non-zero if nothing found.
3702 * When hardwired is off, try to fill possible input pins, and returns
3703 * the badness value.
3704 */
3705static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3706				   hda_nid_t reference_pin,
3707				   bool hardwired, int offset)
3708{
3709	struct alc_spec *spec = codec->spec;
3710	struct auto_pin_cfg *cfg = &spec->autocfg;
3711	int type, i, j, dacs, num_pins, old_pins;
3712	unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin);
3713	unsigned int location = get_defcfg_location(defcfg);
3714	int badness = 0;
3715
3716	old_pins = spec->multi_ios;
3717	if (old_pins >= 2)
3718		goto end_fill;
3719
3720	num_pins = 0;
3721	for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3722		for (i = 0; i < cfg->num_inputs; i++) {
3723			if (cfg->inputs[i].type != type)
3724				continue;
3725			if (can_be_multiio_pin(codec, location,
3726					       cfg->inputs[i].pin))
3727				num_pins++;
3728		}
3729	}
3730	if (num_pins < 2)
3731		goto end_fill;
3732
3733	dacs = spec->multiout.num_dacs;
3734	for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3735		for (i = 0; i < cfg->num_inputs; i++) {
3736			hda_nid_t nid = cfg->inputs[i].pin;
3737			hda_nid_t dac = 0;
3738
3739			if (cfg->inputs[i].type != type)
3740				continue;
3741			if (!can_be_multiio_pin(codec, location, nid))
3742				continue;
3743			for (j = 0; j < spec->multi_ios; j++) {
3744				if (nid == spec->multi_io[j].pin)
3745					break;
3746			}
3747			if (j < spec->multi_ios)
3748				continue;
3749
3750			if (offset && offset + spec->multi_ios < dacs) {
3751				dac = spec->private_dac_nids[offset + spec->multi_ios];
3752				if (!alc_auto_is_dac_reachable(codec, nid, dac))
3753					dac = 0;
3754			}
3755			if (hardwired)
3756				dac = get_dac_if_single(codec, nid);
3757			else if (!dac)
3758				dac = alc_auto_look_for_dac(codec, nid);
3759			if (!dac) {
3760				badness++;
3761				continue;
3762			}
3763			spec->multi_io[spec->multi_ios].pin = nid;
3764			spec->multi_io[spec->multi_ios].dac = dac;
3765			spec->multi_ios++;
3766			if (spec->multi_ios >= 2)
3767				break;
3768		}
3769	}
3770 end_fill:
3771	if (badness)
3772		badness = BAD_MULTI_IO;
3773	if (old_pins == spec->multi_ios) {
3774		if (hardwired)
3775			return 1; /* nothing found */
3776		else
3777			return badness; /* no badness if nothing found */
3778	}
3779	if (!hardwired && spec->multi_ios < 2) {
3780		spec->multi_ios = old_pins;
3781		return badness;
3782	}
3783
3784	return 0;
3785}
3786
3787static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
3788				 struct snd_ctl_elem_info *uinfo)
3789{
3790	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3791	struct alc_spec *spec = codec->spec;
3792
3793	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3794	uinfo->count = 1;
3795	uinfo->value.enumerated.items = spec->multi_ios + 1;
3796	if (uinfo->value.enumerated.item > spec->multi_ios)
3797		uinfo->value.enumerated.item = spec->multi_ios;
3798	sprintf(uinfo->value.enumerated.name, "%dch",
3799		(uinfo->value.enumerated.item + 1) * 2);
3800	return 0;
3801}
3802
3803static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
3804				struct snd_ctl_elem_value *ucontrol)
3805{
3806	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3807	struct alc_spec *spec = codec->spec;
3808	ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
3809	return 0;
3810}
3811
3812static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
3813{
3814	struct alc_spec *spec = codec->spec;
3815	hda_nid_t nid = spec->multi_io[idx].pin;
3816
3817	if (!spec->multi_io[idx].ctl_in)
3818		spec->multi_io[idx].ctl_in =
3819			snd_hda_codec_read(codec, nid, 0,
3820					   AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3821	if (output) {
3822		snd_hda_set_pin_ctl_cache(codec, nid, PIN_OUT);
3823		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3824			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3825						 HDA_AMP_MUTE, 0);
3826		alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
3827	} else {
3828		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3829			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3830						 HDA_AMP_MUTE, HDA_AMP_MUTE);
3831		snd_hda_set_pin_ctl_cache(codec, nid,
3832					  spec->multi_io[idx].ctl_in);
3833	}
3834	return 0;
3835}
3836
3837static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
3838				struct snd_ctl_elem_value *ucontrol)
3839{
3840	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3841	struct alc_spec *spec = codec->spec;
3842	int i, ch;
3843
3844	ch = ucontrol->value.enumerated.item[0];
3845	if (ch < 0 || ch > spec->multi_ios)
3846		return -EINVAL;
3847	if (ch == (spec->ext_channel_count - 1) / 2)
3848		return 0;
3849	spec->ext_channel_count = (ch + 1) * 2;
3850	for (i = 0; i < spec->multi_ios; i++)
3851		alc_set_multi_io(codec, i, i < ch);
3852	spec->multiout.max_channels = spec->ext_channel_count;
3853	if (spec->need_dac_fix && !spec->const_channel_count)
3854		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
3855	return 1;
3856}
3857
3858static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
3859	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3860	.name = "Channel Mode",
3861	.info = alc_auto_ch_mode_info,
3862	.get = alc_auto_ch_mode_get,
3863	.put = alc_auto_ch_mode_put,
3864};
3865
3866static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
3867{
3868	struct alc_spec *spec = codec->spec;
3869
3870	if (spec->multi_ios > 0) {
3871		struct snd_kcontrol_new *knew;
3872
3873		knew = alc_kcontrol_new(spec);
3874		if (!knew)
3875			return -ENOMEM;
3876		*knew = alc_auto_channel_mode_enum;
3877		knew->name = kstrdup("Channel Mode", GFP_KERNEL);
3878		if (!knew->name)
3879			return -ENOMEM;
3880	}
3881	return 0;
3882}
3883
3884/* filter out invalid adc_nids (and capsrc_nids) that don't give all
3885 * active input pins
3886 */
3887static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
3888{
3889	struct alc_spec *spec = codec->spec;
3890	const struct hda_input_mux *imux;
3891	hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3892	hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3893	int i, n, nums;
3894
3895	imux = spec->input_mux;
3896	if (!imux)
3897		return;
3898	if (spec->dyn_adc_switch)
3899		return;
3900
3901 again:
3902	nums = 0;
3903	for (n = 0; n < spec->num_adc_nids; n++) {
3904		hda_nid_t cap = spec->private_capsrc_nids[n];
3905		int num_conns = snd_hda_get_num_conns(codec, cap);
3906		for (i = 0; i < imux->num_items; i++) {
3907			hda_nid_t pin = spec->imux_pins[i];
3908			if (pin) {
3909				if (get_connection_index(codec, cap, pin) < 0)
3910					break;
3911			} else if (num_conns <= imux->items[i].index)
3912				break;
3913		}
3914		if (i >= imux->num_items) {
3915			adc_nids[nums] = spec->private_adc_nids[n];
3916			capsrc_nids[nums++] = cap;
3917		}
3918	}
3919	if (!nums) {
3920		/* check whether ADC-switch is possible */
3921		if (!alc_check_dyn_adc_switch(codec)) {
3922			if (spec->shared_mic_hp) {
3923				spec->shared_mic_hp = 0;
3924				spec->private_imux[0].num_items = 1;
3925				goto again;
3926			}
3927			printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
3928			       " using fallback 0x%x\n",
3929			       codec->chip_name, spec->private_adc_nids[0]);
3930			spec->num_adc_nids = 1;
3931			spec->auto_mic = 0;
3932			return;
3933		}
3934	} else if (nums != spec->num_adc_nids) {
3935		memcpy(spec->private_adc_nids, adc_nids,
3936		       nums * sizeof(hda_nid_t));
3937		memcpy(spec->private_capsrc_nids, capsrc_nids,
3938		       nums * sizeof(hda_nid_t));
3939		spec->num_adc_nids = nums;
3940	}
3941
3942	if (spec->auto_mic)
3943		alc_auto_mic_check_imux(codec); /* check auto-mic setups */
3944	else if (spec->input_mux->num_items == 1 || spec->shared_mic_hp)
3945		spec->num_adc_nids = 1; /* reduce to a single ADC */
3946}
3947
3948/*
3949 * initialize ADC paths
3950 */
3951static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
3952{
3953	struct alc_spec *spec = codec->spec;
3954	hda_nid_t nid;
3955
3956	nid = spec->adc_nids[adc_idx];
3957	/* mute ADC */
3958	if (nid_has_mute(codec, nid, HDA_INPUT)) {
3959		snd_hda_codec_write(codec, nid, 0,
3960				    AC_VERB_SET_AMP_GAIN_MUTE,
3961				    AMP_IN_MUTE(0));
3962		return;
3963	}
3964	if (!spec->capsrc_nids)
3965		return;
3966	nid = spec->capsrc_nids[adc_idx];
3967	if (nid_has_mute(codec, nid, HDA_OUTPUT))
3968		snd_hda_codec_write(codec, nid, 0,
3969				    AC_VERB_SET_AMP_GAIN_MUTE,
3970				    AMP_OUT_MUTE);
3971}
3972
3973static void alc_auto_init_input_src(struct hda_codec *codec)
3974{
3975	struct alc_spec *spec = codec->spec;
3976	int c, nums;
3977
3978	for (c = 0; c < spec->num_adc_nids; c++)
3979		alc_auto_init_adc(codec, c);
3980	if (spec->dyn_adc_switch)
3981		nums = 1;
3982	else
3983		nums = spec->num_adc_nids;
3984	for (c = 0; c < nums; c++)
3985		alc_mux_select(codec, c, spec->cur_mux[c], true);
3986}
3987
3988/* add mic boosts if needed */
3989static int alc_auto_add_mic_boost(struct hda_codec *codec)
3990{
3991	struct alc_spec *spec = codec->spec;
3992	struct auto_pin_cfg *cfg = &spec->autocfg;
3993	int i, err;
3994	int type_idx = 0;
3995	hda_nid_t nid;
3996	const char *prev_label = NULL;
3997
3998	for (i = 0; i < cfg->num_inputs; i++) {
3999		if (cfg->inputs[i].type > AUTO_PIN_MIC)
4000			break;
4001		nid = cfg->inputs[i].pin;
4002		if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
4003			const char *label;
4004			char boost_label[32];
4005
4006			label = hda_get_autocfg_input_label(codec, cfg, i);
4007			if (spec->shared_mic_hp && !strcmp(label, "Misc"))
4008				label = "Headphone Mic";
4009			if (prev_label && !strcmp(label, prev_label))
4010				type_idx++;
4011			else
4012				type_idx = 0;
4013			prev_label = label;
4014
4015			snprintf(boost_label, sizeof(boost_label),
4016				 "%s Boost Volume", label);
4017			err = add_control(spec, ALC_CTL_WIDGET_VOL,
4018					  boost_label, type_idx,
4019				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
4020			if (err < 0)
4021				return err;
4022		}
4023	}
4024	return 0;
4025}
4026
4027/* select or unmute the given capsrc route */
4028static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
4029				    int idx)
4030{
4031	if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
4032		snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
4033					 HDA_AMP_MUTE, 0);
4034	} else if (snd_hda_get_num_conns(codec, cap) > 1) {
4035		snd_hda_codec_write_cache(codec, cap, 0,
4036					  AC_VERB_SET_CONNECT_SEL, idx);
4037	}
4038}
4039
4040/* set the default connection to that pin */
4041static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
4042{
4043	struct alc_spec *spec = codec->spec;
4044	int i;
4045
4046	if (!pin)
4047		return 0;
4048	for (i = 0; i < spec->num_adc_nids; i++) {
4049		hda_nid_t cap = get_capsrc(spec, i);
4050		int idx;
4051
4052		idx = get_connection_index(codec, cap, pin);
4053		if (idx < 0)
4054			continue;
4055		select_or_unmute_capsrc(codec, cap, idx);
4056		return i; /* return the found index */
4057	}
4058	return -1; /* not found */
4059}
4060
4061/* initialize some special cases for input sources */
4062static void alc_init_special_input_src(struct hda_codec *codec)
4063{
4064	struct alc_spec *spec = codec->spec;
4065	int i;
4066
4067	for (i = 0; i < spec->autocfg.num_inputs; i++)
4068		init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin);
4069}
4070
4071/* assign appropriate capture mixers */
4072static void set_capture_mixer(struct hda_codec *codec)
4073{
4074	struct alc_spec *spec = codec->spec;
4075	static const struct snd_kcontrol_new *caps[2][3] = {
4076		{ alc_capture_mixer_nosrc1,
4077		  alc_capture_mixer_nosrc2,
4078		  alc_capture_mixer_nosrc3 },
4079		{ alc_capture_mixer1,
4080		  alc_capture_mixer2,
4081		  alc_capture_mixer3 },
4082	};
4083
4084	/* check whether either of ADC or MUX has a volume control */
4085	if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) {
4086		if (!spec->capsrc_nids)
4087			return; /* no volume */
4088		if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT))
4089			return; /* no volume in capsrc, too */
4090		spec->vol_in_capsrc = 1;
4091	}
4092
4093	if (spec->num_adc_nids > 0) {
4094		int mux = 0;
4095		int num_adcs = 0;
4096
4097		if (spec->input_mux && spec->input_mux->num_items > 1)
4098			mux = 1;
4099		if (spec->auto_mic) {
4100			num_adcs = 1;
4101			mux = 0;
4102		} else if (spec->dyn_adc_switch)
4103			num_adcs = 1;
4104		if (!num_adcs) {
4105			if (spec->num_adc_nids > 3)
4106				spec->num_adc_nids = 3;
4107			else if (!spec->num_adc_nids)
4108				return;
4109			num_adcs = spec->num_adc_nids;
4110		}
4111		spec->cap_mixer = caps[mux][num_adcs - 1];
4112	}
4113}
4114
4115/*
4116 * standard auto-parser initializations
4117 */
4118static void alc_auto_init_std(struct hda_codec *codec)
4119{
4120	struct alc_spec *spec = codec->spec;
4121	alc_auto_init_multi_out(codec);
4122	alc_auto_init_extra_out(codec);
4123	alc_auto_init_analog_input(codec);
4124	alc_auto_init_input_src(codec);
4125	alc_auto_init_digital(codec);
4126	if (spec->unsol_event)
4127		alc_inithook(codec);
4128}
4129
4130/*
4131 * Digital-beep handlers
4132 */
4133#ifdef CONFIG_SND_HDA_INPUT_BEEP
4134#define set_beep_amp(spec, nid, idx, dir) \
4135	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4136
4137static const struct snd_pci_quirk beep_white_list[] = {
 
 
4138	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
 
4139	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
4140	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
4141	SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
4142	SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
4143	SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
4144	{}
4145};
4146
4147static inline int has_cdefine_beep(struct hda_codec *codec)
4148{
4149	struct alc_spec *spec = codec->spec;
4150	const struct snd_pci_quirk *q;
4151	q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
4152	if (q)
4153		return q->value;
4154	return spec->cdefine.enable_pcbeep;
4155}
4156#else
4157#define set_beep_amp(spec, nid, idx, dir) /* NOP */
4158#define has_cdefine_beep(codec)		0
4159#endif
4160
4161/* parse the BIOS configuration and set up the alc_spec */
4162/* return 1 if successful, 0 if the proper config is not found,
4163 * or a negative error code
4164 */
4165static int alc_parse_auto_config(struct hda_codec *codec,
4166				 const hda_nid_t *ignore_nids,
4167				 const hda_nid_t *ssid_nids)
4168{
4169	struct alc_spec *spec = codec->spec;
4170	struct auto_pin_cfg *cfg = &spec->autocfg;
4171	int err;
4172
4173	err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
4174				       spec->parse_flags);
4175	if (err < 0)
4176		return err;
4177	if (!cfg->line_outs) {
4178		if (cfg->dig_outs || cfg->dig_in_pin) {
4179			spec->multiout.max_channels = 2;
4180			spec->no_analog = 1;
4181			goto dig_only;
4182		}
4183		return 0; /* can't find valid BIOS pin config */
4184	}
4185
4186	if (!spec->no_primary_hp &&
4187	    cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
4188	    cfg->line_outs <= cfg->hp_outs) {
4189		/* use HP as primary out */
4190		cfg->speaker_outs = cfg->line_outs;
4191		memcpy(cfg->speaker_pins, cfg->line_out_pins,
4192		       sizeof(cfg->speaker_pins));
4193		cfg->line_outs = cfg->hp_outs;
4194		memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
4195		cfg->hp_outs = 0;
4196		memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
4197		cfg->line_out_type = AUTO_PIN_HP_OUT;
4198	}
4199
4200	err = alc_auto_fill_dac_nids(codec);
4201	if (err < 0)
4202		return err;
4203	err = alc_auto_add_multi_channel_mode(codec);
4204	if (err < 0)
4205		return err;
4206	err = alc_auto_create_multi_out_ctls(codec, cfg);
4207	if (err < 0)
4208		return err;
4209	err = alc_auto_create_hp_out(codec);
4210	if (err < 0)
4211		return err;
4212	err = alc_auto_create_speaker_out(codec);
4213	if (err < 0)
4214		return err;
4215	err = alc_auto_create_shared_input(codec);
4216	if (err < 0)
4217		return err;
4218	err = alc_auto_create_input_ctls(codec);
4219	if (err < 0)
4220		return err;
4221
4222	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4223
4224 dig_only:
4225	alc_auto_parse_digital(codec);
4226
4227	if (!spec->no_analog)
4228		alc_remove_invalid_adc_nids(codec);
4229
4230	if (ssid_nids)
4231		alc_ssid_check(codec, ssid_nids);
4232
4233	if (!spec->no_analog) {
4234		alc_auto_check_switches(codec);
4235		err = alc_auto_add_mic_boost(codec);
4236		if (err < 0)
4237			return err;
4238	}
4239
4240	if (spec->kctls.list)
4241		add_mixer(spec, spec->kctls.list);
4242
4243	if (!spec->no_analog && !spec->cap_mixer)
4244		set_capture_mixer(codec);
4245
4246	return 1;
4247}
4248
4249/* common preparation job for alc_spec */
4250static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
4251{
4252	struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4253	int err;
4254
4255	if (!spec)
4256		return -ENOMEM;
4257	codec->spec = spec;
4258	spec->mixer_nid = mixer_nid;
4259	snd_hda_gen_init(&spec->gen);
 
 
 
 
4260
4261	err = alc_codec_rename_from_preset(codec);
4262	if (err < 0) {
4263		kfree(spec);
4264		return err;
4265	}
4266	return 0;
4267}
4268
4269static int alc880_parse_auto_config(struct hda_codec *codec)
4270{
4271	static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4272	static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
4273	return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
4274}
4275
4276/*
4277 * ALC880 fix-ups
4278 */
4279enum {
4280	ALC880_FIXUP_GPIO1,
4281	ALC880_FIXUP_GPIO2,
4282	ALC880_FIXUP_MEDION_RIM,
4283	ALC880_FIXUP_LG,
 
4284	ALC880_FIXUP_W810,
4285	ALC880_FIXUP_EAPD_COEF,
4286	ALC880_FIXUP_TCL_S700,
4287	ALC880_FIXUP_VOL_KNOB,
4288	ALC880_FIXUP_FUJITSU,
4289	ALC880_FIXUP_F1734,
4290	ALC880_FIXUP_UNIWILL,
4291	ALC880_FIXUP_UNIWILL_DIG,
4292	ALC880_FIXUP_Z71V,
 
4293	ALC880_FIXUP_3ST_BASE,
4294	ALC880_FIXUP_3ST,
4295	ALC880_FIXUP_3ST_DIG,
4296	ALC880_FIXUP_5ST_BASE,
4297	ALC880_FIXUP_5ST,
4298	ALC880_FIXUP_5ST_DIG,
4299	ALC880_FIXUP_6ST_BASE,
4300	ALC880_FIXUP_6ST,
4301	ALC880_FIXUP_6ST_DIG,
 
4302};
4303
4304/* enable the volume-knob widget support on NID 0x21 */
4305static void alc880_fixup_vol_knob(struct hda_codec *codec,
4306				  const struct alc_fixup *fix, int action)
4307{
4308	if (action == ALC_FIXUP_ACT_PROBE)
4309		snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
4310}
4311
4312static const struct alc_fixup alc880_fixups[] = {
4313	[ALC880_FIXUP_GPIO1] = {
4314		.type = ALC_FIXUP_VERBS,
4315		.v.verbs = alc_gpio1_init_verbs,
4316	},
4317	[ALC880_FIXUP_GPIO2] = {
4318		.type = ALC_FIXUP_VERBS,
4319		.v.verbs = alc_gpio2_init_verbs,
4320	},
4321	[ALC880_FIXUP_MEDION_RIM] = {
4322		.type = ALC_FIXUP_VERBS,
4323		.v.verbs = (const struct hda_verb[]) {
4324			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4325			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
4326			{ }
4327		},
4328		.chained = true,
4329		.chain_id = ALC880_FIXUP_GPIO2,
4330	},
4331	[ALC880_FIXUP_LG] = {
4332		.type = ALC_FIXUP_PINS,
4333		.v.pins = (const struct alc_pincfg[]) {
4334			/* disable bogus unused pins */
4335			{ 0x16, 0x411111f0 },
4336			{ 0x18, 0x411111f0 },
4337			{ 0x1a, 0x411111f0 },
4338			{ }
4339		}
4340	},
 
 
 
 
 
 
 
 
4341	[ALC880_FIXUP_W810] = {
4342		.type = ALC_FIXUP_PINS,
4343		.v.pins = (const struct alc_pincfg[]) {
4344			/* disable bogus unused pins */
4345			{ 0x17, 0x411111f0 },
4346			{ }
4347		},
4348		.chained = true,
4349		.chain_id = ALC880_FIXUP_GPIO2,
4350	},
4351	[ALC880_FIXUP_EAPD_COEF] = {
4352		.type = ALC_FIXUP_VERBS,
4353		.v.verbs = (const struct hda_verb[]) {
4354			/* change to EAPD mode */
4355			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4356			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
4357			{}
4358		},
4359	},
4360	[ALC880_FIXUP_TCL_S700] = {
4361		.type = ALC_FIXUP_VERBS,
4362		.v.verbs = (const struct hda_verb[]) {
4363			/* change to EAPD mode */
4364			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4365			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3070 },
4366			{}
4367		},
4368		.chained = true,
4369		.chain_id = ALC880_FIXUP_GPIO2,
4370	},
4371	[ALC880_FIXUP_VOL_KNOB] = {
4372		.type = ALC_FIXUP_FUNC,
4373		.v.func = alc880_fixup_vol_knob,
4374	},
4375	[ALC880_FIXUP_FUJITSU] = {
4376		/* override all pins as BIOS on old Amilo is broken */
4377		.type = ALC_FIXUP_PINS,
4378		.v.pins = (const struct alc_pincfg[]) {
4379			{ 0x14, 0x0121411f }, /* HP */
4380			{ 0x15, 0x99030120 }, /* speaker */
4381			{ 0x16, 0x99030130 }, /* bass speaker */
4382			{ 0x17, 0x411111f0 }, /* N/A */
4383			{ 0x18, 0x411111f0 }, /* N/A */
4384			{ 0x19, 0x01a19950 }, /* mic-in */
4385			{ 0x1a, 0x411111f0 }, /* N/A */
4386			{ 0x1b, 0x411111f0 }, /* N/A */
4387			{ 0x1c, 0x411111f0 }, /* N/A */
4388			{ 0x1d, 0x411111f0 }, /* N/A */
4389			{ 0x1e, 0x01454140 }, /* SPDIF out */
4390			{ }
4391		},
4392		.chained = true,
4393		.chain_id = ALC880_FIXUP_VOL_KNOB,
4394	},
4395	[ALC880_FIXUP_F1734] = {
4396		/* almost compatible with FUJITSU, but no bass and SPDIF */
4397		.type = ALC_FIXUP_PINS,
4398		.v.pins = (const struct alc_pincfg[]) {
4399			{ 0x14, 0x0121411f }, /* HP */
4400			{ 0x15, 0x99030120 }, /* speaker */
4401			{ 0x16, 0x411111f0 }, /* N/A */
4402			{ 0x17, 0x411111f0 }, /* N/A */
4403			{ 0x18, 0x411111f0 }, /* N/A */
4404			{ 0x19, 0x01a19950 }, /* mic-in */
4405			{ 0x1a, 0x411111f0 }, /* N/A */
4406			{ 0x1b, 0x411111f0 }, /* N/A */
4407			{ 0x1c, 0x411111f0 }, /* N/A */
4408			{ 0x1d, 0x411111f0 }, /* N/A */
4409			{ 0x1e, 0x411111f0 }, /* N/A */
4410			{ }
4411		},
4412		.chained = true,
4413		.chain_id = ALC880_FIXUP_VOL_KNOB,
4414	},
4415	[ALC880_FIXUP_UNIWILL] = {
4416		/* need to fix HP and speaker pins to be parsed correctly */
4417		.type = ALC_FIXUP_PINS,
4418		.v.pins = (const struct alc_pincfg[]) {
4419			{ 0x14, 0x0121411f }, /* HP */
4420			{ 0x15, 0x99030120 }, /* speaker */
4421			{ 0x16, 0x99030130 }, /* bass speaker */
4422			{ }
4423		},
4424	},
4425	[ALC880_FIXUP_UNIWILL_DIG] = {
4426		.type = ALC_FIXUP_PINS,
4427		.v.pins = (const struct alc_pincfg[]) {
4428			/* disable bogus unused pins */
4429			{ 0x17, 0x411111f0 },
4430			{ 0x19, 0x411111f0 },
4431			{ 0x1b, 0x411111f0 },
4432			{ 0x1f, 0x411111f0 },
4433			{ }
4434		}
4435	},
4436	[ALC880_FIXUP_Z71V] = {
4437		.type = ALC_FIXUP_PINS,
4438		.v.pins = (const struct alc_pincfg[]) {
4439			/* set up the whole pins as BIOS is utterly broken */
4440			{ 0x14, 0x99030120 }, /* speaker */
4441			{ 0x15, 0x0121411f }, /* HP */
4442			{ 0x16, 0x411111f0 }, /* N/A */
4443			{ 0x17, 0x411111f0 }, /* N/A */
4444			{ 0x18, 0x01a19950 }, /* mic-in */
4445			{ 0x19, 0x411111f0 }, /* N/A */
4446			{ 0x1a, 0x01813031 }, /* line-in */
4447			{ 0x1b, 0x411111f0 }, /* N/A */
4448			{ 0x1c, 0x411111f0 }, /* N/A */
4449			{ 0x1d, 0x411111f0 }, /* N/A */
4450			{ 0x1e, 0x0144111e }, /* SPDIF */
4451			{ }
4452		}
4453	},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4454	[ALC880_FIXUP_3ST_BASE] = {
4455		.type = ALC_FIXUP_PINS,
4456		.v.pins = (const struct alc_pincfg[]) {
4457			{ 0x14, 0x01014010 }, /* line-out */
4458			{ 0x15, 0x411111f0 }, /* N/A */
4459			{ 0x16, 0x411111f0 }, /* N/A */
4460			{ 0x17, 0x411111f0 }, /* N/A */
4461			{ 0x18, 0x01a19c30 }, /* mic-in */
4462			{ 0x19, 0x0121411f }, /* HP */
4463			{ 0x1a, 0x01813031 }, /* line-in */
4464			{ 0x1b, 0x02a19c40 }, /* front-mic */
4465			{ 0x1c, 0x411111f0 }, /* N/A */
4466			{ 0x1d, 0x411111f0 }, /* N/A */
4467			/* 0x1e is filled in below */
4468			{ 0x1f, 0x411111f0 }, /* N/A */
4469			{ }
4470		}
4471	},
4472	[ALC880_FIXUP_3ST] = {
4473		.type = ALC_FIXUP_PINS,
4474		.v.pins = (const struct alc_pincfg[]) {
4475			{ 0x1e, 0x411111f0 }, /* N/A */
4476			{ }
4477		},
4478		.chained = true,
4479		.chain_id = ALC880_FIXUP_3ST_BASE,
4480	},
4481	[ALC880_FIXUP_3ST_DIG] = {
4482		.type = ALC_FIXUP_PINS,
4483		.v.pins = (const struct alc_pincfg[]) {
4484			{ 0x1e, 0x0144111e }, /* SPDIF */
4485			{ }
4486		},
4487		.chained = true,
4488		.chain_id = ALC880_FIXUP_3ST_BASE,
4489	},
4490	[ALC880_FIXUP_5ST_BASE] = {
4491		.type = ALC_FIXUP_PINS,
4492		.v.pins = (const struct alc_pincfg[]) {
4493			{ 0x14, 0x01014010 }, /* front */
4494			{ 0x15, 0x411111f0 }, /* N/A */
4495			{ 0x16, 0x01011411 }, /* CLFE */
4496			{ 0x17, 0x01016412 }, /* surr */
4497			{ 0x18, 0x01a19c30 }, /* mic-in */
4498			{ 0x19, 0x0121411f }, /* HP */
4499			{ 0x1a, 0x01813031 }, /* line-in */
4500			{ 0x1b, 0x02a19c40 }, /* front-mic */
4501			{ 0x1c, 0x411111f0 }, /* N/A */
4502			{ 0x1d, 0x411111f0 }, /* N/A */
4503			/* 0x1e is filled in below */
4504			{ 0x1f, 0x411111f0 }, /* N/A */
4505			{ }
4506		}
4507	},
4508	[ALC880_FIXUP_5ST] = {
4509		.type = ALC_FIXUP_PINS,
4510		.v.pins = (const struct alc_pincfg[]) {
4511			{ 0x1e, 0x411111f0 }, /* N/A */
4512			{ }
4513		},
4514		.chained = true,
4515		.chain_id = ALC880_FIXUP_5ST_BASE,
4516	},
4517	[ALC880_FIXUP_5ST_DIG] = {
4518		.type = ALC_FIXUP_PINS,
4519		.v.pins = (const struct alc_pincfg[]) {
4520			{ 0x1e, 0x0144111e }, /* SPDIF */
4521			{ }
4522		},
4523		.chained = true,
4524		.chain_id = ALC880_FIXUP_5ST_BASE,
4525	},
4526	[ALC880_FIXUP_6ST_BASE] = {
4527		.type = ALC_FIXUP_PINS,
4528		.v.pins = (const struct alc_pincfg[]) {
4529			{ 0x14, 0x01014010 }, /* front */
4530			{ 0x15, 0x01016412 }, /* surr */
4531			{ 0x16, 0x01011411 }, /* CLFE */
4532			{ 0x17, 0x01012414 }, /* side */
4533			{ 0x18, 0x01a19c30 }, /* mic-in */
4534			{ 0x19, 0x02a19c40 }, /* front-mic */
4535			{ 0x1a, 0x01813031 }, /* line-in */
4536			{ 0x1b, 0x0121411f }, /* HP */
4537			{ 0x1c, 0x411111f0 }, /* N/A */
4538			{ 0x1d, 0x411111f0 }, /* N/A */
4539			/* 0x1e is filled in below */
4540			{ 0x1f, 0x411111f0 }, /* N/A */
4541			{ }
4542		}
4543	},
4544	[ALC880_FIXUP_6ST] = {
4545		.type = ALC_FIXUP_PINS,
4546		.v.pins = (const struct alc_pincfg[]) {
4547			{ 0x1e, 0x411111f0 }, /* N/A */
4548			{ }
4549		},
4550		.chained = true,
4551		.chain_id = ALC880_FIXUP_6ST_BASE,
4552	},
4553	[ALC880_FIXUP_6ST_DIG] = {
4554		.type = ALC_FIXUP_PINS,
4555		.v.pins = (const struct alc_pincfg[]) {
4556			{ 0x1e, 0x0144111e }, /* SPDIF */
4557			{ }
4558		},
4559		.chained = true,
4560		.chain_id = ALC880_FIXUP_6ST_BASE,
4561	},
 
 
 
 
 
 
 
 
 
4562};
4563
4564static const struct snd_pci_quirk alc880_fixup_tbl[] = {
4565	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
 
4566	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
4567	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
4568	SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
4569	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
4570	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
4571	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
4572	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
4573	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
4574	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
4575	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
 
4576	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
4577	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
4578	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
4579	SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
4580	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
4581	SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
4582	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
 
4583	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
4584
4585	/* Below is the copied entries from alc880_quirks.c.
4586	 * It's not quite sure whether BIOS sets the correct pin-config table
4587	 * on these machines, thus they are kept to be compatible with
4588	 * the old static quirks.  Once when it's confirmed to work without
4589	 * these overrides, it'd be better to remove.
4590	 */
4591	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
4592	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
4593	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
4594	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
4595	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
4596	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
4597	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
4598	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
4599	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
4600	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
4601	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
4602	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
4603	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
4604	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
4605	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
4606	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
4607	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
4608	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
4609	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
4610	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
4611	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
4612	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
4613	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
4614	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4615	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4616	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4617	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4618	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4619	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4620	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4621	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4622	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4623	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4624	/* default Intel */
4625	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
4626	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
4627	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
4628	{}
4629};
4630
4631static const struct alc_model_fixup alc880_fixup_models[] = {
4632	{.id = ALC880_FIXUP_3ST, .name = "3stack"},
4633	{.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
4634	{.id = ALC880_FIXUP_5ST, .name = "5stack"},
4635	{.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
4636	{.id = ALC880_FIXUP_6ST, .name = "6stack"},
4637	{.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
 
4638	{}
4639};
4640
4641
4642/*
4643 * OK, here we have finally the patch for ALC880
4644 */
4645static int patch_alc880(struct hda_codec *codec)
4646{
4647	struct alc_spec *spec;
4648	int err;
4649
4650	err = alc_alloc_spec(codec, 0x0b);
4651	if (err < 0)
4652		return err;
4653
4654	spec = codec->spec;
4655	spec->need_dac_fix = 1;
 
4656
4657	alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
4658		       alc880_fixups);
4659	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4660
4661	/* automatic parse from the BIOS config */
4662	err = alc880_parse_auto_config(codec);
4663	if (err < 0)
4664		goto error;
4665
4666	if (!spec->no_analog) {
4667		err = snd_hda_attach_beep_device(codec, 0x1);
4668		if (err < 0)
4669			goto error;
4670		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4671	}
4672
4673	codec->patch_ops = alc_patch_ops;
 
 
4674
4675	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4676
4677	return 0;
4678
4679 error:
4680	alc_free(codec);
4681	return err;
4682}
4683
4684
4685/*
4686 * ALC260 support
4687 */
4688static int alc260_parse_auto_config(struct hda_codec *codec)
4689{
4690	static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
4691	static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
4692	return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
4693}
4694
4695/*
4696 * Pin config fixes
4697 */
4698enum {
4699	ALC260_FIXUP_HP_DC5750,
4700	ALC260_FIXUP_HP_PIN_0F,
4701	ALC260_FIXUP_COEF,
4702	ALC260_FIXUP_GPIO1,
4703	ALC260_FIXUP_GPIO1_TOGGLE,
4704	ALC260_FIXUP_REPLACER,
4705	ALC260_FIXUP_HP_B1900,
4706	ALC260_FIXUP_KN1,
 
 
 
4707};
4708
4709static void alc260_gpio1_automute(struct hda_codec *codec)
4710{
4711	struct alc_spec *spec = codec->spec;
4712	snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4713			    spec->hp_jack_present);
4714}
4715
4716static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
4717				      const struct alc_fixup *fix, int action)
4718{
4719	struct alc_spec *spec = codec->spec;
4720	if (action == ALC_FIXUP_ACT_PROBE) {
4721		/* although the machine has only one output pin, we need to
4722		 * toggle GPIO1 according to the jack state
4723		 */
4724		spec->automute_hook = alc260_gpio1_automute;
4725		spec->detect_hp = 1;
4726		spec->automute_speaker = 1;
4727		spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
4728		snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
4729		spec->unsol_event = alc_sku_unsol_event;
4730		snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
4731	}
4732}
4733
4734static void alc260_fixup_kn1(struct hda_codec *codec,
4735			     const struct alc_fixup *fix, int action)
4736{
4737	struct alc_spec *spec = codec->spec;
4738	static const struct alc_pincfg pincfgs[] = {
4739		{ 0x0f, 0x02214000 }, /* HP/speaker */
4740		{ 0x12, 0x90a60160 }, /* int mic */
4741		{ 0x13, 0x02a19000 }, /* ext mic */
4742		{ 0x18, 0x01446000 }, /* SPDIF out */
4743		/* disable bogus I/O pins */
4744		{ 0x10, 0x411111f0 },
4745		{ 0x11, 0x411111f0 },
4746		{ 0x14, 0x411111f0 },
4747		{ 0x15, 0x411111f0 },
4748		{ 0x16, 0x411111f0 },
4749		{ 0x17, 0x411111f0 },
4750		{ 0x19, 0x411111f0 },
4751		{ }
4752	};
4753
4754	switch (action) {
4755	case ALC_FIXUP_ACT_PRE_PROBE:
4756		alc_apply_pincfgs(codec, pincfgs);
4757		break;
4758	case ALC_FIXUP_ACT_PROBE:
4759		spec->init_amp = ALC_INIT_NONE;
4760		break;
4761	}
4762}
4763
4764static const struct alc_fixup alc260_fixups[] = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4765	[ALC260_FIXUP_HP_DC5750] = {
4766		.type = ALC_FIXUP_PINS,
4767		.v.pins = (const struct alc_pincfg[]) {
4768			{ 0x11, 0x90130110 }, /* speaker */
4769			{ }
4770		}
4771	},
4772	[ALC260_FIXUP_HP_PIN_0F] = {
4773		.type = ALC_FIXUP_PINS,
4774		.v.pins = (const struct alc_pincfg[]) {
4775			{ 0x0f, 0x01214000 }, /* HP */
4776			{ }
4777		}
4778	},
4779	[ALC260_FIXUP_COEF] = {
4780		.type = ALC_FIXUP_VERBS,
4781		.v.verbs = (const struct hda_verb[]) {
4782			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4783			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3040 },
4784			{ }
4785		},
4786		.chained = true,
4787		.chain_id = ALC260_FIXUP_HP_PIN_0F,
4788	},
4789	[ALC260_FIXUP_GPIO1] = {
4790		.type = ALC_FIXUP_VERBS,
4791		.v.verbs = alc_gpio1_init_verbs,
4792	},
4793	[ALC260_FIXUP_GPIO1_TOGGLE] = {
4794		.type = ALC_FIXUP_FUNC,
4795		.v.func = alc260_fixup_gpio1_toggle,
4796		.chained = true,
4797		.chain_id = ALC260_FIXUP_HP_PIN_0F,
4798	},
4799	[ALC260_FIXUP_REPLACER] = {
4800		.type = ALC_FIXUP_VERBS,
4801		.v.verbs = (const struct hda_verb[]) {
4802			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4803			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3050 },
4804			{ }
4805		},
4806		.chained = true,
4807		.chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
4808	},
4809	[ALC260_FIXUP_HP_B1900] = {
4810		.type = ALC_FIXUP_FUNC,
4811		.v.func = alc260_fixup_gpio1_toggle,
4812		.chained = true,
4813		.chain_id = ALC260_FIXUP_COEF,
4814	},
4815	[ALC260_FIXUP_KN1] = {
4816		.type = ALC_FIXUP_FUNC,
4817		.v.func = alc260_fixup_kn1,
4818	},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4819};
4820
4821static const struct snd_pci_quirk alc260_fixup_tbl[] = {
4822	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
4823	SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
4824	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
4825	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
4826	SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
 
 
 
4827	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
4828	SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
4829	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
4830	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
4831	{}
4832};
4833
 
 
 
 
 
 
 
 
4834/*
4835 */
4836static int patch_alc260(struct hda_codec *codec)
4837{
4838	struct alc_spec *spec;
4839	int err;
4840
4841	err = alc_alloc_spec(codec, 0x07);
4842	if (err < 0)
4843		return err;
4844
4845	spec = codec->spec;
 
 
 
 
 
 
4846
4847	alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
4848	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
4849
4850	/* automatic parse from the BIOS config */
4851	err = alc260_parse_auto_config(codec);
4852	if (err < 0)
4853		goto error;
4854
4855	if (!spec->no_analog) {
4856		err = snd_hda_attach_beep_device(codec, 0x1);
4857		if (err < 0)
4858			goto error;
4859		set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
4860	}
4861
4862	codec->patch_ops = alc_patch_ops;
4863	spec->shutup = alc_eapd_shutup;
4864
4865	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4866
4867	return 0;
4868
4869 error:
4870	alc_free(codec);
4871	return err;
4872}
4873
4874
4875/*
4876 * ALC882/883/885/888/889 support
4877 *
4878 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4879 * configuration.  Each pin widget can choose any input DACs and a mixer.
4880 * Each ADC is connected from a mixer of all inputs.  This makes possible
4881 * 6-channel independent captures.
4882 *
4883 * In addition, an independent DAC for the multi-playback (not used in this
4884 * driver yet).
4885 */
4886
4887/*
4888 * Pin config fixes
4889 */
4890enum {
4891	ALC882_FIXUP_ABIT_AW9D_MAX,
4892	ALC882_FIXUP_LENOVO_Y530,
4893	ALC882_FIXUP_PB_M5210,
4894	ALC882_FIXUP_ACER_ASPIRE_7736,
4895	ALC882_FIXUP_ASUS_W90V,
4896	ALC889_FIXUP_CD,
 
4897	ALC889_FIXUP_VAIO_TT,
4898	ALC888_FIXUP_EEE1601,
4899	ALC882_FIXUP_EAPD,
4900	ALC883_FIXUP_EAPD,
4901	ALC883_FIXUP_ACER_EAPD,
4902	ALC882_FIXUP_GPIO1,
4903	ALC882_FIXUP_GPIO2,
4904	ALC882_FIXUP_GPIO3,
4905	ALC889_FIXUP_COEF,
4906	ALC882_FIXUP_ASUS_W2JC,
4907	ALC882_FIXUP_ACER_ASPIRE_4930G,
4908	ALC882_FIXUP_ACER_ASPIRE_8930G,
4909	ALC882_FIXUP_ASPIRE_8930G_VERBS,
4910	ALC885_FIXUP_MACPRO_GPIO,
4911	ALC889_FIXUP_DAC_ROUTE,
4912	ALC889_FIXUP_MBP_VREF,
4913	ALC889_FIXUP_IMAC91_VREF,
 
 
 
 
4914	ALC882_FIXUP_NO_PRIMARY_HP,
 
 
4915};
4916
4917static void alc889_fixup_coef(struct hda_codec *codec,
4918			      const struct alc_fixup *fix, int action)
4919{
4920	if (action != ALC_FIXUP_ACT_INIT)
4921		return;
4922	alc889_coef_init(codec);
4923}
4924
4925/* toggle speaker-output according to the hp-jack state */
4926static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
4927{
4928	unsigned int gpiostate, gpiomask, gpiodir;
4929
4930	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
4931				       AC_VERB_GET_GPIO_DATA, 0);
4932
4933	if (!muted)
4934		gpiostate |= (1 << pin);
4935	else
4936		gpiostate &= ~(1 << pin);
4937
4938	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
4939				      AC_VERB_GET_GPIO_MASK, 0);
4940	gpiomask |= (1 << pin);
4941
4942	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
4943				     AC_VERB_GET_GPIO_DIRECTION, 0);
4944	gpiodir |= (1 << pin);
4945
4946
4947	snd_hda_codec_write(codec, codec->afg, 0,
4948			    AC_VERB_SET_GPIO_MASK, gpiomask);
4949	snd_hda_codec_write(codec, codec->afg, 0,
4950			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
4951
4952	msleep(1);
4953
4954	snd_hda_codec_write(codec, codec->afg, 0,
4955			    AC_VERB_SET_GPIO_DATA, gpiostate);
4956}
4957
4958/* set up GPIO at initialization */
4959static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
4960				     const struct alc_fixup *fix, int action)
4961{
4962	if (action != ALC_FIXUP_ACT_INIT)
4963		return;
4964	alc882_gpio_mute(codec, 0, 0);
4965	alc882_gpio_mute(codec, 1, 0);
4966}
4967
4968/* Fix the connection of some pins for ALC889:
4969 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
4970 * work correctly (bko#42740)
4971 */
4972static void alc889_fixup_dac_route(struct hda_codec *codec,
4973				   const struct alc_fixup *fix, int action)
4974{
4975	if (action == ALC_FIXUP_ACT_PRE_PROBE) {
4976		/* fake the connections during parsing the tree */
4977		hda_nid_t conn1[2] = { 0x0c, 0x0d };
4978		hda_nid_t conn2[2] = { 0x0e, 0x0f };
4979		snd_hda_override_conn_list(codec, 0x14, 2, conn1);
4980		snd_hda_override_conn_list(codec, 0x15, 2, conn1);
4981		snd_hda_override_conn_list(codec, 0x18, 2, conn2);
4982		snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
4983	} else if (action == ALC_FIXUP_ACT_PROBE) {
4984		/* restore the connections */
4985		hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
4986		snd_hda_override_conn_list(codec, 0x14, 5, conn);
4987		snd_hda_override_conn_list(codec, 0x15, 5, conn);
4988		snd_hda_override_conn_list(codec, 0x18, 5, conn);
4989		snd_hda_override_conn_list(codec, 0x1a, 5, conn);
4990	}
4991}
4992
4993/* Set VREF on HP pin */
4994static void alc889_fixup_mbp_vref(struct hda_codec *codec,
4995				  const struct alc_fixup *fix, int action)
4996{
4997	struct alc_spec *spec = codec->spec;
4998	static hda_nid_t nids[2] = { 0x14, 0x15 };
4999	int i;
5000
5001	if (action != ALC_FIXUP_ACT_INIT)
5002		return;
5003	for (i = 0; i < ARRAY_SIZE(nids); i++) {
5004		unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
5005		if (get_defcfg_device(val) != AC_JACK_HP_OUT)
5006			continue;
5007		val = snd_hda_codec_read(codec, nids[i], 0,
5008					 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5009		val |= AC_PINCTL_VREF_80;
5010		snd_hda_set_pin_ctl(codec, nids[i], val);
5011		spec->keep_vref_in_automute = 1;
5012		break;
5013	}
5014}
5015
5016/* Set VREF on speaker pins on imac91 */
5017static void alc889_fixup_imac91_vref(struct hda_codec *codec,
5018				     const struct alc_fixup *fix, int action)
5019{
5020	struct alc_spec *spec = codec->spec;
5021	static hda_nid_t nids[2] = { 0x18, 0x1a };
5022	int i;
5023
5024	if (action != ALC_FIXUP_ACT_INIT)
5025		return;
5026	for (i = 0; i < ARRAY_SIZE(nids); i++) {
5027		unsigned int val;
5028		val = snd_hda_codec_read(codec, nids[i], 0,
5029					 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5030		val |= AC_PINCTL_VREF_50;
5031		snd_hda_set_pin_ctl(codec, nids[i], val);
5032	}
5033	spec->keep_vref_in_automute = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5034}
5035
5036/* Don't take HP output as primary
5037 * strangely, the speaker output doesn't work on VAIO Z through DAC 0x05
 
5038 */
5039static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
5040				       const struct alc_fixup *fix, int action)
5041{
5042	struct alc_spec *spec = codec->spec;
5043	if (action == ALC_FIXUP_ACT_PRE_PROBE)
5044		spec->no_primary_hp = 1;
 
 
5045}
5046
5047static const struct alc_fixup alc882_fixups[] = {
 
 
 
5048	[ALC882_FIXUP_ABIT_AW9D_MAX] = {
5049		.type = ALC_FIXUP_PINS,
5050		.v.pins = (const struct alc_pincfg[]) {
5051			{ 0x15, 0x01080104 }, /* side */
5052			{ 0x16, 0x01011012 }, /* rear */
5053			{ 0x17, 0x01016011 }, /* clfe */
5054			{ }
5055		}
5056	},
5057	[ALC882_FIXUP_LENOVO_Y530] = {
5058		.type = ALC_FIXUP_PINS,
5059		.v.pins = (const struct alc_pincfg[]) {
5060			{ 0x15, 0x99130112 }, /* rear int speakers */
5061			{ 0x16, 0x99130111 }, /* subwoofer */
5062			{ }
5063		}
5064	},
5065	[ALC882_FIXUP_PB_M5210] = {
5066		.type = ALC_FIXUP_VERBS,
5067		.v.verbs = (const struct hda_verb[]) {
5068			{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
5069			{}
5070		}
5071	},
5072	[ALC882_FIXUP_ACER_ASPIRE_7736] = {
5073		.type = ALC_FIXUP_FUNC,
5074		.v.func = alc_fixup_sku_ignore,
5075	},
5076	[ALC882_FIXUP_ASUS_W90V] = {
5077		.type = ALC_FIXUP_PINS,
5078		.v.pins = (const struct alc_pincfg[]) {
5079			{ 0x16, 0x99130110 }, /* fix sequence for CLFE */
5080			{ }
5081		}
5082	},
5083	[ALC889_FIXUP_CD] = {
5084		.type = ALC_FIXUP_PINS,
5085		.v.pins = (const struct alc_pincfg[]) {
5086			{ 0x1c, 0x993301f0 }, /* CD */
5087			{ }
5088		}
5089	},
 
 
 
 
 
 
 
 
 
5090	[ALC889_FIXUP_VAIO_TT] = {
5091		.type = ALC_FIXUP_PINS,
5092		.v.pins = (const struct alc_pincfg[]) {
5093			{ 0x17, 0x90170111 }, /* hidden surround speaker */
5094			{ }
5095		}
5096	},
5097	[ALC888_FIXUP_EEE1601] = {
5098		.type = ALC_FIXUP_VERBS,
5099		.v.verbs = (const struct hda_verb[]) {
5100			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
5101			{ 0x20, AC_VERB_SET_PROC_COEF,  0x0838 },
5102			{ }
5103		}
5104	},
5105	[ALC882_FIXUP_EAPD] = {
5106		.type = ALC_FIXUP_VERBS,
5107		.v.verbs = (const struct hda_verb[]) {
5108			/* change to EAPD mode */
5109			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
5110			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
5111			{ }
5112		}
5113	},
5114	[ALC883_FIXUP_EAPD] = {
5115		.type = ALC_FIXUP_VERBS,
5116		.v.verbs = (const struct hda_verb[]) {
5117			/* change to EAPD mode */
5118			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
5119			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
5120			{ }
5121		}
5122	},
5123	[ALC883_FIXUP_ACER_EAPD] = {
5124		.type = ALC_FIXUP_VERBS,
5125		.v.verbs = (const struct hda_verb[]) {
5126			/* eanable EAPD on Acer laptops */
5127			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
5128			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
5129			{ }
5130		}
5131	},
5132	[ALC882_FIXUP_GPIO1] = {
5133		.type = ALC_FIXUP_VERBS,
5134		.v.verbs = alc_gpio1_init_verbs,
5135	},
5136	[ALC882_FIXUP_GPIO2] = {
5137		.type = ALC_FIXUP_VERBS,
5138		.v.verbs = alc_gpio2_init_verbs,
5139	},
5140	[ALC882_FIXUP_GPIO3] = {
5141		.type = ALC_FIXUP_VERBS,
5142		.v.verbs = alc_gpio3_init_verbs,
5143	},
5144	[ALC882_FIXUP_ASUS_W2JC] = {
5145		.type = ALC_FIXUP_VERBS,
5146		.v.verbs = alc_gpio1_init_verbs,
5147		.chained = true,
5148		.chain_id = ALC882_FIXUP_EAPD,
5149	},
5150	[ALC889_FIXUP_COEF] = {
5151		.type = ALC_FIXUP_FUNC,
5152		.v.func = alc889_fixup_coef,
5153	},
5154	[ALC882_FIXUP_ACER_ASPIRE_4930G] = {
5155		.type = ALC_FIXUP_PINS,
5156		.v.pins = (const struct alc_pincfg[]) {
5157			{ 0x16, 0x99130111 }, /* CLFE speaker */
5158			{ 0x17, 0x99130112 }, /* surround speaker */
5159			{ }
5160		},
5161		.chained = true,
5162		.chain_id = ALC882_FIXUP_GPIO1,
5163	},
5164	[ALC882_FIXUP_ACER_ASPIRE_8930G] = {
5165		.type = ALC_FIXUP_PINS,
5166		.v.pins = (const struct alc_pincfg[]) {
5167			{ 0x16, 0x99130111 }, /* CLFE speaker */
5168			{ 0x1b, 0x99130112 }, /* surround speaker */
5169			{ }
5170		},
5171		.chained = true,
5172		.chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
5173	},
5174	[ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
5175		/* additional init verbs for Acer Aspire 8930G */
5176		.type = ALC_FIXUP_VERBS,
5177		.v.verbs = (const struct hda_verb[]) {
5178			/* Enable all DACs */
5179			/* DAC DISABLE/MUTE 1? */
5180			/*  setting bits 1-5 disables DAC nids 0x02-0x06
5181			 *  apparently. Init=0x38 */
5182			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
5183			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
5184			/* DAC DISABLE/MUTE 2? */
5185			/*  some bit here disables the other DACs.
5186			 *  Init=0x4900 */
5187			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
5188			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
5189			/* DMIC fix
5190			 * This laptop has a stereo digital microphone.
5191			 * The mics are only 1cm apart which makes the stereo
5192			 * useless. However, either the mic or the ALC889
5193			 * makes the signal become a difference/sum signal
5194			 * instead of standard stereo, which is annoying.
5195			 * So instead we flip this bit which makes the
5196			 * codec replicate the sum signal to both channels,
5197			 * turning it into a normal mono mic.
5198			 */
5199			/* DMIC_CONTROL? Init value = 0x0001 */
5200			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
5201			{ 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
5202			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
5203			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
5204			{ }
5205		},
5206		.chained = true,
5207		.chain_id = ALC882_FIXUP_GPIO1,
5208	},
5209	[ALC885_FIXUP_MACPRO_GPIO] = {
5210		.type = ALC_FIXUP_FUNC,
5211		.v.func = alc885_fixup_macpro_gpio,
5212	},
5213	[ALC889_FIXUP_DAC_ROUTE] = {
5214		.type = ALC_FIXUP_FUNC,
5215		.v.func = alc889_fixup_dac_route,
5216	},
5217	[ALC889_FIXUP_MBP_VREF] = {
5218		.type = ALC_FIXUP_FUNC,
5219		.v.func = alc889_fixup_mbp_vref,
5220		.chained = true,
5221		.chain_id = ALC882_FIXUP_GPIO1,
5222	},
5223	[ALC889_FIXUP_IMAC91_VREF] = {
5224		.type = ALC_FIXUP_FUNC,
5225		.v.func = alc889_fixup_imac91_vref,
5226		.chained = true,
5227		.chain_id = ALC882_FIXUP_GPIO1,
5228	},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5229	[ALC882_FIXUP_NO_PRIMARY_HP] = {
5230		.type = ALC_FIXUP_FUNC,
5231		.v.func = alc882_fixup_no_primary_hp,
5232	},
 
 
 
 
 
 
 
 
 
 
 
 
 
5233};
5234
5235static const struct snd_pci_quirk alc882_fixup_tbl[] = {
5236	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
5237	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
5238	SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
5239	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
5240	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
5241	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
5242	SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
5243		      ALC882_FIXUP_ACER_ASPIRE_4930G),
5244	SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
5245		      ALC882_FIXUP_ACER_ASPIRE_4930G),
5246	SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
5247		      ALC882_FIXUP_ACER_ASPIRE_8930G),
5248	SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
5249		      ALC882_FIXUP_ACER_ASPIRE_8930G),
5250	SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
5251		      ALC882_FIXUP_ACER_ASPIRE_4930G),
5252	SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
5253		      ALC882_FIXUP_ACER_ASPIRE_4930G),
5254	SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
5255		      ALC882_FIXUP_ACER_ASPIRE_4930G),
5256	SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
5257	SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
5258		      ALC882_FIXUP_ACER_ASPIRE_4930G),
5259	SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
5260	SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
5261	SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
5262	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
5263	SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
5264	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
5265	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
 
5266	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
5267	SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
 
5268
5269	/* All Apple entries are in codec SSIDs */
5270	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
5271	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
5272	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
5273	SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO),
5274	SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
5275	SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
5276	SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
5277	SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
5278	SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
5279	SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
5280	SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF),
5281	SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
5282	SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
5283	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
5284	SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
5285	SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
5286	SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
5287	SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
 
5288	SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
5289	SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
5290	SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
5291
5292	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
5293	SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
5294	SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
5295	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD),
5296	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
5297	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
5298	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
5299	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
5300	SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
5301	{}
5302};
5303
5304static const struct alc_model_fixup alc882_fixup_models[] = {
5305	{.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
5306	{.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
5307	{.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
 
5308	{.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
5309	{}
5310};
5311
5312/*
5313 * BIOS auto configuration
5314 */
5315/* almost identical with ALC880 parser... */
5316static int alc882_parse_auto_config(struct hda_codec *codec)
5317{
5318	static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
5319	static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5320	return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
5321}
5322
5323/*
5324 */
5325static int patch_alc882(struct hda_codec *codec)
5326{
5327	struct alc_spec *spec;
5328	int err;
5329
5330	err = alc_alloc_spec(codec, 0x0b);
5331	if (err < 0)
5332		return err;
5333
5334	spec = codec->spec;
5335
5336	switch (codec->vendor_id) {
5337	case 0x10ec0882:
5338	case 0x10ec0885:
5339		break;
5340	default:
5341		/* ALC883 and variants */
5342		alc_fix_pll_init(codec, 0x20, 0x0a, 10);
5343		break;
5344	}
5345
5346	alc_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
5347		       alc882_fixups);
5348	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
5349
5350	alc_auto_parse_customize_define(codec);
5351
 
 
 
5352	/* automatic parse from the BIOS config */
5353	err = alc882_parse_auto_config(codec);
5354	if (err < 0)
5355		goto error;
5356
5357	if (!spec->no_analog && has_cdefine_beep(codec)) {
5358		err = snd_hda_attach_beep_device(codec, 0x1);
5359		if (err < 0)
5360			goto error;
5361		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5362	}
5363
5364	codec->patch_ops = alc_patch_ops;
5365
5366	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5367
5368	return 0;
5369
5370 error:
5371	alc_free(codec);
5372	return err;
5373}
5374
5375
5376/*
5377 * ALC262 support
5378 */
5379static int alc262_parse_auto_config(struct hda_codec *codec)
5380{
5381	static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
5382	static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5383	return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
5384}
5385
5386/*
5387 * Pin config fixes
5388 */
5389enum {
5390	ALC262_FIXUP_FSC_H270,
 
5391	ALC262_FIXUP_HP_Z200,
5392	ALC262_FIXUP_TYAN,
5393	ALC262_FIXUP_LENOVO_3000,
5394	ALC262_FIXUP_BENQ,
5395	ALC262_FIXUP_BENQ_T31,
 
 
5396};
5397
5398static const struct alc_fixup alc262_fixups[] = {
5399	[ALC262_FIXUP_FSC_H270] = {
5400		.type = ALC_FIXUP_PINS,
5401		.v.pins = (const struct alc_pincfg[]) {
5402			{ 0x14, 0x99130110 }, /* speaker */
5403			{ 0x15, 0x0221142f }, /* front HP */
5404			{ 0x1b, 0x0121141f }, /* rear HP */
5405			{ }
5406		}
5407	},
 
 
 
 
 
 
 
 
 
5408	[ALC262_FIXUP_HP_Z200] = {
5409		.type = ALC_FIXUP_PINS,
5410		.v.pins = (const struct alc_pincfg[]) {
5411			{ 0x16, 0x99130120 }, /* internal speaker */
5412			{ }
5413		}
5414	},
5415	[ALC262_FIXUP_TYAN] = {
5416		.type = ALC_FIXUP_PINS,
5417		.v.pins = (const struct alc_pincfg[]) {
5418			{ 0x14, 0x1993e1f0 }, /* int AUX */
5419			{ }
5420		}
5421	},
5422	[ALC262_FIXUP_LENOVO_3000] = {
5423		.type = ALC_FIXUP_VERBS,
5424		.v.verbs = (const struct hda_verb[]) {
5425			{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
5426			{}
5427		},
5428		.chained = true,
5429		.chain_id = ALC262_FIXUP_BENQ,
5430	},
5431	[ALC262_FIXUP_BENQ] = {
5432		.type = ALC_FIXUP_VERBS,
5433		.v.verbs = (const struct hda_verb[]) {
5434			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
5435			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
5436			{}
5437		}
5438	},
5439	[ALC262_FIXUP_BENQ_T31] = {
5440		.type = ALC_FIXUP_VERBS,
5441		.v.verbs = (const struct hda_verb[]) {
5442			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
5443			{ 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
5444			{}
5445		}
5446	},
 
 
 
 
 
 
 
 
5447};
5448
5449static const struct snd_pci_quirk alc262_fixup_tbl[] = {
5450	SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
5451	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ),
5452	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
5453	SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
5454	SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
5455	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
5456	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
5457	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
 
5458	{}
5459};
5460
 
 
 
 
5461
5462/*
5463 */
5464static int patch_alc262(struct hda_codec *codec)
5465{
5466	struct alc_spec *spec;
5467	int err;
5468
5469	err = alc_alloc_spec(codec, 0x0b);
5470	if (err < 0)
5471		return err;
5472
5473	spec = codec->spec;
 
5474
5475#if 0
5476	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
5477	 * under-run
5478	 */
5479	{
5480	int tmp;
5481	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
5482	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
5483	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
5484	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
5485	}
5486#endif
5487	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
5488
5489	alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
5490	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
 
5491
5492	alc_auto_parse_customize_define(codec);
5493
 
 
 
5494	/* automatic parse from the BIOS config */
5495	err = alc262_parse_auto_config(codec);
5496	if (err < 0)
5497		goto error;
5498
5499	if (!spec->no_analog && has_cdefine_beep(codec)) {
5500		err = snd_hda_attach_beep_device(codec, 0x1);
5501		if (err < 0)
5502			goto error;
5503		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5504	}
5505
5506	codec->patch_ops = alc_patch_ops;
5507	spec->shutup = alc_eapd_shutup;
5508
5509	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5510
5511	return 0;
5512
5513 error:
5514	alc_free(codec);
5515	return err;
5516}
5517
5518/*
5519 *  ALC268
5520 */
5521/* bind Beep switches of both NID 0x0f and 0x10 */
5522static const struct hda_bind_ctls alc268_bind_beep_sw = {
5523	.ops = &snd_hda_bind_sw,
5524	.values = {
5525		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
5526		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
5527		0
5528	},
5529};
5530
5531static const struct snd_kcontrol_new alc268_beep_mixer[] = {
5532	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
5533	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
5534	{ }
5535};
5536
5537/* set PCBEEP vol = 0, mute connections */
5538static const struct hda_verb alc268_beep_init_verbs[] = {
5539	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5540	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5541	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5542	{ }
5543};
5544
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5545/*
5546 * BIOS auto configuration
5547 */
5548static int alc268_parse_auto_config(struct hda_codec *codec)
5549{
5550	static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5551	struct alc_spec *spec = codec->spec;
5552	int err = alc_parse_auto_config(codec, NULL, alc268_ssids);
5553	if (err > 0) {
5554		if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
5555			add_mixer(spec, alc268_beep_mixer);
5556			snd_hda_gen_add_verbs(&spec->gen, alc268_beep_init_verbs);
5557		}
5558	}
5559	return err;
5560}
5561
5562/*
5563 */
5564static int patch_alc268(struct hda_codec *codec)
5565{
5566	struct alc_spec *spec;
5567	int i, has_beep, err;
5568
5569	/* ALC268 has no aa-loopback mixer */
5570	err = alc_alloc_spec(codec, 0);
5571	if (err < 0)
5572		return err;
5573
5574	spec = codec->spec;
 
 
 
 
5575
5576	/* automatic parse from the BIOS config */
5577	err = alc268_parse_auto_config(codec);
5578	if (err < 0)
5579		goto error;
5580
5581	has_beep = 0;
5582	for (i = 0; i < spec->num_mixers; i++) {
5583		if (spec->mixers[i] == alc268_beep_mixer) {
5584			has_beep = 1;
5585			break;
5586		}
5587	}
5588
5589	if (has_beep) {
5590		err = snd_hda_attach_beep_device(codec, 0x1);
5591		if (err < 0)
5592			goto error;
5593		if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
5594			/* override the amp caps for beep generator */
5595			snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
5596					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
5597					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
5598					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
5599					  (0 << AC_AMPCAP_MUTE_SHIFT));
5600	}
5601
5602	codec->patch_ops = alc_patch_ops;
5603	spec->shutup = alc_eapd_shutup;
5604
 
 
5605	return 0;
5606
5607 error:
5608	alc_free(codec);
5609	return err;
5610}
5611
5612/*
5613 * ALC269
5614 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5615static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
5616	.substreams = 1,
5617	.channels_min = 2,
5618	.channels_max = 8,
5619	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
5620	/* NID is set in alc_build_pcms */
5621	.ops = {
5622		.open = alc_playback_pcm_open,
5623		.prepare = alc_playback_pcm_prepare,
5624		.cleanup = alc_playback_pcm_cleanup
5625	},
5626};
5627
5628static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
5629	.substreams = 1,
5630	.channels_min = 2,
5631	.channels_max = 2,
5632	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
5633	/* NID is set in alc_build_pcms */
5634};
5635
5636/* different alc269-variants */
5637enum {
5638	ALC269_TYPE_ALC269VA,
5639	ALC269_TYPE_ALC269VB,
5640	ALC269_TYPE_ALC269VC,
5641	ALC269_TYPE_ALC269VD,
 
 
 
 
 
 
 
5642};
5643
5644/*
5645 * BIOS auto configuration
5646 */
5647static int alc269_parse_auto_config(struct hda_codec *codec)
5648{
5649	static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
5650	static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
5651	static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5652	struct alc_spec *spec = codec->spec;
5653	const hda_nid_t *ssids;
5654
5655	switch (spec->codec_variant) {
5656	case ALC269_TYPE_ALC269VA:
5657	case ALC269_TYPE_ALC269VC:
 
 
 
5658		ssids = alc269va_ssids;
5659		break;
5660	case ALC269_TYPE_ALC269VB:
5661	case ALC269_TYPE_ALC269VD:
 
 
 
 
5662		ssids = alc269_ssids;
5663		break;
5664	default:
5665		ssids = alc269_ssids;
5666		break;
5667	}
5668
5669	return alc_parse_auto_config(codec, alc269_ignore, ssids);
5670}
5671
5672static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
5673{
5674	int val = alc_read_coef_idx(codec, 0x04);
5675	if (power_up)
5676		val |= 1 << 11;
5677	else
5678		val &= ~(1 << 11);
5679	alc_write_coef_idx(codec, 0x04, val);
5680}
5681
5682static void alc269_shutup(struct hda_codec *codec)
5683{
5684	struct alc_spec *spec = codec->spec;
5685
5686	if (spec->codec_variant != ALC269_TYPE_ALC269VB)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5687		return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5688
5689	if ((alc_get_coef0(codec) & 0x00ff) == 0x017)
5690		alc269_toggle_power_output(codec, 0);
5691	if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
5692		alc269_toggle_power_output(codec, 0);
5693		msleep(150);
 
 
 
 
 
 
 
 
 
 
5694	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5695}
5696
 
 
 
 
 
 
 
 
5697#ifdef CONFIG_PM
 
 
 
 
 
 
 
 
 
5698static int alc269_resume(struct hda_codec *codec)
5699{
5700	struct alc_spec *spec = codec->spec;
5701
5702	if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
 
 
5703			(alc_get_coef0(codec) & 0x00ff) == 0x018) {
5704		alc269_toggle_power_output(codec, 0);
5705		msleep(150);
5706	}
5707
5708	codec->patch_ops.init(codec);
5709
5710	if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
 
 
5711			(alc_get_coef0(codec) & 0x00ff) == 0x017) {
5712		alc269_toggle_power_output(codec, 1);
5713		msleep(200);
5714	}
5715
5716	if (spec->codec_variant == ALC269_TYPE_ALC269VB ||
5717			(alc_get_coef0(codec) & 0x00ff) == 0x018)
5718		alc269_toggle_power_output(codec, 1);
5719
5720	snd_hda_codec_resume_amp(codec);
5721	snd_hda_codec_resume_cache(codec);
 
5722	hda_call_check_power_status(codec, 0x01);
 
 
 
5723	return 0;
5724}
5725#endif /* CONFIG_PM */
5726
5727static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
5728						 const struct alc_fixup *fix, int action)
5729{
5730	struct alc_spec *spec = codec->spec;
5731
5732	if (action == ALC_FIXUP_ACT_PRE_PROBE)
5733		spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5734}
5735
5736static void alc269_fixup_hweq(struct hda_codec *codec,
5737			       const struct alc_fixup *fix, int action)
5738{
5739	int coef;
5740
5741	if (action != ALC_FIXUP_ACT_INIT)
5742		return;
5743	coef = alc_read_coef_idx(codec, 0x1e);
5744	alc_write_coef_idx(codec, 0x1e, coef | 0x80);
5745}
5746
 
 
 
 
 
 
 
 
 
5747static void alc271_fixup_dmic(struct hda_codec *codec,
5748			      const struct alc_fixup *fix, int action)
5749{
5750	static const struct hda_verb verbs[] = {
5751		{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
5752		{0x20, AC_VERB_SET_PROC_COEF, 0x4000},
5753		{}
5754	};
5755	unsigned int cfg;
5756
5757	if (strcmp(codec->chip_name, "ALC271X"))
 
5758		return;
5759	cfg = snd_hda_codec_get_pincfg(codec, 0x12);
5760	if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
5761		snd_hda_sequence_write(codec, verbs);
5762}
5763
5764static void alc269_fixup_pcm_44k(struct hda_codec *codec,
5765				 const struct alc_fixup *fix, int action)
5766{
5767	struct alc_spec *spec = codec->spec;
5768
5769	if (action != ALC_FIXUP_ACT_PROBE)
5770		return;
5771
5772	/* Due to a hardware problem on Lenovo Ideadpad, we need to
5773	 * fix the sample rate of analog I/O to 44.1kHz
5774	 */
5775	spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
5776	spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
5777}
5778
5779static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
5780				     const struct alc_fixup *fix, int action)
5781{
5782	int coef;
5783
5784	if (action != ALC_FIXUP_ACT_INIT)
5785		return;
5786	/* The digital-mic unit sends PDM (differential signal) instead of
5787	 * the standard PCM, thus you can't record a valid mono stream as is.
5788	 * Below is a workaround specific to ALC269 to control the dmic
5789	 * signal source as mono.
5790	 */
5791	coef = alc_read_coef_idx(codec, 0x07);
5792	alc_write_coef_idx(codec, 0x07, coef | 0x80);
5793}
5794
5795static void alc269_quanta_automute(struct hda_codec *codec)
5796{
5797	update_outputs(codec);
5798
5799	snd_hda_codec_write(codec, 0x20, 0,
5800			AC_VERB_SET_COEF_INDEX, 0x0c);
5801	snd_hda_codec_write(codec, 0x20, 0,
5802			AC_VERB_SET_PROC_COEF, 0x680);
5803
5804	snd_hda_codec_write(codec, 0x20, 0,
5805			AC_VERB_SET_COEF_INDEX, 0x0c);
5806	snd_hda_codec_write(codec, 0x20, 0,
5807			AC_VERB_SET_PROC_COEF, 0x480);
5808}
5809
5810static void alc269_fixup_quanta_mute(struct hda_codec *codec,
5811				     const struct alc_fixup *fix, int action)
5812{
5813	struct alc_spec *spec = codec->spec;
5814	if (action != ALC_FIXUP_ACT_PROBE)
5815		return;
5816	spec->automute_hook = alc269_quanta_automute;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5817}
5818
5819/* update mute-LED according to the speaker mute state via mic2 VREF pin */
5820static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled)
 
 
 
 
 
 
 
 
 
 
 
 
 
5821{
5822	struct hda_codec *codec = private_data;
5823	unsigned int pinval = enabled ? 0x20 : 0x24;
5824	snd_hda_set_pin_ctl_cache(codec, 0x19, pinval);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5825}
5826
5827static void alc269_fixup_mic2_mute(struct hda_codec *codec,
5828				   const struct alc_fixup *fix, int action)
5829{
5830	struct alc_spec *spec = codec->spec;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5831	switch (action) {
5832	case ALC_FIXUP_ACT_BUILD:
5833		spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook;
5834		snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
5835		/* fallthru */
5836	case ALC_FIXUP_ACT_INIT:
5837		snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
5838		break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5839	}
5840}
5841
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5842enum {
5843	ALC269_FIXUP_SONY_VAIO,
5844	ALC275_FIXUP_SONY_VAIO_GPIO2,
5845	ALC269_FIXUP_DELL_M101Z,
5846	ALC269_FIXUP_SKU_IGNORE,
5847	ALC269_FIXUP_ASUS_G73JW,
5848	ALC269_FIXUP_LENOVO_EAPD,
5849	ALC275_FIXUP_SONY_HWEQ,
5850	ALC271_FIXUP_DMIC,
5851	ALC269_FIXUP_PCM_44K,
5852	ALC269_FIXUP_STEREO_DMIC,
 
5853	ALC269_FIXUP_QUANTA_MUTE,
5854	ALC269_FIXUP_LIFEBOOK,
5855	ALC269_FIXUP_AMIC,
5856	ALC269_FIXUP_DMIC,
5857	ALC269VB_FIXUP_AMIC,
5858	ALC269VB_FIXUP_DMIC,
5859	ALC269_FIXUP_MIC2_MUTE_LED,
 
 
 
 
5860	ALC269_FIXUP_LENOVO_DOCK,
 
 
5861	ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5862};
5863
5864static const struct alc_fixup alc269_fixups[] = {
5865	[ALC269_FIXUP_SONY_VAIO] = {
5866		.type = ALC_FIXUP_VERBS,
5867		.v.verbs = (const struct hda_verb[]) {
5868			{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
5869			{}
5870		}
5871	},
5872	[ALC275_FIXUP_SONY_VAIO_GPIO2] = {
5873		.type = ALC_FIXUP_VERBS,
5874		.v.verbs = (const struct hda_verb[]) {
5875			{0x01, AC_VERB_SET_GPIO_MASK, 0x04},
5876			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
5877			{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5878			{ }
5879		},
5880		.chained = true,
5881		.chain_id = ALC269_FIXUP_SONY_VAIO
5882	},
5883	[ALC269_FIXUP_DELL_M101Z] = {
5884		.type = ALC_FIXUP_VERBS,
5885		.v.verbs = (const struct hda_verb[]) {
5886			/* Enables internal speaker */
5887			{0x20, AC_VERB_SET_COEF_INDEX, 13},
5888			{0x20, AC_VERB_SET_PROC_COEF, 0x4040},
5889			{}
5890		}
5891	},
5892	[ALC269_FIXUP_SKU_IGNORE] = {
5893		.type = ALC_FIXUP_FUNC,
5894		.v.func = alc_fixup_sku_ignore,
5895	},
5896	[ALC269_FIXUP_ASUS_G73JW] = {
5897		.type = ALC_FIXUP_PINS,
5898		.v.pins = (const struct alc_pincfg[]) {
5899			{ 0x17, 0x99130111 }, /* subwoofer */
5900			{ }
5901		}
5902	},
5903	[ALC269_FIXUP_LENOVO_EAPD] = {
5904		.type = ALC_FIXUP_VERBS,
5905		.v.verbs = (const struct hda_verb[]) {
5906			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
5907			{}
5908		}
5909	},
5910	[ALC275_FIXUP_SONY_HWEQ] = {
5911		.type = ALC_FIXUP_FUNC,
5912		.v.func = alc269_fixup_hweq,
5913		.chained = true,
5914		.chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
5915	},
5916	[ALC271_FIXUP_DMIC] = {
5917		.type = ALC_FIXUP_FUNC,
5918		.v.func = alc271_fixup_dmic,
5919	},
5920	[ALC269_FIXUP_PCM_44K] = {
5921		.type = ALC_FIXUP_FUNC,
5922		.v.func = alc269_fixup_pcm_44k,
5923		.chained = true,
5924		.chain_id = ALC269_FIXUP_QUANTA_MUTE
5925	},
5926	[ALC269_FIXUP_STEREO_DMIC] = {
5927		.type = ALC_FIXUP_FUNC,
5928		.v.func = alc269_fixup_stereo_dmic,
5929	},
 
 
 
 
5930	[ALC269_FIXUP_QUANTA_MUTE] = {
5931		.type = ALC_FIXUP_FUNC,
5932		.v.func = alc269_fixup_quanta_mute,
5933	},
5934	[ALC269_FIXUP_LIFEBOOK] = {
5935		.type = ALC_FIXUP_PINS,
5936		.v.pins = (const struct alc_pincfg[]) {
5937			{ 0x1a, 0x2101103f }, /* dock line-out */
5938			{ 0x1b, 0x23a11040 }, /* dock mic-in */
5939			{ }
5940		},
5941		.chained = true,
5942		.chain_id = ALC269_FIXUP_QUANTA_MUTE
5943	},
5944	[ALC269_FIXUP_AMIC] = {
5945		.type = ALC_FIXUP_PINS,
5946		.v.pins = (const struct alc_pincfg[]) {
5947			{ 0x14, 0x99130110 }, /* speaker */
5948			{ 0x15, 0x0121401f }, /* HP out */
5949			{ 0x18, 0x01a19c20 }, /* mic */
5950			{ 0x19, 0x99a3092f }, /* int-mic */
5951			{ }
5952		},
5953	},
5954	[ALC269_FIXUP_DMIC] = {
5955		.type = ALC_FIXUP_PINS,
5956		.v.pins = (const struct alc_pincfg[]) {
5957			{ 0x12, 0x99a3092f }, /* int-mic */
5958			{ 0x14, 0x99130110 }, /* speaker */
5959			{ 0x15, 0x0121401f }, /* HP out */
5960			{ 0x18, 0x01a19c20 }, /* mic */
5961			{ }
5962		},
5963	},
5964	[ALC269VB_FIXUP_AMIC] = {
5965		.type = ALC_FIXUP_PINS,
5966		.v.pins = (const struct alc_pincfg[]) {
5967			{ 0x14, 0x99130110 }, /* speaker */
5968			{ 0x18, 0x01a19c20 }, /* mic */
5969			{ 0x19, 0x99a3092f }, /* int-mic */
5970			{ 0x21, 0x0121401f }, /* HP out */
5971			{ }
5972		},
5973	},
5974	[ALC269VB_FIXUP_DMIC] = {
5975		.type = ALC_FIXUP_PINS,
5976		.v.pins = (const struct alc_pincfg[]) {
5977			{ 0x12, 0x99a3092f }, /* int-mic */
5978			{ 0x14, 0x99130110 }, /* speaker */
5979			{ 0x18, 0x01a19c20 }, /* mic */
5980			{ 0x21, 0x0121401f }, /* HP out */
5981			{ }
5982		},
5983	},
5984	[ALC269_FIXUP_MIC2_MUTE_LED] = {
5985		.type = ALC_FIXUP_FUNC,
5986		.v.func = alc269_fixup_mic2_mute,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5987	},
5988	[ALC269_FIXUP_LENOVO_DOCK] = {
5989		.type = ALC_FIXUP_PINS,
5990		.v.pins = (const struct alc_pincfg[]) {
5991			{ 0x19, 0x23a11040 }, /* dock mic */
5992			{ 0x1b, 0x2121103f }, /* dock headphone */
5993			{ }
5994		},
5995		.chained = true,
5996		.chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
5997	},
5998	[ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
5999		.type = ALC_FIXUP_FUNC,
6000		.v.func = alc269_fixup_pincfg_no_hp_to_lineout,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6001	},
6002};
6003
6004static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6005	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
6006	SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6007	SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
6008	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
 
6009	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
6010	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
6011	SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
6012	SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
 
 
 
6013	SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
6014	SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
6015	SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
6016	SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
6017	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6018	SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
6019	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
6020	SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
6021	SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
6022	SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
6023	SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
6024	SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
6025	SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
6026	SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
 
6027	SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
6028	SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
 
 
 
 
 
 
 
 
 
 
6029	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
6030	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
 
 
6031
6032#if 0
6033	/* Below is a quirk table taken from the old code.
6034	 * Basically the device should work as is without the fixup table.
6035	 * If BIOS doesn't give a proper info, enable the corresponding
6036	 * fixup entry.
6037	 */
6038	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
6039		      ALC269_FIXUP_AMIC),
6040	SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
6041	SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
6042	SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
6043	SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
6044	SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
6045	SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
6046	SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
6047	SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
6048	SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
6049	SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
6050	SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
6051	SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
6052	SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
6053	SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
6054	SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
6055	SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
6056	SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
6057	SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
6058	SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
6059	SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
6060	SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
6061	SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
6062	SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
6063	SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
6064	SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
6065	SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
6066	SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
6067	SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
6068	SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
6069	SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
6070	SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
6071	SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
6072	SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
6073	SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
6074	SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
6075	SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
6076	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
6077	SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
6078	SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
6079#endif
6080	{}
6081};
6082
6083static const struct alc_model_fixup alc269_fixup_models[] = {
6084	{.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
6085	{.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
 
 
 
 
6086	{.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
 
 
 
 
 
6087	{}
6088};
6089
6090
6091static void alc269_fill_coef(struct hda_codec *codec)
6092{
6093	struct alc_spec *spec = codec->spec;
6094	int val;
6095
6096	if (spec->codec_variant != ALC269_TYPE_ALC269VB)
6097		return;
6098
6099	if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
6100		alc_write_coef_idx(codec, 0xf, 0x960b);
6101		alc_write_coef_idx(codec, 0xe, 0x8817);
6102	}
6103
6104	if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
6105		alc_write_coef_idx(codec, 0xf, 0x960b);
6106		alc_write_coef_idx(codec, 0xe, 0x8814);
6107	}
6108
6109	if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
6110		val = alc_read_coef_idx(codec, 0x04);
6111		/* Power up output pin */
6112		alc_write_coef_idx(codec, 0x04, val | (1<<11));
6113	}
6114
6115	if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
6116		val = alc_read_coef_idx(codec, 0xd);
6117		if ((val & 0x0c00) >> 10 != 0x1) {
6118			/* Capless ramp up clock control */
6119			alc_write_coef_idx(codec, 0xd, val | (1<<10));
6120		}
6121		val = alc_read_coef_idx(codec, 0x17);
6122		if ((val & 0x01c0) >> 6 != 0x4) {
6123			/* Class D power on reset */
6124			alc_write_coef_idx(codec, 0x17, val | (1<<7));
6125		}
6126	}
6127
6128	val = alc_read_coef_idx(codec, 0xd); /* Class D */
6129	alc_write_coef_idx(codec, 0xd, val | (1<<14));
6130
6131	val = alc_read_coef_idx(codec, 0x4); /* HP */
6132	alc_write_coef_idx(codec, 0x4, val | (1<<11));
6133}
6134
6135/*
6136 */
6137static int patch_alc269(struct hda_codec *codec)
6138{
6139	struct alc_spec *spec;
6140	int err;
6141
6142	err = alc_alloc_spec(codec, 0x0b);
6143	if (err < 0)
6144		return err;
6145
6146	spec = codec->spec;
 
 
 
 
 
 
 
 
 
 
6147
6148	if (codec->vendor_id == 0x10ec0269) {
 
6149		spec->codec_variant = ALC269_TYPE_ALC269VA;
6150		switch (alc_get_coef0(codec) & 0x00f0) {
6151		case 0x0010:
6152			if (codec->bus->pci->subsystem_vendor == 0x1025 &&
 
6153			    spec->cdefine.platform_type == 1)
6154				err = alc_codec_rename(codec, "ALC271X");
6155			spec->codec_variant = ALC269_TYPE_ALC269VB;
6156			break;
6157		case 0x0020:
6158			if (codec->bus->pci->subsystem_vendor == 0x17aa &&
 
6159			    codec->bus->pci->subsystem_device == 0x21f3)
6160				err = alc_codec_rename(codec, "ALC3202");
6161			spec->codec_variant = ALC269_TYPE_ALC269VC;
6162			break;
6163		case 0x0030:
6164			spec->codec_variant = ALC269_TYPE_ALC269VD;
6165			break;
6166		default:
6167			alc_fix_pll_init(codec, 0x20, 0x04, 15);
6168		}
6169		if (err < 0)
6170			goto error;
6171		spec->init_hook = alc269_fill_coef;
6172		alc269_fill_coef(codec);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6173	}
6174
6175	alc_pick_fixup(codec, alc269_fixup_models,
6176		       alc269_fixup_tbl, alc269_fixups);
6177	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
6178
6179	alc_auto_parse_customize_define(codec);
6180
6181	/* automatic parse from the BIOS config */
6182	err = alc269_parse_auto_config(codec);
6183	if (err < 0)
6184		goto error;
6185
6186	if (!spec->no_analog && has_cdefine_beep(codec)) {
6187		err = snd_hda_attach_beep_device(codec, 0x1);
6188		if (err < 0)
6189			goto error;
6190		set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
6191	}
6192
6193	codec->patch_ops = alc_patch_ops;
6194#ifdef CONFIG_PM
 
6195	codec->patch_ops.resume = alc269_resume;
6196#endif
6197	spec->shutup = alc269_shutup;
 
6198
6199	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6200
6201	return 0;
6202
6203 error:
6204	alc_free(codec);
6205	return err;
6206}
6207
6208/*
6209 * ALC861
6210 */
6211
6212static int alc861_parse_auto_config(struct hda_codec *codec)
6213{
6214	static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
6215	static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
6216	return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
6217}
6218
6219/* Pin config fixes */
6220enum {
6221	ALC861_FIXUP_FSC_AMILO_PI1505,
6222	ALC861_FIXUP_AMP_VREF_0F,
6223	ALC861_FIXUP_NO_JACK_DETECT,
6224	ALC861_FIXUP_ASUS_A6RP,
 
6225};
6226
6227/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
6228static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
6229			const struct alc_fixup *fix, int action)
6230{
6231	struct alc_spec *spec = codec->spec;
6232	unsigned int val;
6233
6234	if (action != ALC_FIXUP_ACT_INIT)
6235		return;
6236	val = snd_hda_codec_read(codec, 0x0f, 0,
6237				 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
6238	if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
6239		val |= AC_PINCTL_IN_EN;
6240	val |= AC_PINCTL_VREF_50;
6241	snd_hda_set_pin_ctl(codec, 0x0f, val);
6242	spec->keep_vref_in_automute = 1;
6243}
6244
6245/* suppress the jack-detection */
6246static void alc_fixup_no_jack_detect(struct hda_codec *codec,
6247				     const struct alc_fixup *fix, int action)
6248{
6249	if (action == ALC_FIXUP_ACT_PRE_PROBE)
6250		codec->no_jack_detect = 1;
6251}
6252
6253static const struct alc_fixup alc861_fixups[] = {
6254	[ALC861_FIXUP_FSC_AMILO_PI1505] = {
6255		.type = ALC_FIXUP_PINS,
6256		.v.pins = (const struct alc_pincfg[]) {
6257			{ 0x0b, 0x0221101f }, /* HP */
6258			{ 0x0f, 0x90170310 }, /* speaker */
6259			{ }
6260		}
6261	},
6262	[ALC861_FIXUP_AMP_VREF_0F] = {
6263		.type = ALC_FIXUP_FUNC,
6264		.v.func = alc861_fixup_asus_amp_vref_0f,
6265	},
6266	[ALC861_FIXUP_NO_JACK_DETECT] = {
6267		.type = ALC_FIXUP_FUNC,
6268		.v.func = alc_fixup_no_jack_detect,
6269	},
6270	[ALC861_FIXUP_ASUS_A6RP] = {
6271		.type = ALC_FIXUP_FUNC,
6272		.v.func = alc861_fixup_asus_amp_vref_0f,
6273		.chained = true,
6274		.chain_id = ALC861_FIXUP_NO_JACK_DETECT,
 
 
 
 
 
 
 
 
 
 
6275	}
6276};
6277
6278static const struct snd_pci_quirk alc861_fixup_tbl[] = {
 
 
6279	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
6280	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
6281	SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
6282	SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
6283	SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
6284	SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
6285	{}
6286};
6287
6288/*
6289 */
6290static int patch_alc861(struct hda_codec *codec)
6291{
6292	struct alc_spec *spec;
6293	int err;
6294
6295	err = alc_alloc_spec(codec, 0x15);
6296	if (err < 0)
6297		return err;
6298
6299	spec = codec->spec;
 
6300
6301	alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
6302	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
6303
6304	/* automatic parse from the BIOS config */
6305	err = alc861_parse_auto_config(codec);
6306	if (err < 0)
6307		goto error;
6308
6309	if (!spec->no_analog) {
6310		err = snd_hda_attach_beep_device(codec, 0x23);
6311		if (err < 0)
6312			goto error;
6313		set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
6314	}
6315
6316	codec->patch_ops = alc_patch_ops;
6317#ifdef CONFIG_SND_HDA_POWER_SAVE
6318	spec->power_hook = alc_power_eapd;
6319#endif
6320
6321	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6322
6323	return 0;
6324
6325 error:
6326	alc_free(codec);
6327	return err;
6328}
6329
6330/*
6331 * ALC861-VD support
6332 *
6333 * Based on ALC882
6334 *
6335 * In addition, an independent DAC
6336 */
6337static int alc861vd_parse_auto_config(struct hda_codec *codec)
6338{
6339	static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
6340	static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6341	return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
6342}
6343
6344enum {
6345	ALC660VD_FIX_ASUS_GPIO1,
6346	ALC861VD_FIX_DALLAS,
6347};
6348
6349/* exclude VREF80 */
6350static void alc861vd_fixup_dallas(struct hda_codec *codec,
6351				  const struct alc_fixup *fix, int action)
6352{
6353	if (action == ALC_FIXUP_ACT_PRE_PROBE) {
6354		snd_hda_override_pin_caps(codec, 0x18, 0x00001714);
6355		snd_hda_override_pin_caps(codec, 0x19, 0x0000171c);
6356	}
6357}
6358
6359static const struct alc_fixup alc861vd_fixups[] = {
6360	[ALC660VD_FIX_ASUS_GPIO1] = {
6361		.type = ALC_FIXUP_VERBS,
6362		.v.verbs = (const struct hda_verb[]) {
6363			/* reset GPIO1 */
6364			{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6365			{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6366			{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6367			{ }
6368		}
6369	},
6370	[ALC861VD_FIX_DALLAS] = {
6371		.type = ALC_FIXUP_FUNC,
6372		.v.func = alc861vd_fixup_dallas,
6373	},
6374};
6375
6376static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
6377	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
6378	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
6379	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
6380	{}
6381};
6382
6383static const struct hda_verb alc660vd_eapd_verbs[] = {
6384	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
6385	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
6386	{ }
6387};
6388
6389/*
6390 */
6391static int patch_alc861vd(struct hda_codec *codec)
6392{
6393	struct alc_spec *spec;
6394	int err;
6395
6396	err = alc_alloc_spec(codec, 0x0b);
6397	if (err < 0)
6398		return err;
6399
6400	spec = codec->spec;
 
6401
6402	alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
6403	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
6404
6405	/* automatic parse from the BIOS config */
6406	err = alc861vd_parse_auto_config(codec);
6407	if (err < 0)
6408		goto error;
6409
6410	if (codec->vendor_id == 0x10ec0660) {
6411		/* always turn on EAPD */
6412		snd_hda_gen_add_verbs(&spec->gen, alc660vd_eapd_verbs);
6413	}
6414
6415	if (!spec->no_analog) {
6416		err = snd_hda_attach_beep_device(codec, 0x23);
6417		if (err < 0)
6418			goto error;
6419		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6420	}
6421
6422	codec->patch_ops = alc_patch_ops;
6423
6424	spec->shutup = alc_eapd_shutup;
6425
6426	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6427
6428	return 0;
6429
6430 error:
6431	alc_free(codec);
6432	return err;
6433}
6434
6435/*
6436 * ALC662 support
6437 *
6438 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
6439 * configuration.  Each pin widget can choose any input DACs and a mixer.
6440 * Each ADC is connected from a mixer of all inputs.  This makes possible
6441 * 6-channel independent captures.
6442 *
6443 * In addition, an independent DAC for the multi-playback (not used in this
6444 * driver yet).
6445 */
6446
6447/*
6448 * BIOS auto configuration
6449 */
6450
6451static int alc662_parse_auto_config(struct hda_codec *codec)
6452{
6453	static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
6454	static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
6455	static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6456	const hda_nid_t *ssids;
6457
6458	if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
6459	    codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
 
6460		ssids = alc663_ssids;
6461	else
6462		ssids = alc662_ssids;
6463	return alc_parse_auto_config(codec, alc662_ignore, ssids);
6464}
6465
6466static void alc272_fixup_mario(struct hda_codec *codec,
6467			       const struct alc_fixup *fix, int action)
6468{
6469	if (action != ALC_FIXUP_ACT_PROBE)
6470		return;
6471	if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
6472				      (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
6473				      (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
6474				      (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
6475				      (0 << AC_AMPCAP_MUTE_SHIFT)))
6476		printk(KERN_WARNING
6477		       "hda_codec: failed to override amp caps for NID 0x2\n");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6478}
6479
6480enum {
6481	ALC662_FIXUP_ASPIRE,
 
6482	ALC662_FIXUP_IDEAPAD,
6483	ALC272_FIXUP_MARIO,
6484	ALC662_FIXUP_CZC_P10T,
6485	ALC662_FIXUP_SKU_IGNORE,
6486	ALC662_FIXUP_HP_RP5800,
6487	ALC662_FIXUP_ASUS_MODE1,
6488	ALC662_FIXUP_ASUS_MODE2,
6489	ALC662_FIXUP_ASUS_MODE3,
6490	ALC662_FIXUP_ASUS_MODE4,
6491	ALC662_FIXUP_ASUS_MODE5,
6492	ALC662_FIXUP_ASUS_MODE6,
6493	ALC662_FIXUP_ASUS_MODE7,
6494	ALC662_FIXUP_ASUS_MODE8,
6495	ALC662_FIXUP_NO_JACK_DETECT,
6496	ALC662_FIXUP_ZOTAC_Z68,
 
 
 
 
 
 
 
 
6497};
6498
6499static const struct alc_fixup alc662_fixups[] = {
6500	[ALC662_FIXUP_ASPIRE] = {
6501		.type = ALC_FIXUP_PINS,
6502		.v.pins = (const struct alc_pincfg[]) {
6503			{ 0x15, 0x99130112 }, /* subwoofer */
6504			{ }
6505		}
6506	},
 
 
 
 
6507	[ALC662_FIXUP_IDEAPAD] = {
6508		.type = ALC_FIXUP_PINS,
6509		.v.pins = (const struct alc_pincfg[]) {
6510			{ 0x17, 0x99130112 }, /* subwoofer */
6511			{ }
6512		}
 
 
6513	},
6514	[ALC272_FIXUP_MARIO] = {
6515		.type = ALC_FIXUP_FUNC,
6516		.v.func = alc272_fixup_mario,
6517	},
6518	[ALC662_FIXUP_CZC_P10T] = {
6519		.type = ALC_FIXUP_VERBS,
6520		.v.verbs = (const struct hda_verb[]) {
6521			{0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6522			{}
6523		}
6524	},
6525	[ALC662_FIXUP_SKU_IGNORE] = {
6526		.type = ALC_FIXUP_FUNC,
6527		.v.func = alc_fixup_sku_ignore,
6528	},
6529	[ALC662_FIXUP_HP_RP5800] = {
6530		.type = ALC_FIXUP_PINS,
6531		.v.pins = (const struct alc_pincfg[]) {
6532			{ 0x14, 0x0221201f }, /* HP out */
6533			{ }
6534		},
6535		.chained = true,
6536		.chain_id = ALC662_FIXUP_SKU_IGNORE
6537	},
6538	[ALC662_FIXUP_ASUS_MODE1] = {
6539		.type = ALC_FIXUP_PINS,
6540		.v.pins = (const struct alc_pincfg[]) {
6541			{ 0x14, 0x99130110 }, /* speaker */
6542			{ 0x18, 0x01a19c20 }, /* mic */
6543			{ 0x19, 0x99a3092f }, /* int-mic */
6544			{ 0x21, 0x0121401f }, /* HP out */
6545			{ }
6546		},
6547		.chained = true,
6548		.chain_id = ALC662_FIXUP_SKU_IGNORE
6549	},
6550	[ALC662_FIXUP_ASUS_MODE2] = {
6551		.type = ALC_FIXUP_PINS,
6552		.v.pins = (const struct alc_pincfg[]) {
6553			{ 0x14, 0x99130110 }, /* speaker */
6554			{ 0x18, 0x01a19820 }, /* mic */
6555			{ 0x19, 0x99a3092f }, /* int-mic */
6556			{ 0x1b, 0x0121401f }, /* HP out */
6557			{ }
6558		},
6559		.chained = true,
6560		.chain_id = ALC662_FIXUP_SKU_IGNORE
6561	},
6562	[ALC662_FIXUP_ASUS_MODE3] = {
6563		.type = ALC_FIXUP_PINS,
6564		.v.pins = (const struct alc_pincfg[]) {
6565			{ 0x14, 0x99130110 }, /* speaker */
6566			{ 0x15, 0x0121441f }, /* HP */
6567			{ 0x18, 0x01a19840 }, /* mic */
6568			{ 0x19, 0x99a3094f }, /* int-mic */
6569			{ 0x21, 0x01211420 }, /* HP2 */
6570			{ }
6571		},
6572		.chained = true,
6573		.chain_id = ALC662_FIXUP_SKU_IGNORE
6574	},
6575	[ALC662_FIXUP_ASUS_MODE4] = {
6576		.type = ALC_FIXUP_PINS,
6577		.v.pins = (const struct alc_pincfg[]) {
6578			{ 0x14, 0x99130110 }, /* speaker */
6579			{ 0x16, 0x99130111 }, /* speaker */
6580			{ 0x18, 0x01a19840 }, /* mic */
6581			{ 0x19, 0x99a3094f }, /* int-mic */
6582			{ 0x21, 0x0121441f }, /* HP */
6583			{ }
6584		},
6585		.chained = true,
6586		.chain_id = ALC662_FIXUP_SKU_IGNORE
6587	},
6588	[ALC662_FIXUP_ASUS_MODE5] = {
6589		.type = ALC_FIXUP_PINS,
6590		.v.pins = (const struct alc_pincfg[]) {
6591			{ 0x14, 0x99130110 }, /* speaker */
6592			{ 0x15, 0x0121441f }, /* HP */
6593			{ 0x16, 0x99130111 }, /* speaker */
6594			{ 0x18, 0x01a19840 }, /* mic */
6595			{ 0x19, 0x99a3094f }, /* int-mic */
6596			{ }
6597		},
6598		.chained = true,
6599		.chain_id = ALC662_FIXUP_SKU_IGNORE
6600	},
6601	[ALC662_FIXUP_ASUS_MODE6] = {
6602		.type = ALC_FIXUP_PINS,
6603		.v.pins = (const struct alc_pincfg[]) {
6604			{ 0x14, 0x99130110 }, /* speaker */
6605			{ 0x15, 0x01211420 }, /* HP2 */
6606			{ 0x18, 0x01a19840 }, /* mic */
6607			{ 0x19, 0x99a3094f }, /* int-mic */
6608			{ 0x1b, 0x0121441f }, /* HP */
6609			{ }
6610		},
6611		.chained = true,
6612		.chain_id = ALC662_FIXUP_SKU_IGNORE
6613	},
6614	[ALC662_FIXUP_ASUS_MODE7] = {
6615		.type = ALC_FIXUP_PINS,
6616		.v.pins = (const struct alc_pincfg[]) {
6617			{ 0x14, 0x99130110 }, /* speaker */
6618			{ 0x17, 0x99130111 }, /* speaker */
6619			{ 0x18, 0x01a19840 }, /* mic */
6620			{ 0x19, 0x99a3094f }, /* int-mic */
6621			{ 0x1b, 0x01214020 }, /* HP */
6622			{ 0x21, 0x0121401f }, /* HP */
6623			{ }
6624		},
6625		.chained = true,
6626		.chain_id = ALC662_FIXUP_SKU_IGNORE
6627	},
6628	[ALC662_FIXUP_ASUS_MODE8] = {
6629		.type = ALC_FIXUP_PINS,
6630		.v.pins = (const struct alc_pincfg[]) {
6631			{ 0x14, 0x99130110 }, /* speaker */
6632			{ 0x12, 0x99a30970 }, /* int-mic */
6633			{ 0x15, 0x01214020 }, /* HP */
6634			{ 0x17, 0x99130111 }, /* speaker */
6635			{ 0x18, 0x01a19840 }, /* mic */
6636			{ 0x21, 0x0121401f }, /* HP */
6637			{ }
6638		},
6639		.chained = true,
6640		.chain_id = ALC662_FIXUP_SKU_IGNORE
6641	},
6642	[ALC662_FIXUP_NO_JACK_DETECT] = {
6643		.type = ALC_FIXUP_FUNC,
6644		.v.func = alc_fixup_no_jack_detect,
6645	},
6646	[ALC662_FIXUP_ZOTAC_Z68] = {
6647		.type = ALC_FIXUP_PINS,
6648		.v.pins = (const struct alc_pincfg[]) {
6649			{ 0x1b, 0x02214020 }, /* Front HP */
6650			{ }
6651		}
6652	},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6653};
6654
6655static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6656	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
 
6657	SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
6658	SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
 
 
6659	SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
 
 
 
 
 
 
 
 
 
 
 
6660	SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
 
 
 
 
 
6661	SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
6662	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
6663	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
6664	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6665	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
6666	SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
6667	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6668
6669#if 0
6670	/* Below is a quirk table taken from the old code.
6671	 * Basically the device should work as is without the fixup table.
6672	 * If BIOS doesn't give a proper info, enable the corresponding
6673	 * fixup entry.
6674	 */
6675	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
6676	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
6677	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
6678	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
6679	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6680	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6681	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6682	SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
6683	SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
6684	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6685	SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
6686	SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
6687	SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
6688	SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
6689	SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
6690	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6691	SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
6692	SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
6693	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6694	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6695	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6696	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6697	SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
6698	SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
6699	SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
6700	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6701	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
6702	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6703	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6704	SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
6705	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6706	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6707	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
6708	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
6709	SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
6710	SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
6711	SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
6712	SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
6713	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
6714	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6715	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
6716	SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
6717	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6718	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
6719	SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
6720	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
6721	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
6722	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
6723	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6724	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
6725#endif
6726	{}
6727};
6728
6729static const struct alc_model_fixup alc662_fixup_models[] = {
6730	{.id = ALC272_FIXUP_MARIO, .name = "mario"},
6731	{.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
6732	{.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
6733	{.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
6734	{.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
6735	{.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
6736	{.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
6737	{.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
6738	{.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
 
 
6739	{}
6740};
6741
6742static void alc662_fill_coef(struct hda_codec *codec)
6743{
6744	int val, coef;
6745
6746	coef = alc_get_coef0(codec);
6747
6748	switch (codec->vendor_id) {
6749	case 0x10ec0662:
6750		if ((coef & 0x00f0) == 0x0030) {
6751			val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */
6752			alc_write_coef_idx(codec, 0x4, val & ~(1<<10));
6753		}
6754		break;
6755	case 0x10ec0272:
6756	case 0x10ec0273:
6757	case 0x10ec0663:
6758	case 0x10ec0665:
6759	case 0x10ec0670:
6760	case 0x10ec0671:
6761	case 0x10ec0672:
6762		val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */
6763		alc_write_coef_idx(codec, 0xd, val | (1<<14));
6764		break;
6765	}
6766}
6767
6768/*
6769 */
6770static int patch_alc662(struct hda_codec *codec)
6771{
6772	struct alc_spec *spec;
6773	int err;
6774
6775	err = alc_alloc_spec(codec, 0x0b);
6776	if (err < 0)
6777		return err;
6778
6779	spec = codec->spec;
6780
6781	/* handle multiple HPs as is */
6782	spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
6783
6784	alc_fix_pll_init(codec, 0x20, 0x04, 15);
6785
6786	spec->init_hook = alc662_fill_coef;
6787	alc662_fill_coef(codec);
6788
6789	alc_pick_fixup(codec, alc662_fixup_models,
6790		       alc662_fixup_tbl, alc662_fixups);
6791	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
6792
6793	alc_auto_parse_customize_define(codec);
6794
 
 
 
6795	if ((alc_get_coef0(codec) & (1 << 14)) &&
6796	    codec->bus->pci->subsystem_vendor == 0x1025 &&
6797	    spec->cdefine.platform_type == 1) {
6798		if (alc_codec_rename(codec, "ALC272X") < 0)
 
6799			goto error;
6800	}
6801
6802	/* automatic parse from the BIOS config */
6803	err = alc662_parse_auto_config(codec);
6804	if (err < 0)
6805		goto error;
6806
6807	if (!spec->no_analog && has_cdefine_beep(codec)) {
6808		err = snd_hda_attach_beep_device(codec, 0x1);
6809		if (err < 0)
6810			goto error;
6811		switch (codec->vendor_id) {
6812		case 0x10ec0662:
6813			set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6814			break;
6815		case 0x10ec0272:
6816		case 0x10ec0663:
6817		case 0x10ec0665:
 
6818			set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
6819			break;
6820		case 0x10ec0273:
6821			set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
6822			break;
6823		}
6824	}
6825
6826	codec->patch_ops = alc_patch_ops;
6827	spec->shutup = alc_eapd_shutup;
6828
6829	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6830
6831	return 0;
6832
6833 error:
6834	alc_free(codec);
6835	return err;
6836}
6837
6838/*
6839 * ALC680 support
6840 */
6841
6842static int alc680_parse_auto_config(struct hda_codec *codec)
6843{
6844	return alc_parse_auto_config(codec, NULL, NULL);
6845}
6846
6847/*
6848 */
6849static int patch_alc680(struct hda_codec *codec)
6850{
6851	int err;
6852
6853	/* ALC680 has no aa-loopback mixer */
6854	err = alc_alloc_spec(codec, 0);
6855	if (err < 0)
6856		return err;
6857
6858	/* automatic parse from the BIOS config */
6859	err = alc680_parse_auto_config(codec);
6860	if (err < 0) {
6861		alc_free(codec);
6862		return err;
6863	}
6864
6865	codec->patch_ops = alc_patch_ops;
6866
6867	return 0;
6868}
6869
6870/*
6871 * patch entries
6872 */
6873static const struct hda_codec_preset snd_hda_preset_realtek[] = {
6874	{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
 
 
 
6875	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
6876	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
6877	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
6878	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
6879	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
6880	{ .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
6881	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
6882	{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
6883	{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
6884	{ .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
6885	{ .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
 
 
 
 
 
 
 
 
6886	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
6887	  .patch = patch_alc861 },
6888	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
6889	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
6890	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
6891	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
6892	  .patch = patch_alc882 },
6893	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
6894	  .patch = patch_alc662 },
6895	{ .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
6896	  .patch = patch_alc662 },
6897	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
6898	{ .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
 
6899	{ .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
 
6900	{ .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
6901	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
6902	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
6903	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
6904	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
6905	  .patch = patch_alc882 },
6906	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
6907	  .patch = patch_alc882 },
6908	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
6909	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
6910	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
6911	  .patch = patch_alc882 },
6912	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
6913	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
6914	{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
6915	{ .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
 
6916	{} /* terminator */
6917};
6918
6919MODULE_ALIAS("snd-hda-codec-id:10ec*");
6920
6921MODULE_LICENSE("GPL");
6922MODULE_DESCRIPTION("Realtek HD-audio codec");
6923
6924static struct hda_codec_preset_list realtek_list = {
6925	.preset = snd_hda_preset_realtek,
6926	.owner = THIS_MODULE,
6927};
6928
6929static int __init patch_realtek_init(void)
6930{
6931	return snd_hda_add_codec_preset(&realtek_list);
6932}
6933
6934static void __exit patch_realtek_exit(void)
6935{
6936	snd_hda_delete_codec_preset(&realtek_list);
6937}
6938
6939module_init(patch_realtek_init)
6940module_exit(patch_realtek_exit)