Merge branch 'for-linus' into HEAD
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
index 06741e9..d0056a4 100644
--- a/Documentation/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl
@@ -468,8 +468,6 @@
                   return err;
           }
 
-          snd_card_set_dev(card, &pci->dev);
-
           *rchip = chip;
           return 0;
   }
@@ -492,7 +490,8 @@
           }
 
           /* (2) */
-          err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+          err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+                             0, &card);
           if (err < 0)
                   return err;
 
@@ -591,7 +590,8 @@
   struct snd_card *card;
   int err;
   ....
-  err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+  err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+                     0, &card);
 ]]>
             </programlisting>
           </informalexample>
@@ -809,28 +809,34 @@
 
       <para>
         As mentioned above, to create a card instance, call
-      <function>snd_card_create()</function>.
+      <function>snd_card_new()</function>.
 
         <informalexample>
           <programlisting>
 <![CDATA[
   struct snd_card *card;
   int err;
-  err = snd_card_create(index, id, module, extra_size, &card);
+  err = snd_card_new(&pci->dev, index, id, module, extra_size, &card);
 ]]>
           </programlisting>
         </informalexample>
       </para>
 
       <para>
-        The function takes five arguments, the card-index number, the
-        id string, the module pointer (usually
+        The function takes six arguments: the parent device pointer,
+        the card-index number, the id string, the module pointer (usually
         <constant>THIS_MODULE</constant>),
         the size of extra-data space, and the pointer to return the
         card instance.  The extra_size argument is used to
         allocate card-&gt;private_data for the
         chip-specific data.  Note that these data
-        are allocated by <function>snd_card_create()</function>.
+        are allocated by <function>snd_card_new()</function>.
+      </para>
+
+      <para>
+	The first argument, the pointer of struct
+	<structname>device</structname>, specifies the parent device.
+	For PCI devices, typically &amp;pci-&gt; is passed there.
       </para>
     </section>
 
@@ -916,16 +922,16 @@
       </para>
 
       <section id="card-management-chip-specific-snd-card-new">
-        <title>1. Allocating via <function>snd_card_create()</function>.</title>
+        <title>1. Allocating via <function>snd_card_new()</function>.</title>
         <para>
           As mentioned above, you can pass the extra-data-length
-	  to the 4th argument of <function>snd_card_create()</function>, i.e.
+	  to the 5th argument of <function>snd_card_new()</function>, i.e.
 
           <informalexample>
             <programlisting>
 <![CDATA[
-  err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-                        sizeof(struct mychip), &card);
+  err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+                     sizeof(struct mychip), &card);
 ]]>
             </programlisting>
           </informalexample>
@@ -954,7 +960,7 @@
 
         <para>
           After allocating a card instance via
-          <function>snd_card_create()</function> (with
+          <function>snd_card_new()</function> (with
           <constant>0</constant> on the 4th arg), call
           <function>kzalloc()</function>. 
 
@@ -963,7 +969,8 @@
 <![CDATA[
   struct snd_card *card;
   struct mychip *chip;
-  err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+  err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+                     0, &card);
   .....
   chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 ]]>
@@ -1170,8 +1177,6 @@
                   return err;
           }
 
-          snd_card_set_dev(card, &pci->dev);
-
           *rchip = chip;
           return 0;
   }        
@@ -1526,30 +1531,6 @@
 
     </section>
 
-    <section id="pci-resource-device-struct">
-      <title>Registration of Device Struct</title>
-      <para>
-	At some point, typically after calling <function>snd_device_new()</function>,
-	you need to register the struct <structname>device</structname> of the chip
-	you're handling for udev and co.  ALSA provides a macro for compatibility with
-	older kernels.  Simply call like the following:
-        <informalexample>
-          <programlisting>
-<![CDATA[
-  snd_card_set_dev(card, &pci->dev);
-]]>
-          </programlisting>
-        </informalexample>
-	so that it stores the PCI's device pointer to the card.  This will be
-	referred by ALSA core functions later when the devices are registered.
-      </para>
-      <para>
-	In the case of non-PCI, pass the proper device struct pointer of the BUS
-	instead.  (In the case of legacy ISA without PnP, you don't have to do
-	anything.)
-      </para>
-    </section>
-
     <section id="pci-resource-entries">
       <title>PCI Entries</title>
       <para>
@@ -5740,7 +5721,8 @@
           struct mychip *chip;
           int err;
           ....
-          err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+          err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+                             0, &card);
           ....
           chip = kzalloc(sizeof(*chip), GFP_KERNEL);
           ....
@@ -5752,7 +5734,7 @@
       </informalexample>
 
 	When you created the chip data with
-	<function>snd_card_create()</function>, it's anyway accessible
+	<function>snd_card_new()</function>, it's anyway accessible
 	via <structfield>private_data</structfield> field.
 
       <informalexample>
@@ -5766,8 +5748,8 @@
           struct mychip *chip;
           int err;
           ....
-          err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-                                sizeof(struct mychip), &card);
+          err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+                             sizeof(struct mychip), &card);
           ....
           chip = card->private_data;
           ....
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index 7ed8280..91fab97 100644
--- a/drivers/hid/hid-prodikeys.c
+++ b/drivers/hid/hid-prodikeys.c
@@ -624,7 +624,8 @@
 
 	/* Setup sound card */
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pm->pk->hdev->dev, index[dev], id[dev],
+			   THIS_MODULE, 0, &card);
 	if (err < 0) {
 		pk_error("failed to create pc-midi sound card\n");
 		err = -ENOMEM;
@@ -660,8 +661,6 @@
 	snd_rawmidi_set_ops(rwmidi, SNDRV_RAWMIDI_STREAM_INPUT,
 		&pcmidi_in_ops);
 
-	snd_card_set_dev(card, &pm->pk->hdev->dev);
-
 	/* create sysfs variables */
 	err = device_create_file(&pm->pk->hdev->dev,
 				 sysfs_device_attr_channel);
diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c
index b2c8c34..ea272bc 100644
--- a/drivers/media/pci/cx18/cx18-alsa-main.c
+++ b/drivers/media/pci/cx18/cx18-alsa-main.c
@@ -145,11 +145,12 @@
 	/* This is a no-op for us.  We'll use the cx->instance */
 
 	/* (2) Create a card instance */
-	ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
-			      SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
-			      THIS_MODULE, 0, &sc);
+	ret = snd_card_new(&cx->pci_dev->dev,
+			   SNDRV_DEFAULT_IDX1, /* use first available id */
+			   SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
+			   THIS_MODULE, 0, &sc);
 	if (ret) {
-		CX18_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
+		CX18_ALSA_ERR("%s: snd_card_new() failed with err %d\n",
 			      __func__, ret);
 		goto err_exit;
 	}
diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c
index c6c9bd5..554798d 100644
--- a/drivers/media/pci/cx23885/cx23885-alsa.c
+++ b/drivers/media/pci/cx23885/cx23885-alsa.c
@@ -489,7 +489,8 @@
 		return NULL;
 	}
 
-	err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+	err = snd_card_new(&dev->pci->dev,
+			   SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
 			THIS_MODULE, sizeof(struct cx23885_audio_dev), &card);
 	if (err < 0)
 		goto error;
@@ -500,8 +501,6 @@
 	chip->card = card;
 	spin_lock_init(&chip->lock);
 
-	snd_card_set_dev(card, &dev->pci->dev);
-
 	err = snd_cx23885_pcm(chip, 0, "CX23885 Digital");
 	if (err < 0)
 		goto error;
diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c
index b1e08c3..2dd5bca 100644
--- a/drivers/media/pci/cx25821/cx25821-alsa.c
+++ b/drivers/media/pci/cx25821/cx25821-alsa.c
@@ -645,8 +645,9 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[devno], id[devno], THIS_MODULE,
-			sizeof(struct cx25821_audio_dev), &card);
+	err = snd_card_new(&dev->pci->dev, index[devno], id[devno],
+			   THIS_MODULE,
+			   sizeof(struct cx25821_audio_dev), &card);
 	if (err < 0) {
 		pr_info("DEBUG ERROR: cannot create snd_card_new in %s\n",
 			__func__);
@@ -682,8 +683,6 @@
 		goto error;
 	}
 
-	snd_card_set_dev(card, &chip->pci->dev);
-
 	strcpy(card->shortname, "cx25821");
 	sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name,
 		chip->iobase, chip->irq);
diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c
index d014206e..a72579a 100644
--- a/drivers/media/pci/cx88/cx88-alsa.c
+++ b/drivers/media/pci/cx88/cx88-alsa.c
@@ -852,8 +852,6 @@
 	chip->irq = pci->irq;
 	synchronize_irq(chip->irq);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 	*core_ptr = core;
 
@@ -876,8 +874,8 @@
 		return (-ENOENT);
 	}
 
-	err = snd_card_create(index[devno], id[devno], THIS_MODULE,
-			      sizeof(snd_cx88_card_t), &card);
+	err = snd_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE,
+			   sizeof(snd_cx88_card_t), &card);
 	if (err < 0)
 		return err;
 
diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c
index e970cfa..39b5292 100644
--- a/drivers/media/pci/ivtv/ivtv-alsa-main.c
+++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c
@@ -145,11 +145,12 @@
 	/* This is a no-op for us.  We'll use the itv->instance */
 
 	/* (2) Create a card instance */
-	ret = snd_card_create(SNDRV_DEFAULT_IDX1, /* use first available id */
-			      SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
-			      THIS_MODULE, 0, &sc);
+	ret = snd_card_new(&itv->pdev->dev,
+			   SNDRV_DEFAULT_IDX1, /* use first available id */
+			   SNDRV_DEFAULT_STR1, /* xid from end of shortname*/
+			   THIS_MODULE, 0, &sc);
 	if (ret) {
-		IVTV_ALSA_ERR("%s: snd_card_create() failed with err %d\n",
+		IVTV_ALSA_ERR("%s: snd_card_new() failed with err %d\n",
 			      __func__, ret);
 		goto err_exit;
 	}
diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c
index dd67c8a..e04a4d5 100644
--- a/drivers/media/pci/saa7134/saa7134-alsa.c
+++ b/drivers/media/pci/saa7134/saa7134-alsa.c
@@ -1072,8 +1072,8 @@
 	if (!enable[devnum])
 		return -ENODEV;
 
-	err = snd_card_create(index[devnum], id[devnum], THIS_MODULE,
-			      sizeof(snd_card_saa7134_t), &card);
+	err = snd_card_new(&dev->pci->dev, index[devnum], id[devnum],
+			   THIS_MODULE, sizeof(snd_card_saa7134_t), &card);
 	if (err < 0)
 		return err;
 
@@ -1115,8 +1115,6 @@
 	if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
 		goto __nodev;
 
-	snd_card_set_dev(card, &chip->pci->dev);
-
 	/* End of "creation" */
 
 	strcpy(card->shortname, "SAA7134");
diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c
index 81a1d97..9b92587 100644
--- a/drivers/media/usb/cx231xx/cx231xx-audio.c
+++ b/drivers/media/usb/cx231xx/cx231xx-audio.c
@@ -665,8 +665,8 @@
 	cx231xx_info("cx231xx-audio.c: probing for cx231xx "
 		     "non standard usbaudio\n");
 
-	err = snd_card_create(index[devnr], "Cx231xx Audio", THIS_MODULE,
-			      0, &card);
+	err = snd_card_new(&dev->udev->dev, index[devnr], "Cx231xx Audio",
+			   THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
@@ -682,7 +682,6 @@
 	pcm->info_flags = 0;
 	pcm->private_data = dev;
 	strcpy(pcm->name, "Conexant cx231xx Capture");
-	snd_card_set_dev(card, &dev->udev->dev);
 	strcpy(card->driver, "Cx231xx-Audio");
 	strcpy(card->shortname, "Cx231xx Audio");
 	strcpy(card->longname, "Conexant cx231xx Audio");
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c
index 05e9bd1..1a28897 100644
--- a/drivers/media/usb/em28xx/em28xx-audio.c
+++ b/drivers/media/usb/em28xx/em28xx-audio.c
@@ -900,8 +900,8 @@
 	printk(KERN_INFO
 	       "em28xx-audio.c: Copyright (C) 2007-2014 Mauro Carvalho Chehab\n");
 
-	err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
-			      &card);
+	err = snd_card_new(&dev->udev->dev, index[devnr], "Em28xx Audio",
+			   THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
@@ -918,7 +918,6 @@
 	pcm->private_data = dev;
 	strcpy(pcm->name, "Empia 28xx Capture");
 
-	snd_card_set_dev(card, &dev->udev->dev);
 	strcpy(card->driver, "Em28xx-Audio");
 	strcpy(card->shortname, "Em28xx Audio");
 	strcpy(card->longname, "Empia Em28xx Audio");
diff --git a/drivers/media/usb/stk1160/stk1160-ac97.c b/drivers/media/usb/stk1160/stk1160-ac97.c
index c8583c2..c46c8be 100644
--- a/drivers/media/usb/stk1160/stk1160-ac97.c
+++ b/drivers/media/usb/stk1160/stk1160-ac97.c
@@ -98,13 +98,11 @@
 	 * Just want a card to access ac96 controls,
 	 * the actual capture interface will be handled by snd-usb-audio
 	 */
-	rc = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-			      THIS_MODULE, 0, &card);
+	rc = snd_card_new(dev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			  THIS_MODULE, 0, &card);
 	if (rc < 0)
 		return rc;
 
-	snd_card_set_dev(card, dev->dev);
-
 	/* TODO: I'm not sure where should I get these names :-( */
 	snprintf(card->shortname, sizeof(card->shortname),
 		 "stk1160-mixer");
diff --git a/drivers/media/usb/tlg2300/pd-alsa.c b/drivers/media/usb/tlg2300/pd-alsa.c
index 3f3e141..dd8fe10 100644
--- a/drivers/media/usb/tlg2300/pd-alsa.c
+++ b/drivers/media/usb/tlg2300/pd-alsa.c
@@ -300,7 +300,8 @@
 	struct snd_pcm *pcm;
 	int ret;
 
-	ret = snd_card_create(-1, "Telegent", THIS_MODULE, 0, &card);
+	ret = snd_card_new(&p->interface->dev, -1, "Telegent",
+			   THIS_MODULE, 0, &card);
 	if (ret != 0)
 		return ret;
 
diff --git a/drivers/media/usb/tm6000/tm6000-alsa.c b/drivers/media/usb/tm6000/tm6000-alsa.c
index 813c1ec..3239cd6 100644
--- a/drivers/media/usb/tm6000/tm6000-alsa.c
+++ b/drivers/media/usb/tm6000/tm6000-alsa.c
@@ -431,7 +431,8 @@
 	if (!enable[devnr])
 		return -ENOENT;
 
-	rc = snd_card_create(index[devnr], "tm6000", THIS_MODULE, 0, &card);
+	rc = snd_card_new(&dev->udev->dev, index[devnr], "tm6000",
+			  THIS_MODULE, 0, &card);
 	if (rc < 0) {
 		snd_printk(KERN_ERR "cannot create card instance %d\n", devnr);
 		return rc;
@@ -445,7 +446,6 @@
 		le16_to_cpu(dev->udev->descriptor.idVendor),
 		le16_to_cpu(dev->udev->descriptor.idProduct));
 	snd_component_add(card, component);
-	snd_card_set_dev(card, &dev->udev->dev);
 
 	chip = kzalloc(sizeof(struct snd_tm6000_card), GFP_KERNEL);
 	if (!chip) {
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index defb6af..94bb615 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -6776,8 +6776,9 @@
 	struct snd_kcontrol *ctl_mute;
 	int rc;
 
-	rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE,
-			    sizeof(struct tpacpi_alsa_data), &card);
+	rc = snd_card_new(&tpacpi_pdev->dev,
+			  alsa_index, alsa_id, THIS_MODULE,
+			  sizeof(struct tpacpi_alsa_data), &card);
 	if (rc < 0 || !card) {
 		pr_err("Failed to create ALSA card structures: %d\n", rc);
 		return 1;
@@ -6828,7 +6829,6 @@
 	}
 	data->ctl_mute_id = &ctl_mute->id;
 
-	snd_card_set_dev(card, &tpacpi_pdev->dev);
 	rc = snd_card_register(card);
 	if (rc < 0) {
 		pr_err("Failed to register ALSA card: %d\n", rc);
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c
index a92e21f..171d80c 100644
--- a/drivers/staging/line6/audio.c
+++ b/drivers/staging/line6/audio.c
@@ -24,8 +24,9 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-			      THIS_MODULE, 0, &card);
+	err = snd_card_new(line6->ifcdev,
+			   SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			   THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
index 3f6d78c..c61cd05 100644
--- a/drivers/staging/line6/midi.c
+++ b/drivers/staging/line6/midi.c
@@ -307,8 +307,6 @@
 	if (err < 0)
 		return err;
 
-	snd_card_set_dev(line6->card, line6->ifcdev);
-
 	err = snd_line6_new_midi(line6midi);
 	if (err < 0)
 		return err;
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
index df8331b..661080b 100644
--- a/drivers/staging/line6/pcm.c
+++ b/drivers/staging/line6/pcm.c
@@ -501,8 +501,6 @@
 	if (err < 0)
 		return err;
 
-	snd_card_set_dev(line6->card, line6->ifcdev);
-
 	err = snd_line6_new_pcm(line6pcm);
 	if (err < 0)
 		return err;
diff --git a/drivers/staging/media/go7007/snd-go7007.c b/drivers/staging/media/go7007/snd-go7007.c
index 16dd649..9eb2a20 100644
--- a/drivers/staging/media/go7007/snd-go7007.c
+++ b/drivers/staging/media/go7007/snd-go7007.c
@@ -245,8 +245,8 @@
 	spin_lock_init(&gosnd->lock);
 	gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
 	gosnd->capturing = 0;
-	ret = snd_card_create(index[dev], id[dev], THIS_MODULE, 0,
-			      &gosnd->card);
+	ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0,
+			   &gosnd->card);
 	if (ret < 0) {
 		kfree(gosnd);
 		return ret;
@@ -257,7 +257,6 @@
 		kfree(gosnd);
 		return ret;
 	}
-	snd_card_set_dev(gosnd->card, go->dev);
 	ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
 	if (ret < 0) {
 		snd_card_free(gosnd->card);
diff --git a/drivers/staging/media/solo6x10/solo6x10-g723.c b/drivers/staging/media/solo6x10/solo6x10-g723.c
index 1db18c7..74f037b 100644
--- a/drivers/staging/media/solo6x10/solo6x10-g723.c
+++ b/drivers/staging/media/solo6x10/solo6x10-g723.c
@@ -366,8 +366,9 @@
 	/* Allows for easier mapping between video and audio */
 	sprintf(name, "Softlogic%d", solo_dev->vfd->num);
 
-	ret = snd_card_create(SNDRV_DEFAULT_IDX1, name, THIS_MODULE, 0,
-			      &solo_dev->snd_card);
+	ret = snd_card_new(&solo_dev->pdev->dev,
+			   SNDRV_DEFAULT_IDX1, name, THIS_MODULE, 0,
+			   &solo_dev->snd_card);
 	if (ret < 0)
 		return ret;
 
@@ -377,7 +378,6 @@
 	strcpy(card->shortname, "SOLO-6x10 Audio");
 	sprintf(card->longname, "%s on %s IRQ %d", card->shortname,
 		pci_name(solo_dev->pdev), solo_dev->pdev->irq);
-	snd_card_set_dev(card, &solo_dev->pdev->dev);
 
 	ret = snd_device_new(card, SNDRV_DEV_LOWLEVEL, solo_dev, &ops);
 	if (ret < 0)
diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c
index 36d4bb2..807b31c 100644
--- a/drivers/usb/gadget/f_midi.c
+++ b/drivers/usb/gadget/f_midi.c
@@ -664,9 +664,10 @@
 		.dev_free = f_midi_snd_free,
 	};
 
-	err = snd_card_create(midi->index, midi->id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&midi->gadget->dev, midi->index, midi->id,
+			   THIS_MODULE, 0, &card);
 	if (err < 0) {
-		ERROR(midi, "snd_card_create() failed\n");
+		ERROR(midi, "snd_card_new() failed\n");
 		goto fail;
 	}
 	midi->card = card;
@@ -703,8 +704,6 @@
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &gmidi_in_ops);
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &gmidi_out_ops);
 
-	snd_card_set_dev(card, &midi->gadget->dev);
-
 	/* register it - we're ready to go */
 	err = snd_card_register(card);
 	if (err < 0) {
diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c
index 2f23566..bc23040 100644
--- a/drivers/usb/gadget/f_uac2.c
+++ b/drivers/usb/gadget/f_uac2.c
@@ -394,7 +394,7 @@
 	int err;
 
 	/* Choose any slot, with no id */
-	err = snd_card_create(-1, NULL, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
@@ -421,8 +421,6 @@
 	strcpy(card->shortname, "UAC2_Gadget");
 	sprintf(card->longname, "UAC2_Gadget %i", pdev->id);
 
-	snd_card_set_dev(card, &pdev->dev);
-
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
 		snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);
 
diff --git a/include/sound/core.h b/include/sound/core.h
index 2a14f1f..a3e3e89 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -22,6 +22,7 @@
  *
  */
 
+#include <linux/device.h>
 #include <linux/sched.h>		/* wake_up() */
 #include <linux/mutex.h>		/* struct mutex */
 #include <linux/rwsem.h>		/* struct rw_semaphore */
@@ -41,39 +42,41 @@
 /* forward declarations */
 struct pci_dev;
 struct module;
-struct device;
-struct device_attribute;
+struct completion;
 
 /* device allocation stuff */
 
 #define SNDRV_DEV_TYPE_RANGE_SIZE		0x1000
 
-typedef int __bitwise snd_device_type_t;
-#define	SNDRV_DEV_TOPLEVEL	((__force snd_device_type_t) 0)
-#define	SNDRV_DEV_CONTROL	((__force snd_device_type_t) 1)
-#define	SNDRV_DEV_LOWLEVEL_PRE	((__force snd_device_type_t) 2)
-#define	SNDRV_DEV_LOWLEVEL_NORMAL ((__force snd_device_type_t) 0x1000)
-#define	SNDRV_DEV_PCM		((__force snd_device_type_t) 0x1001)
-#define	SNDRV_DEV_RAWMIDI	((__force snd_device_type_t) 0x1002)
-#define	SNDRV_DEV_TIMER		((__force snd_device_type_t) 0x1003)
-#define	SNDRV_DEV_SEQUENCER	((__force snd_device_type_t) 0x1004)
-#define	SNDRV_DEV_HWDEP		((__force snd_device_type_t) 0x1005)
-#define	SNDRV_DEV_INFO		((__force snd_device_type_t) 0x1006)
-#define	SNDRV_DEV_BUS		((__force snd_device_type_t) 0x1007)
-#define	SNDRV_DEV_CODEC		((__force snd_device_type_t) 0x1008)
-#define	SNDRV_DEV_JACK          ((__force snd_device_type_t) 0x1009)
-#define	SNDRV_DEV_COMPRESS	((__force snd_device_type_t) 0x100A)
-#define	SNDRV_DEV_LOWLEVEL	((__force snd_device_type_t) 0x2000)
+enum snd_device_type {
+	SNDRV_DEV_TOPLEVEL	= 0,
+	SNDRV_DEV_CONTROL	= 1,
+	SNDRV_DEV_LOWLEVEL_PRE	= 2,
+	SNDRV_DEV_LOWLEVEL_NORMAL = 0x1000,
+	SNDRV_DEV_PCM,
+	SNDRV_DEV_RAWMIDI,
+	SNDRV_DEV_TIMER,
+	SNDRV_DEV_SEQUENCER,
+	SNDRV_DEV_HWDEP,
+	SNDRV_DEV_INFO,
+	SNDRV_DEV_BUS,
+	SNDRV_DEV_CODEC,
+	SNDRV_DEV_JACK,
+	SNDRV_DEV_COMPRESS,
+	SNDRV_DEV_LOWLEVEL	= 0x2000,
+};
 
-typedef int __bitwise snd_device_state_t;
-#define	SNDRV_DEV_BUILD		((__force snd_device_state_t) 0)
-#define	SNDRV_DEV_REGISTERED	((__force snd_device_state_t) 1)
-#define	SNDRV_DEV_DISCONNECTED	((__force snd_device_state_t) 2)
+enum snd_device_state {
+	SNDRV_DEV_BUILD,
+	SNDRV_DEV_REGISTERED,
+	SNDRV_DEV_DISCONNECTED,
+};
 
-typedef int __bitwise snd_device_cmd_t;
-#define	SNDRV_DEV_CMD_PRE	((__force snd_device_cmd_t) 0)
-#define	SNDRV_DEV_CMD_NORMAL	((__force snd_device_cmd_t) 1)	
-#define	SNDRV_DEV_CMD_POST	((__force snd_device_cmd_t) 2)
+enum snd_device_cmd {
+	SNDRV_DEV_CMD_PRE,
+	SNDRV_DEV_CMD_NORMAL,
+	SNDRV_DEV_CMD_POST,
+};
 
 struct snd_device;
 
@@ -86,8 +89,8 @@
 struct snd_device {
 	struct list_head list;		/* list of registered devices */
 	struct snd_card *card;		/* card which holds this device */
-	snd_device_state_t state;	/* state of the device */
-	snd_device_type_t type;		/* device type */
+	enum snd_device_state state;	/* state of the device */
+	enum snd_device_type type;	/* device type */
 	void *device_data;		/* device structure */
 	struct snd_device_ops *ops;	/* operations */
 };
@@ -131,11 +134,10 @@
 								state */
 	spinlock_t files_lock;		/* lock the files for this card */
 	int shutdown;			/* this card is going down */
-	int free_on_last_close;		/* free in context of file_release */
-	wait_queue_head_t shutdown_sleep;
-	atomic_t refcount;		/* refcount for disconnection */
+	struct completion *release_completion;
 	struct device *dev;		/* device assigned to this card */
-	struct device *card_dev;	/* cardX object for sysfs */
+	struct device card_dev;		/* cardX object for sysfs */
+	bool registered;		/* card_dev is registered? */
 
 #ifdef CONFIG_PM
 	unsigned int power_state;	/* power state */
@@ -149,6 +151,8 @@
 #endif
 };
 
+#define dev_to_snd_card(p)	container_of(p, struct snd_card, card_dev)
+
 #ifdef CONFIG_PM
 static inline void snd_power_lock(struct snd_card *card)
 {
@@ -197,7 +201,7 @@
 /* return a device pointer linked to each sound device as a parent */
 static inline struct device *snd_card_get_device_link(struct snd_card *card)
 {
-	return card ? card->card_dev : NULL;
+	return card ? &card->card_dev : NULL;
 }
 
 /* sound.c */
@@ -249,8 +253,7 @@
 
 #ifdef CONFIG_SND_OSSEMUL
 int snd_register_oss_device(int type, struct snd_card *card, int dev,
-			    const struct file_operations *f_ops, void *private_data,
-			    const char *name);
+			    const struct file_operations *f_ops, void *private_data);
 int snd_unregister_oss_device(int type, struct snd_card *card, int dev);
 void *snd_lookup_oss_minor_data(unsigned int minor, int type);
 #endif
@@ -284,9 +287,16 @@
 extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd);
 #endif
 
-int snd_card_create(int idx, const char *id,
-		    struct module *module, int extra_size,
-		    struct snd_card **card_ret);
+int snd_card_new(struct device *parent, int idx, const char *xid,
+		 struct module *module, int extra_size,
+		 struct snd_card **card_ret);
+
+static inline int __deprecated
+snd_card_create(int idx, const char *id, struct module *module, int extra_size,
+		struct snd_card **ret)
+{
+	return snd_card_new(NULL, idx, id, module, extra_size, ret);
+}
 
 int snd_card_disconnect(struct snd_card *card);
 int snd_card_free(struct snd_card *card);
@@ -298,20 +308,20 @@
 int snd_component_add(struct snd_card *card, const char *component);
 int snd_card_file_add(struct snd_card *card, struct file *file);
 int snd_card_file_remove(struct snd_card *card, struct file *file);
-void snd_card_unref(struct snd_card *card);
+#define snd_card_unref(card)	put_device(&(card)->card_dev)
 
 #define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
 
 /* device.c */
 
-int snd_device_new(struct snd_card *card, snd_device_type_t type,
+int snd_device_new(struct snd_card *card, enum snd_device_type type,
 		   void *device_data, struct snd_device_ops *ops);
 int snd_device_register(struct snd_card *card, void *device_data);
 int snd_device_register_all(struct snd_card *card);
 int snd_device_disconnect(struct snd_card *card, void *device_data);
 int snd_device_disconnect_all(struct snd_card *card);
 int snd_device_free(struct snd_card *card, void *device_data);
-int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd);
+int snd_device_free_all(struct snd_card *card, enum snd_device_cmd cmd);
 
 /* isadma.c */
 
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h
index 8c05e47a..6233eb0 100644
--- a/include/sound/hwdep.h
+++ b/include/sound/hwdep.h
@@ -60,7 +60,6 @@
 	int iface;
 
 #ifdef CONFIG_SND_OSSEMUL
-	char oss_dev[32];
 	int oss_type;
 	int ossreg;
 #endif
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 4883499..b4d6697 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -1141,4 +1141,12 @@
 	return 1ULL << (__force int) pcm_format;
 }
 
+/* printk helpers */
+#define pcm_err(pcm, fmt, args...) \
+	dev_err((pcm)->card->dev, fmt, ##args)
+#define pcm_warn(pcm, fmt, args...) \
+	dev_warn((pcm)->card->dev, fmt, ##args)
+#define pcm_dbg(pcm, fmt, args...) \
+	dev_dbg((pcm)->card->dev, fmt, ##args)
+
 #endif /* __SOUND_PCM_H */
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index adf0885..311dafe 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -157,10 +157,8 @@
 
 /* callbacks */
 
-void snd_rawmidi_receive_reset(struct snd_rawmidi_substream *substream);
 int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
 			const unsigned char *buffer, int count);
-void snd_rawmidi_transmit_reset(struct snd_rawmidi_substream *substream);
 int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream);
 int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
 			      unsigned char *buffer, int count);
diff --git a/sound/aoa/aoa.h b/sound/aoa/aoa.h
index e087894..34c668f 100644
--- a/sound/aoa/aoa.h
+++ b/sound/aoa/aoa.h
@@ -116,7 +116,7 @@
 	struct snd_card *alsa_card;
 };
         
-extern int aoa_snd_device_new(snd_device_type_t type,
+extern int aoa_snd_device_new(enum snd_device_type type,
 	void * device_data, struct snd_device_ops * ops);
 extern struct snd_card *aoa_get_card(void);
 extern int aoa_snd_ctl_add(struct snd_kcontrol* control);
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 4cedc69..f01bffb 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -889,7 +889,7 @@
 		return -ENODEV;
 	}
 
-	if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, onyx, &ops)) {
+	if (aoa_snd_device_new(SNDRV_DEV_CODEC, onyx, &ops)) {
 		printk(KERN_ERR PFX "failed to create onyx snd device!\n");
 		return -ENODEV;
 	}
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index c491ae0..cf3c630 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -826,7 +826,7 @@
 		return -ENODEV;
 	}
 
-	if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, tas, &ops)) {
+	if (aoa_snd_device_new(SNDRV_DEV_CODEC, tas, &ops)) {
 		printk(KERN_ERR PFX "failed to create tas snd device!\n");
 		return -ENODEV;
 	}
diff --git a/sound/aoa/codecs/toonie.c b/sound/aoa/codecs/toonie.c
index 69d2cb6..7e8c341 100644
--- a/sound/aoa/codecs/toonie.c
+++ b/sound/aoa/codecs/toonie.c
@@ -92,7 +92,7 @@
 	if (toonie->codec.connected != 1)
 		return -ENOTCONN;
 
-	if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, toonie, &ops)) {
+	if (aoa_snd_device_new(SNDRV_DEV_CODEC, toonie, &ops)) {
 		printk(KERN_ERR PFX "failed to create toonie snd device!\n");
 		return -ENODEV;
 	}
diff --git a/sound/aoa/core/alsa.c b/sound/aoa/core/alsa.c
index 0fa3855..4a7e4e6 100644
--- a/sound/aoa/core/alsa.c
+++ b/sound/aoa/core/alsa.c
@@ -23,13 +23,12 @@
 		/* cannot be EEXIST due to usage in aoa_fabric_register */
 		return -EBUSY;
 
-	err = snd_card_create(index, name, mod, sizeof(struct aoa_card),
-			      &alsa_card);
+	err = snd_card_new(dev, index, name, mod, sizeof(struct aoa_card),
+			   &alsa_card);
 	if (err < 0)
 		return err;
 	aoa_card = alsa_card->private_data;
 	aoa_card->alsa_card = alsa_card;
-	alsa_card->dev = dev;
 	strlcpy(alsa_card->driver, "AppleOnbdAudio", sizeof(alsa_card->driver));
 	strlcpy(alsa_card->shortname, name, sizeof(alsa_card->shortname));
 	strlcpy(alsa_card->longname, name, sizeof(alsa_card->longname));
@@ -60,7 +59,7 @@
 	}
 }
 
-int aoa_snd_device_new(snd_device_type_t type,
+int aoa_snd_device_new(enum snd_device_type type,
 		       void * device_data, struct snd_device_ops * ops)
 {
 	struct snd_card *card = aoa_get_card();
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index c421fdb..0e83a73 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -899,8 +899,8 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-			      THIS_MODULE, sizeof(struct aaci), &card);
+	err = snd_card_new(&dev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			   THIS_MODULE, sizeof(struct aaci), &card);
 	if (err < 0)
 		return NULL;
 
@@ -1055,8 +1055,6 @@
 	if (ret)
 		goto out;
 
-	snd_card_set_dev(aaci->card, &dev->dev);
-
 	ret = snd_card_register(aaci->card);
 	if (ret == 0) {
 		dev_info(&dev->dev, "%s\n", aaci->card->longname);
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 9a2ac1e..3a10df6 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -179,12 +179,11 @@
 		goto err_dev;
 	}
 
-	ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-			      THIS_MODULE, 0, &card);
+	ret = snd_card_new(&dev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			   THIS_MODULE, 0, &card);
 	if (ret < 0)
 		goto err;
 
-	card->dev = &dev->dev;
 	strlcpy(card->driver, dev->dev.driver->name, sizeof(card->driver));
 
 	ret = pxa2xx_pcm_new(card, &pxa2xx_ac97_pcm_client, &pxa2xx_ac97_pcm);
@@ -210,7 +209,6 @@
 
 	if (pdata && pdata->codec_pdata[0])
 		snd_ac97_dev_add_pdata(ac97_bus->codec[0], pdata->codec_pdata[0]);
-	snd_card_set_dev(card, &dev->dev);
 	ret = snd_card_register(card);
 	if (ret == 0) {
 		platform_set_drvdata(dev, card);
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c
index 3519518..edf2ca7 100644
--- a/sound/atmel/abdac.c
+++ b/sound/atmel/abdac.c
@@ -429,8 +429,9 @@
 	}
 	clk_enable(pclk);
 
-	retval = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-			THIS_MODULE, sizeof(struct atmel_abdac), &card);
+	retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
+			      SNDRV_DEFAULT_STR1, THIS_MODULE,
+			      sizeof(struct atmel_abdac), &card);
 	if (retval) {
 		dev_dbg(&pdev->dev, "could not create sound card device\n");
 		goto out_put_sample_clk;
@@ -467,8 +468,6 @@
 		goto out_unmap_regs;
 	}
 
-	snd_card_set_dev(card, &pdev->dev);
-
 	if (pdata->dws.dma_dev) {
 		dma_cap_mask_t mask;
 
@@ -492,7 +491,7 @@
 	if (!pdata->dws.dma_dev || !dac->dma.chan) {
 		dev_dbg(&pdev->dev, "DMA not available\n");
 		retval = -ENODEV;
-		goto out_unset_card_dev;
+		goto out_unmap_regs;
 	}
 
 	strcpy(card->driver, "Atmel ABDAC");
@@ -521,9 +520,6 @@
 out_release_dma:
 	dma_release_channel(dac->dma.chan);
 	dac->dma.chan = NULL;
-out_unset_card_dev:
-	snd_card_set_dev(card, NULL);
-	free_irq(irq, dac);
 out_unmap_regs:
 	iounmap(dac->regs);
 out_free_card:
@@ -579,7 +575,6 @@
 
 	dma_release_channel(dac->dma.chan);
 	dac->dma.chan = NULL;
-	snd_card_set_dev(card, NULL);
 	iounmap(dac->regs);
 	free_irq(dac->irq, dac);
 	snd_card_free(card);
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index c5f0ddd..05ec049 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -945,8 +945,9 @@
 	}
 	clk_enable(pclk);
 
-	retval = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
-			THIS_MODULE, sizeof(struct atmel_ac97c), &card);
+	retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
+			      SNDRV_DEFAULT_STR1, THIS_MODULE,
+			      sizeof(struct atmel_ac97c), &card);
 	if (retval) {
 		dev_dbg(&pdev->dev, "could not create sound card device\n");
 		goto err_snd_card_new;
@@ -990,8 +991,6 @@
 		chip->reset_pin = -EINVAL;
 	}
 
-	snd_card_set_dev(card, &pdev->dev);
-
 	atmel_ac97c_reset(chip);
 
 	/* Enable overrun interrupt from codec channel */
@@ -1113,8 +1112,6 @@
 		chip->dma.tx_chan = NULL;
 	}
 err_ac97_bus:
-	snd_card_set_dev(card, NULL);
-
 	if (gpio_is_valid(chip->reset_pin))
 		gpio_free(chip->reset_pin);
 
@@ -1195,7 +1192,6 @@
 		chip->dma.tx_chan = NULL;
 	}
 
-	snd_card_set_dev(card, NULL);
 	snd_card_free(card);
 
 	return 0;
diff --git a/sound/core/control.c b/sound/core/control.c
index d8aa206..f038f5a 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -151,7 +151,7 @@
 	if (snd_BUG_ON(!card || !id))
 		return;
 	read_lock(&card->ctl_files_rwlock);
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
 	card->mixer_oss_change_count++;
 #endif
 	list_for_each_entry(ctl, &card->ctl_files, list) {
@@ -170,7 +170,7 @@
 			ev->mask = mask;
 			list_add_tail(&ev->list, &ctl->events);
 		} else {
-			snd_printk(KERN_ERR "No memory available to allocate event\n");
+			dev_err(card->dev, "No memory available to allocate event\n");
 		}
 	_found:
 		wake_up(&ctl->change_sleep);
@@ -206,7 +206,7 @@
 
 	kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
 	if (kctl == NULL) {
-		snd_printk(KERN_ERR "Cannot allocate control instance\n");
+		pr_err("ALSA: Cannot allocate control instance\n");
 		return NULL;
 	}
 	*kctl = *control;
@@ -241,9 +241,8 @@
 	if (ncontrol->name) {
 		strlcpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name));
 		if (strcmp(ncontrol->name, kctl.id.name) != 0)
-			snd_printk(KERN_WARNING
-				   "Control name '%s' truncated to '%s'\n",
-				   ncontrol->name, kctl.id.name);
+			pr_warn("ALSA: Control name '%s' truncated to '%s'\n",
+				ncontrol->name, kctl.id.name);
 	}
 	kctl.id.index = ncontrol->index;
 	kctl.count = ncontrol->count ? ncontrol->count : 1;
@@ -306,7 +305,7 @@
 	while (snd_ctl_remove_numid_conflict(card, count)) {
 		if (--iter == 0) {
 			/* this situation is very unlikely */
-			snd_printk(KERN_ERR "unable to allocate new control numid\n");
+			dev_err(card->dev, "unable to allocate new control numid\n");
 			return -ENOMEM;
 		}
 	}
@@ -341,7 +340,7 @@
 	down_write(&card->controls_rwsem);
 	if (snd_ctl_find_id(card, &id)) {
 		up_write(&card->controls_rwsem);
-		snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
+		dev_err(card->dev, "control %i:%i:%i:%s:%i is already present\n",
 					id.iface,
 					id.device,
 					id.subdevice,
@@ -1406,7 +1405,7 @@
 		}
 	}
 	up_read(&snd_ioctl_rwsem);
-	snd_printdd("unknown ioctl = 0x%x\n", cmd);
+	dev_dbg(card->dev, "unknown ioctl = 0x%x\n", cmd);
 	return -ENOTTY;
 }
 
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 2bb95a7..b9c0910 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -247,7 +247,7 @@
 	} else {
 		size = get_elem_size(type, count);
 		if (size < 0) {
-			printk(KERN_ERR "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
+			dev_err(card->dev, "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
 			return -EINVAL;
 		}
 		if (copy_from_user(data->value.bytes.data,
diff --git a/sound/core/device.c b/sound/core/device.c
index df88def..856bfdc 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -41,7 +41,7 @@
  *
  * Return: Zero if successful, or a negative error code on failure.
  */
-int snd_device_new(struct snd_card *card, snd_device_type_t type,
+int snd_device_new(struct snd_card *card, enum snd_device_type type,
 		   void *device_data, struct snd_device_ops *ops)
 {
 	struct snd_device *dev;
@@ -50,7 +50,7 @@
 		return -ENXIO;
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL) {
-		snd_printk(KERN_ERR "Cannot allocate device\n");
+		dev_err(card->dev, "Cannot allocate device, type=%d\n", type);
 		return -ENOMEM;
 	}
 	dev->card = card;
@@ -90,17 +90,17 @@
 		if (dev->state == SNDRV_DEV_REGISTERED &&
 		    dev->ops->dev_disconnect)
 			if (dev->ops->dev_disconnect(dev))
-				snd_printk(KERN_ERR
-					   "device disconnect failure\n");
+				dev_err(card->dev,
+					"device disconnect failure\n");
 		if (dev->ops->dev_free) {
 			if (dev->ops->dev_free(dev))
-				snd_printk(KERN_ERR "device free failure\n");
+				dev_err(card->dev, "device free failure\n");
 		}
 		kfree(dev);
 		return 0;
 	}
-	snd_printd("device free %p (from %pF), not found\n", device_data,
-		   __builtin_return_address(0));
+	dev_dbg(card->dev, "device free %p (from %pF), not found\n",
+		device_data, __builtin_return_address(0));
 	return -ENXIO;
 }
 
@@ -131,13 +131,14 @@
 		if (dev->state == SNDRV_DEV_REGISTERED &&
 		    dev->ops->dev_disconnect) {
 			if (dev->ops->dev_disconnect(dev))
-				snd_printk(KERN_ERR "device disconnect failure\n");
+				dev_err(card->dev,
+					"device disconnect failure\n");
 			dev->state = SNDRV_DEV_DISCONNECTED;
 		}
 		return 0;
 	}
-	snd_printd("device disconnect %p (from %pF), not found\n", device_data,
-		   __builtin_return_address(0));
+	dev_dbg(card->dev, "device disconnect %p (from %pF), not found\n",
+		device_data, __builtin_return_address(0));
 	return -ENXIO;
 }
 
@@ -170,7 +171,7 @@
 			dev->state = SNDRV_DEV_REGISTERED;
 			return 0;
 		}
-		snd_printd("snd_device_register busy\n");
+		dev_dbg(card->dev, "snd_device_register busy\n");
 		return -EBUSY;
 	}
 	snd_BUG();
@@ -222,7 +223,7 @@
  * release all the devices on the card.
  * called from init.c
  */
-int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd)
+int snd_device_free_all(struct snd_card *card, enum snd_device_cmd cmd)
 {
 	struct snd_device *dev;
 	int err;
@@ -230,11 +231,11 @@
 
 	if (snd_BUG_ON(!card))
 		return -ENXIO;
-	range_low = (__force unsigned int)cmd * SNDRV_DEV_TYPE_RANGE_SIZE;
+	range_low = (unsigned int)cmd * SNDRV_DEV_TYPE_RANGE_SIZE;
 	range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1;
       __again:
 	list_for_each_entry(dev, &card->devices, list) {
-		type = (__force unsigned int)dev->type;
+		type = (unsigned int)dev->type;
 		if (type >= range_low && type <= range_high) {
 			if ((err = snd_device_free(card, dev->device_data)) < 0)
 				return err;
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index b8b31c4..886be7d 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -126,8 +126,7 @@
 
 	hrtimer_get_res(CLOCK_MONOTONIC, &tp);
 	if (tp.tv_sec > 0 || !tp.tv_nsec) {
-		snd_printk(KERN_ERR
-			   "snd-hrtimer: Invalid resolution %u.%09u",
+		pr_err("snd-hrtimer: Invalid resolution %u.%09u",
 			   (unsigned)tp.tv_sec, (unsigned)tp.tv_nsec);
 		return -EINVAL;
 	}
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index d105073..8c77865 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -375,7 +375,7 @@
 		*rhwdep = NULL;
 	hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
 	if (hwdep == NULL) {
-		snd_printk(KERN_ERR "hwdep: cannot allocate\n");
+		dev_err(card->dev, "hwdep: cannot allocate\n");
 		return -ENOMEM;
 	}
 	hwdep->card = card;
@@ -415,11 +415,12 @@
 static int snd_hwdep_dev_register(struct snd_device *device)
 {
 	struct snd_hwdep *hwdep = device->device_data;
+	struct snd_card *card = hwdep->card;
 	int err;
 	char name[32];
 
 	mutex_lock(&register_mutex);
-	if (snd_hwdep_search(hwdep->card, hwdep->device)) {
+	if (snd_hwdep_search(card, hwdep->device)) {
 		mutex_unlock(&register_mutex);
 		return -EBUSY;
 	}
@@ -428,8 +429,9 @@
 	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP,
 				       hwdep->card, hwdep->device,
 				       &snd_hwdep_f_ops, hwdep, name)) < 0) {
-		snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n",
-			   hwdep->card->number, hwdep->device);
+		dev_err(card->dev,
+			"unable to register hardware dependent device %i:%i\n",
+			card->number, hwdep->device);
 		list_del(&hwdep->list);
 		mutex_unlock(&register_mutex);
 		return err;
@@ -438,14 +440,15 @@
 	hwdep->ossreg = 0;
 	if (hwdep->oss_type >= 0) {
 		if ((hwdep->oss_type == SNDRV_OSS_DEVICE_TYPE_DMFM) && (hwdep->device != 0)) {
-			snd_printk (KERN_WARNING "only hwdep device 0 can be registered as OSS direct FM device!\n");
+			dev_warn(card->dev,
+				 "only hwdep device 0 can be registered as OSS direct FM device!\n");
 		} else {
 			if (snd_register_oss_device(hwdep->oss_type,
-						    hwdep->card, hwdep->device,
-						    &snd_hwdep_f_ops, hwdep,
-						    hwdep->oss_dev) < 0) {
-				snd_printk(KERN_ERR "unable to register OSS compatibility device %i:%i\n",
-					   hwdep->card->number, hwdep->device);
+						    card, hwdep->device,
+						    &snd_hwdep_f_ops, hwdep) < 0) {
+				dev_err(card->dev,
+					"unable to register OSS compatibility device %i:%i\n",
+					card->number, hwdep->device);
 			} else
 				hwdep->ossreg = 1;
 		}
diff --git a/sound/core/info.c b/sound/core/info.c
index e79baa1..051d55b 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -418,9 +418,14 @@
 			if (entry->c.text.write) {
 				entry->c.text.write(entry, data->wbuffer);
 				if (data->wbuffer->error) {
-					snd_printk(KERN_WARNING "data write error to %s (%i)\n",
-						entry->name,
-						data->wbuffer->error);
+					if (entry->card)
+						dev_warn(entry->card->dev, "info: data write error to %s (%i)\n",
+							 entry->name,
+							 data->wbuffer->error);
+					else
+						pr_warn("ALSA: info: data write error to %s (%i)\n",
+							entry->name,
+							data->wbuffer->error);
 				}
 			}
 			kfree(data->wbuffer->buffer);
@@ -540,7 +545,7 @@
 		snd_oss_root = entry;
 	}
 #endif
-#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+#if IS_ENABLED(CONFIG_SND_SEQUENCER)
 	{
 		struct snd_info_entry *entry;
 		if ((entry = snd_info_create_module_entry(THIS_MODULE, "seq", NULL)) == NULL)
@@ -567,7 +572,7 @@
 	snd_minor_info_done();
 	snd_info_version_done();
 	if (snd_proc_root) {
-#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+#if IS_ENABLED(CONFIG_SND_SEQUENCER)
 		snd_info_free_entry(snd_seq_root);
 #endif
 #ifdef CONFIG_SND_OSSEMUL
diff --git a/sound/core/init.c b/sound/core/init.c
index 0d42fcd..b7085eb 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -28,6 +28,7 @@
 #include <linux/time.h>
 #include <linux/ctype.h>
 #include <linux/pm.h>
+#include <linux/completion.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -94,7 +95,7 @@
 	return match;
 }
 
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
 int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
 EXPORT_SYMBOL(snd_mixer_oss_notify_callback);
 #endif
@@ -112,11 +113,11 @@
 	struct snd_info_entry *entry;
 
 	if ((err = snd_info_card_register(card)) < 0) {
-		snd_printd("unable to create card info\n");
+		dev_dbg(card->dev, "unable to create card info\n");
 		return err;
 	}
 	if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
-		snd_printd("unable to create card entry\n");
+		dev_dbg(card->dev, "unable to create card entry\n");
 		return err;
 	}
 	entry->c.text.read = snd_card_id_read;
@@ -156,8 +157,17 @@
 	return mask; /* unchanged */
 }
 
+static int snd_card_do_free(struct snd_card *card);
+static const struct attribute_group *card_dev_attr_groups[];
+
+static void release_card_device(struct device *dev)
+{
+	snd_card_do_free(dev_to_snd_card(dev));
+}
+
 /**
- *  snd_card_create - create and initialize a soundcard structure
+ *  snd_card_new - create and initialize a soundcard structure
+ *  @parent: the parent device object
  *  @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
  *  @xid: card identification (ASCII string)
  *  @module: top level module for locking
@@ -172,7 +182,7 @@
  *
  *  Return: Zero if successful or a negative error code.
  */
-int snd_card_create(int idx, const char *xid,
+int snd_card_new(struct device *parent, int idx, const char *xid,
 		    struct module *module, int extra_size,
 		    struct snd_card **card_ret)
 {
@@ -188,6 +198,8 @@
 	card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
 	if (!card)
 		return -ENOMEM;
+	if (extra_size > 0)
+		card->private_data = (char *)card + sizeof(struct snd_card);
 	if (xid)
 		strlcpy(card->id, xid, sizeof(card->id));
 	err = 0;
@@ -205,14 +217,16 @@
 		err = -ENODEV;
 	if (err < 0) {
 		mutex_unlock(&snd_card_mutex);
-		snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i), error: %d\n",
+		dev_err(parent, "cannot find the slot for index %d (range 0-%i), error: %d\n",
 			 idx, snd_ecards_limit - 1, err);
-		goto __error;
+		kfree(card);
+		return err;
 	}
 	set_bit(idx, snd_cards_lock);		/* lock it */
 	if (idx >= snd_ecards_limit)
 		snd_ecards_limit = idx + 1; /* increase the limit */
 	mutex_unlock(&snd_card_mutex);
+	card->dev = parent;
 	card->number = idx;
 	card->module = module;
 	INIT_LIST_HEAD(&card->devices);
@@ -222,36 +236,42 @@
 	INIT_LIST_HEAD(&card->ctl_files);
 	spin_lock_init(&card->files_lock);
 	INIT_LIST_HEAD(&card->files_list);
-	init_waitqueue_head(&card->shutdown_sleep);
-	atomic_set(&card->refcount, 0);
 #ifdef CONFIG_PM
 	mutex_init(&card->power_lock);
 	init_waitqueue_head(&card->power_sleep);
 #endif
+
+	device_initialize(&card->card_dev);
+	card->card_dev.parent = parent;
+	card->card_dev.class = sound_class;
+	card->card_dev.release = release_card_device;
+	card->card_dev.groups = card_dev_attr_groups;
+	err = kobject_set_name(&card->card_dev.kobj, "card%d", idx);
+	if (err < 0)
+		goto __error;
+
 	/* the control interface cannot be accessed from the user space until */
 	/* snd_cards_bitmask and snd_cards are set with snd_card_register */
 	err = snd_ctl_create(card);
 	if (err < 0) {
-		snd_printk(KERN_ERR "unable to register control minors\n");
+		dev_err(parent, "unable to register control minors\n");
 		goto __error;
 	}
 	err = snd_info_card_create(card);
 	if (err < 0) {
-		snd_printk(KERN_ERR "unable to create card info\n");
+		dev_err(parent, "unable to create card info\n");
 		goto __error_ctl;
 	}
-	if (extra_size > 0)
-		card->private_data = (char *)card + sizeof(struct snd_card);
 	*card_ret = card;
 	return 0;
 
       __error_ctl:
 	snd_device_free_all(card, SNDRV_DEV_CMD_PRE);
       __error:
-	kfree(card);
+	put_device(&card->card_dev);
   	return err;
 }
-EXPORT_SYMBOL(snd_card_create);
+EXPORT_SYMBOL(snd_card_new);
 
 /* return non-zero if a card is already locked */
 int snd_card_locked(int card)
@@ -394,7 +414,7 @@
 	/* phase 3: notify all connected devices about disconnection */
 	/* at this point, they cannot respond to any calls except release() */
 
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
 	if (snd_mixer_oss_notify_callback)
 		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_DISCONNECT);
 #endif
@@ -402,12 +422,12 @@
 	/* notify all devices that we are disconnected */
 	err = snd_device_disconnect_all(card);
 	if (err < 0)
-		snd_printk(KERN_ERR "not all devices for card %i can be disconnected\n", card->number);
+		dev_err(card->dev, "not all devices for card %i can be disconnected\n", card->number);
 
 	snd_info_card_disconnect(card);
-	if (card->card_dev) {
-		device_unregister(card->card_dev);
-		card->card_dev = NULL;
+	if (card->registered) {
+		device_del(&card->card_dev);
+		card->registered = false;
 	}
 #ifdef CONFIG_PM
 	wake_up(&card->power_sleep);
@@ -430,81 +450,59 @@
  */
 static int snd_card_do_free(struct snd_card *card)
 {
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
 	if (snd_mixer_oss_notify_callback)
 		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE);
 #endif
 	if (snd_device_free_all(card, SNDRV_DEV_CMD_PRE) < 0) {
-		snd_printk(KERN_ERR "unable to free all devices (pre)\n");
+		dev_err(card->dev, "unable to free all devices (pre)\n");
 		/* Fatal, but this situation should never occur */
 	}
 	if (snd_device_free_all(card, SNDRV_DEV_CMD_NORMAL) < 0) {
-		snd_printk(KERN_ERR "unable to free all devices (normal)\n");
+		dev_err(card->dev, "unable to free all devices (normal)\n");
 		/* Fatal, but this situation should never occur */
 	}
 	if (snd_device_free_all(card, SNDRV_DEV_CMD_POST) < 0) {
-		snd_printk(KERN_ERR "unable to free all devices (post)\n");
+		dev_err(card->dev, "unable to free all devices (post)\n");
 		/* Fatal, but this situation should never occur */
 	}
 	if (card->private_free)
 		card->private_free(card);
 	snd_info_free_entry(card->proc_id);
 	if (snd_info_card_free(card) < 0) {
-		snd_printk(KERN_WARNING "unable to free card info\n");
+		dev_warn(card->dev, "unable to free card info\n");
 		/* Not fatal error */
 	}
+	if (card->release_completion)
+		complete(card->release_completion);
 	kfree(card);
 	return 0;
 }
 
-/**
- * snd_card_unref - release the reference counter
- * @card: the card instance
- *
- * Decrements the reference counter.  When it reaches to zero, wake up
- * the sleeper and call the destructor if needed.
- */
-void snd_card_unref(struct snd_card *card)
-{
-	if (atomic_dec_and_test(&card->refcount)) {
-		wake_up(&card->shutdown_sleep);
-		if (card->free_on_last_close)
-			snd_card_do_free(card);
-	}
-}
-EXPORT_SYMBOL(snd_card_unref);
-
 int snd_card_free_when_closed(struct snd_card *card)
 {
-	int ret;
-
-	atomic_inc(&card->refcount);
-	ret = snd_card_disconnect(card);
-	if (ret) {
-		atomic_dec(&card->refcount);
-		return ret;
-	}
-
-	card->free_on_last_close = 1;
-	if (atomic_dec_and_test(&card->refcount))
-		snd_card_do_free(card);
-	return 0;
-}
-
-EXPORT_SYMBOL(snd_card_free_when_closed);
-
-int snd_card_free(struct snd_card *card)
-{
 	int ret = snd_card_disconnect(card);
 	if (ret)
 		return ret;
-
-	/* wait, until all devices are ready for the free operation */
-	wait_event(card->shutdown_sleep, !atomic_read(&card->refcount));
-	snd_card_do_free(card);
+	put_device(&card->card_dev);
 	return 0;
 }
+EXPORT_SYMBOL(snd_card_free_when_closed);
 
+int snd_card_free(struct snd_card *card)
+{
+	struct completion released;
+	int ret;
+
+	init_completion(&released);
+	card->release_completion = &released;
+	ret = snd_card_free_when_closed(card);
+	if (ret)
+		return ret;
+	/* wait, until all devices are ready for the free operation */
+	wait_for_completion(&released);
+	return 0;
+}
 EXPORT_SYMBOL(snd_card_free);
 
 /* retrieve the last word of shortname or longname */
@@ -598,7 +596,7 @@
 		goto again;
 	}
 	/* last resort... */
-	snd_printk(KERN_ERR "unable to set card id (%s)\n", id);
+	dev_err(card->dev, "unable to set card id (%s)\n", id);
 	if (card->proc_root->name)
 		strlcpy(card->id, card->proc_root->name, sizeof(card->id));
 }
@@ -626,15 +624,15 @@
 card_id_show_attr(struct device *dev,
 		  struct device_attribute *attr, char *buf)
 {
-	struct snd_card *card = dev_get_drvdata(dev);
-	return snprintf(buf, PAGE_SIZE, "%s\n", card ? card->id : "(null)");
+	struct snd_card *card = container_of(dev, struct snd_card, card_dev);
+	return snprintf(buf, PAGE_SIZE, "%s\n", card->id);
 }
 
 static ssize_t
 card_id_store_attr(struct device *dev, struct device_attribute *attr,
 		   const char *buf, size_t count)
 {
-	struct snd_card *card = dev_get_drvdata(dev);
+	struct snd_card *card = container_of(dev, struct snd_card, card_dev);
 	char buf1[sizeof(card->id)];
 	size_t copy = count > sizeof(card->id) - 1 ?
 					sizeof(card->id) - 1 : count;
@@ -660,19 +658,32 @@
 	return count;
 }
 
-static struct device_attribute card_id_attrs =
-	__ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
+static DEVICE_ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
 
 static ssize_t
 card_number_show_attr(struct device *dev,
 		     struct device_attribute *attr, char *buf)
 {
-	struct snd_card *card = dev_get_drvdata(dev);
-	return snprintf(buf, PAGE_SIZE, "%i\n", card ? card->number : -1);
+	struct snd_card *card = container_of(dev, struct snd_card, card_dev);
+	return snprintf(buf, PAGE_SIZE, "%i\n", card->number);
 }
 
-static struct device_attribute card_number_attrs =
-	__ATTR(number, S_IRUGO, card_number_show_attr, NULL);
+static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL);
+
+static struct attribute *card_dev_attrs[] = {
+	&dev_attr_id.attr,
+	&dev_attr_number.attr,
+	NULL
+};
+
+static struct attribute_group card_dev_attr_group = {
+	.attrs	= card_dev_attrs,
+};
+
+static const struct attribute_group *card_dev_attr_groups[] = {
+	&card_dev_attr_group,
+	NULL
+};
 
 /**
  *  snd_card_register - register the soundcard
@@ -692,12 +703,11 @@
 	if (snd_BUG_ON(!card))
 		return -EINVAL;
 
-	if (!card->card_dev) {
-		card->card_dev = device_create(sound_class, card->dev,
-					       MKDEV(0, 0), card,
-					       "card%i", card->number);
-		if (IS_ERR(card->card_dev))
-			card->card_dev = NULL;
+	if (!card->registered) {
+		err = device_add(&card->card_dev);
+		if (err < 0)
+			return err;
+		card->registered = true;
 	}
 
 	if ((err = snd_device_register_all(card)) < 0)
@@ -723,19 +733,10 @@
 	snd_cards[card->number] = card;
 	mutex_unlock(&snd_card_mutex);
 	init_info_for_card(card);
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
 	if (snd_mixer_oss_notify_callback)
 		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
 #endif
-	if (card->card_dev) {
-		err = device_create_file(card->card_dev, &card_id_attrs);
-		if (err < 0)
-			return err;
-		err = device_create_file(card->card_dev, &card_number_attrs);
-		if (err < 0)
-			return err;
-	}
-
 	return 0;
 }
 
@@ -908,7 +909,7 @@
 		return -ENODEV;
 	}
 	list_add(&mfile->list, &card->files_list);
-	atomic_inc(&card->refcount);
+	get_device(&card->card_dev);
 	spin_unlock(&card->files_lock);
 	return 0;
 }
@@ -947,11 +948,11 @@
 	}
 	spin_unlock(&card->files_lock);
 	if (!found) {
-		snd_printk(KERN_ERR "ALSA card file remove problem (%p)\n", file);
+		dev_err(card->dev, "card file remove problem (%p)\n", file);
 		return -ENOENT;
 	}
 	kfree(found);
-	snd_card_unref(card);
+	put_device(&card->card_dev);
 	return 0;
 }
 
diff --git a/sound/core/isadma.c b/sound/core/isadma.c
index e2b3861..31e8544 100644
--- a/sound/core/isadma.c
+++ b/sound/core/isadma.c
@@ -106,7 +106,7 @@
 		result = result1;
 #ifdef CONFIG_SND_DEBUG
 	if (result > size)
-		snd_printk(KERN_ERR "pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
+		pr_err("ALSA: pointer (0x%x) for DMA #%ld is greater than transfer size (0x%x)\n", result, dma, size);
 #endif
 	if (result >= size || result == 0)
 		return 0;
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 4595f93..082509e 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -207,7 +207,7 @@
 		break;
 #endif
 	default:
-		printk(KERN_ERR "snd-malloc: invalid device type %d\n", type);
+		pr_err("snd-malloc: invalid device type %d\n", type);
 		dmab->area = NULL;
 		dmab->addr = 0;
 		return -ENXIO;
@@ -284,7 +284,7 @@
 		break;
 #endif
 	default:
-		printk(KERN_ERR "snd-malloc: invalid device type %d\n", dmab->dev.type);
+		pr_err("snd-malloc: invalid device type %d\n", dmab->dev.type);
 	}
 }
 
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index e8a1d18..5e6349f 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1187,7 +1187,8 @@
 			if (oss_mixer_names[ch] && strcmp(oss_mixer_names[ch], str) == 0)
 				break;
 		if (ch >= SNDRV_OSS_MAX_MIXERS) {
-			snd_printk(KERN_ERR "mixer_oss: invalid OSS volume '%s'\n", str);
+			pr_err("ALSA: mixer_oss: invalid OSS volume '%s'\n",
+			       str);
 			continue;
 		}
 		cptr = snd_info_get_str(str, cptr, sizeof(str));
@@ -1201,7 +1202,7 @@
 		snd_info_get_str(idxstr, cptr, sizeof(idxstr));
 		idx = simple_strtoul(idxstr, NULL, 10);
 		if (idx >= 0x4000) { /* too big */
-			snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx);
+			pr_err("ALSA: mixer_oss: invalid index %d\n", idx);
 			continue;
 		}
 		mutex_lock(&mixer->reg_mutex);
@@ -1212,7 +1213,7 @@
 			goto __unlock;
 		tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
 		if (! tbl) {
-			snd_printk(KERN_ERR "mixer_oss: no memory\n");
+			pr_err("ALSA: mixer_oss: no memory\n");
 			goto __unlock;
 		}
 		tbl->oss_id = ch;
@@ -1343,20 +1344,18 @@
 	struct snd_mixer_oss *mixer;
 
 	if (cmd == SND_MIXER_OSS_NOTIFY_REGISTER) {
-		char name[128];
 		int idx, err;
 
 		mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL);
 		if (mixer == NULL)
 			return -ENOMEM;
 		mutex_init(&mixer->reg_mutex);
-		sprintf(name, "mixer%i%i", card->number, 0);
 		if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,
 						   card, 0,
-						   &snd_mixer_oss_f_ops, card,
-						   name)) < 0) {
-			snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n",
-				   card->number, 0);
+						   &snd_mixer_oss_f_ops, card)) < 0) {
+			dev_err(card->dev,
+				"unable to register OSS mixer device %i:%i\n",
+				card->number, 0);
 			kfree(mixer);
 			return err;
 		}
@@ -1365,7 +1364,8 @@
 		if (*card->mixername)
 			strlcpy(mixer->name, card->mixername, sizeof(mixer->name));
 		else
-			strlcpy(mixer->name, name, sizeof(mixer->name));
+			snprintf(mixer->name, sizeof(mixer->name),
+				 "mixer%i", card->number);
 #ifdef SNDRV_OSS_INFO_DEV_MIXERS
 		snd_oss_info_register(SNDRV_OSS_INFO_DEV_MIXERS,
 				      card->number,
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 4c1cc51..ada69d7 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -854,7 +854,7 @@
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
 	sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
 	if (!sw_params || !params || !sparams) {
-		snd_printd("No memory\n");
+		pcm_dbg(substream->pcm, "No memory\n");
 		err = -ENOMEM;
 		goto failure;
 	}
@@ -877,7 +877,7 @@
 	}
 	err = snd_pcm_hw_param_mask(substream, sparams, SNDRV_PCM_HW_PARAM_ACCESS, &mask);
 	if (err < 0) {
-		snd_printd("No usable accesses\n");
+		pcm_dbg(substream->pcm, "No usable accesses\n");
 		err = -EINVAL;
 		goto failure;
 	}
@@ -902,7 +902,7 @@
 				break;
 		}
 		if ((__force int)sformat > (__force int)SNDRV_PCM_FORMAT_LAST) {
-			snd_printd("Cannot find a format!!!\n");
+			pcm_dbg(substream->pcm, "Cannot find a format!!!\n");
 			err = -EINVAL;
 			goto failure;
 		}
@@ -942,14 +942,16 @@
 		if ((err = snd_pcm_plug_format_plugins(substream,
 						       params, 
 						       sparams)) < 0) {
-			snd_printd("snd_pcm_plug_format_plugins failed: %i\n", err);
+			pcm_dbg(substream->pcm,
+				"snd_pcm_plug_format_plugins failed: %i\n", err);
 			snd_pcm_oss_plugin_clear(substream);
 			goto failure;
 		}
 		if (runtime->oss.plugin_first) {
 			struct snd_pcm_plugin *plugin;
 			if ((err = snd_pcm_plugin_build_io(substream, sparams, &plugin)) < 0) {
-				snd_printd("snd_pcm_plugin_build_io failed: %i\n", err);
+				pcm_dbg(substream->pcm,
+					"snd_pcm_plugin_build_io failed: %i\n", err);
 				snd_pcm_oss_plugin_clear(substream);
 				goto failure;
 			}
@@ -983,7 +985,7 @@
 	snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
 
 	if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) {
-		snd_printd("HW_PARAMS failed: %i\n", err);
+		pcm_dbg(substream->pcm, "HW_PARAMS failed: %i\n", err);
 		goto failure;
 	}
 
@@ -1016,7 +1018,7 @@
 	}
 
 	if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params)) < 0) {
-		snd_printd("SW_PARAMS failed: %i\n", err);
+		pcm_dbg(substream->pcm, "SW_PARAMS failed: %i\n", err);
 		goto failure;
 	}
 
@@ -1110,7 +1112,8 @@
 
 	err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL);
 	if (err < 0) {
-		snd_printd("snd_pcm_oss_prepare: SNDRV_PCM_IOCTL_PREPARE failed\n");
+		pcm_dbg(substream->pcm,
+			"snd_pcm_oss_prepare: SNDRV_PCM_IOCTL_PREPARE failed\n");
 		return err;
 	}
 	runtime->oss.prepare = 0;
@@ -1175,12 +1178,10 @@
 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
 		    runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
 #ifdef OSS_DEBUG
-			if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
-				printk(KERN_DEBUG "pcm_oss: write: "
-				       "recovering from XRUN\n");
-			else
-				printk(KERN_DEBUG "pcm_oss: write: "
-				       "recovering from SUSPEND\n");
+			pcm_dbg(substream->pcm,
+				"pcm_oss: write: recovering from %s\n",
+				runtime->status->state == SNDRV_PCM_STATE_XRUN ?
+				"XRUN" : "SUSPEND");
 #endif
 			ret = snd_pcm_oss_prepare(substream);
 			if (ret < 0)
@@ -1213,12 +1214,10 @@
 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
 		    runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
 #ifdef OSS_DEBUG
-			if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
-				printk(KERN_DEBUG "pcm_oss: read: "
-				       "recovering from XRUN\n");
-			else
-				printk(KERN_DEBUG "pcm_oss: read: "
-				       "recovering from SUSPEND\n");
+			pcm_dbg(substream->pcm,
+				"pcm_oss: read: recovering from %s\n",
+				runtime->status->state == SNDRV_PCM_STATE_XRUN ?
+				"XRUN" : "SUSPEND");
 #endif
 			ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
 			if (ret < 0)
