aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-03-18 13:22:33 -0400
committerTakashi Iwai <tiwai@suse.de>2012-03-18 13:22:33 -0400
commit44c76a960a62fcc46cbcaa0a22a34e666a729329 (patch)
treed3887c858f6adffb6714da3cdc0059f93588344c /sound
parentdbf117cbb9c89991727d42e3161e68b868a1b6ae (diff)
parentc6b76d1f02e2ab1109d8549877a3a24c6a2b4587 (diff)
Merge branch 'topic/misc' into for-linus
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/codecs/onyx.c13
-rw-r--r--sound/aoa/codecs/tas.c13
-rw-r--r--sound/core/control.c2
-rw-r--r--sound/core/init.c169
-rw-r--r--sound/core/misc.c2
-rw-r--r--sound/core/pcm_lib.c3
-rw-r--r--sound/core/pcm_native.c15
-rw-r--r--sound/pci/au88x0/au88x0.h13
-rw-r--r--sound/pci/au88x0/au88x0_core.c20
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c127
-rw-r--r--sound/pci/ctxfi/ctvmem.c2
-rw-r--r--sound/pci/ice1712/ice1724.c23
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c9
-rw-r--r--sound/spi/at73c213.c12
-rw-r--r--sound/usb/6fire/chip.c3
-rw-r--r--sound/usb/6fire/chip.h1
-rw-r--r--sound/usb/6fire/comm.c1
-rw-r--r--sound/usb/6fire/comm.h1
-rw-r--r--sound/usb/6fire/common.h1
-rw-r--r--sound/usb/6fire/control.c341
-rw-r--r--sound/usb/6fire/control.h7
-rw-r--r--sound/usb/6fire/firmware.c1
-rw-r--r--sound/usb/6fire/midi.c1
-rw-r--r--sound/usb/6fire/midi.h1
-rw-r--r--sound/usb/6fire/pcm.c1
-rw-r--r--sound/usb/6fire/pcm.h1
-rw-r--r--sound/usb/Kconfig1
-rw-r--r--sound/usb/pcm.c6
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c4
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c2
30 files changed, 606 insertions, 190 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 762af68c8996..270790d384e2 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -1132,15 +1132,4 @@ static struct i2c_driver onyx_driver = {
1132 .id_table = onyx_i2c_id, 1132 .id_table = onyx_i2c_id,
1133}; 1133};
1134 1134
1135static int __init onyx_init(void) 1135module_i2c_driver(onyx_driver);
1136{
1137 return i2c_add_driver(&onyx_driver);
1138}
1139
1140static void __exit onyx_exit(void)
1141{
1142 i2c_del_driver(&onyx_driver);
1143}
1144
1145module_init(onyx_init);
1146module_exit(onyx_exit);
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index fd2188c3df2b..8e63d1f35ce1 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -1026,15 +1026,4 @@ static struct i2c_driver tas_driver = {
1026 .id_table = tas_i2c_id, 1026 .id_table = tas_i2c_id,
1027}; 1027};
1028 1028
1029static int __init tas_init(void) 1029module_i2c_driver(tas_driver);
1030{
1031 return i2c_add_driver(&tas_driver);
1032}
1033
1034static void __exit tas_exit(void)
1035{
1036 i2c_del_driver(&tas_driver);
1037}
1038
1039module_init(tas_init);
1040module_exit(tas_exit);
diff --git a/sound/core/control.c b/sound/core/control.c
index 819a5c579a39..2487a6bb1c54 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1313,7 +1313,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1313 err = -EPERM; 1313 err = -EPERM;
1314 goto __kctl_end; 1314 goto __kctl_end;
1315 } 1315 }
1316 err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); 1316 err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
1317 if (err > 0) { 1317 if (err > 0) {
1318 up_read(&card->controls_rwsem); 1318 up_read(&card->controls_rwsem);
1319 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); 1319 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id);
diff --git a/sound/core/init.c b/sound/core/init.c
index 3ac49b1b7cb8..068cf08d3ffb 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -480,74 +480,104 @@ int snd_card_free(struct snd_card *card)
480 480
481EXPORT_SYMBOL(snd_card_free); 481EXPORT_SYMBOL(snd_card_free);
482 482
483static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid) 483/* retrieve the last word of shortname or longname */
484static const char *retrieve_id_from_card_name(const char *name)
484{ 485{
485 int i, len, idx_flag = 0, loops = SNDRV_CARDS; 486 const char *spos = name;
486 const char *spos, *src; 487
487 char *id; 488 while (*name) {
488 489 if (isspace(*name) && isalnum(name[1]))
489 if (nid == NULL) { 490 spos = name + 1;
490 id = card->shortname; 491 name++;
491 spos = src = id;
492 while (*id != '\0') {
493 if (*id == ' ')
494 spos = id + 1;
495 id++;
496 }
497 } else {
498 spos = src = nid;
499 } 492 }
500 id = card->id; 493 return spos;
501 while (*spos != '\0' && !isalnum(*spos)) 494}
502 spos++; 495
503 if (isdigit(*spos)) 496/* return true if the given id string doesn't conflict any other card ids */
504 *id++ = isalpha(src[0]) ? src[0] : 'D'; 497static bool card_id_ok(struct snd_card *card, const char *id)
505 while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) { 498{
506 if (isalnum(*spos)) 499 int i;
507 *id++ = *spos; 500 if (!snd_info_check_reserved_words(id))
508 spos++; 501 return false;
502 for (i = 0; i < snd_ecards_limit; i++) {
503 if (snd_cards[i] && snd_cards[i] != card &&
504 !strcmp(snd_cards[i]->id, id))
505 return false;
509 } 506 }
510 *id = '\0'; 507 return true;
508}
511 509
512 id = card->id; 510/* copy to card->id only with valid letters from nid */
511static void copy_valid_id_string(struct snd_card *card, const char *src,
512 const char *nid)
513{
514 char *id = card->id;
515
516 while (*nid && !isalnum(*nid))
517 nid++;
518 if (isdigit(*nid))
519 *id++ = isalpha(*src) ? *src : 'D';
520 while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) {
521 if (isalnum(*nid))
522 *id++ = *nid;
523 nid++;
524 }
525 *id = 0;
526}
527
528/* Set card->id from the given string
529 * If the string conflicts with other ids, add a suffix to make it unique.
530 */
531static void snd_card_set_id_no_lock(struct snd_card *card, const char *src,
532 const char *nid)
533{
534 int len, loops;
535 bool with_suffix;
536 bool is_default = false;
537 char *id;
513 538
514 if (*id == '\0') 539 copy_valid_id_string(card, src, nid);
540 id = card->id;
541
542 again:
543 /* use "Default" for obviously invalid strings
544 * ("card" conflicts with proc directories)
545 */
546 if (!*id || !strncmp(id, "card", 4)) {
515 strcpy(id, "Default"); 547 strcpy(id, "Default");
548 is_default = true;
549 }
516 550
517 while (1) { 551 with_suffix = false;
518 if (loops-- == 0) { 552 for (loops = 0; loops < SNDRV_CARDS; loops++) {
519 snd_printk(KERN_ERR "unable to set card id (%s)\n", id); 553 if (card_id_ok(card, id))
520 strcpy(card->id, card->proc_root->name); 554 return; /* OK */
521 return;
522 }
523 if (!snd_info_check_reserved_words(id))
524 goto __change;
525 for (i = 0; i < snd_ecards_limit; i++) {
526 if (snd_cards[i] && !strcmp(snd_cards[i]->id, id))
527 goto __change;
528 }
529 break;
530 555
531 __change:
532 len = strlen(id); 556 len = strlen(id);
533 if (idx_flag) { 557 if (!with_suffix) {
534 if (id[len-1] != '9') 558 /* add the "_X" suffix */
535 id[len-1]++; 559 char *spos = id + len;
536 else 560 if (len > sizeof(card->id) - 3)
537 id[len-1] = 'A'; 561 spos = id + sizeof(card->id) - 3;
538 } else if ((size_t)len <= sizeof(card->id) - 3) { 562 strcpy(spos, "_1");
539 strcat(id, "_1"); 563 with_suffix = true;
540 idx_flag++;
541 } else { 564 } else {
542 spos = id + len - 2; 565 /* modify the existing suffix */
543 if ((size_t)len <= sizeof(card->id) - 2) 566 if (id[len - 1] != '9')
544 spos++; 567 id[len - 1]++;
545 *(char *)spos++ = '_'; 568 else
546 *(char *)spos++ = '1'; 569 id[len - 1] = 'A';
547 *(char *)spos++ = '\0';
548 idx_flag++;
549 } 570 }
550 } 571 }
572 /* fallback to the default id */
573 if (!is_default) {
574 *id = 0;
575 goto again;
576 }
577 /* last resort... */
578 snd_printk(KERN_ERR "unable to set card id (%s)\n", id);
579 if (card->proc_root->name)
580 strcpy(card->id, card->proc_root->name);
551} 581}
552 582
553/** 583/**
@@ -564,7 +594,7 @@ void snd_card_set_id(struct snd_card *card, const char *nid)
564 if (card->id[0] != '\0') 594 if (card->id[0] != '\0')
565 return; 595 return;
566 mutex_lock(&snd_card_mutex); 596 mutex_lock(&snd_card_mutex);
567 snd_card_set_id_no_lock(card, nid); 597 snd_card_set_id_no_lock(card, nid, nid);
568 mutex_unlock(&snd_card_mutex); 598 mutex_unlock(&snd_card_mutex);
569} 599}
570EXPORT_SYMBOL(snd_card_set_id); 600EXPORT_SYMBOL(snd_card_set_id);
@@ -596,22 +626,12 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr,
596 memcpy(buf1, buf, copy); 626 memcpy(buf1, buf, copy);
597 buf1[copy] = '\0'; 627 buf1[copy] = '\0';
598 mutex_lock(&snd_card_mutex); 628 mutex_lock(&snd_card_mutex);
599 if (!snd_info_check_reserved_words(buf1)) { 629 if (!card_id_ok(NULL, buf1)) {
600 __exist:
601 mutex_unlock(&snd_card_mutex); 630 mutex_unlock(&snd_card_mutex);
602 return -EEXIST; 631 return -EEXIST;
603 } 632 }
604 for (idx = 0; idx < snd_ecards_limit; idx++) {
605 if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) {
606 if (card == snd_cards[idx])
607 goto __ok;
608 else
609 goto __exist;
610 }
611 }
612 strcpy(card->id, buf1); 633 strcpy(card->id, buf1);
613 snd_info_card_id_change(card); 634 snd_info_card_id_change(card);
614__ok:
615 mutex_unlock(&snd_card_mutex); 635 mutex_unlock(&snd_card_mutex);
616 636
617 return count; 637 return count;
@@ -665,7 +685,18 @@ int snd_card_register(struct snd_card *card)
665 mutex_unlock(&snd_card_mutex); 685 mutex_unlock(&snd_card_mutex);
666 return 0; 686 return 0;
667 } 687 }
668 snd_card_set_id_no_lock(card, card->id[0] == '\0' ? NULL : card->id); 688 if (*card->id) {
689 /* make a unique id name from the given string */
690 char tmpid[sizeof(card->id)];
691 memcpy(tmpid, card->id, sizeof(card->id));
692 snd_card_set_id_no_lock(card, tmpid, tmpid);
693 } else {
694 /* create an id from either shortname or longname */
695 const char *src;
696 src = *card->shortname ? card->shortname : card->longname;
697 snd_card_set_id_no_lock(card, src,
698 retrieve_id_from_card_name(src));
699 }
669 snd_cards[card->number] = card; 700 snd_cards[card->number] = card;
670 mutex_unlock(&snd_card_mutex); 701 mutex_unlock(&snd_card_mutex);
671 init_info_for_card(card); 702 init_info_for_card(card);
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 465f0ce772cb..768167925409 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -72,7 +72,7 @@ void __snd_printk(unsigned int level, const char *path, int line,
72 char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV"; 72 char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV";
73#endif 73#endif
74 74
75#ifdef CONFIG_SND_DEBUG 75#ifdef CONFIG_SND_DEBUG
76 if (debug < level) 76 if (debug < level)
77 return; 77 return;
78#endif 78#endif
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 3420bd3da5d7..4d18941178e6 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1029,7 +1029,8 @@ static int snd_interval_ratden(struct snd_interval *i,
1029 * 1029 *
1030 * Returns non-zero if the value is changed, zero if not changed. 1030 * Returns non-zero if the value is changed, zero if not changed.
1031 */ 1031 */
1032int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask) 1032int snd_interval_list(struct snd_interval *i, unsigned int count,
1033 const unsigned int *list, unsigned int mask)
1033{ 1034{
1034 unsigned int k; 1035 unsigned int k;
1035 struct snd_interval list_range; 1036 struct snd_interval list_range;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 25ed9fe41b89..3fe99e644eb8 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1586,12 +1586,18 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
1586 struct file *file; 1586 struct file *file;
1587 struct snd_pcm_file *pcm_file; 1587 struct snd_pcm_file *pcm_file;
1588 struct snd_pcm_substream *substream1; 1588 struct snd_pcm_substream *substream1;
1589 struct snd_pcm_group *group;
1589 1590
1590 file = snd_pcm_file_fd(fd); 1591 file = snd_pcm_file_fd(fd);
1591 if (!file) 1592 if (!file)
1592 return -EBADFD; 1593 return -EBADFD;
1593 pcm_file = file->private_data; 1594 pcm_file = file->private_data;
1594 substream1 = pcm_file->substream; 1595 substream1 = pcm_file->substream;
1596 group = kmalloc(sizeof(*group), GFP_KERNEL);
1597 if (!group) {
1598 res = -ENOMEM;
1599 goto _nolock;
1600 }
1595 down_write(&snd_pcm_link_rwsem); 1601 down_write(&snd_pcm_link_rwsem);
1596 write_lock_irq(&snd_pcm_link_rwlock); 1602 write_lock_irq(&snd_pcm_link_rwlock);
1597 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || 1603 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
@@ -1604,11 +1610,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
1604 goto _end; 1610 goto _end;
1605 } 1611 }
1606 if (!snd_pcm_stream_linked(substream)) { 1612 if (!snd_pcm_stream_linked(substream)) {
1607 substream->group = kmalloc(sizeof(struct snd_pcm_group), GFP_ATOMIC); 1613 substream->group = group;
1608 if (substream->group == NULL) {
1609 res = -ENOMEM;
1610 goto _end;
1611 }
1612 spin_lock_init(&substream->group->lock); 1614 spin_lock_init(&substream->group->lock);
1613 INIT_LIST_HEAD(&substream->group->substreams); 1615 INIT_LIST_HEAD(&substream->group->substreams);
1614 list_add_tail(&substream->link_list, &substream->group->substreams); 1616 list_add_tail(&substream->link_list, &substream->group->substreams);
@@ -1620,7 +1622,10 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
1620 _end: 1622 _end:
1621 write_unlock_irq(&snd_pcm_link_rwlock); 1623 write_unlock_irq(&snd_pcm_link_rwlock);
1622 up_write(&snd_pcm_link_rwsem); 1624 up_write(&snd_pcm_link_rwsem);
1625 _nolock:
1623 fput(file); 1626 fput(file);
1627 if (res < 0)
1628 kfree(group);
1624 return res; 1629 return res;
1625} 1630}
1626 1631
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index bb938153a964..466a5c8e8354 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -26,7 +26,7 @@
26#include <sound/mpu401.h> 26#include <sound/mpu401.h>
27#include <sound/hwdep.h> 27#include <sound/hwdep.h>
28#include <sound/ac97_codec.h> 28#include <sound/ac97_codec.h>
29 29#include <sound/tlv.h>
30#endif 30#endif
31 31
32#ifndef CHIP_AU8820 32#ifndef CHIP_AU8820
@@ -107,6 +107,14 @@
107#define NR_WTPB 0x20 /* WT channels per each bank. */ 107#define NR_WTPB 0x20 /* WT channels per each bank. */
108#define NR_PCM 0x10 108#define NR_PCM 0x10
109 109
110struct pcm_vol {
111 struct snd_kcontrol *kctl;
112 int active;
113 int dma;
114 int mixin[4];
115 int vol[4];
116};
117
110/* Structs */ 118/* Structs */
111typedef struct { 119typedef struct {
112 //int this_08; /* Still unknown */ 120 //int this_08; /* Still unknown */
@@ -168,6 +176,7 @@ struct snd_vortex {
168 /* Xtalk canceler */ 176 /* Xtalk canceler */
169 int xt_mode; /* 1: speakers, 0:headphones. */ 177 int xt_mode; /* 1: speakers, 0:headphones. */
170#endif 178#endif
179 struct pcm_vol pcm_vol[NR_PCM];
171 180
172 int isquad; /* cache of extended ID codec flag. */ 181 int isquad; /* cache of extended ID codec flag. */
173 182
@@ -239,7 +248,7 @@ static int vortex_alsafmt_aspfmt(int alsafmt);
239/* Connection stuff. */ 248/* Connection stuff. */
240static void vortex_connect_default(vortex_t * vortex, int en); 249static void vortex_connect_default(vortex_t * vortex, int en);
241static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, 250static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
242 int dir, int type); 251 int dir, int type, int subdev);
243static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, 252static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
244 int restype); 253 int restype);
245#ifndef CHIP_AU8810 254#ifndef CHIP_AU8810
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 6933a27a5d76..525f881f0409 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -2050,8 +2050,6 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
2050} 2050}
2051 2051
2052/* Default Connections */ 2052/* Default Connections */
2053static int
2054vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
2055 2053
2056static void vortex_connect_default(vortex_t * vortex, int en) 2054static void vortex_connect_default(vortex_t * vortex, int en)
2057{ 2055{
@@ -2111,15 +2109,13 @@ static void vortex_connect_default(vortex_t * vortex, int en)
2111 Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0. 2109 Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
2112*/ 2110*/
2113static int 2111static int
2114vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) 2112vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir,
2113 int type, int subdev)
2115{ 2114{
2116 stream_t *stream; 2115 stream_t *stream;
2117 int i, en; 2116 int i, en;
2117 struct pcm_vol *p;
2118 2118
2119 if ((nr_ch == 3)
2120 || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
2121 return -EBUSY;
2122
2123 if (dma >= 0) { 2119 if (dma >= 0) {
2124 en = 0; 2120 en = 0;
2125 vortex_adb_checkinout(vortex, 2121 vortex_adb_checkinout(vortex,
@@ -2250,6 +2246,14 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
2250 MIX_DEFIGAIN); 2246 MIX_DEFIGAIN);
2251#endif 2247#endif
2252 } 2248 }
2249 if (stream->type == VORTEX_PCM_ADB && en) {
2250 p = &vortex->pcm_vol[subdev];
2251 p->dma = dma;
2252 for (i = 0; i < nr_ch; i++)
2253 p->mixin[i] = mix[i];
2254 for (i = 0; i < ch_top; i++)
2255 p->vol[i] = 0;
2256 }
2253 } 2257 }
2254#ifndef CHIP_AU8820 2258#ifndef CHIP_AU8820
2255 else { 2259 else {
@@ -2473,7 +2477,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id)
2473 hwread(vortex->mmio, VORTEX_IRQ_STAT); 2477 hwread(vortex->mmio, VORTEX_IRQ_STAT);
2474 handled = 1; 2478 handled = 1;
2475 } 2479 }
2476 if (source & IRQ_MIDI) { 2480 if ((source & IRQ_MIDI) && vortex->rmidi) {
2477 snd_mpu401_uart_interrupt(vortex->irq, 2481 snd_mpu401_uart_interrupt(vortex->irq,
2478 vortex->rmidi->private_data); 2482 vortex->rmidi->private_data);
2479 handled = 1; 2483 handled = 1;
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 0ef2f9712208..e59f120742a4 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -122,6 +122,18 @@ static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
122 .mask = 0, 122 .mask = 0,
123}; 123};
124#endif 124#endif
125
126static void vortex_notify_pcm_vol_change(struct snd_card *card,
127 struct snd_kcontrol *kctl, int activate)
128{
129 if (activate)
130 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
131 else
132 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
133 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
134 SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
135}
136
125/* open callback */ 137/* open callback */
126static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) 138static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
127{ 139{
@@ -230,12 +242,14 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
230 if (stream != NULL) 242 if (stream != NULL)
231 vortex_adb_allocroute(chip, stream->dma, 243 vortex_adb_allocroute(chip, stream->dma,
232 stream->nr_ch, stream->dir, 244 stream->nr_ch, stream->dir,
233 stream->type); 245 stream->type,
246 substream->number);
234 /* Alloc routes. */ 247 /* Alloc routes. */
235 dma = 248 dma =
236 vortex_adb_allocroute(chip, -1, 249 vortex_adb_allocroute(chip, -1,
237 params_channels(hw_params), 250 params_channels(hw_params),
238 substream->stream, type); 251 substream->stream, type,
252 substream->number);
239 if (dma < 0) { 253 if (dma < 0) {
240 spin_unlock_irq(&chip->lock); 254 spin_unlock_irq(&chip->lock);
241 return dma; 255 return dma;
@@ -246,6 +260,11 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
246 vortex_adbdma_setbuffers(chip, dma, 260 vortex_adbdma_setbuffers(chip, dma,
247 params_period_bytes(hw_params), 261 params_period_bytes(hw_params),
248 params_periods(hw_params)); 262 params_periods(hw_params));
263 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
264 chip->pcm_vol[substream->number].active = 1;
265 vortex_notify_pcm_vol_change(chip->card,
266 chip->pcm_vol[substream->number].kctl, 1);
267 }
249 } 268 }
250#ifndef CHIP_AU8810 269#ifndef CHIP_AU8810
251 else { 270 else {
@@ -275,10 +294,18 @@ static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
275 spin_lock_irq(&chip->lock); 294 spin_lock_irq(&chip->lock);
276 // Delete audio routes. 295 // Delete audio routes.
277 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { 296 if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
278 if (stream != NULL) 297 if (stream != NULL) {
298 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
299 chip->pcm_vol[substream->number].active = 0;
300 vortex_notify_pcm_vol_change(chip->card,
301 chip->pcm_vol[substream->number].kctl,
302 0);
303 }
279 vortex_adb_allocroute(chip, stream->dma, 304 vortex_adb_allocroute(chip, stream->dma,
280 stream->nr_ch, stream->dir, 305 stream->nr_ch, stream->dir,
281 stream->type); 306 stream->type,
307 substream->number);
308 }
282 } 309 }
283#ifndef CHIP_AU8810 310#ifndef CHIP_AU8810
284 else { 311 else {
@@ -506,6 +533,83 @@ static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
506 }, 533 },
507}; 534};
508 535
536/* subdevice PCM Volume control */
537
538static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
539 struct snd_ctl_elem_info *uinfo)
540{
541 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
542 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
543 uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
544 uinfo->value.integer.min = -128;
545 uinfo->value.integer.max = 32;
546 return 0;
547}
548
549static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
550 struct snd_ctl_elem_value *ucontrol)
551{
552 int i;
553 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
554 int subdev = kcontrol->id.subdevice;
555 struct pcm_vol *p = &vortex->pcm_vol[subdev];
556 int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
557 for (i = 0; i < max_chn; i++)
558 ucontrol->value.integer.value[i] = p->vol[i];
559 return 0;
560}
561
562static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
564{
565 int i;
566 int changed = 0;
567 int mixin;
568 unsigned char vol;
569 vortex_t *vortex = snd_kcontrol_chip(kcontrol);
570 int subdev = kcontrol->id.subdevice;
571 struct pcm_vol *p = &vortex->pcm_vol[subdev];
572 int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
573 for (i = 0; i < max_chn; i++) {
574 if (p->vol[i] != ucontrol->value.integer.value[i]) {
575 p->vol[i] = ucontrol->value.integer.value[i];
576 if (p->active) {
577 switch (vortex->dma_adb[p->dma].nr_ch) {
578 case 1:
579 mixin = p->mixin[0];
580 break;
581 case 2:
582 default:
583 mixin = p->mixin[(i < 2) ? i : (i - 2)];
584 break;
585 case 4:
586 mixin = p->mixin[i];
587 break;
588 };
589 vol = p->vol[i];
590 vortex_mix_setinputvolumebyte(vortex,
591 vortex->mixplayb[i], mixin, vol);
592 }
593 changed = 1;
594 }
595 }
596 return changed;
597}
598
599static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
600
601static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = {
602 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
603 .name = "PCM Playback Volume",
604 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
605 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
606 SNDRV_CTL_ELEM_ACCESS_INACTIVE,
607 .info = snd_vortex_pcm_vol_info,
608 .get = snd_vortex_pcm_vol_get,
609 .put = snd_vortex_pcm_vol_put,
610 .tlv = { .p = vortex_pcm_vol_db_scale },
611};
612
509/* create a pcm device */ 613/* create a pcm device */
510static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) 614static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
511{ 615{
@@ -555,5 +659,20 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
555 return err; 659 return err;
556 } 660 }
557 } 661 }
662 if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
663 for (i = 0; i < NR_PCM; i++) {
664 chip->pcm_vol[i].active = 0;
665 chip->pcm_vol[i].dma = -1;
666 kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
667 if (!kctl)
668 return -ENOMEM;
669 chip->pcm_vol[i].kctl = kctl;
670 kctl->id.device = 0;
671 kctl->id.subdevice = i;
672 err = snd_ctl_add(chip->card, kctl);
673 if (err < 0)
674 return err;
675 }
676 }
558 return 0; 677 return 0;
559} 678}
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index b78f3fc3c33c..6109490b83e8 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -36,7 +36,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
36 36
37 size = CT_PAGE_ALIGN(size); 37 size = CT_PAGE_ALIGN(size);
38 if (size > vm->size) { 38 if (size > vm->size) {
39 printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural " 39 printk(KERN_ERR "ctxfi: Fail! No sufficient device virtual "
40 "memory space available!\n"); 40 "memory space available!\n");
41 return NULL; 41 return NULL;
42 } 42 }
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 92362973764d..812d10e43ae0 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -1013,6 +1013,25 @@ static int set_rate_constraints(struct snd_ice1712 *ice,
1013 ice->hw_rates); 1013 ice->hw_rates);
1014} 1014}
1015 1015
1016/* if the card has the internal rate locked (is_pro_locked), limit runtime
1017 hw rates to the current internal rate only.
1018*/
1019static void constrain_rate_if_locked(struct snd_pcm_substream *substream)
1020{
1021 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
1022 struct snd_pcm_runtime *runtime = substream->runtime;
1023 unsigned int rate;
1024 if (is_pro_rate_locked(ice)) {
1025 rate = ice->get_rate(ice);
1026 if (rate >= runtime->hw.rate_min
1027 && rate <= runtime->hw.rate_max) {
1028 runtime->hw.rate_min = rate;
1029 runtime->hw.rate_max = rate;
1030 }
1031 }
1032}
1033
1034
1016/* multi-channel playback needs alignment 8x32bit regardless of the channels 1035/* multi-channel playback needs alignment 8x32bit regardless of the channels
1017 * actually used 1036 * actually used
1018 */ 1037 */
@@ -1046,6 +1065,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
1046 VT1724_BUFFER_ALIGN); 1065 VT1724_BUFFER_ALIGN);
1047 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1066 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1048 VT1724_BUFFER_ALIGN); 1067 VT1724_BUFFER_ALIGN);
1068 constrain_rate_if_locked(substream);
1049 if (ice->pro_open) 1069 if (ice->pro_open)
1050 ice->pro_open(ice, substream); 1070 ice->pro_open(ice, substream);
1051 return 0; 1071 return 0;
@@ -1066,6 +1086,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
1066 VT1724_BUFFER_ALIGN); 1086 VT1724_BUFFER_ALIGN);
1067 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1087 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1068 VT1724_BUFFER_ALIGN); 1088 VT1724_BUFFER_ALIGN);
1089 constrain_rate_if_locked(substream);
1069 if (ice->pro_open) 1090 if (ice->pro_open)
1070 ice->pro_open(ice, substream); 1091 ice->pro_open(ice, substream);
1071 return 0; 1092 return 0;
@@ -1215,6 +1236,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream)
1215 VT1724_BUFFER_ALIGN); 1236 VT1724_BUFFER_ALIGN);
1216 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1237 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1217 VT1724_BUFFER_ALIGN); 1238 VT1724_BUFFER_ALIGN);
1239 constrain_rate_if_locked(substream);
1218 if (ice->spdif.ops.open) 1240 if (ice->spdif.ops.open)
1219 ice->spdif.ops.open(ice, substream); 1241 ice->spdif.ops.open(ice, substream);
1220 return 0; 1242 return 0;
@@ -1251,6 +1273,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream)
1251 VT1724_BUFFER_ALIGN); 1273 VT1724_BUFFER_ALIGN);
1252 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1274 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
1253 VT1724_BUFFER_ALIGN); 1275 VT1724_BUFFER_ALIGN);
1276 constrain_rate_if_locked(substream);
1254 if (ice->spdif.ops.open) 1277 if (ice->spdif.ops.open)
1255 ice->spdif.ops.open(ice, substream); 1278 ice->spdif.ops.open(ice, substream);
1256 return 0; 1279 return 0;
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 12a9a2b03387..a8159b81e9c4 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2317,6 +2317,10 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
2317 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) 2317 for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++)
2318 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); 2318 chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]);
2319 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); 2319 chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
2320 pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY,
2321 &chip->saved_dsxg_legacy);
2322 pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2323 &chip->saved_dsxg_elegacy);
2320 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); 2324 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
2321 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); 2325 snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0);
2322 snd_ymfpci_disable_dsp(chip); 2326 snd_ymfpci_disable_dsp(chip);
@@ -2351,6 +2355,11 @@ int snd_ymfpci_resume(struct pci_dev *pci)
2351 2355
2352 snd_ac97_resume(chip->ac97); 2356 snd_ac97_resume(chip->ac97);
2353 2357
2358 pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY,
2359 chip->saved_dsxg_legacy);
2360 pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY,
2361 chip->saved_dsxg_elegacy);
2362
2354 /* start hw again */ 2363 /* start hw again */
2355 if (chip->start_count > 0) { 2364 if (chip->start_count > 0) {
2356 spin_lock_irq(&chip->reg_lock); 2365 spin_lock_irq(&chip->reg_lock);
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c
index 4dd051bdf4fd..c6500d00053b 100644
--- a/sound/spi/at73c213.c
+++ b/sound/spi/at73c213.c
@@ -1112,17 +1112,7 @@ static struct spi_driver at73c213_driver = {
1112 .remove = __devexit_p(snd_at73c213_remove), 1112 .remove = __devexit_p(snd_at73c213_remove),
1113}; 1113};
1114 1114
1115static int __init at73c213_init(void) 1115module_spi_driver(at73c213_driver);
1116{
1117 return spi_register_driver(&at73c213_driver);
1118}
1119module_init(at73c213_init);
1120
1121static void __exit at73c213_exit(void)
1122{
1123 spi_unregister_driver(&at73c213_driver);
1124}
1125module_exit(at73c213_exit);
1126 1116
1127MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); 1117MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
1128MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC"); 1118MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC");
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index 8af92e3e9c18..fc8cc823e438 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
@@ -29,7 +28,7 @@
29#include <sound/initval.h> 28#include <sound/initval.h>
30 29
31MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>"); 30MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>");
32MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver, version 0.3.0"); 31MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver");
33MODULE_LICENSE("GPL v2"); 32MODULE_LICENSE("GPL v2");
34MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}"); 33MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}");
35 34
diff --git a/sound/usb/6fire/chip.h b/sound/usb/6fire/chip.h
index d11e5cb520f0..bde02d105a51 100644
--- a/sound/usb/6fire/chip.h
+++ b/sound/usb/6fire/chip.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c
index c994daa57af2..6c3d531a250e 100644
--- a/sound/usb/6fire/comm.c
+++ b/sound/usb/6fire/comm.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/comm.h b/sound/usb/6fire/comm.h
index edc5dc84b888..d2af0a5ddcf3 100644
--- a/sound/usb/6fire/comm.h
+++ b/sound/usb/6fire/comm.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/common.h b/sound/usb/6fire/common.h
index 7dbeb4a37831..b6eb03ed1c2c 100644
--- a/sound/usb/6fire/common.h
+++ b/sound/usb/6fire/common.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c
index ac828eff1a63..07ed914d5e71 100644
--- a/sound/usb/6fire/control.c
+++ b/sound/usb/6fire/control.c
@@ -5,9 +5,12 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
10 * Thanks to:
11 * - Holger Ruckdeschel: he found out how to control individual channel
12 * volumes and introduced mute switch
13 *
11 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 16 * the Free Software Foundation; either version 2 of the License, or
@@ -16,6 +19,7 @@
16 19
17#include <linux/interrupt.h> 20#include <linux/interrupt.h>
18#include <sound/control.h> 21#include <sound/control.h>
22#include <sound/tlv.h>
19 23
20#include "control.h" 24#include "control.h"
21#include "comm.h" 25#include "comm.h"
@@ -25,26 +29,6 @@ static char *opt_coax_texts[2] = { "Optical", "Coax" };
25static char *line_phono_texts[2] = { "Line", "Phono" }; 29static char *line_phono_texts[2] = { "Line", "Phono" };
26 30
27/* 31/*
28 * calculated with $value\[i\] = 128 \cdot sqrt[3]{\frac{i}{128}}$
29 * this is done because the linear values cause rapid degredation
30 * of volume in the uppermost region.
31 */
32static const u8 log_volume_table[128] = {
33 0x00, 0x19, 0x20, 0x24, 0x28, 0x2b, 0x2e, 0x30, 0x32, 0x34,
34 0x36, 0x38, 0x3a, 0x3b, 0x3d, 0x3e, 0x40, 0x41, 0x42, 0x43,
35 0x44, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
36 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x53, 0x54, 0x55, 0x56,
37 0x56, 0x57, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c,
38 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x62, 0x62,
39 0x63, 0x63, 0x64, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68,
40 0x68, 0x69, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c,
41 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71,
42 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75,
43 0x75, 0x76, 0x76, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79,
44 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c,
45 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f };
46
47/*
48 * data that needs to be sent to device. sets up card internal stuff. 32 * data that needs to be sent to device. sets up card internal stuff.
49 * values dumped from windows driver and filtered by trial'n'error. 33 * values dumped from windows driver and filtered by trial'n'error.
50 */ 34 */
@@ -59,7 +43,7 @@ init_data[] = {
59 { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 }, 43 { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 },
60 { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 }, 44 { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 },
61 { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 }, 45 { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 },
62 { 0x12, 0x0d, 0x78 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 }, 46 { 0x12, 0x0d, 0x38 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 },
63 { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 }, 47 { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 },
64 { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 }, 48 { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 },
65 { 0 } /* TERMINATING ENTRY */ 49 { 0 } /* TERMINATING ENTRY */
@@ -70,20 +54,47 @@ static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 };
70static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; 54static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
71static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; 55static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00};
72 56
57static DECLARE_TLV_DB_MINMAX(tlv_output, -9000, 0);
58static DECLARE_TLV_DB_MINMAX(tlv_input, -1500, 1500);
59
73enum { 60enum {
74 DIGITAL_THRU_ONLY_SAMPLERATE = 3 61 DIGITAL_THRU_ONLY_SAMPLERATE = 3
75}; 62};
76 63
77static void usb6fire_control_master_vol_update(struct control_runtime *rt) 64static void usb6fire_control_output_vol_update(struct control_runtime *rt)
78{ 65{
79 struct comm_runtime *comm_rt = rt->chip->comm; 66 struct comm_runtime *comm_rt = rt->chip->comm;
80 if (comm_rt) { 67 int i;
81 /* set volume */ 68
82 comm_rt->write8(comm_rt, 0x12, 0x0f, 0x7f - 69 if (comm_rt)
83 log_volume_table[rt->master_vol]); 70 for (i = 0; i < 6; i++)
84 /* unmute */ 71 if (!(rt->ovol_updated & (1 << i))) {
85 comm_rt->write8(comm_rt, 0x12, 0x0e, 0x00); 72 comm_rt->write8(comm_rt, 0x12, 0x0f + i,
86 } 73 180 - rt->output_vol[i]);
74 rt->ovol_updated |= 1 << i;
75 }
76}
77
78static void usb6fire_control_output_mute_update(struct control_runtime *rt)
79{
80 struct comm_runtime *comm_rt = rt->chip->comm;
81
82 if (comm_rt)
83 comm_rt->write8(comm_rt, 0x12, 0x0e, ~rt->output_mute);
84}
85
86static void usb6fire_control_input_vol_update(struct control_runtime *rt)
87{
88 struct comm_runtime *comm_rt = rt->chip->comm;
89 int i;
90
91 if (comm_rt)
92 for (i = 0; i < 2; i++)
93 if (!(rt->ivol_updated & (1 << i))) {
94 comm_rt->write8(comm_rt, 0x12, 0x1c + i,
95 rt->input_vol[i] & 0x3f);
96 rt->ivol_updated |= 1 << i;
97 }
87} 98}
88 99
89static void usb6fire_control_line_phono_update(struct control_runtime *rt) 100static void usb6fire_control_line_phono_update(struct control_runtime *rt)
@@ -165,34 +176,147 @@ static int usb6fire_control_streaming_update(struct control_runtime *rt)
165 return -EINVAL; 176 return -EINVAL;
166} 177}
167 178
168static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, 179static int usb6fire_control_output_vol_info(struct snd_kcontrol *kcontrol,
169 struct snd_ctl_elem_info *uinfo) 180 struct snd_ctl_elem_info *uinfo)
170{ 181{
171 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 182 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
172 uinfo->count = 1; 183 uinfo->count = 2;
173 uinfo->value.integer.min = 0; 184 uinfo->value.integer.min = 0;
174 uinfo->value.integer.max = 127; 185 uinfo->value.integer.max = 180;
175 return 0; 186 return 0;
176} 187}
177 188
178static int usb6fire_control_master_vol_put(struct snd_kcontrol *kcontrol, 189static int usb6fire_control_output_vol_put(struct snd_kcontrol *kcontrol,
179 struct snd_ctl_elem_value *ucontrol) 190 struct snd_ctl_elem_value *ucontrol)
180{ 191{
181 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 192 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
193 unsigned int ch = kcontrol->private_value;
182 int changed = 0; 194 int changed = 0;
183 if (rt->master_vol != ucontrol->value.integer.value[0]) { 195
184 rt->master_vol = ucontrol->value.integer.value[0]; 196 if (ch > 4) {
185 usb6fire_control_master_vol_update(rt); 197 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
198 return -EINVAL;
199 }
200
201 if (rt->output_vol[ch] != ucontrol->value.integer.value[0]) {
202 rt->output_vol[ch] = ucontrol->value.integer.value[0];
203 rt->ovol_updated &= ~(1 << ch);
186 changed = 1; 204 changed = 1;
187 } 205 }
206 if (rt->output_vol[ch + 1] != ucontrol->value.integer.value[1]) {
207 rt->output_vol[ch + 1] = ucontrol->value.integer.value[1];
208 rt->ovol_updated &= ~(2 << ch);
209 changed = 1;
210 }
211
212 if (changed)
213 usb6fire_control_output_vol_update(rt);
214
188 return changed; 215 return changed;
189} 216}
190 217
191static int usb6fire_control_master_vol_get(struct snd_kcontrol *kcontrol, 218static int usb6fire_control_output_vol_get(struct snd_kcontrol *kcontrol,
192 struct snd_ctl_elem_value *ucontrol) 219 struct snd_ctl_elem_value *ucontrol)
193{ 220{
194 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 221 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
195 ucontrol->value.integer.value[0] = rt->master_vol; 222 unsigned int ch = kcontrol->private_value;
223
224 if (ch > 4) {
225 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
226 return -EINVAL;
227 }
228
229 ucontrol->value.integer.value[0] = rt->output_vol[ch];
230 ucontrol->value.integer.value[1] = rt->output_vol[ch + 1];
231 return 0;
232}
233
234static int usb6fire_control_output_mute_put(struct snd_kcontrol *kcontrol,
235 struct snd_ctl_elem_value *ucontrol)
236{
237 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
238 unsigned int ch = kcontrol->private_value;
239 u8 old = rt->output_mute;
240 u8 value = 0;
241
242 if (ch > 4) {
243 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
244 return -EINVAL;
245 }
246
247 rt->output_mute &= ~(3 << ch);
248 if (ucontrol->value.integer.value[0])
249 value |= 1;
250 if (ucontrol->value.integer.value[1])
251 value |= 2;
252 rt->output_mute |= value << ch;
253
254 if (rt->output_mute != old)
255 usb6fire_control_output_mute_update(rt);
256
257 return rt->output_mute != old;
258}
259
260static int usb6fire_control_output_mute_get(struct snd_kcontrol *kcontrol,
261 struct snd_ctl_elem_value *ucontrol)
262{
263 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
264 unsigned int ch = kcontrol->private_value;
265 u8 value = rt->output_mute >> ch;
266
267 if (ch > 4) {
268 snd_printk(KERN_ERR PREFIX "Invalid channel in volume control.");
269 return -EINVAL;
270 }
271
272 ucontrol->value.integer.value[0] = 1 & value;
273 value >>= 1;
274 ucontrol->value.integer.value[1] = 1 & value;
275
276 return 0;
277}
278
279static int usb6fire_control_input_vol_info(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_info *uinfo)
281{
282 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
283 uinfo->count = 2;
284 uinfo->value.integer.min = 0;
285 uinfo->value.integer.max = 30;
286 return 0;
287}
288
289static int usb6fire_control_input_vol_put(struct snd_kcontrol *kcontrol,
290 struct snd_ctl_elem_value *ucontrol)
291{
292 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
293 int changed = 0;
294
295 if (rt->input_vol[0] != ucontrol->value.integer.value[0]) {
296 rt->input_vol[0] = ucontrol->value.integer.value[0] - 15;
297 rt->ivol_updated &= ~(1 << 0);
298 changed = 1;
299 }
300 if (rt->input_vol[1] != ucontrol->value.integer.value[1]) {
301 rt->input_vol[1] = ucontrol->value.integer.value[1] - 15;
302 rt->ivol_updated &= ~(1 << 1);
303 changed = 1;
304 }
305
306 if (changed)
307 usb6fire_control_input_vol_update(rt);
308
309 return changed;
310}
311
312static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol,
313 struct snd_ctl_elem_value *ucontrol)
314{
315 struct control_runtime *rt = snd_kcontrol_chip(kcontrol);
316
317 ucontrol->value.integer.value[0] = rt->input_vol[0] + 15;
318 ucontrol->value.integer.value[1] = rt->input_vol[1] + 15;
319
196 return 0; 320 return 0;
197} 321}
198 322
@@ -287,18 +411,83 @@ static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol,
287 return 0; 411 return 0;
288} 412}
289 413
290static struct __devinitdata snd_kcontrol_new elements[] = { 414static struct __devinitdata snd_kcontrol_new vol_elements[] = {
291 { 415 {
292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
293 .name = "Master Playback Volume", 417 .name = "Analog Playback Volume",
294 .index = 0, 418 .index = 0,
419 .private_value = 0,
420 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
421 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
422 .info = usb6fire_control_output_vol_info,
423 .get = usb6fire_control_output_vol_get,
424 .put = usb6fire_control_output_vol_put,
425 .tlv = { .p = tlv_output }
426 },
427 {
428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
429 .name = "Analog Playback Volume",
430 .index = 1,
431 .private_value = 2,
432 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
433 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
434 .info = usb6fire_control_output_vol_info,
435 .get = usb6fire_control_output_vol_get,
436 .put = usb6fire_control_output_vol_put,
437 .tlv = { .p = tlv_output }
438 },
439 {
440 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
441 .name = "Analog Playback Volume",
442 .index = 2,
443 .private_value = 4,
444 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
445 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
446 .info = usb6fire_control_output_vol_info,
447 .get = usb6fire_control_output_vol_get,
448 .put = usb6fire_control_output_vol_put,
449 .tlv = { .p = tlv_output }
450 },
451 {}
452};
453
454static struct __devinitdata snd_kcontrol_new mute_elements[] = {
455 {
456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
457 .name = "Analog Playback Switch",
458 .index = 0,
459 .private_value = 0,
460 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
461 .info = snd_ctl_boolean_stereo_info,
462 .get = usb6fire_control_output_mute_get,
463 .put = usb6fire_control_output_mute_put,
464 },
465 {
466 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
467 .name = "Analog Playback Switch",
468 .index = 1,
469 .private_value = 2,
295 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 470 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
296 .info = usb6fire_control_master_vol_info, 471 .info = snd_ctl_boolean_stereo_info,
297 .get = usb6fire_control_master_vol_get, 472 .get = usb6fire_control_output_mute_get,
298 .put = usb6fire_control_master_vol_put 473 .put = usb6fire_control_output_mute_put,
299 }, 474 },
300 { 475 {
301 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 476 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
477 .name = "Analog Playback Switch",
478 .index = 2,
479 .private_value = 4,
480 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
481 .info = snd_ctl_boolean_stereo_info,
482 .get = usb6fire_control_output_mute_get,
483 .put = usb6fire_control_output_mute_put,
484 },
485 {}
486};
487
488static struct __devinitdata snd_kcontrol_new elements[] = {
489 {
490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
302 .name = "Line/Phono Capture Route", 491 .name = "Line/Phono Capture Route",
303 .index = 0, 492 .index = 0,
304 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 493 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -324,9 +513,54 @@ static struct __devinitdata snd_kcontrol_new elements[] = {
324 .get = usb6fire_control_digital_thru_get, 513 .get = usb6fire_control_digital_thru_get,
325 .put = usb6fire_control_digital_thru_put 514 .put = usb6fire_control_digital_thru_put
326 }, 515 },
516 {
517 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
518 .name = "Analog Capture Volume",
519 .index = 0,
520 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
521 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
522 .info = usb6fire_control_input_vol_info,
523 .get = usb6fire_control_input_vol_get,
524 .put = usb6fire_control_input_vol_put,
525 .tlv = { .p = tlv_input }
526 },
327 {} 527 {}
328}; 528};
329 529
530static int usb6fire_control_add_virtual(
531 struct control_runtime *rt,
532 struct snd_card *card,
533 char *name,
534 struct snd_kcontrol_new *elems)
535{
536 int ret;
537 int i;
538 struct snd_kcontrol *vmaster =
539 snd_ctl_make_virtual_master(name, tlv_output);
540 struct snd_kcontrol *control;
541
542 if (!vmaster)
543 return -ENOMEM;
544 ret = snd_ctl_add(card, vmaster);
545 if (ret < 0)
546 return ret;
547
548 i = 0;
549 while (elems[i].name) {
550 control = snd_ctl_new1(&elems[i], rt);
551 if (!control)
552 return -ENOMEM;
553 ret = snd_ctl_add(card, control);
554 if (ret < 0)
555 return ret;
556 ret = snd_ctl_add_slave(vmaster, control);
557 if (ret < 0)
558 return ret;
559 i++;
560 }
561 return 0;
562}
563
330int __devinit usb6fire_control_init(struct sfire_chip *chip) 564int __devinit usb6fire_control_init(struct sfire_chip *chip)
331{ 565{
332 int i; 566 int i;
@@ -352,9 +586,26 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip)
352 586
353 usb6fire_control_opt_coax_update(rt); 587 usb6fire_control_opt_coax_update(rt);
354 usb6fire_control_line_phono_update(rt); 588 usb6fire_control_line_phono_update(rt);
355 usb6fire_control_master_vol_update(rt); 589 usb6fire_control_output_vol_update(rt);
590 usb6fire_control_output_mute_update(rt);
591 usb6fire_control_input_vol_update(rt);
356 usb6fire_control_streaming_update(rt); 592 usb6fire_control_streaming_update(rt);
357 593
594 ret = usb6fire_control_add_virtual(rt, chip->card,
595 "Master Playback Volume", vol_elements);
596 if (ret) {
597 snd_printk(KERN_ERR PREFIX "cannot add control.\n");
598 kfree(rt);
599 return ret;
600 }
601 ret = usb6fire_control_add_virtual(rt, chip->card,
602 "Master Playback Switch", mute_elements);
603 if (ret) {
604 snd_printk(KERN_ERR PREFIX "cannot add control.\n");
605 kfree(rt);
606 return ret;
607 }
608
358 i = 0; 609 i = 0;
359 while (elements[i].name) { 610 while (elements[i].name) {
360 ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt)); 611 ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt));
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h
index 8f5aeead2e3d..9a596d95474a 100644
--- a/sound/usb/6fire/control.h
+++ b/sound/usb/6fire/control.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
@@ -44,7 +43,11 @@ struct control_runtime {
44 bool line_phono_switch; 43 bool line_phono_switch;
45 bool digital_thru_switch; 44 bool digital_thru_switch;
46 bool usb_streaming; 45 bool usb_streaming;
47 u8 master_vol; 46 u8 output_vol[6];
47 u8 ovol_updated;
48 u8 output_mute;
49 s8 input_vol[2];
50 u8 ivol_updated;
48}; 51};
49 52
50int __devinit usb6fire_control_init(struct sfire_chip *chip); 53int __devinit usb6fire_control_init(struct sfire_chip *chip);
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index 3b5f517a3972..6f9715ab32fe 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c
index 13f4509dce2b..f0e5179b242b 100644
--- a/sound/usb/6fire/midi.c
+++ b/sound/usb/6fire/midi.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/midi.h b/sound/usb/6fire/midi.h
index 97a7bf669135..5114eccc1d8e 100644
--- a/sound/usb/6fire/midi.h
+++ b/sound/usb/6fire/midi.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index d144cdb2f159..c97d05f0e966 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * Author: Torsten Schenk <torsten.schenk@zoho.com> 6 * Author: Torsten Schenk <torsten.schenk@zoho.com>
7 * Created: Jan 01, 2011 7 * Created: Jan 01, 2011
8 * Version: 0.3.0
9 * Copyright: (C) Torsten Schenk 8 * Copyright: (C) Torsten Schenk
10 * 9 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h
index 2bee81374002..3104301b257d 100644
--- a/sound/usb/6fire/pcm.h
+++ b/sound/usb/6fire/pcm.h
@@ -3,7 +3,6 @@
3 * 3 *
4 * Author: Torsten Schenk <torsten.schenk@zoho.com> 4 * Author: Torsten Schenk <torsten.schenk@zoho.com>
5 * Created: Jan 01, 2011 5 * Created: Jan 01, 2011
6 * Version: 0.3.0
7 * Copyright: (C) Torsten Schenk 6 * Copyright: (C) Torsten Schenk
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 3efc21c3d67c..ff77b28f3da1 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -106,6 +106,7 @@ config SND_USB_6FIRE
106 select BITREVERSE 106 select BITREVERSE
107 select SND_RAWMIDI 107 select SND_RAWMIDI
108 select SND_PCM 108 select SND_PCM
109 select SND_VMASTER
109 help 110 help
110 Say Y here to include support for TerraTec 6fire DMX USB interface. 111 Say Y here to include support for TerraTec 6fire DMX USB interface.
111 112
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 0220b0f335b9..0eed6115c2d4 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -695,6 +695,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
695 struct snd_usb_substream *subs) 695 struct snd_usb_substream *subs)
696{ 696{
697 struct audioformat *fp; 697 struct audioformat *fp;
698 int *rate_list;
698 int count = 0, needs_knot = 0; 699 int count = 0, needs_knot = 0;
699 int err; 700 int err;
700 701
@@ -708,7 +709,8 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
708 if (!needs_knot) 709 if (!needs_knot)
709 return 0; 710 return 0;
710 711
711 subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); 712 subs->rate_list.list = rate_list =
713 kmalloc(sizeof(int) * count, GFP_KERNEL);
712 if (!subs->rate_list.list) 714 if (!subs->rate_list.list)
713 return -ENOMEM; 715 return -ENOMEM;
714 subs->rate_list.count = count; 716 subs->rate_list.count = count;
@@ -717,7 +719,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
717 list_for_each_entry(fp, &subs->fmt_list, list) { 719 list_for_each_entry(fp, &subs->fmt_list, list) {
718 int i; 720 int i;
719 for (i = 0; i < fp->nr_rates; i++) 721 for (i = 0; i < fp->nr_rates; i++)
720 subs->rate_list.list[count++] = fp->rate_table[i]; 722 rate_list[count++] = fp->rate_table[i];
721 } 723 }
722 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 724 err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
723 &subs->rate_list); 725 &subs->rate_list);
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 6ffb3713b60c..520ef96d7c75 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -80,7 +80,7 @@ static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
80 cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset; 80 cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
81 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ 81 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
82 snd_printk(KERN_ERR "active frame status %i. " 82 snd_printk(KERN_ERR "active frame status %i. "
83 "Most propably some hardware problem.\n", 83 "Most probably some hardware problem.\n",
84 urb->iso_frame_desc[i].status); 84 urb->iso_frame_desc[i].status);
85 return urb->iso_frame_desc[i].status; 85 return urb->iso_frame_desc[i].status;
86 } 86 }
@@ -300,7 +300,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
300{ 300{
301 snd_printk(KERN_ERR 301 snd_printk(KERN_ERR
302"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" 302"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
303"Most propably some urb of usb-frame %i is still missing.\n" 303"Most probably some urb of usb-frame %i is still missing.\n"
304"Cause could be too long delays in usb-hcd interrupt handling.\n", 304"Cause could be too long delays in usb-hcd interrupt handling.\n",
305 usb_get_current_frame_number(usX2Y->dev), 305 usb_get_current_frame_number(usX2Y->dev),
306 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", 306 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index a51340f6f2db..8e40b6e67e9e 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -74,7 +74,7 @@ static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs)
74 } 74 }
75 for (i = 0; i < nr_of_packs(); i++) { 75 for (i = 0; i < nr_of_packs(); i++) {
76 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ 76 if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
77 snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status); 77 snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status);
78 return urb->iso_frame_desc[i].status; 78 return urb->iso_frame_desc[i].status;
79 } 79 }
80 lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride; 80 lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride;