]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'fix/hda' into topic/hda
authorTakashi Iwai <tiwai@suse.de>
Fri, 25 Dec 2009 13:17:48 +0000 (14:17 +0100)
committerTakashi Iwai <tiwai@suse.de>
Fri, 25 Dec 2009 13:17:48 +0000 (14:17 +0100)
1  2 
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c

index 29c90d748c91697aff5cdc81882ed88c2416a59f,950ee5cfcacf06611d9d818832b8367944314086..b3554df740ffc96162d78dd0c35d4670f249258f
@@@ -931,7 -931,6 +931,7 @@@ static void snd_hda_codec_free(struct h
  #endif
        list_del(&codec->list);
        snd_array_free(&codec->mixers);
 +      snd_array_free(&codec->nids);
        codec->bus->caddr_tbl[codec->addr] = NULL;
        if (codec->patch_ops.free)
                codec->patch_ops.free(codec);
@@@ -986,8 -985,7 +986,8 @@@ int /*__devinit*/ snd_hda_codec_new(str
        mutex_init(&codec->control_mutex);
        init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
        init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
 -      snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60);
 +      snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
 +      snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
        snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
        snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
        if (codec->bus->modelname) {
@@@ -1088,11 -1086,6 +1088,6 @@@ int snd_hda_codec_configure(struct hda_
                if (err < 0)
                        return err;
        }
-       /* audio codec should override the mixer name */
-       if (codec->afg || !*codec->bus->card->mixername)
-               snprintf(codec->bus->card->mixername,
-                        sizeof(codec->bus->card->mixername),
-                        "%s %s", codec->vendor_name, codec->chip_name);
  
        if (is_generic_config(codec)) {
                err = snd_hda_parse_generic_codec(codec);
   patched:
        if (!err && codec->patch_ops.unsol_event)
                err = init_unsol_queue(codec->bus);
+       /* audio codec should override the mixer name */
+       if (!err && (codec->afg || !*codec->bus->card->mixername))
+               snprintf(codec->bus->card->mixername,
+                        sizeof(codec->bus->card->mixername),
+                        "%s %s", codec->vendor_name, codec->chip_name);
        return err;
  }
  EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
@@@ -1708,7 -1706,7 +1708,7 @@@ struct snd_kcontrol *snd_hda_find_mixer
  EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
  
  /**
 - * snd_hda_ctl-add - Add a control element and assign to the codec
 + * snd_hda_ctl_add - Add a control element and assign to the codec
   * @codec: HD-audio codec
   * @nid: corresponding NID (optional)
   * @kctl: the control element to assign
   *
   * snd_hda_ctl_add() checks the control subdev id field whether
   * #HDA_SUBDEV_NID_FLAG bit is set.  If set (and @nid is zero), the lower
 - * bits value is taken as the NID to assign.
 + * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit
 + * specifies if kctl->private_value is a HDA amplifier value.
   */
  int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
                    struct snd_kcontrol *kctl)
  {
        int err;
 +      unsigned short flags = 0;
        struct hda_nid_item *item;
  
 -      if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) {
 +      if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) {
 +              flags |= HDA_NID_ITEM_AMP;
                if (nid == 0)
 -                      nid = kctl->id.subdevice & 0xffff;
 -              kctl->id.subdevice = 0;
 +                      nid = get_amp_nid_(kctl->private_value);
        }
 +      if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0)
 +              nid = kctl->id.subdevice & 0xffff;
 +      if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG))
 +              kctl->id.subdevice = 0;
        err = snd_ctl_add(codec->bus->card, kctl);
        if (err < 0)
                return err;
                return -ENOMEM;
        item->kctl = kctl;
        item->nid = nid;
 +      item->flags = flags;
        return 0;
  }
  EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
  
 +/**
 + * snd_hda_add_nid - Assign a NID to a control element
 + * @codec: HD-audio codec
 + * @nid: corresponding NID (optional)
 + * @kctl: the control element to assign
 + * @index: index to kctl
 + *
 + * Add the given control element to an array inside the codec instance.
 + * This function is used when #snd_hda_ctl_add cannot be used for 1:1
 + * NID:KCTL mapping - for example "Capture Source" selector.
 + */
 +int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
 +                  unsigned int index, hda_nid_t nid)
 +{
 +      struct hda_nid_item *item;
 +
 +      if (nid > 0) {
 +              item = snd_array_new(&codec->nids);
 +              if (!item)
 +                      return -ENOMEM;
 +              item->kctl = kctl;
 +              item->index = index;
 +              item->nid = nid;
 +              return 0;
 +      }
 +      return -EINVAL;
 +}
 +EXPORT_SYMBOL_HDA(snd_hda_add_nid);
 +
  /**
   * snd_hda_ctls_clear - Clear all controls assigned to the given codec
   * @codec: HD-audio codec
@@@ -1795,7 -1757,6 +1795,7 @@@ void snd_hda_ctls_clear(struct hda_code
        for (i = 0; i < codec->mixers.used; i++)
                snd_ctl_remove(codec->bus->card, items[i].kctl);
        snd_array_free(&codec->mixers);
 +      snd_array_free(&codec->nids);
  }
  
  /* pseudo device locking
@@@ -3515,8 -3476,6 +3515,8 @@@ int snd_hda_add_new_ctls(struct hda_cod
  
        for (; knew->name; knew++) {
                struct snd_kcontrol *kctl;
 +              if (knew->iface == -1)  /* skip this codec private value */
 +                      continue;
                kctl = snd_ctl_new1(knew, codec);
                if (!kctl)
                        return -ENOMEM;