@@ -1261,12 +1260,10 @@
 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
 		    runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
 #ifdef OSS_DEBUG
-			if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
-				printk(KERN_DEBUG "pcm_oss: writev: "
-				       "recovering from XRUN\n");
-			else
-				printk(KERN_DEBUG "pcm_oss: writev: "
-				       "recovering from SUSPEND\n");
+			pcm_dbg(substream->pcm,
+				"pcm_oss: writev: recovering from %s\n",
+				runtime->status->state == SNDRV_PCM_STATE_XRUN ?
+				"XRUN" : "SUSPEND");
 #endif
 			ret = snd_pcm_oss_prepare(substream);
 			if (ret < 0)
@@ -1299,12 +1296,10 @@
 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
 		    runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
 #ifdef OSS_DEBUG
-			if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
-				printk(KERN_DEBUG "pcm_oss: readv: "
-				       "recovering from XRUN\n");
-			else
-				printk(KERN_DEBUG "pcm_oss: readv: "
-				       "recovering from SUSPEND\n");
+			pcm_dbg(substream->pcm,
+				"pcm_oss: readv: recovering from %s\n",
+				runtime->status->state == SNDRV_PCM_STATE_XRUN ?
+				"XRUN" : "SUSPEND");
 #endif
 			ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
 			if (ret < 0)
@@ -1561,7 +1556,7 @@
 	init_waitqueue_entry(&wait, current);
 	add_wait_queue(&runtime->sleep, &wait);
 #ifdef OSS_DEBUG
-	printk(KERN_DEBUG "sync1: size = %li\n", size);
+	pcm_dbg(substream->pcm, "sync1: size = %li\n", size);
 #endif
 	while (1) {
 		result = snd_pcm_oss_write2(substream, runtime->oss.buffer, size, 1);
@@ -1587,7 +1582,8 @@
 			break;
 		}
 		if (res == 0) {
-			snd_printk(KERN_ERR "OSS sync error - DMA timeout\n");
+			pcm_err(substream->pcm,
+				"OSS sync error - DMA timeout\n");
 			result = -EIO;
 			break;
 		}
@@ -1618,7 +1614,7 @@
 		mutex_lock(&runtime->oss.params_lock);
 		if (runtime->oss.buffer_used > 0) {
 #ifdef OSS_DEBUG
-			printk(KERN_DEBUG "sync: buffer_used\n");
+			pcm_dbg(substream->pcm, "sync: buffer_used\n");
 #endif
 			size = (8 * (runtime->oss.period_bytes - runtime->oss.buffer_used) + 7) / width;
 			snd_pcm_format_set_silence(format,
@@ -1631,7 +1627,7 @@
 			}
 		} else if (runtime->oss.period_ptr > 0) {
 #ifdef OSS_DEBUG
-			printk(KERN_DEBUG "sync: period_ptr\n");
+			pcm_dbg(substream->pcm, "sync: period_ptr\n");
 #endif
 			size = runtime->oss.period_bytes - runtime->oss.period_ptr;
 			snd_pcm_format_set_silence(format,
@@ -1983,7 +1979,7 @@
 	int err, cmd;
 
 #ifdef OSS_DEBUG
-	printk(KERN_DEBUG "pcm_oss: trigger = 0x%x\n", trigger);
+	pcm_dbg(substream->pcm, "pcm_oss: trigger = 0x%x\n", trigger);
 #endif
 	
 	psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
@@ -2203,9 +2199,9 @@
 	}
 
 #ifdef OSS_DEBUG
-	printk(KERN_DEBUG "pcm_oss: space: bytes = %i, fragments = %i, "
-	       "fragstotal = %i, fragsize = %i\n",
-	       info.bytes, info.fragments, info.fragstotal, info.fragsize);
+	pcm_dbg(substream->pcm,
+		"pcm_oss: space: bytes = %i, fragments = %i, fragstotal = %i, fragsize = %i\n",
+		info.bytes, info.fragments, info.fragstotal, info.fragsize);
 #endif
 	if (copy_to_user(_info, &info, sizeof(info)))
 		return -EFAULT;
@@ -2215,7 +2211,7 @@
 static int snd_pcm_oss_get_mapbuf(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct buffmem_desc __user * _info)
 {
 	// it won't be probably implemented
-	// snd_printd("TODO: snd_pcm_oss_get_mapbuf\n");
+	// pr_debug("TODO: snd_pcm_oss_get_mapbuf\n");
 	return -EINVAL;
 }
 
@@ -2519,7 +2515,7 @@
 	if (((cmd >> 8) & 0xff) != 'P')
 		return -EINVAL;
 #ifdef OSS_DEBUG
-	printk(KERN_DEBUG "pcm_oss: ioctl = 0x%x\n", cmd);
+	pr_debug("pcm_oss: ioctl = 0x%x\n", cmd);
 #endif
 	switch (cmd) {
 	case SNDCTL_DSP_RESET:
@@ -2646,7 +2642,7 @@
 	case SNDCTL_DSP_PROFILE:
 		return 0;	/* silently ignore */
 	default:
-		snd_printd("pcm_oss: unknown command = 0x%x\n", cmd);
+		pr_debug("pcm_oss: unknown command = 0x%x\n", cmd);
 	}
 	return -EINVAL;
 }
@@ -2673,8 +2669,9 @@
 #else
 	{
 		ssize_t res = snd_pcm_oss_read1(substream, buf, count);
-		printk(KERN_DEBUG "pcm_oss: read %li bytes "
-		       "(returned %li bytes)\n", (long)count, (long)res);
+		pcm_dbg(substream->pcm,
+			"pcm_oss: read %li bytes (returned %li bytes)\n",
+			(long)count, (long)res);
 		return res;
 	}
 #endif
@@ -2693,7 +2690,7 @@
 	substream->f_flags = file->f_flags & O_NONBLOCK;
 	result = snd_pcm_oss_write1(substream, buf, count);
 #ifdef OSS_DEBUG
-	printk(KERN_DEBUG "pcm_oss: write %li bytes (wrote %li bytes)\n",
+	pcm_dbg(substream->pcm, "pcm_oss: write %li bytes (wrote %li bytes)\n",
 	       (long)count, (long)result);
 #endif
 	return result;
@@ -2772,7 +2769,7 @@
 	int err;
 
 #ifdef OSS_DEBUG
-	printk(KERN_DEBUG "pcm_oss: mmap begin\n");
+	pr_debug("pcm_oss: mmap begin\n");
 #endif
 	pcm_oss_file = file->private_data;
 	switch ((area->vm_flags & (VM_READ | VM_WRITE))) {
@@ -2822,7 +2819,7 @@
 	runtime->silence_threshold = 0;
 	runtime->silence_size = 0;
 #ifdef OSS_DEBUG
-	printk(KERN_DEBUG "pcm_oss: mmap ok, bytes = 0x%x\n",
+	pr_debug("pcm_oss: mmap ok, bytes = 0x%x\n",
 	       runtime->oss.mmap_bytes);
 #endif
 	/* In mmap mode we never stop */
@@ -3007,12 +3004,10 @@
 
 static void register_oss_dsp(struct snd_pcm *pcm, int index)
 {
-	char name[128];
-	sprintf(name, "dsp%i%i", pcm->card->number, pcm->device);
 	if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
 				    pcm->card, index, &snd_pcm_oss_f_reg,
-				    pcm, name) < 0) {
-		snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n",
+				    pcm) < 0) {
+		pcm_err(pcm, "unable to register OSS PCM device %i:%i\n",
 			   pcm->card->number, pcm->device);
 	}
 }
@@ -3093,12 +3088,12 @@
 	/* check device map table */
 	for (i = 0; i < SNDRV_CARDS; i++) {
 		if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) {
-			snd_printk(KERN_ERR "invalid dsp_map[%d] = %d\n",
+			pr_err("ALSA: pcm_oss: invalid dsp_map[%d] = %d\n",
 				   i, dsp_map[i]);
 			dsp_map[i] = 0;
 		}
 		if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) {
-			snd_printk(KERN_ERR "invalid adsp_map[%d] = %d\n",
+			pr_err("ALSA: pcm_oss: invalid adsp_map[%d] = %d\n",
 				   i, adsp_map[i]);
 			adsp_map[i] = 1;
 		}
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index e1e9e0c..9defdae 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -295,7 +295,7 @@
 	return snd_pcm_state_names[(__force int)state];
 }
 
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 #include <linux/soundcard.h>
 
 static const char *snd_pcm_oss_format_name(int format)
@@ -338,7 +338,8 @@
 
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (! info) {
-		printk(KERN_DEBUG "snd_pcm_proc_info_read: cannot malloc\n");
+		pcm_dbg(substream->pcm,
+			"snd_pcm_proc_info_read: cannot malloc\n");
 		return;
 	}
 
@@ -398,7 +399,7 @@
 	snd_iprintf(buffer, "rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, runtime->rate_den);	
 	snd_iprintf(buffer, "period_size: %lu\n", runtime->period_size);	
 	snd_iprintf(buffer, "buffer_size: %lu\n", runtime->buffer_size);	
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 	if (substream->oss.oss) {
 		snd_iprintf(buffer, "OSS format: %s\n", snd_pcm_oss_format_name(runtime->oss.format));
 		snd_iprintf(buffer, "OSS channels: %u\n", runtime->oss.channels);	
@@ -651,7 +652,7 @@
 	struct snd_pcm_str *pstr = &pcm->streams[stream];
 	struct snd_pcm_substream *substream, *prev;
 
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 	mutex_init(&pstr->oss.setup_mutex);
 #endif
 	pstr->stream = stream;
@@ -660,7 +661,7 @@
 	if (substream_count > 0 && !pcm->internal) {
 		err = snd_pcm_stream_proc_init(pstr);
 		if (err < 0) {
-			snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
+			pcm_err(pcm, "Error in snd_pcm_stream_proc_init\n");
 			return err;
 		}
 	}
@@ -668,7 +669,7 @@
 	for (idx = 0, prev = NULL; idx < substream_count; idx++) {
 		substream = kzalloc(sizeof(*substream), GFP_KERNEL);
 		if (substream == NULL) {
-			snd_printk(KERN_ERR "Cannot allocate PCM substream\n");
+			pcm_err(pcm, "Cannot allocate PCM substream\n");
 			return -ENOMEM;
 		}
 		substream->pcm = pcm;
@@ -685,7 +686,8 @@
 		if (!pcm->internal) {
 			err = snd_pcm_substream_proc_init(substream);
 			if (err < 0) {
-				snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
+				pcm_err(pcm,
+					"Error in snd_pcm_stream_proc_init\n");
 				if (prev == NULL)
 					pstr->substream = NULL;
 				else
@@ -724,7 +726,7 @@
 		*rpcm = NULL;
 	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
 	if (pcm == NULL) {
-		snd_printk(KERN_ERR "Cannot allocate PCM\n");
+		dev_err(card->dev, "Cannot allocate PCM\n");
 		return -ENOMEM;
 	}
 	pcm->card = card;
@@ -807,7 +809,7 @@
 static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
 {
 	struct snd_pcm_substream *substream, *substream_next;
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 	struct snd_pcm_oss_setup *setup, *setupn;
 #endif
 	substream = pstr->substream;
@@ -819,7 +821,7 @@
 		substream = substream_next;
 	}
 	snd_pcm_stream_proc_done(pstr);
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 	for (setup = pstr->oss.setup_list; setup; setup = setupn) {
 		setupn = setup->next;
 		kfree(setup->task_name);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a210467..6630a4e 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -174,7 +174,7 @@
 	if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {
 		char name[16];
 		snd_pcm_debug_name(substream, name, sizeof(name));
-		snd_printd(KERN_DEBUG "XRUN: %s\n", name);
+		pcm_warn(substream->pcm, "XRUN: %s\n", name);
 		dump_stack_on_xrun(substream);
 	}
 }
@@ -184,9 +184,7 @@
 	do {								\
 		if (xrun_debug(substream, XRUN_DEBUG_BASIC)) {		\
 			xrun_log_show(substream);			\
-			if (snd_printd_ratelimit()) {			\
-				snd_printd("PCM: " fmt, ##args);	\
-			}						\
+			pr_err_ratelimited("ALSA: PCM: " fmt, ##args);	\
 			dump_stack_on_xrun(substream);			\
 		}							\
 	} while (0)
@@ -253,7 +251,7 @@
 		entry = &log->entries[idx];
 		if (entry->period_size == 0)
 			break;
-		snd_printd("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, "
+		pr_info("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, "
 			   "hwptr=%ld/%ld\n",
 			   name, entry->in_interrupt ? "[Q] " : "",
 			   entry->jiffies,
@@ -342,14 +340,14 @@
 		return -EPIPE;
 	}
 	if (pos >= runtime->buffer_size) {
-		if (snd_printd_ratelimit()) {
+		if (printk_ratelimit()) {
 			char name[16];
 			snd_pcm_debug_name(substream, name, sizeof(name));
 			xrun_log_show(substream);
-			snd_printd(KERN_ERR  "BUG: %s, pos = %ld, "
-				   "buffer size = %ld, period size = %ld\n",
-				   name, pos, runtime->buffer_size,
-				   runtime->period_size);
+			pcm_err(substream->pcm,
+				"BUG: %s, pos = %ld, buffer size = %ld, period size = %ld\n",
+				name, pos, runtime->buffer_size,
+				runtime->period_size);
 		}
 		pos = 0;
 	}
@@ -394,8 +392,8 @@
 			XRUN_DEBUG_PERIODUPDATE : XRUN_DEBUG_HWPTRUPDATE)) {
 		char name[16];
 		snd_pcm_debug_name(substream, name, sizeof(name));
-		snd_printd("%s_update: %s: pos=%u/%u/%u, "
-			   "hwptr=%ld/%ld/%ld/%ld\n",
+		pcm_dbg(substream->pcm,
+			"%s_update: %s: pos=%u/%u/%u, hwptr=%ld/%ld/%ld/%ld\n",
 			   in_interrupt ? "period" : "hwptr",
 			   name,
 			   (unsigned int)pos,
@@ -1941,8 +1939,9 @@
 			continue;
 		}
 		if (!tout) {
-			snd_printd("%s write error (DMA or IRQ trouble?)\n",
-				   is_playback ? "playback" : "capture");
+			pcm_dbg(substream->pcm,
+				"%s write error (DMA or IRQ trouble?)\n",
+				is_playback ? "playback" : "capture");
 			err = -EIO;
 			break;
 		}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 01a5e05..b653ab0 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -190,12 +190,12 @@
 		if (!(params->rmask & (1 << k)))
 			continue;
 #ifdef RULES_DEBUG
-		printk(KERN_DEBUG "%s = ", snd_pcm_hw_param_names[k]);
-		printk("%04x%04x%04x%04x -> ", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
+		pr_debug("%s = ", snd_pcm_hw_param_names[k]);
+		pr_cont("%04x%04x%04x%04x -> ", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
 #endif
 		changed = snd_mask_refine(m, constrs_mask(constrs, k));
 #ifdef RULES_DEBUG
-		printk("%04x%04x%04x%04x\n", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
+		pr_cont("%04x%04x%04x%04x\n", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
 #endif
 		if (changed)
 			params->cmask |= 1 << k;
@@ -210,21 +210,21 @@
 		if (!(params->rmask & (1 << k)))
 			continue;
 #ifdef RULES_DEBUG
-		printk(KERN_DEBUG "%s = ", snd_pcm_hw_param_names[k]);
+		pr_debug("%s = ", snd_pcm_hw_param_names[k]);
 		if (i->empty)
-			printk("empty");
+			pr_cont("empty");
 		else
-			printk("%c%u %u%c", 
+			pr_cont("%c%u %u%c",
 			       i->openmin ? '(' : '[', i->min,
 			       i->max, i->openmax ? ')' : ']');
-		printk(" -> ");
+		pr_cont(" -> ");
 #endif
 		changed = snd_interval_refine(i, constrs_interval(constrs, k));
 #ifdef RULES_DEBUG
 		if (i->empty)
-			printk("empty\n");
+			pr_cont("empty\n");
 		else 
-			printk("%c%u %u%c\n", 
+			pr_cont("%c%u %u%c\n",
 			       i->openmin ? '(' : '[', i->min,
 			       i->max, i->openmax ? ')' : ']');
 #endif
@@ -255,18 +255,18 @@
 			if (!doit)
 				continue;
 #ifdef RULES_DEBUG
-			printk(KERN_DEBUG "Rule %d [%p]: ", k, r->func);
+			pr_debug("Rule %d [%p]: ", k, r->func);
 			if (r->var >= 0) {
-				printk("%s = ", snd_pcm_hw_param_names[r->var]);
+				pr_cont("%s = ", snd_pcm_hw_param_names[r->var]);
 				if (hw_is_mask(r->var)) {
 					m = hw_param_mask(params, r->var);
-					printk("%x", *m->bits);
+					pr_cont("%x", *m->bits);
 				} else {
 					i = hw_param_interval(params, r->var);
 					if (i->empty)
-						printk("empty");
+						pr_cont("empty");
 					else
-						printk("%c%u %u%c", 
+						pr_cont("%c%u %u%c",
 						       i->openmin ? '(' : '[', i->min,
 						       i->max, i->openmax ? ')' : ']');
 				}
@@ -275,19 +275,19 @@
 			changed = r->func(params, r);
 #ifdef RULES_DEBUG
 			if (r->var >= 0) {
-				printk(" -> ");
+				pr_cont(" -> ");
 				if (hw_is_mask(r->var))
-					printk("%x", *m->bits);
+					pr_cont("%x", *m->bits);
 				else {
 					if (i->empty)
-						printk("empty");
+						pr_cont("empty");
 					else
-						printk("%c%u %u%c", 
+						pr_cont("%c%u %u%c",
 						       i->openmin ? '(' : '[', i->min,
 						       i->max, i->openmax ? ')' : ']');
 				}
 			}
-			printk("\n");
+			pr_cont("\n");
 #endif
 			rstamps[k] = stamp;
 			if (changed && r->var >= 0) {
@@ -399,7 +399,7 @@
 		return -EBADFD;
 	}
 	snd_pcm_stream_unlock_irq(substream);
-#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
+#if IS_ENABLED(CONFIG_SND_PCM_OSS)
 	if (!substream->oss.oss)
 #endif
 		if (atomic_read(&substream->mmap_count))
@@ -954,7 +954,7 @@
  *
  * The state of each stream is then changed to the given state unconditionally.
  *
- * Return: Zero if succesful, or a negative error code.
+ * Return: Zero if successful, or a negative error code.
  */
 int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t state)
 {
@@ -1541,7 +1541,8 @@
 			if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
 				result = -ESTRPIPE;
 			else {
-				snd_printd("playback drain error (DMA or IRQ trouble?)\n");
+				dev_dbg(substream->pcm->card->dev,
+					"playback drain error (DMA or IRQ trouble?)\n");
 				snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
 				result = -EIO;
 			}
@@ -2066,7 +2067,7 @@
 
 	err = snd_pcm_hw_constraints_init(substream);
 	if (err < 0) {
-		snd_printd("snd_pcm_hw_constraints_init failed\n");
+		pcm_dbg(pcm, "snd_pcm_hw_constraints_init failed\n");
 		goto error;
 	}
 
@@ -2077,7 +2078,7 @@
 
 	err = snd_pcm_hw_constraints_complete(substream);
 	if (err < 0) {
-		snd_printd("snd_pcm_hw_constraints_complete failed\n");
+		pcm_dbg(pcm, "snd_pcm_hw_constraints_complete failed\n");
 		goto error;
 	}
 
@@ -2609,7 +2610,7 @@
 		return res;
 	}
 	}
-	snd_printd("unknown ioctl = 0x%x\n", cmd);
+	pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd);
 	return -ENOTTY;
 }
 
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index b01d948..20ecd8f 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -53,7 +53,9 @@
 		post *= 2;
 	}
 	if (rate == 0) {
-		snd_printk(KERN_ERR "pcm timer resolution out of range (rate = %u, period_size = %lu)\n", runtime->rate, runtime->period_size);
+		pcm_err(substream->pcm,
+			"pcm timer resolution out of range (rate = %u, period_size = %lu)\n",
+			runtime->rate, runtime->period_size);
 		runtime->timer_resolution = -1;
 		return;
 	}
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 7b596b5..801c861 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -56,6 +56,13 @@
 static LIST_HEAD(snd_rawmidi_devices);
 static DEFINE_MUTEX(register_mutex);
 
+#define rmidi_err(rmidi, fmt, args...) \
+	dev_err((rmidi)->card->dev, fmt, ##args)
+#define rmidi_warn(rmidi, fmt, args...) \
+	dev_warn((rmidi)->card->dev, fmt, ##args)
+#define rmidi_dbg(rmidi, fmt, args...) \
+	dev_dbg((rmidi)->card->dev, fmt, ##args)
+
 static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device)
 {
 	struct snd_rawmidi *rawmidi;
@@ -180,7 +187,9 @@
 	if (signal_pending(current))
 		err = -ERESTARTSYS;
 	if (runtime->avail < runtime->buffer_size && !timeout) {
-		snd_printk(KERN_WARNING "rawmidi drain error (avail = %li, buffer_size = %li)\n", (long)runtime->avail, (long)runtime->buffer_size);
+		rmidi_warn(substream->rmidi,
+			   "rawmidi drain error (avail = %li, buffer_size = %li)\n",
+			   (long)runtime->avail, (long)runtime->buffer_size);
 		err = -EIO;
 	}
 	runtime->drain = 0;
@@ -802,10 +811,9 @@
 			return -EINVAL;
 		}
 	}
-#ifdef CONFIG_SND_DEBUG
 	default:
-		snd_printk(KERN_WARNING "rawmidi: unknown command = 0x%x\n", cmd);
-#endif
+		rmidi_dbg(rfile->rmidi,
+			  "rawmidi: unknown command = 0x%x\n", cmd);
 	}
 	return -ENOTTY;
 }
@@ -875,7 +883,8 @@
 	if (!substream->opened)
 		return -EBADFD;
 	if (runtime->buffer == NULL) {
-		snd_printd("snd_rawmidi_receive: input is not active!!!\n");
+		rmidi_dbg(substream->rmidi,
+			  "snd_rawmidi_receive: input is not active!!!\n");
 		return -EINVAL;
 	}
 	spin_lock_irqsave(&runtime->lock, flags);
@@ -1034,7 +1043,8 @@
 	unsigned long flags;
 
 	if (runtime->buffer == NULL) {
-		snd_printd("snd_rawmidi_transmit_empty: output is not active!!!\n");
+		rmidi_dbg(substream->rmidi,
+			  "snd_rawmidi_transmit_empty: output is not active!!!\n");
 		return 1;
 	}
 	spin_lock_irqsave(&runtime->lock, flags);
@@ -1065,7 +1075,8 @@
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	if (runtime->buffer == NULL) {
-		snd_printd("snd_rawmidi_transmit_peek: output is not active!!!\n");
+		rmidi_dbg(substream->rmidi,
+			  "snd_rawmidi_transmit_peek: output is not active!!!\n");
 		return -EINVAL;
 	}
 	result = 0;
@@ -1101,7 +1112,7 @@
 /**
  * snd_rawmidi_transmit_ack - acknowledge the transmission
  * @substream: the rawmidi substream
- * @count: the tranferred count
+ * @count: the transferred count
  *
  * Advances the hardware pointer for the internal output buffer with
  * the given size and updates the condition.
@@ -1115,7 +1126,8 @@
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	if (runtime->buffer == NULL) {
-		snd_printd("snd_rawmidi_transmit_ack: output is not active!!!\n");
+		rmidi_dbg(substream->rmidi,
+			  "snd_rawmidi_transmit_ack: output is not active!!!\n");
 		return -EINVAL;
 	}
 	spin_lock_irqsave(&runtime->lock, flags);
@@ -1413,7 +1425,7 @@
 	for (idx = 0; idx < count; idx++) {
 		substream = kzalloc(sizeof(*substream), GFP_KERNEL);
 		if (substream == NULL) {
-			snd_printk(KERN_ERR "rawmidi: cannot allocate substream\n");
+			rmidi_err(rmidi, "rawmidi: cannot allocate substream\n");
 			return -ENOMEM;
 		}
 		substream->stream = direction;
@@ -1458,7 +1470,7 @@
 		*rrawmidi = NULL;
 	rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
 	if (rmidi == NULL) {
-		snd_printk(KERN_ERR "rawmidi: cannot allocate\n");
+		dev_err(card->dev, "rawmidi: cannot allocate\n");
 		return -ENOMEM;
 	}
 	rmidi->card = card;
@@ -1557,7 +1569,8 @@
 	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
 				       rmidi->card, rmidi->device,
 				       &snd_rawmidi_f_ops, rmidi, name)) < 0) {
-		snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
+		rmidi_err(rmidi, "unable to register rawmidi device %i:%i\n",
+			  rmidi->card->number, rmidi->device);
 		list_del(&rmidi->list);
 		mutex_unlock(&register_mutex);
 		return err;
@@ -1574,8 +1587,10 @@
 	if ((int)rmidi->device == midi_map[rmidi->card->number]) {
 		if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
 					    rmidi->card, 0, &snd_rawmidi_f_ops,
-					    rmidi, name) < 0) {
-			snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0);
+					    rmidi) < 0) {
+			rmidi_err(rmidi,
+				  "unable to register OSS rawmidi device %i:%i\n",
+				  rmidi->card->number, 0);
 		} else {
 			rmidi->ossreg++;
 #ifdef SNDRV_OSS_INFO_DEV_MIDI
@@ -1586,8 +1601,10 @@
 	if ((int)rmidi->device == amidi_map[rmidi->card->number]) {
 		if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
 					    rmidi->card, 1, &snd_rawmidi_f_ops,
-					    rmidi, name) < 0) {
-			snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1);
+					    rmidi) < 0) {
+			rmidi_err(rmidi,
+				  "unable to register OSS rawmidi device %i:%i\n",
+				  rmidi->card->number, 1);
 		} else {
 			rmidi->ossreg++;
 		}
@@ -1685,11 +1702,13 @@
 	/* check device map table */
 	for (i = 0; i < SNDRV_CARDS; i++) {
 		if (midi_map[i] < 0 || midi_map[i] >= SNDRV_RAWMIDI_DEVICES) {
-			snd_printk(KERN_ERR "invalid midi_map[%d] = %d\n", i, midi_map[i]);
+			pr_err("ALSA: rawmidi: invalid midi_map[%d] = %d\n",
+			       i, midi_map[i]);
 			midi_map[i] = 0;
 		}
 		if (amidi_map[i] < 0 || amidi_map[i] >= SNDRV_RAWMIDI_DEVICES) {
-			snd_printk(KERN_ERR "invalid amidi_map[%d] = %d\n", i, amidi_map[i]);
+			pr_err("ALSA: rawmidi: invalid amidi_map[%d] = %d\n",
+			       i, amidi_map[i]);
 			amidi_map[i] = 1;
 		}
 	}
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index e85e72b..f3420d1 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -27,7 +27,7 @@
 #include <sound/core.h>
 #include <sound/timer.h>
 
-#if defined(CONFIG_RTC) || defined(CONFIG_RTC_MODULE)
+#if IS_ENABLED(CONFIG_RTC)
 
 #include <linux/mc146818rtc.h>
 
@@ -132,8 +132,7 @@
 
 	if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
 	    !is_power_of_2(rtctimer_freq)) {
-		snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
-			   rtctimer_freq);
+		pr_err("ALSA: rtctimer: invalid frequency %d\n", rtctimer_freq);
 		return -EINVAL;
 	}
 
@@ -185,4 +184,4 @@
 
 MODULE_ALIAS("snd-timer-" __stringify(SNDRV_TIMER_GLOBAL_RTC));
 
-#endif /* CONFIG_RTC || CONFIG_RTC_MODULE */
+#endif /* IS_ENABLED(CONFIG_RTC) */
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 8d4d5e8..16d4267 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -39,12 +39,6 @@
 MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_SEQUENCER);
 MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_MUSIC);
 
-#ifdef SNDRV_SEQ_OSS_DEBUG
-module_param(seq_oss_debug, int, 0644);
-MODULE_PARM_DESC(seq_oss_debug, "debug option");
-int seq_oss_debug = 0;
-#endif
-
 
 /*
  * prototypes
@@ -231,22 +225,19 @@
 	mutex_lock(&register_mutex);
 	if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
 					  NULL, 0,
-					  &seq_oss_f_ops, NULL,
-					  SNDRV_SEQ_OSS_DEVNAME)) < 0) {
-		snd_printk(KERN_ERR "can't register device seq\n");
+					  &seq_oss_f_ops, NULL)) < 0) {
+		pr_err("ALSA: seq_oss: can't register device seq\n");
 		mutex_unlock(&register_mutex);
 		return rc;
 	}
 	if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
 					  NULL, 0,
-					  &seq_oss_f_ops, NULL,
-					  SNDRV_SEQ_OSS_DEVNAME)) < 0) {
-		snd_printk(KERN_ERR "can't register device music\n");
+					  &seq_oss_f_ops, NULL)) < 0) {
+		pr_err("ALSA: seq_oss: can't register device music\n");
 		snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0);
 		mutex_unlock(&register_mutex);
 		return rc;
 	}
-	debug_printk(("device registered\n"));
 	mutex_unlock(&register_mutex);
 	return 0;
 }
@@ -255,11 +246,10 @@
 unregister_device(void)
 {
 	mutex_lock(&register_mutex);
-	debug_printk(("device unregistered\n"));
 	if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0)		
-		snd_printk(KERN_ERR "error unregister device music\n");
+		pr_err("ALSA: seq_oss: error unregister device music\n");
 	if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0)
-		snd_printk(KERN_ERR "error unregister device seq\n");
+		pr_err("ALSA: seq_oss: error unregister device seq\n");
 	mutex_unlock(&register_mutex);
 }
 
diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h
index c0154a9..b439243 100644
--- a/sound/core/seq/oss/seq_oss_device.h
+++ b/sound/core/seq/oss/seq_oss_device.h
@@ -31,9 +31,6 @@
 #include <sound/seq_kernel.h>
 #include <sound/info.h>
 
-/* enable debug print */
-#define SNDRV_SEQ_OSS_DEBUG
-
 /* max. applications */
 #define SNDRV_SEQ_OSS_MAX_CLIENTS	16
 #define SNDRV_SEQ_OSS_MAX_SYNTH_DEVS	16
@@ -46,7 +43,6 @@
 #define SNDRV_SEQ_OSS_VERSION_STR	"0.1.8"
 
 /* device and proc interface name */
-#define SNDRV_SEQ_OSS_DEVNAME		"seq_oss"
 #define SNDRV_SEQ_OSS_PROCNAME		"oss"
 
 
@@ -177,13 +173,4 @@
 /* misc. functions for proc interface */
 char *enabled_str(int bool);
 
-
-/* for debug */
-#ifdef SNDRV_SEQ_OSS_DEBUG
-extern int seq_oss_debug;
-#define debug_printk(x)	do { if (seq_oss_debug > 0) snd_printd x; } while (0)
-#else
-#define debug_printk(x)	/**/
-#endif
-
 #endif /* __SEQ_OSS_DEVICE_H */
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index b3f39b5..b9184d2 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -92,7 +92,6 @@
 		goto __error;
 
 	system_client = rc;
-	debug_printk(("new client = %d\n", rc));
 
 	/* create annoucement receiver port */
 	memset(port, 0, sizeof(*port));
@@ -190,10 +189,9 @@
 
 	dp = kzalloc(sizeof(*dp), GFP_KERNEL);
 	if (!dp) {
-		snd_printk(KERN_ERR "can't malloc device info\n");
+		pr_err("ALSA: seq_oss: can't malloc device info\n");
 		return -ENOMEM;
 	}
-	debug_printk(("oss_open: dp = %p\n", dp));
 
 	dp->cseq = system_client;
 	dp->port = -1;
@@ -206,7 +204,7 @@
 
 	dp->index = i;
 	if (i >= SNDRV_SEQ_OSS_MAX_CLIENTS) {
-		snd_printk(KERN_ERR "too many applications\n");
+		pr_err("ALSA: seq_oss: too many applications\n");
 		rc = -ENOMEM;
 		goto _error;
 	}
@@ -216,21 +214,19 @@
 	snd_seq_oss_midi_setup(dp);
 
 	if (dp->synth_opened == 0 && dp->max_mididev == 0) {
-		/* snd_printk(KERN_ERR "no device found\n"); */
+		/* pr_err("ALSA: seq_oss: no device found\n"); */
 		rc = -ENODEV;
 		goto _error;
 	}
 
 	/* create port */
-	debug_printk(("create new port\n"));
 	rc = create_port(dp);
 	if (rc < 0) {
-		snd_printk(KERN_ERR "can't create port\n");
+		pr_err("ALSA: seq_oss: can't create port\n");
 		goto _error;
 	}
 
 	/* allocate queue */
-	debug_printk(("allocate queue\n"));
 	rc = alloc_seq_queue(dp);
 	if (rc < 0)
 		goto _error;
@@ -247,7 +243,6 @@
 	dp->file_mode = translate_mode(file);
 
 	/* initialize read queue */
-	debug_printk(("initialize read queue\n"));
 	if (is_read_mode(dp->file_mode)) {
 		dp->readq = snd_seq_oss_readq_new(dp, maxqlen);
 		if (!dp->readq) {
@@ -257,7 +252,6 @@
 	}
 
 	/* initialize write queue */
-	debug_printk(("initialize write queue\n"));
 	if (is_write_mode(dp->file_mode)) {
 		dp->writeq = snd_seq_oss_writeq_new(dp, maxqlen);
 		if (!dp->writeq) {
@@ -267,14 +261,12 @@
 	}
 
 	/* initialize timer */
-	debug_printk(("initialize timer\n"));
 	dp->timer = snd_seq_oss_timer_new(dp);
 	if (!dp->timer) {
-		snd_printk(KERN_ERR "can't alloc timer\n");
+		pr_err("ALSA: seq_oss: can't alloc timer\n");
 		rc = -ENOMEM;
 		goto _error;
 	}
-	debug_printk(("timer initialized\n"));
 
 	/* set private data pointer */
 	file->private_data = dp;
@@ -288,7 +280,6 @@
 	client_table[dp->index] = dp;
 	num_clients++;
 
-	debug_printk(("open done\n"));
 	return 0;
 
  _error:
@@ -347,7 +338,6 @@
 		return rc;
 
 	dp->port = port.addr.port;
-	debug_printk(("new port = %d\n", port.addr.port));
 
 	return 0;
 }
@@ -363,7 +353,6 @@
 		return 0;
 	}
 
-	debug_printk(("delete_port %i\n", dp->port));
 	return snd_seq_event_port_detach(dp->cseq, dp->port);
 }
 
@@ -401,7 +390,7 @@
 	qinfo.queue = queue;
 	rc = call_ctl(SNDRV_SEQ_IOCTL_DELETE_QUEUE, &qinfo);
 	if (rc < 0)
-		printk(KERN_ERR "seq-oss: unable to delete queue %d (%d)\n", queue, rc);
+		pr_err("ALSA: seq_oss: unable to delete queue %d (%d)\n", queue, rc);
 	return rc;
 }
 
@@ -438,21 +427,16 @@
 	client_table[dp->index] = NULL;
 	num_clients--;
 
-	debug_printk(("resetting..\n"));
 	snd_seq_oss_reset(dp);
 
-	debug_printk(("cleaning up..\n"));
 	snd_seq_oss_synth_cleanup(dp);
 	snd_seq_oss_midi_cleanup(dp);
 
 	/* clear slot */
-	debug_printk(("releasing resource..\n"));
 	queue = dp->queue;
 	if (dp->port >= 0)
 		delete_port(dp);
 	delete_seq_queue(queue);
-
-	debug_printk(("release done\n"));
 }
 
 
@@ -466,7 +450,6 @@
 		return;
 	if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) &&
 	    dp->writeq) {
-		debug_printk(("syncing..\n"));
 		while (snd_seq_oss_writeq_sync(dp->writeq))
 			;
 	}
diff --git a/sound/core/seq/oss/seq_oss_ioctl.c b/sound/core/seq/oss/seq_oss_ioctl.c
index 5ac701c..5b85201 100644
--- a/sound/core/seq/oss/seq_oss_ioctl.c
+++ b/sound/core/seq/oss/seq_oss_ioctl.c
@@ -90,12 +90,10 @@
 		return snd_seq_oss_timer_ioctl(dp->timer, cmd, arg);
 
 	case SNDCTL_SEQ_PANIC:
-		debug_printk(("panic\n"));
 		snd_seq_oss_reset(dp);
 		return -EINVAL;
 
 	case SNDCTL_SEQ_SYNC:
-		debug_printk(("sync\n"));
 		if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
 			return 0;
 		while (snd_seq_oss_writeq_sync(dp->writeq))
@@ -105,55 +103,45 @@
 		return 0;
 
 	case SNDCTL_SEQ_RESET:
-		debug_printk(("reset\n"));
 		snd_seq_oss_reset(dp);
 		return 0;
 
 	case SNDCTL_SEQ_TESTMIDI:
-		debug_printk(("test midi\n"));
 		if (get_user(dev, p))
 			return -EFAULT;
 		return snd_seq_oss_midi_open(dp, dev, dp->file_mode);
 
 	case SNDCTL_SEQ_GETINCOUNT:
-		debug_printk(("get in count\n"));
 		if (dp->readq == NULL || ! is_read_mode(dp->file_mode))
 			return 0;
 		return put_user(dp->readq->qlen, p) ? -EFAULT : 0;
 
 	case SNDCTL_SEQ_GETOUTCOUNT:
-		debug_printk(("get out count\n"));
 		if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
 			return 0;
 		return put_user(snd_seq_oss_writeq_get_free_size(dp->writeq), p) ? -EFAULT : 0;
 
 	case SNDCTL_SEQ_GETTIME:
-		debug_printk(("get time\n"));
 		return put_user(snd_seq_oss_timer_cur_tick(dp->timer), p) ? -EFAULT : 0;
 
 	case SNDCTL_SEQ_RESETSAMPLES:
-		debug_printk(("reset samples\n"));
 		if (get_user(dev, p))
 			return -EFAULT;
 		return snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
 
 	case SNDCTL_SEQ_NRSYNTHS:
-		debug_printk(("nr synths\n"));
 		return put_user(dp->max_synthdev, p) ? -EFAULT : 0;
 
 	case SNDCTL_SEQ_NRMIDIS:
-		debug_printk(("nr midis\n"));
 		return put_user(dp->max_mididev, p) ? -EFAULT : 0;
 
 	case SNDCTL_SYNTH_MEMAVL:
-		debug_printk(("mem avail\n"));
 		if (get_user(dev, p))
 			return -EFAULT;
 		val = snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
 		return put_user(val, p) ? -EFAULT : 0;
 
 	case SNDCTL_FM_4OP_ENABLE:
-		debug_printk(("4op\n"));
 		if (get_user(dev, p))
 			return -EFAULT;
 		snd_seq_oss_synth_ioctl(dp, dev, cmd, carg);
@@ -161,19 +149,15 @@
 
 	case SNDCTL_SYNTH_INFO:
 	case SNDCTL_SYNTH_ID:
-		debug_printk(("synth info\n"));
 		return snd_seq_oss_synth_info_user(dp, arg);
 
 	case SNDCTL_SEQ_OUTOFBAND:
-		debug_printk(("out of band\n"));
 		return snd_seq_oss_oob_user(dp, arg);
 
 	case SNDCTL_MIDI_INFO:
-		debug_printk(("midi info\n"));
 		return snd_seq_oss_midi_info_user(dp, arg);
 
 	case SNDCTL_SEQ_THRESHOLD:
-		debug_printk(("threshold\n"));
 		if (! is_write_mode(dp->file_mode))
 			return 0;
 		if (get_user(val, p))
@@ -186,7 +170,6 @@
 		return 0;
 
 	case SNDCTL_MIDI_PRETIME:
-		debug_printk(("pretime\n"));
 		if (dp->readq == NULL || !is_read_mode(dp->file_mode))
 			return 0;
 		if (get_user(val, p))
@@ -199,7 +182,6 @@
 		return put_user(val, p) ? -EFAULT : 0;
 
 	default:
-		debug_printk(("others\n"));
 		if (! is_write_mode(dp->file_mode))
 			return -EIO;
 		return snd_seq_oss_synth_ioctl(dp, 0, cmd, carg);
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 862d8489..3a45696 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -153,7 +153,6 @@
 	struct seq_oss_midi *mdev;
 	unsigned long flags;
 
-	debug_printk(("check for MIDI client %d port %d\n", pinfo->addr.client, pinfo->addr.port));
 	/* the port must include generic midi */
 	if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC))
 		return 0;
@@ -175,7 +174,7 @@
 	 * allocate midi info record
 	 */
 	if ((mdev = kzalloc(sizeof(*mdev), GFP_KERNEL)) == NULL) {
-		snd_printk(KERN_ERR "can't malloc midi info\n");
+		pr_err("ALSA: seq_oss: can't malloc midi info\n");
 		return -ENOMEM;
 	}
 
@@ -191,7 +190,7 @@
 
 	/* create MIDI coder */
 	if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) {
-		snd_printk(KERN_ERR "can't malloc midi coder\n");
+		pr_err("ALSA: seq_oss: can't malloc midi coder\n");
 		kfree(mdev);
 		return -ENOMEM;
 	}
