]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'fix/hda' into topic/hda
authorTakashi Iwai <tiwai@suse.de>
Tue, 23 Aug 2011 13:02:36 +0000 (15:02 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 23 Aug 2011 13:02:36 +0000 (15:02 +0200)
Conflicts:
sound/pci/hda/patch_realtek.c

1  2 
sound/pci/hda/patch_realtek.c

index e0ecf5a5b097c8d0cdce67a4d9260ad6495739ef,7cabd731716395e7f5386425236660283f096fdf..c3e5af955620fc5a3b71fe7382c4adc04c6f3c81
@@@ -159,7 -159,6 +159,7 @@@ struct alc_spec 
        void (*power_hook)(struct hda_codec *codec);
  #endif
        void (*shutup)(struct hda_codec *codec);
 +      void (*automute_hook)(struct hda_codec *codec);
  
        /* for pin sensing */
        unsigned int jack_present: 1;
        /* multi-io */
        int multi_ios;
        struct alc_multi_io multi_io[4];
 +
 +      /* bind volumes */
 +      struct snd_array bind_ctls;
  };
  
  #define ALC_MODEL_AUTO                0       /* common for all chips */
@@@ -564,26 -560,17 +564,26 @@@ static void update_speakers(struct hda_
                    spec->autocfg.line_out_pins, on, false);
  }
  
 +static void call_update_speakers(struct hda_codec *codec)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      if (spec->automute_hook)
 +              spec->automute_hook(codec);
 +      else
 +              update_speakers(codec);
 +}
 +
  /* standard HP-automute helper */
  static void alc_hp_automute(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
  
-       if (!spec->automute)
-               return;
        spec->jack_present =
                detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
                             spec->autocfg.hp_pins);
 -      update_speakers(codec);
+       if (!spec->automute)
+               return;
 +      call_update_speakers(codec);
  }
  
  /* standard line-out-automute helper */
@@@ -591,12 -578,12 +591,12 @@@ static void alc_line_automute(struct hd
  {
        struct alc_spec *spec = codec->spec;
  
-       if (!spec->automute || !spec->detect_line)
-               return;
        spec->line_jack_present =
                detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
                             spec->autocfg.line_out_pins);
 -      update_speakers(codec);
+       if (!spec->automute || !spec->detect_line)
+               return;
 +      call_update_speakers(codec);
  }
  
  #define get_connection_index(codec, mux, nid) \
@@@ -853,7 -840,7 +853,7 @@@ static int alc_automute_mode_put(struc
        default:
                return -EINVAL;
        }
 -      update_speakers(codec);
 +      call_update_speakers(codec);
        return 1;
  }
  
@@@ -1797,6 -1784,7 +1797,7 @@@ static const char * const alc_slave_vol
        "Speaker Playback Volume",
        "Mono Playback Volume",
        "Line-Out Playback Volume",
+       "PCM Playback Volume",
        NULL,
  };
  
@@@ -1811,6 -1799,7 +1812,7 @@@ static const char * const alc_slave_sws
        "Mono Playback Switch",
        "IEC958 Playback Switch",
        "Line-Out Playback Switch",
+       "PCM Playback Switch",
        NULL,
  };
  
@@@ -2372,18 -2361,6 +2374,18 @@@ static void alc_free_kctls(struct hda_c
        snd_array_free(&spec->kctls);
  }
  
 +static void alc_free_bind_ctls(struct hda_codec *codec)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      if (spec->bind_ctls.list) {
 +              struct hda_bind_ctls **ctl = spec->bind_ctls.list;
 +              int i;
 +              for (i = 0; i < spec->bind_ctls.used; i++)
 +                      kfree(ctl[i]);
 +      }
 +      snd_array_free(&spec->bind_ctls);
 +}
 +
  static void alc_free(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
        alc_shutup(codec);
        snd_hda_input_jack_free(codec);
        alc_free_kctls(codec);
 +      alc_free_bind_ctls(codec);
        kfree(spec);
        snd_hda_detach_beep_device(codec);
  }
@@@ -2465,15 -2441,11 +2467,15 @@@ enum 
        ALC_CTL_WIDGET_VOL,
        ALC_CTL_WIDGET_MUTE,
        ALC_CTL_BIND_MUTE,
 +      ALC_CTL_BIND_VOL,
 +      ALC_CTL_BIND_SW,
  };
  static const struct snd_kcontrol_new alc_control_templates[] = {
        HDA_CODEC_VOLUME(NULL, 0, 0, 0),
        HDA_CODEC_MUTE(NULL, 0, 0, 0),
        HDA_BIND_MUTE(NULL, 0, 0, 0),
 +      HDA_BIND_VOL(NULL, 0),
 +      HDA_BIND_SW(NULL, 0),
  };
  
  /* add dynamic controls */
