瀏覽代碼

Merge branch 'topic/misc' into for-linus

Takashi Iwai 14 年之前
父節點
當前提交
7d339ae997
共有 100 個文件被更改,包括 1236 次插入923 次删除
  1. 5 5
      Documentation/DocBook/writing-an-alsa-driver.tmpl
  2. 1 0
      include/linux/pci_ids.h
  3. 3 1
      include/sound/rawmidi.h
  4. 15 30
      sound/core/rawmidi.c
  5. 1 1
      sound/firewire/speakers.c
  6. 2 2
      sound/pci/ad1889.c
  7. 2 2
      sound/pci/ali5451/ali5451.c
  8. 2 2
      sound/pci/als300.c
  9. 1 1
      sound/pci/als4000.c
  10. 66 15
      sound/pci/asihpi/asihpi.c
  11. 15 9
      sound/pci/asihpi/hpi.h
  12. 4 7
      sound/pci/asihpi/hpi6000.c
  13. 15 37
      sound/pci/asihpi/hpi6205.c
  14. 19 6
      sound/pci/asihpi/hpi6205.h
  15. 41 114
      sound/pci/asihpi/hpi_internal.h
  16. 9 8
      sound/pci/asihpi/hpicmn.c
  17. 54 82
      sound/pci/asihpi/hpidspcd.c
  18. 39 33
      sound/pci/asihpi/hpidspcd.h
  19. 41 45
      sound/pci/asihpi/hpifunc.c
  20. 2 2
      sound/pci/asihpi/hpimsginit.c
  21. 2 4
      sound/pci/asihpi/hpimsgx.c
  22. 3 7
      sound/pci/asihpi/hpioctl.c
  23. 0 8
      sound/pci/asihpi/hpios.c
  24. 1 0
      sound/pci/asihpi/hpios.h
  25. 2 2
      sound/pci/atiixp.c
  26. 2 2
      sound/pci/atiixp_modem.c
  27. 2 2
      sound/pci/au88x0/au88x0.c
  28. 2 2
      sound/pci/aw2/aw2-alsa.c
  29. 2 2
      sound/pci/azt3328.c
  30. 2 2
      sound/pci/bt87x.c
  31. 2 2
      sound/pci/ca0106/ca0106_main.c
  32. 2 2
      sound/pci/cmipci.c
  33. 2 2
      sound/pci/cs4281.c
  34. 1 1
      sound/pci/cs46xx/cs46xx.c
  35. 1 1
      sound/pci/cs46xx/cs46xx_lib.c
  36. 1 1
      sound/pci/cs5530.c
  37. 2 2
      sound/pci/cs5535audio/cs5535audio.c
  38. 1 0
      sound/pci/ctxfi/ct20k2reg.h
  39. 71 36
      sound/pci/ctxfi/ctatc.c
  40. 7 1
      sound/pci/ctxfi/ctatc.h
  41. 7 16
      sound/pci/ctxfi/ctdaio.c
  42. 1 0
      sound/pci/ctxfi/ctdaio.h
  43. 13 1
      sound/pci/ctxfi/cthardware.h
  44. 11 4
      sound/pci/ctxfi/cthw20k1.c
  45. 240 97
      sound/pci/ctxfi/cthw20k2.c
  46. 112 33
      sound/pci/ctxfi/ctmixer.c
  47. 3 3
      sound/pci/ctxfi/xfi.c
  48. 3 3
      sound/pci/echoaudio/echoaudio.c
  49. 1 1
      sound/pci/emu10k1/emu10k1.c
  50. 1 1
      sound/pci/emu10k1/emu10k1_main.c
  51. 2 2
      sound/pci/emu10k1/emu10k1x.c
  52. 2 2
      sound/pci/ens1370.c
  53. 3 3
      sound/pci/es1938.c
  54. 13 55
      sound/pci/es1968.c
  55. 2 2
      sound/pci/fm801.c
  56. 4 6
      sound/pci/hda/hda_codec.c
  57. 2 2
      sound/pci/hda/hda_intel.c
  58. 2 2
      sound/pci/ice1712/ice1712.c
  59. 2 2
      sound/pci/ice1712/ice1724.c
  60. 9 3
      sound/pci/intel8x0.c
  61. 3 3
      sound/pci/intel8x0m.c
  62. 2 2
      sound/pci/korg1212/korg1212.c
  63. 2 2
      sound/pci/lola/lola.c
  64. 1 1
      sound/pci/lola/lola.h
  65. 93 37
      sound/pci/lola/lola_mixer.c
  66. 15 10
      sound/pci/lx6464es/lx6464es.c
  67. 2 0
      sound/pci/lx6464es/lx6464es.h
  68. 7 7
      sound/pci/lx6464es/lx_core.c
  69. 1 1
      sound/pci/lx6464es/lx_core.h
  70. 14 61
      sound/pci/maestro3.c
  71. 2 2
      sound/pci/mixart/mixart.c
  72. 2 2
      sound/pci/nm256/nm256.c
  73. 1 1
      sound/pci/oxygen/oxygen.c
  74. 1 1
      sound/pci/oxygen/oxygen_lib.c
  75. 0 6
      sound/pci/oxygen/oxygen_pcm.c
  76. 1 1
      sound/pci/oxygen/virtuoso.c
  77. 4 1
      sound/pci/oxygen/xonar_pcm179x.c
  78. 2 2
      sound/pci/pcxhr/pcxhr.c
  79. 3 3
      sound/pci/riptide/riptide.c
  80. 2 2
      sound/pci/rme32.c
  81. 2 2
      sound/pci/rme96.c
  82. 2 2
      sound/pci/rme9652/hdsp.c
  83. 2 2
      sound/pci/rme9652/hdspm.c
  84. 2 2
      sound/pci/rme9652/rme9652.c
  85. 3 3
      sound/pci/sis7019.c
  86. 2 2
      sound/pci/sonicvibes.c
  87. 1 1
      sound/pci/trident/trident.c
  88. 1 1
      sound/pci/trident/trident_main.c
  89. 2 2
      sound/pci/via82xx.c
  90. 2 2
      sound/pci/via82xx_modem.c
  91. 2 2
      sound/pci/vx222/vx222.c
  92. 1 1
      sound/pci/ymfpci/ymfpci.c
  93. 1 1
      sound/pci/ymfpci/ymfpci_main.c
  94. 1 1
      sound/pcmcia/pdaudiocf/pdaudiocf.c
  95. 1 1
      sound/pcmcia/vx/vxpocket.c
  96. 8 8
      sound/usb/card.c
  97. 2 0
      sound/usb/endpoint.c
  98. 1 1
      sound/usb/misc/ua101.c
  99. 30 0
      sound/usb/quirks-table.h
  100. 134 25
      sound/usb/quirks.c

+ 5 - 5
Documentation/DocBook/writing-an-alsa-driver.tmpl

@@ -1164,7 +1164,7 @@
           }
           }
           chip->port = pci_resource_start(pci, 0);
           chip->port = pci_resource_start(pci, 0);
           if (request_irq(pci->irq, snd_mychip_interrupt,
           if (request_irq(pci->irq, snd_mychip_interrupt,
-                          IRQF_SHARED, "My Chip", chip)) {
+                          IRQF_SHARED, KBUILD_MODNAME, chip)) {
                   printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
                   printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
                   snd_mychip_free(chip);
                   snd_mychip_free(chip);
                   return -EBUSY;
                   return -EBUSY;
@@ -1197,7 +1197,7 @@
 
 
   /* pci_driver definition */
   /* pci_driver definition */
   static struct pci_driver driver = {
   static struct pci_driver driver = {
-          .name = "My Own Chip",
+          .name = KBUILD_MODNAME,
           .id_table = snd_mychip_ids,
           .id_table = snd_mychip_ids,
           .probe = snd_mychip_probe,
           .probe = snd_mychip_probe,
           .remove = __devexit_p(snd_mychip_remove),
           .remove = __devexit_p(snd_mychip_remove),
@@ -1340,7 +1340,7 @@
           <programlisting>
           <programlisting>
 <![CDATA[
 <![CDATA[
   if (request_irq(pci->irq, snd_mychip_interrupt,
   if (request_irq(pci->irq, snd_mychip_interrupt,
-                  IRQF_SHARED, "My Chip", chip)) {
+                  IRQF_SHARED, KBUILD_MODNAME, chip)) {
           printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
           printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
           snd_mychip_free(chip);
           snd_mychip_free(chip);
           return -EBUSY;
           return -EBUSY;
@@ -1616,7 +1616,7 @@
           <programlisting>
           <programlisting>
 <![CDATA[
 <![CDATA[
   static struct pci_driver driver = {
   static struct pci_driver driver = {
-          .name = "My Own Chip",
+          .name = KBUILD_MODNAME,
           .id_table = snd_mychip_ids,
           .id_table = snd_mychip_ids,
           .probe = snd_mychip_probe,
           .probe = snd_mychip_probe,
           .remove = __devexit_p(snd_mychip_remove),
           .remove = __devexit_p(snd_mychip_remove),
@@ -5816,7 +5816,7 @@ struct _snd_pcm_runtime {
         <programlisting>
         <programlisting>
 <![CDATA[
 <![CDATA[
   static struct pci_driver driver = {
   static struct pci_driver driver = {
-          .name = "My Chip",
+          .name = KBUILD_MODNAME,
           .id_table = snd_my_ids,
           .id_table = snd_my_ids,
           .probe = snd_my_probe,
           .probe = snd_my_probe,
           .remove = __devexit_p(snd_my_remove),
           .remove = __devexit_p(snd_my_remove),

+ 1 - 0
include/linux/pci_ids.h

@@ -1308,6 +1308,7 @@
 #define PCI_SUBDEVICE_ID_CREATIVE_SB08801	0x0041
 #define PCI_SUBDEVICE_ID_CREATIVE_SB08801	0x0041
 #define PCI_SUBDEVICE_ID_CREATIVE_SB08802	0x0042
 #define PCI_SUBDEVICE_ID_CREATIVE_SB08802	0x0042
 #define PCI_SUBDEVICE_ID_CREATIVE_SB08803	0x0043
 #define PCI_SUBDEVICE_ID_CREATIVE_SB08803	0x0043
+#define PCI_SUBDEVICE_ID_CREATIVE_SB1270	0x0062
 #define PCI_SUBDEVICE_ID_CREATIVE_HENDRIX	0x6000
 #define PCI_SUBDEVICE_ID_CREATIVE_HENDRIX	0x6000
 
 
 #define PCI_VENDOR_ID_ECTIVA		0x1102 /* duplicate: CREATIVE */
 #define PCI_VENDOR_ID_ECTIVA		0x1102 /* duplicate: CREATIVE */

+ 3 - 1
include/sound/rawmidi.h

@@ -27,6 +27,7 @@
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
 #include <linux/wait.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
+#include <linux/workqueue.h>
 
 
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
 #include "seq_device.h"
 #include "seq_device.h"
@@ -63,6 +64,7 @@ struct snd_rawmidi_global_ops {
 };
 };
 
 
 struct snd_rawmidi_runtime {
 struct snd_rawmidi_runtime {
+	struct snd_rawmidi_substream *substream;
 	unsigned int drain: 1,	/* drain stage */
 	unsigned int drain: 1,	/* drain stage */
 		     oss: 1;	/* OSS compatible mode */
 		     oss: 1;	/* OSS compatible mode */
 	/* midi stream buffer */
 	/* midi stream buffer */
@@ -79,7 +81,7 @@ struct snd_rawmidi_runtime {
 	/* event handler (new bytes, input only) */
 	/* event handler (new bytes, input only) */
 	void (*event)(struct snd_rawmidi_substream *substream);
 	void (*event)(struct snd_rawmidi_substream *substream);
 	/* defers calls to event [input] or ops->trigger [output] */
 	/* defers calls to event [input] or ops->trigger [output] */
-	struct tasklet_struct tasklet;
+	struct work_struct event_work;
 	/* private data */
 	/* private data */
 	void *private_data;
 	void *private_data;
 	void (*private_free)(struct snd_rawmidi_substream *substream);
 	void (*private_free)(struct snd_rawmidi_substream *substream);

+ 15 - 30
sound/core/rawmidi.c

@@ -92,16 +92,12 @@ static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substre
 	       (!substream->append || runtime->avail >= count);
 	       (!substream->append || runtime->avail >= count);
 }
 }
 
 
-static void snd_rawmidi_input_event_tasklet(unsigned long data)
+static void snd_rawmidi_input_event_work(struct work_struct *work)
 {
 {
-	struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
-	substream->runtime->event(substream);
-}
-
-static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
-{
-	struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
-	substream->ops->trigger(substream, 1);
+	struct snd_rawmidi_runtime *runtime =
+		container_of(work, struct snd_rawmidi_runtime, event_work);
+	if (runtime->event)
+		runtime->event(runtime->substream);
 }
 }
 
 
 static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
 static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
@@ -110,16 +106,10 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
 
 
 	if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
 	if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
+	runtime->substream = substream;
 	spin_lock_init(&runtime->lock);
 	spin_lock_init(&runtime->lock);
 	init_waitqueue_head(&runtime->sleep);
 	init_waitqueue_head(&runtime->sleep);
-	if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
-		tasklet_init(&runtime->tasklet,
-			     snd_rawmidi_input_event_tasklet,
-			     (unsigned long)substream);
-	else
-		tasklet_init(&runtime->tasklet,
-			     snd_rawmidi_output_trigger_tasklet,
-			     (unsigned long)substream);
+	INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
 	runtime->event = NULL;
 	runtime->event = NULL;
 	runtime->buffer_size = PAGE_SIZE;
 	runtime->buffer_size = PAGE_SIZE;
 	runtime->avail_min = 1;
 	runtime->avail_min = 1;
@@ -150,12 +140,7 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
 {
 {
 	if (!substream->opened)
 	if (!substream->opened)
 		return;
 		return;
-	if (up) {
-		tasklet_schedule(&substream->runtime->tasklet);
-	} else {
-		tasklet_kill(&substream->runtime->tasklet);
-		substream->ops->trigger(substream, 0);
-	}
+	substream->ops->trigger(substream, up);
 }
 }
 
 
 static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -163,8 +148,8 @@ static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, i
 	if (!substream->opened)
 	if (!substream->opened)
 		return;
 		return;
 	substream->ops->trigger(substream, up);
 	substream->ops->trigger(substream, up);
-	if (!up && substream->runtime->event)
-		tasklet_kill(&substream->runtime->tasklet);
+	if (!up)
+		cancel_work_sync(&substream->runtime->event_work);
 }
 }
 
 
 int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
 int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
@@ -641,10 +626,10 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 	if (params->buffer_size != runtime->buffer_size) {
 	if (params->buffer_size != runtime->buffer_size) {
-		newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
+		newbuf = krealloc(runtime->buffer, params->buffer_size,
+				  GFP_KERNEL);
 		if (!newbuf)
 		if (!newbuf)
 			return -ENOMEM;
 			return -ENOMEM;
-		kfree(runtime->buffer);
 		runtime->buffer = newbuf;
 		runtime->buffer = newbuf;
 		runtime->buffer_size = params->buffer_size;
 		runtime->buffer_size = params->buffer_size;
 		runtime->avail = runtime->buffer_size;
 		runtime->avail = runtime->buffer_size;
@@ -668,10 +653,10 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 	if (params->buffer_size != runtime->buffer_size) {
 	if (params->buffer_size != runtime->buffer_size) {
-		newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
+		newbuf = krealloc(runtime->buffer, params->buffer_size,
+				  GFP_KERNEL);
 		if (!newbuf)
 		if (!newbuf)
 			return -ENOMEM;
 			return -ENOMEM;
-		kfree(runtime->buffer);
 		runtime->buffer = newbuf;
 		runtime->buffer = newbuf;
 		runtime->buffer_size = params->buffer_size;
 		runtime->buffer_size = params->buffer_size;
 	}
 	}
@@ -926,7 +911,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
 	}
 	}
 	if (result > 0) {
 	if (result > 0) {
 		if (runtime->event)
 		if (runtime->event)
-			tasklet_schedule(&runtime->tasklet);
+			schedule_work(&runtime->event_work);
 		else if (snd_rawmidi_ready(substream))
 		else if (snd_rawmidi_ready(substream))
 			wake_up(&runtime->sleep);
 			wake_up(&runtime->sleep);
 	}
 	}

+ 1 - 1
sound/firewire/speakers.c

@@ -171,7 +171,7 @@ static int fwspk_open(struct snd_pcm_substream *substream)
 
 
 	err = snd_pcm_hw_constraint_minmax(runtime,
 	err = snd_pcm_hw_constraint_minmax(runtime,
 					   SNDRV_PCM_HW_PARAM_PERIOD_TIME,
 					   SNDRV_PCM_HW_PARAM_PERIOD_TIME,
-					   5000, 8192000);
+					   5000, UINT_MAX);
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 
 

+ 2 - 2
sound/pci/ad1889.c

@@ -944,7 +944,7 @@ snd_ad1889_create(struct snd_card *card,
 	spin_lock_init(&chip->lock);	/* only now can we call ad1889_free */
 	spin_lock_init(&chip->lock);	/* only now can we call ad1889_free */
 
 
 	if (request_irq(pci->irq, snd_ad1889_interrupt,
 	if (request_irq(pci->irq, snd_ad1889_interrupt,
-			IRQF_SHARED, card->driver, chip)) {
+			IRQF_SHARED, KBUILD_MODNAME, chip)) {
 		printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
 		printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
 		snd_ad1889_free(chip);
 		snd_ad1889_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -1055,7 +1055,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
 MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
 MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
 
 
 static struct pci_driver ad1889_pci_driver = {
 static struct pci_driver ad1889_pci_driver = {
-	.name = "AD1889 Audio",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_ad1889_ids,
 	.id_table = snd_ad1889_ids,
 	.probe = snd_ad1889_probe,
 	.probe = snd_ad1889_probe,
 	.remove = __devexit_p(snd_ad1889_remove),
 	.remove = __devexit_p(snd_ad1889_remove),

+ 2 - 2
sound/pci/ali5451/ali5451.c

@@ -2090,7 +2090,7 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
 	codec->port = pci_resource_start(codec->pci, 0);
 	codec->port = pci_resource_start(codec->pci, 0);
 
 
 	if (request_irq(codec->pci->irq, snd_ali_card_interrupt,
 	if (request_irq(codec->pci->irq, snd_ali_card_interrupt,
-			IRQF_SHARED, "ALI 5451", codec)) {
+			IRQF_SHARED, KBUILD_MODNAME, codec)) {
 		snd_printk(KERN_ERR "Unable to request irq.\n");
 		snd_printk(KERN_ERR "Unable to request irq.\n");
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
@@ -2295,7 +2295,7 @@ static void __devexit snd_ali_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "ALI 5451",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_ali_ids,
 	.id_table = snd_ali_ids,
 	.probe = snd_ali_probe,
 	.probe = snd_ali_probe,
 	.remove = __devexit_p(snd_ali_remove),
 	.remove = __devexit_p(snd_ali_remove),

+ 2 - 2
sound/pci/als300.c

@@ -722,7 +722,7 @@ static int __devinit snd_als300_create(struct snd_card *card,
 		irq_handler = snd_als300_interrupt;
 		irq_handler = snd_als300_interrupt;
 
 
 	if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
 	if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
-			card->shortname, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_als300_free(chip);
 		snd_als300_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -846,7 +846,7 @@ static int __devinit snd_als300_probe(struct pci_dev *pci,
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "ALS300",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_als300_ids,
 	.id_table = snd_als300_ids,
 	.probe = snd_als300_probe,
 	.probe = snd_als300_probe,
 	.remove = __devexit_p(snd_als300_remove),
 	.remove = __devexit_p(snd_als300_remove),

+ 1 - 1
sound/pci/als4000.c

@@ -1036,7 +1036,7 @@ static int snd_als4000_resume(struct pci_dev *pci)
 
 
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "ALS4000",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_als4000_ids,
 	.id_table = snd_als4000_ids,
 	.probe = snd_card_als4000_probe,
 	.probe = snd_card_als4000_probe,
 	.remove = __devexit_p(snd_card_als4000_remove),
 	.remove = __devexit_p(snd_card_als4000_remove),

+ 66 - 15
sound/pci/asihpi/asihpi.c

@@ -49,19 +49,21 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
 #if defined CONFIG_SND_DEBUG
 #if defined CONFIG_SND_DEBUG
 /* copied from pcm_lib.c, hope later patch will make that version public
 /* copied from pcm_lib.c, hope later patch will make that version public
 and this copy can be removed */
 and this copy can be removed */
-static void pcm_debug_name(struct snd_pcm_substream *substream,
-			   char *name, size_t len)
+static inline void
+snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
 {
 {
-	snprintf(name, len, "pcmC%dD%d%c:%d",
+	snprintf(buf, size, "pcmC%dD%d%c:%d",
 		 substream->pcm->card->number,
 		 substream->pcm->card->number,
 		 substream->pcm->device,
 		 substream->pcm->device,
 		 substream->stream ? 'c' : 'p',
 		 substream->stream ? 'c' : 'p',
 		 substream->number);
 		 substream->number);
 }
 }
-#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
 #else
 #else
-#define pcm_debug_name(s, n, l) do { } while (0)
-#define DEBUG_NAME(name, substream) do { } while (0)
+static inline void
+snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
+{
+	*buf = 0;
+}
 #endif
 #endif
 
 
 #if defined CONFIG_SND_DEBUG_VERBOSE
 #if defined CONFIG_SND_DEBUG_VERBOSE
@@ -304,7 +306,8 @@ static u16 handle_error(u16 err, int line, char *filename)
 static void print_hwparams(struct snd_pcm_substream *substream,
 static void print_hwparams(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *p)
 				struct snd_pcm_hw_params *p)
 {
 {
-	DEBUG_NAME(substream, name);
+	char name[16];
+	snd_pcm_debug_name(substream, name, sizeof(name));
 	snd_printd("%s HWPARAMS\n", name);
 	snd_printd("%s HWPARAMS\n", name);
 	snd_printd(" samplerate %d Hz\n", params_rate(p));
 	snd_printd(" samplerate %d Hz\n", params_rate(p));
 	snd_printd(" channels %d\n", params_channels(p));
 	snd_printd(" channels %d\n", params_channels(p));
@@ -576,8 +579,9 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
 	struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
 	struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
 	struct snd_pcm_substream *s;
 	struct snd_pcm_substream *s;
 	u16 e;
 	u16 e;
-	DEBUG_NAME(substream, name);
+	char name[16];
 
 
+	snd_pcm_debug_name(substream, name, sizeof(name));
 	snd_printdd("%s trigger\n", name);
 	snd_printdd("%s trigger\n", name);
 
 
 	switch (cmd) {
 	switch (cmd) {
@@ -741,7 +745,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
 	int loops = 0;
 	int loops = 0;
 	u16 state;
 	u16 state;
 	u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
 	u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
-	DEBUG_NAME(substream, name);
+	char name[16];
+
+	snd_pcm_debug_name(substream, name, sizeof(name));
 
 
 	snd_printdd("%s snd_card_asihpi_timer_function\n", name);
 	snd_printdd("%s snd_card_asihpi_timer_function\n", name);
 
 
@@ -1323,10 +1329,12 @@ static const char * const asihpi_src_names[] = {
 	"RF",
 	"RF",
 	"Clock",
 	"Clock",
 	"Bitstream",
 	"Bitstream",
-	"Microphone",
-	"Cobranet",
+	"Mic",
+	"Net",
 	"Analog",
 	"Analog",
 	"Adapter",
 	"Adapter",
+	"RTP",
+	"GPI",
 };
 };
 
 
 compile_time_assert(
 compile_time_assert(
@@ -1341,8 +1349,10 @@ static const char * const asihpi_dst_names[] = {
 	"Digital",
 	"Digital",
 	"RF",
 	"RF",
 	"Speaker",
 	"Speaker",
-	"Cobranet Out",
-	"Analog"
+	"Net",
+	"Analog",
+	"RTP",
+	"GPO",
 };
 };
 
 
 compile_time_assert(
 compile_time_assert(
@@ -1476,11 +1486,40 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
 
 
 static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
 static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
 
 
+#define snd_asihpi_volume_mute_info	snd_ctl_boolean_mono_info
+
+static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	u32 h_control = kcontrol->private_value;
+	u32 mute;
+
+	hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
+	ucontrol->value.integer.value[0] = mute ? 0 : 1;
+
+	return 0;
+}
+
+static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	u32 h_control = kcontrol->private_value;
+	int change = 1;
+	/* HPI currently only supports all or none muting of multichannel volume
+	ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
+	*/
+	int mute =  ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
+	hpi_handle_error(hpi_volume_set_mute(h_control, mute));
+	return change;
+}
+
 static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
 static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
 					struct hpi_control *hpi_ctl)
 					struct hpi_control *hpi_ctl)
 {
 {
 	struct snd_card *card = asihpi->card;
 	struct snd_card *card = asihpi->card;
 	struct snd_kcontrol_new snd_control;
 	struct snd_kcontrol_new snd_control;
+	int err;
+	u32 mute;
 
 
 	asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
 	asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
 	snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1490,7 +1529,19 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
 	snd_control.put = snd_asihpi_volume_put;
 	snd_control.put = snd_asihpi_volume_put;
 	snd_control.tlv.p = db_scale_100;
 	snd_control.tlv.p = db_scale_100;
 
 
-	return ctl_add(card, &snd_control, asihpi);
+	err = ctl_add(card, &snd_control, asihpi);
+	if (err)
+		return err;
+
+	if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
+		asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
+		snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
+		snd_control.info = snd_asihpi_volume_mute_info;
+		snd_control.get = snd_asihpi_volume_mute_get;
+		snd_control.put = snd_asihpi_volume_mute_put;
+		err = ctl_add(card, &snd_control, asihpi);
+	}
+	return err;
 }
 }
 
 
 /*------------------------------------------------------------
 /*------------------------------------------------------------
@@ -2923,7 +2974,7 @@ static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
 MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
 MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "asihpi",
+	.name = KBUILD_MODNAME,
 	.id_table = asihpi_pci_tbl,
 	.id_table = asihpi_pci_tbl,
 	.probe = snd_asihpi_probe,
 	.probe = snd_asihpi_probe,
 	.remove = __devexit_p(snd_asihpi_remove),
 	.remove = __devexit_p(snd_asihpi_remove),

+ 15 - 9
sound/pci/asihpi/hpi.h

@@ -1,7 +1,7 @@
 /******************************************************************************
 /******************************************************************************
 
 
     AudioScience HPI driver
     AudioScience HPI driver
-    Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
+    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
 
 
     This program is free software; you can redistribute it and/or modify
     This program is free software; you can redistribute it and/or modify
     it under the terms of version 2 of the GNU General Public License as
     it under the terms of version 2 of the GNU General Public License as
@@ -42,12 +42,11 @@ i.e 3.05.02 is a development version
 #define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
 #define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
 #define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
 #define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
 
 
-/* Use single digits for versions less that 10 to avoid octal. */
-#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 6, 0)
-#define HPI_VER_STRING "4.06.00"
+#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 8, 0)
+#define HPI_VER_STRING "4.08.00"
 
 
 /* Library version as documented in hpi-api-versions.txt */
 /* Library version as documented in hpi-api-versions.txt */
-#define HPI_LIB_VER  HPI_VERSION_CONSTRUCTOR(9, 0, 0)
+#define HPI_LIB_VER  HPI_VERSION_CONSTRUCTOR(10, 0, 0)
 
 
 #include <linux/types.h>
 #include <linux/types.h>
 #define HPI_BUILD_EXCLUDE_DEPRECATED
 #define HPI_BUILD_EXCLUDE_DEPRECATED
@@ -211,8 +210,12 @@ enum HPI_SOURCENODES {
 	HPI_SOURCENODE_COBRANET = 109,
 	HPI_SOURCENODE_COBRANET = 109,
 	HPI_SOURCENODE_ANALOG = 110,	     /**< analog input node. */
 	HPI_SOURCENODE_ANALOG = 110,	     /**< analog input node. */
 	HPI_SOURCENODE_ADAPTER = 111,	     /**< adapter node. */
 	HPI_SOURCENODE_ADAPTER = 111,	     /**< adapter node. */
+	/** RTP stream input node - This node is a destination for
+	    packets of RTP audio samples from other devices. */
+	HPI_SOURCENODE_RTP_DESTINATION = 112,
+	HPI_SOURCENODE_GP_IN = 113,	     /**< general purpose input. */
 	/* !!!Update this  AND hpidebug.h if you add a new sourcenode type!!! */
 	/* !!!Update this  AND hpidebug.h if you add a new sourcenode type!!! */
-	HPI_SOURCENODE_LAST_INDEX = 111	     /**< largest ID */
+	HPI_SOURCENODE_LAST_INDEX = 113	     /**< largest ID */
 		/* AX6 max sourcenode types = 15 */
 		/* AX6 max sourcenode types = 15 */
 };
 };
 
 
@@ -228,7 +231,7 @@ enum HPI_DESTNODES {
 	HPI_DESTNODE_NONE = 200,
 	HPI_DESTNODE_NONE = 200,
 	/** In Stream (Record) node. */
 	/** In Stream (Record) node. */
 	HPI_DESTNODE_ISTREAM = 201,
 	HPI_DESTNODE_ISTREAM = 201,
-	HPI_DESTNODE_LINEOUT = 202,	    /**< line out node. */
+	HPI_DESTNODE_LINEOUT = 202,	     /**< line out node. */
 	HPI_DESTNODE_AESEBU_OUT = 203,	     /**< AES/EBU output node. */
 	HPI_DESTNODE_AESEBU_OUT = 203,	     /**< AES/EBU output node. */
 	HPI_DESTNODE_RF = 204,		     /**< RF output node. */
 	HPI_DESTNODE_RF = 204,		     /**< RF output node. */
 	HPI_DESTNODE_SPEAKER = 205,	     /**< speaker output node. */
 	HPI_DESTNODE_SPEAKER = 205,	     /**< speaker output node. */
@@ -236,9 +239,12 @@ enum HPI_DESTNODES {
 	    Audio samples from the device are sent out on the Cobranet network.*/
 	    Audio samples from the device are sent out on the Cobranet network.*/
 	HPI_DESTNODE_COBRANET = 206,
 	HPI_DESTNODE_COBRANET = 206,
 	HPI_DESTNODE_ANALOG = 207,	     /**< analog output node. */
 	HPI_DESTNODE_ANALOG = 207,	     /**< analog output node. */
-
+	/** RTP stream output node - This node is a source for
+	    packets of RTP audio samples that are sent to other devices. */
+	HPI_DESTNODE_RTP_SOURCE = 208,
+	HPI_DESTNODE_GP_OUT = 209,	     /**< general purpose output node. */
 	/* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
 	/* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
-	HPI_DESTNODE_LAST_INDEX = 207	     /**< largest ID */
+	HPI_DESTNODE_LAST_INDEX = 209	     /**< largest ID */
 		/* AX6 max destnode types = 15 */
 		/* AX6 max destnode types = 15 */
 };
 };
 
 

+ 4 - 7
sound/pci/asihpi/hpi6000.c

@@ -359,7 +359,7 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
 			HPI_ERROR_PROCESSING_MESSAGE);
 			HPI_ERROR_PROCESSING_MESSAGE);
 
 
 	switch (phm->type) {
 	switch (phm->type) {
-	case HPI_TYPE_MESSAGE:
+	case HPI_TYPE_REQUEST:
 		switch (phm->object) {
 		switch (phm->object) {
 		case HPI_OBJ_SUBSYSTEM:
 		case HPI_OBJ_SUBSYSTEM:
 			subsys_message(phm, phr);
 			subsys_message(phm, phr);
@@ -538,7 +538,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
 
 
 		HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
 		HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
 		memset(&hm, 0, sizeof(hm));
 		memset(&hm, 0, sizeof(hm));
-		hm.type = HPI_TYPE_MESSAGE;
+		hm.type = HPI_TYPE_REQUEST;
 		hm.size = sizeof(struct hpi_message);
 		hm.size = sizeof(struct hpi_message);
 		hm.object = HPI_OBJ_ADAPTER;
 		hm.object = HPI_OBJ_ADAPTER;
 		hm.function = HPI_ADAPTER_GET_INFO;
 		hm.function = HPI_ADAPTER_GET_INFO;
@@ -946,11 +946,8 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
 		}
 		}
 
 
 		/* write the DSP code down into the DSPs memory */
 		/* write the DSP code down into the DSPs memory */
-		/*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
-		dsp_code.ps_dev = pao->pci.pci_dev;
-
-		error = hpi_dsp_code_open(boot_load_family, &dsp_code,
-			pos_error_code);
+		error = hpi_dsp_code_open(boot_load_family, pao->pci.pci_dev,
+			&dsp_code, pos_error_code);
 
 
 		if (error)
 		if (error)
 			return error;
 			return error;

+ 15 - 37
sound/pci/asihpi/hpi6205.c

@@ -373,6 +373,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
 /** Entry point to this HPI backend
 /** Entry point to this HPI backend
  * All calls to the HPI start here
  * All calls to the HPI start here
  */
  */
+static
 void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
 void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
 	struct hpi_response *phr)
 	struct hpi_response *phr)
 {
 {
@@ -392,7 +393,7 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
 
 
 	HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
 	HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
 	switch (phm->type) {
 	switch (phm->type) {
-	case HPI_TYPE_MESSAGE:
+	case HPI_TYPE_REQUEST:
 		switch (phm->object) {
 		switch (phm->object) {
 		case HPI_OBJ_SUBSYSTEM:
 		case HPI_OBJ_SUBSYSTEM:
 			subsys_message(pao, phm, phr);
 			subsys_message(pao, phm, phr);
@@ -402,7 +403,6 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
 			adapter_message(pao, phm, phr);
 			adapter_message(pao, phm, phr);
 			break;
 			break;
 
 
-		case HPI_OBJ_CONTROLEX:
 		case HPI_OBJ_CONTROL:
 		case HPI_OBJ_CONTROL:
 			control_message(pao, phm, phr);
 			control_message(pao, phm, phr);
 			break;
 			break;
@@ -634,11 +634,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
 
 
 		HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
 		HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
 		memset(&hm, 0, sizeof(hm));
 		memset(&hm, 0, sizeof(hm));
-		hm.type = HPI_TYPE_MESSAGE;
+		/* wAdapterIndex == version == 0 */
+		hm.type = HPI_TYPE_REQUEST;
 		hm.size = sizeof(hm);
 		hm.size = sizeof(hm);
 		hm.object = HPI_OBJ_ADAPTER;
 		hm.object = HPI_OBJ_ADAPTER;
 		hm.function = HPI_ADAPTER_GET_INFO;
 		hm.function = HPI_ADAPTER_GET_INFO;
-		hm.adapter_index = 0;
+
 		memset(&hr, 0, sizeof(hr));
 		memset(&hr, 0, sizeof(hr));
 		hr.size = sizeof(hr);
 		hr.size = sizeof(hr);
 
 
@@ -658,9 +659,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
 			hr.u.ax.info.num_outstreams +
 			hr.u.ax.info.num_outstreams +
 			hr.u.ax.info.num_instreams;
 			hr.u.ax.info.num_instreams;
 
 
-		hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
-			65536, pao->pci.pci_dev);
-
 		HPI_DEBUG_LOG(VERBOSE,
 		HPI_DEBUG_LOG(VERBOSE,
 			"got adapter info type %x index %d serial %d\n",
 			"got adapter info type %x index %d serial %d\n",
 			hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
 			hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
@@ -709,9 +707,6 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao)
 				[i]);
 				[i]);
 			phw->outstream_host_buffer_size[i] = 0;
 			phw->outstream_host_buffer_size[i] = 0;
 		}
 		}
-
-	hpios_locked_mem_unprepare(pao->pci.pci_dev);
-
 	kfree(phw);
 	kfree(phw);
 }
 }
 
 
@@ -1371,9 +1366,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
 			return err;
 			return err;
 
 
 		/* write the DSP code down into the DSPs memory */
 		/* write the DSP code down into the DSPs memory */
-		dsp_code.ps_dev = pao->pci.pci_dev;
-		err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
-			pos_error_code);
+		err = hpi_dsp_code_open(boot_code_id[dsp], pao->pci.pci_dev,
+			&dsp_code, pos_error_code);
 		if (err)
 		if (err)
 			return err;
 			return err;
 
 
@@ -2084,13 +2078,13 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
 	u16 err = 0;
 	u16 err = 0;
 
 
 	message_count++;
 	message_count++;
-	if (phm->size > sizeof(interface->u)) {
+	if (phm->size > sizeof(interface->u.message_buffer)) {
 		phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
 		phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
-		phr->specific_error = sizeof(interface->u);
+		phr->specific_error = sizeof(interface->u.message_buffer);
 		phr->size = sizeof(struct hpi_response_header);
 		phr->size = sizeof(struct hpi_response_header);
 		HPI_DEBUG_LOG(ERROR,
 		HPI_DEBUG_LOG(ERROR,
 			"message len %d too big for buffer %zd \n", phm->size,
 			"message len %d too big for buffer %zd \n", phm->size,
-			sizeof(interface->u));
+			sizeof(interface->u.message_buffer));
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -2122,18 +2116,19 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
 
 
 	/* read the result */
 	/* read the result */
 	if (time_out) {
 	if (time_out) {
-		if (interface->u.response_buffer.size <= phr->size)
+		if (interface->u.response_buffer.response.size <= phr->size)
 			memcpy(phr, &interface->u.response_buffer,
 			memcpy(phr, &interface->u.response_buffer,
-				interface->u.response_buffer.size);
+				interface->u.response_buffer.response.size);
 		else {
 		else {
 			HPI_DEBUG_LOG(ERROR,
 			HPI_DEBUG_LOG(ERROR,
 				"response len %d too big for buffer %d\n",
 				"response len %d too big for buffer %d\n",
-				interface->u.response_buffer.size, phr->size);
+				interface->u.response_buffer.response.size,
+				phr->size);
 			memcpy(phr, &interface->u.response_buffer,
 			memcpy(phr, &interface->u.response_buffer,
 				sizeof(struct hpi_response_header));
 				sizeof(struct hpi_response_header));
 			phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
 			phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
 			phr->specific_error =
 			phr->specific_error =
-				interface->u.response_buffer.size;
+				interface->u.response_buffer.response.size;
 			phr->size = sizeof(struct hpi_response_header);
 			phr->size = sizeof(struct hpi_response_header);
 		}
 		}
 	}
 	}
@@ -2202,23 +2197,6 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
 			phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
 			phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
 		break;
 		break;
 
 
-	case HPI_CONTROL_SET_STATE:
-		if (phm->object == HPI_OBJ_CONTROLEX
-			&& phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
-			err = hpi6205_transfer_data(pao,
-				phm->u.cx.u.cobranet_bigdata.pb_data,
-				phm->u.cx.u.cobranet_bigdata.byte_count,
-				H620_HIF_SEND_DATA);
-		break;
-
-	case HPI_CONTROL_GET_STATE:
-		if (phm->object == HPI_OBJ_CONTROLEX
-			&& phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
-			err = hpi6205_transfer_data(pao,
-				phm->u.cx.u.cobranet_bigdata.pb_data,
-				phr->u.cx.u.cobranet_data.byte_count,
-				H620_HIF_GET_DATA);
-		break;
 	}
 	}
 	phr->error = err;
 	phr->error = err;
 
 

+ 19 - 6
sound/pci/asihpi/hpi6205.h

@@ -1,7 +1,7 @@
 /*****************************************************************************
 /*****************************************************************************
 
 
     AudioScience HPI driver
     AudioScience HPI driver
-    Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
+    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
 
 
     This program is free software; you can redistribute it and/or modify
     This program is free software; you can redistribute it and/or modify
     it under the terms of version 2 of the GNU General Public License as
     it under the terms of version 2 of the GNU General Public License as
@@ -70,15 +70,28 @@ The Host located memory buffer that the 6205 will bus master
 in and out of.
 in and out of.
 ************************************************************/
 ************************************************************/
 #define HPI6205_SIZEOF_DATA (16*1024)
 #define HPI6205_SIZEOF_DATA (16*1024)
+
+struct message_buffer_6205 {
+	struct hpi_message message;
+	char data[256];
+};
+
+struct response_buffer_6205 {
+	struct hpi_response response;
+	char data[256];
+};
+
+union buffer_6205 {
+	struct message_buffer_6205 message_buffer;
+	struct response_buffer_6205 response_buffer;
+	u8 b_data[HPI6205_SIZEOF_DATA];
+};
+
 struct bus_master_interface {
 struct bus_master_interface {
 	u32 host_cmd;
 	u32 host_cmd;
 	u32 dsp_ack;
 	u32 dsp_ack;
 	u32 transfer_size_in_bytes;
 	u32 transfer_size_in_bytes;
-	union {
-		struct hpi_message_header message_buffer;
-		struct hpi_response_header response_buffer;
-		u8 b_data[HPI6205_SIZEOF_DATA];
-	} u;
+	union buffer_6205 u;
 	struct controlcache_6205 control_cache;
 	struct controlcache_6205 control_cache;
 	struct async_event_buffer_6205 async_buffer;
 	struct async_event_buffer_6205 async_buffer;
 	struct hpi_hostbuffer_status
 	struct hpi_hostbuffer_status

+ 41 - 114
sound/pci/asihpi/hpi_internal.h

@@ -1,7 +1,7 @@
 /******************************************************************************
 /******************************************************************************
 
 
     AudioScience HPI driver
     AudioScience HPI driver
-    Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
+    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
 
 
     This program is free software; you can redistribute it and/or modify
     This program is free software; you can redistribute it and/or modify
     it under the terms of version 2 of the GNU General Public License as
     it under the terms of version 2 of the GNU General Public License as
@@ -32,12 +32,6 @@ HPI internal definitions
 #include "hpios.h"
 #include "hpios.h"
 
 
 /* physical memory allocation */
 /* physical memory allocation */
-void hpios_locked_mem_init(void
-	);
-void hpios_locked_mem_free_all(void
-	);
-#define hpios_locked_mem_prepare(a, b, c, d);
-#define hpios_locked_mem_unprepare(a)
 
 
 /** Allocate and map an area of locked memory for bus master DMA operations.
 /** Allocate and map an area of locked memory for bus master DMA operations.
 
 
@@ -226,8 +220,8 @@ enum HPI_CONTROL_ATTRIBUTES {
 
 
 	HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
 	HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
 	HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
 	HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
-	HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3),
-	HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4),
+	/*HPI_COBRANET_SET_DATA         = HPI_CTL_ATTR(COBRANET, 3), */
+	/*HPI_COBRANET_GET_DATA         = HPI_CTL_ATTR(COBRANET, 4), */
 	HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
 	HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
 	HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
 	HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
 	HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
 	HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
@@ -364,10 +358,12 @@ Used in DLL to indicate device not present
 #define HPI_ADAPTER_ASI(f)   (f)
 #define HPI_ADAPTER_ASI(f)   (f)
 
 
 enum HPI_MESSAGE_TYPES {
 enum HPI_MESSAGE_TYPES {
-	HPI_TYPE_MESSAGE = 1,
+	HPI_TYPE_REQUEST = 1,
 	HPI_TYPE_RESPONSE = 2,
 	HPI_TYPE_RESPONSE = 2,
 	HPI_TYPE_DATA = 3,
 	HPI_TYPE_DATA = 3,
-	HPI_TYPE_SSX2BYPASS_MESSAGE = 4
+	HPI_TYPE_SSX2BYPASS_MESSAGE = 4,
+	HPI_TYPE_COMMAND = 5,
+	HPI_TYPE_NOTIFICATION = 6
 };
 };
 
 
 enum HPI_OBJECT_TYPES {
 enum HPI_OBJECT_TYPES {
@@ -383,7 +379,7 @@ enum HPI_OBJECT_TYPES {
 	HPI_OBJ_WATCHDOG = 10,
 	HPI_OBJ_WATCHDOG = 10,
 	HPI_OBJ_CLOCK = 11,
 	HPI_OBJ_CLOCK = 11,
 	HPI_OBJ_PROFILE = 12,
 	HPI_OBJ_PROFILE = 12,
-	HPI_OBJ_CONTROLEX = 13,
+	/* HPI_ OBJ_ CONTROLEX  = 13, */
 	HPI_OBJ_ASYNCEVENT = 14
 	HPI_OBJ_ASYNCEVENT = 14
 #define HPI_OBJ_MAXINDEX 14
 #define HPI_OBJ_MAXINDEX 14
 };
 };
@@ -608,7 +604,7 @@ struct hpi_data_compat32 {
 #endif
 #endif
 
 
 struct hpi_buffer {
 struct hpi_buffer {
-  /** placehoder for backward compatibility (see dwBufferSize) */
+  /** placeholder for backward compatibility (see dwBufferSize) */
 	struct hpi_msg_format reserved;
 	struct hpi_msg_format reserved;
 	u32 command; /**< HPI_BUFFER_CMD_xxx*/
 	u32 command; /**< HPI_BUFFER_CMD_xxx*/
 	u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
 	u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
@@ -912,95 +908,13 @@ union hpi_control_union_res {
 		u32 remaining_chars;
 		u32 remaining_chars;
 	} chars8;
 	} chars8;
 	char c_data12[12];
 	char c_data12[12];
-};
-
-/* HPI_CONTROLX_STRUCTURES */
-
-/* Message */
-
-/** Used for all HMI variables where max length <= 8 bytes
-*/
-struct hpi_controlx_msg_cobranet_data {
-	u32 hmi_address;
-	u32 byte_count;
-	u32 data[2];
-};
-
-/** Used for string data, and for packet bridge
-*/
-struct hpi_controlx_msg_cobranet_bigdata {
-	u32 hmi_address;
-	u32 byte_count;
-	u8 *pb_data;
-#ifndef HPI64BIT
-	u32 padding;
-#endif
-};
-
-/** Used for PADS control reading of string fields.
-*/
-struct hpi_controlx_msg_pad_data {
-	u32 field;
-	u32 byte_count;
-	u8 *pb_data;
-#ifndef HPI64BIT
-	u32 padding;
-#endif
-};
-
-/** Used for generic data
-*/
-
-struct hpi_controlx_msg_generic {
-	u32 param1;
-	u32 param2;
-};
-
-struct hpi_controlx_msg {
-	u16 attribute;		/* control attribute or property */
-	u16 saved_index;
-	union {
-		struct hpi_controlx_msg_cobranet_data cobranet_data;
-		struct hpi_controlx_msg_cobranet_bigdata cobranet_bigdata;
-		struct hpi_controlx_msg_generic generic;
-		struct hpi_controlx_msg_pad_data pad_data;
-		/*struct param_value universal_value; */
-		/* nothing extra to send for status read */
-	} u;
-};
-
-/* Response */
-/**
-*/
-struct hpi_controlx_res_cobranet_data {
-	u32 byte_count;
-	u32 data[2];
-};
-
-struct hpi_controlx_res_cobranet_bigdata {
-	u32 byte_count;
-};
-
-struct hpi_controlx_res_cobranet_status {
-	u32 status;
-	u32 readable_size;
-	u32 writeable_size;
-};
-
-struct hpi_controlx_res_generic {
-	u32 param1;
-	u32 param2;
-};
-
-struct hpi_controlx_res {
 	union {
 	union {
-		struct hpi_controlx_res_cobranet_bigdata cobranet_bigdata;
-		struct hpi_controlx_res_cobranet_data cobranet_data;
-		struct hpi_controlx_res_cobranet_status cobranet_status;
-		struct hpi_controlx_res_generic generic;
-		/*struct param_info universal_info; */
-		/*struct param_value universal_value; */
-	} u;
+		struct {
+			u32 status;
+			u32 readable_size;
+			u32 writeable_size;
+		} status;
+	} cobranet;
 };
 };
 
 
 struct hpi_nvmemory_msg {
 struct hpi_nvmemory_msg {
@@ -1126,7 +1040,6 @@ struct hpi_message {
 		/* identical to struct hpi_control_msg,
 		/* identical to struct hpi_control_msg,
 		   but field naming is improved */
 		   but field naming is improved */
 		struct hpi_control_union_msg cu;
 		struct hpi_control_union_msg cu;
-		struct hpi_controlx_msg cx;	/* extended mixer control; */
 		struct hpi_nvmemory_msg n;
 		struct hpi_nvmemory_msg n;
 		struct hpi_gpio_msg l;	/* digital i/o */
 		struct hpi_gpio_msg l;	/* digital i/o */
 		struct hpi_watchdog_msg w;
 		struct hpi_watchdog_msg w;
@@ -1151,7 +1064,7 @@ struct hpi_message {
 	sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\
 	sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\
 	sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\
 	sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\
 	sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\
 	sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\
-	sizeof(struct hpi_message_header) + sizeof(struct hpi_controlx_msg),\
+	sizeof(struct hpi_message_header), /* controlx obj removed */ \
 	sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
 	sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
 }
 }
 
 
@@ -1188,7 +1101,6 @@ struct hpi_response {
 		struct hpi_control_res c;	/* mixer control; */
 		struct hpi_control_res c;	/* mixer control; */
 		/* identical to hpi_control_res, but field naming is improved */
 		/* identical to hpi_control_res, but field naming is improved */
 		union hpi_control_union_res cu;
 		union hpi_control_union_res cu;
-		struct hpi_controlx_res cx;	/* extended mixer control; */
 		struct hpi_nvmemory_res n;
 		struct hpi_nvmemory_res n;
 		struct hpi_gpio_res l;	/* digital i/o */
 		struct hpi_gpio_res l;	/* digital i/o */
 		struct hpi_watchdog_res w;
 		struct hpi_watchdog_res w;
@@ -1213,7 +1125,7 @@ struct hpi_response {
 	sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\
 	sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\
 	sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\
 	sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\
 	sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\
 	sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\
-	sizeof(struct hpi_response_header) + sizeof(struct hpi_controlx_res),\
+	sizeof(struct hpi_response_header), /* controlx obj removed */ \
 	sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
 	sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
 }
 }
 
 
@@ -1308,6 +1220,30 @@ struct hpi_res_adapter_debug_read {
 	u8 bytes[256];
 	u8 bytes[256];
 };
 };
 
 
+struct hpi_msg_cobranet_hmi {
+	u16 attribute;
+	u16 padding;
+	u32 hmi_address;
+	u32 byte_count;
+};
+
+struct hpi_msg_cobranet_hmiwrite {
+	struct hpi_message_header h;
+	struct hpi_msg_cobranet_hmi p;
+	u8 bytes[256];
+};
+
+struct hpi_msg_cobranet_hmiread {
+	struct hpi_message_header h;
+	struct hpi_msg_cobranet_hmi p;
+};
+
+struct hpi_res_cobranet_hmiread {
+	struct hpi_response_header h;
+	u32 byte_count;
+	u8 bytes[256];
+};
+
 #if 1
 #if 1
 #define hpi_message_header_v1 hpi_message_header
 #define hpi_message_header_v1 hpi_message_header
 #define hpi_response_header_v1 hpi_response_header
 #define hpi_response_header_v1 hpi_response_header
@@ -1338,7 +1274,6 @@ struct hpi_msg_payload_v0 {
 		union hpi_mixerx_msg mx;
 		union hpi_mixerx_msg mx;
 		struct hpi_control_msg c;
 		struct hpi_control_msg c;
 		struct hpi_control_union_msg cu;
 		struct hpi_control_union_msg cu;
-		struct hpi_controlx_msg cx;
 		struct hpi_nvmemory_msg n;
 		struct hpi_nvmemory_msg n;
 		struct hpi_gpio_msg l;
 		struct hpi_gpio_msg l;
 		struct hpi_watchdog_msg w;
 		struct hpi_watchdog_msg w;
@@ -1358,7 +1293,6 @@ struct hpi_res_payload_v0 {
 		union hpi_mixerx_res mx;
 		union hpi_mixerx_res mx;
 		struct hpi_control_res c;
 		struct hpi_control_res c;
 		union hpi_control_union_res cu;
 		union hpi_control_union_res cu;
-		struct hpi_controlx_res cx;
 		struct hpi_nvmemory_res n;
 		struct hpi_nvmemory_res n;
 		struct hpi_gpio_res l;
 		struct hpi_gpio_res l;
 		struct hpi_watchdog_res w;
 		struct hpi_watchdog_res w;
@@ -1493,12 +1427,6 @@ struct hpi_control_cache_microphone {
 	char temp_padding[6];
 	char temp_padding[6];
 };
 };
 
 
-struct hpi_control_cache_generic {
-	struct hpi_control_cache_info i;
-	u32 dw1;
-	u32 dw2;
-};
-
 struct hpi_control_cache_single {
 struct hpi_control_cache_single {
 	union {
 	union {
 		struct hpi_control_cache_info i;
 		struct hpi_control_cache_info i;
@@ -1514,7 +1442,6 @@ struct hpi_control_cache_single {
 		struct hpi_control_cache_silencedetector silence;
 		struct hpi_control_cache_silencedetector silence;
 		struct hpi_control_cache_sampleclock clk;
 		struct hpi_control_cache_sampleclock clk;
 		struct hpi_control_cache_microphone microphone;
 		struct hpi_control_cache_microphone microphone;
-		struct hpi_control_cache_generic generic;
 	} u;
 	} u;
 };
 };
 
 

+ 9 - 8
sound/pci/asihpi/hpicmn.c

@@ -57,7 +57,7 @@ u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
 	}
 	}
 
 
 	if (phr->function != phm->function) {
 	if (phr->function != phm->function) {
-		HPI_DEBUG_LOG(ERROR, "header type %d invalid\n",
+		HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
 			phr->function);
 			phr->function);
 		return HPI_ERROR_INVALID_RESPONSE;
 		return HPI_ERROR_INVALID_RESPONSE;
 	}
 	}
@@ -315,8 +315,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
 	short found = 1;
 	short found = 1;
 	struct hpi_control_cache_info *pI;
 	struct hpi_control_cache_info *pI;
 	struct hpi_control_cache_single *pC;
 	struct hpi_control_cache_single *pC;
-	struct hpi_control_cache_pad *p_pad;
-
+	size_t response_size;
 	if (!find_control(phm->obj_index, p_cache, &pI)) {
 	if (!find_control(phm->obj_index, p_cache, &pI)) {
 		HPI_DEBUG_LOG(VERBOSE,
 		HPI_DEBUG_LOG(VERBOSE,
 			"HPICMN find_control() failed for adap %d\n",
 			"HPICMN find_control() failed for adap %d\n",
@@ -326,11 +325,15 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
 
 
 	phr->error = 0;
 	phr->error = 0;
 
 
+	/* set the default response size */
+	response_size =
+		sizeof(struct hpi_response_header) +
+		sizeof(struct hpi_control_res);
+
 	/* pC is the default cached control strucure. May be cast to
 	/* pC is the default cached control strucure. May be cast to
 	   something else in the following switch statement.
 	   something else in the following switch statement.
 	 */
 	 */
 	pC = (struct hpi_control_cache_single *)pI;
 	pC = (struct hpi_control_cache_single *)pI;
-	p_pad = (struct hpi_control_cache_pad *)pI;
 
 
 	switch (pI->control_type) {
 	switch (pI->control_type) {
 
 
@@ -529,9 +532,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
 		pI->control_index, pI->control_type, phm->u.c.attribute);
 		pI->control_index, pI->control_type, phm->u.c.attribute);
 
 
 	if (found)
 	if (found)
-		phr->size =
-			sizeof(struct hpi_response_header) +
-			sizeof(struct hpi_control_res);
+		phr->size = (u16)response_size;
 
 
 	return found;
 	return found;
 }
 }
@@ -682,7 +683,7 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
 void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
 void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
 {
 {
 	switch (phm->type) {
 	switch (phm->type) {
-	case HPI_TYPE_MESSAGE:
+	case HPI_TYPE_REQUEST:
 		switch (phm->object) {
 		switch (phm->object) {
 		case HPI_OBJ_SUBSYSTEM:
 		case HPI_OBJ_SUBSYSTEM:
 			subsys_message(phm, phr);
 			subsys_message(phm, phr);

+ 54 - 82
sound/pci/asihpi/hpidspcd.c

@@ -1,8 +1,8 @@
 /***********************************************************************/
 /***********************************************************************/
-/*!
+/**
 
 
     AudioScience HPI driver
     AudioScience HPI driver
-    Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
+    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
 
 
     This program is free software; you can redistribute it and/or modify
     This program is free software; you can redistribute it and/or modify
     it under the terms of version 2 of the GNU General Public License as
     it under the terms of version 2 of the GNU General Public License as
@@ -18,90 +18,59 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 
 \file
 \file
-Functions for reading DSP code to load into DSP
-
-(Linux only:) If DSPCODE_FIRMWARE_LOADER is defined, code is read using
+Functions for reading DSP code using
 hotplug firmware loader from individual dsp code files
 hotplug firmware loader from individual dsp code files
-
-If neither of the above is defined, code is read from linked arrays.
-DSPCODE_ARRAY is defined.
-
-HPI_INCLUDE_**** must be defined
-and the appropriate hzz?????.c or hex?????.c linked in
-
- */
+*/
 /***********************************************************************/
 /***********************************************************************/
 #define SOURCEFILE_NAME "hpidspcd.c"
 #define SOURCEFILE_NAME "hpidspcd.c"
 #include "hpidspcd.h"
 #include "hpidspcd.h"
 #include "hpidebug.h"
 #include "hpidebug.h"
 
 
-/**
- Header structure for binary dsp code file (see asidsp.doc)
- This structure must match that used in s2bin.c for generation of asidsp.bin
- */
-
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(push, 1)
-#endif
-
-struct code_header {
-	u32 size;
-	char type[4];
-	u32 adapter;
-	u32 version;
-	u32 crc;
+struct dsp_code_private {
+	/**  Firmware descriptor */
+	const struct firmware *firmware;
+	struct pci_dev *dev;
 };
 };
 
 
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(pop)
-#endif
-
 #define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
 #define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
 	    HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
 	    HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
 
 
-/***********************************************************************/
-#include <linux/pci.h>
 /*-------------------------------------------------------------------*/
 /*-------------------------------------------------------------------*/
-short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
-	u32 *pos_error_code)
+short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
+	u32 *os_error_code)
 {
 {
-	const struct firmware *ps_firmware = ps_dsp_code->ps_firmware;
+	const struct firmware *firmware;
+	struct pci_dev *dev = os_data;
 	struct code_header header;
 	struct code_header header;
 	char fw_name[20];
 	char fw_name[20];
 	int err;
 	int err;
 
 
 	sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
 	sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
 
 
-	err = request_firmware(&ps_firmware, fw_name,
-		&ps_dsp_code->ps_dev->dev);
+	err = request_firmware(&firmware, fw_name, &dev->dev);
 
 
-	if (err != 0) {
-		dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
+	if (err || !firmware) {
+		dev_printk(KERN_ERR, &dev->dev,
 			"%d, request_firmware failed for  %s\n", err,
 			"%d, request_firmware failed for  %s\n", err,
 			fw_name);
 			fw_name);
 		goto error1;
 		goto error1;
 	}
 	}
-	if (ps_firmware->size < sizeof(header)) {
-		dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
-			"Header size too small %s\n", fw_name);
-		goto error2;
-	}
-	memcpy(&header, ps_firmware->data, sizeof(header));
-	if (header.adapter != adapter) {
-		dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
-			"Adapter type incorrect %4x != %4x\n", header.adapter,
-			adapter);
+	if (firmware->size < sizeof(header)) {
+		dev_printk(KERN_ERR, &dev->dev, "Header size too small %s\n",
+			fw_name);
 		goto error2;
 		goto error2;
 	}
 	}
-	if (header.size != ps_firmware->size) {
-		dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
-			"Code size wrong  %d != %ld\n", header.size,
-			(unsigned long)ps_firmware->size);
+	memcpy(&header, firmware->data, sizeof(header));
+
+	if ((header.type != 0x45444F43) ||	/* "CODE" */
+		(header.adapter != adapter)
+		|| (header.size != firmware->size)) {
+		dev_printk(KERN_ERR, &dev->dev, "Invalid firmware file\n");
 		goto error2;
 		goto error2;
 	}
 	}
 
 
-	if (header.version / 100 != HPI_VER_DECIMAL / 100) {
-		dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
+	if ((header.version / 100 & ~1) != (HPI_VER_DECIMAL / 100 & ~1)) {
+		dev_printk(KERN_ERR, &dev->dev,
 			"Incompatible firmware version "
 			"Incompatible firmware version "
 			"DSP image %d != Driver %d\n", header.version,
 			"DSP image %d != Driver %d\n", header.version,
 			HPI_VER_DECIMAL);
 			HPI_VER_DECIMAL);
@@ -109,67 +78,70 @@ short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
 	}
 	}
 
 
 	if (header.version != HPI_VER_DECIMAL) {
 	if (header.version != HPI_VER_DECIMAL) {
-		dev_printk(KERN_WARNING, &ps_dsp_code->ps_dev->dev,
+		dev_printk(KERN_WARNING, &dev->dev,
 			"Firmware: release version mismatch  DSP image %d != Driver %d\n",
 			"Firmware: release version mismatch  DSP image %d != Driver %d\n",
 			header.version, HPI_VER_DECIMAL);
 			header.version, HPI_VER_DECIMAL);
 	}
 	}
 
 
 	HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
 	HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
-	ps_dsp_code->ps_firmware = ps_firmware;
-	ps_dsp_code->block_length = header.size / sizeof(u32);
-	ps_dsp_code->word_count = sizeof(header) / sizeof(u32);
-	ps_dsp_code->version = header.version;
-	ps_dsp_code->crc = header.crc;
+	dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL);
+	if (!dsp_code->pvt)
+		return HPI_ERROR_MEMORY_ALLOC;
+
+	dsp_code->pvt->dev = dev;
+	dsp_code->pvt->firmware = firmware;
+	dsp_code->header = header;
+	dsp_code->block_length = header.size / sizeof(u32);
+	dsp_code->word_count = sizeof(header) / sizeof(u32);
 	return 0;
 	return 0;
 
 
 error2:
 error2:
-	release_firmware(ps_firmware);
+	release_firmware(firmware);
 error1:
 error1:
-	ps_dsp_code->ps_firmware = NULL;
-	ps_dsp_code->block_length = 0;
+	dsp_code->block_length = 0;
 	return HPI_ERROR_DSP_FILE_NOT_FOUND;
 	return HPI_ERROR_DSP_FILE_NOT_FOUND;
 }
 }
 
 
 /*-------------------------------------------------------------------*/
 /*-------------------------------------------------------------------*/
-void hpi_dsp_code_close(struct dsp_code *ps_dsp_code)
+void hpi_dsp_code_close(struct dsp_code *dsp_code)
 {
 {
-	if (ps_dsp_code->ps_firmware != NULL) {
+	if (dsp_code->pvt->firmware) {
 		HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
 		HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
-		release_firmware(ps_dsp_code->ps_firmware);
-		ps_dsp_code->ps_firmware = NULL;
+		release_firmware(dsp_code->pvt->firmware);
+		dsp_code->pvt->firmware = NULL;
 	}
 	}
+	kfree(dsp_code->pvt);
 }
 }
 
 
 /*-------------------------------------------------------------------*/
 /*-------------------------------------------------------------------*/
-void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code)
+void hpi_dsp_code_rewind(struct dsp_code *dsp_code)
 {
 {
 	/* Go back to start of  data, after header */
 	/* Go back to start of  data, after header */
-	ps_dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
+	dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
 }
 }
 
 
 /*-------------------------------------------------------------------*/
 /*-------------------------------------------------------------------*/
-short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword)
+short hpi_dsp_code_read_word(struct dsp_code *dsp_code, u32 *pword)
 {
 {
-	if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length)
+	if (dsp_code->word_count + 1 > dsp_code->block_length)
 		return HPI_ERROR_DSP_FILE_FORMAT;
 		return HPI_ERROR_DSP_FILE_FORMAT;
 
 
-	*pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code->
+	*pword = ((u32 *)(dsp_code->pvt->firmware->data))[dsp_code->
 		word_count];
 		word_count];
-	ps_dsp_code->word_count++;
+	dsp_code->word_count++;
 	return 0;
 	return 0;
 }
 }
 
 
 /*-------------------------------------------------------------------*/
 /*-------------------------------------------------------------------*/
 short hpi_dsp_code_read_block(size_t words_requested,
 short hpi_dsp_code_read_block(size_t words_requested,
-	struct dsp_code *ps_dsp_code, u32 **ppblock)
+	struct dsp_code *dsp_code, u32 **ppblock)
 {
 {
-	if (ps_dsp_code->word_count + words_requested >
-		ps_dsp_code->block_length)
+	if (dsp_code->word_count + words_requested > dsp_code->block_length)
 		return HPI_ERROR_DSP_FILE_FORMAT;
 		return HPI_ERROR_DSP_FILE_FORMAT;
 
 
 	*ppblock =
 	*ppblock =
-		((u32 *)(ps_dsp_code->ps_firmware->data)) +
-		ps_dsp_code->word_count;
-	ps_dsp_code->word_count += words_requested;
+		((u32 *)(dsp_code->pvt->firmware->data)) +
+		dsp_code->word_count;
+	dsp_code->word_count += words_requested;
 	return 0;
 	return 0;
 }
 }

+ 39 - 33
sound/pci/asihpi/hpidspcd.h

@@ -2,7 +2,7 @@
 /**
 /**
 
 
     AudioScience HPI driver
     AudioScience HPI driver
-    Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
+    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
 
 
     This program is free software; you can redistribute it and/or modify
     This program is free software; you can redistribute it and/or modify
     it under the terms of version 2 of the GNU General Public License as
     it under the terms of version 2 of the GNU General Public License as
@@ -20,19 +20,6 @@
 \file
 \file
 Functions for reading DSP code to load into DSP
 Functions for reading DSP code to load into DSP
 
 
- hpi_dspcode_defines HPI DSP code loading method
-Define exactly one of these to select how the DSP code is supplied to
-the adapter.
-
-End users writing applications that use the HPI interface do not have to
-use any of the below defines; they are only necessary for building drivers
-
-HPI_DSPCODE_FILE:
-DSP code is supplied as a file that is opened and read from by the driver.
-
-HPI_DSPCODE_FIRMWARE:
-DSP code is read using the hotplug firmware loader module.
-     Only valid when compiling the HPI kernel driver under Linux.
 */
 */
 /***********************************************************************/
 /***********************************************************************/
 #ifndef _HPIDSPCD_H_
 #ifndef _HPIDSPCD_H_
@@ -40,37 +27,56 @@ DSP code is read using the hotplug firmware loader module.
 
 
 #include "hpi_internal.h"
 #include "hpi_internal.h"
 
 
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(push, 1)
-#endif
+/** Code header version is decimal encoded e.g. 4.06.10 is 40601 */
+#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
+HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
+
+/** Header structure for dsp firmware file
+ This structure must match that used in s2bin.c for generation of asidsp.bin
+ */
+/*#ifndef DISABLE_PRAGMA_PACK1 */
+/*#pragma pack(push, 1) */
+/*#endif */
+struct code_header {
+	/** Size in bytes including header */
+	u32 size;
+	/** File type tag "CODE" == 0x45444F43 */
+	u32 type;
+	/** Adapter model number */
+	u32 adapter;
+	/** Firmware version*/
+	u32 version;
+	/** Data checksum */
+	u32 checksum;
+};
+/*#ifndef DISABLE_PRAGMA_PACK1 */
+/*#pragma pack(pop) */
+/*#endif */
+
+/*? Don't need the pragmas? */
+compile_time_assert((sizeof(struct code_header) == 20), code_header_size);
 
 
 /** Descriptor for dspcode from firmware loader */
 /** Descriptor for dspcode from firmware loader */
 struct dsp_code {
 struct dsp_code {
-	/**  Firmware descriptor */
-	const struct firmware *ps_firmware;
-	struct pci_dev *ps_dev;
+	/** copy of  file header */
+	struct code_header header;
 	/** Expected number of words in the whole dsp code,INCL header */
 	/** Expected number of words in the whole dsp code,INCL header */
-	long int block_length;
+	u32 block_length;
 	/** Number of words read so far */
 	/** Number of words read so far */
-	long int word_count;
-	/** Version read from dsp code file */
-	u32 version;
-	/** CRC read from dsp code file */
-	u32 crc;
-};
+	u32 word_count;
 
 
-#ifndef DISABLE_PRAGMA_PACK1
-#pragma pack(pop)
-#endif
+	/** internal state of DSP code reader */
+	struct dsp_code_private *pvt;
+};
 
 
-/** Prepare *psDspCode to refer to the requuested adapter.
- Searches the file, or selects the appropriate linked array
+/** Prepare *psDspCode to refer to the requested adapter's firmware.
+Code file name is obtained from HpiOs_GetDspCodePath
 
 
 \return 0 for success, or error code if requested code is not available
 \return 0 for success, or error code if requested code is not available
 */
 */
 short hpi_dsp_code_open(
 short hpi_dsp_code_open(
 	/** Code identifier, usually adapter family */
 	/** Code identifier, usually adapter family */
-	u32 adapter,
+	u32 adapter, void *pci_dev,
 	/** Pointer to DSP code control structure */
 	/** Pointer to DSP code control structure */
 	struct dsp_code *ps_dsp_code,
 	struct dsp_code *ps_dsp_code,
 	/** Pointer to dword to receive OS specific error code */
 	/** Pointer to dword to receive OS specific error code */

+ 41 - 45
sound/pci/asihpi/hpifunc.c

@@ -1663,68 +1663,64 @@ u16 hpi_channel_mode_get(u32 h_control, u16 *mode)
 u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
 u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
 	u8 *pb_data)
 	u8 *pb_data)
 {
 {
-	struct hpi_message hm;
-	struct hpi_response hr;
+	struct hpi_msg_cobranet_hmiwrite hm;
+	struct hpi_response_header hr;
 
 
-	hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
-		HPI_CONTROL_SET_STATE);
-	if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
-		return HPI_ERROR_INVALID_HANDLE;
+	hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr, sizeof(hr),
+		HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
 
 
-	hm.u.cx.u.cobranet_data.byte_count = byte_count;
-	hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
+	if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
+			&hm.h.obj_index))
+		return HPI_ERROR_INVALID_HANDLE;
 
 
-	if (byte_count <= 8) {
-		memcpy(hm.u.cx.u.cobranet_data.data, pb_data, byte_count);
-		hm.u.cx.attribute = HPI_COBRANET_SET;
-	} else {
-		hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
-		hm.u.cx.attribute = HPI_COBRANET_SET_DATA;
-	}
+	if (byte_count > sizeof(hm.bytes))
+		return HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
 
 
-	hpi_send_recv(&hm, &hr);
+	hm.p.attribute = HPI_COBRANET_SET;
+	hm.p.byte_count = byte_count;
+	hm.p.hmi_address = hmi_address;
+	memcpy(hm.bytes, pb_data, byte_count);
+	hm.h.size = (u16)(sizeof(hm.h) + sizeof(hm.p) + byte_count);
 
 
+	hpi_send_recvV1(&hm.h, &hr);
 	return hr.error;
 	return hr.error;
 }
 }
 
 
 u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
 u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
 	u32 *pbyte_count, u8 *pb_data)
 	u32 *pbyte_count, u8 *pb_data)
 {
 {
-	struct hpi_message hm;
-	struct hpi_response hr;
+	struct hpi_msg_cobranet_hmiread hm;
+	struct hpi_res_cobranet_hmiread hr;
 
 
-	hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
-		HPI_CONTROL_GET_STATE);
-	if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
+	hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr.h, sizeof(hr),
+		HPI_OBJ_CONTROL, HPI_CONTROL_GET_STATE);
+
+	if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
+			&hm.h.obj_index))
 		return HPI_ERROR_INVALID_HANDLE;
 		return HPI_ERROR_INVALID_HANDLE;
 
 
-	hm.u.cx.u.cobranet_data.byte_count = max_byte_count;
-	hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
+	if (max_byte_count > sizeof(hr.bytes))
+		return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
 
 
-	if (max_byte_count <= 8) {
-		hm.u.cx.attribute = HPI_COBRANET_GET;
-	} else {
-		hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
-		hm.u.cx.attribute = HPI_COBRANET_GET_DATA;
-	}
+	hm.p.attribute = HPI_COBRANET_GET;
+	hm.p.byte_count = max_byte_count;
+	hm.p.hmi_address = hmi_address;
 
 
-	hpi_send_recv(&hm, &hr);
-	if (!hr.error && pb_data) {
+	hpi_send_recvV1(&hm.h, &hr.h);
 
 
-		*pbyte_count = hr.u.cx.u.cobranet_data.byte_count;
+	if (!hr.h.error && pb_data) {
+		if (hr.byte_count > sizeof(hr.bytes))
 
 
-		if (*pbyte_count < max_byte_count)
-			max_byte_count = *pbyte_count;
+			return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
 
 
-		if (hm.u.cx.attribute == HPI_COBRANET_GET) {
-			memcpy(pb_data, hr.u.cx.u.cobranet_data.data,
-				max_byte_count);
-		} else {
+		*pbyte_count = hr.byte_count;
 
 
-		}
+		if (hr.byte_count < max_byte_count)
+			max_byte_count = *pbyte_count;
 
 
+		memcpy(pb_data, hr.bytes, max_byte_count);
 	}
 	}
-	return hr.error;
+	return hr.h.error;
 }
 }
 
 
 u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
 u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
@@ -1733,23 +1729,23 @@ u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
 	struct hpi_message hm;
 	struct hpi_message hm;
 	struct hpi_response hr;
 	struct hpi_response hr;
 
 
-	hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
+	hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
 		HPI_CONTROL_GET_STATE);
 		HPI_CONTROL_GET_STATE);
 	if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
 	if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
 		return HPI_ERROR_INVALID_HANDLE;
 		return HPI_ERROR_INVALID_HANDLE;
 
 
-	hm.u.cx.attribute = HPI_COBRANET_GET_STATUS;
+	hm.u.c.attribute = HPI_COBRANET_GET_STATUS;
 
 
 	hpi_send_recv(&hm, &hr);
 	hpi_send_recv(&hm, &hr);
 	if (!hr.error) {
 	if (!hr.error) {
 		if (pstatus)
 		if (pstatus)
-			*pstatus = hr.u.cx.u.cobranet_status.status;
+			*pstatus = hr.u.cu.cobranet.status.status;
 		if (preadable_size)
 		if (preadable_size)
 			*preadable_size =
 			*preadable_size =
-				hr.u.cx.u.cobranet_status.readable_size;
+				hr.u.cu.cobranet.status.readable_size;
 		if (pwriteable_size)
 		if (pwriteable_size)
 			*pwriteable_size =
 			*pwriteable_size =
-				hr.u.cx.u.cobranet_status.writeable_size;
+				hr.u.cu.cobranet.status.writeable_size;
 	}
 	}
 	return hr.error;
 	return hr.error;
 }
 }

+ 2 - 2
sound/pci/asihpi/hpimsginit.c

@@ -46,7 +46,7 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
 	if (gwSSX2_bypass)
 	if (gwSSX2_bypass)
 		phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
 		phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
 	else
 	else
-		phm->type = HPI_TYPE_MESSAGE;
+		phm->type = HPI_TYPE_REQUEST;
 	phm->object = object;
 	phm->object = object;
 	phm->function = function;
 	phm->function = function;
 	phm->version = 0;
 	phm->version = 0;
@@ -89,7 +89,7 @@ static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
 	memset(phm, 0, sizeof(*phm));
 	memset(phm, 0, sizeof(*phm));
 	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
 	if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
 		phm->size = size;
 		phm->size = size;
-		phm->type = HPI_TYPE_MESSAGE;
+		phm->type = HPI_TYPE_REQUEST;
 		phm->object = object;
 		phm->object = object;
 		phm->function = function;
 		phm->function = function;
 		phm->version = 1;
 		phm->version = 1;

+ 2 - 4
sound/pci/asihpi/hpimsgx.c

@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 
-Extended Message Function With Response Cacheing
+Extended Message Function With Response Caching
 
 
 (C) Copyright AudioScience Inc. 2002
 (C) Copyright AudioScience Inc. 2002
 *****************************************************************************/
 *****************************************************************************/
@@ -186,7 +186,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
 		/* Initialize this module's internal state */
 		/* Initialize this module's internal state */
 		hpios_msgxlock_init(&msgx_lock);
 		hpios_msgxlock_init(&msgx_lock);
 		memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
 		memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
-		hpios_locked_mem_init();
 		/* Init subsys_findadapters response to no-adapters */
 		/* Init subsys_findadapters response to no-adapters */
 		HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
 		HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
 		hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
 		hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
@@ -197,7 +196,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
 	case HPI_SUBSYS_DRIVER_UNLOAD:
 	case HPI_SUBSYS_DRIVER_UNLOAD:
 		HPI_COMMON(phm, phr);
 		HPI_COMMON(phm, phr);
 		HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
 		HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
-		hpios_locked_mem_free_all();
 		hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
 		hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
 			HPI_SUBSYS_DRIVER_UNLOAD, 0);
 			HPI_SUBSYS_DRIVER_UNLOAD, 0);
 		return;
 		return;
@@ -315,7 +313,7 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
 {
 {
 	HPI_DEBUG_MESSAGE(DEBUG, phm);
 	HPI_DEBUG_MESSAGE(DEBUG, phm);
 
 
-	if (phm->type != HPI_TYPE_MESSAGE) {
+	if (phm->type != HPI_TYPE_REQUEST) {
 		hpi_init_response(phr, phm->object, phm->function,
 		hpi_init_response(phr, phm->object, phm->function,
 			HPI_ERROR_INVALID_TYPE);
 			HPI_ERROR_INVALID_TYPE);
 		return;
 		return;

+ 3 - 7
sound/pci/asihpi/hpioctl.c

@@ -1,7 +1,7 @@
 /*******************************************************************************
 /*******************************************************************************
 
 
     AudioScience HPI driver
     AudioScience HPI driver
-    Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
+    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
 
 
     This program is free software; you can redistribute it and/or modify
     This program is free software; you can redistribute it and/or modify
     it under the terms of version 2 of the GNU General Public License as
     it under the terms of version 2 of the GNU General Public License as
@@ -157,11 +157,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		goto out;
 		goto out;
 	}
 	}
 
 
-	if (hm->h.adapter_index >= HPI_MAX_ADAPTERS) {
-		err = -EINVAL;
-		goto out;
-	}
-
 	switch (hm->h.function) {
 	switch (hm->h.function) {
 	case HPI_SUBSYS_CREATE_ADAPTER:
 	case HPI_SUBSYS_CREATE_ADAPTER:
 	case HPI_ADAPTER_DELETE:
 	case HPI_ADAPTER_DELETE:
@@ -187,7 +182,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		/* -1=no data 0=read from user mem, 1=write to user mem */
 		/* -1=no data 0=read from user mem, 1=write to user mem */
 		int wrflag = -1;
 		int wrflag = -1;
 		u32 adapter = hm->h.adapter_index;
 		u32 adapter = hm->h.adapter_index;
-		pa = &adapters[adapter];
 
 
 		if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
 		if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
 			hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
 			hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
@@ -203,6 +197,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 			goto out;
 			goto out;
 		}
 		}
 
 
+		pa = &adapters[adapter];
+
 		if (mutex_lock_interruptible(&adapters[adapter].mutex)) {
 		if (mutex_lock_interruptible(&adapters[adapter].mutex)) {
 			err = -EINTR;
 			err = -EINTR;
 			goto out;
 			goto out;

+ 0 - 8
sound/pci/asihpi/hpios.c

@@ -39,10 +39,6 @@ void hpios_delay_micro_seconds(u32 num_micro_sec)
 
 
 }
 }
 
 
-void hpios_locked_mem_init(void)
-{
-}
-
 /** Allocated an area of locked memory for bus master DMA operations.
 /** Allocated an area of locked memory for bus master DMA operations.
 
 
 On error, return -ENOMEM, and *pMemArea.size = 0
 On error, return -ENOMEM, and *pMemArea.size = 0
@@ -85,7 +81,3 @@ u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
 		return 1;
 		return 1;
 	}
 	}
 }
 }
-
-void hpios_locked_mem_free_all(void)
-{
-}

+ 1 - 0
sound/pci/asihpi/hpios.h

@@ -38,6 +38,7 @@ HPI Operating System Specific macros for Linux Kernel driver
 #include <linux/firmware.h>
 #include <linux/firmware.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
+#include <linux/mutex.h>
 
 
 #define HPI_NO_OS_FILE_OPS
 #define HPI_NO_OS_FILE_OPS
 
 

+ 2 - 2
sound/pci/atiixp.c

@@ -1624,7 +1624,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
-			card->shortname, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_atiixp_free(chip);
 		snd_atiixp_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -1701,7 +1701,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "ATI IXP AC97 controller",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_atiixp_ids,
 	.id_table = snd_atiixp_ids,
 	.probe = snd_atiixp_probe,
 	.probe = snd_atiixp_probe,
 	.remove = __devexit_p(snd_atiixp_remove),
 	.remove = __devexit_p(snd_atiixp_remove),

+ 2 - 2
sound/pci/atiixp_modem.c

@@ -1260,7 +1260,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
-			card->shortname, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_atiixp_free(chip);
 		snd_atiixp_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -1332,7 +1332,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "ATI IXP MC97 controller",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_atiixp_ids,
 	.id_table = snd_atiixp_ids,
 	.probe = snd_atiixp_probe,
 	.probe = snd_atiixp_probe,
 	.remove = __devexit_p(snd_atiixp_remove),
 	.remove = __devexit_p(snd_atiixp_remove),

+ 2 - 2
sound/pci/au88x0/au88x0.c

@@ -196,7 +196,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
 	}
 	}
 
 
 	if ((err = request_irq(pci->irq, vortex_interrupt,
 	if ((err = request_irq(pci->irq, vortex_interrupt,
-	                       IRQF_SHARED, CARD_NAME_SHORT,
+			       IRQF_SHARED, KBUILD_MODNAME,
 	                       chip)) != 0) {
 	                       chip)) != 0) {
 		printk(KERN_ERR "cannot grab irq\n");
 		printk(KERN_ERR "cannot grab irq\n");
 		goto irq_out;
 		goto irq_out;
@@ -375,7 +375,7 @@ static void __devexit snd_vortex_remove(struct pci_dev *pci)
 
 
 // pci_driver definition
 // pci_driver definition
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = CARD_NAME_SHORT,
+	.name = KBUILD_MODNAME,
 	.id_table = snd_vortex_ids,
 	.id_table = snd_vortex_ids,
 	.probe = snd_vortex_probe,
 	.probe = snd_vortex_probe,
 	.remove = __devexit_p(snd_vortex_remove),
 	.remove = __devexit_p(snd_vortex_remove),

+ 2 - 2
sound/pci/aw2/aw2-alsa.c

@@ -171,7 +171,7 @@ MODULE_DEVICE_TABLE(pci, snd_aw2_ids);
 
 
 /* pci_driver definition */
 /* pci_driver definition */
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Emagic Audiowerk 2",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_aw2_ids,
 	.id_table = snd_aw2_ids,
 	.probe = snd_aw2_probe,
 	.probe = snd_aw2_probe,
 	.remove = __devexit_p(snd_aw2_remove),
 	.remove = __devexit_p(snd_aw2_remove),
@@ -317,7 +317,7 @@ static int __devinit snd_aw2_create(struct snd_card *card,
 	snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
 	snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
 
 
 	if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
 	if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
-			IRQF_SHARED, "Audiowerk2", chip)) {
+			IRQF_SHARED, KBUILD_MODNAME, chip)) {
 		printk(KERN_ERR "aw2: Cannot grab irq %d\n", pci->irq);
 		printk(KERN_ERR "aw2: Cannot grab irq %d\n", pci->irq);
 
 
 		iounmap(chip->iobase_virt);
 		iounmap(chip->iobase_virt);

+ 2 - 2
sound/pci/azt3328.c

@@ -2559,7 +2559,7 @@ snd_azf3328_create(struct snd_card *card,
 	codec_setup->name = "I2S_OUT";
 	codec_setup->name = "I2S_OUT";
 
 
 	if (request_irq(pci->irq, snd_azf3328_interrupt,
 	if (request_irq(pci->irq, snd_azf3328_interrupt,
-			IRQF_SHARED, card->shortname, chip)) {
+			IRQF_SHARED, KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		err = -EBUSY;
 		err = -EBUSY;
 		goto out_err;
 		goto out_err;
@@ -2860,7 +2860,7 @@ snd_azf3328_resume(struct pci_dev *pci)
 
 
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "AZF3328",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_azf3328_ids,
 	.id_table = snd_azf3328_ids,
 	.probe = snd_azf3328_probe,
 	.probe = snd_azf3328_probe,
 	.remove = __devexit_p(snd_azf3328_remove),
 	.remove = __devexit_p(snd_azf3328_remove),

+ 2 - 2
sound/pci/bt87x.c

@@ -760,7 +760,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
 	snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
 	snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
 
 
 	err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
 	err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
-			  "Bt87x audio", chip);
+			  KBUILD_MODNAME, chip);
 	if (err < 0) {
 	if (err < 0) {
 		snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
 		snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
 		goto fail;
 		goto fail;
@@ -965,7 +965,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = {
 };
 };
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Bt87x",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_bt87x_ids,
 	.id_table = snd_bt87x_ids,
 	.probe = snd_bt87x_probe,
 	.probe = snd_bt87x_probe,
 	.remove = __devexit_p(snd_bt87x_remove),
 	.remove = __devexit_p(snd_bt87x_remove),

+ 2 - 2
sound/pci/ca0106/ca0106_main.c

@@ -1666,7 +1666,7 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_ca0106_interrupt,
 	if (request_irq(pci->irq, snd_ca0106_interrupt,
-			IRQF_SHARED, "snd_ca0106", chip)) {
+			IRQF_SHARED, KBUILD_MODNAME, chip)) {
 		snd_ca0106_free(chip);
 		snd_ca0106_free(chip);
 		printk(KERN_ERR "cannot grab irq\n");
 		printk(KERN_ERR "cannot grab irq\n");
 		return -EBUSY;
 		return -EBUSY;
@@ -1933,7 +1933,7 @@ MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
 
 
 // pci_driver definition
 // pci_driver definition
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "CA0106",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_ca0106_ids,
 	.id_table = snd_ca0106_ids,
 	.probe = snd_ca0106_probe,
 	.probe = snd_ca0106_probe,
 	.remove = __devexit_p(snd_ca0106_remove),
 	.remove = __devexit_p(snd_ca0106_remove),

+ 2 - 2
sound/pci/cmipci.c

@@ -3053,7 +3053,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
 	cm->iobase = pci_resource_start(pci, 0);
 	cm->iobase = pci_resource_start(pci, 0);
 
 
 	if (request_irq(pci->irq, snd_cmipci_interrupt,
 	if (request_irq(pci->irq, snd_cmipci_interrupt,
-			IRQF_SHARED, card->driver, cm)) {
+			IRQF_SHARED, KBUILD_MODNAME, cm)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cmipci_free(cm);
 		snd_cmipci_free(cm);
 		return -EBUSY;
 		return -EBUSY;
@@ -3398,7 +3398,7 @@ static int snd_cmipci_resume(struct pci_dev *pci)
 #endif /* CONFIG_PM */
 #endif /* CONFIG_PM */
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "C-Media PCI",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_cmipci_ids,
 	.id_table = snd_cmipci_ids,
 	.probe = snd_cmipci_probe,
 	.probe = snd_cmipci_probe,
 	.remove = __devexit_p(snd_cmipci_remove),
 	.remove = __devexit_p(snd_cmipci_remove),

+ 2 - 2
sound/pci/cs4281.c

@@ -1382,7 +1382,7 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
 	}
 	}
 	
 	
 	if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED,
-			"CS4281", chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cs4281_free(chip);
 		snd_cs4281_free(chip);
 		return -ENOMEM;
 		return -ENOMEM;
@@ -2085,7 +2085,7 @@ static int cs4281_resume(struct pci_dev *pci)
 #endif /* CONFIG_PM */
 #endif /* CONFIG_PM */
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "CS4281",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_cs4281_ids,
 	.id_table = snd_cs4281_ids,
 	.probe = snd_cs4281_probe,
 	.probe = snd_cs4281_probe,
 	.remove = __devexit_p(snd_cs4281_remove),
 	.remove = __devexit_p(snd_cs4281_remove),

+ 1 - 1
sound/pci/cs46xx/cs46xx.c

@@ -162,7 +162,7 @@ static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Sound Fusion CS46xx",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_cs46xx_ids,
 	.id_table = snd_cs46xx_ids,
 	.probe = snd_card_cs46xx_probe,
 	.probe = snd_card_cs46xx_probe,
 	.remove = __devexit_p(snd_card_cs46xx_remove),
 	.remove = __devexit_p(snd_card_cs46xx_remove),

+ 1 - 1
sound/pci/cs46xx/cs46xx_lib.c

@@ -3835,7 +3835,7 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
-			"CS46XX", chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cs46xx_free(chip);
 		snd_cs46xx_free(chip);
 		return -EBUSY;
 		return -EBUSY;

+ 1 - 1
sound/pci/cs5530.c

@@ -285,7 +285,7 @@ static int __devinit snd_cs5530_probe(struct pci_dev *pci,
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "CS5530_Audio",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_cs5530_ids,
 	.id_table = snd_cs5530_ids,
 	.probe = snd_cs5530_probe,
 	.probe = snd_cs5530_probe,
 	.remove = __devexit_p(snd_cs5530_remove),
 	.remove = __devexit_p(snd_cs5530_remove),

+ 2 - 2
sound/pci/cs5535audio/cs5535audio.c

@@ -311,7 +311,7 @@ static int __devinit snd_cs5535audio_create(struct snd_card *card,
 	cs5535au->port = pci_resource_start(pci, 0);
 	cs5535au->port = pci_resource_start(pci, 0);
 
 
 	if (request_irq(pci->irq, snd_cs5535audio_interrupt,
 	if (request_irq(pci->irq, snd_cs5535audio_interrupt,
-			IRQF_SHARED, "CS5535 Audio", cs5535au)) {
+			IRQF_SHARED, KBUILD_MODNAME, cs5535au)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		err = -EBUSY;
 		err = -EBUSY;
 		goto sndfail;
 		goto sndfail;
@@ -395,7 +395,7 @@ static void __devexit snd_cs5535audio_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = DRIVER_NAME,
+	.name = KBUILD_MODNAME,
 	.id_table = snd_cs5535audio_ids,
 	.id_table = snd_cs5535audio_ids,
 	.probe = snd_cs5535audio_probe,
 	.probe = snd_cs5535audio_probe,
 	.remove = __devexit_p(snd_cs5535audio_remove),
 	.remove = __devexit_p(snd_cs5535audio_remove),

+ 1 - 0
sound/pci/ctxfi/ct20k2reg.h

@@ -55,6 +55,7 @@
 /* GPIO Registers */
 /* GPIO Registers */
 #define GPIO_DATA           0x1B7020
 #define GPIO_DATA           0x1B7020
 #define GPIO_CTRL           0x1B7024
 #define GPIO_CTRL           0x1B7024
+#define GPIO_EXT_DATA       0x1B70A0
 
 
 /* Virtual memory registers */
 /* Virtual memory registers */
 #define VMEM_PTPAL          0x1C6300 /* 0x1C6300 + (16 * Chn) */
 #define VMEM_PTPAL          0x1C6300 /* 0x1C6300 + (16 * Chn) */

+ 71 - 36
sound/pci/ctxfi/ctatc.c

@@ -18,7 +18,6 @@
 #include "ctatc.h"
 #include "ctatc.h"
 #include "ctpcm.h"
 #include "ctpcm.h"
 #include "ctmixer.h"
 #include "ctmixer.h"
-#include "cthardware.h"
 #include "ctsrc.h"
 #include "ctsrc.h"
 #include "ctamixer.h"
 #include "ctamixer.h"
 #include "ctdaio.h"
 #include "ctdaio.h"
@@ -30,7 +29,6 @@
 #include <sound/asoundef.h>
 #include <sound/asoundef.h>
 
 
 #define MONO_SUM_SCALE	0x19a8	/* 2^(-0.5) in 14-bit floating format */
 #define MONO_SUM_SCALE	0x19a8	/* 2^(-0.5) in 14-bit floating format */
-#define DAIONUM		7
 #define MAX_MULTI_CHN	8
 #define MAX_MULTI_CHN	8
 
 
 #define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \
 #define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \
@@ -53,6 +51,8 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
 static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
 static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
 		      "SB0760", CTSB0760),
 		      "SB0760", CTSB0760),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB1270,
+		      "SB1270", CTSB1270),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801,
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801,
 		      "SB0880", CTSB0880),
 		      "SB0880", CTSB0880),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802,
 	SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802,
@@ -75,6 +75,7 @@ static const char *ct_subsys_name[NUM_CTCARDS] = {
 	[CTSB0760]	= "SB076x",
 	[CTSB0760]	= "SB076x",
 	[CTHENDRIX]	= "Hendrix",
 	[CTHENDRIX]	= "Hendrix",
 	[CTSB0880]	= "SB0880",
 	[CTSB0880]	= "SB0880",
+	[CTSB1270]      = "SB1270",
 	[CT20K2_UNKNOWN] = "Unknown",
 	[CT20K2_UNKNOWN] = "Unknown",
 };
 };
 
 
@@ -459,12 +460,12 @@ static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm,
 				apcm->substream->runtime->rate);
 				apcm->substream->runtime->rate);
 	*n_srcc = 0;
 	*n_srcc = 0;
 
 
-	if (1 == atc->msr) {
+	if (1 == atc->msr) { /* FIXME: do we really need SRC here if pitch==1 */
 		*n_srcc = apcm->substream->runtime->channels;
 		*n_srcc = apcm->substream->runtime->channels;
 		conf[0].pitch = pitch;
 		conf[0].pitch = pitch;
 		conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1;
 		conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1;
 		conf[0].vo = 1;
 		conf[0].vo = 1;
-	} else if (2 == atc->msr) {
+	} else if (2 <= atc->msr) {
 		if (0x8000000 < pitch) {
 		if (0x8000000 < pitch) {
 			/* Need two-stage SRCs, SRCIMPs and
 			/* Need two-stage SRCs, SRCIMPs and
 			 * AMIXERs for converting format */
 			 * AMIXERs for converting format */
@@ -970,11 +971,39 @@ static int atc_select_mic_in(struct ct_atc *atc)
 	return 0;
 	return 0;
 }
 }
 
 
-static int atc_have_digit_io_switch(struct ct_atc *atc)
+static struct capabilities atc_capabilities(struct ct_atc *atc)
 {
 {
 	struct hw *hw = atc->hw;
 	struct hw *hw = atc->hw;
 
 
-	return hw->have_digit_io_switch(hw);
+	return hw->capabilities(hw);
+}
+
+static int atc_output_switch_get(struct ct_atc *atc)
+{
+	struct hw *hw = atc->hw;
+
+	return hw->output_switch_get(hw);
+}
+
+static int atc_output_switch_put(struct ct_atc *atc, int position)
+{
+	struct hw *hw = atc->hw;
+
+	return hw->output_switch_put(hw, position);
+}
+
+static int atc_mic_source_switch_get(struct ct_atc *atc)
+{
+	struct hw *hw = atc->hw;
+
+	return hw->mic_source_switch_get(hw);
+}
+
+static int atc_mic_source_switch_put(struct ct_atc *atc, int position)
+{
+	struct hw *hw = atc->hw;
+
+	return hw->mic_source_switch_put(hw, position);
 }
 }
 
 
 static int atc_select_digit_io(struct ct_atc *atc)
 static int atc_select_digit_io(struct ct_atc *atc)
@@ -1045,6 +1074,11 @@ static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
 	return atc_daio_unmute(atc, state, LINEIM);
 	return atc_daio_unmute(atc, state, LINEIM);
 }
 }
 
 
+static int atc_mic_unmute(struct ct_atc *atc, unsigned char state)
+{
+	return atc_daio_unmute(atc, state, MIC);
+}
+
 static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state)
 static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state)
 {
 {
 	return atc_daio_unmute(atc, state, SPDIFOO);
 	return atc_daio_unmute(atc, state, SPDIFOO);
@@ -1331,17 +1365,20 @@ static int atc_get_resources(struct ct_atc *atc)
 	struct srcimp_mgr *srcimp_mgr;
 	struct srcimp_mgr *srcimp_mgr;
 	struct sum_desc sum_dsc = {0};
 	struct sum_desc sum_dsc = {0};
 	struct sum_mgr *sum_mgr;
 	struct sum_mgr *sum_mgr;
-	int err, i;
+	int err, i, num_srcs, num_daios;
 
 
-	atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL);
+	num_daios = ((atc->model == CTSB1270) ? 8 : 7);
+	num_srcs = ((atc->model == CTSB1270) ? 6 : 4);
+
+	atc->daios = kzalloc(sizeof(void *)*num_daios, GFP_KERNEL);
 	if (!atc->daios)
 	if (!atc->daios)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
+	atc->srcs = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
 	if (!atc->srcs)
 	if (!atc->srcs)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
+	atc->srcimps = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
 	if (!atc->srcimps)
 	if (!atc->srcimps)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -1351,8 +1388,9 @@ static int atc_get_resources(struct ct_atc *atc)
 
 
 	daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
 	daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
 	da_desc.msr = atc->msr;
 	da_desc.msr = atc->msr;
-	for (i = 0, atc->n_daio = 0; i < DAIONUM-1; i++) {
-		da_desc.type = i;
+	for (i = 0, atc->n_daio = 0; i < num_daios; i++) {
+		da_desc.type = (atc->model != CTSB073X) ? i :
+			     ((i == SPDIFIO) ? SPDIFI1 : i);
 		err = daio_mgr->get_daio(daio_mgr, &da_desc,
 		err = daio_mgr->get_daio(daio_mgr, &da_desc,
 					(struct daio **)&atc->daios[i]);
 					(struct daio **)&atc->daios[i]);
 		if (err) {
 		if (err) {
@@ -1362,23 +1400,12 @@ static int atc_get_resources(struct ct_atc *atc)
 		}
 		}
 		atc->n_daio++;
 		atc->n_daio++;
 	}
 	}
-	if (atc->model == CTSB073X)
-		da_desc.type = SPDIFI1;
-	else
-		da_desc.type = SPDIFIO;
-	err = daio_mgr->get_daio(daio_mgr, &da_desc,
-				(struct daio **)&atc->daios[i]);
-	if (err) {
-		printk(KERN_ERR "ctxfi: Failed to get S/PDIF-in resource!!!\n");
-		return err;
-	}
-	atc->n_daio++;
 
 
 	src_mgr = atc->rsc_mgrs[SRC];
 	src_mgr = atc->rsc_mgrs[SRC];
 	src_dsc.multi = 1;
 	src_dsc.multi = 1;
 	src_dsc.msr = atc->msr;
 	src_dsc.msr = atc->msr;
 	src_dsc.mode = ARCRW;
 	src_dsc.mode = ARCRW;
-	for (i = 0, atc->n_src = 0; i < (2*2); i++) {
+	for (i = 0, atc->n_src = 0; i < num_srcs; i++) {
 		err = src_mgr->get_src(src_mgr, &src_dsc,
 		err = src_mgr->get_src(src_mgr, &src_dsc,
 					(struct src **)&atc->srcs[i]);
 					(struct src **)&atc->srcs[i]);
 		if (err)
 		if (err)
@@ -1388,8 +1415,8 @@ static int atc_get_resources(struct ct_atc *atc)
 	}
 	}
 
 
 	srcimp_mgr = atc->rsc_mgrs[SRCIMP];
 	srcimp_mgr = atc->rsc_mgrs[SRCIMP];
-	srcimp_dsc.msr = 8; /* SRCIMPs for S/PDIFIn SRT */
-	for (i = 0, atc->n_srcimp = 0; i < (2*1); i++) {
+	srcimp_dsc.msr = 8;
+	for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) {
 		err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
 		err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
 					(struct srcimp **)&atc->srcimps[i]);
 					(struct srcimp **)&atc->srcimps[i]);
 		if (err)
 		if (err)
@@ -1397,15 +1424,6 @@ static int atc_get_resources(struct ct_atc *atc)
 
 
 		atc->n_srcimp++;
 		atc->n_srcimp++;
 	}
 	}
-	srcimp_dsc.msr = 8; /* SRCIMPs for LINE/MICIn SRT */
-	for (i = 0; i < (2*1); i++) {
-		err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
-				(struct srcimp **)&atc->srcimps[2*1+i]);
-		if (err)
-			return err;
-
-		atc->n_srcimp++;
-	}
 
 
 	sum_mgr = atc->rsc_mgrs[SUM];
 	sum_mgr = atc->rsc_mgrs[SUM];
 	sum_dsc.msr = atc->msr;
 	sum_dsc.msr = atc->msr;
@@ -1488,6 +1506,18 @@ static void atc_connect_resources(struct ct_atc *atc)
 	src = atc->srcs[3];
 	src = atc->srcs[3];
 	mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
 	mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
 
 
+	if (atc->model == CTSB1270) {
+		/* Titanium HD has a dedicated ADC for the Mic. */
+		dai = container_of(atc->daios[MIC], struct dai, daio);
+		atc_connect_dai(atc->rsc_mgrs[SRC], dai,
+			(struct src **)&atc->srcs[4],
+			(struct srcimp **)&atc->srcimps[4]);
+		src = atc->srcs[4];
+		mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc);
+		src = atc->srcs[5];
+		mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc);
+	}
+
 	dai = container_of(atc->daios[SPDIFIO], struct dai, daio);
 	dai = container_of(atc->daios[SPDIFIO], struct dai, daio);
 	atc_connect_dai(atc->rsc_mgrs[SRC], dai,
 	atc_connect_dai(atc->rsc_mgrs[SRC], dai,
 			(struct src **)&atc->srcs[0],
 			(struct src **)&atc->srcs[0],
@@ -1606,12 +1636,17 @@ static struct ct_atc atc_preset __devinitdata = {
 	.line_clfe_unmute = atc_line_clfe_unmute,
 	.line_clfe_unmute = atc_line_clfe_unmute,
 	.line_rear_unmute = atc_line_rear_unmute,
 	.line_rear_unmute = atc_line_rear_unmute,
 	.line_in_unmute = atc_line_in_unmute,
 	.line_in_unmute = atc_line_in_unmute,
+	.mic_unmute = atc_mic_unmute,
 	.spdif_out_unmute = atc_spdif_out_unmute,
 	.spdif_out_unmute = atc_spdif_out_unmute,
 	.spdif_in_unmute = atc_spdif_in_unmute,
 	.spdif_in_unmute = atc_spdif_in_unmute,
 	.spdif_out_get_status = atc_spdif_out_get_status,
 	.spdif_out_get_status = atc_spdif_out_get_status,
 	.spdif_out_set_status = atc_spdif_out_set_status,
 	.spdif_out_set_status = atc_spdif_out_set_status,
 	.spdif_out_passthru = atc_spdif_out_passthru,
 	.spdif_out_passthru = atc_spdif_out_passthru,
-	.have_digit_io_switch = atc_have_digit_io_switch,
+	.capabilities = atc_capabilities,
+	.output_switch_get = atc_output_switch_get,
+	.output_switch_put = atc_output_switch_put,
+	.mic_source_switch_get = atc_mic_source_switch_get,
+	.mic_source_switch_put = atc_mic_source_switch_put,
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
 	.suspend = atc_suspend,
 	.suspend = atc_suspend,
 	.resume = atc_resume,
 	.resume = atc_resume,

+ 7 - 1
sound/pci/ctxfi/ctatc.h

@@ -25,6 +25,7 @@
 #include <sound/core.h>
 #include <sound/core.h>
 
 
 #include "ctvmem.h"
 #include "ctvmem.h"
+#include "cthardware.h"
 #include "ctresource.h"
 #include "ctresource.h"
 
 
 enum CTALSADEVS {		/* Types of alsa devices */
 enum CTALSADEVS {		/* Types of alsa devices */
@@ -115,12 +116,17 @@ struct ct_atc {
 	int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*line_in_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*line_in_unmute)(struct ct_atc *atc, unsigned char state);
+	int (*mic_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state);
 	int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
 	int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
 	int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
 	int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
 	int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
 	int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
-	int (*have_digit_io_switch)(struct ct_atc *atc);
+	struct capabilities (*capabilities)(struct ct_atc *atc);
+	int (*output_switch_get)(struct ct_atc *atc);
+	int (*output_switch_put)(struct ct_atc *atc, int position);
+	int (*mic_source_switch_get)(struct ct_atc *atc);
+	int (*mic_source_switch_put)(struct ct_atc *atc, int position);
 
 
 	/* Don't touch! Used for internal object. */
 	/* Don't touch! Used for internal object. */
 	void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */
 	void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */

+ 7 - 16
sound/pci/ctxfi/ctdaio.c

@@ -22,20 +22,9 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 
 
-#define DAIO_RESOURCE_NUM	NUM_DAIOTYP
 #define DAIO_OUT_MAX		SPDIFOO
 #define DAIO_OUT_MAX		SPDIFOO
 
 
-union daio_usage {
-	struct {
-		unsigned short lineo1:1;
-		unsigned short lineo2:1;
-		unsigned short lineo3:1;
-		unsigned short lineo4:1;
-		unsigned short spdifoo:1;
-		unsigned short lineim:1;
-		unsigned short spdifio:1;
-		unsigned short spdifi1:1;
-	} bf;
+struct daio_usage {
 	unsigned short data;
 	unsigned short data;
 };
 };
 
 
@@ -61,6 +50,7 @@ struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
 	[LINEO3] = {.left = 0x50, .right = 0x51},
 	[LINEO3] = {.left = 0x50, .right = 0x51},
 	[LINEO4] = {.left = 0x70, .right = 0x71},
 	[LINEO4] = {.left = 0x70, .right = 0x71},
 	[LINEIM] = {.left = 0x45, .right = 0xc5},
 	[LINEIM] = {.left = 0x45, .right = 0xc5},
+	[MIC]	 = {.left = 0x55, .right = 0xd5},
 	[SPDIFOO] = {.left = 0x00, .right = 0x01},
 	[SPDIFOO] = {.left = 0x00, .right = 0x01},
 	[SPDIFIO] = {.left = 0x05, .right = 0x85},
 	[SPDIFIO] = {.left = 0x05, .right = 0x85},
 };
 };
@@ -138,6 +128,7 @@ static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
 		case LINEO3:	return 5;
 		case LINEO3:	return 5;
 		case LINEO4:	return 6;
 		case LINEO4:	return 6;
 		case LINEIM:	return 4;
 		case LINEIM:	return 4;
+		case MIC:	return 5;
 		default:	return -EINVAL;
 		default:	return -EINVAL;
 		}
 		}
 	default:
 	default:
@@ -519,17 +510,17 @@ static int dai_rsc_uninit(struct dai *dai)
 
 
 static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
 static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
 {
 {
-	if (((union daio_usage *)mgr->rscs)->data & (0x1 << type))
+	if (((struct daio_usage *)mgr->rscs)->data & (0x1 << type))
 		return -ENOENT;
 		return -ENOENT;
 
 
-	((union daio_usage *)mgr->rscs)->data |= (0x1 << type);
+	((struct daio_usage *)mgr->rscs)->data |= (0x1 << type);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
 static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
 static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
 {
 {
-	((union daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
+	((struct daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -712,7 +703,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
 	if (!daio_mgr)
 	if (!daio_mgr)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw);
+	err = rsc_mgr_init(&daio_mgr->mgr, DAIO, NUM_DAIOTYP, hw);
 	if (err)
 	if (err)
 		goto error1;
 		goto error1;
 
 

+ 1 - 0
sound/pci/ctxfi/ctdaio.h

@@ -33,6 +33,7 @@ enum DAIOTYP {
 	SPDIFOO,	/* S/PDIF Out (Flexijack/Optical) */
 	SPDIFOO,	/* S/PDIF Out (Flexijack/Optical) */
 	LINEIM,
 	LINEIM,
 	SPDIFIO,	/* S/PDIF In (Flexijack/Optical) on the card */
 	SPDIFIO,	/* S/PDIF In (Flexijack/Optical) on the card */
+	MIC,		/* Dedicated mic on Titanium HD */
 	SPDIFI1,	/* S/PDIF In on internal Drive Bay */
 	SPDIFI1,	/* S/PDIF In on internal Drive Bay */
 	NUM_DAIOTYP
 	NUM_DAIOTYP
 };
 };

+ 13 - 1
sound/pci/ctxfi/cthardware.h

@@ -39,6 +39,7 @@ enum CTCARDS {
 	CT20K2_MODEL_FIRST = CTSB0760,
 	CT20K2_MODEL_FIRST = CTSB0760,
 	CTHENDRIX,
 	CTHENDRIX,
 	CTSB0880,
 	CTSB0880,
+	CTSB1270,
 	CT20K2_UNKNOWN,
 	CT20K2_UNKNOWN,
 	NUM_CTCARDS		/* This should always be the last */
 	NUM_CTCARDS		/* This should always be the last */
 };
 };
@@ -60,6 +61,13 @@ struct card_conf {
 	unsigned int msr;	/* master sample rate in rsrs */
 	unsigned int msr;	/* master sample rate in rsrs */
 };
 };
 
 
+struct capabilities {
+	unsigned int digit_io_switch:1;
+	unsigned int dedicated_mic:1;
+	unsigned int output_switch:1;
+	unsigned int mic_source_switch:1;
+};
+
 struct hw {
 struct hw {
 	int (*card_init)(struct hw *hw, struct card_conf *info);
 	int (*card_init)(struct hw *hw, struct card_conf *info);
 	int (*card_stop)(struct hw *hw);
 	int (*card_stop)(struct hw *hw);
@@ -70,7 +78,11 @@ struct hw {
 #endif
 #endif
 	int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
 	int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
 	int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
 	int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
-	int (*have_digit_io_switch)(struct hw *hw);
+	struct capabilities (*capabilities)(struct hw *hw);
+	int (*output_switch_get)(struct hw *hw);
+	int (*output_switch_put)(struct hw *hw, int position);
+	int (*mic_source_switch_get)(struct hw *hw);
+	int (*mic_source_switch_put)(struct hw *hw, int position);
 
 
 	/* SRC operations */
 	/* SRC operations */
 	int (*src_rsc_get_ctrl_blk)(void **rblk);
 	int (*src_rsc_get_ctrl_blk)(void **rblk);

+ 11 - 4
sound/pci/ctxfi/cthw20k1.c

@@ -1777,10 +1777,17 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
 		return adc_init_SBx(hw, info->input, info->mic20db);
 		return adc_init_SBx(hw, info->input, info->mic20db);
 }
 }
 
 
-static int hw_have_digit_io_switch(struct hw *hw)
+static struct capabilities hw_capabilities(struct hw *hw)
 {
 {
+	struct capabilities cap;
+
 	/* SB073x and Vista compatible cards have no digit IO switch */
 	/* SB073x and Vista compatible cards have no digit IO switch */
-	return !(hw->model == CTSB073X || hw->model == CTUAA);
+	cap.digit_io_switch = !(hw->model == CTSB073X || hw->model == CTUAA);
+	cap.dedicated_mic = 0;
+	cap.output_switch = 0;
+	cap.mic_source_switch = 0;
+
+	return cap;
 }
 }
 
 
 #define CTLBITS(a, b, c, d)	(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
 #define CTLBITS(a, b, c, d)	(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
@@ -1933,7 +1940,7 @@ static int hw_card_start(struct hw *hw)
 
 
 	if (hw->irq < 0) {
 	if (hw->irq < 0) {
 		err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
 		err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
-				  "ctxfi", hw);
+				  KBUILD_MODNAME, hw);
 		if (err < 0) {
 		if (err < 0) {
 			printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
 			printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
 			goto error2;
 			goto error2;
@@ -2172,7 +2179,7 @@ static struct hw ct20k1_preset __devinitdata = {
 	.pll_init = hw_pll_init,
 	.pll_init = hw_pll_init,
 	.is_adc_source_selected = hw_is_adc_input_selected,
 	.is_adc_source_selected = hw_is_adc_input_selected,
 	.select_adc_source = hw_adc_input_select,
 	.select_adc_source = hw_adc_input_select,
-	.have_digit_io_switch = hw_have_digit_io_switch,
+	.capabilities = hw_capabilities,
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
 	.suspend = hw_suspend,
 	.suspend = hw_suspend,
 	.resume = hw_resume,
 	.resume = hw_resume,

+ 240 - 97
sound/pci/ctxfi/cthw20k2.c

@@ -8,7 +8,7 @@
  * @File	cthw20k2.c
  * @File	cthw20k2.c
  *
  *
  * @Brief
  * @Brief
- * This file contains the implementation of hardware access methord for 20k2.
+ * This file contains the implementation of hardware access method for 20k2.
  *
  *
  * @Author	Liu Chun
  * @Author	Liu Chun
  * @Date 	May 14 2008
  * @Date 	May 14 2008
@@ -38,6 +38,8 @@ struct hw20k2 {
 	unsigned char dev_id;
 	unsigned char dev_id;
 	unsigned char addr_size;
 	unsigned char addr_size;
 	unsigned char data_size;
 	unsigned char data_size;
+
+	int mic_source;
 };
 };
 
 
 static u32 hw_read_20kx(struct hw *hw, u32 reg);
 static u32 hw_read_20kx(struct hw *hw, u32 reg);
@@ -1163,7 +1165,12 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
 		hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101);
 		hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101);
 		hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
 		hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
 	} else if (2 == info->msr) {
 	} else if (2 == info->msr) {
-		hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
+		if (hw->model != CTSB1270) {
+			hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
+		} else {
+			/* PCM4220 on Titanium HD is different. */
+			hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11011111);
+		}
 		/* Specify all playing 96khz
 		/* Specify all playing 96khz
 		 * EA [0]	- Enabled
 		 * EA [0]	- Enabled
 		 * RTA [4:5]	- 96kHz
 		 * RTA [4:5]	- 96kHz
@@ -1175,6 +1182,10 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
 		 * RTD [28:29]	- 96kHz */
 		 * RTD [28:29]	- 96kHz */
 		hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111);
 		hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111);
 		hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
 		hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
+	} else if ((4 == info->msr) && (hw->model == CTSB1270)) {
+		hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21011111);
+		hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121);
+		hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
 	} else {
 	} else {
 		printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n");
 		printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n");
 		return -EINVAL;
 		return -EINVAL;
@@ -1182,6 +1193,8 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
 
 
 	for (i = 0; i < 8; i++) {
 	for (i = 0; i < 8; i++) {
 		if (i <= 3) {
 		if (i <= 3) {
+			/* This comment looks wrong since loop is over 4  */
+			/* channels and emu20k2 supports 4 spdif IOs.     */
 			/* 1st 3 channels are SPDIFs (SB0960) */
 			/* 1st 3 channels are SPDIFs (SB0960) */
 			if (i == 3)
 			if (i == 3)
 				data = 0x1001001;
 				data = 0x1001001;
@@ -1206,12 +1219,16 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
 
 
 			hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B);
 			hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B);
 		} else {
 		} else {
+			/* Again, loop is over 4 channels not 5. */
 			/* Next 5 channels are I2S (SB0960) */
 			/* Next 5 channels are I2S (SB0960) */
 			data = 0x11;
 			data = 0x11;
 			hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data);
 			hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data);
 			if (2 == info->msr) {
 			if (2 == info->msr) {
 				/* Four channels per sample period */
 				/* Four channels per sample period */
 				data |= 0x1000;
 				data |= 0x1000;
+			} else if (4 == info->msr) {
+				/* FIXME: check this against the chip spec */
+				data |= 0x2000;
 			}
 			}
 			hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data);
 			hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data);
 		}
 		}
@@ -1299,21 +1316,18 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
 
 
 	pllenb = 0xB;
 	pllenb = 0xB;
 	hw_write_20kx(hw, PLL_ENB, pllenb);
 	hw_write_20kx(hw, PLL_ENB, pllenb);
-	pllctl = 0x20D00000;
-	set_field(&pllctl, PLLCTL_FD, 16 - 4);
+	pllctl = 0x20C00000;
+	set_field(&pllctl, PLLCTL_B, 0);
+	set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4);
+	set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1);
 	hw_write_20kx(hw, PLL_CTL, pllctl);
 	hw_write_20kx(hw, PLL_CTL, pllctl);
 	mdelay(40);
 	mdelay(40);
+
 	pllctl = hw_read_20kx(hw, PLL_CTL);
 	pllctl = hw_read_20kx(hw, PLL_CTL);
-	set_field(&pllctl, PLLCTL_B, 0);
-	if (48000 == rsr) {
-		set_field(&pllctl, PLLCTL_FD, 16 - 2);
-		set_field(&pllctl, PLLCTL_RD, 1 - 1); /* 3000*16/1 = 48000 */
-	} else { /* 44100 */
-		set_field(&pllctl, PLLCTL_FD, 147 - 2);
-		set_field(&pllctl, PLLCTL_RD, 10 - 1); /* 3000*147/10 = 44100 */
-	}
+	set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2);
 	hw_write_20kx(hw, PLL_CTL, pllctl);
 	hw_write_20kx(hw, PLL_CTL, pllctl);
 	mdelay(40);
 	mdelay(40);
+
 	for (i = 0; i < 1000; i++) {
 	for (i = 0; i < 1000; i++) {
 		pllstat = hw_read_20kx(hw, PLL_STAT);
 		pllstat = hw_read_20kx(hw, PLL_STAT);
 		if (get_field(pllstat, PLLSTAT_PD))
 		if (get_field(pllstat, PLLSTAT_PD))
@@ -1557,7 +1571,7 @@ static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
 
 
 	hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
 	hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
 	hw20k2_i2c_wait_data_ready(hw);
 	hw20k2_i2c_wait_data_ready(hw);
-	/* Dummy write to trigger the write oprtation */
+	/* Dummy write to trigger the write operation */
 	hw_write_20kx(hw, I2C_IF_WDATA, 0);
 	hw_write_20kx(hw, I2C_IF_WDATA, 0);
 	hw20k2_i2c_wait_data_ready(hw);
 	hw20k2_i2c_wait_data_ready(hw);
 
 
@@ -1568,6 +1582,30 @@ static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
 	return 0;
 	return 0;
 }
 }
 
 
+static void hw_dac_stop(struct hw *hw)
+{
+	u32 data;
+	data = hw_read_20kx(hw, GPIO_DATA);
+	data &= 0xFFFFFFFD;
+	hw_write_20kx(hw, GPIO_DATA, data);
+	mdelay(10);
+}
+
+static void hw_dac_start(struct hw *hw)
+{
+	u32 data;
+	data = hw_read_20kx(hw, GPIO_DATA);
+	data |= 0x2;
+	hw_write_20kx(hw, GPIO_DATA, data);
+	mdelay(50);
+}
+
+static void hw_dac_reset(struct hw *hw)
+{
+	hw_dac_stop(hw);
+	hw_dac_start(hw);
+}
+
 static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
 static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
 {
 {
 	int err;
 	int err;
@@ -1594,6 +1632,21 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
 				   0x00000000   /* Vol Control B4 */
 				   0x00000000   /* Vol Control B4 */
 				 };
 				 };
 
 