@@ -406,7 +405,6 @@
 		return 0;
 	}
 
-	debug_printk(("closing client %d port %d mode %d\n", mdev->client, mdev->port, mdev->opened));
 	memset(&subs, 0, sizeof(subs));
 	if (mdev->opened & PERM_WRITE) {
 		subs.sender = dp->addr;
@@ -470,7 +468,6 @@
 		struct snd_seq_event ev;
 		int c;
 
-		debug_printk(("resetting client %d port %d\n", mdev->client, mdev->port));
 		memset(&ev, 0, sizeof(ev));
 		ev.dest.client = mdev->client;
 		ev.dest.port = mdev->port;
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index 73661c4..654d17a 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -48,12 +48,12 @@
 	struct seq_oss_readq *q;
 
 	if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL) {
-		snd_printk(KERN_ERR "can't malloc read queue\n");
+		pr_err("ALSA: seq_oss: can't malloc read queue\n");
 		return NULL;
 	}
 
 	if ((q->q = kcalloc(maxlen, sizeof(union evrec), GFP_KERNEL)) == NULL) {
-		snd_printk(KERN_ERR "can't malloc read queue buffer\n");
+		pr_err("ALSA: seq_oss: can't malloc read queue buffer\n");
 		kfree(q);
 		return NULL;
 	}
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index c5b773a..701feb7 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -106,7 +106,7 @@
 	unsigned long flags;
 
 	if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) {
-		snd_printk(KERN_ERR "can't malloc synth info\n");
+		pr_err("ALSA: seq_oss: can't malloc synth info\n");
 		return -ENOMEM;
 	}
 	rec->seq_device = -1;
@@ -130,7 +130,7 @@
 	if (i >= max_synth_devs) {
 		if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) {
 			spin_unlock_irqrestore(&register_lock, flags);
-			snd_printk(KERN_ERR "no more synth slot\n");
+			pr_err("ALSA: seq_oss: no more synth slot\n");
 			kfree(rec);
 			return -ENOMEM;
 		}
@@ -138,7 +138,6 @@
 	}
 	rec->seq_device = i;
 	synth_devs[i] = rec;
-	debug_printk(("synth %s registered %d\n", rec->name, i));
 	spin_unlock_irqrestore(&register_lock, flags);
 	dev->driver_data = rec;
 #ifdef SNDRV_OSS_INFO_DEV_SYNTH
@@ -163,7 +162,7 @@
 	}
 	if (index >= max_synth_devs) {
 		spin_unlock_irqrestore(&register_lock, flags);
-		snd_printk(KERN_ERR "can't unregister synth\n");
+		pr_err("ALSA: seq_oss: can't unregister synth\n");
 		return -EINVAL;
 	}
 	synth_devs[index] = NULL;
@@ -248,7 +247,7 @@
 		if (info->nr_voices > 0) {
 			info->ch = kcalloc(info->nr_voices, sizeof(struct seq_oss_chinfo), GFP_KERNEL);
 			if (!info->ch) {
-				snd_printk(KERN_ERR "Cannot malloc\n");
+				pr_err("ALSA: seq_oss: Cannot malloc voices\n");
 				rec->oper.close(&info->arg);
 				module_put(rec->oper.owner);
 				snd_use_lock_free(&rec->use_lock);
@@ -256,7 +255,6 @@
 			}
 			reset_channels(info);
 		}
-		debug_printk(("synth %d assigned\n", i));
 		info->opened++;
 		rec->opened++;
 		dp->synth_opened++;
@@ -326,7 +324,6 @@
 			if (rec == NULL)
 				continue;
 			if (rec->opened > 0) {
-				debug_printk(("synth %d closed\n", i));
 				rec->oper.close(&info->arg);
 				module_put(rec->oper.owner);
 				rec->opened = 0;
diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
index ab59cbf..4f24ea9 100644
--- a/sound/core/seq/oss/seq_oss_timer.c
+++ b/sound/core/seq/oss/seq_oss_timer.c
@@ -233,7 +233,6 @@
 	int value;
 
 	if (cmd == SNDCTL_SEQ_CTRLRATE) {
-		debug_printk(("ctrl rate\n"));
 		/* if *arg == 0, just return the current rate */
 		if (get_user(value, arg))
 			return -EFAULT;
@@ -248,21 +247,16 @@
 
 	switch (cmd) {
 	case SNDCTL_TMR_START:
-		debug_printk(("timer start\n"));
 		return snd_seq_oss_timer_start(timer);
 	case SNDCTL_TMR_STOP:
-		debug_printk(("timer stop\n"));
 		return snd_seq_oss_timer_stop(timer);
 	case SNDCTL_TMR_CONTINUE:
-		debug_printk(("timer continue\n"));
 		return snd_seq_oss_timer_continue(timer);
 	case SNDCTL_TMR_TEMPO:
-		debug_printk(("timer tempo\n"));
 		if (get_user(value, arg))
 			return -EFAULT;
 		return snd_seq_oss_timer_tempo(timer, value);
 	case SNDCTL_TMR_TIMEBASE:
-		debug_printk(("timer timebase\n"));
 		if (get_user(value, arg))
 			return -EFAULT;
 		if (value < MIN_OSS_TIMEBASE)
@@ -276,7 +270,6 @@
 	case SNDCTL_TMR_METRONOME:
 	case SNDCTL_TMR_SELECT:
 	case SNDCTL_TMR_SOURCE:
-		debug_printk(("timer XXX\n"));
 		/* not supported */
 		return 0;
 	}
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 4dc6bae..9ca5e64 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -123,7 +123,7 @@
 static struct snd_seq_client *clientptr(int clientid)
 {
 	if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
-		snd_printd("Seq: oops. Trying to get pointer to client %d\n",
+		pr_debug("ALSA: seq: oops. Trying to get pointer to client %d\n",
 			   clientid);
 		return NULL;
 	}
@@ -136,7 +136,7 @@
 	struct snd_seq_client *client;
 
 	if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
-		snd_printd("Seq: oops. Trying to get pointer to client %d\n",
+		pr_debug("ALSA: seq: oops. Trying to get pointer to client %d\n",
 			   clientid);
 		return NULL;
 	}
@@ -291,8 +291,8 @@
 	mutex_lock(&register_mutex);
 	switch (client->type) {
 	case NO_CLIENT:
-		snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n",
-			   client->number);
+		pr_warn("ALSA: seq: Trying to free unused client %d\n",
+			client->number);
 		break;
 	case USER_CLIENT:
 	case KERNEL_CLIENT:
@@ -301,7 +301,7 @@
 		break;
 
 	default:
-		snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n",
+		pr_err("ALSA: seq: Trying to free client %d with undefined type = %d\n",
 			   client->number, client->type);
 	}
 	mutex_unlock(&register_mutex);
@@ -773,7 +773,7 @@
 static int multicast_event(struct snd_seq_client *client, struct snd_seq_event *event,
 			   int atomic, int hop)
 {
-	snd_printd("seq: multicast not supported yet.\n");
+	pr_debug("ALSA: seq: multicast not supported yet.\n");
 	return 0; /* ignored */
 }
 #endif /* SUPPORT_BROADCAST */
@@ -794,7 +794,7 @@
 
 	hop++;
 	if (hop >= SNDRV_SEQ_MAX_HOPS) {
-		snd_printd("too long delivery path (%d:%d->%d:%d)\n",
+		pr_debug("ALSA: seq: too long delivery path (%d:%d->%d:%d)\n",
 			   event->source.client, event->source.port,
 			   event->dest.client, event->dest.port);
 		return -EMLINK;
@@ -2196,7 +2196,7 @@
 		if (p->cmd == cmd)
 			return p->func(client, arg);
 	}
-	snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
+	pr_debug("ALSA: seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
 		   cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
 	return -ENOTTY;
 }
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 040c60e..91a786a 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -168,7 +168,7 @@
 
 /*
  * register a sequencer device
- * card = card info (NULL allowed)
+ * card = card info
  * device = device number (if any)
  * id = id of driver
  * result = return pointer (NULL allowed if unnecessary)
@@ -325,7 +325,7 @@
 		return -ENOMEM;
 	}
 	if (ops->driver & DRIVER_LOADED) {
-		snd_printk(KERN_WARNING "driver_register: driver '%s' already exists\n", id);
+		pr_warn("ALSA: seq: driver_register: driver '%s' already exists\n", id);
 		unlock_driver(ops);
 		snd_seq_autoload_unlock();
 		return -EBUSY;
@@ -398,7 +398,7 @@
 		return -ENXIO;
 	if (! (ops->driver & DRIVER_LOADED) ||
 	    (ops->driver & DRIVER_LOCKED)) {
-		snd_printk(KERN_ERR "driver_unregister: cannot unload driver '%s': status=%x\n",
+		pr_err("ALSA: seq: driver_unregister: cannot unload driver '%s': status=%x\n",
 			   id, ops->driver);
 		unlock_driver(ops);
 		return -EBUSY;
@@ -413,7 +413,7 @@
 
 	ops->driver = 0;
 	if (ops->num_init_devices > 0)
-		snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n",
+		pr_err("ALSA: seq: free_driver: init_devices > 0!! (%d)\n",
 			   ops->num_init_devices);
 	mutex_unlock(&ops->reg_mutex);
 
@@ -459,7 +459,7 @@
 	if (dev->status != SNDRV_SEQ_DEVICE_FREE)
 		return 0; /* already initialized */
 	if (ops->argsize != dev->argsize) {
-		snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
+		pr_err("ALSA: seq: incompatible device '%s' for plug-in '%s' (%d %d)\n",
 			   dev->name, ops->id, ops->argsize, dev->argsize);
 		return -EINVAL;
 	}
@@ -467,7 +467,7 @@
 		dev->status = SNDRV_SEQ_DEVICE_REGISTERED;
 		ops->num_init_devices++;
 	} else {
-		snd_printk(KERN_ERR "init_device failed: %s: %s\n",
+		pr_err("ALSA: seq: init_device failed: %s: %s\n",
 			   dev->name, dev->id);
 	}
 
@@ -486,7 +486,7 @@
 	if (dev->status != SNDRV_SEQ_DEVICE_REGISTERED)
 		return 0; /* not registered */
 	if (ops->argsize != dev->argsize) {
-		snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
+		pr_err("ALSA: seq: incompatible device '%s' for plug-in '%s' (%d %d)\n",
 			   dev->name, ops->id, ops->argsize, dev->argsize);
 		return -EINVAL;
 	}
@@ -495,7 +495,7 @@
 		dev->driver_data = NULL;
 		ops->num_init_devices--;
 	} else {
-		snd_printk(KERN_ERR "free_device failed: %s: %s\n",
+		pr_err("ALSA: seq: free_device failed: %s: %s\n",
 			   dev->name, dev->id);
 	}
 
@@ -559,7 +559,7 @@
 	snd_info_free_entry(info_entry);
 #endif
 	if (num_ops)
-		snd_printk(KERN_ERR "drivers not released (%d)\n", num_ops);
+		pr_err("ALSA: seq: drivers not released (%d)\n", num_ops);
 }
 
 module_init(alsa_seq_device_init)
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index dbc5507..ec667f1 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -198,7 +198,7 @@
 	int i;
 
 	if (ports < 1) {
-		snd_printk(KERN_ERR "invalid number of ports %d\n", ports);
+		pr_err("ALSA: seq_dummy: invalid number of ports %d\n", ports);
 		return -EINVAL;
 	}
 
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
index 0d75afa..5599899 100644
--- a/sound/core/seq/seq_fifo.c
+++ b/sound/core/seq/seq_fifo.c
@@ -34,7 +34,7 @@
 
 	f = kzalloc(sizeof(*f), GFP_KERNEL);
 	if (f == NULL) {
-		snd_printd("malloc failed for snd_seq_fifo_new() \n");
+		pr_debug("ALSA: seq: malloc failed for snd_seq_fifo_new() \n");
 		return NULL;
 	}
 
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index 2cfe50c..3b693e9 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -31,12 +31,12 @@
 	int max_count = 5 * HZ;
 
 	if (atomic_read(lockp) < 0) {
-		printk(KERN_WARNING "seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line);
+		pr_warn("ALSA: seq_lock: lock trouble [counter = %d] in %s:%d\n", atomic_read(lockp), file, line);
 		return;
 	}
 	while (atomic_read(lockp) > 0) {
 		if (max_count == 0) {
-			snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
+			pr_warn("ALSA: seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
 			break;
 		}
 		schedule_timeout_uninterruptible(1);
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index f478f77..1e206de 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -236,7 +236,7 @@
 	init_waitqueue_entry(&wait, current);
 	spin_lock_irqsave(&pool->lock, flags);
 	if (pool->ptr == NULL) {	/* not initialized */
-		snd_printd("seq: pool is not initialized\n");
+		pr_debug("ALSA: seq: pool is not initialized\n");
 		err = -EINVAL;
 		goto __error;
 	}
@@ -388,7 +388,7 @@
 
 	pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
 	if (pool->ptr == NULL) {
-		snd_printd("seq: malloc for sequencer events failed\n");
+		pr_debug("ALSA: seq: malloc for sequencer events failed\n");
 		return -ENOMEM;
 	}
 
@@ -431,7 +431,7 @@
 
 	while (atomic_read(&pool->counter) > 0) {
 		if (max_count == 0) {
-			snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter));
+			pr_warn("ALSA: snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter));
 			break;
 		}
 		schedule_timeout_uninterruptible(1);
@@ -464,7 +464,7 @@
 	/* create pool block */
 	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
 	if (pool == NULL) {
-		snd_printd("seq: malloc failed for pool\n");
+		pr_debug("ALSA: seq: malloc failed for pool\n");
 		return NULL;
 	}
 	spin_lock_init(&pool->lock);
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 64069db..3e05c55 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -121,7 +121,7 @@
 	runtime = substream->runtime;
 	if ((tmp = runtime->avail) < count) {
 		if (printk_ratelimit())
-			snd_printk(KERN_ERR "MIDI output buffer overrun\n");
+			pr_err("ALSA: seq_midi: MIDI output buffer overrun\n");
 		return -ENOMEM;
 	}
 	if (snd_rawmidi_kernel_write(substream, buf, count) < count)
@@ -145,7 +145,7 @@
 	if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {	/* special case, to save space */
 		if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) {
 			/* invalid event */
-			snd_printd("seq_midi: invalid sysex event flags = 0x%x\n", ev->flags);
+			pr_debug("ALSA: seq_midi: invalid sysex event flags = 0x%x\n", ev->flags);
 			return 0;
 		}
 		snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream);
@@ -189,7 +189,7 @@
 					   msynth->subdevice,
 					   SNDRV_RAWMIDI_LFLG_INPUT,
 					   &msynth->input_rfile)) < 0) {
-		snd_printd("midi input open failed!!!\n");
+		pr_debug("ALSA: seq_midi: midi input open failed!!!\n");
 		return err;
 	}
 	runtime = msynth->input_rfile.input->runtime;
@@ -231,7 +231,7 @@
 					   msynth->subdevice,
 					   SNDRV_RAWMIDI_LFLG_OUTPUT,
 					   &msynth->output_rfile)) < 0) {
-		snd_printd("midi output open failed!!!\n");
+		pr_debug("ALSA: seq_midi: midi output open failed!!!\n");
 		return err;
 	}
 	memset(&params, 0, sizeof(params));
diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
index 6f64471..9b6470c 100644
--- a/sound/core/seq/seq_midi_emul.c
+++ b/sound/core/seq/seq_midi_emul.c
@@ -89,7 +89,7 @@
 	int dest_channel = 0;
 
 	if (ev == NULL || chanset == NULL) {
-		snd_printd("ev or chanbase NULL (snd_midi_process_event)\n");
+		pr_debug("ALSA: seq_midi_emul: ev or chanbase NULL (snd_midi_process_event)\n");
 		return;
 	}
 	if (chanset->channels == NULL)
@@ -98,7 +98,7 @@
 	if (snd_seq_ev_is_channel_type(ev)) {
 		dest_channel = ev->data.note.channel;
 		if (dest_channel >= chanset->max_channels) {
-			snd_printd("dest channel is %d, max is %d\n",
+			pr_debug("ALSA: seq_midi_emul: dest channel is %d, max is %d\n",
 				   dest_channel, chanset->max_channels);
 			return;
 		}
@@ -232,7 +232,7 @@
 	case SNDRV_SEQ_EVENT_ECHO:
 	not_yet:
 	default:
-		/*snd_printd("Unimplemented event %d\n", ev->type);*/
+		/*pr_debug("ALSA: seq_midi_emul: Unimplemented event %d\n", ev->type);*/
 		break;
 	}
 }
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 9516e5c..794a341 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -135,14 +135,14 @@
 		return NULL;
 
 	if (client->num_ports >= SNDRV_SEQ_MAX_PORTS - 1) {
-		snd_printk(KERN_WARNING "too many ports for client %d\n", client->number);
+		pr_warn("ALSA: seq: too many ports for client %d\n", client->number);
 		return NULL;
 	}
 
 	/* create a new port */
 	new_port = kzalloc(sizeof(*new_port), GFP_KERNEL);
 	if (! new_port) {
-		snd_printd("malloc failed for registering client port\n");
+		pr_debug("ALSA: seq: malloc failed for registering client port\n");
 		return NULL;	/* failure, out of memory */
 	}
 	/* init port data */
diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c
index 29896ab..021b02b 100644
--- a/sound/core/seq/seq_prioq.c
+++ b/sound/core/seq/seq_prioq.c
@@ -60,7 +60,7 @@
 
 	f = kzalloc(sizeof(*f), GFP_KERNEL);
 	if (f == NULL) {
-		snd_printd("oops: malloc failed for snd_seq_prioq_new()\n");
+		pr_debug("ALSA: seq: malloc failed for snd_seq_prioq_new()\n");
 		return NULL;
 	}
 	
@@ -79,7 +79,7 @@
 	*fifo = NULL;
 
 	if (f == NULL) {
-		snd_printd("oops: snd_seq_prioq_delete() called with NULL prioq\n");
+		pr_debug("ALSA: seq: snd_seq_prioq_delete() called with NULL prioq\n");
 		return;
 	}
 
@@ -197,7 +197,7 @@
 		cur = cur->next;
 		if (! --count) {
 			spin_unlock_irqrestore(&f->lock, flags);
-			snd_printk(KERN_ERR "cannot find a pointer.. infinite loop?\n");
+			pr_err("ALSA: seq: cannot find a pointer.. infinite loop?\n");
 			return -EINVAL;
 		}
 	}
@@ -223,7 +223,7 @@
 	unsigned long flags;
 
 	if (f == NULL) {
-		snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
+		pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n");
 		return NULL;
 	}
 	spin_lock_irqsave(&f->lock, flags);
@@ -248,7 +248,7 @@
 int snd_seq_prioq_avail(struct snd_seq_prioq * f)
 {
 	if (f == NULL) {
-		snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
+		pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n");
 		return 0;
 	}
 	return f->cells;
@@ -259,7 +259,7 @@
 struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f)
 {
 	if (f == NULL) {
-		snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
+		pr_debug("ALSA: seq: snd_seq_prioq_cell_in() called with NULL prioq\n");
 		return NULL;
 	}
 	return f->head;
@@ -321,7 +321,7 @@
 			freeprev = cell;
 		} else {
 #if 0
-			printk(KERN_DEBUG "type = %i, source = %i, dest = %i, "
+			pr_debug("ALSA: seq: type = %i, source = %i, dest = %i, "
 			       "client = %i\n",
 				cell->event.type,
 				cell->event.source.client,
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index f907736..aad4878 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -112,7 +112,7 @@
 
 	q = kzalloc(sizeof(*q), GFP_KERNEL);
 	if (q == NULL) {
-		snd_printd("malloc failed for snd_seq_queue_new()\n");
+		pr_debug("ALSA: seq: malloc failed for snd_seq_queue_new()\n");
 		return NULL;
 	}
 
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index 24d44b2..e736053 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -57,7 +57,7 @@
 	
 	tmr = kzalloc(sizeof(*tmr), GFP_KERNEL);
 	if (tmr == NULL) {
-		snd_printd("malloc failed for snd_seq_timer_new() \n");
+		pr_debug("ALSA: seq: malloc failed for snd_seq_timer_new() \n");
 		return NULL;
 	}
 	spin_lock_init(&tmr->lock);
@@ -78,7 +78,7 @@
 	*tmr = NULL;
 
 	if (t == NULL) {
-		snd_printd("oops: snd_seq_timer_delete() called with NULL timer\n");
+		pr_debug("ALSA: seq: snd_seq_timer_delete() called with NULL timer\n");
 		return;
 	}
 	t->running = 0;
@@ -199,7 +199,7 @@
 		/* refuse to change ppq on running timers */
 		/* because it will upset the song position (ticks) */
 		spin_unlock_irqrestore(&tmr->lock, flags);
-		snd_printd("seq: cannot change ppq of a running timer\n");
+		pr_debug("ALSA: seq: cannot change ppq of a running timer\n");
 		return -EBUSY;
 	}
 
@@ -252,7 +252,7 @@
 
 	/* FIXME */
 	if (base != SKEW_BASE) {
-		snd_printd("invalid skew base 0x%x\n", base);
+		pr_debug("ALSA: seq: invalid skew base 0x%x\n", base);
 		return -EINVAL;
 	}
 	spin_lock_irqsave(&tmr->lock, flags);
@@ -292,7 +292,7 @@
 		}
 	}
 	if (err < 0) {
-		snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
+		pr_err("ALSA: seq fatal error: cannot create timer (%i)\n", err);
 		return err;
 	}
 	t->callback = snd_seq_timer_interrupt;
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 4b50e60..56e0f4cd 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -446,7 +446,7 @@
 		/* should check presence of port more strictly.. */
 		break;
 	default:
-		snd_printk(KERN_ERR "seq_mode is not set: %d\n", rdev->seq_mode);
+		pr_err("ALSA: seq_virmidi: seq_mode is not set: %d\n", rdev->seq_mode);
 		return -EINVAL;
 	}
 	return 0;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 437c25e..60ab9b1 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -118,7 +118,7 @@
 	if (mreg && mreg->type == type) {
 		private_data = mreg->private_data;
 		if (private_data && mreg->card_ptr)
-			atomic_inc(&mreg->card_ptr->refcount);
+			get_device(&mreg->card_ptr->card_dev);
 	} else
 		private_data = NULL;
 	mutex_unlock(&sound_mutex);
@@ -458,7 +458,7 @@
 	snd_major = major;
 	snd_ecards_limit = cards_limit;
 	if (register_chrdev(major, "alsa", &snd_fops)) {
-		snd_printk(KERN_ERR "unable to register native major device number %d\n", major);
+		pr_err("ALSA core: unable to register native major device number %d\n", major);
 		return -EIO;
 	}
 	if (snd_info_init() < 0) {
@@ -467,7 +467,7 @@
 	}
 	snd_info_minor_register();
 #ifndef MODULE
-	printk(KERN_INFO "Advanced Linux Sound Architecture Driver Initialized.\n");
+	pr_info("Advanced Linux Sound Architecture Driver Initialized.\n");
 #endif
 	return 0;
 }
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index 726a49a..573a65e 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -21,7 +21,7 @@
 
 #ifdef CONFIG_SND_OSSEMUL
 
-#if !defined(CONFIG_SOUND) && !(defined(MODULE) && defined(CONFIG_SOUND_MODULE))
+#if !IS_ENABLED(CONFIG_SOUND)
 #error "Enable the OSS soundcore multiplexer (CONFIG_SOUND) in the kernel."
 #endif
 
@@ -55,7 +55,7 @@
 	if (mreg && mreg->type == type) {
 		private_data = mreg->private_data;
 		if (private_data && mreg->card_ptr)
-			atomic_inc(&mreg->card_ptr->refcount);
+			get_device(&mreg->card_ptr->card_dev);
 	} else
 		private_data = NULL;
 	mutex_unlock(&sound_oss_mutex);
@@ -105,8 +105,7 @@
 }
 
 int snd_register_oss_device(int type, struct snd_card *card, int dev,
-			    const struct file_operations *f_ops, void *private_data,
-			    const char *name)
+			    const struct file_operations *f_ops, void *private_data)
 {
 	int minor = snd_oss_kernel_minor(type, card, dev);
 	int minor_unit;
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 6ddcf06..cfd455a 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -35,9 +35,9 @@
 #include <sound/initval.h>
 #include <linux/kmod.h>
 
-#if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE)
+#if IS_ENABLED(CONFIG_SND_HRTIMER)
 #define DEFAULT_TIMER_LIMIT 4
-#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
+#elif IS_ENABLED(CONFIG_SND_RTCTIMER)
 #define DEFAULT_TIMER_LIMIT 2
 #else
 #define DEFAULT_TIMER_LIMIT 1
@@ -240,7 +240,8 @@
 		/* open a slave instance */
 		if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
 		    tid->dev_sclass > SNDRV_TIMER_SCLASS_OSS_SEQUENCER) {
-			snd_printd("invalid slave class %i\n", tid->dev_sclass);
+			pr_debug("ALSA: timer: invalid slave class %i\n",
+				 tid->dev_sclass);
 			return -EINVAL;
 		}
 		mutex_lock(&register_mutex);
@@ -774,7 +775,7 @@
 		*rtimer = NULL;
 	timer = kzalloc(sizeof(*timer), GFP_KERNEL);
 	if (timer == NULL) {
-		snd_printk(KERN_ERR "timer: cannot allocate\n");
+		pr_err("ALSA: timer: cannot allocate\n");
 		return -ENOMEM;
 	}
 	timer->tmr_class = tid->dev_class;
@@ -813,7 +814,7 @@
 	if (! list_empty(&timer->open_list_head)) {
 		struct list_head *p, *n;
 		struct snd_timer_instance *ti;
-		snd_printk(KERN_WARNING "timer %p is busy?\n", timer);
+		pr_warn("ALSA: timer %p is busy?\n", timer);
 		list_for_each_safe(p, n, &timer->open_list_head) {
 			list_del_init(p);
 			ti = list_entry(p, struct snd_timer_instance, open_list);
@@ -1955,12 +1956,10 @@
 #endif
 
 	if ((err = snd_timer_register_system()) < 0)
-		snd_printk(KERN_ERR "unable to register system timer (%i)\n",
-			   err);
+		pr_err("ALSA: unable to register system timer (%i)\n", err);
 	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,
 				       &snd_timer_f_ops, NULL, "timer")) < 0)
-		snd_printk(KERN_ERR "unable to register timer device (%i)\n",
-			   err);
+		pr_err("ALSA: unable to register timer device (%i)\n", err);
 	snd_timer_proc_init();
 	return 0;
 }
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 842a97d..6c58e6f 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -101,7 +101,7 @@
 	if (slave->info.count > 2  ||
 	    (slave->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER &&
 	     slave->info.type != SNDRV_CTL_ELEM_TYPE_BOOLEAN)) {
-		snd_printk(KERN_ERR "invalid slave element\n");
+		pr_err("ALSA: vmaster: invalid slave element\n");
 		kfree(uinfo);
 		return -EINVAL;
 	}
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index f758992..2a16c86 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -1142,8 +1142,8 @@
 	int dev = devptr->id;
 	int err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct loopback), &card);
+	err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct loopback), &card);
 	if (err < 0)
 		return err;
 	loopback = card->private_data;
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 915b4d7..fab90bd 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -1054,8 +1054,8 @@
 	int idx, err;
 	int dev = devptr->id;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_dummy), &card);
+	err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_dummy), &card);
 	if (err < 0)
 		return err;
 	dummy = card->private_data;
@@ -1114,8 +1114,6 @@
 
 	dummy_proc_init(dummy);
 