index d258569fc921f792603b1f0e2268fe18869b3c02,ec9c348336cc383d5bb2902bc1e525bdda1afd96..1f516e668d884158c438b2beb2f094b3de2ad7d8
@@@ -356,6 -356,7 +356,7 @@@ struct azx_dev 
                                         */
        unsigned char stream_tag;       /* assigned stream */
        unsigned char index;            /* stream index */
+       int device;                     /* last device number assigned to */
  
        unsigned int opened :1;
        unsigned int running :1;
@@@ -1441,10 -1442,13 +1442,13 @@@ static int __devinit azx_codec_configur
   */
  
  /* assign a stream for the PCM */
- static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
+ static inline struct azx_dev *
+ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
  {
        int dev, i, nums;
-       if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+       struct azx_dev *res = NULL;
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                dev = chip->playback_index_offset;
                nums = chip->playback_streams;
        } else {
        }
        for (i = 0; i < nums; i++, dev++)
                if (!chip->azx_dev[dev].opened) {
-                       chip->azx_dev[dev].opened = 1;
-                       return &chip->azx_dev[dev];
+                       res = &chip->azx_dev[dev];
+                       if (res->device == substream->pcm->device)
+                               break;
                }
-       return NULL;
+       if (res) {
+               res->opened = 1;
+               res->device = substream->pcm->device;
+       }
+       return res;
  }
  
  /* release the assigned stream */
