]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'topic/hda-unbind' into for-next
authorTakashi Iwai <tiwai@suse.de>
Mon, 16 Mar 2015 13:48:20 +0000 (14:48 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 16 Mar 2015 13:48:20 +0000 (14:48 +0100)
1  2 
sound/core/device.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_proc.c
sound/pci/hda/patch_realtek.c

diff --combined sound/core/device.c
index c1a845b42a8bd47f0bd50a340b6253fdf200e9a2,446dc452654e51a2bbf416dfb103f8013849e0cf..8918838b1999478e2d03b28dd6425005312bba02
@@@ -50,8 -50,10 +50,8 @@@ int snd_device_new(struct snd_card *car
        if (snd_BUG_ON(!card || !device_data || !ops))
                return -ENXIO;
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 -      if (dev == NULL) {
 -              dev_err(card->dev, "Cannot allocate device, type=%d\n", type);
 +      if (!dev)
                return -ENOMEM;
 -      }
        INIT_LIST_HEAD(&dev->list);
        dev->card = card;
        dev->type = type;
@@@ -71,7 -73,7 +71,7 @@@
  }
  EXPORT_SYMBOL(snd_device_new);
  
- static int __snd_device_disconnect(struct snd_device *dev)
+ static void __snd_device_disconnect(struct snd_device *dev)
  {
        if (dev->state == SNDRV_DEV_REGISTERED) {
                if (dev->ops->dev_disconnect &&
@@@ -79,7 -81,6 +79,6 @@@
                        dev_err(dev->card->dev, "device disconnect failure\n");
                dev->state = SNDRV_DEV_DISCONNECTED;
        }
-       return 0;
  }
  
  static void __snd_device_free(struct snd_device *dev)
@@@ -106,6 -107,34 +105,34 @@@ static struct snd_device *look_for_dev(
        return NULL;
  }
  
+ /**
+  * snd_device_disconnect - disconnect the device
+  * @card: the card instance
+  * @device_data: the data pointer to disconnect
+  *
+  * Turns the device into the disconnection state, invoking
+  * dev_disconnect callback, if the device was already registered.
+  *
+  * Usually called from snd_card_disconnect().
+  *
+  * Return: Zero if successful, or a negative error code on failure or if the
+  * device not found.
+  */
+ void snd_device_disconnect(struct snd_card *card, void *device_data)
+ {
+       struct snd_device *dev;
+       if (snd_BUG_ON(!card || !device_data))
+               return;
+       dev = look_for_dev(card, device_data);
+       if (dev)
+               __snd_device_disconnect(dev);
+       else
+               dev_dbg(card->dev, "device disconnect %p (from %pF), not found\n",
+                       device_data, __builtin_return_address(0));
+ }
+ EXPORT_SYMBOL_GPL(snd_device_disconnect);
  /**
   * snd_device_free - release the device from the card
   * @card: the card instance
@@@ -193,18 -222,14 +220,14 @@@ int snd_device_register_all(struct snd_
   * disconnect all the devices on the card.
   * called from init.c
   */
int snd_device_disconnect_all(struct snd_card *card)
void snd_device_disconnect_all(struct snd_card *card)
  {
        struct snd_device *dev;
-       int err = 0;
  
        if (snd_BUG_ON(!card))
-               return -ENXIO;
-       list_for_each_entry_reverse(dev, &card->devices, list) {
-               if (__snd_device_disconnect(dev) < 0)
-                       err = -ENXIO;
-       }
-       return err;
+               return;
+       list_for_each_entry_reverse(dev, &card->devices, list)
+               __snd_device_disconnect(dev);
  }
  
  /*
index a438e8540763711f479f894b27d6f239f28c637a,b1143f22a0c251ec0bb077873ab35dcf56b974ed..4fd0b2ef26e9f469ce964d954b6170b638266402
@@@ -27,7 -27,6 +27,6 @@@
  #include <linux/module.h>
  #include <linux/pm_runtime.h>
  #include <linux/slab.h>
- #include <linux/reboot.h>
  #include <sound/core.h>
  #include <sound/initval.h>
  #include "hda_controller.h"
@@@ -416,9 -415,11 +415,11 @@@ static int azx_pcm_close(struct snd_pcm
        azx_dev->running = 0;
        spin_unlock_irqrestore(&chip->reg_lock, flags);
        azx_release_device(azx_dev);
-       hinfo->ops.close(hinfo, apcm->codec, substream);
+       if (hinfo->ops.close)
+               hinfo->ops.close(hinfo, apcm->codec, substream);
        snd_hda_power_down(apcm->codec);
        mutex_unlock(&chip->open_mutex);
+       snd_hda_codec_pcm_put(apcm->info);
        return 0;
  }
  
@@@ -805,11 -806,12 +806,12 @@@ static int azx_pcm_open(struct snd_pcm_
        int err;
        int buff_step;
  
+       snd_hda_codec_pcm_get(apcm->info);
        mutex_lock(&chip->open_mutex);
        azx_dev = azx_assign_device(chip, substream);
        if (azx_dev == NULL) {
-               mutex_unlock(&chip->open_mutex);
-               return -EBUSY;
+               err = -EBUSY;
+               goto unlock;
        }
        runtime->hw = azx_pcm_hw;
        runtime->hw.channels_min = hinfo->channels_min;
        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
                                   buff_step);
        snd_hda_power_up(apcm->codec);
-       err = hinfo->ops.open(hinfo, apcm->codec, substream);
+       if (hinfo->ops.open)
+               err = hinfo->ops.open(hinfo, apcm->codec, substream);
+       else
+               err = -ENODEV;
        if (err < 0) {
                azx_release_device(azx_dev);
-               snd_hda_power_down(apcm->codec);
-               mutex_unlock(&chip->open_mutex);
-               return err;
+               goto powerdown;
        }
        snd_pcm_limit_hw_rates(runtime);
        /* sanity check */
            snd_BUG_ON(!runtime->hw.formats) ||
            snd_BUG_ON(!runtime->hw.rates)) {
                azx_release_device(azx_dev);
-               hinfo->ops.close(hinfo, apcm->codec, substream);
-               snd_hda_power_down(apcm->codec);
-               mutex_unlock(&chip->open_mutex);
-               return -EINVAL;
+               if (hinfo->ops.close)
+                       hinfo->ops.close(hinfo, apcm->codec, substream);
+               err = -EINVAL;
+               goto powerdown;
        }
  
        /* disable LINK_ATIME timestamps for capture streams
        snd_pcm_set_sync(substream);
        mutex_unlock(&chip->open_mutex);
        return 0;
+  powerdown:
+       snd_hda_power_down(apcm->codec);
+  unlock:
+       mutex_unlock(&chip->open_mutex);
+       snd_hda_codec_pcm_put(apcm->info);
+       return err;
  }
  
  static int azx_pcm_mmap(struct snd_pcm_substream *substream,
@@@ -974,15 -984,11 +984,10 @@@ static int azx_attach_pcm_stream(struc
   */
  static int azx_alloc_cmd_io(struct azx *chip)
  {
-       int err;
        /* single page (at least 4096 bytes) must suffice for both ringbuffes */
-       err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
-                                        PAGE_SIZE, &chip->rb);
-       if (err < 0)
-               dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n");
-       return err;
+       return chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
+                                         PAGE_SIZE, &chip->rb);
  }
 -EXPORT_SYMBOL_GPL(azx_alloc_cmd_io);
  
  static void azx_init_cmd_io(struct azx *chip)
  {
        azx_writeb(chip, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN);
        spin_unlock_irq(&chip->reg_lock);
  }
 -EXPORT_SYMBOL_GPL(azx_init_cmd_io);
  
  static void azx_free_cmd_io(struct azx *chip)
  {
        azx_writeb(chip, CORBCTL, 0);
        spin_unlock_irq(&chip->reg_lock);
  }
 -EXPORT_SYMBOL_GPL(azx_free_cmd_io);
  
  static unsigned int azx_command_addr(u32 cmd)
  {
@@@ -1186,7 -1194,7 +1191,7 @@@ static unsigned int azx_rirb_get_respon
                }
        }
  
 -      if (!bus->no_response_fallback)
 +      if (bus->no_response_fallback)
                return -1;
  
        if (!chip->polling_mode && chip->poll_count < 2) {
@@@ -1335,6 -1343,7 +1340,6 @@@ static int azx_send_cmd(struct hda_bus 
        else
                return azx_corb_send_cmd(bus, val);
  }
 -EXPORT_SYMBOL_GPL(azx_send_cmd);
  
  /* get a response */
  static unsigned int azx_get_response(struct hda_bus *bus,
        else
                return azx_rirb_get_response(bus, addr);
  }
 -EXPORT_SYMBOL_GPL(azx_get_response);
  
  #ifdef CONFIG_SND_HDA_DSP_LOADER
  /*
@@@ -1467,7 -1477,6 +1472,6 @@@ static void azx_load_dsp_cleanup(struc
  int azx_alloc_stream_pages(struct azx *chip)
  {
        int i, err;
-       struct snd_card *card = chip->card;
  
        for (i = 0; i < chip->num_streams; i++) {
                dsp_lock_init(&chip->azx_dev[i]);
                err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
                                                 BDL_SIZE,
                                                 &chip->azx_dev[i].bdl);
-               if (err < 0) {
-                       dev_err(card->dev, "cannot allocate BDL\n");
+               if (err < 0)
                        return -ENOMEM;
-               }
        }
        /* allocate memory for the position buffer */
        err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
                                         chip->num_streams * 8, &chip->posbuf);