-	snd_card_set_dev(card, &devptr->dev);
-
 	err = snd_card_register(card);
 	if (err == 0) {
 		platform_set_drvdata(devptr, card);
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index 95ea4a1..33ed765 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1280,7 +1280,8 @@
 	if (!enable[dev])
 		return -ENOENT;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pfdev->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 	err = snd_ml403_ac97cr_create(card, pfdev, &ml403_ac97cr);
@@ -1310,8 +1311,6 @@
 		(unsigned long)ml403_ac97cr->port, ml403_ac97cr->irq,
 		ml403_ac97cr->capture_irq, dev + 1);
 
-	snd_card_set_dev(card, &pfdev->dev);
-
 	err = snd_card_register(card);
 	if (err < 0) {
 		snd_card_free(card);
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 90a3a7b..83014b8 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -64,7 +64,8 @@
 static int pnp_registered;
 static unsigned int snd_mpu401_devices;
 
-static int snd_mpu401_create(int dev, struct snd_card **rcard)
+static int snd_mpu401_create(struct device *devptr, int dev,
+			     struct snd_card **rcard)
 {
 	struct snd_card *card;
 	int err;
@@ -73,7 +74,8 @@
 		snd_printk(KERN_ERR "the uart_enter option is obsolete; remove it\n");
 
 	*rcard = NULL;
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 	strcpy(card->driver, "MPU-401 UART");
@@ -114,10 +116,9 @@
 		snd_printk(KERN_ERR "specify or disable IRQ\n");
 		return -EINVAL;
 	}
-	err = snd_mpu401_create(dev, &card);
+	err = snd_mpu401_create(&devptr->dev, dev, &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, &devptr->dev);
 	if ((err = snd_card_register(card)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -194,14 +195,13 @@
 		err = snd_mpu401_pnp(dev, pnp_dev, id);
 		if (err < 0)
 			return err;
-		err = snd_mpu401_create(dev, &card);
+		err = snd_mpu401_create(&pnp_dev->dev, dev, &card);
 		if (err < 0)
 			return err;
 		if ((err = snd_card_register(card)) < 0) {
 			snd_card_free(card);
 			return err;
 		}
-		snd_card_set_dev(card, &pnp_dev->dev);
 		pnp_set_drvdata(pnp_dev, card);
 		snd_mpu401_devices++;
 		++dev;
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index e5ec7eb..4b66c7f 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -697,7 +697,8 @@
 	int err;
 	struct mtpav *mtp_card;
 
-	err = snd_card_create(index, id, THIS_MODULE, sizeof(*mtp_card), &card);
+	err = snd_card_new(&dev->dev, index, id, THIS_MODULE,
+			   sizeof(*mtp_card), &card);
 	if (err < 0)
 		return err;
 
@@ -732,7 +733,6 @@
 
 	snd_mtpav_portscan(mtp_card);
 
-	snd_card_set_dev(card, &dev->dev);
 	err = snd_card_register(mtp_card->card);
 	if (err < 0)
 		goto __error;
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 4e0dd22..f5fd448 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -959,7 +959,8 @@
 	if ((err = snd_mts64_probe_port(p)) < 0)
 		return err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0) {
 		snd_printd("Cannot create card\n");
 		return err;
@@ -1009,8 +1010,6 @@
 
 	platform_set_drvdata(pdev, card);
 
-	snd_card_set_dev(card, &pdev->dev);
-
 	/* At this point card will be usable */
 	if ((err = snd_card_register(card)) < 0) {
 		snd_printd("Cannot register card\n");
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index 33d9a85..f66af58 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -501,10 +501,8 @@
 	hw->private_data = opl3;
 	hw->exclusive = 1;
 #ifdef CONFIG_SND_OSSEMUL
-	if (device == 0) {
+	if (device == 0)
 		hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
-		sprintf(hw->oss_dev, "dmfm%i", card->number);
-	}
 #endif
 	strcpy(hw->name, hw->id);
 	switch (opl3->hardware & OPL3_HW_MASK) {
diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c
index 742a4b6..ddcc1a3 100644
--- a/sound/drivers/opl3/opl3_synth.c
+++ b/sound/drivers/opl3/opl3_synth.c
@@ -24,7 +24,7 @@
 #include <sound/opl3.h>
 #include <sound/asound_fm.h>
 
-#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
+#if IS_ENABLED(CONFIG_SND_SEQUENCER)
 #define OPL3_SUPPORT_SYNTH
 #endif
 
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 328bd29..36808cd 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -105,7 +105,7 @@
 	hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	pcsp_chip.timer.function = pcsp_do_timer;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
@@ -127,8 +127,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(pcsp_chip.card, dev);
-
 	strcpy(card->driver, "PC-Speaker");
 	strcpy(card->shortname, "pcsp");
 	sprintf(card->longname, "Internal PC-Speaker at port 0x%x",
diff --git a/sound/drivers/pcsp/pcsp_input.c b/sound/drivers/pcsp/pcsp_input.c
index b874b0a..0ecf8a4 100644
--- a/sound/drivers/pcsp/pcsp_input.c
+++ b/sound/drivers/pcsp/pcsp_input.c
@@ -16,6 +16,7 @@
 #include <linux/input.h>
 #include <asm/io.h>
 #include "pcsp.h"
+#include "pcsp_input.h"
 
 static void pcspkr_do_sound(unsigned int count)
 {
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index 991018d..78ccfa4 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -748,7 +748,8 @@
 	if ((err = snd_portman_probe_port(p)) < 0)
 		return err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0) {
 		snd_printd("Cannot create card\n");
 		return err;
@@ -798,8 +799,6 @@
 
 	platform_set_drvdata(pdev, card);
 
-	snd_card_set_dev(card, &pdev->dev);
-
 	/* At this point card will be usable */
 	if ((err = snd_card_register(card)) < 0) {
 		snd_printd("Cannot register card\n");
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index e0bf5e7..9ad4414 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -942,7 +942,8 @@
 		return -ENODEV;
 	}
 
-	err  = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err  = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
+			    0, &card);
 	if (err < 0)
 		return err;
 
@@ -969,8 +970,6 @@
 		uart->base,
 		uart->irq);
 
-	snd_card_set_dev(card, &devptr->dev);
-
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index ace3879..b17872429 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -90,8 +90,8 @@
 	int idx, err;
 	int dev = devptr->id;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_card_virmidi), &card);
+	err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_card_virmidi), &card);
 	if (err < 0)
 		return err;
 	vmidi = card->private_data;
@@ -118,8 +118,6 @@
 	strcpy(card->shortname, "VirMIDI");
 	sprintf(card->longname, "Virtual MIDI Card %i", dev + 1);
 
-	snd_card_set_dev(card, &devptr->dev);
-
 	if ((err = snd_card_register(card)) == 0) {
 		platform_set_drvdata(devptr, card);
 		return 0;
diff --git a/sound/firewire/dice.c b/sound/firewire/dice.c
index c0aa649..0c39486 100644
--- a/sound/firewire/dice.c
+++ b/sound/firewire/dice.c
@@ -1326,10 +1326,10 @@
 	if (err < 0)
 		return err;
 
-	err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*dice), &card);
+	err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
+			   sizeof(*dice), &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, &unit->device);
 
 	dice = card->private_data;
 	dice->card = card;
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c
index fd42e6b..7ac9443 100644
--- a/sound/firewire/isight.c
+++ b/sound/firewire/isight.c
@@ -631,10 +631,10 @@
 	struct isight *isight;
 	int err;
 
-	err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card);
+	err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
+			   sizeof(*isight), &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, &unit->device);
 
 	isight = card->private_data;
 	isight->card = card;
diff --git a/sound/firewire/scs1x.c b/sound/firewire/scs1x.c
index 858023c..2dba848 100644
--- a/sound/firewire/scs1x.c
+++ b/sound/firewire/scs1x.c
@@ -391,10 +391,10 @@
 	struct scs *scs;
 	int err;
 
-	err = snd_card_create(-16, NULL, THIS_MODULE, sizeof(*scs), &card);
+	err = snd_card_new(&unit->device, -16, NULL, THIS_MODULE,
+			   sizeof(*scs), &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, &unit->device);
 
 	scs = card->private_data;
 	scs->card = card;
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index cc8bc3a..9f7ef21 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -668,10 +668,10 @@
 	u32 firmware;
 	int err;
 
-	err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*fwspk), &card);
+	err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE,
+			   sizeof(*fwspk), &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, &unit->device);
 
 	fwspk = card->private_data;
 	fwspk->card = card;
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index e04e750..1a3a6fa 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -98,7 +98,7 @@
 			AK4113_CINT | AK4113_STC);
 	chip->rcs1 = reg_read(chip, AK4113_REG_RCS1);
 	chip->rcs2 = reg_read(chip, AK4113_REG_RCS2);
-	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+	err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops);
 	if (err < 0)
 		goto __fail;
 
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 15ae025..c7f5633 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -111,7 +111,7 @@
 	chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT);
 	chip->rcs1 = reg_read(chip, AK4114_REG_RCS1);
 
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
+	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops)) < 0)
 		goto __fail;
 
 	if (r_ak4114)
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index 40e33c9..88452e8 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -62,7 +62,7 @@
 
 static void snd_ak4117_free(struct ak4117 *chip)
 {
-	del_timer(&chip->timer);
+	del_timer_sync(&chip->timer);
 	kfree(chip);
 }
 
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 26ce26a..f481a41 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -144,8 +144,9 @@
 	struct snd_opl3 *opl3;
 	struct snd_timer *timer;
 
-	error = snd_card_create(index[dev], id[dev], THIS_MODULE,
-				sizeof(struct snd_ad1816a), &card);
+	error = snd_card_new(&pcard->card->dev,
+			     index[dev], id[dev], THIS_MODULE,
+			     sizeof(struct snd_ad1816a), &card);
 	if (error < 0)
 		return error;
 	chip = card->private_data;
@@ -154,7 +155,6 @@
 		snd_card_free(card);
 		return error;
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 
 	if ((error = snd_ad1816a_create(card, port[dev],
 					irq[dev],
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index e3f455bd..093f22a 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -91,7 +91,7 @@
 	struct snd_pcm *pcm;
 	int error;
 
-	error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
+	error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
 	if (error < 0)
 		return error;
 
@@ -119,8 +119,6 @@
 	if (thinkpad[n])
 		strcat(card->longname, " [Thinkpad]");
 
-	snd_card_set_dev(card, dev);
-
 	error = snd_card_register(card);
 	if (error < 0)
 		goto out;
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c
index 3565921..120c524 100644
--- a/sound/isa/adlib.c
+++ b/sound/isa/adlib.c
@@ -53,7 +53,7 @@
 	struct snd_opl3 *opl3;
 	int error;
 
-	error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
+	error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
 	if (error < 0) {
 		dev_err(dev, "could not create card\n");
 		return error;
@@ -83,8 +83,6 @@
 		goto out;
 	}
 
-	snd_card_set_dev(card, dev);
-
 	error = snd_card_register(card);
 	if (error < 0) {
 		dev_err(dev, "could not register card\n");
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index 10f08a1..32d0152 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -193,8 +193,9 @@
 	struct snd_card_als100 *acard;
 	struct snd_opl3 *opl3;
 
-	error = snd_card_create(index[dev], id[dev], THIS_MODULE,
-				sizeof(struct snd_card_als100), &card);
+	error = snd_card_new(&pcard->card->dev,
+			     index[dev], id[dev], THIS_MODULE,
+			     sizeof(struct snd_card_als100), &card);
 	if (error < 0)
 		return error;
 	acard = card->private_data;
@@ -203,7 +204,6 @@
 		snd_card_free(card);
 		return error;
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 
 	if (pid->driver_data == SB_HW_DT019X)
 		dma16[dev] = -1;
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index db301ff..0ea75fc 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -184,8 +184,9 @@
 	struct snd_wss *chip;
 	struct snd_opl3 *opl3;
 
-	error = snd_card_create(index[dev], id[dev], THIS_MODULE,
-				sizeof(struct snd_card_azt2320), &card);
+	error = snd_card_new(&pcard->card->dev,
+			     index[dev], id[dev], THIS_MODULE,
+			     sizeof(struct snd_card_azt2320), &card);
 	if (error < 0)
 		return error;
 	acard = card->private_data;
@@ -194,7 +195,6 @@
 		snd_card_free(card);
 		return error;
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 
 	if ((error = snd_card_azt2320_enable_wss(port[dev]))) {
 		snd_card_free(card);
diff --git a/sound/isa/cmi8328.c b/sound/isa/cmi8328.c
index ab6b2dc..4778852 100644
--- a/sound/isa/cmi8328.c
+++ b/sound/isa/cmi8328.c
@@ -293,15 +293,14 @@
 	}
 	outb(val, port);
 
-	err = snd_card_create(index[ndev], id[ndev], THIS_MODULE,
-				sizeof(struct snd_cmi8328), &card);
+	err = snd_card_new(pdev, index[ndev], id[ndev], THIS_MODULE,
+			   sizeof(struct snd_cmi8328), &card);
 	if (err < 0)
 		return err;
 	cmi = card->private_data;
 	cmi->card = card;
 	cmi->port = port;
 	cmi->wss_cfg = val;
-	snd_card_set_dev(card, pdev);
 
 	err = snd_wss_create(card, port + 4, -1, irq[ndev], dma1[ndev],
 			dma2[ndev], WSS_HW_DETECT, 0, &cmi->wss);
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 270b965..dfedfd8 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -514,14 +514,15 @@
 
 #define PFX	"cmi8330: "
 
-static int snd_cmi8330_card_new(int dev, struct snd_card **cardp)
+static int snd_cmi8330_card_new(struct device *pdev, int dev,
+				struct snd_card **cardp)
 {
 	struct snd_card *card;
 	struct snd_cmi8330 *acard;
 	int err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_cmi8330), &card);
+	err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_cmi8330), &card);
 	if (err < 0) {
 		snd_printk(KERN_ERR PFX "could not get a new card\n");
 		return err;
@@ -635,10 +636,9 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_cmi8330_card_new(dev, &card);
+	err = snd_cmi8330_card_new(pdev, dev, &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, pdev);
 	if ((err = snd_cmi8330_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -698,7 +698,7 @@
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
 			       
-	res = snd_cmi8330_card_new(dev, &card);
+	res = snd_cmi8330_card_new(&pcard->card->dev, dev, &card);
 	if (res < 0)
 		return res;
 	if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) {
@@ -706,7 +706,6 @@
 		snd_card_free(card);
 		return res;
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 	if ((res = snd_cmi8330_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return res;
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index ba9a74e..7dba07a 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -95,7 +95,7 @@
 	struct snd_pcm *pcm;
 	int error;
 
-	error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
+	error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
 	if (error < 0)
 		return error;
 
@@ -135,8 +135,6 @@
 			dev_warn(dev, "MPU401 not detected\n");
 	}
 
-	snd_card_set_dev(card, dev);
-
 	error = snd_card_register(card);
 	if (error < 0)
 		goto out;
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 69614ac..750f51c 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -364,13 +364,14 @@
 	release_and_free_resource(acard->res_sb_port);
 }
 
-static int snd_cs423x_card_new(int dev, struct snd_card **cardp)
+static int snd_cs423x_card_new(struct device *pdev, int dev,
+			       struct snd_card **cardp)
 {
 	struct snd_card *card;
 	int err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_card_cs4236), &card);
+	err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_card_cs4236), &card);
 	if (err < 0)
 		return err;
 	card->private_free = snd_card_cs4236_free;
@@ -487,10 +488,9 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_cs423x_card_new(dev, &card);
+	err = snd_cs423x_card_new(pdev, dev, &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, pdev);
 	if ((err = snd_cs423x_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -577,7 +577,7 @@
 		if (!strcmp(cdev->id[0].id, cid))
 			break;
 	}
-	err = snd_cs423x_card_new(dev, &card);
+	err = snd_cs423x_card_new(&pdev->dev, dev, &card);
 	if (err < 0)
 		return err;
 	err = snd_card_cs423x_pnp(dev, card->private_data, pdev, cdev);
@@ -586,7 +586,6 @@
 		snd_card_free(card);
 		return err;
 	}
-	snd_card_set_dev(card, &pdev->dev);
 	if ((err = snd_cs423x_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -638,7 +637,7 @@
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
 
-	res = snd_cs423x_card_new(dev, &card);
+	res = snd_cs423x_card_new(&pcard->card->dev, dev, &card);
 	if (res < 0)
 		return res;
 	if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) {
@@ -647,7 +646,6 @@
 		snd_card_free(card);
 		return res;
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 	if ((res = snd_cs423x_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return res;
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index cdcfb57..76001fe0 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -187,8 +187,8 @@
 	struct snd_card *card;
 	int error;
 
-	error = snd_card_create(index[n], id[n], THIS_MODULE,
-				sizeof(struct snd_es1688), &card);
+	error = snd_card_new(dev, index[n], id[n], THIS_MODULE,
+			     sizeof(struct snd_es1688), &card);
 	if (error < 0)
 		return error;
 
@@ -196,8 +196,6 @@
 	if (error < 0)
 		goto out;
 
-	snd_card_set_dev(card, dev);
-
 	error = snd_es1688_probe(card, n);
 	if (error < 0)
 		goto out;
@@ -274,8 +272,9 @@
 	if (dev == SNDRV_CARDS)
 		return -ENODEV;
 
-	error = snd_card_create(index[dev], id[dev], THIS_MODULE,
-				sizeof(struct snd_es1688), &card);
+	error = snd_card_new(&pcard->card->dev,
+			     index[dev], id[dev], THIS_MODULE,
+			     sizeof(struct snd_es1688), &card);
 	if (error < 0)
 		return error;
 	chip = card->private_data;
@@ -285,7 +284,6 @@
 		snd_card_free(card);
 		return error;
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 	error = snd_es1688_probe(card, dev);
 	if (error < 0)
 		return error;
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 12978b8..1c16830 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -2105,10 +2105,11 @@
 #define is_isapnp_selected(dev)		0
 #endif
 
-static int snd_es18xx_card_new(int dev, struct snd_card **cardp)
+static int snd_es18xx_card_new(struct device *pdev, int dev,
+			       struct snd_card **cardp)
 {
-	return snd_card_create(index[dev], id[dev], THIS_MODULE,
-			       sizeof(struct snd_es18xx), cardp);
+	return snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
+			    sizeof(struct snd_es18xx), cardp);
 }
 
 static int snd_audiodrive_probe(struct snd_card *card, int dev)
@@ -2179,10 +2180,9 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_es18xx_card_new(dev, &card);
+	err = snd_es18xx_card_new(devptr, dev, &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, devptr);
 	if ((err = snd_audiodrive_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -2284,14 +2284,13 @@
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
 
-	err = snd_es18xx_card_new(dev, &card);
+	err = snd_es18xx_card_new(&pdev->dev, dev, &card);
 	if (err < 0)
 		return err;
 	if ((err = snd_audiodrive_pnp(dev, card->private_data, pdev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	snd_card_set_dev(card, &pdev->dev);
 	if ((err = snd_audiodrive_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -2342,7 +2341,7 @@
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
 
-	res = snd_es18xx_card_new(dev, &card);
+	res = snd_es18xx_card_new(&pcard->card->dev, dev, &card);
 	if (res < 0)
 		return res;
 
@@ -2350,7 +2349,6 @@
 		snd_card_free(card);
 		return res;
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 	if ((res = snd_audiodrive_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return res;
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c
index 81244e7..1eb2b1e 100644
--- a/sound/isa/galaxy/galaxy.c
+++ b/sound/isa/galaxy/galaxy.c
@@ -506,13 +506,11 @@
 	u8 type;
 	int err;
 
-	err = snd_card_create(index[n], id[n], THIS_MODULE, sizeof *galaxy,
-			      &card);
+	err = snd_card_new(dev, index[n], id[n], THIS_MODULE,
+			   sizeof(*galaxy), &card);
 	if (err < 0)
 		return err;
 
-	snd_card_set_dev(card, dev);
-
 	card->private_free = snd_galaxy_free;
 	galaxy = card->private_data;
 
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index 1adc1b9..7ce29ff 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -149,7 +149,7 @@
 	struct snd_gus_card *gus;
 	int error;
 
-	error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
+	error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
 	if (error < 0)
 		return error;
 
@@ -199,8 +199,6 @@
 		sprintf(card->longname + strlen(card->longname),
 			"&%d", gus->gf1.dma2);
 
-	snd_card_set_dev(card, dev);
-
 	error = snd_card_register(card);
 	if (error < 0)
 		goto out;
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index 38e1e32..28a1693 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -242,8 +242,8 @@
 	struct snd_opl3 *opl3;
 	int error;
 
-	error = snd_card_create(index[n], id[n], THIS_MODULE,
-				sizeof(struct snd_es1688), &card);
+	error = snd_card_new(dev, index[n], id[n], THIS_MODULE,
+			     sizeof(struct snd_es1688), &card);
 	if (error < 0)
 		return error;
 
@@ -328,8 +328,6 @@
 		"irq %i&%i, dma %i&%i", es1688->port,
 		gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8);
 
-	snd_card_set_dev(card, dev);
-
 	error = snd_card_register(card);
 	if (error < 0)
 		goto out;
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index 652d5d8..39df36c 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -214,8 +214,8 @@
 	struct snd_wss *wss;
 	struct snd_gusmax *maxcard;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_gusmax), &card);
+	err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_gusmax), &card);
 	if (err < 0)
 		return err;
 	card->private_free = snd_gusmax_free;
@@ -337,8 +337,6 @@
 	if (xdma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
 
-	snd_card_set_dev(card, pdev);
-
 	err = snd_card_register(card);
 	if (err < 0)
 		goto _err;
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index afef0d7..5abbbe4 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -625,14 +625,15 @@
 		free_irq(iwcard->irq, (void *)iwcard);
 }
 
-static int snd_interwave_card_new(int dev, struct snd_card **cardp)
+static int snd_interwave_card_new(struct device *pdev, int dev,
+				  struct snd_card **cardp)
 {
 	struct snd_card *card;
 	struct snd_interwave *iwcard;
 	int err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_interwave), &card);
+	err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_interwave), &card);
 	if (err < 0)
 		return err;
 	iwcard = card->private_data;
@@ -779,11 +780,10 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_interwave_card_new(dev, &card);
+	err = snd_interwave_card_new(devptr, dev, &card);
 	if (err < 0)
 		return err;
 
-	snd_card_set_dev(card, devptr);
 	if ((err = snd_interwave_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -876,7 +876,7 @@
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
 				
-	res = snd_interwave_card_new(dev, &card);
+	res = snd_interwave_card_new(&pcard->card->dev, dev, &card);
 	if (res < 0)
 		return res;
 
@@ -884,7 +884,6 @@
 		snd_card_free(card);
 		return res;
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 	if ((res = snd_interwave_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return res;
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index 0a90bd6..5016bf9 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -905,12 +905,11 @@
 		return -ENODEV;
 	}
 
-	err = snd_card_create(index[idx], id[idx], THIS_MODULE,
-			      sizeof(struct snd_msnd), &card);
+	err = snd_card_new(pdev, index[idx], id[idx], THIS_MODULE,
+			   sizeof(struct snd_msnd), &card);
 	if (err < 0)
 		return err;
 
-	snd_card_set_dev(card, pdev);
 	chip = card->private_data;
 	chip->card = card;
 
@@ -1122,14 +1121,14 @@
 	 * Create a new ALSA sound card entry, in anticipation
 	 * of detecting our hardware ...
 	 */
-	ret = snd_card_create(index[idx], id[idx], THIS_MODULE,
-			      sizeof(struct snd_msnd), &card);
+	ret = snd_card_new(&pcard->card->dev,
+			   index[idx], id[idx], THIS_MODULE,
+			   sizeof(struct snd_msnd), &card);
 	if (ret < 0)
 		return ret;
 
 	chip = card->private_data;
 	chip->card = card;
-	snd_card_set_dev(card, &pcard->card->dev);
 
 	/*
 	 * Read the correct parameters off the ISA PnP bus ...
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index cc01c41..a219bc3 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -627,14 +627,15 @@
 	release_and_free_resource(chip->res_port);
 }
 
-static int snd_opl3sa2_card_new(int dev, struct snd_card **cardp)
+static int snd_opl3sa2_card_new(struct device *pdev, int dev,
+				struct snd_card **cardp)
 {
 	struct snd_card *card;
 	struct snd_opl3sa2 *chip;
 	int err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_opl3sa2), &card);
+	err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_opl3sa2), &card);
 	if (err < 0)
 		return err;
 	strcpy(card->driver, "OPL3SA2");
@@ -737,14 +738,13 @@
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
 
-	err = snd_opl3sa2_card_new(dev, &card);
+	err = snd_opl3sa2_card_new(&pdev->dev, dev, &card);
 	if (err < 0)
 		return err;
 	if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	snd_card_set_dev(card, &pdev->dev);
 	if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -802,14 +802,13 @@
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
 
-	err = snd_opl3sa2_card_new(dev, &card);
+	err = snd_opl3sa2_card_new(&pdev->dev, dev, &card);
 	if (err < 0)
 		return err;
 	if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	snd_card_set_dev(card, &pdev->dev);
 	if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -883,10 +882,9 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_opl3sa2_card_new(dev, &card);
+	err = snd_opl3sa2_card_new(pdev, dev, &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, pdev);
 	if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 619753d..c2ca681 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1411,8 +1411,8 @@
 	struct snd_miro *miro;
 	struct snd_card *card;
 
-	error = snd_card_create(index, id, THIS_MODULE,
-				sizeof(struct snd_miro), &card);
+	error = snd_card_new(devptr, index, id, THIS_MODULE,
+			     sizeof(struct snd_miro), &card);
 	if (error < 0)
 		return error;
 
@@ -1479,8 +1479,6 @@
 		}
 	}
 
-	snd_card_set_dev(card, devptr);
-
 	error = snd_miro_probe(card);
 	if (error < 0) {
 		snd_card_free(card);
@@ -1584,8 +1582,8 @@
 		return -EBUSY;
 	if (!isapnp)
 		return -ENODEV;
-	err = snd_card_create(index, id, THIS_MODULE,
-				sizeof(struct snd_miro), &card);
+	err = snd_card_new(&pcard->card->dev, index, id, THIS_MODULE,
+			   sizeof(struct snd_miro), &card);
 	if (err < 0)
 		return err;
 
@@ -1612,7 +1610,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pcard->card->dev);
 	err = snd_miro_probe(card);
 	if (err < 0) {
 		snd_card_free(card);
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 6effe99..c9b5828 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -934,13 +934,13 @@
 	return snd_card_register(card);
 }
 
-static int snd_opti9xx_card_new(struct snd_card **cardp)
+static int snd_opti9xx_card_new(struct device *pdev, struct snd_card **cardp)
 {
 	struct snd_card *card;
 	int err;
 
-	err = snd_card_create(index, id, THIS_MODULE,
-			      sizeof(struct snd_opti9xx), &card);
+	err = snd_card_new(pdev, index, id, THIS_MODULE,
+			   sizeof(struct snd_opti9xx), &card);
 	if (err < 0)
 		return err;
 	card->private_free = snd_card_opti9xx_free;
@@ -1010,7 +1010,7 @@
 	}
 #endif
 
-	error = snd_opti9xx_card_new(&card);
+	error = snd_opti9xx_card_new(devptr, &card);
 	if (error < 0)
 		return error;
 
@@ -1018,7 +1018,6 @@
 		snd_card_free(card);
 		return error;
 	}
-	snd_card_set_dev(card, devptr);
 	if ((error = snd_opti9xx_probe(card)) < 0) {
 		snd_card_free(card);
 		return error;
@@ -1100,7 +1099,7 @@
 		return -EBUSY;
 	if (! isapnp)
 		return -ENODEV;
-	error = snd_opti9xx_card_new(&card);
+	error = snd_opti9xx_card_new(&pcard->card->dev, &card);
 	if (error < 0)
 		return error;
 	chip = card->private_data;
@@ -1131,7 +1130,6 @@
 		snd_card_free(card);
 		return error;
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 	if ((error = snd_opti9xx_probe(card)) < 0) {
 		snd_card_free(card);
 		return error;
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c
index 356a630..90d2eba 100644
--- a/sound/isa/sb/jazz16.c
+++ b/sound/isa/sb/jazz16.c
@@ -229,8 +229,8 @@
 	static int possible_dmas16[] = {5, 7, -1};
 	int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_card_jazz16), &card);
+	err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_card_jazz16), &card);
 	if (err < 0)
 		return err;
 
@@ -327,8 +327,6 @@
 					mpu_port[dev]);
 	}
 
-	snd_card_set_dev(card, devptr);
-
 	err = snd_card_register(card);
 	if (err < 0)
 		goto err_free;
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index a413099..3f69454 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -323,13 +323,14 @@
 #define is_isapnp_selected(dev)		0
 #endif
 
-static int snd_sb16_card_new(int dev, struct snd_card **cardp)
+static int snd_sb16_card_new(struct device *devptr, int dev,
+			     struct snd_card **cardp)
 {
 	struct snd_card *card;
 	int err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_card_sb16), &card);
+	err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_card_sb16), &card);
 	if (err < 0)
 		return err;
 	card->private_free = snd_sb16_free;
@@ -493,7 +494,7 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_sb16_card_new(dev, &card);
+	err = snd_sb16_card_new(pdev, dev, &card);
 	if (err < 0)
 		return err;
 
@@ -507,7 +508,6 @@
 	awe_port[dev] = port[dev] + 0x400;
 #endif
 
-	snd_card_set_dev(card, pdev);
 	if ((err = snd_sb16_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -613,10 +613,9 @@
 	for ( ; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev] || !isapnp[dev])
 			continue;
-		res = snd_sb16_card_new(dev, &card);
+		res = snd_sb16_card_new(&pcard->card->dev, dev, &card);
 		if (res < 0)
 			return res;
-		snd_card_set_dev(card, &pcard->card->dev);
 		if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 ||
 		    (res = snd_sb16_probe(card, dev)) < 0) {
 			snd_card_free(card);
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index a806ae9..6c32b3a 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -102,8 +102,8 @@
 	struct snd_opl3 *opl3;
 	int err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_sb8), &card);
+	err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_sb8), &card);
 	if (err < 0)
 		return err;
 	acard = card->private_data;
@@ -192,8 +192,6 @@
 		chip->port,
 		irq[dev], dma8[dev]);
 
-	snd_card_set_dev(card, pdev);
-
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c
index 09d481b..15a152e 100644
--- a/sound/isa/sc6000.c
+++ b/sound/isa/sc6000.c
@@ -559,8 +559,8 @@
 	char __iomem *vmss_port;
 
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, sizeof(vport),
-				&card);
+	err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE,
+			   sizeof(vport), &card);
 	if (err < 0)
 		return err;
 
@@ -668,8 +668,6 @@
 	sprintf(card->longname, "Gallant SC-6000 at 0x%lx, irq %d, dma %d",
 		mss_port[dev], xirq, xdma);
 
-	snd_card_set_dev(card, devptr);
-
 	err = snd_card_register(card);
 	if (err < 0)
 		goto err_unmap2;
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 57b3389..44405df 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -1169,8 +1169,8 @@
 	struct soundscape *sscape;
 	int ret;
 
-	ret = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct soundscape), &card);
+	ret = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct soundscape), &card);
 	if (ret < 0)
 		return ret;
 
@@ -1178,7 +1178,6 @@
 	sscape->type = SSCAPE;
 
 	dma[dev] &= 0x03;
-	snd_card_set_dev(card, pdev);
 
 	ret = create_sscape(dev, card);
 	if (ret < 0)
@@ -1259,8 +1258,9 @@
 	 * Create a new ALSA sound card entry, in anticipation
 	 * of detecting our hardware ...
 	 */
-	ret = snd_card_create(index[idx], id[idx], THIS_MODULE,
-			      sizeof(struct soundscape), &card);
+	ret = snd_card_new(&pcard->card->dev,
+			   index[idx], id[idx], THIS_MODULE,
+			   sizeof(struct soundscape), &card);
 	if (ret < 0)
 		return ret;
 
@@ -1288,7 +1288,6 @@
 		wss_port[idx] = pnp_port_start(dev, 1);
 		dma2[idx] = pnp_dma(dev, 1);
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 
 	ret = create_sscape(idx, card);
 	if (ret < 0)
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 82dd769..bfbf38c 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -334,14 +334,15 @@
 	}
 }
 
-static int snd_wavefront_card_new(int dev, struct snd_card **cardp)
+static int snd_wavefront_card_new(struct device *pdev, int dev,
+				  struct snd_card **cardp)
 {
 	struct snd_card *card;
 	snd_wavefront_card_t *acard;
 	int err;
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(snd_wavefront_card_t), &card);
+	err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(snd_wavefront_card_t), &card);
 	if (err < 0)
 		return err;
 
@@ -564,10 +565,9 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_wavefront_card_new(dev, &card);
+	err = snd_wavefront_card_new(pdev, dev, &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, pdev);
 	if ((err = snd_wavefront_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -612,7 +612,7 @@
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
 
-	res = snd_wavefront_card_new(dev, &card);
+	res = snd_wavefront_card_new(&pcard->card->dev, dev, &card);
 	if (res < 0)
 		return res;
 
@@ -623,7 +623,6 @@
 			return -ENODEV;
 		}
 	}
-	snd_card_set_dev(card, &pcard->card->dev);
 
 	if ((res = snd_wavefront_probe(card, dev)) < 0)
 		return res;
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 224f54b..a7cc49e 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -37,6 +37,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <sound/core.h>
@@ -98,6 +99,7 @@
 
 	struct snd_pcm *pcm;
 	struct audio_stream *stream[2];	/* playback & capture */
+	int dmaid[2];		/* tx(0)/rx(1) DMA ids */
 };
 
 /*--------------------------- Local Functions --------------------------------*/
@@ -465,15 +467,17 @@
 	spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
 
 	flags = claim_dma_lock();
-	if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX,
+	au1000->stream[PLAYBACK]->dma = request_au1000_dma(au1000->dmaid[0],
 			"AC97 TX", au1000_dma_interrupt, 0,
-			au1000->stream[PLAYBACK])) < 0) {
+			au1000->stream[PLAYBACK]);
+	if (au1000->stream[PLAYBACK]->dma < 0) {
 		release_dma_lock(flags);
 		return -EBUSY;
 	}
-	if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX,
+	au1000->stream[CAPTURE]->dma = request_au1000_dma(au1000->dmaid[1],
 			"AC97 RX", au1000_dma_interrupt, 0,
-			au1000->stream[CAPTURE])) < 0){
+			au1000->stream[CAPTURE]);
+	if (au1000->stream[CAPTURE]->dma < 0){
 		release_dma_lock(flags);
 		return -EBUSY;
 	}
@@ -552,27 +556,111 @@
 	spin_unlock(&au1000->ac97_lock);
 }
 