+	if (hw->model == CTSB1270) {
+		hw_dac_stop(hw);
+		data = hw_read_20kx(hw, GPIO_DATA);
+		data &= ~0x0600;
+		if (1 == info->msr)
+			data |= 0x0000; /* Single Speed Mode 0-50kHz */
+		else if (2 == info->msr)
+			data |= 0x0200; /* Double Speed Mode 50-100kHz */
+		else
+			data |= 0x0600; /* Quad Speed Mode 100-200kHz */
+		hw_write_20kx(hw, GPIO_DATA, data);
+		hw_dac_start(hw);
+		return 0;
+	}
+
 	/* Set DAC reset bit as output */
 	/* Set DAC reset bit as output */
 	data = hw_read_20kx(hw, GPIO_CTRL);
 	data = hw_read_20kx(hw, GPIO_CTRL);
 	data |= 0x02;
 	data |= 0x02;
@@ -1606,22 +1659,8 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
 	for (i = 0; i < 2; i++) {
 	for (i = 0; i < 2; i++) {
 		/* Reset DAC twice just in-case the chip
 		/* Reset DAC twice just in-case the chip
 		 * didn't initialized properly */
 		 * didn't initialized properly */
-		data = hw_read_20kx(hw, GPIO_DATA);
-		/* GPIO data bit 1 */
-		data &= 0xFFFFFFFD;
-		hw_write_20kx(hw, GPIO_DATA, data);
-		mdelay(10);
-		data |= 0x2;
-		hw_write_20kx(hw, GPIO_DATA, data);
-		mdelay(50);
-
-		/* Reset the 2nd time */
-		data &= 0xFFFFFFFD;
-		hw_write_20kx(hw, GPIO_DATA, data);
-		mdelay(10);
-		data |= 0x2;
-		hw_write_20kx(hw, GPIO_DATA, data);
-		mdelay(50);
+		hw_dac_reset(hw);
+		hw_dac_reset(hw);
 
 
 		if (hw20k2_i2c_read(hw, CS4382_MC1,  &cs_read.mode_control_1))
 		if (hw20k2_i2c_read(hw, CS4382_MC1,  &cs_read.mode_control_1))
 			continue;
 			continue;
@@ -1725,7 +1764,11 @@ End:
 static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
 static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
 {
 {
 	u32 data;
 	u32 data;
-
+	if (hw->model == CTSB1270) {
+		/* Titanium HD has two ADC chips, one for line in and one */
+		/* for MIC. We don't need to switch the ADC input. */
+		return 1;
+	}
 	data = hw_read_20kx(hw, GPIO_DATA);
 	data = hw_read_20kx(hw, GPIO_DATA);
 	switch (type) {
 	switch (type) {
 	case ADC_MICIN:
 	case ADC_MICIN:
@@ -1742,35 +1785,47 @@ static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
 
 
 #define MIC_BOOST_0DB 0xCF
 #define MIC_BOOST_0DB 0xCF
 #define MIC_BOOST_STEPS_PER_DB 2
 #define MIC_BOOST_STEPS_PER_DB 2
-#define MIC_BOOST_20DB (MIC_BOOST_0DB + 20 * MIC_BOOST_STEPS_PER_DB)
+
+static void hw_wm8775_input_select(struct hw *hw, u8 input, s8 gain_in_db)
+{
+	u32 adcmc, gain;
+
+	if (input > 3)
+		input = 3;
+
+	adcmc = ((u32)1 << input) | 0x100; /* Link L+R gain... */
+
+	hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, adcmc),
+				MAKE_WM8775_DATA(adcmc));
+
+	if (gain_in_db < -103)
+		gain_in_db = -103;
+	if (gain_in_db > 24)
+		gain_in_db = 24;
+
+	gain = gain_in_db * MIC_BOOST_STEPS_PER_DB + MIC_BOOST_0DB;
+
+	hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, gain),
+				MAKE_WM8775_DATA(gain));
+	/* ...so there should be no need for the following. */
+	hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, gain),
+				MAKE_WM8775_DATA(gain));
+}
 
 
 static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
 static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
 {
 {
 	u32 data;
 	u32 data;
-
 	data = hw_read_20kx(hw, GPIO_DATA);
 	data = hw_read_20kx(hw, GPIO_DATA);
 	switch (type) {
 	switch (type) {
 	case ADC_MICIN:
 	case ADC_MICIN:
 		data |= (0x1 << 14);
 		data |= (0x1 << 14);
 		hw_write_20kx(hw, GPIO_DATA, data);
 		hw_write_20kx(hw, GPIO_DATA, data);
-		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
-				MAKE_WM8775_DATA(0x101)); /* Mic-in */
-		hw20k2_i2c_write(hw,
-				MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
-				MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
-		hw20k2_i2c_write(hw,
-				MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
-				MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
+		hw_wm8775_input_select(hw, 0, 20); /* Mic, 20dB */
 		break;
 		break;
 	case ADC_LINEIN:
 	case ADC_LINEIN:
 		data &= ~(0x1 << 14);
 		data &= ~(0x1 << 14);
 		hw_write_20kx(hw, GPIO_DATA, data);
 		hw_write_20kx(hw, GPIO_DATA, data);
-		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
-				MAKE_WM8775_DATA(0x102)); /* Line-in */
-		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
-				MAKE_WM8775_DATA(0xCF)); /* No boost */
-		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
-				MAKE_WM8775_DATA(0xCF)); /* No boost */
+		hw_wm8775_input_select(hw, 1, 0); /* Line-in, 0dB */
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;
@@ -1782,7 +1837,7 @@ static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
 static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
 static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
 {
 {
 	int err;
 	int err;
-	u32 mux = 2, data, ctl;
+	u32 data, ctl;
 
 
 	/*  Set ADC reset bit as output */
 	/*  Set ADC reset bit as output */
 	data = hw_read_20kx(hw, GPIO_CTRL);
 	data = hw_read_20kx(hw, GPIO_CTRL);
@@ -1796,19 +1851,42 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
 		goto error;
 		goto error;
 	}
 	}
 
 
-	/* Make ADC in normal operation */
+	/* Reset the ADC (reset is active low). */
 	data = hw_read_20kx(hw, GPIO_DATA);
 	data = hw_read_20kx(hw, GPIO_DATA);
 	data &= ~(0x1 << 15);
 	data &= ~(0x1 << 15);
+	hw_write_20kx(hw, GPIO_DATA, data);
+
+	if (hw->model == CTSB1270) {
+		/* Set up the PCM4220 ADC on Titanium HD */
+		data &= ~0x0C;
+		if (1 == info->msr)
+			data |= 0x00; /* Single Speed Mode 32-50kHz */
+		else if (2 == info->msr)
+			data |= 0x08; /* Double Speed Mode 50-108kHz */
+		else
+			data |= 0x04; /* Quad Speed Mode 108kHz-216kHz */
+		hw_write_20kx(hw, GPIO_DATA, data);
+	}
+
 	mdelay(10);
 	mdelay(10);
+	/* Return the ADC to normal operation. */
 	data |= (0x1 << 15);
 	data |= (0x1 << 15);
 	hw_write_20kx(hw, GPIO_DATA, data);
 	hw_write_20kx(hw, GPIO_DATA, data);
 	mdelay(50);
 	mdelay(50);
 
 
+	/* I2C write to register offset 0x0B to set ADC LRCLK polarity */
+	/* invert bit, interface format to I2S, word length to 24-bit, */
+	/* enable ADC high pass filter. Fixes bug 5323?		*/
+	hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_IC, 0x26),
+			 MAKE_WM8775_DATA(0x26));
+
 	/* Set the master mode (256fs) */
 	/* Set the master mode (256fs) */
 	if (1 == info->msr) {
 	if (1 == info->msr) {
+		/* slave mode, 128x oversampling 256fs */
 		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02),
 		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02),
 						MAKE_WM8775_DATA(0x02));
 						MAKE_WM8775_DATA(0x02));