-       if (err < 0) {
-               dev_err(card->dev, "cannot allocate posbuf\n");
+       if (err < 0)
                return -ENOMEM;
-       }
  
        /* allocate CORB/RIRB */
        err = azx_alloc_cmd_io(chip);
@@@ -1893,7 -1898,7 +1893,7 @@@ int azx_probe_codecs(struct azx *chip, 
        for (c = 0; c < max_slots; c++) {
                if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
                        struct hda_codec *codec;
-                       err = snd_hda_codec_new(bus, c, &codec);
+                       err = snd_hda_codec_new(bus, bus->card, c, &codec);
                        if (err < 0)
                                continue;
                        codec->jackpoll_interval = get_jackpoll_interval(chip);
@@@ -1966,30 -1971,5 +1966,5 @@@ int azx_init_stream(struct azx *chip
  }
  EXPORT_SYMBOL_GPL(azx_init_stream);
  
- /*
-  * reboot notifier for hang-up problem at power-down
-  */
- static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
- {
-       struct azx *chip = container_of(nb, struct azx, reboot_notifier);
-       snd_hda_bus_reboot_notify(chip->bus);
-       azx_stop_chip(chip);
-       return NOTIFY_OK;
- }
- void azx_notifier_register(struct azx *chip)
- {
-       chip->reboot_notifier.notifier_call = azx_halt;
-       register_reboot_notifier(&chip->reboot_notifier);
- }
- EXPORT_SYMBOL_GPL(azx_notifier_register);
- void azx_notifier_unregister(struct azx *chip)
- {
-       if (chip->reboot_notifier.notifier_call)
-               unregister_reboot_notifier(&chip->reboot_notifier);
- }
- EXPORT_SYMBOL_GPL(azx_notifier_unregister);
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("Common HDA driver functions");
index 43ad51c672d67670982a211a4e93b687b175a4e8,092f06fd21bd0c136ceab926902b5ba31d85315c..ebdbc023583dc27fbd43c98a77c99b19e87f5321
@@@ -687,45 -687,12 +687,45 @@@ static int get_amp_val_to_activate(stru
        return val;
  }
  
 +/* is this a stereo widget or a stereo-to-mono mix? */
 +static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid, int dir)
 +{
 +      unsigned int wcaps = get_wcaps(codec, nid);
 +      hda_nid_t conn;
 +
 +      if (wcaps & AC_WCAP_STEREO)
 +              return true;
 +      if (dir != HDA_INPUT || get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
 +              return false;
 +      if (snd_hda_get_num_conns(codec, nid) != 1)
 +              return false;
 +      if (snd_hda_get_connections(codec, nid, &conn, 1) < 0)
 +              return false;
 +      return !!(get_wcaps(codec, conn) & AC_WCAP_STEREO);
 +}
 +
  /* initialize the amp value (only at the first time) */
  static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx)
  {
        unsigned int caps = query_amp_caps(codec, nid, dir);
        int val = get_amp_val_to_activate(codec, nid, dir, caps, false);
 -      snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
 +
 +      if (is_stereo_amps(codec, nid, dir))
 +              snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
 +      else
 +              snd_hda_codec_amp_init(codec, nid, 0, dir, idx, 0xff, val);
 +}
 +
 +/* update the amp, doing in stereo or mono depending on NID */
 +static int update_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx,
 +                    unsigned int mask, unsigned int val)
 +{
 +      if (is_stereo_amps(codec, nid, dir))
 +              return snd_hda_codec_amp_stereo(codec, nid, dir, idx,
 +                                              mask, val);
 +      else
 +              return snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
 +                                              mask, val);
  }
  
  /* calculate amp value mask we can modify;
@@@ -765,7 -732,7 +765,7 @@@ static void activate_amp(struct hda_cod
                return;
  
        val &= mask;
 -      snd_hda_codec_amp_stereo(codec, nid, dir, idx, mask, val);
 +      update_amp(codec, nid, dir, idx, mask, val);
  }
  
  static void activate_amp_out(struct hda_codec *codec, struct nid_path *path,
@@@ -4457,11 -4424,13 +4457,11 @@@ static void mute_all_mixer_nid(struct h
        has_amp = nid_has_mute(codec, mix, HDA_INPUT);
        for (i = 0; i < nums; i++) {
                if (has_amp)
 -                      snd_hda_codec_amp_stereo(codec, mix,
 -                                               HDA_INPUT, i,
 -                                               0xff, HDA_AMP_MUTE);
 +                      update_amp(codec, mix, HDA_INPUT, i,
 +                                 0xff, HDA_AMP_MUTE);
                else if (nid_has_volume(codec, conn[i], HDA_OUTPUT))
 -                      snd_hda_codec_amp_stereo(codec, conn[i],
 -                                               HDA_OUTPUT, 0,
 -                                               0xff, HDA_AMP_MUTE);
 +                      update_amp(codec, conn[i], HDA_OUTPUT, 0,
 +                                 0xff, HDA_AMP_MUTE);
        }
  }
  
@@@ -4675,7 -4644,7 +4675,7 @@@ int snd_hda_gen_build_controls(struct h
                err = snd_hda_create_dig_out_ctls(codec,
                                                  spec->multiout.dig_out_nid,
                                                  spec->multiout.dig_out_nid,
-                                                 spec->pcm_rec[1].pcm_type);
+                                                 spec->pcm_rec[1]->pcm_type);
                if (err < 0)
                        return err;
                if (!spec->no_analog) {
@@@ -5146,20 -5115,20 +5146,20 @@@ static void fill_pcm_stream_name(char *
  int snd_hda_gen_build_pcms(struct hda_codec *codec)
  {
        struct hda_gen_spec *spec = codec->spec;
-       struct hda_pcm *info = spec->pcm_rec;
+       struct hda_pcm *info;
        const struct hda_pcm_stream *p;
        bool have_multi_adcs;
  
-       codec->num_pcms = 1;
-       codec->pcm_info = info;
        if (spec->no_analog)
                goto skip_analog;
  
        fill_pcm_stream_name(spec->stream_name_analog,
                             sizeof(spec->stream_name_analog),
                             " Analog", codec->chip_name);
-       info->name = spec->stream_name_analog;
+       info = snd_hda_codec_pcm_new(codec, "%s", spec->stream_name_analog);
+       if (!info)
+               return -ENOMEM;
+       spec->pcm_rec[0] = info;
  
        if (spec->multiout.num_dacs > 0) {
                p = spec->stream_analog_playback;
                fill_pcm_stream_name(spec->stream_name_digital,
                                     sizeof(spec->stream_name_digital),
                                     " Digital", codec->chip_name);
-               codec->num_pcms = 2;
+               info = snd_hda_codec_pcm_new(codec, "%s",
+                                            spec->stream_name_digital);
+               if (!info)
+                       return -ENOMEM;
                codec->slave_dig_outs = spec->multiout.slave_dig_outs;
-               info = spec->pcm_rec + 1;
-               info->name = spec->stream_name_digital;
+               spec->pcm_rec[1] = info;
                if (spec->dig_out_type)
                        info->pcm_type = spec->dig_out_type;
                else
                fill_pcm_stream_name(spec->stream_name_alt_analog,
                                     sizeof(spec->stream_name_alt_analog),
                             " Alt Analog", codec->chip_name);
-               codec->num_pcms = 3;
-               info = spec->pcm_rec + 2;
-               info->name = spec->stream_name_alt_analog;
+               info = snd_hda_codec_pcm_new(codec, "%s",
+                                            spec->stream_name_alt_analog);
+               if (!info)
+                       return -ENOMEM;
+               spec->pcm_rec[2] = info;
                if (spec->alt_dac_nid) {
                        p = spec->stream_analog_alt_playback;
                        if (!p)
index 13529715bc55250ebd13aa8757e9d716e2b3777b,25668fde84801775bce4647548e6409f7d194b07..060f7a2b1aeb4f04809bf70e9ccbf71a999638c2
@@@ -528,10 -528,10 +528,10 @@@ static int azx_position_check(struct az
        if (ok == 1) {
                azx_dev->irq_pending = 0;
                return ok;
-       } else if (ok == 0 && chip->bus && chip->bus->workq) {
+       } else if (ok == 0) {
                /* bogus IRQ, process it later */
                azx_dev->irq_pending = 1;