-static int
-snd_au1000_ac97_new(struct snd_au1000 *au1000)
+/*------------------------------ Setup / Destroy ----------------------------*/
+
+static void snd_au1000_free(struct snd_card *card)
+{
+	struct snd_au1000 *au1000 = card->private_data;
+
+	if (au1000->stream[PLAYBACK]) {
+	  	if (au1000->stream[PLAYBACK]->dma >= 0)
+			free_au1000_dma(au1000->stream[PLAYBACK]->dma);
+		kfree(au1000->stream[PLAYBACK]);
+	}
+
+	if (au1000->stream[CAPTURE]) {
+		if (au1000->stream[CAPTURE]->dma >= 0)
+			free_au1000_dma(au1000->stream[CAPTURE]->dma);
+		kfree(au1000->stream[CAPTURE]);
+	}
+
+	if (au1000->ac97_res_port) {
+		/* put internal AC97 block into reset */
+		if (au1000->ac97_ioport) {
+			au1000->ac97_ioport->cntrl = AC97C_RS;
+			iounmap(au1000->ac97_ioport);
+			au1000->ac97_ioport = NULL;
+		}
+		release_and_free_resource(au1000->ac97_res_port);
+		au1000->ac97_res_port = NULL;
+	}
+}
+
+static struct snd_ac97_bus_ops ops = {
+	.write	= snd_au1000_ac97_write,
+	.read	= snd_au1000_ac97_read,
+};
+
+static int au1000_ac97_probe(struct platform_device *pdev)
 {
 	int err;
+	void __iomem *io;
+	struct resource *r;
+	struct snd_card *card;
+	struct snd_au1000 *au1000;
 	struct snd_ac97_bus *pbus;
 	struct snd_ac97_template ac97;
- 	static struct snd_ac97_bus_ops ops = {
-		.write = snd_au1000_ac97_write,
-		.read = snd_au1000_ac97_read,
-	};
 
-	if ((au1000->ac97_res_port = request_mem_region(CPHYSADDR(AC97C_CONFIG),
-	       		0x100000, "Au1x00 AC97")) == NULL) {
-		snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n");
-		return -EBUSY;
-	}
-	au1000->ac97_ioport = (struct au1000_ac97_reg *)
-		KSEG1ADDR(au1000->ac97_res_port->start);
+	err = snd_card_new(&pdev->dev, -1, "AC97", THIS_MODULE,
+			   sizeof(struct snd_au1000), &card);
+	if (err < 0)
+		return err;
 
+	au1000 = card->private_data;
+	au1000->card = card;
 	spin_lock_init(&au1000->ac97_lock);
 
+	/* from here on let ALSA call the special freeing function */
+	card->private_free = snd_au1000_free;
+
+	/* TX DMA ID */
+	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (!r) {
+		err = -ENODEV;
+		snd_printk(KERN_INFO "no TX DMA platform resource!\n");
+		goto out;
+	}
+	au1000->dmaid[0] = r->start;
+
+	/* RX DMA ID */
+	r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+	if (!r) {
+		err = -ENODEV;
+		snd_printk(KERN_INFO "no RX DMA platform resource!\n");
+		goto out;
+	}
+	au1000->dmaid[1] = r->start;
+
+	au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream),
+					   GFP_KERNEL);
+	if (!au1000->stream[PLAYBACK])
+		goto out;
+	au1000->stream[PLAYBACK]->dma = -1;
+
+	au1000->stream[CAPTURE] = kmalloc(sizeof(struct audio_stream),
+					  GFP_KERNEL);
+	if (!au1000->stream[CAPTURE])
+		goto out;
+	au1000->stream[CAPTURE]->dma = -1;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		goto out;
+
+	err = -EBUSY;
+	au1000->ac97_res_port = request_mem_region(r->start,
+					r->end - r->start + 1, pdev->name);
+	if (!au1000->ac97_res_port) {
+		snd_printk(KERN_ERR "ALSA AC97: can't grab AC97 port\n");
+		goto out;
+	}
+
+	io = ioremap(r->start, r->end - r->start + 1);
+	if (!io)
+		goto out;
+
+	au1000->ac97_ioport = (struct au1000_ac97_reg *)io;
+
 	/* configure pins for AC'97
 	TODO: move to board_setup.c */
 	au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
@@ -590,107 +678,62 @@
 	mdelay(5);
 
 	/* Initialise AC97 middle-layer */
-	if ((err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus)) < 0)
- 		return err;
+	err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus);
+	if (err < 0)
+		goto out;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = au1000;
-	if ((err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97)) < 0)
-		return err;
-
-	return 0;
-}
-
-/*------------------------------ Setup / Destroy ----------------------------*/
-
-void
-snd_au1000_free(struct snd_card *card)
-{
-	struct snd_au1000 *au1000 = card->private_data;
-
-	if (au1000->ac97_res_port) {
-		/* put internal AC97 block into reset */
-		au1000->ac97_ioport->cntrl = AC97C_RS;
-		au1000->ac97_ioport = NULL;
-		release_and_free_resource(au1000->ac97_res_port);
-	}
-
-	if (au1000->stream[PLAYBACK]) {
-	  	if (au1000->stream[PLAYBACK]->dma >= 0)
-			free_au1000_dma(au1000->stream[PLAYBACK]->dma);
-		kfree(au1000->stream[PLAYBACK]);
-	}
-
-	if (au1000->stream[CAPTURE]) {
-		if (au1000->stream[CAPTURE]->dma >= 0)
-			free_au1000_dma(au1000->stream[CAPTURE]->dma);
-		kfree(au1000->stream[CAPTURE]);
-	}
-}
-
-
-static struct snd_card *au1000_card;
-
-static int __init
-au1000_init(void)
-{
-	int err;
-	struct snd_card *card;
-	struct snd_au1000 *au1000;
-
-	err = snd_card_create(-1, "AC97", THIS_MODULE,
-			      sizeof(struct snd_au1000), &card);
+	err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97);
 	if (err < 0)
-		return err;
+		goto out;
 
-	card->private_free = snd_au1000_free;
-	au1000 = card->private_data;
-	au1000->card = card;
-
-	au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
-	au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
-	/* so that snd_au1000_free will work as intended */
- 	au1000->ac97_res_port = NULL;
-	if (au1000->stream[PLAYBACK])
-		au1000->stream[PLAYBACK]->dma = -1;
-	if (au1000->stream[CAPTURE ])
-		au1000->stream[CAPTURE ]->dma = -1;
-
-	if (au1000->stream[PLAYBACK] == NULL ||
-	    au1000->stream[CAPTURE ] == NULL) {
-		snd_card_free(card);
-		return -ENOMEM;
-	}
-
-	if ((err = snd_au1000_ac97_new(au1000)) < 0 ) {
-		snd_card_free(card);
-		return err;
-	}
-
-	if ((err = snd_au1000_pcm_new(au1000)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	err = snd_au1000_pcm_new(au1000);
+	if (err < 0)
+		goto out;
 
 	strcpy(card->driver, "Au1000-AC97");
 	strcpy(card->shortname, "AMD Au1000-AC97");
 	sprintf(card->longname, "AMD Au1000--AC97 ALSA Driver");
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	err = snd_card_register(card);
+	if (err < 0)
+		goto out;
 
 	printk(KERN_INFO "ALSA AC97: Driver Initialized\n");
-	au1000_card = card;
+
+	platform_set_drvdata(pdev, card);
+
 	return 0;
+
+ out:
+	snd_card_free(card);
+	return err;
 }
 
-static void __exit au1000_exit(void)
+static int au1000_ac97_remove(struct platform_device *pdev)
 {
-	snd_card_free(au1000_card);
+	return snd_card_free(platform_get_drvdata(pdev));
 }
 
-module_init(au1000_init);
-module_exit(au1000_exit);
+struct platform_driver au1000_ac97c_driver = {
+	.driver	= {
+		.name	= "au1000-ac97c",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= au1000_ac97_probe,
+	.remove		= au1000_ac97_remove,
+};
 
+static int __init au1000_ac97_load(void)
+{
+	return platform_driver_register(&au1000_ac97c_driver);
+}
+
+static void __exit au1000_ac97_unload(void)
+{
+	platform_driver_unregister(&au1000_ac97c_driver);
+}
+
+module_init(au1000_ac97_load);
+module_exit(au1000_ac97_unload);
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index 2b7f6e8..23441b9 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -880,7 +880,7 @@
 	struct snd_hal2 *chip;
 	int err;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
@@ -889,7 +889,6 @@
 		snd_card_free(card);
 		return err;
 	}
-	snd_card_set_dev(card, &pdev->dev);
 
 	err = hal2_pcm_create(chip);
 	if (err < 0) {
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index cfe99ae..04bb06c 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -920,7 +920,7 @@
 	struct snd_sgio2audio *chip;
 	int err;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pdev->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
@@ -929,7 +929,6 @@
 		snd_card_free(card);
 		return err;
 	}
-	snd_card_set_dev(card, &pdev->dev);
 
 	err = snd_sgio2audio_new_pcm(chip);
 	if (err < 0) {
diff --git a/sound/oss/pas2.h b/sound/oss/pas2.h
index fa12c55..d19f757 100644
--- a/sound/oss/pas2.h
+++ b/sound/oss/pas2.h
@@ -15,3 +15,6 @@
 /*	From pas_midi.c */
 void pas_midi_init(void);
 void pas_midi_interrupt(void);
+
+/*	From pas2_mixer.c*/
+void mix_write(unsigned char data, int ioaddr);
diff --git a/sound/oss/pas2_card.c b/sound/oss/pas2_card.c
index 7004e24..b07954a 100644
--- a/sound/oss/pas2_card.c
+++ b/sound/oss/pas2_card.c
@@ -74,8 +74,6 @@
  * to support other than the default base address
  */
 
-extern void     mix_write(unsigned char data, int ioaddr);
-
 unsigned char pas_read(int ioaddr)
 {
 	return inb(ioaddr + pas_translate_code);
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index 67f56a2..4b20be7 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -959,8 +959,6 @@
                 goto free_and_ret;
         }
 
-	snd_card_set_dev(card, &padev->dev);
-
 	*rchip = h;
 
 	return 0;
@@ -977,7 +975,7 @@
 	struct snd_card *card;
 	struct snd_harmony *h;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&padev->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index b680d03..ba4da1e 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -965,8 +965,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 
 	return 0;
@@ -996,7 +994,8 @@
 	}
 
 	/* (2) */
-	err = snd_card_create(index[devno], id[devno], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE,
+			   0, &card);
 	/* XXX REVISIT: we can probably allocate chip in this call */
 	if (err < 0)
 		return err;
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index c6835a3..115b112 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -2218,8 +2218,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	/* initialise synth voices*/
 	for (i = 0; i < ALI_CHANNELS; i++)
 		codec->synth.voices[i].number = i;
@@ -2253,7 +2251,7 @@
 
 	snd_ali_printk("probe ...\n");
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 591efb6..9acd88a 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -761,8 +761,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 	snd_als300_dbgcallleave();
 	return 0;
@@ -829,7 +827,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 
 	if (err < 0)
 		return err;
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index ffc821b..2b2bb0f 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -888,9 +888,9 @@
 	pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
 	pci_set_master(pci);
 	
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 
-			      sizeof(*acard) /* private_data: acard */,
-			      &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(*acard) /* private_data: acard */,
+			   &card);
 	if (err < 0) {
 		pci_release_regions(pci);
 		pci_disable_device(pci);
@@ -920,7 +920,6 @@
 
 	chip->pci = pci;
 	chip->alt_port = iobase;
-	snd_card_set_dev(card, &pci->dev);
 
 	snd_als4000_configure(chip);
 
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index 5f2acd3..e4e42f2 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -2827,17 +2827,13 @@
 	hpi = pci_get_drvdata(pci_dev);
 	adapter_index = hpi->adapter->index;
 	/* first try to give the card the same index as its hardware index */
-	err = snd_card_create(adapter_index,
-			      id[adapter_index], THIS_MODULE,
-			      sizeof(struct snd_card_asihpi),
-			      &card);
+	err = snd_card_new(&pci_dev->dev, adapter_index, id[adapter_index],
+			   THIS_MODULE, sizeof(struct snd_card_asihpi), &card);
 	if (err < 0) {
 		/* if that fails, try the default index==next available */
-		err =
-		    snd_card_create(index[dev], id[dev],
-				    THIS_MODULE,
-				    sizeof(struct snd_card_asihpi),
-				    &card);
+		err = snd_card_new(&pci_dev->dev, index[dev], id[dev],
+				   THIS_MODULE, sizeof(struct snd_card_asihpi),
+				   &card);
 		if (err < 0)
 			return err;
 		snd_printk(KERN_WARNING
@@ -2845,8 +2841,6 @@
 			adapter_index, card->number);
 	}
 
-	snd_card_set_dev(card, &pci_dev->dev);
-
 	asihpi = card->private_data;
 	asihpi->card = card;
 	asihpi->pci = pci_dev;
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index f6dec3e..85f893b 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1657,8 +1657,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*r_chip = chip;
 	return 0;
 }
@@ -1671,7 +1669,7 @@
 	struct atiixp *chip;
 	int err;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 289563e..2b3244a 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1282,8 +1282,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*r_chip = chip;
 	return 0;
 }
@@ -1296,7 +1294,7 @@
 	struct atiixp_modem *chip;
 	int err;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 7059dd6..afb1b44 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -211,8 +211,6 @@
 		goto alloc_out;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 
 	return 0;
@@ -250,7 +248,8 @@
 		return -ENOENT;
 	}
 	// (2)
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
index 2925220..e9dabee 100644
--- a/sound/pci/aw2/aw2-alsa.c
+++ b/sound/pci/aw2/aw2-alsa.c
@@ -322,7 +322,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
 	*rchip = chip;
 
 	printk(KERN_INFO
@@ -349,7 +348,8 @@
 	}
 
 	/* (2) Create card instance */
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 1aef712..641c235 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2599,8 +2599,6 @@
 		spin_unlock_irq(codec->lock);
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 
 	err = 0;
@@ -2635,7 +2633,8 @@
 		goto out;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		goto out;
 
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 1880203..06dc7d9 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -773,7 +773,6 @@
 	if (err < 0)
 		goto fail;
 
-	snd_card_set_dev(card, &pci->dev);
 	*rchip = chip;
 	return 0;
 
@@ -888,7 +887,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index f4db558..f659c7a 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1843,7 +1843,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
@@ -1878,8 +1879,6 @@
 	snd_ca0106_proc_init(chip);
 #endif
 
-	snd_card_set_dev(card, &pci->dev);
-
 	err = snd_card_register(card);
 	if (err < 0)
 		goto error;
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 2755ec5..66c0558 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3254,8 +3254,6 @@
 	if (snd_cmipci_create_gameport(cm, dev) < 0)
 		snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rcmipci = cm;
 	return 0;
 }
@@ -3280,7 +3278,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 	
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 1dc793e..2bd5517 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1402,8 +1402,6 @@
 
 	snd_cs4281_proc_init(chip);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 	return 0;
 }
@@ -1917,7 +1915,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index b034983..af0eacb 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -88,7 +88,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 	if ((err = snd_cs46xx_create(card, pci,
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 062398e..2876647 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -4058,8 +4058,6 @@
 
 	chip->active_ctrl(chip, -1); /* disable CLKRUN */
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 	return 0;
 }
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index c6b82c8..8037e86 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -244,7 +244,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
 	*rchip = chip;
 	return 0;
 }
@@ -264,7 +263,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 
 	if (err < 0)
 		return err;
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index c0d2835..051b3e2 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -324,8 +324,6 @@
 				  cs5535au, &ops)) < 0)
 		goto sndfail;
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rcs5535au = cs5535au;
 	return 0;
 
@@ -353,7 +351,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index eb86829..af632bd 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1739,8 +1739,6 @@
 	if (err < 0)
 		goto error1;
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*ratc = atc;
 	return 0;
 
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index d464ad2..98426d0 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -71,7 +71,8 @@
 		dev++;
 		return -ENOENT;
 	}
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err)
 		return err;
 	if ((reference_rate != 48000) && (reference_rate != 44100)) {
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 05cfe55..1ef77c0 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -2058,12 +2058,11 @@
 
 	DE_INIT(("Echoaudio driver starting...\n"));
 	i = 0;
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
-	snd_card_set_dev(card, &pci->dev);
-
 	chip = NULL;	/* Tells snd_echo_create to allocate chip */
 	if ((err = snd_echo_create(card, pci, &chip)) < 0) {
 		snd_card_free(card);
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 9e1bd0c..5c0413b 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -117,7 +117,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 	if (max_buffer_size[dev] < 32)
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index bdd888e..75504da 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -2021,7 +2021,6 @@
 	snd_emu10k1_proc_init(emu);
 #endif
 
-	snd_card_set_dev(card, &pci->dev);
 	*remu = emu;
 	return 0;
 
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 56ad9d6..3988eaa 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -1564,7 +1564,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
@@ -1608,8 +1609,6 @@
 	sprintf(card->longname, "%s at 0x%lx irq %i",
 		card->shortname, chip->port, chip->irq);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	if ((err = snd_card_register(card)) < 0) {
 		snd_card_free(card);
 		return err;
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 61262f3..0f89d2a2 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -2180,8 +2180,6 @@
 
 	snd_ensoniq_proc_init(ensoniq);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rensoniq = ensoniq;
 	return 0;
 }
@@ -2437,7 +2435,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 9213fb3..33489bc 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1658,8 +1658,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 	return 0;
 }
@@ -1808,7 +1806,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 	for (idx = 0; idx < 5; idx++) {
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 772cc36..87e9cd5d 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -2783,8 +2783,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 #ifdef CONFIG_SND_ES1968_RADIO
 	/* don't play with GPIOs on laptops */
 	if (chip->pci->subsystem_vendor != 0x125d)
@@ -2836,7 +2834,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
                 
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 45bc8a9..8b6af21 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1251,8 +1251,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 #ifdef CONFIG_SND_FM801_TEA575X_BOOL
 	err = v4l2_device_register(&pci->dev, &chip->v4l2_dev);
 	if (err < 0) {
@@ -1312,7 +1310,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 	if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip)) < 0) {
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 0589b39..d8c437a 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -20,7 +20,6 @@
  */
 
 #include <linux/input.h>
-#include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/export.h>
@@ -167,7 +166,7 @@
 	input_dev->evbit[0] = BIT_MASK(EV_SND);
 	input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 	input_dev->event = snd_hda_beep_event;
-	input_dev->dev.parent = &codec->bus->pci->dev;
+	input_dev->dev.parent = codec->bus->card->dev;
 	input_set_drvdata(input_dev, beep);
 
 	err = input_register_device(input_dev);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index dafcf82..1155027 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/async.h>
@@ -68,6 +67,7 @@
 	{ 0x17e8, "Chrontel" },
 	{ 0x1854, "LG" },
 	{ 0x1aec, "Wolfson Microelectronics" },
+	{ 0x1af4, "QEMU" },
 	{ 0x434d, "C-Media" },
 	{ 0x8086, "Intel" },
 	{ 0x8384, "SigmaTel" },
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index d9a09bd..bcd9c71 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -79,7 +79,7 @@
 	snd_array_free(&spec->kctls);
 }
 
-void snd_hda_gen_spec_free(struct hda_gen_spec *spec)
+static void snd_hda_gen_spec_free(struct hda_gen_spec *spec)
 {
 	if (!spec)
 		return;
@@ -87,7 +87,6 @@
 	snd_array_free(&spec->paths);
 	snd_array_free(&spec->loopback_list);
 }
-EXPORT_SYMBOL_GPL(snd_hda_gen_spec_free);
 
 /*
  * store user hints
@@ -762,7 +761,7 @@
 						    AC_PWRST_D0);
 		}
 		if (enable && path->multi[i])
-			snd_hda_codec_write_cache(codec, nid, 0,
+			snd_hda_codec_update_cache(codec, nid, 0,
 					    AC_VERB_SET_CONNECT_SEL,
 					    path->idx[i]);
 		if (has_amp_in(codec, path, i))
@@ -5350,6 +5349,7 @@
  */
 void snd_hda_gen_free(struct hda_codec *codec)
 {
+	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_FREE);
 	snd_hda_detach_beep_device(codec);
 	snd_hda_gen_spec_free(codec->spec);
 	kfree(codec->spec);
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index c908afb..bb2dea7 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -297,7 +297,6 @@
 };
 
 int snd_hda_gen_spec_init(struct hda_gen_spec *spec);
-void snd_hda_gen_spec_free(struct hda_gen_spec *spec);
 
 int snd_hda_gen_init(struct hda_codec *codec);
 void snd_hda_gen_free(struct hda_codec *codec);
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 72d8389..53c9619 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -20,7 +20,6 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/compat.h>
 #include <linux/mutex.h>
 #include <linux/ctype.h>
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index e354ab1..0870f5f 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -834,18 +834,6 @@
 	return addr;
 }
 
-static unsigned int azx_response_addr(u32 res)
-{
-	unsigned int addr = res & 0xf;
-
-	if (addr >= AZX_MAX_CODECS) {
-		snd_BUG();
-		addr = 0;
-	}
-
-	return addr;
-}
-
 /* send a command */
 static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
 {
@@ -907,8 +895,15 @@
 		rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
 		res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
 		res = le32_to_cpu(chip->rirb.buf[rp]);
-		addr = azx_response_addr(res_ex);
-		if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
+		addr = res_ex & 0xf;
+		if ((addr >= AZX_MAX_CODECS) || !(chip->codec_mask & (1 << addr))) {
+			snd_printk(KERN_ERR SFX "%s: spurious response %#x:%#x, rp = %d, wp = %d",
+				   pci_name(chip->pci),
+				   res, res_ex,
+				   chip->rirb.rp, wp);
+			snd_BUG();
+		}
+		else if (res_ex & ICH6_RIRB_EX_UNSOL_EV)
 			snd_hda_queue_unsol_event(chip->bus, res, res_ex);
 		else if (chip->rirb.cmds[addr]) {
 			chip->rirb.res[addr] = res;
@@ -3828,14 +3823,13 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0) {
 		snd_printk(KERN_ERR "hda-intel: Error creating card!\n");
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
 	if (err < 0)
 		goto out_free;
@@ -4142,7 +4136,7 @@
 	  .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
 	{ PCI_DEVICE(0x1102, 0x0012),
 	  .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
-#if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE)
+#if !IS_ENABLED(CONFIG_SND_CTXFI)
 	/* the following entry conflicts with snd-ctxfi driver,
 	 * as ctxfi driver mutates from HD-audio to native mode with
 	 * a special command sequence.
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index df3652a..1eb00a6 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -21,7 +21,6 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/module.h>
 
 #include <sound/core.h>
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 30b3a4b..5e65999 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -20,7 +20,6 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/module.h>
 #include <sound/core.h>
 #include "hda_codec.h"
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 46ecdbb..c7ea40f 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -24,7 +24,6 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/firmware.h>
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index fc492ac..387f0b5 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -20,7 +20,6 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/module.h>
 #include <sound/core.h>
 #include <sound/tlv.h>
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 9c6ce73..d782292 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -23,7 +23,6 @@
 
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/module.h>
 #include <sound/core.h>
 #include "hda_codec.h"
@@ -32,6 +31,9 @@
 #include "hda_jack.h"
 #include "hda_generic.h"
 
+#undef ENABLE_CMI_STATIC_QUIRKS
+
+#ifdef ENABLE_CMI_STATIC_QUIRKS
 #define NUM_PINS	11
 
 
@@ -45,10 +47,12 @@
 	CMI_AUTO,	/* let driver guess it */
 	CMI_MODELS
 };
+#endif /* ENABLE_CMI_STATIC_QUIRKS */
 
 struct cmi_spec {
 	struct hda_gen_spec gen;
 
+#ifdef ENABLE_CMI_STATIC_QUIRKS
 	/* below are only for static models */
 
 	int board_config;
@@ -81,8 +85,10 @@
 
 	/* multichannel pins */
 	struct hda_verb multi_init[9];	/* 2 verbs for each pin + terminator */
+#endif /* ENABLE_CMI_STATIC_QUIRKS */
 };
 
+#ifdef ENABLE_CMI_STATIC_QUIRKS
 /*
  * input MUX
  */
@@ -566,6 +572,7 @@
 	.init = cmi9880_init,
 	.free = cmi9880_free,
 };
+#endif /* ENABLE_CMI_STATIC_QUIRKS */
 
 /*
  * stuff for auto-parser
@@ -588,15 +595,20 @@
 
 	err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
 	if (err < 0)
-		return err;
+		goto error;
 	err = snd_hda_gen_parse_auto_config(codec, cfg);
 	if (err < 0)
-		return err;
+		goto error;
 
 	codec->patch_ops = cmi_auto_patch_ops;
 	return 0;
+
+ error:
+	snd_hda_gen_free(codec);
+	return err;
 }
 
+
 static int patch_cmi9880(struct hda_codec *codec)
 {
 	struct cmi_spec *spec;
@@ -606,6 +618,7 @@
 		return -ENOMEM;
 
 	codec->spec = spec;
+#ifdef ENABLE_CMI_STATIC_QUIRKS
 	spec->board_config = snd_hda_check_board_config(codec, CMI_MODELS,
 							cmi9880_models,
 							cmi9880_cfg_tbl);
@@ -615,14 +628,8 @@
 		spec->board_config = CMI_AUTO; /* try everything */
 	}
 
-	if (spec->board_config == CMI_AUTO) {
-		int err = cmi_parse_auto_config(codec);
-		if (err < 0) {
-			snd_hda_gen_free(codec);
-			return err;
-		}
-		return 0;
-	}
+	if (spec->board_config == CMI_AUTO)
+		return cmi_parse_auto_config(codec);
 
 	/* copy default DAC NIDs */
 	memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids));
@@ -669,6 +676,9 @@
 	codec->patch_ops = cmi9880_patch_ops;
 
 	return 0;
+#else
+	return cmi_parse_auto_config(codec);
+#endif
 }
 
 /*
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index bcf91be..13a4160 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/module.h>
 #include <sound/core.h>
 #include <sound/jack.h>
@@ -35,7 +34,7 @@
 #include "hda_jack.h"
 #include "hda_generic.h"
 
-#define ENABLE_CXT_STATIC_QUIRKS
+#undef ENABLE_CXT_STATIC_QUIRKS
 
 #define CXT_PIN_DIR_IN              0x00
 #define CXT_PIN_DIR_OUT             0x01
@@ -68,6 +67,12 @@
 
 	unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
 
+	/* OPLC XO specific */
+	bool recording;
+	bool dc_enable;
+	unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */
+	struct nid_path *dc_mode_path;
+
 #ifdef ENABLE_CXT_STATIC_QUIRKS
 	const struct snd_kcontrol_new *mixers[5];
 	int num_mixers;
@@ -123,19 +128,6 @@
 	unsigned int hp_laptop:1;
 	unsigned int asus:1;
 
-	unsigned int ext_mic_present;
-	unsigned int recording;
-	void (*capture_prepare)(struct hda_codec *codec);
-	void (*capture_cleanup)(struct hda_codec *codec);
-
-	/* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
-	 * through the microphone jack.
-	 * When the user enables this through a mixer switch, both internal and
-	 * external microphones are disabled. Gain is fixed at 0dB. In this mode,
-	 * we also allow the bias to be configured through a separate mixer
-	 * control. */
-	unsigned int dc_enable;
-	unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
 	unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
 #endif /* ENABLE_CXT_STATIC_QUIRKS */
 };
@@ -253,8 +245,6 @@
 				      struct snd_pcm_substream *substream)
 {
 	struct conexant_spec *spec = codec->spec;
-	if (spec->capture_prepare)
-		spec->capture_prepare(codec);
 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
 				   stream_tag, 0, format);
 	return 0;
@@ -266,8 +256,6 @@
 {
 	struct conexant_spec *spec = codec->spec;
 	snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
-	if (spec->capture_cleanup)
-		spec->capture_cleanup(codec);
 	return 0;
 }
 
@@ -673,14 +661,6 @@
 	}
 };
 
-static const struct hda_input_mux cxt5045_capture_source_hp530 = {
-	.num_items = 2,
-	.items = {
-		{ "Mic",          0x1 },
-		{ "Internal Mic", 0x2 },
-	}
-};
-
 /* turn on/off EAPD (+ mute HP) as a master switch */
 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
 				    struct snd_ctl_elem_value *ucontrol)
@@ -796,28 +776,6 @@
 	{}
 };
 
-static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
-	HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
-	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
-	HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Switch",
-		.info = cxt_eapd_info,
-		.get = cxt_eapd_get,
-		.put = cxt5045_hp_master_sw_put,
-		.private_value = 0x10,
-	},
-
-	{}
-};
-
 static const struct hda_verb cxt5045_init_verbs[] = {
 	/* Line in, Mic */
 	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
@@ -1000,7 +958,6 @@
 	CXT5045_LAPTOP_MICSENSE,
 	CXT5045_LAPTOP_HPMICSENSE,
 	CXT5045_BENQ,
-	CXT5045_LAPTOP_HP530,
 #ifdef CONFIG_SND_DEBUG
 	CXT5045_TEST,
 #endif
@@ -1013,7 +970,6 @@
 	[CXT5045_LAPTOP_MICSENSE]	= "laptop-micsense",
 	[CXT5045_LAPTOP_HPMICSENSE]	= "laptop-hpmicsense",
 	[CXT5045_BENQ]			= "benq",
-	[CXT5045_LAPTOP_HP530]		= "laptop-hp530",
 #ifdef CONFIG_SND_DEBUG
 	[CXT5045_TEST]		= "test",
 #endif
@@ -1021,8 +977,6 @@
 };
 
 static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
-	SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
-	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
 	SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
 	SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
 	SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
@@ -1113,14 +1067,6 @@
 		spec->num_mixers = 2;
 		codec->patch_ops.init = cxt5045_init;
 		break;
-	case CXT5045_LAPTOP_HP530:
-		codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
-		spec->input_mux = &cxt5045_capture_source_hp530;
-		spec->num_init_verbs = 2;
-		spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
-		spec->mixers[0] = cxt5045_mixers_hp530;
-		codec->patch_ops.init = cxt5045_init;
-		break;
 #ifdef CONFIG_SND_DEBUG
 	case CXT5045_TEST:
 		spec->input_mux = &cxt5045_test_capture_source;
@@ -1940,11 +1886,6 @@
 static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
 static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
 
-/* OLPC's microphone port is DC coupled for use with external sensors,
- * therefore we use a 50% mic bias in order to center the input signal with
- * the DC input range of the codec. */
-#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
-
 static const struct hda_channel_mode cxt5066_modes[1] = {
 	{ 2, NULL },
 };
@@ -1997,88 +1938,6 @@
 	return 1;
 }
 
-static const struct hda_input_mux cxt5066_olpc_dc_bias = {
-	.num_items = 3,
-	.items = {
-		{ "Off", PIN_IN },
-		{ "50%", PIN_VREF50 },
-		{ "80%", PIN_VREF80 },
-	},
-};
-
-static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
-{
-	struct conexant_spec *spec = codec->spec;
-	/* Even though port F is the DC input, the bias is controlled on port B.
-	 * we also leave that port as an active input (but unselected) in DC mode
-	 * just in case that is necessary to make the bias setting take effect. */
-	return snd_hda_set_pin_ctl_cache(codec, 0x1a,
-		cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
-}
-
-/* OLPC defers mic widget control until when capture is started because the
- * microphone LED comes on as soon as these settings are put in place. if we
- * did this before recording, it would give the false indication that recording
- * is happening when it is not. */
-static void cxt5066_olpc_select_mic(struct hda_codec *codec)
-{
-	struct conexant_spec *spec = codec->spec;
-	if (!spec->recording)
-		return;
-
-	if (spec->dc_enable) {
-		/* in DC mode we ignore presence detection and just use the jack
-		 * through our special DC port */
-		const struct hda_verb enable_dc_mode[] = {
-			/* disble internal mic, port C */
-			{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
-			/* enable DC capture, port F */
-			{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
-			{},
-		};
-
-		snd_hda_sequence_write(codec, enable_dc_mode);
-		/* port B input disabled (and bias set) through the following call */
-		cxt5066_set_olpc_dc_bias(codec);
-		return;
-	}
-
-	/* disable DC (port F) */
-	snd_hda_set_pin_ctl(codec, 0x1e, 0);
-
-	/* external mic, port B */
-	snd_hda_set_pin_ctl(codec, 0x1a,
-		spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
-
-	/* internal mic, port C */
-	snd_hda_set_pin_ctl(codec, 0x1b,
-		spec->ext_mic_present ? 0 : PIN_VREF80);
-}
-
-/* toggle input of built-in and mic jack appropriately */
-static void cxt5066_olpc_automic(struct hda_codec *codec)
-{
-	struct conexant_spec *spec = codec->spec;
-	unsigned int present;
-
-	if (spec->dc_enable) /* don't do presence detection in DC mode */
-		return;
-
-	present = snd_hda_codec_read(codec, 0x1a, 0,
-				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
-	if (present)
-		snd_printdd("CXT5066: external microphone detected\n");
-	else
-		snd_printdd("CXT5066: external microphone absent\n");
-
-	snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
-		present ? 0 : 1);
-	spec->ext_mic_present = !!present;
-
-	cxt5066_olpc_select_mic(codec);
-}
-
 /* toggle input of built-in digital mic and mic jack appropriately */
 static void cxt5066_vostro_automic(struct hda_codec *codec)
 {
@@ -2252,23 +2111,6 @@
 }
 
 /* unsolicited event for jack sensing */
-static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-	struct conexant_spec *spec = codec->spec;
-	snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
-	switch (res >> 26) {
-	case CONEXANT_HP_EVENT:
-		cxt5066_hp_automute(codec);
-		break;
-	case CONEXANT_MIC_EVENT:
-		/* ignore mic events in DC mode; we're always using the jack */
-		if (!spec->dc_enable)
-			cxt5066_olpc_automic(codec);
-		break;
-	}
-}
-
-/* unsolicited event for jack sensing */
 static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
 {
 	snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
@@ -2338,124 +2180,10 @@
 		idx = imux->num_items - 1;
 
 	spec->mic_boost = idx;
-	if (!spec->dc_enable)
-		cxt5066_set_mic_boost(codec);
-	return 1;
-}
-
-static void cxt5066_enable_dc(struct hda_codec *codec)
-{
-	const struct hda_verb enable_dc_mode[] = {
-		/* disable gain */
-		{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-		/* switch to DC input */
-		{0x17, AC_VERB_SET_CONNECT_SEL, 3},
-		{}
-	};
-
-	/* configure as input source */
-	snd_hda_sequence_write(codec, enable_dc_mode);
-	cxt5066_olpc_select_mic(codec); /* also sets configured bias */
-}
-
-static void cxt5066_disable_dc(struct hda_codec *codec)
-{
-	/* reconfigure input source */
 	cxt5066_set_mic_boost(codec);
-	/* automic also selects the right mic if we're recording */
-	cxt5066_olpc_automic(codec);
-}
-
-static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
-			     struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct conexant_spec *spec = codec->spec;
-	ucontrol->value.integer.value[0] = spec->dc_enable;
-	return 0;
-}
-
-static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
-			     struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct conexant_spec *spec = codec->spec;
-	int dc_enable = !!ucontrol->value.integer.value[0];
-
-	if (dc_enable == spec->dc_enable)
-		return 0;
-
-	spec->dc_enable = dc_enable;
-	if (dc_enable)
-		cxt5066_enable_dc(codec);
-	else
-		cxt5066_disable_dc(codec);
-
 	return 1;
 }
 
-static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
-					   struct snd_ctl_elem_info *uinfo)
-{
-	return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
-}
-
-static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
-					  struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct conexant_spec *spec = codec->spec;
-	ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
-	return 0;
-}
-
-static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
-					  struct snd_ctl_elem_value *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct conexant_spec *spec = codec->spec;
-	const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
-	unsigned int idx;
-
-	idx = ucontrol->value.enumerated.item[0];
-	if (idx >= imux->num_items)
-		idx = imux->num_items - 1;
-
-	spec->dc_input_bias = idx;
-	if (spec->dc_enable)
-		cxt5066_set_olpc_dc_bias(codec);
-	return 1;
-}
-
-static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
-{
-	struct conexant_spec *spec = codec->spec;
-	/* mark as recording and configure the microphone widget so that the
-	 * recording LED comes on. */
-	spec->recording = 1;
-	cxt5066_olpc_select_mic(codec);
-}
-
-static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
-{
-	struct conexant_spec *spec = codec->spec;
-	const struct hda_verb disable_mics[] = {
-		/* disable external mic, port B */
-		{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
-		/* disble internal mic, port C */
-		{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
-		/* disable DC capture, port F */
-		{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-		{},
-	};
-
-	snd_hda_sequence_write(codec, disable_mics);
-	spec->recording = 0;
-}
-
 static void conexant_check_dig_outs(struct hda_codec *codec,
 				    const hda_nid_t *dig_pins,
 				    int num_pins)
@@ -2506,43 +2234,6 @@
 	{}
 };
 
-static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Volume",
-		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-				  SNDRV_CTL_ELEM_ACCESS_TLV_READ |
-				  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
-		.subdevice = HDA_SUBDEV_AMP_FLAG,
-		.info = snd_hda_mixer_amp_volume_info,
-		.get = snd_hda_mixer_amp_volume_get,
-		.put = snd_hda_mixer_amp_volume_put,
-		.tlv = { .c = snd_hda_mixer_amp_tlv },
-		/* offset by 28 volume steps to limit minimum gain to -46dB */
-		.private_value =
-			HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
-	},
-	{}
-};
-
-static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "DC Mode Enable Switch",
-		.info = snd_ctl_boolean_mono_info,
-		.get = cxt5066_olpc_dc_get,
-		.put = cxt5066_olpc_dc_put,
-	},
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "DC Input Bias Enum",
-		.info = cxt5066_olpc_dc_bias_enum_info,
-		.get = cxt5066_olpc_dc_bias_enum_get,
-		.put = cxt5066_olpc_dc_bias_enum_put,
-	},
-	{}
-};
-
 static const struct snd_kcontrol_new cxt5066_mixers[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2633,67 +2324,6 @@
 	{ } /* end */
 };
 