-	} else if (2 == info->msr) {
+	} else if ((2 == info->msr) || (4 == info->msr)) {
+		/* slave mode, 64x oversampling, 256fs */
 		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A),
 		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A),
 						MAKE_WM8775_DATA(0x0A));
 						MAKE_WM8775_DATA(0x0A));
 	} else {
 	} else {
@@ -1818,55 +1896,113 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
 		goto error;
 		goto error;
 	}
 	}
 
 
-	/* Configure GPIO bit 14 change to line-in/mic-in */
-	ctl = hw_read_20kx(hw, GPIO_CTRL);
-	ctl |= 0x1 << 14;
-	hw_write_20kx(hw, GPIO_CTRL, ctl);
-
-	/* Check using Mic-in or Line-in */
-	data = hw_read_20kx(hw, GPIO_DATA);
-
-	if (mux == 1) {
-		/* Configures GPIO data to select Mic-in */
-		data |= 0x1 << 14;
-		hw_write_20kx(hw, GPIO_DATA, data);
-
-		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
-				MAKE_WM8775_DATA(0x101)); /* Mic-in */
-		hw20k2_i2c_write(hw,
-				MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
-				MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
-		hw20k2_i2c_write(hw,
-				MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
-				MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
-	} else if (mux == 2) {
-		/* Configures GPIO data to select Line-in */
-		data &= ~(0x1 << 14);
-		hw_write_20kx(hw, GPIO_DATA, data);
-
-		/* Setup ADC */
-		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
-				MAKE_WM8775_DATA(0x102)); /* Line-in */
-		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
-				MAKE_WM8775_DATA(0xCF)); /* No boost */
-		hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
-				MAKE_WM8775_DATA(0xCF)); /* No boost */
+	if (hw->model != CTSB1270) {
+		/* Configure GPIO bit 14 change to line-in/mic-in */
+		ctl = hw_read_20kx(hw, GPIO_CTRL);
+		ctl |= 0x1 << 14;
+		hw_write_20kx(hw, GPIO_CTRL, ctl);
+		hw_adc_input_select(hw, ADC_LINEIN);
 	} else {
 	} else {
-		printk(KERN_ALERT "ctxfi: ERROR!!! Invalid input mux!!!\n");
-		err = -EINVAL;
-		goto error;
+		hw_wm8775_input_select(hw, 0, 0);
 	}
 	}
 
 
 	return 0;
 	return 0;
-
 error:
 error:
 	hw20k2_i2c_uninit(hw);
 	hw20k2_i2c_uninit(hw);
 	return err;
 	return err;
 }
 }
 
 
-static int hw_have_digit_io_switch(struct hw *hw)
+static struct capabilities hw_capabilities(struct hw *hw)
 {
 {
-	return 0;
+	struct capabilities cap;
+
+	cap.digit_io_switch = 0;
+	cap.dedicated_mic = hw->model == CTSB1270;
+	cap.output_switch = hw->model == CTSB1270;
+	cap.mic_source_switch = hw->model == CTSB1270;
+
+	return cap;
+}
+
+static int hw_output_switch_get(struct hw *hw)
+{
+	u32 data = hw_read_20kx(hw, GPIO_EXT_DATA);
+
+	switch (data & 0x30) {
+	case 0x00:
+	     return 0;
+	case 0x10:
+	     return 1;
+	case 0x20:
+	     return 2;
+	default:
+	     return 3;
+	}
+}
+
+static int hw_output_switch_put(struct hw *hw, int position)
+{
+	u32 data;
+
+	if (position == hw_output_switch_get(hw))
+		return 0;
+
+	/* Mute line and headphones (intended for anti-pop). */
+	data = hw_read_20kx(hw, GPIO_DATA);
+	data |= (0x03 << 11);
+	hw_write_20kx(hw, GPIO_DATA, data);
+
+	data = hw_read_20kx(hw, GPIO_EXT_DATA) & ~0x30;
+	switch (position) {
+	case 0:
+		break;
+	case 1:
+		data |= 0x10;
+		break;
+	default:
+		data |= 0x20;
+	}
+	hw_write_20kx(hw, GPIO_EXT_DATA, data);
+
+	/* Unmute line and headphones. */
+	data = hw_read_20kx(hw, GPIO_DATA);
+	data &= ~(0x03 << 11);
+	hw_write_20kx(hw, GPIO_DATA, data);
+
+	return 1;
+}
+
+static int hw_mic_source_switch_get(struct hw *hw)
+{
+	struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
+
+	return hw20k2->mic_source;
+}
+
+static int hw_mic_source_switch_put(struct hw *hw, int position)
+{
+	struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
+
+	if (position == hw20k2->mic_source)
+		return 0;
+
+	switch (position) {
+	case 0:
+		hw_wm8775_input_select(hw, 0, 0); /* Mic, 0dB */
+		break;
+	case 1:
+		hw_wm8775_input_select(hw, 1, 0); /* FP Mic, 0dB */
+		break;
+	case 2:
+		hw_wm8775_input_select(hw, 3, 0); /* Aux Ext, 0dB */
+		break;
+	default:
+		return 0;
+	}
+
+	hw20k2->mic_source = position;
+
+	return 1;
 }
 }
 
 
 static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
 static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
@@ -1925,7 +2061,7 @@ static int hw_card_start(struct hw *hw)
 
 
 	if (hw->irq < 0) {
 	if (hw->irq < 0) {
 		err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
 		err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
-				  "ctxfi", hw);
+				  KBUILD_MODNAME, hw);
 		if (err < 0) {
 		if (err < 0) {
 			printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
 			printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
 			goto error2;
 			goto error2;
@@ -2023,13 +2159,16 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
 	/* Reset all SRC pending interrupts */
 	/* Reset all SRC pending interrupts */
 	hw_write_20kx(hw, SRC_IP, 0);
 	hw_write_20kx(hw, SRC_IP, 0);
 
 
-	/* TODO: detect the card ID and configure GPIO accordingly. */
-	/* Configures GPIO (0xD802 0x98028) */
-	/*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/
-	/* Configures GPIO (SB0880) */
-	/*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/
-	hw_write_20kx(hw, GPIO_CTRL, 0xD802);
-
+	if (hw->model != CTSB1270) {
+		/* TODO: detect the card ID and configure GPIO accordingly. */
+		/* Configures GPIO (0xD802 0x98028) */
+		/*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/
+		/* Configures GPIO (SB0880) */
+		/*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/
+		hw_write_20kx(hw, GPIO_CTRL, 0xD802);
+	} else {
+		hw_write_20kx(hw, GPIO_CTRL, 0x9E5F);
+	}
 	/* Enable audio ring */
 	/* Enable audio ring */
 	hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01);
 	hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01);
 
 
@@ -2106,7 +2245,11 @@ static struct hw ct20k2_preset __devinitdata = {
 	.pll_init = hw_pll_init,
 	.pll_init = hw_pll_init,
 	.is_adc_source_selected = hw_is_adc_input_selected,
 	.is_adc_source_selected = hw_is_adc_input_selected,
 	.select_adc_source = hw_adc_input_select,
 	.select_adc_source = hw_adc_input_select,
-	.have_digit_io_switch = hw_have_digit_io_switch,
+	.capabilities = hw_capabilities,
+	.output_switch_get = hw_output_switch_get,
+	.output_switch_put = hw_output_switch_put,
+	.mic_source_switch_get = hw_mic_source_switch_get,
+	.mic_source_switch_put = hw_mic_source_switch_put,
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
 	.suspend = hw_suspend,
 	.suspend = hw_suspend,
 	.resume = hw_resume,
 	.resume = hw_resume,

+ 112 - 33
sound/pci/ctxfi/ctmixer.c

@@ -86,9 +86,7 @@ enum CTALSA_MIXER_CTL {
 	MIXER_LINEIN_C_S,
 	MIXER_LINEIN_C_S,
 	MIXER_MIC_C_S,
 	MIXER_MIC_C_S,
 	MIXER_SPDIFI_C_S,
 	MIXER_SPDIFI_C_S,
-	MIXER_LINEIN_P_S,
 	MIXER_SPDIFO_P_S,
 	MIXER_SPDIFO_P_S,
-	MIXER_SPDIFI_P_S,
 	MIXER_WAVEF_P_S,
 	MIXER_WAVEF_P_S,
 	MIXER_WAVER_P_S,
 	MIXER_WAVER_P_S,
 	MIXER_WAVEC_P_S,
 	MIXER_WAVEC_P_S,
@@ -137,11 +135,11 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
 	},
 	},
 	[MIXER_LINEIN_P] = {
 	[MIXER_LINEIN_P] = {
 		.ctl = 1,
 		.ctl = 1,
-		.name = "Line-in Playback Volume",
+		.name = "Line Playback Volume",
 	},
 	},
 	[MIXER_LINEIN_C] = {
 	[MIXER_LINEIN_C] = {
 		.ctl = 1,
 		.ctl = 1,
-		.name = "Line-in Capture Volume",
+		.name = "Line Capture Volume",
 	},
 	},
 	[MIXER_MIC_P] = {
 	[MIXER_MIC_P] = {
 		.ctl = 1,
 		.ctl = 1,
@@ -153,15 +151,15 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
 	},
 	},
 	[MIXER_SPDIFI_P] = {
 	[MIXER_SPDIFI_P] = {
 		.ctl = 1,
 		.ctl = 1,
-		.name = "S/PDIF-in Playback Volume",
+		.name = "IEC958 Playback Volume",
 	},
 	},
 	[MIXER_SPDIFI_C] = {
 	[MIXER_SPDIFI_C] = {
 		.ctl = 1,
 		.ctl = 1,
-		.name = "S/PDIF-in Capture Volume",
+		.name = "IEC958 Capture Volume",
 	},
 	},
 	[MIXER_SPDIFO_P] = {
 	[MIXER_SPDIFO_P] = {
 		.ctl = 1,
 		.ctl = 1,
-		.name = "S/PDIF-out Playback Volume",
+		.name = "Digital Playback Volume",
 	},
 	},
 	[MIXER_WAVEF_P] = {
 	[MIXER_WAVEF_P] = {
 		.ctl = 1,
 		.ctl = 1,
@@ -179,14 +177,13 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
 		.ctl = 1,
 		.ctl = 1,
 		.name = "Surround Playback Volume",
 		.name = "Surround Playback Volume",
 	},
 	},
-
 	[MIXER_PCM_C_S] = {
 	[MIXER_PCM_C_S] = {
 		.ctl = 1,
 		.ctl = 1,
 		.name = "PCM Capture Switch",
 		.name = "PCM Capture Switch",
 	},
 	},
 	[MIXER_LINEIN_C_S] = {
 	[MIXER_LINEIN_C_S] = {
 		.ctl = 1,
 		.ctl = 1,
-		.name = "Line-in Capture Switch",
+		.name = "Line Capture Switch",
 	},
 	},
 	[MIXER_MIC_C_S] = {
 	[MIXER_MIC_C_S] = {
 		.ctl = 1,
 		.ctl = 1,
@@ -194,19 +191,11 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
 	},
 	},
 	[MIXER_SPDIFI_C_S] = {
 	[MIXER_SPDIFI_C_S] = {
 		.ctl = 1,
 		.ctl = 1,
-		.name = "S/PDIF-in Capture Switch",
-	},
-	[MIXER_LINEIN_P_S] = {
-		.ctl = 1,
-		.name = "Line-in Playback Switch",
+		.name = "IEC958 Capture Switch",
 	},
 	},
 	[MIXER_SPDIFO_P_S] = {
 	[MIXER_SPDIFO_P_S] = {
 		.ctl = 1,
 		.ctl = 1,
-		.name = "S/PDIF-out Playback Switch",
-	},
-	[MIXER_SPDIFI_P_S] = {
-		.ctl = 1,
-		.name = "S/PDIF-in Playback Switch",
+		.name = "Digital Playback Switch",
 	},
 	},
 	[MIXER_WAVEF_P_S] = {
 	[MIXER_WAVEF_P_S] = {
 		.ctl = 1,
 		.ctl = 1,
@@ -236,6 +225,8 @@ ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
 static void
 static void
 ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
 ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
 
 
+/* FIXME: this static looks like it would fail if more than one card was */
+/* installed. */
 static struct snd_kcontrol *kctls[2] = {NULL};
 static struct snd_kcontrol *kctls[2] = {NULL};
 
 
 static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index)
 static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index)
@@ -420,6 +411,77 @@ static struct snd_kcontrol_new vol_ctl = {
 	.tlv		= { .p =  ct_vol_db_scale },
 	.tlv		= { .p =  ct_vol_db_scale },
 };
 };
 
 
+static int output_switch_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *info)
+{
+	static const char *const names[3] = {
+	  "FP Headphones", "Headphones", "Speakers"
+	};
+
+	return snd_ctl_enum_info(info, 1, 3, names);
+}
+
+static int output_switch_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.enumerated.item[0] = atc->output_switch_get(atc);
+	return 0;
+}
+
+static int output_switch_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
+	if (ucontrol->value.enumerated.item[0] > 2)
+		return -EINVAL;
+	return atc->output_switch_put(atc, ucontrol->value.enumerated.item[0]);
+}
+
+static struct snd_kcontrol_new output_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Analog Output Playback Enum",
+	.info = output_switch_info,
+	.get = output_switch_get,
+	.put = output_switch_put,
+};
+
+static int mic_source_switch_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *info)
+{
+	static const char *const names[3] = {
+	  "Mic", "FP Mic", "Aux"
+	};
+
+	return snd_ctl_enum_info(info, 1, 3, names);
+}
+
+static int mic_source_switch_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.enumerated.item[0] = atc->mic_source_switch_get(atc);
+	return 0;
+}
+
+static int mic_source_switch_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
+	if (ucontrol->value.enumerated.item[0] > 2)
+		return -EINVAL;
+	return atc->mic_source_switch_put(atc,
+					ucontrol->value.enumerated.item[0]);
+}
+
+static struct snd_kcontrol_new mic_source_ctl = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Mic Source Capture Enum",
+	.info = mic_source_switch_info,
+	.get = mic_source_switch_get,
+	.put = mic_source_switch_put,
+};
+
 static void
 static void
 do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type)
 do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type)
 {
 {
@@ -465,6 +527,7 @@ do_digit_io_switch(struct ct_atc *atc, int state)
 static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
 static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
 {
 {
 	struct ct_mixer *mixer = atc->mixer;
 	struct ct_mixer *mixer = atc->mixer;
+	struct capabilities cap = atc->capabilities(atc);
 
 
 	/* Do changes in mixer. */
 	/* Do changes in mixer. */
 	if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
 	if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
@@ -477,8 +540,17 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
 		}
 		}
 	}
 	}
 	/* Do changes out of mixer. */
 	/* Do changes out of mixer. */
-	if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type))
-		do_line_mic_switch(atc, type);
+	if (!cap.dedicated_mic &&
+	    (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) {
+		if (state)
+			do_line_mic_switch(atc, type);
+		atc->line_in_unmute(atc, state);
+	} else if (cap.dedicated_mic && (MIXER_LINEIN_C_S == type))
+		atc->line_in_unmute(atc, state);
+	else if (cap.dedicated_mic && (MIXER_MIC_C_S == type))
+		atc->mic_unmute(atc, state);
+	else if (MIXER_SPDIFI_C_S == type)
+		atc->spdif_in_unmute(atc, state);
 	else if (MIXER_WAVEF_P_S == type)
 	else if (MIXER_WAVEF_P_S == type)
 		atc->line_front_unmute(atc, state);
 		atc->line_front_unmute(atc, state);
 	else if (MIXER_WAVES_P_S == type)
 	else if (MIXER_WAVES_P_S == type)
@@ -487,12 +559,8 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
 		atc->line_clfe_unmute(atc, state);
 		atc->line_clfe_unmute(atc, state);
 	else if (MIXER_WAVER_P_S == type)
 	else if (MIXER_WAVER_P_S == type)
 		atc->line_rear_unmute(atc, state);
 		atc->line_rear_unmute(atc, state);
-	else if (MIXER_LINEIN_P_S == type)
-		atc->line_in_unmute(atc, state);
 	else if (MIXER_SPDIFO_P_S == type)
 	else if (MIXER_SPDIFO_P_S == type)
 		atc->spdif_out_unmute(atc, state);
 		atc->spdif_out_unmute(atc, state);
-	else if (MIXER_SPDIFI_P_S == type)
-		atc->spdif_in_unmute(atc, state);
 	else if (MIXER_DIGITAL_IO_S == type)
 	else if (MIXER_DIGITAL_IO_S == type)
 		do_digit_io_switch(atc, state);
 		do_digit_io_switch(atc, state);
 
 
@@ -671,6 +739,7 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
 {
 {
 	enum CTALSA_MIXER_CTL type;
 	enum CTALSA_MIXER_CTL type;
 	struct ct_atc *atc = mixer->atc;
 	struct ct_atc *atc = mixer->atc;
+	struct capabilities cap = atc->capabilities(atc);
 	int err;
 	int err;
 
 
 	/* Create snd kcontrol instances on demand */
 	/* Create snd kcontrol instances on demand */
@@ -684,8 +753,8 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
 		}
 		}
 	}
 	}
 
 