@@@ -2514,14 -2486,13 +2516,14 @@@ static int add_control_with_pfx(struct 
  #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val)                  \
        add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
  
 +static const char * const channel_name[4] = {
 +      "Front", "Surround", "CLFE", "Side"
 +};
 +
  static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
                                        bool can_be_master, int *index)
  {
        struct auto_pin_cfg *cfg = &spec->autocfg;
 -      static const char * const chname[4] = {
 -              "Front", "Surround", NULL /*CLFE*/, "Side"
 -      };
  
        *index = 0;
        if (cfg->line_outs == 1 && !spec->multi_ios &&
                        return "PCM";
                break;
        }
 -      return chname[ch];
 +      if (snd_BUG_ON(ch >= ARRAY_SIZE(channel_name)))
 +              return "PCM";
 +
 +      return channel_name[ch];
  }
  
  /* create input playback/capture controls for the given pin */
@@@ -2893,28 -2861,6 +2895,28 @@@ static int alc_auto_fill_dac_nids(struc
        return 0;
  }
  
 +/* fill in the dac_nids table for surround speakers, etc */
 +static int alc_auto_fill_extra_dacs(struct hda_codec *codec)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      const struct auto_pin_cfg *cfg = &spec->autocfg;
 +      int i;
 +
 +      if (cfg->speaker_outs < 2 || !spec->multiout.extra_out_nid[0])
 +              return 0;
 +
 +      for (i = 1; i < cfg->speaker_outs; i++)
 +              spec->multiout.extra_out_nid[i] =
 +                      get_dac_if_single(codec, cfg->speaker_pins[i]);
 +      for (i = 1; i < cfg->speaker_outs; i++) {
 +              if (spec->multiout.extra_out_nid[i])
 +                      continue;
 +              spec->multiout.extra_out_nid[i] =
 +                      alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
 +      }
 +      return 0;
 +}
 +
  static int alc_auto_add_vol_ctl(struct hda_codec *codec,
                              const char *pfx, int cidx,
                              hda_nid_t nid, unsigned int chs)
@@@ -3037,13 -2983,16 +3039,13 @@@ static int alc_auto_create_multi_out_ct
        return 0;
  }
  
 -/* add playback controls for speaker and HP outputs */
  static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
 -                                      hda_nid_t dac, const char *pfx)
 +                                   hda_nid_t dac, const char *pfx)
  {
        struct alc_spec *spec = codec->spec;
        hda_nid_t sw, vol;
        int err;
  
 -      if (!pin)
 -              return 0;
        if (!dac) {
                /* the corresponding DAC is already occupied */
                if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
        return 0;
  }
  
 +static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec,
 +                                        unsigned int nums,
 +                                        struct hda_ctl_ops *ops)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      struct hda_bind_ctls **ctlp, *ctl;
 +      snd_array_init(&spec->bind_ctls, sizeof(ctl), 8);
 +      ctlp = snd_array_new(&spec->bind_ctls);
 +      if (!ctlp)
 +              return NULL;
 +      ctl = kzalloc(sizeof(*ctl) + sizeof(long) * (nums + 1), GFP_KERNEL);
 +      *ctlp = ctl;
 +      if (ctl)
 +              ctl->ops = ops;
 +      return ctl;
 +}
 +
 +/* add playback controls for speaker and HP outputs */
 +static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
 +                                    const hda_nid_t *pins,
 +                                    const hda_nid_t *dacs,
 +                                    const char *pfx)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      struct hda_bind_ctls *ctl;
 +      char name[32];
 +      int i, n, err;
 +
 +      if (!num_pins || !pins[0])
 +              return 0;
 +
 +      if (num_pins == 1)
 +              return alc_auto_create_extra_out(codec, *pins, *dacs, pfx);
 +
 +      if (dacs[num_pins - 1]) {
 +              /* OK, we have a multi-output system with individual volumes */
 +              for (i = 0; i < num_pins; i++) {
 +                      snprintf(name, sizeof(name), "%s %s",
 +                               pfx, channel_name[i]);
 +                      err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
 +                                                      name);
 +                      if (err < 0)
 +                              return err;
 +              }
 +              return 0;
 +      }
 +
 +      /* Let's create a bind-controls */
 +      ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw);
 +      if (!ctl)
 +              return -ENOMEM;
 +      n = 0;
 +      for (i = 0; i < num_pins; i++) {
 +              if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP)
 +                      ctl->values[n++] =
 +                              HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT);
 +      }
 +      if (n) {
 +              snprintf(name, sizeof(name), "%s Playback Switch", pfx);
 +              err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl);
 +              if (err < 0)
 +                      return err;
 +      }
 +
 +      ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
 +      if (!ctl)
 +              return -ENOMEM;
 +      n = 0;
 +      for (i = 0; i < num_pins; i++) {
 +              hda_nid_t vol;
 +              if (!pins[i] || !dacs[i])
 +                      continue;
 +              vol = alc_look_for_out_vol_nid(codec, pins[i], dacs[i]);
 +              if (vol)
 +                      ctl->values[n++] =
 +                              HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT);
 +      }
 +      if (n) {
 +              snprintf(name, sizeof(name), "%s Playback Volume", pfx);
 +              err = add_control(spec, ALC_CTL_BIND_VOL, name, 0, (long)ctl);
 +              if (err < 0)
 +                      return err;
 +      }
 +      return 0;
 +}
 +
  static int alc_auto_create_hp_out(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
  static int alc_auto_create_speaker_out(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
 -      return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
 -                                       spec->multiout.extra_out_nid[0],
 -                                       "Speaker");
 +      return alc_auto_create_extra_outs(codec, spec->autocfg.speaker_outs,
 +                                        spec->autocfg.speaker_pins,
 +                                        spec->multiout.extra_out_nid,
 +                                        "Speaker");
  }
  
  static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