-static const struct hda_verb cxt5066_init_verbs_olpc[] = {
-	/* Port A: headphones */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
-	{0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
-	/* Port B: external microphone */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
-	/* Port C: internal microphone */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
-	/* Port D: unused */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
-	/* Port E: unused, but has primary EAPD */
-	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
-
-	/* Port F: external DC input through microphone port */
-	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
-	/* Port G: internal speakers */
-	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
-	{0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
-
-	/* DAC1 */
-	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
-
-	/* DAC2: unused */
-	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
-
-	/* Disable digital microphone port */
-	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
-	/* Audio input selectors */
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
-
-	/* Disable SPDIF */
-	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
-
-	/* enable unsolicited events for Port A and B */
-	{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
-	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
-	{ } /* end */
-};
-
 static const struct hda_verb cxt5066_init_verbs_vostro[] = {
 	/* Port A: headphones */
 	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -2889,25 +2519,9 @@
 	return 0;
 }
 
-static int cxt5066_olpc_init(struct hda_codec *codec)
-{
-	struct conexant_spec *spec = codec->spec;
-	snd_printdd("CXT5066: init\n");
-	conexant_init(codec);
-	cxt5066_hp_automute(codec);
-	if (!spec->dc_enable) {
-		cxt5066_set_mic_boost(codec);
-		cxt5066_olpc_automic(codec);
-	} else {
-		cxt5066_enable_dc(codec);
-	}
-	return 0;
-}
-
 enum {
 	CXT5066_LAPTOP,		/* Laptops w/ EAPD support */
 	CXT5066_DELL_LAPTOP,	/* Dell Laptop */
-	CXT5066_OLPC_XO_1_5,	/* OLPC XO 1.5 */
 	CXT5066_DELL_VOSTRO,	/* Dell Vostro 1015i */
 	CXT5066_IDEAPAD,	/* Lenovo IdeaPad U150 */
 	CXT5066_THINKPAD,	/* Lenovo ThinkPad T410s, others? */
@@ -2920,7 +2534,6 @@
 static const char * const cxt5066_models[CXT5066_MODELS] = {
 	[CXT5066_LAPTOP]	= "laptop",
 	[CXT5066_DELL_LAPTOP]	= "dell-laptop",
-	[CXT5066_OLPC_XO_1_5]	= "olpc-xo-1_5",
 	[CXT5066_DELL_VOSTRO]	= "dell-vostro",
 	[CXT5066_IDEAPAD]	= "ideapad",
 	[CXT5066_THINKPAD]	= "thinkpad",
@@ -2941,10 +2554,8 @@
 	SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
 	SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
 	SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
-	SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
 	SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
 		      CXT5066_LAPTOP),
-	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
 	SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
 	SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
@@ -3030,32 +2641,11 @@
 		spec->mic_boost = 3; /* default 30dB gain */
 		break;
 
-	case CXT5066_OLPC_XO_1_5:
-		codec->patch_ops.init = cxt5066_olpc_init;
-		codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
-		spec->init_verbs[0] = cxt5066_init_verbs_olpc;
-		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
-		spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
-		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
-		spec->port_d_mode = 0;
-		spec->mic_boost = 3; /* default 30dB gain */
-
-		/* no S/PDIF out */
-		spec->multiout.dig_out_nid = 0;
-
-		/* input source automatically selected */
-		spec->input_mux = NULL;
-
-		/* our capture hooks which allow us to turn on the microphone LED
-		 * at the right time */
-		spec->capture_prepare = cxt5066_olpc_capture_prepare;
-		spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
-		break;
 	case CXT5066_DELL_VOSTRO:
 		codec->patch_ops.init = cxt5066_init;
 		codec->patch_ops.unsol_event = cxt5066_unsol_event;
 		spec->init_verbs[0] = cxt5066_init_verbs_vostro;
-		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
+		spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
 		spec->mixers[spec->num_mixers++] = cxt5066_mixers;
 		spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
 		spec->port_d_mode = 0;
@@ -3207,11 +2797,7 @@
 	return 0;
 }
 
-static void cx_auto_free(struct hda_codec *codec)
-{
-	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_FREE);
-	snd_hda_gen_free(codec);
-}
+#define cx_auto_free	snd_hda_gen_free
 
 static const struct hda_codec_ops cx_auto_patch_ops = {
 	.build_controls = cx_auto_build_controls,
@@ -3238,6 +2824,11 @@
 	CXT_FIXUP_HEADPHONE_MIC,
 	CXT_FIXUP_GPIO1,
 	CXT_FIXUP_THINKPAD_ACPI,
+	CXT_FIXUP_OLPC_XO,
+	CXT_FIXUP_CAP_MIX_AMP,
+	CXT_FIXUP_TOSHIBA_P105,
+	CXT_FIXUP_HP_530,
+	CXT_FIXUP_CAP_MIX_AMP_5047,
 };
 
 /* for hda_fixup_thinkpad_acpi() */
@@ -3316,6 +2907,288 @@
 	}
 }
 
+/* OPLC XO 1.5 fixup */
+
+/* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
+ * through the microphone jack.
+ * When the user enables this through a mixer switch, both internal and
+ * external microphones are disabled. Gain is fixed at 0dB. In this mode,
+ * we also allow the bias to be configured through a separate mixer
+ * control. */
+
+#define update_mic_pin(codec, nid, val)					\
+	snd_hda_codec_update_cache(codec, nid, 0,			\
+				   AC_VERB_SET_PIN_WIDGET_CONTROL, val)
+
+static const struct hda_input_mux olpc_xo_dc_bias = {
+	.num_items = 3,
+	.items = {
+		{ "Off", PIN_IN },
+		{ "50%", PIN_VREF50 },
+		{ "80%", PIN_VREF80 },
+	},
+};
+
+static void olpc_xo_update_mic_boost(struct hda_codec *codec)
+{
+	struct conexant_spec *spec = codec->spec;
+	int ch, val;
+
+	for (ch = 0; ch < 2; ch++) {
+		val = AC_AMP_SET_OUTPUT |
+			(ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT);
+		if (!spec->dc_enable)
+			val |= snd_hda_codec_amp_read(codec, 0x17, ch, HDA_OUTPUT, 0);
+		snd_hda_codec_write(codec, 0x17, 0,
+				    AC_VERB_SET_AMP_GAIN_MUTE, val);
+	}
+}
+
+static void olpc_xo_update_mic_pins(struct hda_codec *codec)
+{
+	struct conexant_spec *spec = codec->spec;
+	int cur_input, val;
+	struct nid_path *path;
+
+	cur_input = spec->gen.input_paths[0][spec->gen.cur_mux[0]];
+
+	/* Set up mic pins for port-B, C and F dynamically as the recording
+	 * LED is turned on/off by these pin controls
+	 */
+	if (!spec->dc_enable) {
+		/* disable DC bias path and pin for port F */
+		update_mic_pin(codec, 0x1e, 0);
+		snd_hda_activate_path(codec, spec->dc_mode_path, false, false);
+
+		/* update port B (ext mic) and C (int mic) */
+		/* OLPC defers mic widget control until when capture is
+		 * started because the microphone LED comes on as soon as
+		 * these settings are put in place. if we did this before
+		 * recording, it would give the false indication that
+		 * recording is happening when it is not.
+		 */
+		update_mic_pin(codec, 0x1a, spec->recording ?
+			       snd_hda_codec_get_pin_target(codec, 0x1a) : 0);
+		update_mic_pin(codec, 0x1b, spec->recording ?
+			       snd_hda_codec_get_pin_target(codec, 0x1b) : 0);
+		/* enable normal mic path */
+		path = snd_hda_get_path_from_idx(codec, cur_input);
+		if (path)
+			snd_hda_activate_path(codec, path, true, false);
+	} else {
+		/* disable normal mic path */
+		path = snd_hda_get_path_from_idx(codec, cur_input);
+		if (path)
+			snd_hda_activate_path(codec, path, false, false);
+
+		/* Even though port F is the DC input, the bias is controlled
+		 * on port B.  We also leave that port as an active input (but
+		 * unselected) in DC mode just in case that is necessary to
+		 * make the bias setting take effect.
+		 */
+		if (spec->recording)
+			val = olpc_xo_dc_bias.items[spec->dc_input_bias].index;
+		else
+			val = 0;
+		update_mic_pin(codec, 0x1a, val);
+		update_mic_pin(codec, 0x1b, 0);
+		/* enable DC bias path and pin */
+		update_mic_pin(codec, 0x1e, spec->recording ? PIN_IN : 0);
+		snd_hda_activate_path(codec, spec->dc_mode_path, true, false);
+	}
+}
+
+/* mic_autoswitch hook */
+static void olpc_xo_automic(struct hda_codec *codec, struct hda_jack_tbl *jack)
+{
+	struct conexant_spec *spec = codec->spec;
+	int saved_cached_write = codec->cached_write;
+
+	codec->cached_write = 1;
+	/* in DC mode, we don't handle automic */
+	if (!spec->dc_enable)
+		snd_hda_gen_mic_autoswitch(codec, jack);
+	olpc_xo_update_mic_pins(codec);
+	snd_hda_codec_flush_cache(codec);
+	codec->cached_write = saved_cached_write;
+	if (spec->dc_enable)
+		olpc_xo_update_mic_boost(codec);
+}
+
+/* pcm_capture hook */
+static void olpc_xo_capture_hook(struct hda_pcm_stream *hinfo,
+				 struct hda_codec *codec,
+				 struct snd_pcm_substream *substream,
+				 int action)
+{
+	struct conexant_spec *spec = codec->spec;
+
+	/* toggle spec->recording flag and update mic pins accordingly
+	 * for turning on/off LED
+	 */
+	switch (action) {
+	case HDA_GEN_PCM_ACT_PREPARE:
+		spec->recording = 1;
+		olpc_xo_update_mic_pins(codec);
+		break;
+	case HDA_GEN_PCM_ACT_CLEANUP:
+		spec->recording = 0;
+		olpc_xo_update_mic_pins(codec);
+		break;
+	}
+}
+
+static int olpc_xo_dc_mode_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	ucontrol->value.integer.value[0] = spec->dc_enable;
+	return 0;
+}
+
+static int olpc_xo_dc_mode_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	int dc_enable = !!ucontrol->value.integer.value[0];
+
+	if (dc_enable == spec->dc_enable)
+		return 0;
+
+	spec->dc_enable = dc_enable;
+	olpc_xo_update_mic_pins(codec);
+	olpc_xo_update_mic_boost(codec);
+	return 1;
+}
+
+static int olpc_xo_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
+	return 0;
+}
+
+static int olpc_xo_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
+{
+	return snd_hda_input_mux_info(&olpc_xo_dc_bias, uinfo);
+}
+
+static int olpc_xo_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	const struct hda_input_mux *imux = &olpc_xo_dc_bias;
+	unsigned int idx;
+
+	idx = ucontrol->value.enumerated.item[0];
+	if (idx >= imux->num_items)
+		idx = imux->num_items - 1;
+	if (spec->dc_input_bias == idx)
+		return 0;
+
+	spec->dc_input_bias = idx;
+	if (spec->dc_enable)
+		olpc_xo_update_mic_pins(codec);
+	return 1;
+}
+
+static const struct snd_kcontrol_new olpc_xo_mixers[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "DC Mode Enable Switch",
+		.info = snd_ctl_boolean_mono_info,
+		.get = olpc_xo_dc_mode_get,
+		.put = olpc_xo_dc_mode_put,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "DC Input Bias Enum",
+		.info = olpc_xo_dc_bias_enum_info,
+		.get = olpc_xo_dc_bias_enum_get,
+		.put = olpc_xo_dc_bias_enum_put,
+	},
+	{}
+};
+
+/* overriding mic boost put callback; update mic boost volume only when
+ * DC mode is disabled
+ */
+static int olpc_xo_mic_boost_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct conexant_spec *spec = codec->spec;
+	int ret = snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
+	if (ret > 0 && spec->dc_enable)
+		olpc_xo_update_mic_boost(codec);
+	return ret;
+}
+
+static void cxt_fixup_olpc_xo(struct hda_codec *codec,
+				    const struct hda_fixup *fix, int action)
+{
+	struct conexant_spec *spec = codec->spec;
+	int i;
+
+	if (action != HDA_FIXUP_ACT_PROBE)
+		return;
+
+	spec->gen.mic_autoswitch_hook = olpc_xo_automic;
+	spec->gen.pcm_capture_hook = olpc_xo_capture_hook;
+	spec->dc_mode_path = snd_hda_add_new_path(codec, 0x1e, 0x14, 0);
+
+	snd_hda_add_new_ctls(codec, olpc_xo_mixers);
+
+	/* OLPC's microphone port is DC coupled for use with external sensors,
+	 * therefore we use a 50% mic bias in order to center the input signal
+	 * with the DC input range of the codec.
+	 */
+	snd_hda_codec_set_pin_target(codec, 0x1a, PIN_VREF50);
+
+	/* override mic boost control */
+	for (i = 0; i < spec->gen.kctls.used; i++) {
+		struct snd_kcontrol_new *kctl =
+			snd_array_elem(&spec->gen.kctls, i);
+		if (!strcmp(kctl->name, "Mic Boost Volume")) {
+			kctl->put = olpc_xo_mic_boost_put;
+			break;
+		}
+	}
+}
+
+/*
+ * Fix max input level on mixer widget to 0dB
+ * (originally it has 0x2b steps with 0dB offset 0x14)
+ */
+static void cxt_fixup_cap_mix_amp(struct hda_codec *codec,
+				  const struct hda_fixup *fix, int action)
+{
+	snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
+				  (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
+				  (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+				  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+				  (1 << AC_AMPCAP_MUTE_SHIFT));
+}
+
+/*
+ * Fix max input level on mixer widget to 0dB
+ * (originally it has 0x1e steps with 0 dB offset 0x17)
+ */
+static void cxt_fixup_cap_mix_amp_5047(struct hda_codec *codec,
+				  const struct hda_fixup *fix, int action)
+{
+	snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
+				  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
+				  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
+				  (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
+				  (1 << AC_AMPCAP_MUTE_SHIFT));
+}
 
 /* ThinkPad X200 & co with cxt5051 */
 static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
@@ -3401,6 +3274,68 @@
 		.type = HDA_FIXUP_FUNC,
 		.v.func = hda_fixup_thinkpad_acpi,
 	},
+	[CXT_FIXUP_OLPC_XO] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = cxt_fixup_olpc_xo,
+	},
+	[CXT_FIXUP_CAP_MIX_AMP] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = cxt_fixup_cap_mix_amp,
+	},
+	[CXT_FIXUP_TOSHIBA_P105] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{ 0x10, 0x961701f0 }, /* speaker/hp */
+			{ 0x12, 0x02a1901e }, /* ext mic */
+			{ 0x14, 0x95a70110 }, /* int mic */
+			{}
+		},
+	},
+	[CXT_FIXUP_HP_530] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{ 0x12, 0x90a60160 }, /* int mic */
+			{}
+		},
+		.chained = true,
+		.chain_id = CXT_FIXUP_CAP_MIX_AMP,
+	},
+	[CXT_FIXUP_CAP_MIX_AMP_5047] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = cxt_fixup_cap_mix_amp_5047,
+	},
+};
+
+static const struct snd_pci_quirk cxt5045_fixups[] = {
+	SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT_FIXUP_HP_530),
+	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT_FIXUP_TOSHIBA_P105),
+	/* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
+	 * really bad sound over 0dB on NID 0x17.
+	 */
+	SND_PCI_QUIRK_VENDOR(0x103c, "HP", CXT_FIXUP_CAP_MIX_AMP),
+	SND_PCI_QUIRK_VENDOR(0x1631, "Packard Bell", CXT_FIXUP_CAP_MIX_AMP),
+	SND_PCI_QUIRK_VENDOR(0x1734, "Fujitsu", CXT_FIXUP_CAP_MIX_AMP),
+	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT_FIXUP_CAP_MIX_AMP),
+	{}
+};
+
+static const struct hda_model_fixup cxt5045_fixup_models[] = {
+	{ .id = CXT_FIXUP_CAP_MIX_AMP, .name = "cap-mix-amp" },
+	{ .id = CXT_FIXUP_TOSHIBA_P105, .name = "toshiba-p105" },
+	{ .id = CXT_FIXUP_HP_530, .name = "hp-530" },
+	{}
+};
+
+static const struct snd_pci_quirk cxt5047_fixups[] = {
+	/* HP laptops have really bad sound over 0 dB on NID 0x10.
+	 */
+	SND_PCI_QUIRK_VENDOR(0x103c, "HP", CXT_FIXUP_CAP_MIX_AMP_5047),
+	{}
+};
+
+static const struct hda_model_fixup cxt5047_fixup_models[] = {
+	{ .id = CXT_FIXUP_CAP_MIX_AMP_5047, .name = "cap-mix-amp" },
+	{}
 };
 
 static const struct snd_pci_quirk cxt5051_fixups[] = {
@@ -3408,10 +3343,16 @@
 	{}
 };
 
+static const struct hda_model_fixup cxt5051_fixup_models[] = {
+	{ .id = CXT_PINCFG_LENOVO_X200, .name = "lenovo-x200" },
+	{}
+};
+
 static const struct snd_pci_quirk cxt5066_fixups[] = {
 	SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_GPIO1),
 	SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
+	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
@@ -3428,6 +3369,17 @@
 	{}
 };
 
+static const struct hda_model_fixup cxt5066_fixup_models[] = {
+	{ .id = CXT_FIXUP_STEREO_DMIC, .name = "stereo-dmic" },
+	{ .id = CXT_FIXUP_GPIO1, .name = "gpio1" },
+	{ .id = CXT_FIXUP_HEADPHONE_MIC_PIN, .name = "headphone-mic-pin" },
+	{ .id = CXT_PINCFG_LENOVO_TP410, .name = "tp410" },
+	{ .id = CXT_FIXUP_THINKPAD_ACPI, .name = "thinkpad" },
+	{ .id = CXT_PINCFG_LEMOTE_A1004, .name = "lemote-a1004" },
+	{ .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" },
+	{}
+};
+
 /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
  * can be created (bko#42825)
  */
@@ -3467,19 +3419,28 @@
 	switch (codec->vendor_id) {
 	case 0x14f15045:
 		codec->single_adc_amp = 1;
+		spec->gen.mixer_nid = 0x17;
+		spec->gen.add_stereo_mix_input = 1;
+		snd_hda_pick_fixup(codec, cxt5045_fixup_models,
+				   cxt5045_fixups, cxt_fixups);
 		break;
 	case 0x14f15047:
 		codec->pin_amp_workaround = 1;
 		spec->gen.mixer_nid = 0x19;
+		spec->gen.add_stereo_mix_input = 1;
+		snd_hda_pick_fixup(codec, cxt5047_fixup_models,
+				   cxt5047_fixups, cxt_fixups);
 		break;
 	case 0x14f15051:
 		add_cx5051_fake_mutes(codec);
 		codec->pin_amp_workaround = 1;
-		snd_hda_pick_fixup(codec, NULL, cxt5051_fixups, cxt_fixups);
+		snd_hda_pick_fixup(codec, cxt5051_fixup_models,
+				   cxt5051_fixups, cxt_fixups);
 		break;
 	default:
 		codec->pin_amp_workaround = 1;
-		snd_hda_pick_fixup(codec, NULL, cxt5066_fixups, cxt_fixups);
+		snd_hda_pick_fixup(codec, cxt5066_fixup_models,
+				   cxt5066_fixups, cxt_fixups);
 		break;
 	}
 
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 0b4ea6c..ee1ba22 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -395,6 +395,8 @@
 		goto do_sku;
 	}
 
+	if (!codec->bus->pci)
+		return -1;
 	ass = codec->subsystem_id & 0xffff;
 	if (ass != codec->bus->pci->subsystem_device && (ass & 1))
 		goto do_sku;
@@ -483,7 +485,8 @@
 	}
 
 	ass = codec->subsystem_id & 0xffff;
-	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
+	if (codec->bus->pci &&
+	    ass != codec->bus->pci->subsystem_device && (ass & 1))
 		goto do_sku;
 
 	/* invalid SSID, check the special NID pin defcfg instead */
@@ -845,11 +848,7 @@
 		snd_hda_shutup_pins(codec);
 }
 
-static void alc_free(struct hda_codec *codec)
-{
-	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_FREE);
-	snd_hda_gen_free(codec);
-}
+#define alc_free	snd_hda_gen_free
 
 #ifdef CONFIG_PM
 static void alc_power_eapd(struct hda_codec *codec)
@@ -970,6 +969,8 @@
 			return alc_codec_rename(codec, p->name);
 	}
 
+	if (!codec->bus->pci)
+		return 0;
 	for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
 		if (q->codec_vendor_id != codec->vendor_id)
 			continue;
@@ -4552,13 +4553,15 @@
 		spec->codec_variant = ALC269_TYPE_ALC269VA;
 		switch (alc_get_coef0(codec) & 0x00f0) {
 		case 0x0010:
-			if (codec->bus->pci->subsystem_vendor == 0x1025 &&
+			if (codec->bus->pci &&
+			    codec->bus->pci->subsystem_vendor == 0x1025 &&
 			    spec->cdefine.platform_type == 1)
 				err = alc_codec_rename(codec, "ALC271X");
 			spec->codec_variant = ALC269_TYPE_ALC269VB;
 			break;
 		case 0x0020:
-			if (codec->bus->pci->subsystem_vendor == 0x17aa &&
+			if (codec->bus->pci &&
+			    codec->bus->pci->subsystem_vendor == 0x17aa &&
 			    codec->bus->pci->subsystem_device == 0x21f3)
 				err = alc_codec_rename(codec, "ALC3202");
 			spec->codec_variant = ALC269_TYPE_ALC269VC;
@@ -4921,8 +4924,54 @@
 	}
 }
 
+/* turn on/off mute LED per vmaster hook */
+static void alc662_led_gpio1_mute_hook(void *private_data, int enabled)
+{
+	struct hda_codec *codec = private_data;
+	struct alc_spec *spec = codec->spec;
+	unsigned int oldval = spec->gpio_led;
+
+	if (enabled)
+		spec->gpio_led &= ~0x01;
+	else
+		spec->gpio_led |= 0x01;
+	if (spec->gpio_led != oldval)
+		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
+				    spec->gpio_led);
+}
+
+/* avoid D3 for keeping GPIO up */
+static unsigned int gpio_led_power_filter(struct hda_codec *codec,
+					  hda_nid_t nid,
+					  unsigned int power_state)
+{
+	struct alc_spec *spec = codec->spec;
+	if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led)
+		return AC_PWRST_D0;
+	return power_state;
+}
+
+static void alc662_fixup_led_gpio1(struct hda_codec *codec,
+				   const struct hda_fixup *fix, int action)
+{
+	struct alc_spec *spec = codec->spec;
+	static const struct hda_verb gpio_init[] = {
+		{ 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
+		{ 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
+		{}
+	};
+
+	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+		spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook;
+		spec->gpio_led = 0;
+		snd_hda_add_verbs(codec, gpio_init);
+		codec->power_filter = gpio_led_power_filter;
+	}
+}
+
 enum {
 	ALC662_FIXUP_ASPIRE,
+	ALC662_FIXUP_LED_GPIO1,
 	ALC662_FIXUP_IDEAPAD,
 	ALC272_FIXUP_MARIO,
 	ALC662_FIXUP_CZC_P10T,
@@ -4941,9 +4990,10 @@
 	ALC662_FIXUP_INV_DMIC,
 	ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
 	ALC668_FIXUP_HEADSET_MODE,
-	ALC662_FIXUP_BASS_CHMAP,
+	ALC662_FIXUP_BASS_MODE4_CHMAP,
+	ALC662_FIXUP_BASS_16,
 	ALC662_FIXUP_BASS_1A,
-	ALC662_FIXUP_BASS_1A_CHMAP,
+	ALC662_FIXUP_BASS_CHMAP,
 	ALC668_FIXUP_AUTO_MUTE,
 };
 
@@ -4955,12 +5005,18 @@
 			{ }
 		}
 	},
+	[ALC662_FIXUP_LED_GPIO1] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc662_fixup_led_gpio1,
+	},
 	[ALC662_FIXUP_IDEAPAD] = {
 		.type = HDA_FIXUP_PINS,
 		.v.pins = (const struct hda_pintbl[]) {
 			{ 0x17, 0x99130112 }, /* subwoofer */
 			{ }
-		}
+		},
+		.chained = true,
+		.chain_id = ALC662_FIXUP_LED_GPIO1,
 	},
 	[ALC272_FIXUP_MARIO] = {
 		.type = HDA_FIXUP_FUNC,
@@ -5125,24 +5181,33 @@
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc_fixup_headset_mode_alc668,
 	},
-	[ALC662_FIXUP_BASS_CHMAP] = {
+	[ALC662_FIXUP_BASS_MODE4_CHMAP] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc_fixup_bass_chmap,
 		.chained = true,
 		.chain_id = ALC662_FIXUP_ASUS_MODE4
 	},
+	[ALC662_FIXUP_BASS_16] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{0x16, 0x80106111}, /* bass speaker */
+			{}
+		},
+		.chained = true,
+		.chain_id = ALC662_FIXUP_BASS_CHMAP,
+	},
 	[ALC662_FIXUP_BASS_1A] = {
 		.type = HDA_FIXUP_PINS,
 		.v.pins = (const struct hda_pintbl[]) {
 			{0x1a, 0x80106111}, /* bass speaker */
 			{}
 		},
+		.chained = true,
+		.chain_id = ALC662_FIXUP_BASS_CHMAP,
 	},
-	[ALC662_FIXUP_BASS_1A_CHMAP] = {
+	[ALC662_FIXUP_BASS_CHMAP] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc_fixup_bass_chmap,
-		.chained = true,
-		.chain_id = ALC662_FIXUP_BASS_1A,
 	},
 };
 
@@ -5164,9 +5229,11 @@
 	SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
 	SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
-	SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A_CHMAP),
-	SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_CHMAP),
-	SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_CHMAP),
+	SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
+	SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
+	SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
+	SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
+	SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
 	SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
 	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
 	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
@@ -5307,7 +5374,7 @@
 		spec->gen.beep_nid = 0x01;
 
 	if ((alc_get_coef0(codec) & (1 << 14)) &&
-	    codec->bus->pci->subsystem_vendor == 0x1025 &&
+	    codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
 	    spec->cdefine.platform_type == 1) {
 		err = alc_codec_rename(codec, "ALC272X");
 		if (err < 0)
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index f84195f..7781662 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -465,14 +465,8 @@
 
 static void via_free(struct hda_codec *codec)
 {
-	struct via_spec *spec = codec->spec;
-
-	if (!spec)
-		return;
-
 	vt1708_stop_hp_work(codec);
-	snd_hda_gen_spec_free(&spec->gen);
-	kfree(spec);
+	snd_hda_gen_free(codec);
 }
 
 #ifdef CONFIG_PM
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 28ec872..99c022a0 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2639,8 +2639,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*r_ice1712 = ice;
 	return 0;
 }
@@ -2670,7 +2668,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 5004717..cf1ba11 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2609,8 +2609,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*r_ice1712 = ice;
 	return 0;
 }
@@ -2638,7 +2636,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 08d8733..ff24acf 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -3217,8 +3217,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*r_intel8x0 = chip;
 	return 0;
 }
@@ -3285,7 +3283,7 @@
 	int err;
 	struct shortname_table *name;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 3573c11..f8c72bd 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1243,8 +1243,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*r_intel8x0m = chip;
 	return 0;
 }
@@ -1283,7 +1281,7 @@
 	int err;
 	struct shortname_table *name;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 9cf9829..8f36d77 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2418,8 +2418,6 @@
 
         snd_korg1212_proc_init(korg1212);
         
-	snd_card_set_dev(card, &pci->dev);
-
         * rchip = korg1212;
 	return 0;
 
@@ -2445,7 +2443,8 @@
 		dev++;
 		return -ENOENT;
 	}
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
index 0568540..56d4f94 100644
--- a/sound/pci/lola/lola.c
+++ b/sound/pci/lola/lola.c
@@ -717,14 +717,13 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0) {
 		snd_printk(KERN_ERR SFX "Error creating card!\n");
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	err = lola_create(card, pci, dev, &chip);
 	if (err < 0)
 		goto out_free;
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c
index 5fcaaa6..b9743d4 100644
--- a/sound/pci/lx6464es/lx6464es.c
+++ b/sound/pci/lx6464es/lx6464es.c
@@ -1062,8 +1062,6 @@
 	if (err < 0)
 		return err;
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 	return 0;
 
@@ -1099,7 +1097,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c
index 626ecad..df4044d 100644
--- a/sound/pci/lx6464es/lx_core.c
+++ b/sound/pci/lx6464es/lx_core.c
@@ -141,63 +141,6 @@
 	iowrite32(data, address);
 }
 
-u32 lx_plx_mbox_read(struct lx6464es *chip, int mbox_nr)
-{
-	int index;
-
-	switch (mbox_nr) {
-	case 1:
-		index = ePLX_MBOX1;    break;
-	case 2:
-		index = ePLX_MBOX2;    break;
-	case 3:
-		index = ePLX_MBOX3;    break;
-	case 4:
-		index = ePLX_MBOX4;    break;
-	case 5:
-		index = ePLX_MBOX5;    break;
-	case 6:
-		index = ePLX_MBOX6;    break;
-	case 7:
-		index = ePLX_MBOX7;    break;
-	case 0:			/* reserved for HF flags */
-		snd_BUG();
-	default:
-		return 0xdeadbeef;
-	}
-
-	return lx_plx_reg_read(chip, index);
-}
-
-int lx_plx_mbox_write(struct lx6464es *chip, int mbox_nr, u32 value)
-{
-	int index = -1;
-
-	switch (mbox_nr) {
-	case 1:
-		index = ePLX_MBOX1;    break;
-	case 3:
-		index = ePLX_MBOX3;    break;
-	case 4:
-		index = ePLX_MBOX4;    break;
-	case 5:
-		index = ePLX_MBOX5;    break;
-	case 6:
-		index = ePLX_MBOX6;    break;
-	case 7:
-		index = ePLX_MBOX7;    break;
-	case 0:			/* reserved for HF flags */
-	case 2:			/* reserved for Pipe States
-				 * the DSP keeps an image of it */
-		snd_BUG();
-		return -EBADRQC;
-	}
-
-	lx_plx_reg_write(chip, index, value);
-	return 0;
-}
-
-
 /* rmh */
 
 #ifdef CONFIG_SND_DEBUG
@@ -491,33 +434,6 @@
 #define CSES_BROADCAST      0x0002
 #define CSES_UPDATE_LDSV    0x0004
 
-int lx_dsp_es_check_pipeline(struct lx6464es *chip)
-{
-	int i;
-
-	for (i = 0; i != CSES_TIMEOUT; ++i) {
-		/*
-		 * le bit CSES_UPDATE_LDSV est à 1 dés que le macprog
-		 * est pret. il re-passe à 0 lorsque le premier read a
-		 * été fait. pour l'instant on retire le test car ce bit
-		 * passe a 1 environ 200 à 400 ms aprés que le registre
-		 * confES à été écrit (kick du xilinx ES).
-		 *
-		 * On ne teste que le bit CE.
-		 * */
-
-		u32 cses = lx_dsp_reg_read(chip, eReg_CSES);
-
-		if ((cses & CSES_CE) == 0)
-			return 0;
-
-		udelay(1);
-	}
-
-	return -ETIMEDOUT;
-}
-
-
 #define PIPE_INFO_TO_CMD(capture, pipe)					\
 	((u32)((u32)(pipe) | ((capture) ? ID_IS_CAPTURE : 0L)) << ID_OFFSET)
 
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index d541736..076c3ec 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -2693,8 +2693,6 @@
 	snd_m3_enable_ints(chip);
 	snd_m3_assp_continue(chip);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*chip_ret = chip;
 
 	return 0; 