-	ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl =
-					atc->have_digit_io_switch(atc);
+	ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl = cap.digit_io_switch;
+
 	for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) {
 	for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) {
 		if (ct_kcontrol_init_table[type].ctl) {
 		if (ct_kcontrol_init_table[type].ctl) {
 			swh_ctl.name = ct_kcontrol_init_table[type].name;
 			swh_ctl.name = ct_kcontrol_init_table[type].name;
@@ -708,6 +777,17 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
+	if (cap.output_switch) {
+		err = ct_mixer_kcontrol_new(mixer, &output_ctl);
+		if (err)
+			return err;
+	}
+
+	if (cap.mic_source_switch) {
+		err = ct_mixer_kcontrol_new(mixer, &mic_source_ctl);
+		if (err)
+			return err;
+	}
 	atc->line_front_unmute(atc, 1);
 	atc->line_front_unmute(atc, 1);
 	set_switch_state(mixer, MIXER_WAVEF_P_S, 1);
 	set_switch_state(mixer, MIXER_WAVEF_P_S, 1);
 	atc->line_surround_unmute(atc, 0);
 	atc->line_surround_unmute(atc, 0);
@@ -719,13 +799,12 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
 	atc->spdif_out_unmute(atc, 0);
 	atc->spdif_out_unmute(atc, 0);
 	set_switch_state(mixer, MIXER_SPDIFO_P_S, 0);
 	set_switch_state(mixer, MIXER_SPDIFO_P_S, 0);
 	atc->line_in_unmute(atc, 0);
 	atc->line_in_unmute(atc, 0);
-	set_switch_state(mixer, MIXER_LINEIN_P_S, 0);
+	if (cap.dedicated_mic)
+		atc->mic_unmute(atc, 0);
 	atc->spdif_in_unmute(atc, 0);
 	atc->spdif_in_unmute(atc, 0);
-	set_switch_state(mixer, MIXER_SPDIFI_P_S, 0);
-
-	set_switch_state(mixer, MIXER_PCM_C_S, 1);
-	set_switch_state(mixer, MIXER_LINEIN_C_S, 1);
-	set_switch_state(mixer, MIXER_SPDIFI_C_S, 1);
+	set_switch_state(mixer, MIXER_PCM_C_S, 0);
+	set_switch_state(mixer, MIXER_LINEIN_C_S, 0);
+	set_switch_state(mixer, MIXER_SPDIFI_C_S, 0);
 
 
 	return 0;
 	return 0;
 }
 }

+ 3 - 3
sound/pci/ctxfi/xfi.c

@@ -80,11 +80,11 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 		       "are 48000 and 44100, Value 48000 is assumed.\n");
 		       "are 48000 and 44100, Value 48000 is assumed.\n");
 		reference_rate = 48000;
 		reference_rate = 48000;
 	}
 	}
-	if ((multiple != 1) && (multiple != 2)) {
+	if ((multiple != 1) && (multiple != 2) && (multiple != 4)) {
 		printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n",
 		printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n",
 		       multiple);
 		       multiple);
 		printk(KERN_ERR "ctxfi: The valid values for multiple are "
 		printk(KERN_ERR "ctxfi: The valid values for multiple are "
-		       "1 and 2, Value 2 is assumed.\n");
+		       "1, 2 and 4, Value 2 is assumed.\n");
 		multiple = 2;
 		multiple = 2;
 	}
 	}
 	err = ct_atc_create(card, pci, reference_rate, multiple,
 	err = ct_atc_create(card, pci, reference_rate, multiple,
@@ -143,7 +143,7 @@ static int ct_card_resume(struct pci_dev *pci)
 #endif
 #endif
 
 
 static struct pci_driver ct_driver = {
 static struct pci_driver ct_driver = {
-	.name = "SB-XFi",
+	.name = KBUILD_MODNAME,
 	.id_table = ct_pci_dev_ids,
 	.id_table = ct_pci_dev_ids,
 	.probe = ct_card_probe,
 	.probe = ct_card_probe,
 	.remove = __devexit_p(ct_card_remove),
 	.remove = __devexit_p(ct_card_remove),

+ 3 - 3
sound/pci/echoaudio/echoaudio.c

@@ -1995,7 +1995,7 @@ static __devinit int snd_echo_create(struct snd_card *card,
 		ioremap_nocache(chip->dsp_registers_phys, sz);
 		ioremap_nocache(chip->dsp_registers_phys, sz);
 
 
 	if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
-			ECHOCARD_NAME, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_echo_free(chip);
 		snd_echo_free(chip);
 		snd_printk(KERN_ERR "cannot grab irq\n");
 		snd_printk(KERN_ERR "cannot grab irq\n");
 		return -EBUSY;
 		return -EBUSY;
@@ -2286,7 +2286,7 @@ static int snd_echo_resume(struct pci_dev *pci)
 	kfree(commpage_bak);
 	kfree(commpage_bak);
 
 
 	if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
-			ECHOCARD_NAME, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_echo_free(chip);
 		snd_echo_free(chip);
 		snd_printk(KERN_ERR "cannot grab irq\n");
 		snd_printk(KERN_ERR "cannot grab irq\n");
 		return -EBUSY;
 		return -EBUSY;
@@ -2327,7 +2327,7 @@ static void __devexit snd_echo_remove(struct pci_dev *pci)
 
 
 /* pci_driver definition */
 /* pci_driver definition */
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Echoaudio " ECHOCARD_NAME,
+	.name = KBUILD_MODNAME,
 	.id_table = snd_echo_ids,
 	.id_table = snd_echo_ids,
 	.probe = snd_echo_probe,
 	.probe = snd_echo_probe,
 	.remove = __devexit_p(snd_echo_remove),
 	.remove = __devexit_p(snd_echo_remove),

+ 1 - 1
sound/pci/emu10k1/emu10k1.c

@@ -264,7 +264,7 @@ static int snd_emu10k1_resume(struct pci_dev *pci)
 #endif
 #endif
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "EMU10K1_Audigy",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_emu10k1_ids,
 	.id_table = snd_emu10k1_ids,
 	.probe = snd_card_emu10k1_probe,
 	.probe = snd_card_emu10k1_probe,
 	.remove = __devexit_p(snd_card_emu10k1_remove),
 	.remove = __devexit_p(snd_card_emu10k1_remove),

+ 1 - 1
sound/pci/emu10k1/emu10k1_main.c

@@ -1912,7 +1912,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
 
 
 	/* irq handler must be registered after I/O ports are activated */
 	/* irq handler must be registered after I/O ports are activated */
 	if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED,
-			"EMU10K1", emu)) {
+			KBUILD_MODNAME, emu)) {
 		err = -EBUSY;
 		err = -EBUSY;
 		goto error;
 		goto error;
 	}
 	}

+ 2 - 2
sound/pci/emu10k1/emu10k1x.c

@@ -925,7 +925,7 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card,
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_emu10k1x_interrupt,
 	if (request_irq(pci->irq, snd_emu10k1x_interrupt,
-			IRQF_SHARED, "EMU10K1X", chip)) {
+			IRQF_SHARED, KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
 		snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
 		snd_emu10k1x_free(chip);
 		snd_emu10k1x_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -1613,7 +1613,7 @@ MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
 
 
 // pci_driver definition
 // pci_driver definition
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "EMU10K1X",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_emu10k1x_ids,
 	.id_table = snd_emu10k1x_ids,
 	.probe = snd_emu10k1x_probe,
 	.probe = snd_emu10k1x_probe,
 	.remove = __devexit_p(snd_emu10k1x_remove),
 	.remove = __devexit_p(snd_emu10k1x_remove),

+ 2 - 2
sound/pci/ens1370.c

@@ -2120,7 +2120,7 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
 	}
 	}
 	ensoniq->port = pci_resource_start(pci, 0);
 	ensoniq->port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED,
-			"Ensoniq AudioPCI", ensoniq)) {
+			KBUILD_MODNAME, ensoniq)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ensoniq_free(ensoniq);
 		snd_ensoniq_free(ensoniq);
 		return -EBUSY;
 		return -EBUSY;
@@ -2489,7 +2489,7 @@ static void __devexit snd_audiopci_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = DRIVER_NAME,
+	.name = KBUILD_MODNAME,
 	.id_table = snd_audiopci_ids,
 	.id_table = snd_audiopci_ids,
 	.probe = snd_audiopci_probe,
 	.probe = snd_audiopci_probe,
 	.remove = __devexit_p(snd_audiopci_remove),
 	.remove = __devexit_p(snd_audiopci_remove),

+ 3 - 3
sound/pci/es1938.c

@@ -1514,7 +1514,7 @@ static int es1938_resume(struct pci_dev *pci)
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_es1938_interrupt,
 	if (request_irq(pci->irq, snd_es1938_interrupt,
-			IRQF_SHARED, "ES1938", chip)) {
+			IRQF_SHARED, KBUILD_MODNAME, chip)) {
 		printk(KERN_ERR "es1938: unable to grab IRQ %d, "
 		printk(KERN_ERR "es1938: unable to grab IRQ %d, "
 		       "disabling device\n", pci->irq);
 		       "disabling device\n", pci->irq);
 		snd_card_disconnect(card);
 		snd_card_disconnect(card);
@@ -1636,7 +1636,7 @@ static int __devinit snd_es1938_create(struct snd_card *card,
 	chip->mpu_port = pci_resource_start(pci, 3);
 	chip->mpu_port = pci_resource_start(pci, 3);
 	chip->game_port = pci_resource_start(pci, 4);
 	chip->game_port = pci_resource_start(pci, 4);
 	if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,
-			"ES1938", chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_es1938_free(chip);
 		snd_es1938_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -1882,7 +1882,7 @@ static void __devexit snd_es1938_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "ESS ES1938 (Solo-1)",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_es1938_ids,
 	.id_table = snd_es1938_ids,
 	.probe = snd_es1938_probe,
 	.probe = snd_es1938_probe,
 	.remove = __devexit_p(snd_es1938_remove),
 	.remove = __devexit_p(snd_es1938_remove),

+ 13 - 55
sound/pci/es1968.c

@@ -554,9 +554,8 @@ struct es1968 {
 #else
 #else
 	struct snd_kcontrol *master_switch; /* for h/w volume control */
 	struct snd_kcontrol *master_switch; /* for h/w volume control */
 	struct snd_kcontrol *master_volume;
 	struct snd_kcontrol *master_volume;
-	spinlock_t ac97_lock;
-	struct tasklet_struct hwvol_tq;
 #endif
 #endif
+	struct work_struct hwvol_work;
 
 
 #ifdef CONFIG_SND_ES1968_RADIO
 #ifdef CONFIG_SND_ES1968_RADIO
 	struct snd_tea575x tea;
 	struct snd_tea575x tea;
@@ -646,38 +645,23 @@ static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
 static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
 {
 	struct es1968 *chip = ac97->private_data;
 	struct es1968 *chip = ac97->private_data;
-#ifndef CONFIG_SND_ES1968_INPUT
-	unsigned long flags;
-#endif
 
 
 	snd_es1968_ac97_wait(chip);
 	snd_es1968_ac97_wait(chip);
 
 
 	/* Write the bus */
 	/* Write the bus */
-#ifndef CONFIG_SND_ES1968_INPUT
-	spin_lock_irqsave(&chip->ac97_lock, flags);
-#endif
 	outw(val, chip->io_port + ESM_AC97_DATA);
 	outw(val, chip->io_port + ESM_AC97_DATA);
 	/*msleep(1);*/
 	/*msleep(1);*/
 	outb(reg, chip->io_port + ESM_AC97_INDEX);
 	outb(reg, chip->io_port + ESM_AC97_INDEX);
 	/*msleep(1);*/
 	/*msleep(1);*/
-#ifndef CONFIG_SND_ES1968_INPUT
-	spin_unlock_irqrestore(&chip->ac97_lock, flags);
-#endif
 }
 }
 
 
 static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
 {
 	u16 data = 0;
 	u16 data = 0;
 	struct es1968 *chip = ac97->private_data;
 	struct es1968 *chip = ac97->private_data;
-#ifndef CONFIG_SND_ES1968_INPUT
-	unsigned long flags;
-#endif
 
 
 	snd_es1968_ac97_wait(chip);
 	snd_es1968_ac97_wait(chip);
 
 
-#ifndef CONFIG_SND_ES1968_INPUT
-	spin_lock_irqsave(&chip->ac97_lock, flags);
-#endif
 	outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
 	outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
 	/*msleep(1);*/
 	/*msleep(1);*/
 
 
@@ -685,9 +669,6 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
 		data = inw(chip->io_port + ESM_AC97_DATA);
 		data = inw(chip->io_port + ESM_AC97_DATA);
 		/*msleep(1);*/
 		/*msleep(1);*/
 	}
 	}
-#ifndef CONFIG_SND_ES1968_INPUT
-	spin_unlock_irqrestore(&chip->ac97_lock, flags);
-#endif
 
 
 	return data;
 	return data;
 }
 }
@@ -1904,13 +1885,10 @@ static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
    (without wrap around) in response to volume button presses and then
    (without wrap around) in response to volume button presses and then
    generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
    generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
    of a byte wide register. The meaning of bits 0 and 4 is unknown. */
    of a byte wide register. The meaning of bits 0 and 4 is unknown. */
-static void es1968_update_hw_volume(unsigned long private_data)
+static void es1968_update_hw_volume(struct work_struct *work)
 {
 {
-	struct es1968 *chip = (struct es1968 *) private_data;
+	struct es1968 *chip = container_of(work, struct es1968, hwvol_work);
 	int x, val;
 	int x, val;
-#ifndef CONFIG_SND_ES1968_INPUT
-	unsigned long flags;
-#endif
 
 
 	/* Figure out which volume control button was pushed,
 	/* Figure out which volume control button was pushed,
 	   based on differences from the default register
 	   based on differences from the default register
@@ -1929,18 +1907,11 @@ static void es1968_update_hw_volume(unsigned long private_data)
 	if (! chip->master_switch || ! chip->master_volume)
 	if (! chip->master_switch || ! chip->master_volume)
 		return;
 		return;
 
 
-	/* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
-	spin_lock_irqsave(&chip->ac97_lock, flags);
-	val = chip->ac97->regs[AC97_MASTER];
+	val = snd_ac97_read(chip->ac97, AC97_MASTER);
 	switch (x) {
 	switch (x) {
 	case 0x88:
 	case 0x88:
 		/* mute */
 		/* mute */
 		val ^= 0x8000;
 		val ^= 0x8000;
-		chip->ac97->regs[AC97_MASTER] = val;
-		outw(val, chip->io_port + ESM_AC97_DATA);
-		outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
-		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
-			       &chip->master_switch->id);
 		break;
 		break;
 	case 0xaa:
 	case 0xaa:
 		/* volume up */
 		/* volume up */
@@ -1948,11 +1919,6 @@ static void es1968_update_hw_volume(unsigned long private_data)
 			val--;
 			val--;
 		if ((val & 0x7f00) > 0)
 		if ((val & 0x7f00) > 0)
 			val -= 0x0100;
 			val -= 0x0100;
-		chip->ac97->regs[AC97_MASTER] = val;
-		outw(val, chip->io_port + ESM_AC97_DATA);
-		outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
-		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
-			       &chip->master_volume->id);
 		break;
 		break;
 	case 0x66:
 	case 0x66:
 		/* volume down */
 		/* volume down */
@@ -1960,14 +1926,11 @@ static void es1968_update_hw_volume(unsigned long private_data)
 			val++;
 			val++;
 		if ((val & 0x7f00) < 0x1f00)
 		if ((val & 0x7f00) < 0x1f00)
 			val += 0x0100;
 			val += 0x0100;
-		chip->ac97->regs[AC97_MASTER] = val;
-		outw(val, chip->io_port + ESM_AC97_DATA);
-		outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
-		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
-			       &chip->master_volume->id);
 		break;
 		break;
 	}
 	}
-	spin_unlock_irqrestore(&chip->ac97_lock, flags);
+	if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
+		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &chip->master_volume->id);
 #else
 #else
 	if (!chip->input_dev)
 	if (!chip->input_dev)
 		return;
 		return;
@@ -2013,11 +1976,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
 	outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
 	outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
 
 
 	if (event & ESM_HWVOL_IRQ)
 	if (event & ESM_HWVOL_IRQ)
-#ifdef CONFIG_SND_ES1968_INPUT
-		es1968_update_hw_volume((unsigned long)chip);
-#else
-		tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
-#endif
+		schedule_work(&chip->hwvol_work);
 
 
 	/* else ack 'em all, i imagine */
 	/* else ack 'em all, i imagine */
 	outb(0xFF, chip->io_port + 0x1A);
 	outb(0xFF, chip->io_port + 0x1A);
@@ -2426,6 +2385,7 @@ static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
 		return 0;
 		return 0;
 
 
 	chip->in_suspend = 1;
 	chip->in_suspend = 1;
+	cancel_work_sync(&chip->hwvol_work);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
 	snd_ac97_suspend(chip->ac97);
@@ -2638,6 +2598,7 @@ static struct snd_tea575x_ops snd_es1968_tea_ops = {
 
 
 static int snd_es1968_free(struct es1968 *chip)
 static int snd_es1968_free(struct es1968 *chip)
 {
 {
+	cancel_work_sync(&chip->hwvol_work);
 #ifdef CONFIG_SND_ES1968_INPUT
 #ifdef CONFIG_SND_ES1968_INPUT
 	if (chip->input_dev)
 	if (chip->input_dev)
 		input_unregister_device(chip->input_dev);
 		input_unregister_device(chip->input_dev);
@@ -2728,10 +2689,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
 	INIT_LIST_HEAD(&chip->buf_list);
 	INIT_LIST_HEAD(&chip->buf_list);
 	INIT_LIST_HEAD(&chip->substream_list);
 	INIT_LIST_HEAD(&chip->substream_list);
 	mutex_init(&chip->memory_mutex);
 	mutex_init(&chip->memory_mutex);
-#ifndef CONFIG_SND_ES1968_INPUT
-	spin_lock_init(&chip->ac97_lock);
-	tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
-#endif
+	INIT_WORK(&chip->hwvol_work, es1968_update_hw_volume);
 	chip->card = card;
 	chip->card = card;
 	chip->pci = pci;
 	chip->pci = pci;
 	chip->irq = -1;
 	chip->irq = -1;
@@ -2746,7 +2704,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
 	}
 	}
 	chip->io_port = pci_resource_start(pci, 0);
 	chip->io_port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
-			"ESS Maestro", chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_es1968_free(chip);
 		snd_es1968_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -2925,7 +2883,7 @@ static void __devexit snd_es1968_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "ES1968 (ESS Maestro)",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_es1968_ids,
 	.id_table = snd_es1968_ids,
 	.probe = snd_es1968_probe,
 	.probe = snd_es1968_probe,
 	.remove = __devexit_p(snd_es1968_remove),
 	.remove = __devexit_p(snd_es1968_remove),

+ 2 - 2
sound/pci/fm801.c

@@ -1199,7 +1199,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
 	chip->port = pci_resource_start(pci, 0);
 	chip->port = pci_resource_start(pci, 0);
 	if ((tea575x_tuner & TUNER_ONLY) == 0) {
 	if ((tea575x_tuner & TUNER_ONLY) == 0) {
 		if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
 		if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
-				"FM801", chip)) {
+				KBUILD_MODNAME, chip)) {
 			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
 			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
 			snd_fm801_free(chip);
 			snd_fm801_free(chip);
 			return -EBUSY;
 			return -EBUSY;
@@ -1394,7 +1394,7 @@ static int snd_fm801_resume(struct pci_dev *pci)
 #endif
 #endif
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "FM801",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_fm801_ids,
 	.id_table = snd_fm801_ids,
 	.probe = snd_card_fm801_probe,
 	.probe = snd_card_fm801_probe,
 	.remove = __devexit_p(snd_card_fm801_remove),
 	.remove = __devexit_p(snd_card_fm801_remove),

+ 4 - 6
sound/pci/hda/hda_codec.c

@@ -4957,17 +4957,15 @@ void *snd_array_new(struct snd_array *array)
 {
 {
 	if (array->used >= array->alloced) {
 	if (array->used >= array->alloced) {
 		int num = array->alloced + array->alloc_align;
 		int num = array->alloced + array->alloc_align;
+		int size = (num + 1) * array->elem_size;
+		int oldsize = array->alloced * array->elem_size;
 		void *nlist;
 		void *nlist;
 		if (snd_BUG_ON(num >= 4096))
 		if (snd_BUG_ON(num >= 4096))
 			return NULL;
 			return NULL;
-		nlist = kcalloc(num + 1, array->elem_size, GFP_KERNEL);
+		nlist = krealloc(array->list, size, GFP_KERNEL);
 		if (!nlist)
 		if (!nlist)
 			return NULL;
 			return NULL;
-		if (array->list) {
-			memcpy(nlist, array->list,
-			       array->elem_size * array->alloced);
-			kfree(array->list);
-		}
+		memset(nlist + oldsize, 0, size - oldsize);
 		array->list = nlist;
 		array->list = nlist;
 		array->alloced = num;
 		array->alloced = num;
 	}
 	}

+ 2 - 2
sound/pci/hda/hda_intel.c

@@ -2149,7 +2149,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
 {
 {
 	if (request_irq(chip->pci->irq, azx_interrupt,
 	if (request_irq(chip->pci->irq, azx_interrupt,
 			chip->msi ? 0 : IRQF_SHARED,
 			chip->msi ? 0 : IRQF_SHARED,
-			"hda_intel", chip)) {
+			KBUILD_MODNAME, chip)) {
 		printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
 		printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
 		       "disabling device\n", chip->pci->irq);
 		       "disabling device\n", chip->pci->irq);
 		if (do_disconnect)
 		if (do_disconnect)
@@ -2908,7 +2908,7 @@ MODULE_DEVICE_TABLE(pci, azx_ids);
 
 
 /* pci_driver definition */
 /* pci_driver definition */
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "HDA Intel",
+	.name = KBUILD_MODNAME,
 	.id_table = azx_ids,
 	.id_table = azx_ids,
 	.probe = azx_probe,
 	.probe = azx_probe,
 	.remove = __devexit_p(azx_remove),
 	.remove = __devexit_p(azx_remove),

+ 2 - 2
sound/pci/ice1712/ice1712.c

@@ -2607,7 +2607,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
 	ice->profi_port = pci_resource_start(pci, 3);
 	ice->profi_port = pci_resource_start(pci, 3);
 
 
 	if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED,
-			"ICE1712", ice)) {
+			KBUILD_MODNAME, ice)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ice1712_free(ice);
 		snd_ice1712_free(ice);
 		return -EIO;
 		return -EIO;
@@ -2802,7 +2802,7 @@ static void __devexit snd_ice1712_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "ICE1712",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_ice1712_ids,
 	.id_table = snd_ice1712_ids,
 	.probe = snd_ice1712_probe,
 	.probe = snd_ice1712_probe,
 	.remove = __devexit_p(snd_ice1712_remove),
 	.remove = __devexit_p(snd_ice1712_remove),

+ 2 - 2
sound/pci/ice1712/ice1724.c

@@ -2509,7 +2509,7 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
 	ice->profi_port = pci_resource_start(pci, 1);
 	ice->profi_port = pci_resource_start(pci, 1);
 
 
 	if (request_irq(pci->irq, snd_vt1724_interrupt,
 	if (request_irq(pci->irq, snd_vt1724_interrupt,
-			IRQF_SHARED, "ICE1724", ice)) {
+			IRQF_SHARED, KBUILD_MODNAME, ice)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_vt1724_free(ice);
 		snd_vt1724_free(ice);
 		return -EIO;
 		return -EIO;
@@ -2802,7 +2802,7 @@ static int snd_vt1724_resume(struct pci_dev *pci)
 #endif
 #endif
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "ICE1724",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_vt1724_ids,
 	.id_table = snd_vt1724_ids,
 	.probe = snd_vt1724_probe,
 	.probe = snd_vt1724_probe,
 	.remove = __devexit_p(snd_vt1724_remove),
 	.remove = __devexit_p(snd_vt1724_remove),

+ 9 - 3
sound/pci/intel8x0.c

@@ -1882,6 +1882,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
 		.name = "Dell Inspiron 6000",
 		.name = "Dell Inspiron 6000",
 		.type = AC97_TUNE_HP_MUTE_LED /* cf. Malone #41015 */
 		.type = AC97_TUNE_HP_MUTE_LED /* cf. Malone #41015 */
 	},
 	},
+	{
+		.subvendor = 0x1028,
+		.subdevice = 0x0189,
+		.name = "Dell Inspiron 9300",
+		.type = AC97_TUNE_HP_MUTE_LED
+	},
 	{
 	{
 		.subvendor = 0x1028,
 		.subvendor = 0x1028,
 		.subdevice = 0x0191,
 		.subdevice = 0x0191,
@@ -2647,7 +2653,7 @@ static int intel8x0_resume(struct pci_dev *pci)
 	pci_set_master(pci);
 	pci_set_master(pci);
 	snd_intel8x0_chip_init(chip, 0);
 	snd_intel8x0_chip_init(chip, 0);
 	if (request_irq(pci->irq, snd_intel8x0_interrupt,
 	if (request_irq(pci->irq, snd_intel8x0_interrupt,
-			IRQF_SHARED, card->shortname, chip)) {
+			IRQF_SHARED, KBUILD_MODNAME, chip)) {
 		printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
 		printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
 		       "disabling device\n", pci->irq);
 		       "disabling device\n", pci->irq);
 		snd_card_disconnect(card);
 		snd_card_disconnect(card);
@@ -3106,7 +3112,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
 
 
 	/* request irq after initializaing int_sta_mask, etc */
 	/* request irq after initializaing int_sta_mask, etc */
 	if (request_irq(pci->irq, snd_intel8x0_interrupt,
 	if (request_irq(pci->irq, snd_intel8x0_interrupt,
-			IRQF_SHARED, card->shortname, chip)) {
+			IRQF_SHARED, KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_intel8x0_free(chip);
 		snd_intel8x0_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -3266,7 +3272,7 @@ static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Intel ICH",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_intel8x0_ids,
 	.id_table = snd_intel8x0_ids,
 	.probe = snd_intel8x0_probe,
 	.probe = snd_intel8x0_probe,
 	.remove = __devexit_p(snd_intel8x0_remove),
 	.remove = __devexit_p(snd_intel8x0_remove),

+ 3 - 3
sound/pci/intel8x0m.c

@@ -1047,7 +1047,7 @@ static int intel8x0m_resume(struct pci_dev *pci)
 	}
 	}
 	pci_set_master(pci);
 	pci_set_master(pci);
 	if (request_irq(pci->irq, snd_intel8x0m_interrupt,
 	if (request_irq(pci->irq, snd_intel8x0m_interrupt,
-			IRQF_SHARED, card->shortname, chip)) {
+			IRQF_SHARED, KBUILD_MODNAME, chip)) {
 		printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
 		printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
 		       "disabling device\n", pci->irq);
 		       "disabling device\n", pci->irq);
 		snd_card_disconnect(card);
 		snd_card_disconnect(card);
@@ -1174,7 +1174,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
 
 
  port_inited:
  port_inited:
 	if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
-			card->shortname, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_intel8x0m_free(chip);
 		snd_intel8x0m_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -1325,7 +1325,7 @@ static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Intel ICH Modem",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_intel8x0m_ids,
 	.id_table = snd_intel8x0m_ids,
 	.probe = snd_intel8x0m_probe,
 	.probe = snd_intel8x0m_probe,
 	.remove = __devexit_p(snd_intel8x0m_remove),
 	.remove = __devexit_p(snd_intel8x0m_remove),

+ 2 - 2
sound/pci/korg1212/korg1212.c

@@ -2241,7 +2241,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
 
 
         err = request_irq(pci->irq, snd_korg1212_interrupt,
         err = request_irq(pci->irq, snd_korg1212_interrupt,
                           IRQF_SHARED,
                           IRQF_SHARED,
-                          "korg1212", korg1212);
+                          KBUILD_MODNAME, korg1212);
 
 
         if (err) {
         if (err) {
 		snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
@@ -2477,7 +2477,7 @@ static void __devexit snd_korg1212_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "korg1212",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_korg1212_ids,
 	.id_table = snd_korg1212_ids,
 	.probe = snd_korg1212_probe,
 	.probe = snd_korg1212_probe,
 	.remove = __devexit_p(snd_korg1212_remove),
 	.remove = __devexit_p(snd_korg1212_remove),

+ 2 - 2
sound/pci/lola/lola.c

@@ -648,7 +648,7 @@ static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
 		goto errout;
 		goto errout;
 
 
 	if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
-			DRVNAME, chip)) {
+			KBUILD_MODNAME, chip)) {
 		printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
 		printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
 		err = -EBUSY;
 		err = -EBUSY;
 		goto errout;
 		goto errout;
@@ -771,7 +771,7 @@ MODULE_DEVICE_TABLE(pci, lola_ids);
 
 
 /* pci_driver definition */
 /* pci_driver definition */
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = DRVNAME,
+	.name = KBUILD_MODNAME,
 	.id_table = lola_ids,
 	.id_table = lola_ids,
 	.probe = lola_probe,
 	.probe = lola_probe,
 	.remove = __devexit_p(lola_remove),
 	.remove = __devexit_p(lola_remove),

+ 1 - 1
sound/pci/lola/lola.h

@@ -480,7 +480,7 @@ struct lola {
 
 
 /* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
 /* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
 #define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res)   ((res >> 2) & 0x1f)
 #define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res)   ((res >> 2) & 0x1f)
-#define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res)  ((res >> 7) & 0x1f)
+#define LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(res)  ((res >> 7) & 0x1f)
 
 
 int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
 int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
 		     unsigned int data, unsigned int extdata);
 		     unsigned int data, unsigned int extdata);

+ 93 - 37
sound/pci/lola/lola_mixer.c

@@ -144,40 +144,61 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
 	chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
 	chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
 	chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
 	chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
 
 
-	/* mixer matrix can have unused areas between PhysIn and
+	/* mixer matrix may have unused areas between PhysIn and
 	 * Play or Record and PhysOut zones
 	 * Play or Record and PhysOut zones
 	 */
 	 */
 	chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
 	chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
 		LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
 		LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
 	chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
 	chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
-		LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val);
-
-	/* example : MixerMatrix of LoLa881
-	 * 0-------8------16-------8------16
-	 * |       |       |       |       |
-	 * | INPUT |       | INPUT |       |
-	 * | ->    |unused | ->    |unused |
-	 * | RECORD|       | OUTPUT|       |
-	 * |       |       |       |       |
-	 * 8--------------------------------
-	 * |       |       |       |       |
-	 * |       |       |       |       |
-	 * |unused |unused |unused |unused |
-	 * |       |       |       |       |
-	 * |       |       |       |       |
-	 * 16-------------------------------
-	 * |       |       |       |       |
-	 * | PLAY  |       | PLAY  |       |
-	 * |  ->   |unused | ->    |unused |
-	 * | RECORD|       | OUTPUT|       |
-	 * |       |       |       |       |
-	 * 8--------------------------------
-	 * |       |       |       |       |
-	 * |       |       |       |       |
-	 * |unused |unused |unused |unused |
-	 * |       |       |       |       |
-	 * |       |       |       |       |
-	 * 16-------------------------------
+		LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
+
+	/* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
+	 * +-+  0-------8------16-------8------16
+	 * | |  |       |       |       |       |
+	 * |s|  | INPUT |       | INPUT |       |
+	 * | |->|  ->   |unused |  ->   |unused |
+	 * |r|  |CAPTURE|       | OUTPUT|       |
+	 * | |  |  MIX  |       |  MIX  |       |
+	 * |c|  8--------------------------------
+	 * | |  |       |       |       |       |
+	 * | |  |       |       |       |       |
+	 * |g|  |unused |unused |unused |unused |
+	 * | |  |       |       |       |       |
+	 * |a|  |       |       |       |       |
+	 * | |  16-------------------------------
+	 * |i|  |       |       |       |       |
+	 * | |  | PLAYBK|       | PLAYBK|       |
+	 * |n|->|  ->   |unused |  ->   |unused |
+	 * | |  |CAPTURE|       | OUTPUT|       |
+	 * | |  |  MIX  |       |  MIX  |       |
+	 * |a|  8--------------------------------
+	 * |r|  |       |       |       |       |
+	 * |r|  |       |       |       |       |
+	 * |a|  |unused |unused |unused |unused |
+	 * |y|  |       |       |       |       |
+	 * | |  |       |       |       |       |
+	 * +++  16--|---------------|------------
+	 *      +---V---------------V-----------+
+	 *      |  dest_mix_gain_enable array   |
+	 *      +-------------------------------+
+	 */
+	/* example : MixerMatrix of LoLa280
+	 * +-+  0-------8-2
+	 * | |  |       | |
+	 * |s|  | INPUT | |     INPUT
+	 * |r|->|  ->   | |      ->
+	 * |c|  |CAPTURE| | <-  OUTPUT
+	 * | |  |  MIX  | |      MIX
+	 * |g|  8----------
+	 * |a|  |       | |
+	 * |i|  | PLAYBK| |     PLAYBACK
+	 * |n|->|  ->   | |      ->
+	 * | |  |CAPTURE| | <-  OUTPUT
+	 * |a|  |  MIX  | |      MIX
+	 * |r|  8---|----|-
+	 * |r|  +---V----V-------------------+
+	 * |a|  | dest_mix_gain_enable array |
+	 * |y|  +----------------------------+
 	 */
 	 */
 	if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
 	if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
 	    chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
 	    chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
@@ -192,6 +213,9 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
 		(((1U << chip->mixer.dest_phys_outs) - 1)
 		(((1U << chip->mixer.dest_phys_outs) - 1)
 		 << chip->mixer.dest_phys_out_ofs);
 		 << chip->mixer.dest_phys_out_ofs);
 
 
+	snd_printdd("Mixer src_mask=%x, dest_mask=%x\n",
+		    chip->mixer.src_mask, chip->mixer.dest_mask);
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -202,12 +226,19 @@ static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
 
 
 	if (!(chip->mixer.src_mask & (1 << id)))
 	if (!(chip->mixer.src_mask & (1 << id)))
 		return -EINVAL;
 		return -EINVAL;
-	writew(gain, &chip->mixer.array->src_gain[id]);
 	oldval = val = readl(&chip->mixer.array->src_gain_enable);
 	oldval = val = readl(&chip->mixer.array->src_gain_enable);
 	if (on)
 	if (on)
 		val |= (1 << id);
 		val |= (1 << id);
 	else
 	else
 		val &= ~(1 << id);
 		val &= ~(1 << id);
+	/* test if values unchanged */
+	if ((val == oldval) &&
+	    (gain == readw(&chip->mixer.array->src_gain[id])))
+		return 0;
+
+	snd_printdd("lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
+			id, gain, val);
+	writew(gain, &chip->mixer.array->src_gain[id]);
 	writel(val, &chip->mixer.array->src_gain_enable);
 	writel(val, &chip->mixer.array->src_gain_enable);
 	lola_codec_flush(chip);
 	lola_codec_flush(chip);
 	/* inform micro-controller about the new source gain */
 	/* inform micro-controller about the new source gain */
@@ -269,6 +300,7 @@ static int lola_mixer_set_mapping_gain(struct lola *chip,
 				src, dest);
 				src, dest);
 }
 }
 
 
+#if 0 /* not used */
 static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
 static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
 				     unsigned int mask, unsigned short *gains)
 				     unsigned int mask, unsigned short *gains)
 {
 {
@@ -289,6 +321,7 @@ static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
 	return lola_codec_write(chip, chip->mixer.nid,
 	return lola_codec_write(chip, chip->mixer.nid,
 				LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
 				LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
 }
 }
+#endif /* not used */
 
 
 /*
 /*
  */
  */
@@ -376,6 +409,8 @@ static int set_analog_volume(struct lola *chip, int dir,
 		return 0;
 		return 0;
 	if (external_call)
 	if (external_call)
 		lola_codec_flush(chip);
 		lola_codec_flush(chip);
+	snd_printdd("set_analog_volume (dir=%d idx=%d, volume=%d)\n",
+			dir, idx, val);
 	err = lola_codec_write(chip, pin->nid,
 	err = lola_codec_write(chip, pin->nid,
 			       LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
 			       LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
 	if (err < 0)
 	if (err < 0)
@@ -427,23 +462,40 @@ static int init_mixer_values(struct lola *chip)
 {
 {
 	int i;
 	int i;
 
 
-	/* all src on */
+	/* all sample rate converters on */
 	lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
 	lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
 
 
-	/* clear all matrix */
+	/* clear all mixer matrix settings */
 	memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
 	memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
-	/* set src gain to 0dB */
+	/* inform firmware about all updated matrix columns - capture part */
+	for (i = 0; i < chip->mixer.dest_stream_ins; i++)
+		lola_codec_write(chip, chip->mixer.nid,
+				 LOLA_VERB_SET_DESTINATION_GAIN,
+				 i, 0);
+	/* inform firmware about all updated matrix columns - output part */
+	for (i = 0; i < chip->mixer.dest_phys_outs; i++)
+		lola_codec_write(chip, chip->mixer.nid,
+				 LOLA_VERB_SET_DESTINATION_GAIN,
+				 chip->mixer.dest_phys_out_ofs + i, 0);
+
+	/* set all digital input source (master) gains to 0dB */
 	for (i = 0; i < chip->mixer.src_phys_ins; i++)
 	for (i = 0; i < chip->mixer.src_phys_ins; i++)
 		lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
 		lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
+
+	/* set all digital playback source (master) gains to 0dB */
 	for (i = 0; i < chip->mixer.src_stream_outs; i++)
 	for (i = 0; i < chip->mixer.src_stream_outs; i++)
 		lola_mixer_set_src_gain(chip,
 		lola_mixer_set_src_gain(chip,
 					i + chip->mixer.src_stream_out_ofs,
 					i + chip->mixer.src_stream_out_ofs,
 					336, true); /* 0dB */
 					336, true); /* 0dB */
-	/* set 1:1 dest gain */
+	/* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
 	for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
 	for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
 		int src = i % chip->mixer.src_phys_ins;
 		int src = i % chip->mixer.src_phys_ins;
 		lola_mixer_set_mapping_gain(chip, src, i, 336, true);
 		lola_mixer_set_mapping_gain(chip, src, i, 336, true);
 	}
 	}
+	/* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
+	 * (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
+	 * (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
+	 */
 	for (i = 0; i < chip->mixer.src_stream_outs; i++) {
 	for (i = 0; i < chip->mixer.src_stream_outs; i++) {
 		int src = chip->mixer.src_stream_out_ofs + i;
 		int src = chip->mixer.src_stream_out_ofs + i;
 		int dst = chip->mixer.dest_phys_out_ofs +
 		int dst = chip->mixer.dest_phys_out_ofs +
@@ -693,6 +745,7 @@ static int __devinit create_src_gain_mixer(struct lola *chip,
 			   snd_ctl_new1(&lola_src_gain_mixer, chip));
 			   snd_ctl_new1(&lola_src_gain_mixer, chip));
 }
 }
 
 
+#if 0 /* not used */
 /*
 /*
  * destination gain (matrix-like) mixer
  * destination gain (matrix-like) mixer
  */
  */
@@ -781,6 +834,7 @@ static int __devinit create_dest_gain_mixer(struct lola *chip,
 	return snd_ctl_add(chip->card,
 	return snd_ctl_add(chip->card,
 			  snd_ctl_new1(&lola_dest_gain_mixer, chip));
 			  snd_ctl_new1(&lola_dest_gain_mixer, chip));
 }
 }
+#endif /* not used */
 
 
 /*
 /*
  */
  */
@@ -798,14 +852,16 @@ int __devinit lola_create_mixer(struct lola *chip)
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 	err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
 	err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
-				    "Line Source Gain Volume");
+				    "Digital Capture Volume");
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 	err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
 	err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
 				    chip->mixer.src_stream_out_ofs,
 				    chip->mixer.src_stream_out_ofs,
-				    "Stream Source Gain Volume");
+				    "Digital Playback Volume");
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
+#if 0
+/* FIXME: buggy mixer matrix handling */
 	err = create_dest_gain_mixer(chip,
 	err = create_dest_gain_mixer(chip,
 				     chip->mixer.src_phys_ins, 0,
 				     chip->mixer.src_phys_ins, 0,
 				     chip->mixer.dest_stream_ins, 0,
 				     chip->mixer.dest_stream_ins, 0,
@@ -834,6 +890,6 @@ int __devinit lola_create_mixer(struct lola *chip)
 				     "Stream Playback Volume");
 				     "Stream Playback Volume");
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
-
+#endif /* FIXME */
 	return init_mixer_values(chip);
 	return init_mixer_values(chip);
 }
 }