@@@ -1505,7 -1514,7 +1514,7 @@@ static int azx_pcm_open(struct snd_pcm_
        int err;
  
        mutex_lock(&chip->open_mutex);
-       azx_dev = azx_assign_device(chip, substream->stream);
+       azx_dev = azx_assign_device(chip, substream);
        if (azx_dev == NULL) {
                mutex_unlock(&chip->open_mutex);
                return -EBUSY;
@@@ -2695,10 -2704,32 +2704,10 @@@ static struct pci_device_id azx_ids[] 
        /* ULI M5461 */
        { PCI_DEVICE(0x10b9, 0x5461), .driver_data = AZX_DRIVER_ULI },
        /* NVIDIA MCP */
 -      { PCI_DEVICE(0x10de, 0x026c), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0371), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x03e4), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x03f0), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x044a), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0777), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x07fc), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x07fd), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0ac0), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA },
 -      { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA },
 +      { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
 +        .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
 +        .class_mask = 0xffffff,
 +        .driver_data = AZX_DRIVER_NVIDIA },
        /* Teradici */
        { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
        /* Creative X-Fi (CA0110-IBG) */
index a45199014986b9c264590c59365791de8ca30b83,c7465053d6bbe338cbbad141cc565726982cf5d5..6361e6b3c9c5a99d34fb8a0fb4841b03e8af3f0b
@@@ -633,7 -633,6 +633,7 @@@ static int alc_pin_mode_put(struct snd_
  
  #define ALC_PIN_MODE(xname, nid, dir) \
        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 +        .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
          .info = alc_pin_mode_info, \
          .get = alc_pin_mode_get, \
          .put = alc_pin_mode_put, \
@@@ -685,7 -684,6 +685,7 @@@ static int alc_gpio_data_put(struct snd
  }
  #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 +        .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
          .info = alc_gpio_data_info, \
          .get = alc_gpio_data_get, \
          .put = alc_gpio_data_put, \
@@@ -740,7 -738,6 +740,7 @@@ static int alc_spdif_ctrl_put(struct sn
  }
  #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 +        .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
          .info = alc_spdif_ctrl_info, \
          .get = alc_spdif_ctrl_get, \
          .put = alc_spdif_ctrl_put, \
@@@ -794,7 -791,6 +794,7 @@@ static int alc_eapd_ctrl_put(struct snd
  
  #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 +        .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
          .info = alc_eapd_ctrl_info, \
          .get = alc_eapd_ctrl_get, \
          .put = alc_eapd_ctrl_put, \
@@@ -2447,15 -2443,6 +2447,15 @@@ static const char *alc_slave_sws[] = 
   * build control elements
   */
  
 +#define NID_MAPPING           (-1)
 +
 +#define SUBDEV_SPEAKER_               (0 << 6)
 +#define SUBDEV_HP_            (1 << 6)
 +#define SUBDEV_LINE_          (2 << 6)
 +#define SUBDEV_SPEAKER(x)     (SUBDEV_SPEAKER_ | ((x) & 0x3f))
 +#define SUBDEV_HP(x)          (SUBDEV_HP_ | ((x) & 0x3f))
 +#define SUBDEV_LINE(x)                (SUBDEV_LINE_ | ((x) & 0x3f))
 +
  static void alc_free_kctls(struct hda_codec *codec);
  
  #ifdef CONFIG_SND_HDA_INPUT_BEEP
@@@ -2470,11 -2457,8 +2470,11 @@@ static struct snd_kcontrol_new alc_beep
  static int alc_build_controls(struct hda_codec *codec)
  {
        struct alc_spec *spec = codec->spec;
 -      int err;
 -      int i;
 +      struct snd_kcontrol *kctl;
 +      struct snd_kcontrol_new *knew;
 +      int i, j, err;
 +      unsigned int u;
 +      hda_nid_t nid;
  
        for (i = 0; i < spec->num_mixers; i++) {
                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
                        if (!kctl)
                                return -ENOMEM;
                        kctl->private_value = spec->beep_amp;
 -                      err = snd_hda_ctl_add(codec,
 -                                      get_amp_nid_(spec->beep_amp), kctl);
 +                      err = snd_hda_ctl_add(codec, 0, kctl);
                        if (err < 0)
                                return err;
                }
        }
  
        alc_free_kctls(codec); /* no longer needed */
 +
 +      /* assign Capture Source enums to NID */
 +      kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
 +      if (!kctl)
 +              kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
 +      for (i = 0; kctl && i < kctl->count; i++) {
 +              hda_nid_t *nids = spec->capsrc_nids;
 +              if (!nids)
 +                      nids = spec->adc_nids;
 +              err = snd_hda_add_nid(codec, kctl, i, nids[i]);
 +              if (err < 0)
 +                      return err;
 +      }
 +      if (spec->cap_mixer) {
 +              const char *kname = kctl ? kctl->id.name : NULL;
 +              for (knew = spec->cap_mixer; knew->name; knew++) {
 +                      if (kname && strcmp(knew->name, kname) == 0)
 +                              continue;
 +                      kctl = snd_hda_find_mixer_ctl(codec, knew->name);
 +                      for (i = 0; kctl && i < kctl->count; i++) {
 +                              err = snd_hda_add_nid(codec, kctl, i,
 +                                                    spec->adc_nids[i]);
 +                              if (err < 0)
 +                                      return err;
 +                      }
 +              }
 +      }
 +
 +      /* other nid->control mapping */
 +      for (i = 0; i < spec->num_mixers; i++) {
 +              for (knew = spec->mixers[i]; knew->name; knew++) {
 +                      if (knew->iface != NID_MAPPING)
 +                              continue;
 +                      kctl = snd_hda_find_mixer_ctl(codec, knew->name);
 +                      if (kctl == NULL)
 +                              continue;
 +                      u = knew->subdevice;
 +                      for (j = 0; j < 4; j++, u >>= 8) {
 +                              nid = u & 0x3f;
 +                              if (nid == 0)
 +                                      continue;
 +                              switch (u & 0xc0) {
 +                              case SUBDEV_SPEAKER_:
 +                                      nid = spec->autocfg.speaker_pins[nid];
 +                                      break;
 +                              case SUBDEV_LINE_:
 +                                      nid = spec->autocfg.line_out_pins[nid];
 +                                      break;
 +                              case SUBDEV_HP_:
 +                                      nid = spec->autocfg.hp_pins[nid];
 +                                      break;
 +                              default:
 +                                      continue;
 +                              }
 +                              err = snd_hda_add_nid(codec, kctl, 0, nid);
 +                              if (err < 0)
 +                                      return err;
 +                      }
 +                      u = knew->private_value;
 +                      for (j = 0; j < 4; j++, u >>= 8) {
 +                              nid = u & 0xff;
 +                              if (nid == 0)
 +                                      continue;
 +                              err = snd_hda_add_nid(codec, kctl, 0, nid);
 +                              if (err < 0)
 +                                      return err;
 +                      }
 +              }
 +      }
        return 0;
  }
  
@@@ -3916,7 -3832,6 +3916,7 @@@ static int alc_test_pin_src_put(struct 
  #define PIN_CTL_TEST(xname,nid) {                     \
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
                        .name = xname,                 \
 +                      .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
                        .info = alc_test_pin_ctl_info, \
                        .get = alc_test_pin_ctl_get,   \
                        .put = alc_test_pin_ctl_put,   \
  #define PIN_SRC_TEST(xname,nid) {                     \
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
                        .name = xname,                 \
 +                      .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
                        .info = alc_test_pin_src_info, \
                        .get = alc_test_pin_src_get,   \
                        .put = alc_test_pin_src_put,   \
@@@ -4466,7 -4380,7 +4466,7 @@@ static int add_control(struct alc_spec 
        if (!knew->name)
                return -ENOMEM;
        if (get_amp_nid_(val))
 -              knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val);
 +              knew->subdevice = HDA_SUBDEV_AMP_FLAG;
        knew->private_value = val;
        return 0;
  }
@@@ -5217,7 -5131,6 +5217,7 @@@ static struct snd_kcontrol_new alc260_h
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
 +              .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
                .info = snd_ctl_boolean_mono_info,
                .get = alc260_hp_master_sw_get,
                .put = alc260_hp_master_sw_put,
@@@ -5256,7 -5169,6 +5256,7 @@@ static struct snd_kcontrol_new alc260_h
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
 +              .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
                .info = snd_ctl_boolean_mono_info,
                .get = alc260_hp_master_sw_get,
                .put = alc260_hp_master_sw_put,
@@@ -10336,14 -10248,8 +10336,14 @@@ static int alc262_hp_master_sw_put(stru
                .info = snd_ctl_boolean_mono_info,              \
                .get = alc262_hp_master_sw_get,                 \
                .put = alc262_hp_master_sw_put,                 \
 +      }, \
 +      {                                                       \
 +              .iface = NID_MAPPING,                           \
 +              .name = "Master Playback Switch",               \
 +              .private_value = 0x15 | (0x16 << 8) | (0x1b << 16),     \
        }
  
 +
  static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
        ALC262_HP_MASTER_SWITCH,
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@@ -10501,12 -10407,6 +10501,12 @@@ static int alc262_hippo_master_sw_put(s
                .info = snd_ctl_boolean_mono_info,              \
                .get = alc262_hippo_master_sw_get,              \
                .put = alc262_hippo_master_sw_put,              \
 +      },                                                      \
 +      {                                                       \
 +              .iface = NID_MAPPING,                           \
 +              .name = "Master Playback Switch",               \
 +              .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
 +                           (SUBDEV_SPEAKER(0) << 16), \
        }
  
  static struct snd_kcontrol_new alc262_hippo_mixer[] = {
@@@ -10987,17 -10887,11 +10987,17 @@@ static struct snd_kcontrol_new alc262_f
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
 +              .subdevice = HDA_SUBDEV_AMP_FLAG,
                .info = snd_hda_mixer_amp_switch_info,
                .get = snd_hda_mixer_amp_switch_get,
                .put = alc262_fujitsu_master_sw_put,
                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
        },
 +      {
 +              .iface = NID_MAPPING,
 +              .name = "Master Playback Switch",
 +              .private_value = 0x1b,
 +      },
        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
@@@ -11028,7 -10922,6 +11028,7 @@@ static struct snd_kcontrol_new alc262_l
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
 +              .subdevice = HDA_SUBDEV_AMP_FLAG,
                .info = snd_hda_mixer_amp_switch_info,
                .get = snd_hda_mixer_amp_switch_get,
                .put = alc262_lenovo_3000_master_sw_put,
@@@ -11183,11 -11076,6 +11183,11 @@@ static struct snd_kcontrol_new alc262_u
                .get = alc_mux_enum_get,
                .put = alc262_ultra_mux_enum_put,
        },
 +      {
 +              .iface = NID_MAPPING,
 +              .name = "Capture Source",
 +              .private_value = 0x15,
 +      },
        { } /* end */
  };
  