@@ -2721,7 +2719,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 1e0f6ee..9ab057b 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1028,8 +1028,6 @@
 	}
 
 	mgr->chip[idx] = chip;
-	snd_card_set_dev(card, &mgr->pci->dev);
-
 	return 0;
 }
 
@@ -1308,7 +1306,8 @@
 		else
 			idx = index[dev] + i;
 		snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : "MIXART", i);
-		err = snd_card_create(idx, tmpid, THIS_MODULE, 0, &card);
+		err = snd_card_new(&pci->dev, idx, tmpid, THIS_MODULE,
+				   0, &card);
 
 		if (err < 0) {
 			snd_printk(KERN_ERR "cannot allocate the card %d\n", i);
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index fe79fff..b7afd9c 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1626,8 +1626,6 @@
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
 		goto __error;
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*chip_ret = chip;
 	return 0;
 
@@ -1676,7 +1674,7 @@
 		}
 	}
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index b0cb48a..efa610c 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -595,7 +595,8 @@
 	const struct pci_device_id *pci_id;
 	int err;
 
-	err = snd_card_create(index, id, owner, sizeof(*chip), &card);
+	err = snd_card_new(&pci->dev, index, id, owner,
+			   sizeof(*chip), &card);
 	if (err < 0)
 		return err;
 
@@ -648,7 +649,6 @@
 	}
 
 	pci_set_master(pci);
-	snd_card_set_dev(card, &pci->dev);
 	card->private_free = oxygen_card_free;
 
 	configure_pcie_bridge(pci);
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index d379b28..3880f6d 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1239,7 +1239,6 @@
 	}
 
 	mgr->chip[idx] = chip;
-	snd_card_set_dev(card, &mgr->pci->dev);
 
 	return 0;
 }
@@ -1638,7 +1637,8 @@
 
 		snprintf(tmpid, sizeof(tmpid), "%s-%d",
 			 id[dev] ? id[dev] : card_name, i);
-		err = snd_card_create(idx, tmpid, THIS_MODULE, 0, &card);
+		err = snd_card_new(&pci->dev, idx, tmpid, THIS_MODULE,
+				   0, &card);
 
 		if (err < 0) {
 			snd_printk(KERN_ERR "cannot allocate the card %d\n", i);
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 56cc891..b4a8278 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1916,8 +1916,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 	return 0;
 }
@@ -2086,7 +2084,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 	err = snd_riptide_create(card, pci, &chip);
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index cc26346..77465cc 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -1938,15 +1938,14 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct rme32), &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct rme32), &card);
 	if (err < 0)
 		return err;
 	card->private_free = snd_rme32_card_free;
 	rme32 = (struct rme32 *) card->private_data;
 	rme32->card = card;
 	rme32->pci = pci;
-	snd_card_set_dev(card, &pci->dev);
         if (fullduplex[dev])
 		rme32->fullduplex_mode = 1;
 	if ((err = snd_rme32_create(rme32)) < 0) {
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 0236363..00d4611 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -2475,15 +2475,14 @@
 		dev++;
 		return -ENOENT;
 	}
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct rme96), &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct rme96), &card);
 	if (err < 0)
 		return err;
 	card->private_free = snd_rme96_card_free;
 	rme96 = card->private_data;
 	rme96->card = card;
 	rme96->pci = pci;
-	snd_card_set_dev(card, &pci->dev);
 	if ((err = snd_rme96_create(rme96)) < 0) {
 		snd_card_free(card);
 		return err;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index bd90c80..825fbbe 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -5375,8 +5375,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct hdsp), &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct hdsp), &card);
 	if (err < 0)
 		return err;
 
@@ -5384,7 +5384,6 @@
 	card->private_free = snd_hdsp_card_free;
 	hdsp->dev = dev;
 	hdsp->pci = pci;
-	snd_card_set_dev(card, &pci->dev);
 
 	if ((err = snd_hdsp_create(card, hdsp)) < 0) {
 		snd_card_free(card);
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index e98dc00..7601628 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -7016,8 +7016,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev],
-			THIS_MODULE, sizeof(struct hdspm), &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev],
+			   THIS_MODULE, sizeof(struct hdspm), &card);
 	if (err < 0)
 		return err;
 
@@ -7026,8 +7026,6 @@
 	hdspm->dev = dev;
 	hdspm->pci = pci;
 
-	snd_card_set_dev(card, &pci->dev);
-
 	err = snd_hdspm_create(card, hdspm);
 	if (err < 0) {
 		snd_card_free(card);
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index 1503ee3..a62d6e1 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -2587,8 +2587,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_rme9652), &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_rme9652), &card);
 
 	if (err < 0)
 		return err;
@@ -2597,7 +2597,6 @@
 	card->private_free = snd_rme9652_card_free;
 	rme9652->dev = dev;
 	rme9652->pci = pci;
-	snd_card_set_dev(card, &pci->dev);
 
 	if ((err = snd_rme9652_create(card, rme9652, precise_ptr[dev])) < 0) {
 		snd_card_free(card);
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index e413b4e..6b26b93 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -1404,8 +1404,6 @@
 	if (rc)
 		goto error_out_cleanup;
 
-	snd_card_set_dev(card, &pci->dev);
-
 	return 0;
 
 error_out_cleanup:
@@ -1440,7 +1438,8 @@
 	if (!codecs)
 		codecs = SIS_PRIMARY_CODEC_PRESENT;
 
-	rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card);
+	rc = snd_card_new(&pci->dev, index, id, THIS_MODULE,
+			  sizeof(*sis), &card);
 	if (rc < 0)
 		goto error_out;
 
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 2a46bf9..9ff408f 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1392,8 +1392,6 @@
 
 	snd_sonicvibes_proc_init(sonic);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rsonic = sonic;
 	return 0;
 }
@@ -1459,7 +1457,8 @@
 		return -ENOENT;
 	}
  
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 	for (idx = 0; idx < 5; idx++) {
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index b3b588b..d852458 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -89,7 +89,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index fb0e158..4f3c4be 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -3664,7 +3664,6 @@
 	snd_trident_enable_eso(trident);
 
 	snd_trident_proc_init(trident);
-	snd_card_set_dev(card, &pci->dev);
 	*rtrident = trident;
 	return 0;
 }
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 5ae6f04..20d2eee 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2441,8 +2441,6 @@
 	 * We call pci_set_master here because it does not hurt. */
 	pci_set_master(pci);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*r_via = chip;
 	return 0;
 }
@@ -2544,7 +2542,7 @@
 	unsigned int i;
 	int err;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index ca19028..5197401 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1161,8 +1161,6 @@
 	 * We call pci_set_master here because it does not hurt. */
 	pci_set_master(pci);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*r_via = chip;
 	return 0;
 }
@@ -1177,7 +1175,7 @@
 	unsigned int i;
 	int err;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index ab8a9b1..4323556 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -181,8 +181,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = vx;
 	return 0;
 }
@@ -204,7 +202,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index e8932b2..6ff4ea3 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -187,7 +187,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+			   0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index d591c15..c7e98ff 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2487,8 +2487,6 @@
 
 	snd_ymfpci_proc_init(card, chip);
 
-	snd_card_set_dev(card, &pci->dev);
-
 	*rchip = chip;
 	return 0;
 }
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 8f489de..56bda12 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -112,7 +112,8 @@
 		return -ENODEV; /* disabled explicitly */
 
 	/* ok, create a card instance */
-	err = snd_card_create(index[i], id[i], THIS_MODULE, 0, &card);
+	err = snd_card_new(&link->dev, index[i], id[i], THIS_MODULE,
+			   0, &card);
 	if (err < 0) {
 		snd_printk(KERN_ERR "pdacf: cannot create a card instance\n");
 		return err;
@@ -131,8 +132,6 @@
 		return err;
 	}
 
-	snd_card_set_dev(card, &link->dev);
-
 	pdacf->index = i;
 	card_list[i] = card;
 
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index d4db7ec..786e7e1 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -238,7 +238,6 @@
 		goto failed;
 
 	chip->dev = &link->dev;
-	snd_card_set_dev(chip->card, chip->dev);
 
 	if (snd_vxpocket_assign_resources(chip, link->resource[0]->start,
 						link->irq) < 0)
@@ -307,7 +306,8 @@
 		return -ENODEV; /* disabled explicitly */
 
 	/* ok, create a card instance */
-	err = snd_card_create(index[i], id[i], THIS_MODULE, 0, &card);
+	err = snd_card_new(&p_dev->dev, index[i], id[i], THIS_MODULE,
+			   0, &card);
 	if (err < 0) {
 		snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n");
 		return err;
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 8abb521..350a7c8f 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -58,7 +58,7 @@
 	char *name_ext;
 	int err;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&devptr->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
@@ -122,8 +122,6 @@
 	if (enable_beep)
 		snd_pmac_attach_beep(chip);
 
-	snd_card_set_dev(card, &devptr->dev);
-
 	if ((err = snd_card_register(card)) < 0)
 		goto __error;
 
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index ebb76f2..58f292a 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -984,7 +984,8 @@
 	}
 
 	/* create card instance */
-	ret = snd_card_create(index, id, THIS_MODULE, 0, &the_card.card);
+	ret = snd_card_new(&dev->core, index, id, THIS_MODULE,
+			   0, &the_card.card);
 	if (ret < 0)
 		goto clean_irq;
 
@@ -1052,7 +1053,6 @@
 	snd_ps3_init_avsetting(&the_card);
 
 	/* register the card */
-	snd_card_set_dev(the_card.card, &dev->core);
 	ret = snd_card_register(the_card.card);
 	if (ret < 0)
 		goto clean_dma_map;
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 78a3697..47849ea 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -608,8 +608,8 @@
 	dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL);
 	if (unlikely(!dreamcastcard))
 		return -ENOMEM;
-	err = snd_card_create(index, SND_AICA_DRIVER, THIS_MODULE, 0,
-			      &dreamcastcard->card);
+	err = snd_card_new(&devptr->dev, index, SND_AICA_DRIVER,
+			   THIS_MODULE, 0, &dreamcastcard->card);
 	if (unlikely(err < 0)) {
 		kfree(dreamcastcard);
 		return err;
@@ -624,7 +624,6 @@
 	err = snd_aicapcmchip(dreamcastcard, 0);
 	if (unlikely(err < 0))
 		goto freedreamcast;
-	snd_card_set_dev(dreamcastcard->card, &devptr->dev);
 	dreamcastcard->timer.data = 0;
 	dreamcastcard->channel = NULL;
 	/* Add basic controls */
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index 7c9422c..d1fb74d 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -396,7 +396,7 @@
 	struct snd_card *card;
 	int err;
 
-	err = snd_card_create(index, id, THIS_MODULE, 0, &card);
+	err = snd_card_new(&devptr->dev, index, id, THIS_MODULE, 0, &card);
 	if (err < 0) {
 			snd_printk(KERN_ERR "cannot allocate the card\n");
 			return err;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index fe1df50..135ddb0 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1654,7 +1654,7 @@
 	}
 
 	/* card bind complete so register a sound card */
-	ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+	ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
 			card->owner, 0, &card->snd_card);
 	if (ret < 0) {
 		dev_err(card->dev,
@@ -1662,7 +1662,6 @@
 			card->name, ret);
 		goto base_error;
 	}
-	card->snd_card->dev = card->dev;
 
 	card->dapm.bias_level = SND_SOC_BIAS_OFF;
 	card->dapm.dev = card->dev;
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index 174d21f..4a85e14 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -1019,8 +1019,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev_num], id[dev_num], THIS_MODULE, 0,
-			      &card);
+	err = snd_card_new(&op->dev, index[dev_num], id[dev_num],
+			   THIS_MODULE, 0, &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index dbb1b625..4e91bca 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -1565,7 +1565,8 @@
 
 static int dev;
 
-static int cs4231_attach_begin(struct snd_card **rcard)
+static int cs4231_attach_begin(struct platform_device *op,
+			       struct snd_card **rcard)
 {
 	struct snd_card *card;
 	struct snd_cs4231 *chip;
@@ -1581,8 +1582,8 @@
 		return -ENOENT;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_cs4231), &card);
+	err = snd_card_new(&op->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_cs4231), &card);
 	if (err < 0)
 		return err;
 
@@ -1869,7 +1870,7 @@
 	struct snd_card *card;
 	int err;
 
-	err = cs4231_attach_begin(&card);
+	err = cs4231_attach_begin(op, &card);
 	if (err)
 		return err;
 
@@ -2060,7 +2061,7 @@
 	struct snd_card *card;
 	int err;
 
-	err = cs4231_attach_begin(&card);
+	err = cs4231_attach_begin(op, &card);
 	if (err)
 		return err;
 
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index eee7afc..be1b1aa 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -2615,8 +2615,8 @@
 		return -ENODEV;
 	}
 
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct snd_dbri), &card);
+	err = snd_card_new(&op->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct snd_dbri), &card);
 	if (err < 0)
 		return err;
 
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index 25c38af..3952236 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -927,8 +927,6 @@
 	if (retval)
 		goto out_snd_dev;
 
-	snd_card_set_dev(card, &spi->dev);
-
 	goto out;
 
 out_snd_dev:
@@ -966,8 +964,8 @@
 
 	/* Allocate "card" using some unused identifiers. */
 	snprintf(id, sizeof id, "at73c213_%d", board->ssc_id);
-	retval = snd_card_create(-1, id, THIS_MODULE,
-				 sizeof(struct snd_at73c213), &card);
+	retval = snd_card_new(&spi->dev, -1, id, THIS_MODULE,
+			      sizeof(struct snd_at73c213), &card);
 	if (retval < 0)
 		goto out;
 
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index 66edc4a..e0fe0d9 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -124,8 +124,8 @@
 		snd_printk(KERN_ERR PREFIX "can't set first interface.\n");
 		return -EIO;
 	}
-	ret = snd_card_create(index[regidx], id[regidx], THIS_MODULE,
-			sizeof(struct sfire_chip), &card);
+	ret = snd_card_new(&intf->dev, index[regidx], id[regidx],
+			   THIS_MODULE, sizeof(struct sfire_chip), &card);
 	if (ret < 0) {
 		snd_printk(KERN_ERR PREFIX "cannot create alsa card.\n");
 		return ret;
@@ -134,7 +134,6 @@
 	strcpy(card->shortname, "TerraTec DMX6FireUSB");
 	sprintf(card->longname, "%s at %d:%d", card->shortname,
 			device->bus->busnum, device->devnum);
-	snd_card_set_dev(card, &intf->dev);
 
 	chip = card->private_data;
 	chips[regidx] = chip;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index bc55f70..b871ba4 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -418,8 +418,9 @@
 	if (devnum >= SNDRV_CARDS)
 		return -ENODEV;
 
-	err = snd_card_create(index[devnum], id[devnum], THIS_MODULE,
-			      sizeof(struct snd_usb_caiaqdev), &card);
+	err = snd_card_new(&intf->dev,
+			   index[devnum], id[devnum], THIS_MODULE,
+			   sizeof(struct snd_usb_caiaqdev), &card);
 	if (err < 0)
 		return err;
 
@@ -429,7 +430,6 @@
 	cdev->chip.usb_id = USB_ID(le16_to_cpu(usb_dev->descriptor.idVendor),
 				  le16_to_cpu(usb_dev->descriptor.idProduct));
 	spin_lock_init(&cdev->spinlock);
-	snd_card_set_dev(card, &intf->dev);
 
 	*cardp = card;
 	return 0;
diff --git a/sound/usb/card.c b/sound/usb/card.c
index d979050..0cfdc2d 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -328,7 +328,8 @@
 /*
  * create a chip instance and set its names.
  */
-static int snd_usb_audio_create(struct usb_device *dev, int idx,
+static int snd_usb_audio_create(struct usb_interface *intf,
+				struct usb_device *dev, int idx,
 				const struct snd_usb_audio_quirk *quirk,
 				struct snd_usb_audio **rchip)
 {
@@ -354,7 +355,8 @@
 		return -ENXIO;
 	}
 
-	err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
+	err = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE,
+			   0, &card);
 	if (err < 0) {
 		snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
 		return err;
@@ -513,10 +515,10 @@
 			if (enable[i] && ! usb_chip[i] &&
 			    (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
 			    (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
-				if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
+				if (snd_usb_audio_create(intf, dev, i, quirk,
+							 &chip) < 0) {
 					goto __error;
 				}
-				snd_card_set_dev(chip->card, &intf->dev);
 				chip->pm_intf = intf;
 				break;
 			}
@@ -691,12 +693,12 @@
 	}
 
 	list_for_each_entry(mixer, &chip->mixer_list, list)
-		snd_usb_mixer_inactivate(mixer);
+		snd_usb_mixer_suspend(mixer);
 
 	return 0;
 }
 
-static int usb_audio_resume(struct usb_interface *intf)
+static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume)
 {
 	struct snd_usb_audio *chip = usb_get_intfdata(intf);
 	struct usb_mixer_interface *mixer;
@@ -711,7 +713,7 @@
 	 * we just notify and restart the mixers
 	 */
 	list_for_each_entry(mixer, &chip->mixer_list, list) {
-		err = snd_usb_mixer_activate(mixer);
+		err = snd_usb_mixer_resume(mixer, reset_resume);
 		if (err < 0)
 			goto err_out;
 	}
@@ -723,9 +725,20 @@
 err_out:
 	return err;
 }
+
+static int usb_audio_resume(struct usb_interface *intf)
+{
+	return __usb_audio_resume(intf, false);
+}
+
+static int usb_audio_reset_resume(struct usb_interface *intf)
+{
+	return __usb_audio_resume(intf, true);
+}
 #else
 #define usb_audio_suspend	NULL
 #define usb_audio_resume	NULL
+#define usb_audio_reset_resume	NULL
 #endif		/* CONFIG_PM */
 
 static struct usb_device_id usb_audio_ids [] = {
@@ -747,6 +760,7 @@
 	.disconnect =	usb_audio_disconnect,
 	.suspend =	usb_audio_suspend,
 	.resume =	usb_audio_resume,
+	.reset_resume =	usb_audio_reset_resume,
 	.id_table =	usb_audio_ids,
 	.supports_autosuspend = 1,
 };
diff --git a/sound/usb/hiface/chip.c b/sound/usb/hiface/chip.c
index b0dcb39..2670d646 100644
--- a/sound/usb/hiface/chip.c
+++ b/sound/usb/hiface/chip.c
@@ -64,7 +64,8 @@
 	u8 extra_freq;
 };
 
-static int hiface_chip_create(struct usb_device *device, int idx,
+static int hiface_chip_create(struct usb_interface *intf,
+			      struct usb_device *device, int idx,
 			      const struct hiface_vendor_quirk *quirk,
 			      struct hiface_chip **rchip)
 {
@@ -76,7 +77,8 @@
 	*rchip = NULL;
 
 	/* if we are here, card can be registered in alsa. */
-	ret = snd_card_create(index[idx], id[idx], THIS_MODULE, sizeof(*chip), &card);
+	ret = snd_card_new(&intf->dev, index[idx], id[idx], THIS_MODULE,
+			   sizeof(*chip), &card);
 	if (ret < 0) {
 		dev_err(&device->dev, "cannot create alsa card.\n");
 		return ret;
@@ -132,12 +134,10 @@
 		goto err;
 	}
 
-	ret = hiface_chip_create(device, i, quirk, &chip);
+	ret = hiface_chip_create(intf, device, i, quirk, &chip);
 	if (ret < 0)
 		goto err;
 
-	snd_card_set_dev(chip->card, &intf->dev);
-
 	ret = hiface_pcm_init(chip, quirk ? quirk->extra_freq : 0);
 	if (ret < 0)
 		goto err_chip_destroy;
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index 5093159..a1bab14 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -1243,8 +1243,9 @@
 		mutex_unlock(&devices_mutex);
 		return -ENOENT;
 	}
-	err = snd_card_create(index[card_index], id[card_index], THIS_MODULE,
-			      sizeof(*ua), &card);
+	err = snd_card_new(&interface->dev,
+			   index[card_index], id[card_index], THIS_MODULE,
+			   sizeof(*ua), &card);
 	if (err < 0) {
 		mutex_unlock(&devices_mutex);
 		return err;
@@ -1283,8 +1284,6 @@
 		}
 	}
 
-	snd_card_set_dev(card, &interface->dev);
-
 	err = detect_usb_format(ua);
 	if (err < 0)
 		goto probe_error;
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 44b0ba4..8c152b0 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2299,26 +2299,6 @@
 	}
 }
 
-/* stop any bus activity of a mixer */
-void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
-{
-	usb_kill_urb(mixer->urb);
-	usb_kill_urb(mixer->rc_urb);
-}
-
-int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
-{
-	int err;
-
-	if (mixer->urb) {
-		err = usb_submit_urb(mixer->urb, GFP_NOIO);
-		if (err < 0)
-			return err;
-	}
-
-	return 0;
-}
-
 /* create the handler for the optional status interrupt endpoint */
 static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
 {
@@ -2393,7 +2373,7 @@
 
 	snd_usb_mixer_apply_create_quirk(mixer);
 
-	err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
+	err = snd_device_new(chip->card, SNDRV_DEV_CODEC, mixer, &dev_ops);
 	if (err < 0)
 		goto _error;
 
@@ -2417,3 +2397,82 @@
 	usb_kill_urb(mixer->urb);
 	usb_kill_urb(mixer->rc_urb);
 }
+
+#ifdef CONFIG_PM
+/* stop any bus activity of a mixer */
+static void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer)
+{
+	usb_kill_urb(mixer->urb);
+	usb_kill_urb(mixer->rc_urb);
+}
+
+static int snd_usb_mixer_activate(struct usb_mixer_interface *mixer)
+{
+	int err;
+
+	if (mixer->urb) {
+		err = usb_submit_urb(mixer->urb, GFP_NOIO);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer)
+{
+	snd_usb_mixer_inactivate(mixer);
+	return 0;
+}
+
+static int restore_mixer_value(struct usb_mixer_elem_info *cval)
+{
+	int c, err, idx;
+
+	if (cval->cmask) {
+		idx = 0;
+		for (c = 0; c < MAX_CHANNELS; c++) {
+			if (!(cval->cmask & (1 << c)))
+				continue;
+			if (cval->cached & (1 << c)) {
+				err = set_cur_mix_value(cval, c + 1, idx,
+							cval->cache_val[idx]);
+				if (err < 0)
+					return err;
+			}
+			idx++;
+		}
+	} else {
+		/* master */
+		if (cval->cached) {
+			err = set_cur_mix_value(cval, 0, 0, *cval->cache_val);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	return 0;
+}
+
+int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume)
+{
+	struct usb_mixer_elem_info *cval;
+	int id, err;
+
+	/* FIXME: any mixer quirks? */
+
+	if (reset_resume) {
+		/* restore cached mixer values */
+		for (id = 0; id < MAX_ID_ELEMS; id++) {
+			for (cval = mixer->id_elems[id]; cval;
+			     cval = cval->next_id_elem) {
+				err = restore_mixer_value(cval);
+				if (err < 0)
+					return err;
+			}
+		}
+	}
+
+	return snd_usb_mixer_activate(mixer);
+}
+#endif
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index aab80df..73b1f64 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -63,8 +63,6 @@
 
 int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
 				int request, int validx, int value_set);
-void snd_usb_mixer_inactivate(struct usb_mixer_interface *mixer);
-int snd_usb_mixer_activate(struct usb_mixer_interface *mixer);
 
 int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer,
 			      struct snd_kcontrol *kctl);
@@ -72,4 +70,9 @@
 int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
 			  unsigned int size, unsigned int __user *_tlv);
 
+#ifdef CONFIG_PM
+int snd_usb_mixer_suspend(struct usb_mixer_interface *mixer);
+int snd_usb_mixer_resume(struct usb_mixer_interface *mixer, bool reset_resume);
+#endif
+
 #endif /* __USBMIXER_H */
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 999550b..cf5dc33 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -535,7 +535,9 @@
 		snd_us122l_card_used[index] = 0;
 }
 
-static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
+static int usx2y_create_card(struct usb_device *device,
+			     struct usb_interface *intf,
+			     struct snd_card **cardp)
 {
 	int		dev;
 	struct snd_card *card;
@@ -546,8 +548,8 @@
 			break;
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct us122l), &card);
+	err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct us122l), &card);
 	if (err < 0)
 		return err;
 	snd_us122l_card_used[US122L(card)->card_index = dev] = 1;
@@ -578,11 +580,10 @@
 	struct snd_card *card;
 	int err;
 
-	err = usx2y_create_card(device, &card);
+	err = usx2y_create_card(device, intf, &card);
 	if (err < 0)
 		return err;
 
-	snd_card_set_dev(card, &intf->dev);
 	if (!us122l_create_card(card)) {
 		snd_card_free(card);
 		return -EINVAL;
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 5a51b18..91e0e2a 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -332,7 +332,9 @@
 	{ /* terminator */ }
 };
 
-static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
+static int usX2Y_create_card(struct usb_device *device,
+			     struct usb_interface *intf,
+			     struct snd_card **cardp)
 {
 	int		dev;
 	struct snd_card *	card;
@@ -343,15 +345,15 @@
 			break;
 	if (dev >= SNDRV_CARDS)
 		return -ENODEV;
-	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
-			      sizeof(struct usX2Ydev), &card);
+	err = snd_card_new(&intf->dev, index[dev], id[dev], THIS_MODULE,
+			   sizeof(struct usX2Ydev), &card);
 	if (err < 0)
 		return err;
 	snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;
 	card->private_free = snd_usX2Y_card_private_free;
 	usX2Y(card)->dev = device;
 	init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
-	mutex_init(&usX2Y(card)->prepare_mutex);
+	mutex_init(&usX2Y(card)->pcm_mutex);
 	INIT_LIST_HEAD(&usX2Y(card)->midi_list);
 	strcpy(card->driver, "USB "NAME_ALLCAPS"");
 	sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
@@ -382,10 +384,9 @@
 	     le16_to_cpu(device->descriptor.idProduct) != USB_ID_US428))
 		return -EINVAL;
 
-	err = usX2Y_create_card(device, &card);
+	err = usX2Y_create_card(device, intf, &card);
 	if (err < 0)
 		return err;
-	snd_card_set_dev(card, &intf->dev);
 	if ((err = usX2Y_hwdep_new(card, device)) < 0  ||
 	    (err = snd_card_register(card)) < 0) {
 		snd_card_free(card);
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index e43c0a8..6ae6b08 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -36,7 +36,7 @@
 	unsigned int		rate,
 				format;
 	int			chip_status;
-	struct mutex		prepare_mutex;
+	struct mutex		pcm_mutex;
 	struct us428ctls_sharedmem	*us428ctls_sharedmem;
 	int			wait_iso_frame;
 	wait_queue_head_t	us428ctls_wait_queue_head;
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 6234a51..a63330d 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -752,36 +752,44 @@
 	unsigned int		rate = params_rate(hw_params);
 	snd_pcm_format_t	format = params_format(hw_params);
 	struct snd_card *card = substream->pstr->pcm->card;
-	struct list_head *list;
+	struct usX2Ydev	*dev = usX2Y(card);
+	int i;
 
+	mutex_lock(&usX2Y(card)->pcm_mutex);
 	snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
-	// all pcm substreams off one usX2Y have to operate at the same rate & format
-	list_for_each(list, &card->devices) {
-		struct snd_device *dev;
-		struct snd_pcm *pcm;
-		int s;
-		dev = snd_device(list);
-		if (dev->type != SNDRV_DEV_PCM)
+	/* all pcm substreams off one usX2Y have to operate at the same
+	 * rate & format
+	 */
+	for (i = 0; i < dev->pcm_devs * 2; i++) {
+		struct snd_usX2Y_substream *subs = dev->subs[i];
+		struct snd_pcm_substream *test_substream;
+
+		if (!subs)
 			continue;
-		pcm = dev->device_data;
-		for (s = 0; s < 2; ++s) {
-			struct snd_pcm_substream *test_substream;
-			test_substream = pcm->streams[s].substream;
-			if (test_substream && test_substream != substream  &&
-			    test_substream->runtime &&
-			    ((test_substream->runtime->format &&
-			      test_substream->runtime->format != format) ||
-			     (test_substream->runtime->rate &&
-			      test_substream->runtime->rate != rate)))
-				return -EINVAL;
+		test_substream = subs->pcm_substream;
+		if (!test_substream || test_substream == substream ||
+		    !test_substream->runtime)
+			continue;
+		if ((test_substream->runtime->format &&
+		     test_substream->runtime->format != format) ||
+		    (test_substream->runtime->rate &&
+		     test_substream->runtime->rate != rate)) {
+			err = -EINVAL;
+			goto error;
 		}
 	}
-	if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
+
+	err = snd_pcm_lib_malloc_pages(substream,
+				       params_buffer_bytes(hw_params));
+	if (err < 0) {
 		snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n",
 			   substream, params_buffer_bytes(hw_params), err);
-		return err;
+		goto error;
 	}
-	return 0;
+
+ error:
+	mutex_unlock(&usX2Y(card)->pcm_mutex);
+	return err;
 }
 
 /*
@@ -791,7 +799,7 @@
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_usX2Y_substream *subs = runtime->private_data;
-	mutex_lock(&subs->usX2Y->prepare_mutex);
+	mutex_lock(&subs->usX2Y->pcm_mutex);
 	snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
 
 	if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
@@ -812,7 +820,7 @@
 			usX2Y_urbs_release(subs);
 		}
 	}
-	mutex_unlock(&subs->usX2Y->prepare_mutex);
+	mutex_unlock(&subs->usX2Y->pcm_mutex);
 	return snd_pcm_lib_free_pages(substream);
 }
 /*
@@ -829,7 +837,7 @@
 	int err = 0;
 	snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
 
-	mutex_lock(&usX2Y->prepare_mutex);
+	mutex_lock(&usX2Y->pcm_mutex);
 	usX2Y_subs_prepare(subs);
 // Start hardware streams
 // SyncStream first....
@@ -849,7 +857,7 @@
 		err = usX2Y_urbs_start(subs);
 
  up_prepare_mutex:
-	mutex_unlock(&usX2Y->prepare_mutex);
+	mutex_unlock(&usX2Y->pcm_mutex);
 	return err;
 }
 
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 814d0e8..90766a9 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -358,7 +358,7 @@
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_usX2Y_substream *subs = runtime->private_data,
 		*cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
-	mutex_lock(&subs->usX2Y->prepare_mutex);
+	mutex_lock(&subs->usX2Y->pcm_mutex);
 	snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
 
 	if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
@@ -387,7 +387,7 @@
 				usX2Y_usbpcm_urbs_release(cap_subs2);
 		}
 	}
-	mutex_unlock(&subs->usX2Y->prepare_mutex);
+	mutex_unlock(&subs->usX2Y->pcm_mutex);
 	return snd_pcm_lib_free_pages(substream);
 }
 
@@ -493,7 +493,7 @@
 		memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
 	}
 
-	mutex_lock(&usX2Y->prepare_mutex);
+	mutex_lock(&usX2Y->pcm_mutex);
 	usX2Y_subs_prepare(subs);
 // Start hardware streams
 // SyncStream first....
@@ -534,7 +534,7 @@
 		usX2Y->hwdep_pcm_shm->capture_iso_start = -1;
 
  up_prepare_mutex:
-	mutex_unlock(&usX2Y->prepare_mutex);
+	mutex_unlock(&usX2Y->pcm_mutex);
 	return err;
 }
 
@@ -600,59 +600,30 @@
 };
 
 
-static int usX2Y_pcms_lock_check(struct snd_card *card)
+static int usX2Y_pcms_busy_check(struct snd_card *card)
 {
-	struct list_head *list;
-	struct snd_device *dev;
-	struct snd_pcm *pcm;
-	int err = 0;
-	list_for_each(list, &card->devices) {
-		dev = snd_device(list);
-		if (dev->type != SNDRV_DEV_PCM)
-			continue;
-		pcm = dev->device_data;
-		mutex_lock(&pcm->open_mutex);
+	struct usX2Ydev	*dev = usX2Y(card);
+	int i;
+
+	for (i = 0; i < dev->pcm_devs * 2; i++) {
+		struct snd_usX2Y_substream *subs = dev->subs[i];
+		if (subs && subs->pcm_substream &&
+		    SUBSTREAM_BUSY(subs->pcm_substream))
+			return -EBUSY;
 	}
-	list_for_each(list, &card->devices) {
-		int s;
-		dev = snd_device(list);
-		if (dev->type != SNDRV_DEV_PCM)
-			continue;
-		pcm = dev->device_data;
-		for (s = 0; s < 2; ++s) {
-			struct snd_pcm_substream *substream;
-			substream = pcm->streams[s].substream;
-			if (substream && SUBSTREAM_BUSY(substream))
-				err = -EBUSY;
-		}
-	}
-	return err;
+	return 0;
 }
 
-
-static void usX2Y_pcms_unlock(struct snd_card *card)
-{
-	struct list_head *list;
-	struct snd_device *dev;
-	struct snd_pcm *pcm;
-	list_for_each(list, &card->devices) {
-		dev = snd_device(list);
-		if (dev->type != SNDRV_DEV_PCM)
-			continue;
-		pcm = dev->device_data;
-		mutex_unlock(&pcm->open_mutex);
-	}
-}
-
-
 static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
 {
-	// we need to be the first 
 	struct snd_card *card = hw->card;
-	int err = usX2Y_pcms_lock_check(card);
-	if (0 == err)
+	int err;
+
+	mutex_lock(&usX2Y(card)->pcm_mutex);
+	err = usX2Y_pcms_busy_check(card);
+	if (!err)
 		usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
-	usX2Y_pcms_unlock(card);
+	mutex_unlock(&usX2Y(card)->pcm_mutex);
 	return err;
 }
 
@@ -660,10 +631,13 @@
 static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
 {
 	struct snd_card *card = hw->card;
-	int err = usX2Y_pcms_lock_check(card);
-	if (0 == err)
+	int err;
+
+	mutex_lock(&usX2Y(card)->pcm_mutex);
+	err = usX2Y_pcms_busy_check(card);
+	if (!err)
 		usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
-	usX2Y_pcms_unlock(card);
+	mutex_unlock(&usX2Y(card)->pcm_mutex);
 	return err;
 }