+ 15 - 10
sound/pci/lx6464es/lx6464es.c

@@ -762,7 +762,6 @@ static int lx_set_granularity(struct lx6464es *chip, u32 gran)
 static int __devinit lx_init_dsp(struct lx6464es *chip)
 static int __devinit lx_init_dsp(struct lx6464es *chip)
 {
 {
 	int err;
 	int err;
-	u8 mac_address[6];
 	int i;
 	int i;
 
 
 	snd_printdd("->lx_init_dsp\n");
 	snd_printdd("->lx_init_dsp\n");
@@ -787,11 +786,11 @@ static int __devinit lx_init_dsp(struct lx6464es *chip)
 	/** \todo the mac address should be ready by not, but it isn't,
 	/** \todo the mac address should be ready by not, but it isn't,
 	 *  so we wait for it */
 	 *  so we wait for it */
 	for (i = 0; i != 1000; ++i) {
 	for (i = 0; i != 1000; ++i) {
-		err = lx_dsp_get_mac(chip, mac_address);
+		err = lx_dsp_get_mac(chip);
 		if (err)
 		if (err)
 			return err;
 			return err;
-		if (mac_address[0] || mac_address[1] || mac_address[2] ||
-		    mac_address[3] || mac_address[4] || mac_address[5])
+		if (chip->mac_address[0] || chip->mac_address[1] || chip->mac_address[2] ||
+		    chip->mac_address[3] || chip->mac_address[4] || chip->mac_address[5])
 			goto mac_ready;
 			goto mac_ready;
 		msleep(1);
 		msleep(1);
 	}
 	}
@@ -800,8 +799,8 @@ static int __devinit lx_init_dsp(struct lx6464es *chip)
 mac_ready:
 mac_ready:
 	snd_printd(LXP "mac address ready read after: %dms\n", i);
 	snd_printd(LXP "mac address ready read after: %dms\n", i);
 	snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n",
 	snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n",
-		   mac_address[0], mac_address[1], mac_address[2],
-		   mac_address[3], mac_address[4], mac_address[5]);
+		   chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
+		   chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
 
 
 	err = lx_init_get_version_features(chip);
 	err = lx_init_get_version_features(chip);
 	if (err)
 	if (err)
@@ -1031,7 +1030,7 @@ static int __devinit snd_lx6464es_create(struct snd_card *card,
 	chip->port_dsp_bar = pci_ioremap_bar(pci, 2);
 	chip->port_dsp_bar = pci_ioremap_bar(pci, 2);
 
 
 	err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED,
 	err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED,
-			  card_name, chip);
+			  KBUILD_MODNAME, chip);
 	if (err) {
 	if (err) {
 		snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq);
 		goto request_irq_failed;
 		goto request_irq_failed;
@@ -1108,8 +1107,14 @@ static int __devinit snd_lx6464es_probe(struct pci_dev *pci,
 		goto out_free;
 		goto out_free;
 	}
 	}
 
 
-	strcpy(card->driver, "lx6464es");
-	strcpy(card->shortname, "Digigram LX6464ES");
+	strcpy(card->driver, "LX6464ES");
+	sprintf(card->id, "LX6464ES_%02X%02X%02X",
+		chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
+
+	sprintf(card->shortname, "LX6464ES %02X.%02X.%02X.%02X.%02X.%02X",
+		chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
+		chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
+
 	sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i",
 	sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i",
 		card->shortname, chip->port_plx,
 		card->shortname, chip->port_plx,
 		chip->port_dsp_bar, chip->irq);
 		chip->port_dsp_bar, chip->irq);
@@ -1137,7 +1142,7 @@ static void __devexit snd_lx6464es_remove(struct pci_dev *pci)
 
 
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name =     "Digigram LX6464ES",
+	.name =     KBUILD_MODNAME,
 	.id_table = snd_lx6464es_ids,
 	.id_table = snd_lx6464es_ids,
 	.probe =    snd_lx6464es_probe,
 	.probe =    snd_lx6464es_probe,
 	.remove = __devexit_p(snd_lx6464es_remove),
 	.remove = __devexit_p(snd_lx6464es_remove),

+ 2 - 0
sound/pci/lx6464es/lx6464es.h

@@ -69,6 +69,8 @@ struct lx6464es {
 	struct pci_dev         *pci;
 	struct pci_dev         *pci;
 	int			irq;
 	int			irq;
 
 
+	u8			mac_address[6];
+
 	spinlock_t		lock;        /* interrupt spinlock */
 	spinlock_t		lock;        /* interrupt spinlock */
 	struct mutex            setup_mutex; /* mutex used in hw_params, open
 	struct mutex            setup_mutex; /* mutex used in hw_params, open
 					      * and close */
 					      * and close */

+ 7 - 7
sound/pci/lx6464es/lx_core.c

@@ -424,7 +424,7 @@ int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
 	return ret;
 	return ret;
 }
 }
 
 
-int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address)
+int lx_dsp_get_mac(struct lx6464es *chip)
 {
 {
 	u32 macmsb, maclsb;
 	u32 macmsb, maclsb;
 
 
@@ -432,12 +432,12 @@ int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address)
 	maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF;
 	maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF;
 
 
 	/* todo: endianess handling */
 	/* todo: endianess handling */
-	mac_address[5] = ((u8 *)(&maclsb))[0];
-	mac_address[4] = ((u8 *)(&maclsb))[1];
-	mac_address[3] = ((u8 *)(&maclsb))[2];
-	mac_address[2] = ((u8 *)(&macmsb))[0];
-	mac_address[1] = ((u8 *)(&macmsb))[1];
-	mac_address[0] = ((u8 *)(&macmsb))[2];
+	chip->mac_address[5] = ((u8 *)(&maclsb))[0];
+	chip->mac_address[4] = ((u8 *)(&maclsb))[1];
+	chip->mac_address[3] = ((u8 *)(&maclsb))[2];
+	chip->mac_address[2] = ((u8 *)(&macmsb))[0];
+	chip->mac_address[1] = ((u8 *)(&macmsb))[1];
+	chip->mac_address[0] = ((u8 *)(&macmsb))[2];
 
 
 	return 0;
 	return 0;
 }
 }

+ 1 - 1
sound/pci/lx6464es/lx_core.h

@@ -116,7 +116,7 @@ int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version);
 int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq);
 int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq);
 int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran);
 int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran);
 int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data);
 int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data);
-int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address);
+int lx_dsp_get_mac(struct lx6464es *chip);
 
 
 
 
 /* low-level pipe handling */
 /* low-level pipe handling */

+ 14 - 61
sound/pci/maestro3.c

@@ -850,11 +850,10 @@ struct snd_m3 {
 	struct input_dev *input_dev;
 	struct input_dev *input_dev;
 	char phys[64];			/* physical device path */
 	char phys[64];			/* physical device path */
 #else
 #else
-	spinlock_t ac97_lock;
 	struct snd_kcontrol *master_switch;
 	struct snd_kcontrol *master_switch;
 	struct snd_kcontrol *master_volume;
 	struct snd_kcontrol *master_volume;
-	struct tasklet_struct hwvol_tq;
 #endif
 #endif
+	struct work_struct hwvol_work;
 
 
 	unsigned int in_suspend;
 	unsigned int in_suspend;
 
 
@@ -1609,13 +1608,10 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
    (without wrap around) in response to volume button presses and then
    (without wrap around) in response to volume button presses and then
    generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
    generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
    of a byte wide register. The meaning of bits 0 and 4 is unknown. */
    of a byte wide register. The meaning of bits 0 and 4 is unknown. */
-static void snd_m3_update_hw_volume(unsigned long private_data)
+static void snd_m3_update_hw_volume(struct work_struct *work)
 {
 {
-	struct snd_m3 *chip = (struct snd_m3 *) private_data;
+	struct snd_m3 *chip = container_of(work, struct snd_m3, hwvol_work);
 	int x, val;
 	int x, val;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
-	unsigned long flags;
-#endif
 
 
 	/* Figure out which volume control button was pushed,
 	/* Figure out which volume control button was pushed,
 	   based on differences from the default register
 	   based on differences from the default register
@@ -1645,21 +1641,13 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
 	if (!chip->master_switch || !chip->master_volume)
 	if (!chip->master_switch || !chip->master_volume)
 		return;
 		return;
 
 
-	/* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
-	spin_lock_irqsave(&chip->ac97_lock, flags);
-
-	val = chip->ac97->regs[AC97_MASTER_VOL];
+	val = snd_ac97_read(chip->ac97, AC97_MASTER);
 	switch (x) {
 	switch (x) {
 	case 0x88:
 	case 0x88:
 		/* The counters have not changed, yet we've received a HV
 		/* The counters have not changed, yet we've received a HV
 		   interrupt. According to tests run by various people this
 		   interrupt. According to tests run by various people this
 		   happens when pressing the mute button. */
 		   happens when pressing the mute button. */
 		val ^= 0x8000;
 		val ^= 0x8000;
-		chip->ac97->regs[AC97_MASTER_VOL] = val;
-		outw(val, chip->iobase + CODEC_DATA);
-		outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
-		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
-			       &chip->master_switch->id);
 		break;
 		break;
 	case 0xaa:
 	case 0xaa:
 		/* counters increased by 1 -> volume up */
 		/* counters increased by 1 -> volume up */
@@ -1667,11 +1655,6 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
 			val--;
 			val--;
 		if ((val & 0x7f00) > 0)
 		if ((val & 0x7f00) > 0)
 			val -= 0x0100;
 			val -= 0x0100;
-		chip->ac97->regs[AC97_MASTER_VOL] = val;
-		outw(val, chip->iobase + CODEC_DATA);
-		outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
-		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
-			       &chip->master_volume->id);
 		break;
 		break;
 	case 0x66:
 	case 0x66:
 		/* counters decreased by 1 -> volume down */
 		/* counters decreased by 1 -> volume down */
@@ -1679,14 +1662,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
 			val++;
 			val++;
 		if ((val & 0x7f00) < 0x1f00)
 		if ((val & 0x7f00) < 0x1f00)
 			val += 0x0100;
 			val += 0x0100;
-		chip->ac97->regs[AC97_MASTER_VOL] = val;
-		outw(val, chip->iobase + CODEC_DATA);
-		outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
-		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
-			       &chip->master_volume->id);
 		break;
 		break;
 	}
 	}
-	spin_unlock_irqrestore(&chip->ac97_lock, flags);
+	if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
+		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &chip->master_switch->id);
 #else
 #else
 	if (!chip->input_dev)
 	if (!chip->input_dev)
 		return;
 		return;
@@ -1730,11 +1710,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
 		return IRQ_NONE;
 		return IRQ_NONE;
 
 
 	if (status & HV_INT_PENDING)
 	if (status & HV_INT_PENDING)