@@@ -3221,16 -3083,22 +3223,22 @@@ static void alc_auto_init_multi_out(str
  static void alc_auto_init_extra_out(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
-       hda_nid_t pin;
+       hda_nid_t pin, dac;
  
        pin = spec->autocfg.hp_pins[0];
-       if (pin)
-               alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
-                                                 spec->multiout.hp_nid);
+       if (pin) {
+               dac = spec->multiout.hp_nid;
+               if (!dac)
+                       dac = spec->multiout.dac_nids[0];
+               alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
+       }
        pin = spec->autocfg.speaker_pins[0];
-       if (pin)
-               alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
-                                       spec->multiout.extra_out_nid[0]);
+       if (pin) {
+               dac = spec->multiout.extra_out_nid[0];
+               if (!dac)
+                       dac = spec->multiout.dac_nids[0];
+               alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
+       }
  }
  
  /*
@@@ -3355,13 -3223,27 +3363,13 @@@ static const struct snd_kcontrol_new al
        .put = alc_auto_ch_mode_put,
  };
  
 -static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
 -                                         int (*fill_dac)(struct hda_codec *))
 +static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
        struct auto_pin_cfg *cfg = &spec->autocfg;
        unsigned int location, defcfg;
        int num_pins;
  
 -      if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
 -              /* use HP as primary out */
 -              cfg->speaker_outs = cfg->line_outs;
 -              memcpy(cfg->speaker_pins, cfg->line_out_pins,
 -                     sizeof(cfg->speaker_pins));
 -              cfg->line_outs = cfg->hp_outs;
 -              memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
 -              cfg->hp_outs = 0;
 -              memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
 -              cfg->line_out_type = AUTO_PIN_HP_OUT;
 -              if (fill_dac)
 -                      fill_dac(codec);
 -      }
        if (cfg->line_outs != 1 ||
            cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
                return 0;
@@@ -3666,43 -3548,27 +3674,43 @@@ static int alc_parse_auto_config(struc
                                 const hda_nid_t *ssid_nids)
  {
        struct alc_spec *spec = codec->spec;
 +      struct auto_pin_cfg *cfg = &spec->autocfg;
        int err;
  
 -      err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
 -                                         ignore_nids);
 +      err = snd_hda_parse_pin_def_config(codec, cfg, ignore_nids);
        if (err < 0)
                return err;
 -      if (!spec->autocfg.line_outs) {
 -              if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
 +      if (!cfg->line_outs) {
 +              if (cfg->dig_outs || cfg->dig_in_pin) {
                        spec->multiout.max_channels = 2;
                        spec->no_analog = 1;
                        goto dig_only;
                }
                return 0; /* can't find valid BIOS pin config */
        }
 +
 +      if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
 +              /* use HP as primary out */
 +              cfg->speaker_outs = cfg->line_outs;
 +              memcpy(cfg->speaker_pins, cfg->line_out_pins,
 +                     sizeof(cfg->speaker_pins));
 +              cfg->line_outs = cfg->hp_outs;
 +              memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
 +              cfg->hp_outs = 0;
 +              memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
 +              cfg->line_out_type = AUTO_PIN_HP_OUT;
 +      }
 +
        err = alc_auto_fill_dac_nids(codec);
        if (err < 0)
                return err;
 -      err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
 +      err = alc_auto_add_multi_channel_mode(codec);
        if (err < 0)
                return err;
 -      err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
 +      err = alc_auto_fill_extra_dacs(codec);
 +      if (err < 0)
 +              return err;
 +      err = alc_auto_create_multi_out_ctls(codec, cfg);
        if (err < 0)
                return err;
        err = alc_auto_create_hp_out(codec);
@@@ -4364,9 -4230,14 +4372,9 @@@ static int alc268_parse_auto_config(str
  
  /*
   */
 -#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
 -#include "alc268_quirks.c"
 -#endif
 -
  static int patch_alc268(struct hda_codec *codec)
  {
        struct alc_spec *spec;
 -      int board_config;
        int i, has_beep, err;
  
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  
        /* ALC268 has no aa-loopback mixer */
  
 -      board_config = alc_board_config(codec, ALC268_MODEL_LAST,
 -                                      alc268_models, alc268_cfg_tbl);
 -
 -      if (board_config < 0)
 -              board_config = alc_board_codec_sid_config(codec,
 -                      ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
 -
 -      if (board_config < 0) {
 -              printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
 -                     codec->chip_name);
 -              board_config = ALC_MODEL_AUTO;
 -      }
 -
 -      if (board_config == ALC_MODEL_AUTO) {
 -              /* automatic parse from the BIOS config */
 -              err = alc268_parse_auto_config(codec);
 -              if (err < 0) {
 -                      alc_free(codec);
 -                      return err;
 -              }
 -#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
 -              else if (!err) {
 -                      printk(KERN_INFO
 -                             "hda_codec: Cannot set up configuration "
 -                             "from BIOS.  Using base mode...\n");
 -                      board_config = ALC268_3ST;
 -              }
 -#endif
 +      /* automatic parse from the BIOS config */
 +      err = alc268_parse_auto_config(codec);
 +      if (err < 0) {
 +              alc_free(codec);
 +              return err;
        }
  
 -      if (board_config != ALC_MODEL_AUTO)
 -              setup_preset(codec, &alc268_presets[board_config]);
 -
        has_beep = 0;
        for (i = 0; i < spec->num_mixers; i++) {
                if (spec->mixers[i] == alc268_beep_mixer) {
        spec->vmaster_nid = 0x02;
  
        codec->patch_ops = alc_patch_ops;
 -      if (board_config == ALC_MODEL_AUTO)
 -              spec->init_hook = alc_auto_init_std;
 +      spec->init_hook = alc_auto_init_std;
        spec->shutup = alc_eapd_shutup;
  
        alc_init_jacks(codec);
@@@ -4610,30 -4508,6 +4618,30 @@@ static void alc269_fixup_stereo_dmic(st
        alc_write_coef_idx(codec, 0x07, coef | 0x80);
  }
  
 +static void alc269_quanta_automute(struct hda_codec *codec)
 +{
 +      update_speakers(codec);
 +
 +      snd_hda_codec_write(codec, 0x20, 0,
 +                      AC_VERB_SET_COEF_INDEX, 0x0c);
 +      snd_hda_codec_write(codec, 0x20, 0,
 +                      AC_VERB_SET_PROC_COEF, 0x680);
 +
 +      snd_hda_codec_write(codec, 0x20, 0,
 +                      AC_VERB_SET_COEF_INDEX, 0x0c);
 +      snd_hda_codec_write(codec, 0x20, 0,
 +                      AC_VERB_SET_PROC_COEF, 0x480);
 +}
 +
 +static void alc269_fixup_quanta_mute(struct hda_codec *codec,
 +                                   const struct alc_fixup *fix, int action)
 +{
 +      struct alc_spec *spec = codec->spec;
 +      if (action != ALC_FIXUP_ACT_PROBE)
 +              return;
 +      spec->automute_hook = alc269_quanta_automute;
 +}
 +
  enum {
        ALC269_FIXUP_SONY_VAIO,
        ALC275_FIXUP_SONY_VAIO_GPIO2,
        ALC271_FIXUP_DMIC,
        ALC269_FIXUP_PCM_44K,
        ALC269_FIXUP_STEREO_DMIC,
 +      ALC269_FIXUP_QUANTA_MUTE,
 +      ALC269_FIXUP_LIFEBOOK,
  };
  
  static const struct alc_fixup alc269_fixups[] = {
                .type = ALC_FIXUP_FUNC,
                .v.func = alc269_fixup_stereo_dmic,
        },
 +      [ALC269_FIXUP_QUANTA_MUTE] = {
 +              .type = ALC_FIXUP_FUNC,
 +              .v.func = alc269_fixup_quanta_mute,
 +      },
 +      [ALC269_FIXUP_LIFEBOOK] = {
 +              .type = ALC_FIXUP_PINS,
 +              .v.pins = (const struct alc_pincfg[]) {
 +                      { 0x1a, 0x2101103f }, /* dock line-out */
 +                      { 0x1b, 0x23a11040 }, /* dock mic-in */
 +                      { }
 +              },
 +              .chained = true,
 +              .chain_id = ALC269_FIXUP_QUANTA_MUTE
 +      },
  };
  
  static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
        SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
 +      SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
 +      SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE),
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
        {}
@@@ -5255,7 -5111,6 +5263,7 @@@ enum 
        ALC662_FIXUP_CZC_P10T,
        ALC662_FIXUP_SKU_IGNORE,
        ALC662_FIXUP_HP_RP5800,
 +      ALC662_FIXUP_ECS,
  };
  
  static const struct alc_fixup alc662_fixups[] = {
                .chained = true,
                .chain_id = ALC662_FIXUP_SKU_IGNORE
        },
 +      [ALC662_FIXUP_ECS] = {
 +              .type = ALC_FIXUP_PINS,
 +              .v.pins = (const struct alc_pincfg[]) {
 +                      { 0x14, 0x99130110 }, /* speaker */
 +                      { 0x18, 0x01a19820 }, /* mic */
 +                      { 0x19, 0x99a3092f }, /* int-mic */
 +                      { 0x1b, 0x0121401f }, /* HP out */
 +                      { }
 +              },
 +      },
  };
  
  static const struct snd_pci_quirk alc662_fixup_tbl[] = {
 +      SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ECS),
        SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
        SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
 +      SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ECS),
        SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
@@@ -5479,9 -5322,14 +5487,9 @@@ static int alc680_parse_auto_config(str
  
  /*
   */
 -#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
 -#include "alc680_quirks.c"
 -#endif
 -
  static int patch_alc680(struct hda_codec *codec)
  {
        struct alc_spec *spec;
 -      int board_config;
        int err;
  
        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
  
        /* ALC680 has no aa-loopback mixer */
  
 -      board_config = alc_board_config(codec, ALC680_MODEL_LAST,
 -                                      alc680_models, alc680_cfg_tbl);
 -
 -      if (board_config < 0) {
 -              printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
 -                     codec->chip_name);
 -              board_config = ALC_MODEL_AUTO;
 -      }
 -
 -      if (board_config == ALC_MODEL_AUTO) {
 -              /* automatic parse from the BIOS config */
 -              err = alc680_parse_auto_config(codec);
 -              if (err < 0) {
 -                      alc_free(codec);
 -                      return err;
 -              }
 -#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
 -              else if (!err) {
 -                      printk(KERN_INFO
 -                             "hda_codec: Cannot set up configuration "
 -                             "from BIOS.  Using base mode...\n");
 -                      board_config = ALC680_BASE;
 -              }
 -#endif
 -      }
 -
 -      if (board_config != ALC_MODEL_AUTO) {
 -              setup_preset(codec, &alc680_presets[board_config]);
 -#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
 -              spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
 -#endif
 -      }
 -
 -      if (!spec->no_analog && !spec->adc_nids) {
 -              alc_auto_fill_adc_caps(codec);
 -              alc_rebuild_imux_for_auto_mic(codec);
 -              alc_remove_invalid_adc_nids(codec);
 +      /* automatic parse from the BIOS config */
 +      err = alc680_parse_auto_config(codec);
 +      if (err < 0) {
 +              alc_free(codec);
 +              return err;
        }
  
        if (!spec->no_analog && !spec->cap_mixer)
        spec->vmaster_nid = 0x02;
  
        codec->patch_ops = alc_patch_ops;
 -      if (board_config == ALC_MODEL_AUTO)
 -              spec->init_hook = alc_auto_init_std;
 +      spec->init_hook = alc_auto_init_std;
  
        return 0;
  }