@@@ -12206,7 -12094,6 +12206,7 @@@ static struct snd_kcontrol_new alc268_a
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
 +              .subdevice = HDA_SUBDEV_AMP_FLAG,
                .info = snd_hda_mixer_amp_switch_info,
                .get = snd_hda_mixer_amp_switch_get,
                .put = alc268_acer_master_sw_put,
@@@ -12222,7 -12109,6 +12222,7 @@@ static struct snd_kcontrol_new alc268_a
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
 +              .subdevice = HDA_SUBDEV_AMP_FLAG,
                .info = snd_hda_mixer_amp_switch_info,
                .get = snd_hda_mixer_amp_switch_get,
                .put = alc268_acer_master_sw_put,
@@@ -12240,7 -12126,6 +12240,7 @@@ static struct snd_kcontrol_new alc268_a
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
 +              .subdevice = HDA_SUBDEV_AMP_FLAG,
                .info = snd_hda_mixer_amp_switch_info,
                .get = snd_hda_mixer_amp_switch_get,
                .put = alc268_acer_master_sw_put,
@@@ -13039,7 -12924,7 +13039,7 @@@ static int patch_alc268(struct hda_code
        int board_config;
        int i, has_beep, err;
  
-       spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+       spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
                return -ENOMEM;
  
@@@ -13193,7 -13078,6 +13193,7 @@@ static struct snd_kcontrol_new alc269_q
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
 +              .subdevice = HDA_SUBDEV_AMP_FLAG,
                .info = snd_hda_mixer_amp_switch_info,
                .get = snd_hda_mixer_amp_switch_get,
                .put = alc268_acer_master_sw_put,
@@@ -13214,7 -13098,6 +13214,7 @@@ static struct snd_kcontrol_new alc269_l
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
                .name = "Master Playback Switch",
 +              .subdevice = HDA_SUBDEV_AMP_FLAG,
                .info = snd_hda_mixer_amp_switch_info,
                .get = snd_hda_mixer_amp_switch_get,
                .put = alc268_acer_master_sw_put,
index 2f08b434bbd8409c2e1f793e6a0df6813150c899,eeda7beeb57a2300fe38ed2e83b7b1d22dcfeea0..247be19e17b836296f0692ad5361cbb709d3dd29
@@@ -2104,6 -2104,7 +2104,7 @@@ static unsigned int ref9205_pin_configs
      10280204
      1028021F
      10280228 (Dell Vostro 1500)
+     10280229 (Dell Vostro 1700)
  */
  static unsigned int dell_9205_m42_pin_configs[12] = {
        0x0321101F, 0x03A11020, 0x400003FA, 0x90170310,
@@@ -2189,6 -2190,8 +2190,8 @@@ static struct snd_pci_quirk stac9205_cf
                      "Dell Inspiron", STAC_9205_DELL_M44),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
                      "Dell Vostro 1500", STAC_9205_DELL_M42),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0229,