-#ifdef CONFIG_SND_MAESTRO3_INPUT
-		snd_m3_update_hw_volume((unsigned long)chip);
-#else
-		tasklet_schedule(&chip->hwvol_tq);
-#endif
+		schedule_work(&chip->hwvol_work);
 
 
 	/*
 	/*
 	 * ack an assp int if its running
 	 * ack an assp int if its running
@@ -2000,24 +1976,14 @@ static unsigned short
 snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
 {
 	struct snd_m3 *chip = ac97->private_data;
 	struct snd_m3 *chip = ac97->private_data;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
-	unsigned long flags;
-#endif
 	unsigned short data = 0xffff;
 	unsigned short data = 0xffff;
 
 
 	if (snd_m3_ac97_wait(chip))
 	if (snd_m3_ac97_wait(chip))
 		goto fail;
 		goto fail;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
-	spin_lock_irqsave(&chip->ac97_lock, flags);
-#endif
 	snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
 	snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
 	if (snd_m3_ac97_wait(chip))
 	if (snd_m3_ac97_wait(chip))
-		goto fail_unlock;
+		goto fail;
 	data = snd_m3_inw(chip, CODEC_DATA);
 	data = snd_m3_inw(chip, CODEC_DATA);
-fail_unlock:
-#ifndef CONFIG_SND_MAESTRO3_INPUT
-	spin_unlock_irqrestore(&chip->ac97_lock, flags);
-#endif
 fail:
 fail:
 	return data;
 	return data;
 }
 }
@@ -2026,20 +1992,11 @@ static void
 snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
 {
 	struct snd_m3 *chip = ac97->private_data;
 	struct snd_m3 *chip = ac97->private_data;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
-	unsigned long flags;
-#endif
 
 
 	if (snd_m3_ac97_wait(chip))
 	if (snd_m3_ac97_wait(chip))
 		return;
 		return;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
-	spin_lock_irqsave(&chip->ac97_lock, flags);
-#endif
 	snd_m3_outw(chip, val, CODEC_DATA);
 	snd_m3_outw(chip, val, CODEC_DATA);
 	snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
 	snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
-#ifndef CONFIG_SND_MAESTRO3_INPUT
-	spin_unlock_irqrestore(&chip->ac97_lock, flags);
-#endif
 }
 }
 
 
 
 
@@ -2458,6 +2415,7 @@ static int snd_m3_free(struct snd_m3 *chip)
 	struct m3_dma *s;
 	struct m3_dma *s;
 	int i;
 	int i;
 
 
+	cancel_work_sync(&chip->hwvol_work);
 #ifdef CONFIG_SND_MAESTRO3_INPUT
 #ifdef CONFIG_SND_MAESTRO3_INPUT
 	if (chip->input_dev)
 	if (chip->input_dev)
 		input_unregister_device(chip->input_dev);
 		input_unregister_device(chip->input_dev);
@@ -2511,6 +2469,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
 		return 0;
 		return 0;
 
 
 	chip->in_suspend = 1;
 	chip->in_suspend = 1;
+	cancel_work_sync(&chip->hwvol_work);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
 	snd_ac97_suspend(chip->ac97);
@@ -2667,9 +2626,6 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
 	}
 	}
 
 
 	spin_lock_init(&chip->reg_lock);
 	spin_lock_init(&chip->reg_lock);
-#ifndef CONFIG_SND_MAESTRO3_INPUT
-	spin_lock_init(&chip->ac97_lock);
-#endif
 
 
 	switch (pci->device) {
 	switch (pci->device) {
 	case PCI_DEVICE_ID_ESS_ALLEGRO:
 	case PCI_DEVICE_ID_ESS_ALLEGRO:
@@ -2683,6 +2639,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
 	chip->card = card;
 	chip->card = card;
 	chip->pci = pci;
 	chip->pci = pci;
 	chip->irq = -1;
 	chip->irq = -1;
+	INIT_WORK(&chip->hwvol_work, snd_m3_update_hw_volume);
 
 
 	chip->external_amp = enable_amp;
 	chip->external_amp = enable_amp;
 	if (amp_gpio >= 0 && amp_gpio <= 0x0f)
 	if (amp_gpio >= 0 && amp_gpio <= 0x0f)
@@ -2752,12 +2709,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
 
 
 	snd_m3_hv_init(chip);
 	snd_m3_hv_init(chip);
 
 
-#ifndef CONFIG_SND_MAESTRO3_INPUT
-	tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
-#endif
-
 	if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
-			card->driver, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_m3_free(chip);
 		snd_m3_free(chip);
 		return -ENOMEM;
 		return -ENOMEM;
@@ -2885,7 +2838,7 @@ static void __devexit snd_m3_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Maestro3",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_m3_ids,
 	.id_table = snd_m3_ids,
 	.probe = snd_m3_probe,
 	.probe = snd_m3_probe,
 	.remove = __devexit_p(snd_m3_remove),
 	.remove = __devexit_p(snd_m3_remove),

+ 2 - 2
sound/pci/mixart/mixart.c

@@ -1268,7 +1268,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED,
-			CARD_NAME, mgr)) {
+			KBUILD_MODNAME, mgr)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_mixart_free(mgr);
 		snd_mixart_free(mgr);
 		return -EBUSY;
 		return -EBUSY;
@@ -1381,7 +1381,7 @@ static void __devexit snd_mixart_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Digigram miXart",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_mixart_ids,
 	.id_table = snd_mixart_ids,
 	.probe = snd_mixart_probe,
 	.probe = snd_mixart_probe,
 	.remove = __devexit_p(snd_mixart_remove),
 	.remove = __devexit_p(snd_mixart_remove),

+ 2 - 2
sound/pci/nm256/nm256.c

@@ -465,7 +465,7 @@ static int snd_nm256_acquire_irq(struct nm256 *chip)
 	mutex_lock(&chip->irq_mutex);
 	mutex_lock(&chip->irq_mutex);
 	if (chip->irq < 0) {
 	if (chip->irq < 0) {
 		if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED,
 		if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED,
-				chip->card->driver, chip)) {
+				KBUILD_MODNAME, chip)) {
 			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
 			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
 			mutex_unlock(&chip->irq_mutex);
 			mutex_unlock(&chip->irq_mutex);
 			return -EBUSY;
 			return -EBUSY;
@@ -1743,7 +1743,7 @@ static void __devexit snd_nm256_remove(struct pci_dev *pci)
 
 
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "NeoMagic 256",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_nm256_ids,
 	.id_table = snd_nm256_ids,
 	.probe = snd_nm256_probe,
 	.probe = snd_nm256_probe,
 	.remove = __devexit_p(snd_nm256_remove),
 	.remove = __devexit_p(snd_nm256_remove),

+ 1 - 1
sound/pci/oxygen/oxygen.c

@@ -859,7 +859,7 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
 }
 }
 
 
 static struct pci_driver oxygen_driver = {
 static struct pci_driver oxygen_driver = {
-	.name = "CMI8788",
+	.name = KBUILD_MODNAME,
 	.id_table = oxygen_ids,
 	.id_table = oxygen_ids,
 	.probe = generic_oxygen_probe,
 	.probe = generic_oxygen_probe,
 	.remove = __devexit_p(oxygen_pci_remove),
 	.remove = __devexit_p(oxygen_pci_remove),

+ 1 - 1
sound/pci/oxygen/oxygen_lib.c

@@ -655,7 +655,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
 	chip->model.init(chip);
 	chip->model.init(chip);
 
 
 	err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
 	err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
-			  DRIVER, chip);
+			  KBUILD_MODNAME, chip);
 	if (err < 0) {
 	if (err < 0) {
 		snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
 		snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
 		goto err_card;
 		goto err_card;

+ 0 - 6
sound/pci/oxygen/oxygen_pcm.c

@@ -168,12 +168,6 @@ static int oxygen_open(struct snd_pcm_substream *substream,
 		if (err < 0)
 		if (err < 0)
 			return err;
 			return err;
 	}
 	}
-	if (channel == PCM_MULTICH) {
-		err = snd_pcm_hw_constraint_minmax
-			(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 0, 8192000);
-		if (err < 0)
-			return err;
-	}
 	snd_pcm_set_sync(substream);
 	snd_pcm_set_sync(substream);
 	chip->streams[channel] = substream;
 	chip->streams[channel] = substream;
 
 

+ 1 - 1
sound/pci/oxygen/virtuoso.c

@@ -88,7 +88,7 @@ static int __devinit xonar_probe(struct pci_dev *pci,
 }
 }
 
 
 static struct pci_driver xonar_driver = {
 static struct pci_driver xonar_driver = {
-	.name = "AV200",
+	.name = KBUILD_MODNAME,
 	.id_table = xonar_ids,
 	.id_table = xonar_ids,
 	.probe = xonar_probe,
 	.probe = xonar_probe,
 	.remove = __devexit_p(oxygen_pci_remove),
 	.remove = __devexit_p(oxygen_pci_remove),

+ 4 - 1
sound/pci/oxygen/xonar_pcm179x.c

@@ -327,8 +327,10 @@ static void pcm1796_init(struct oxygen *chip)
 {
 {
 	struct xonar_pcm179x *data = chip->model_data;
 	struct xonar_pcm179x *data = chip->model_data;
 
 
-	data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE |
+	data->pcm1796_regs[0][18 - PCM1796_REG_BASE] =
 		PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
 		PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
+	if (!data->broken_i2c)
+		data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE;
 	data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
 	data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
 		PCM1796_FLT_SHARP | PCM1796_ATS_1;
 		PCM1796_FLT_SHARP | PCM1796_ATS_1;
 	data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
 	data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
@@ -1123,6 +1125,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
 			chip->model.control_filter = xonar_st_h6_control_filter;
 			chip->model.control_filter = xonar_st_h6_control_filter;
 			chip->model.dac_channels_pcm = 8;
 			chip->model.dac_channels_pcm = 8;
 			chip->model.dac_channels_mixer = 8;
 			chip->model.dac_channels_mixer = 8;
+			chip->model.dac_volume_min = 255;
 			chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
 			chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
 			break;
 			break;
 		}
 		}

+ 2 - 2
sound/pci/pcxhr/pcxhr.c

@@ -1501,7 +1501,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci,
 	mgr->irq = -1;
 	mgr->irq = -1;
 
 
 	if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED,
-			card_name, mgr)) {
+			KBUILD_MODNAME, mgr)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		pcxhr_free(mgr);
 		pcxhr_free(mgr);
 		return -EBUSY;
 		return -EBUSY;
@@ -1608,7 +1608,7 @@ static void __devexit pcxhr_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Digigram pcxhr",
+	.name = KBUILD_MODNAME,
 	.id_table = pcxhr_ids,
 	.id_table = pcxhr_ids,
 	.probe = pcxhr_probe,
 	.probe = pcxhr_probe,
 	.remove = __devexit_p(pcxhr_remove),
 	.remove = __devexit_p(pcxhr_remove),

+ 3 - 3
sound/pci/riptide/riptide.c

@@ -1890,7 +1890,7 @@ snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
 	UNSET_AIE(hwport);
 	UNSET_AIE(hwport);
 
 
 	if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED,
-			"RIPTIDE", chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
 		snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
 			   pci->irq);
 			   pci->irq);
 		snd_riptide_free(chip);
 		snd_riptide_free(chip);
@@ -2176,7 +2176,7 @@ static void __devexit snd_card_riptide_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "RIPTIDE",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_riptide_ids,
 	.id_table = snd_riptide_ids,
 	.probe = snd_card_riptide_probe,
 	.probe = snd_card_riptide_probe,
 	.remove = __devexit_p(snd_card_riptide_remove),
 	.remove = __devexit_p(snd_card_riptide_remove),
@@ -2188,7 +2188,7 @@ static struct pci_driver driver = {
 
 
 #ifdef SUPPORT_JOYSTICK
 #ifdef SUPPORT_JOYSTICK
 static struct pci_driver joystick_driver = {
 static struct pci_driver joystick_driver = {
-	.name = "Riptide Joystick",
+	.name = KBUILD_MODNAME "-joystick",
 	.id_table = snd_riptide_joystick_ids,
 	.id_table = snd_riptide_joystick_ids,
 	.probe = snd_riptide_joystick_probe,
 	.probe = snd_riptide_joystick_probe,
 	.remove = __devexit_p(snd_riptide_joystick_remove),
 	.remove = __devexit_p(snd_riptide_joystick_remove),

+ 2 - 2
sound/pci/rme32.c

@@ -1355,7 +1355,7 @@ static int __devinit snd_rme32_create(struct rme32 * rme32)
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_SHARED,
-			"RME32", rme32)) {
+			KBUILD_MODNAME, rme32)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
@@ -1985,7 +1985,7 @@ static void __devexit snd_rme32_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name =		"RME Digi32",
+	.name =		KBUILD_MODNAME,
 	.id_table =	snd_rme32_ids,
 	.id_table =	snd_rme32_ids,
 	.probe =	snd_rme32_probe,
 	.probe =	snd_rme32_probe,
 	.remove =	__devexit_p(snd_rme32_remove),
 	.remove =	__devexit_p(snd_rme32_remove),

+ 2 - 2
sound/pci/rme96.c

@@ -1561,7 +1561,7 @@ snd_rme96_create(struct rme96 *rme96)
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED,
-			"RME96", rme96)) {
+			KBUILD_MODNAME, rme96)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
@@ -2396,7 +2396,7 @@ static void __devexit snd_rme96_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "RME Digi96",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_rme96_ids,
 	.id_table = snd_rme96_ids,
 	.probe = snd_rme96_probe,
 	.probe = snd_rme96_probe,
 	.remove = __devexit_p(snd_rme96_remove),
 	.remove = __devexit_p(snd_rme96_remove),

+ 2 - 2
sound/pci/rme9652/hdsp.c

@@ -5482,7 +5482,7 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
 	}
 	}
 
 
 	if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED,
-			"hdsp", hdsp)) {
+			KBUILD_MODNAME, hdsp)) {
 		snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
@@ -5637,7 +5637,7 @@ static void __devexit snd_hdsp_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name =     "RME Hammerfall DSP",
+	.name =     KBUILD_MODNAME,
 	.id_table = snd_hdsp_ids,
 	.id_table = snd_hdsp_ids,
 	.probe =    snd_hdsp_probe,
 	.probe =    snd_hdsp_probe,
 	.remove = __devexit_p(snd_hdsp_remove),
 	.remove = __devexit_p(snd_hdsp_remove),

+ 2 - 2
sound/pci/rme9652/hdspm.c

@@ -6441,7 +6441,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
 			hdspm->port + io_extent - 1);
 			hdspm->port + io_extent - 1);
 
 
 	if (request_irq(pci->irq, snd_hdspm_interrupt,
 	if (request_irq(pci->irq, snd_hdspm_interrupt,
-				IRQF_SHARED, "hdspm", hdspm)) {
+			IRQF_SHARED, KBUILD_MODNAME, hdspm)) {
 		snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
@@ -6779,7 +6779,7 @@ static void __devexit snd_hdspm_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "RME Hammerfall DSP MADI",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_hdspm_ids,
 	.id_table = snd_hdspm_ids,
 	.probe = snd_hdspm_probe,
 	.probe = snd_hdspm_probe,
 	.remove = __devexit_p(snd_hdspm_remove),
 	.remove = __devexit_p(snd_hdspm_remove),

+ 2 - 2
sound/pci/rme9652/rme9652.c

@@ -2479,7 +2479,7 @@ static int __devinit snd_rme9652_create(struct snd_card *card,
 	}
 	}
 	
 	
 	if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED,
-			"rme9652", rme9652)) {
+			KBUILD_MODNAME, rme9652)) {
 		snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
@@ -2632,7 +2632,7 @@ static void __devexit snd_rme9652_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name	  = "RME Digi9652 (Hammerfall)",
+	.name	  = KBUILD_MODNAME,
 	.id_table = snd_rme9652_ids,
 	.id_table = snd_rme9652_ids,
 	.probe	  = snd_rme9652_probe,
 	.probe	  = snd_rme9652_probe,
 	.remove	  = __devexit_p(snd_rme9652_remove),
 	.remove	  = __devexit_p(snd_rme9652_remove),

+ 3 - 3
sound/pci/sis7019.c

@@ -1235,7 +1235,7 @@ static int sis_resume(struct pci_dev *pci)
 	}
 	}
 
 
 	if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
 	if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
-				card->shortname, sis)) {
+			KBUILD_MODNAME, sis)) {
 		printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq);
 		printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq);
 		goto error;
 		goto error;
 	}
 	}
@@ -1341,7 +1341,7 @@ static int __devinit sis_chip_create(struct snd_card *card,
 		goto error_out_cleanup;
 		goto error_out_cleanup;
 
 
 	if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
 	if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
-				card->shortname, sis)) {
+			KBUILD_MODNAME, sis)) {
 		printk(KERN_ERR "unable to allocate irq %d\n", sis->irq);
 		printk(KERN_ERR "unable to allocate irq %d\n", sis->irq);
 		goto error_out_cleanup;
 		goto error_out_cleanup;
 	}
 	}
@@ -1436,7 +1436,7 @@ static void __devexit snd_sis7019_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver sis7019_driver = {
 static struct pci_driver sis7019_driver = {
-	.name = "SiS7019",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_sis7019_ids,
 	.id_table = snd_sis7019_ids,
 	.probe = snd_sis7019_probe,
 	.probe = snd_sis7019_probe,
 	.remove = __devexit_p(snd_sis7019_remove),
 	.remove = __devexit_p(snd_sis7019_remove),

+ 2 - 2
sound/pci/sonicvibes.c

@@ -1294,7 +1294,7 @@ static int __devinit snd_sonicvibes_create(struct snd_card *card,
 	sonic->game_port = pci_resource_start(pci, 4);
 	sonic->game_port = pci_resource_start(pci, 4);
 
 
 	if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED,
-			"S3 SonicVibes", sonic)) {
+			KBUILD_MODNAME, sonic)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_sonicvibes_free(sonic);
 		snd_sonicvibes_free(sonic);
 		return -EBUSY;
 		return -EBUSY;
@@ -1530,7 +1530,7 @@ static void __devexit snd_sonic_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "S3 SonicVibes",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_sonic_ids,
 	.id_table = snd_sonic_ids,
 	.probe = snd_sonic_probe,
 	.probe = snd_sonic_probe,
 	.remove = __devexit_p(snd_sonic_remove),
 	.remove = __devexit_p(snd_sonic_remove),

+ 1 - 1
sound/pci/trident/trident.c

@@ -172,7 +172,7 @@ static void __devexit snd_trident_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Trident4DWaveAudio",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_trident_ids,
 	.id_table = snd_trident_ids,
 	.probe = snd_trident_probe,
 	.probe = snd_trident_probe,
 	.remove = __devexit_p(snd_trident_remove),
 	.remove = __devexit_p(snd_trident_remove),

+ 1 - 1
sound/pci/trident/trident_main.c

@@ -3598,7 +3598,7 @@ int __devinit snd_trident_create(struct snd_card *card,
 	trident->port = pci_resource_start(pci, 0);
 	trident->port = pci_resource_start(pci, 0);
 
 
 	if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
-			"Trident Audio", trident)) {
+			KBUILD_MODNAME, trident)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_trident_free(trident);
 		snd_trident_free(trident);
 		return -EBUSY;
 		return -EBUSY;

+ 2 - 2
sound/pci/via82xx.c

@@ -2377,7 +2377,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
 			chip_type == TYPE_VIA8233 ?
 			chip_type == TYPE_VIA8233 ?
 			snd_via8233_interrupt :	snd_via686_interrupt,
 			snd_via8233_interrupt :	snd_via686_interrupt,
 			IRQF_SHARED,
 			IRQF_SHARED,
-			card->driver, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
 		snd_via82xx_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -2611,7 +2611,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "VIA 82xx Audio",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_via82xx_ids,
 	.id_table = snd_via82xx_ids,
 	.probe = snd_via82xx_probe,
 	.probe = snd_via82xx_probe,
 	.remove = __devexit_p(snd_via82xx_remove),
 	.remove = __devexit_p(snd_via82xx_remove),

+ 2 - 2
sound/pci/via82xx_modem.c

@@ -1129,7 +1129,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
 	}
 	}
 	chip->port = pci_resource_start(pci, 0);
 	chip->port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED,
-			card->driver, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
 		snd_via82xx_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -1224,7 +1224,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "VIA 82xx Modem",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_via82xx_modem_ids,
 	.id_table = snd_via82xx_modem_ids,
 	.probe = snd_via82xx_probe,
 	.probe = snd_via82xx_probe,
 	.remove = __devexit_p(snd_via82xx_remove),
 	.remove = __devexit_p(snd_via82xx_remove),

+ 2 - 2
sound/pci/vx222/vx222.c

@@ -169,7 +169,7 @@ static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci
 		vx->port[i] = pci_resource_start(pci, i + 1);
 		vx->port[i] = pci_resource_start(pci, i + 1);
 
 
 	if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
-			CARD_NAME, chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_vx222_free(chip);
 		snd_vx222_free(chip);
 		return -EBUSY;
 		return -EBUSY;
@@ -290,7 +290,7 @@ static int snd_vx222_resume(struct pci_dev *pci)
 #endif
 #endif
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Digigram VX222",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_vx222_ids,
 	.id_table = snd_vx222_ids,
 	.probe = snd_vx222_probe,
 	.probe = snd_vx222_probe,
 	.remove = __devexit_p(snd_vx222_remove),
 	.remove = __devexit_p(snd_vx222_remove),

+ 1 - 1
sound/pci/ymfpci/ymfpci.c

@@ -345,7 +345,7 @@ static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
 }
 }
 
 
 static struct pci_driver driver = {
 static struct pci_driver driver = {
-	.name = "Yamaha DS-1 PCI",
+	.name = KBUILD_MODNAME,
 	.id_table = snd_ymfpci_ids,
 	.id_table = snd_ymfpci_ids,
 	.probe = snd_card_ymfpci_probe,
 	.probe = snd_card_ymfpci_probe,
 	.remove = __devexit_p(snd_card_ymfpci_remove),
 	.remove = __devexit_p(snd_card_ymfpci_remove),

+ 1 - 1
sound/pci/ymfpci/ymfpci_main.c

@@ -2380,7 +2380,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
 	if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED,
 	if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED,
-			"YMFPCI", chip)) {
+			KBUILD_MODNAME, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ymfpci_free(chip);
 		snd_ymfpci_free(chip);
 		return -EBUSY;
 		return -EBUSY;

+ 1 - 1
sound/pcmcia/pdaudiocf/pdaudiocf.c

@@ -223,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link)
 	if (ret)
 	if (ret)
 		goto failed;
 		goto failed;
 
 
-	ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt);
+	ret = pcmcia_request_irq(link, pdacf_interrupt);
 	if (ret)
 	if (ret)
 		goto failed;
 		goto failed;
 
 

+ 1 - 1
sound/pcmcia/vx/vxpocket.c

@@ -229,7 +229,7 @@ static int vxpocket_config(struct pcmcia_device *link)
 	if (ret)
 	if (ret)
 		goto failed;
 		goto failed;
 
 
-	ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler);
+	ret = pcmcia_request_irq(link, snd_vx_irq_handler);
 	if (ret)
 	if (ret)
 		goto failed;
 		goto failed;
 
 

+ 8 - 8
sound/usb/card.c

@@ -433,9 +433,10 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
  * only at the first time.  the successive calls of this function will
  * only at the first time.  the successive calls of this function will
  * append the pcm interface to the corresponding card.
  * append the pcm interface to the corresponding card.
  */
  */
-static void *snd_usb_audio_probe(struct usb_device *dev,
-				 struct usb_interface *intf,
-				 const struct usb_device_id *usb_id)
+static struct snd_usb_audio *
+snd_usb_audio_probe(struct usb_device *dev,
+		    struct usb_interface *intf,
+		    const struct usb_device_id *usb_id)
 {
 {
 	const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
 	const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
 	int i, err;
 	int i, err;
@@ -540,16 +541,15 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
  * we need to take care of counter, since disconnection can be called also
  * we need to take care of counter, since disconnection can be called also
  * many times as well as usb_audio_probe().
  * many times as well as usb_audio_probe().
  */
  */
-static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
+static void snd_usb_audio_disconnect(struct usb_device *dev,
+				     struct snd_usb_audio *chip)
 {
 {
-	struct snd_usb_audio *chip;
 	struct snd_card *card;
 	struct snd_card *card;
 	struct list_head *p;
 	struct list_head *p;
 
 
-	if (ptr == (void *)-1L)
+	if (chip == (void *)-1L)
 		return;
 		return;
 
 
-	chip = ptr;
 	card = chip->card;
 	card = chip->card;
 	mutex_lock(&register_mutex);
 	mutex_lock(&register_mutex);
 	mutex_lock(&chip->shutdown_mutex);
 	mutex_lock(&chip->shutdown_mutex);
@@ -585,7 +585,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
 static int usb_audio_probe(struct usb_interface *intf,
 static int usb_audio_probe(struct usb_interface *intf,
 			   const struct usb_device_id *id)
 			   const struct usb_device_id *id)
 {
 {
-	void *chip;
+	struct snd_usb_audio *chip;
 	chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
 	chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
 	if (chip) {
 	if (chip) {
 		usb_set_intfdata(intf, chip);
 		usb_set_intfdata(intf, chip);

+ 2 - 0
sound/usb/endpoint.c

@@ -408,6 +408,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 			/* doesn't set the sample rate attribute, but supports it */
 			/* doesn't set the sample rate attribute, but supports it */
 			fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
 			fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
 			break;
 			break;
+		case USB_ID(0x0763, 0x2001):  /* M-Audio Quattro USB */
+		case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
 		case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
 		case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
 		case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
 		case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
 						an older model 77d:223) */
 						an older model 77d:223) */

+ 1 - 1
sound/usb/misc/ua101.c

@@ -645,7 +645,7 @@ static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
 	err = snd_pcm_hw_constraint_minmax(substream->runtime,
 	err = snd_pcm_hw_constraint_minmax(substream->runtime,
 					   SNDRV_PCM_HW_PARAM_PERIOD_TIME,
 					   SNDRV_PCM_HW_PARAM_PERIOD_TIME,
 					   1500000 / ua->packets_per_second,
 					   1500000 / ua->packets_per_second,
-					   8192000);
+					   UINT_MAX);
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 	err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
 	err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);

+ 30 - 0
sound/usb/quirks-table.h

@@ -1677,6 +1677,36 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 		}
 		}
 	}
 	}
 },
 },
+{
+	USB_DEVICE(0x0582, 0x011e),
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+		/* .vendor_name = "BOSS", */
+		/* .product_name = "BR-800", */
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const struct snd_usb_audio_quirk[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const struct snd_usb_midi_endpoint_info) {
+					.out_cables = 0x0001,
+					.in_cables  = 0x0001
+				}
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
 
 
 /* Guillemot devices */
 /* Guillemot devices */
 {
 {

+ 134 - 25
sound/usb/quirks.c

@@ -369,6 +369,30 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
 	return 0;
 	return 0;
 }
 }
 
 
+static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)
+{
+	int err;
+
+	if (dev->actconfig->desc.bConfigurationValue == 1) {
+		snd_printk(KERN_INFO "usb-audio: "
+			   "Fast Track Pro switching to config #2\n");
+		/* This function has to be available by the usb core module.
+		 * if it is not avialable the boot quirk has to be left out
+		 * and the configuration has to be set by udev or hotplug
+		 * rules
+		 */
+		err = usb_driver_set_configuration(dev, 2);
+		if (err < 0) {
+			snd_printdd("error usb_driver_set_configuration: %d\n",
+				    err);
+			return -ENODEV;
+		}
+	} else
+		snd_printk(KERN_INFO "usb-audio: Fast Track Pro config OK\n");
+
+	return 0;
+}
+
 /*
 /*
  * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
  * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
  * documented in the device's data sheet.
  * documented in the device's data sheet.
@@ -471,16 +495,49 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
 /*
 /*
  * Setup quirks
  * Setup quirks
  */
  */
-#define AUDIOPHILE_SET			0x01 /* if set, parse device_setup */
-#define AUDIOPHILE_SET_DTS              0x02 /* if set, enable DTS Digital Output */
-#define AUDIOPHILE_SET_96K              0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
-#define AUDIOPHILE_SET_24B		0x08 /* 24bits sample if set, 16bits otherwise */
-#define AUDIOPHILE_SET_DI		0x10 /* if set, enable Digital Input */
-#define AUDIOPHILE_SET_MASK		0x1F /* bit mask for setup value */
-#define AUDIOPHILE_SET_24B_48K_DI	0x19 /* value for 24bits+48KHz+Digital Input */
-#define AUDIOPHILE_SET_24B_48K_NOTDI	0x09 /* value for 24bits+48KHz+No Digital Input */
-#define AUDIOPHILE_SET_16B_48K_DI	0x11 /* value for 16bits+48KHz+Digital Input */
-#define AUDIOPHILE_SET_16B_48K_NOTDI	0x01 /* value for 16bits+48KHz+No Digital Input */
+#define MAUDIO_SET		0x01 /* parse device_setup */
+#define MAUDIO_SET_COMPATIBLE	0x80 /* use only "win-compatible" interfaces */
+#define MAUDIO_SET_DTS		0x02 /* enable DTS Digital Output */
+#define MAUDIO_SET_96K		0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
+#define MAUDIO_SET_24B		0x08 /* 24bits sample if set, 16bits otherwise */
+#define MAUDIO_SET_DI		0x10 /* enable Digital Input */
+#define MAUDIO_SET_MASK		0x1f /* bit mask for setup value */
+#define MAUDIO_SET_24B_48K_DI	 0x19 /* 24bits+48KHz+Digital Input */
+#define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48KHz+No Digital Input */
+#define MAUDIO_SET_16B_48K_DI	 0x11 /* 16bits+48KHz+Digital Input */
+#define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48KHz+No Digital Input */
+
+static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
+				      int iface, int altno)
+{
+	/* Reset ALL ifaces to 0 altsetting.
+	 * Call it for every possible altsetting of every interface.
+	 */
+	usb_set_interface(chip->dev, iface, 0);
+	if (chip->setup & MAUDIO_SET) {
+		if (chip->setup & MAUDIO_SET_COMPATIBLE) {
+			if (iface != 1 && iface != 2)
+				return 1; /* skip all interfaces but 1 and 2 */
+		} else {
+			unsigned int mask;
+			if (iface == 1 || iface == 2)
+				return 1; /* skip interfaces 1 and 2 */
+			if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
+				return 1; /* skip this altsetting */
+			mask = chip->setup & MAUDIO_SET_MASK;
+			if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
+				return 1; /* skip this altsetting */
+			if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
+				return 1; /* skip this altsetting */
+			if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 4)
+				return 1; /* skip this altsetting */
+		}
+	}
+	snd_printdd(KERN_INFO
+		    "using altsetting %d for interface %d config %d\n",
+		    altno, iface, chip->setup);
+	return 0; /* keep this altsetting */
+}
 
 
 static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
 static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
 					 int iface,
 					 int iface,
@@ -491,30 +548,65 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
 	 */
 	 */
 	usb_set_interface(chip->dev, iface, 0);
 	usb_set_interface(chip->dev, iface, 0);
 
 
-	if (chip->setup & AUDIOPHILE_SET) {
-		if ((chip->setup & AUDIOPHILE_SET_DTS)
-		    && altno != 6)
+	if (chip->setup & MAUDIO_SET) {
+		unsigned int mask;
+		if ((chip->setup & MAUDIO_SET_DTS) && altno != 6)
 			return 1; /* skip this altsetting */
 			return 1; /* skip this altsetting */
-		if ((chip->setup & AUDIOPHILE_SET_96K)
-		    && altno != 1)
+		if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
 			return 1; /* skip this altsetting */
 			return 1; /* skip this altsetting */
-		if ((chip->setup & AUDIOPHILE_SET_MASK) ==
-		    AUDIOPHILE_SET_24B_48K_DI && altno != 2)
+		mask = chip->setup & MAUDIO_SET_MASK;
+		if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
 			return 1; /* skip this altsetting */
 			return 1; /* skip this altsetting */
-		if ((chip->setup & AUDIOPHILE_SET_MASK) ==
-		    AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
+		if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
 			return 1; /* skip this altsetting */
 			return 1; /* skip this altsetting */
-		if ((chip->setup & AUDIOPHILE_SET_MASK) ==
-		    AUDIOPHILE_SET_16B_48K_DI && altno != 4)
+		if (mask == MAUDIO_SET_16B_48K_DI && altno != 4)
 			return 1; /* skip this altsetting */
 			return 1; /* skip this altsetting */
-		if ((chip->setup & AUDIOPHILE_SET_MASK) ==
-		    AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
+		if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5)
 			return 1; /* skip this altsetting */
 			return 1; /* skip this altsetting */
 	}
 	}
 
 
 	return 0; /* keep this altsetting */
 	return 0; /* keep this altsetting */
 }
 }
 
 
+
+static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
+					   int iface, int altno)
+{
+	/* Reset ALL ifaces to 0 altsetting.
+	 * Call it for every possible altsetting of every interface.
+	 */
+	usb_set_interface(chip->dev, iface, 0);
+
+	/* possible configuration where both inputs and only one output is
+	 *used is not supported by the current setup
+	 */
+	if (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) {
+		if (chip->setup & MAUDIO_SET_96K) {
+			if (altno != 3 && altno != 6)
+				return 1;
+		} else if (chip->setup & MAUDIO_SET_DI) {
+			if (iface == 4)
+				return 1; /* no analog input */
+			if (altno != 2 && altno != 5)
+				return 1; /* enable only altsets 2 and 5 */
+		} else {
+			if (iface == 5)
+				return 1; /* disable digialt input */
+			if (altno != 2 && altno != 5)
+				return 1; /* enalbe only altsets 2 and 5 */
+		}
+	} else {
+		/* keep only 16-Bit mode */
+		if (altno != 1)
+			return 1;
+	}
+
+	snd_printdd(KERN_INFO
+		    "using altsetting %d for interface %d config %d\n",
+		    altno, iface, chip->setup);
+	return 0; /* keep this altsetting */
+}
+
 int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
 int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
 				  int iface,
 				  int iface,
 				  int altno)
 				  int altno)
@@ -522,6 +614,12 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
 	/* audiophile usb: skip altsets incompatible with device_setup */
 	/* audiophile usb: skip altsets incompatible with device_setup */
 	if (chip->usb_id == USB_ID(0x0763, 0x2003))
 	if (chip->usb_id == USB_ID(0x0763, 0x2003))
 		return audiophile_skip_setting_quirk(chip, iface, altno);
 		return audiophile_skip_setting_quirk(chip, iface, altno);
+	/* quattro usb: skip altsets incompatible with device_setup */
+	if (chip->usb_id == USB_ID(0x0763, 0x2001))
+		return quattro_skip_setting_quirk(chip, iface, altno);
+	/* fasttrackpro usb: skip altsets incompatible with device_setup */
+	if (chip->usb_id == USB_ID(0x0763, 0x2012))
+		return fasttrackpro_skip_setting_quirk(chip, iface, altno);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -560,6 +658,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
 	case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
 	case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
 	case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
 	case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
 		return snd_usb_nativeinstruments_boot_quirk(dev);
 		return snd_usb_nativeinstruments_boot_quirk(dev);
+	case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
+		return snd_usb_fasttrackpro_boot_quirk(dev);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -570,15 +670,24 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
  */
  */
 int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
 int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
 {
 {
+	/* it depends on altsetting wether the device is big-endian or not */
 	switch (chip->usb_id) {
 	switch (chip->usb_id) {
 	case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
 	case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
-		if (fp->endpoint & USB_DIR_IN)
+		if (fp->altsetting == 2 || fp->altsetting == 3 ||
+			fp->altsetting == 5 || fp->altsetting == 6)
 			return 1;
 			return 1;
 		break;
 		break;
 	case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
 	case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
 		if (chip->setup == 0x00 ||
 		if (chip->setup == 0x00 ||
-		    fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
+			fp->altsetting == 1 || fp->altsetting == 2 ||
+			fp->altsetting == 3)
+			return 1;
+		break;
+	case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */
+		if (fp->altsetting == 2 || fp->altsetting == 3 ||
+			fp->altsetting == 5 || fp->altsetting == 6)
 			return 1;
 			return 1;
+		break;
 	}
 	}
 	return 0;
 	return 0;
 }
 }