-               queue_work(chip->bus->workq, &hda->irq_pending_work);
+               schedule_work(&hda->irq_pending_work);
        }
        return 0;
  }
@@@ -893,8 -893,8 +893,8 @@@ static int azx_runtime_resume(struct de
        if (status && bus) {
                list_for_each_entry(codec, &bus->codec_list, list)
                        if (status & (1 << codec->addr))
-                               queue_delayed_work(codec->bus->workq,
-                                                  &codec->jackpoll_work, codec->jackpoll_interval);
+                               schedule_delayed_work(&codec->jackpoll_work,
+                                                     codec->jackpoll_interval);
        }
  
        /* disable controller Wake Up event*/
@@@ -1066,8 -1066,6 +1066,6 @@@ static int azx_free(struct azx *chip
  
        azx_del_card_list(chip);
  
-       azx_notifier_unregister(chip);
        hda->init_failed = 1; /* to be sure */
        complete_all(&hda->probe_wait);
  
@@@ -1383,7 -1381,6 +1381,6 @@@ static int azx_create(struct snd_card *
  
        hda = kzalloc(sizeof(*hda), GFP_KERNEL);
        if (!hda) {
-               dev_err(card->dev, "Cannot allocate hda\n");
                pci_disable_device(pci);
                return -ENOMEM;
        }
@@@ -1564,10 -1561,8 +1561,8 @@@ static int azx_first_init(struct azx *c
        chip->num_streams = chip->playback_streams + chip->capture_streams;
        chip->azx_dev = kcalloc(chip->num_streams, sizeof(*chip->azx_dev),
                                GFP_KERNEL);
-       if (!chip->azx_dev) {
-               dev_err(card->dev, "cannot malloc azx_dev\n");
+       if (!chip->azx_dev)
                return -ENOMEM;
-       }
  
        err = azx_alloc_stream_pages(chip);
        if (err < 0)
@@@ -1898,22 -1893,11 +1893,11 @@@ static int azx_probe_continue(struct az
                        goto out_free;
        }
  
-       /* create PCM streams */
-       err = snd_hda_build_pcms(chip->bus);
-       if (err < 0)
-               goto out_free;
-       /* create mixer controls */
-       err = snd_hda_build_controls(chip->bus);
-       if (err < 0)
-               goto out_free;
        err = snd_card_register(chip->card);
        if (err < 0)
                goto out_free;
  
        chip->running = 1;
-       azx_notifier_register(chip);
        azx_add_card_list(chip);
        snd_hda_set_power_save(chip->bus, power_save * 1000);
        if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
@@@ -1934,6 -1918,18 +1918,18 @@@ static void azx_remove(struct pci_dev *
                snd_card_free(card);
  }
  
+ static void azx_shutdown(struct pci_dev *pci)
+ {
+       struct snd_card *card = pci_get_drvdata(pci);
+       struct azx *chip;
+       if (!card)
+               return;
+       chip = card->private_data;
+       if (chip && chip->running)
+               azx_stop_chip(chip);
+ }
  /* PCI IDs */
  static const struct pci_device_id azx_ids[] = {
        /* CPT */
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* Panther Point */
        { PCI_DEVICE(0x8086, 0x1e20),
 -        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
 +        .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
        /* Lynx Point */
        { PCI_DEVICE(0x8086, 0x8c20),
          .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
@@@ -2156,6 -2152,7 +2152,7 @@@ static struct pci_driver azx_driver = 
        .id_table = azx_ids,
        .probe = azx_probe,
        .remove = azx_remove,
+       .shutdown = azx_shutdown,
        .driver = {
                .pm = AZX_PM_OPS,
        },
diff --combined sound/pci/hda/hda_proc.c
index 05e19f78b4cb8689ff8ac1b0b4f699bdbf5759da,aeb983e7506d1c722102717ed5a3ff4173976ff9..dacfe74a2a1fefc432fb36f58f5e645f10f04057
@@@ -99,10 -99,10 +99,10 @@@ static void print_nid_array(struct snd_
  static void print_nid_pcms(struct snd_info_buffer *buffer,
                           struct hda_codec *codec, hda_nid_t nid)
  {
-       int pcm, type;
+       int type;
        struct hda_pcm *cpcm;
-       for (pcm = 0; pcm < codec->num_pcms; pcm++) {
-               cpcm = &codec->pcm_info[pcm];
+       list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
                for (type = 0; type < 2; type++) {
                        if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL)
                                continue;
@@@ -134,38 -134,13 +134,38 @@@ static void print_amp_caps(struct snd_i
                    (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT);
  }
  
 +/* is this a stereo widget or a stereo-to-mono mix? */
 +static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid,
 +                         int dir, unsigned int wcaps, int indices)
 +{
 +      hda_nid_t conn;
 +
 +      if (wcaps & AC_WCAP_STEREO)
 +              return true;
 +      /* check for a stereo-to-mono mix; it must be:
 +       * only a single connection, only for input, and only a mixer widget
 +       */
 +      if (indices != 1 || dir != HDA_INPUT ||
 +          get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
 +              return false;
 +
 +      if (snd_hda_get_raw_connections(codec, nid, &conn, 1) < 0)
 +              return false;
 +      /* the connection source is a stereo? */
 +      wcaps = snd_hda_param_read(codec, conn, AC_PAR_AUDIO_WIDGET_CAP);
 +      return !!(wcaps & AC_WCAP_STEREO);
 +}
 +
  static void print_amp_vals(struct snd_info_buffer *buffer,
                           struct hda_codec *codec, hda_nid_t nid,
 -                         int dir, int stereo, int indices)
 +                         int dir, unsigned int wcaps, int indices)
  {
        unsigned int val;
 +      bool stereo;
        int i;
  
 +      stereo = is_stereo_amps(codec, nid, dir, wcaps, indices);
 +
        dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
        for (i = 0; i < indices; i++) {
                snd_iprintf(buffer, " [");
@@@ -782,10 -757,12 +782,10 @@@ static void print_codec_info(struct snd
                            (codec->single_adc_amp &&
                             wid_type == AC_WID_AUD_IN))
                                print_amp_vals(buffer, codec, nid, HDA_INPUT,
 -                                             wid_caps & AC_WCAP_STEREO,
 -                                             1);
 +                                             wid_caps, 1);
                        else
                                print_amp_vals(buffer, codec, nid, HDA_INPUT,
 -                                             wid_caps & AC_WCAP_STEREO,
 -                                             conn_len);
 +                                             wid_caps, conn_len);
                }
                if (wid_caps & AC_WCAP_OUT_AMP) {
                        snd_iprintf(buffer, "  Amp-Out caps: ");
                        if (wid_type == AC_WID_PIN &&
                            codec->pin_amp_workaround)
                                print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
 -                                             wid_caps & AC_WCAP_STEREO,
 -                                             conn_len);
 +                                             wid_caps, conn_len);
                        else
                                print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
 -                                             wid_caps & AC_WCAP_STEREO, 1);
 +                                             wid_caps, 1);
                }
  
                switch (wid_type) {
@@@ -861,7 -839,7 +861,7 @@@ int snd_hda_codec_proc_new(struct hda_c
        int err;
  
        snprintf(name, sizeof(name), "codec#%d", codec->addr);
-       err = snd_card_proc_new(codec->bus->card, name, &entry);
+       err = snd_card_proc_new(codec->card, name, &entry);
        if (err < 0)
                return err;
  
index 0ae1f5b7639befd7b0c40ac133d5a733e719a199,0a5a2246e57afff3745590e0017247bbb35486a5..2a61bda8115d422062dc77b13875048da406e347
@@@ -5209,13 -5209,6 +5209,13 @@@ static const struct snd_hda_pin_quirk a
                {0x17, 0x40000000},
                {0x1d, 0x40700001},
                {0x21, 0x02211040}),
 +      SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
 +              ALC255_STANDARD_PINS,
 +              {0x12, 0x90a60170},
 +              {0x14, 0x90170140},
 +              {0x17, 0x40000000},
 +              {0x1d, 0x40700001},
 +              {0x21, 0x02211050}),
        SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
                {0x12, 0x90a60130},
                {0x13, 0x40000000},
@@@ -5850,7 -5843,7 +5850,7 @@@ static void alc_fixup_bass_chmap(struc
  {
        if (action == HDA_FIXUP_ACT_BUILD) {
                struct alc_spec *spec = codec->spec;
-               spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps;
+               spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
        }
  }