+                     "Dell Vostro 1700", STAC_9205_DELL_M42),
        /* Gateway */
        SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
        SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
@@@ -2685,7 -2688,7 +2688,7 @@@ static struct snd_kcontrol_new 
  stac_control_new(struct sigmatel_spec *spec,
                 struct snd_kcontrol_new *ktemp,
                 const char *name,
 -               hda_nid_t nid)
 +               unsigned int subdev)
  {
        struct snd_kcontrol_new *knew;
  
                spec->kctls.alloced--;
                return NULL;
        }
 -      if (nid)
 -              knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
 +      knew->subdevice = subdev;
        return knew;
  }
  
@@@ -2711,7 -2715,7 +2714,7 @@@ static int stac92xx_add_control_temp(st
                                     unsigned long val)
  {
        struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
 -                                                       get_amp_nid_(val));
 +                                                       HDA_SUBDEV_AMP_FLAG);
        if (!knew)
                return -ENOMEM;
        knew->index = idx;
@@@ -5403,54 -5407,6 +5406,54 @@@ static int stac92hd71bxx_connected_smux
                return 0;
  }
  
 +/* HP dv7 bass switch - GPIO5 */
 +#define stac_hp_bass_gpio_info        snd_ctl_boolean_mono_info
 +static int stac_hp_bass_gpio_get(struct snd_kcontrol *kcontrol,
 +                               struct snd_ctl_elem_value *ucontrol)
 +{
 +      struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 +      struct sigmatel_spec *spec = codec->spec;
 +      ucontrol->value.integer.value[0] = !!(spec->gpio_data & 0x20);
 +      return 0;
 +}
 +
 +static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol,
 +                               struct snd_ctl_elem_value *ucontrol)
 +{
 +      struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 +      struct sigmatel_spec *spec = codec->spec;
 +      unsigned int gpio_data;
 +
 +      gpio_data = (spec->gpio_data & ~0x20) |
 +              (ucontrol->value.integer.value[0] ? 0x20 : 0);
 +      if (gpio_data == spec->gpio_data)
 +              return 0;
 +      spec->gpio_data = gpio_data;
 +      stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
 +      return 1;
 +}
 +
 +static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = {
 +      .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 +      .info = stac_hp_bass_gpio_info,
 +      .get = stac_hp_bass_gpio_get,
 +      .put = stac_hp_bass_gpio_put,
 +};
 +
 +static int stac_add_hp_bass_switch(struct hda_codec *codec)
 +{
 +      struct sigmatel_spec *spec = codec->spec;
 +
 +      if (!stac_control_new(spec, &stac_hp_bass_sw_ctrl,
 +                            "Bass Speaker Playback Switch", 0))
 +              return -ENOMEM;
 +
 +      spec->gpio_mask |= 0x20;
 +      spec->gpio_dir |= 0x20;
 +      spec->gpio_data |= 0x20;
 +      return 0;
 +}
 +
  static int patch_stac92hd71bxx(struct hda_codec *codec)
  {
        struct sigmatel_spec *spec;
@@@ -5691,15 -5647,6 +5694,15 @@@ again
                return err;
        }
  
 +      /* enable bass on HP dv7 */
 +      if (spec->board_config == STAC_HP_DV5) {
 +              unsigned int cap;
 +              cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP);
 +              cap &= AC_GPIO_IO_COUNT;
 +              if (cap >= 6)
 +                      stac_add_hp_bass_switch(codec);
 +      }
 +
        codec->proc_widget_hook = stac92hd7x_proc_hook;
  
        return 0;