aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/core/init.c9
-rw-r--r--sound/core/oss/mixer_oss.c34
-rw-r--r--sound/core/pcm.c3
-rw-r--r--sound/core/pcm_lib.c14
-rw-r--r--sound/core/pcm_native.c4
-rw-r--r--sound/drivers/Kconfig19
-rw-r--r--sound/drivers/Makefile2
-rw-r--r--sound/drivers/aloop.c1258
-rw-r--r--sound/drivers/virmidi.c2
-rw-r--r--sound/i2c/other/ak4xxx-adda.c2
-rw-r--r--sound/isa/Kconfig36
-rw-r--r--sound/isa/Makefile4
-rw-r--r--sound/isa/ad1816a/ad1816a.c2
-rw-r--r--sound/isa/azt2320.c2
-rw-r--r--sound/isa/galaxy/Makefile10
-rw-r--r--sound/isa/galaxy/azt1605.c91
-rw-r--r--sound/isa/galaxy/azt2316.c111
-rw-r--r--sound/isa/galaxy/galaxy.c652
-rw-r--r--sound/isa/gus/gusmax.c4
-rw-r--r--sound/isa/sb/sb8.c2
-rw-r--r--sound/isa/sgalaxy.c369
-rw-r--r--sound/oss/Kconfig8
-rw-r--r--sound/oss/Makefile1
-rw-r--r--sound/oss/au1550_ac97.c48
-rw-r--r--sound/oss/dmasound/dmasound_core.c41
-rw-r--r--sound/oss/msnd_pinnacle.c15
-rw-r--r--sound/oss/sh_dac_audio.c325
-rw-r--r--sound/oss/soundcard.c43
-rw-r--r--sound/oss/swarm_cs4297a.c20
-rw-r--r--sound/oss/vwsnd.c30
-rw-r--r--sound/pci/Kconfig17
-rw-r--r--sound/pci/au88x0/au88x0_mixer.c2
-rw-r--r--sound/pci/ca0106/ca0106.h5
-rw-r--r--sound/pci/ca0106/ca0106_main.c136
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c93
-rw-r--r--sound/pci/emu10k1/emumpu401.c2
-rw-r--r--sound/pci/ice1712/delta.c10
-rw-r--r--sound/pci/ice1712/delta.h4
-rw-r--r--sound/pci/ice1712/pontis.c6
-rw-r--r--sound/pci/ice1712/prodigy192.c2
-rw-r--r--sound/pci/oxygen/oxygen.c4
-rw-r--r--sound/pci/oxygen/oxygen.h1
-rw-r--r--sound/pci/oxygen/oxygen_lib.c55
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c5
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c12
-rw-r--r--sound/pci/oxygen/oxygen_regs.h10
-rw-r--r--sound/pci/oxygen/virtuoso.c5
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c8
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c29
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c121
-rw-r--r--sound/pci/rme96.c8
-rw-r--r--sound/pci/rme9652/hdsp.c8
-rw-r--r--sound/ppc/tumbler.c2
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c2
-rw-r--r--sound/soc/s3c24xx/neo1973_gta02_wm8753.c2
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c2
-rw-r--r--sound/synth/emux/emux_hwdep.c3
-rw-r--r--sound/usb/Kconfig2
-rw-r--r--sound/usb/caiaq/audio.c175
-rw-r--r--sound/usb/caiaq/control.c208
-rw-r--r--sound/usb/caiaq/device.c10
-rw-r--r--sound/usb/caiaq/device.h6
-rw-r--r--sound/usb/caiaq/input.c248
-rw-r--r--sound/usb/card.c31
-rw-r--r--sound/usb/endpoint.c2
-rw-r--r--sound/usb/helper.c17
-rw-r--r--sound/usb/midi.c16
-rw-r--r--sound/usb/mixer.c9
-rw-r--r--sound/usb/mixer_quirks.c1
-rw-r--r--sound/usb/pcm.c4
-rw-r--r--sound/usb/proc.c2
-rw-r--r--sound/usb/quirks-table.h184
-rw-r--r--sound/usb/quirks.c2
-rw-r--r--sound/usb/urb.c2
-rw-r--r--sound/usb/usbaudio.h2
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c6
76 files changed, 3535 insertions, 1107 deletions
diff --git a/sound/core/init.c b/sound/core/init.c
index ec4a50ce5656..2de45fbd70fb 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -607,11 +607,16 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr,
607 return -EEXIST; 607 return -EEXIST;
608 } 608 }
609 for (idx = 0; idx < snd_ecards_limit; idx++) { 609 for (idx = 0; idx < snd_ecards_limit; idx++) {
610 if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) 610 if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) {
611 goto __exist; 611 if (card == snd_cards[idx])
612 goto __ok;
613 else
614 goto __exist;
615 }
612 } 616 }
613 strcpy(card->id, buf1); 617 strcpy(card->id, buf1);
614 snd_info_card_id_change(card); 618 snd_info_card_id_change(card);
619__ok:
615 mutex_unlock(&snd_card_mutex); 620 mutex_unlock(&snd_card_mutex);
616 621
617 return count; 622 return count;
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index f50ebf20df96..822dd56993ca 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -77,7 +77,7 @@ static int snd_mixer_oss_release(struct inode *inode, struct file *file)
77 struct snd_mixer_oss_file *fmixer; 77 struct snd_mixer_oss_file *fmixer;
78 78
79 if (file->private_data) { 79 if (file->private_data) {
80 fmixer = (struct snd_mixer_oss_file *) file->private_data; 80 fmixer = file->private_data;
81 module_put(fmixer->card->module); 81 module_put(fmixer->card->module);
82 snd_card_file_remove(fmixer->card, file); 82 snd_card_file_remove(fmixer->card, file);
83 kfree(fmixer); 83 kfree(fmixer);
@@ -368,7 +368,7 @@ static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int
368 368
369static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 369static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
370{ 370{
371 return snd_mixer_oss_ioctl1((struct snd_mixer_oss_file *) file->private_data, cmd, arg); 371 return snd_mixer_oss_ioctl1(file->private_data, cmd, arg);
372} 372}
373 373
374int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg) 374int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg)
@@ -582,7 +582,7 @@ static int snd_mixer_oss_get_volume1(struct snd_mixer_oss_file *fmixer,
582 struct snd_mixer_oss_slot *pslot, 582 struct snd_mixer_oss_slot *pslot,
583 int *left, int *right) 583 int *left, int *right)
584{ 584{
585 struct slot *slot = (struct slot *)pslot->private_data; 585 struct slot *slot = pslot->private_data;
586 586
587 *left = *right = 100; 587 *left = *right = 100;
588 if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { 588 if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
@@ -618,8 +618,10 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer,
618 if (numid == ID_UNKNOWN) 618 if (numid == ID_UNKNOWN)
619 return; 619 return;
620 down_read(&card->controls_rwsem); 620 down_read(&card->controls_rwsem);
621 if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) 621 if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
622 up_read(&card->controls_rwsem);
622 return; 623 return;
624 }
623 uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL); 625 uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
624 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); 626 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
625 if (uinfo == NULL || uctl == NULL) 627 if (uinfo == NULL || uctl == NULL)
@@ -658,7 +660,7 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer,
658 return; 660 return;
659 down_read(&card->controls_rwsem); 661 down_read(&card->controls_rwsem);
660 if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) { 662 if ((kctl = snd_ctl_find_numid(card, numid)) == NULL) {
661 up_read(&fmixer->card->controls_rwsem); 663 up_read(&card->controls_rwsem);
662 return; 664 return;
663 } 665 }
664 uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL); 666 uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
@@ -691,7 +693,7 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer,
691 struct snd_mixer_oss_slot *pslot, 693 struct snd_mixer_oss_slot *pslot,
692 int left, int right) 694 int left, int right)
693{ 695{
694 struct slot *slot = (struct slot *)pslot->private_data; 696 struct slot *slot = pslot->private_data;
695 697
696 if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) { 698 if (slot->present & SNDRV_MIXER_OSS_PRESENT_PVOLUME) {
697 snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); 699 snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
@@ -740,7 +742,7 @@ static int snd_mixer_oss_get_recsrc1_sw(struct snd_mixer_oss_file *fmixer,
740 struct snd_mixer_oss_slot *pslot, 742 struct snd_mixer_oss_slot *pslot,
741 int *active) 743 int *active)
742{ 744{
743 struct slot *slot = (struct slot *)pslot->private_data; 745 struct slot *slot = pslot->private_data;
744 int left, right; 746 int left, right;
745 747
746 left = right = 1; 748 left = right = 1;
@@ -753,7 +755,7 @@ static int snd_mixer_oss_get_recsrc1_route(struct snd_mixer_oss_file *fmixer,
753 struct snd_mixer_oss_slot *pslot, 755 struct snd_mixer_oss_slot *pslot,
754 int *active) 756 int *active)
755{ 757{
756 struct slot *slot = (struct slot *)pslot->private_data; 758 struct slot *slot = pslot->private_data;
757 int left, right; 759 int left, right;
758 760
759 left = right = 1; 761 left = right = 1;
@@ -766,7 +768,7 @@ static int snd_mixer_oss_put_recsrc1_sw(struct snd_mixer_oss_file *fmixer,
766 struct snd_mixer_oss_slot *pslot, 768 struct snd_mixer_oss_slot *pslot,
767 int active) 769 int active)
768{ 770{
769 struct slot *slot = (struct slot *)pslot->private_data; 771 struct slot *slot = pslot->private_data;
770 772
771 snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0); 773 snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], active, active, 0);
772 return 0; 774 return 0;
@@ -776,7 +778,7 @@ static int snd_mixer_oss_put_recsrc1_route(struct snd_mixer_oss_file *fmixer,
776 struct snd_mixer_oss_slot *pslot, 778 struct snd_mixer_oss_slot *pslot,
777 int active) 779 int active)
778{ 780{
779 struct slot *slot = (struct slot *)pslot->private_data; 781 struct slot *slot = pslot->private_data;
780 782
781 snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1); 783 snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], active, active, 1);
782 return 0; 784 return 0;
@@ -797,7 +799,7 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
797 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); 799 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
798 if (uinfo == NULL || uctl == NULL) { 800 if (uinfo == NULL || uctl == NULL) {
799 err = -ENOMEM; 801 err = -ENOMEM;
800 goto __unlock; 802 goto __free_only;
801 } 803 }
802 down_read(&card->controls_rwsem); 804 down_read(&card->controls_rwsem);
803 kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); 805 kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
@@ -813,7 +815,7 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
813 if (!(mixer->mask_recsrc & (1 << idx))) 815 if (!(mixer->mask_recsrc & (1 << idx)))
814 continue; 816 continue;
815 pslot = &mixer->slots[idx]; 817 pslot = &mixer->slots[idx];
816 slot = (struct slot *)pslot->private_data; 818 slot = pslot->private_data;
817 if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE) 819 if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)
818 continue; 820 continue;
819 if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE)) 821 if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE))
@@ -826,6 +828,7 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
826 err = 0; 828 err = 0;
827 __unlock: 829 __unlock:
828 up_read(&card->controls_rwsem); 830 up_read(&card->controls_rwsem);
831 __free_only:
829 kfree(uctl); 832 kfree(uctl);
830 kfree(uinfo); 833 kfree(uinfo);
831 return err; 834 return err;
@@ -847,7 +850,7 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
847 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); 850 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
848 if (uinfo == NULL || uctl == NULL) { 851 if (uinfo == NULL || uctl == NULL) {
849 err = -ENOMEM; 852 err = -ENOMEM;
850 goto __unlock; 853 goto __free_only;
851 } 854 }
852 down_read(&card->controls_rwsem); 855 down_read(&card->controls_rwsem);
853 kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); 856 kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
@@ -861,7 +864,7 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
861 if (!(mixer->mask_recsrc & (1 << idx))) 864 if (!(mixer->mask_recsrc & (1 << idx)))
862 continue; 865 continue;
863 pslot = &mixer->slots[idx]; 866 pslot = &mixer->slots[idx];
864 slot = (struct slot *)pslot->private_data; 867 slot = pslot->private_data;
865 if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE) 868 if (slot->signature != SNDRV_MIXER_OSS_SIGNATURE)
866 continue; 869 continue;
867 if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE)) 870 if (!(slot->present & SNDRV_MIXER_OSS_PRESENT_CAPTURE))
@@ -880,6 +883,7 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
880 err = 0; 883 err = 0;
881 __unlock: 884 __unlock:
882 up_read(&card->controls_rwsem); 885 up_read(&card->controls_rwsem);
886 __free_only:
883 kfree(uctl); 887 kfree(uctl);
884 kfree(uinfo); 888 kfree(uinfo);
885 return err; 889 return err;
@@ -925,7 +929,7 @@ static int snd_mixer_oss_build_test(struct snd_mixer_oss *mixer, struct slot *sl
925 929
926static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn) 930static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn)
927{ 931{
928 struct slot *p = (struct slot *)chn->private_data; 932 struct slot *p = chn->private_data;
929 if (p) { 933 if (p) {
930 if (p->allocated && p->assigned) { 934 if (p->allocated && p->assigned) {
931 kfree(p->assigned->name); 935 kfree(p->assigned->name);
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index ac242a377aea..6b4b1287b314 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -364,8 +364,7 @@ static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,
364static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry, 364static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry,
365 struct snd_info_buffer *buffer) 365 struct snd_info_buffer *buffer)
366{ 366{
367 snd_pcm_proc_info_read((struct snd_pcm_substream *)entry->private_data, 367 snd_pcm_proc_info_read(entry->private_data, buffer);
368 buffer);
369} 368}
370 369
371static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, 370static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index e23e0e7ab26f..a1707cca9c66 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -334,11 +334,15 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
334 /* delta = "expected next hw_ptr" for in_interrupt != 0 */ 334 /* delta = "expected next hw_ptr" for in_interrupt != 0 */
335 delta = runtime->hw_ptr_interrupt + runtime->period_size; 335 delta = runtime->hw_ptr_interrupt + runtime->period_size;
336 if (delta > new_hw_ptr) { 336 if (delta > new_hw_ptr) {
337 hw_base += runtime->buffer_size; 337 /* check for double acknowledged interrupts */
338 if (hw_base >= runtime->boundary) 338 hdelta = jiffies - runtime->hw_ptr_jiffies;
339 hw_base = 0; 339 if (hdelta > runtime->hw_ptr_buffer_jiffies/2) {
340 new_hw_ptr = hw_base + pos; 340 hw_base += runtime->buffer_size;
341 goto __delta; 341 if (hw_base >= runtime->boundary)
342 hw_base = 0;
343 new_hw_ptr = hw_base + pos;
344 goto __delta;
345 }
342 } 346 }
343 } 347 }
344 /* new_hw_ptr might be lower than old_hw_ptr in case when */ 348 /* new_hw_ptr might be lower than old_hw_ptr in case when */
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index d4eb2ef80784..8bc7cb3db330 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -142,7 +142,7 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream,
142 142
143#ifdef RULES_DEBUG 143#ifdef RULES_DEBUG
144#define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v 144#define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v
145char *snd_pcm_hw_param_names[] = { 145static const char * const snd_pcm_hw_param_names[] = {
146 HW_PARAM(ACCESS), 146 HW_PARAM(ACCESS),
147 HW_PARAM(FORMAT), 147 HW_PARAM(FORMAT),
148 HW_PARAM(SUBFORMAT), 148 HW_PARAM(SUBFORMAT),
@@ -864,6 +864,8 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
864 struct snd_pcm_runtime *runtime = substream->runtime; 864 struct snd_pcm_runtime *runtime = substream->runtime;
865 snd_pcm_trigger_tstamp(substream); 865 snd_pcm_trigger_tstamp(substream);
866 runtime->hw_ptr_jiffies = jiffies; 866 runtime->hw_ptr_jiffies = jiffies;
867 runtime->hw_ptr_buffer_jiffies = (runtime->buffer_size * HZ) /
868 runtime->rate;
867 runtime->status->state = state; 869 runtime->status->state = state;
868 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && 870 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
869 runtime->silence_size > 0) 871 runtime->silence_size > 0)
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 480c38623da8..c8961165277c 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -74,6 +74,25 @@ config SND_DUMMY
74 To compile this driver as a module, choose M here: the module 74 To compile this driver as a module, choose M here: the module
75 will be called snd-dummy. 75 will be called snd-dummy.
76 76
77config SND_ALOOP
78 tristate "Generic loopback driver (PCM)"
79 select SND_PCM
80 help
81 Say 'Y' or 'M' to include support for the PCM loopback device.
82 This module returns played samples back to the user space using
83 the standard ALSA PCM device. The devices are routed 0->1 and
84 1->0, where first number is the playback PCM device and second
85 number is the capture device. Module creates two PCM devices and
86 configured number of substreams (see the pcm_substreams module
87 parameter).
88
89 The looback device allow time sychronization with an external
90 timing source using the time shift universal control (+-20%
91 of system time).
92
93 To compile this driver as a module, choose M here: the module
94 will be called snd-aloop.
95
77config SND_VIRMIDI 96config SND_VIRMIDI
78 tristate "Virtual MIDI soundcard" 97 tristate "Virtual MIDI soundcard"
79 depends on SND_SEQUENCER 98 depends on SND_SEQUENCER
diff --git a/sound/drivers/Makefile b/sound/drivers/Makefile
index d4a07f9ff2c7..1a8440c8b138 100644
--- a/sound/drivers/Makefile
+++ b/sound/drivers/Makefile
@@ -4,6 +4,7 @@
4# 4#
5 5
6snd-dummy-objs := dummy.o 6snd-dummy-objs := dummy.o
7snd-aloop-objs := aloop.o
7snd-mtpav-objs := mtpav.o 8snd-mtpav-objs := mtpav.o
8snd-mts64-objs := mts64.o 9snd-mts64-objs := mts64.o
9snd-portman2x4-objs := portman2x4.o 10snd-portman2x4-objs := portman2x4.o
@@ -13,6 +14,7 @@ snd-ml403-ac97cr-objs := ml403-ac97cr.o pcm-indirect2.o
13 14
14# Toplevel Module Dependency 15# Toplevel Module Dependency
15obj-$(CONFIG_SND_DUMMY) += snd-dummy.o 16obj-$(CONFIG_SND_DUMMY) += snd-dummy.o
17obj-$(CONFIG_SND_ALOOP) += snd-aloop.o
16obj-$(CONFIG_SND_VIRMIDI) += snd-virmidi.o 18obj-$(CONFIG_SND_VIRMIDI) += snd-virmidi.o
17obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o 19obj-$(CONFIG_SND_SERIAL_U16550) += snd-serial-u16550.o
18obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o 20obj-$(CONFIG_SND_MTPAV) += snd-mtpav.o
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
new file mode 100644
index 000000000000..12b44b0b6777
--- /dev/null
+++ b/sound/drivers/aloop.c
@@ -0,0 +1,1258 @@
1/*
2 * Loopback soundcard
3 *
4 * Original code:
5 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
6 *
7 * More accurate positioning and full-duplex support:
8 * Copyright (c) Ahmet Ä°nan <ainan at mathematik.uni-freiburg.de>
9 *
10 * Major (almost complete) rewrite:
11 * Copyright (c) by Takashi Iwai <tiwai@suse.de>
12 *
13 * A next major update in 2010 (separate timers for playback and capture):
14 * Copyright (c) Jaroslav Kysela <perex@perex.cz>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/jiffies.h>
34#include <linux/slab.h>
35#include <linux/time.h>
36#include <linux/wait.h>
37#include <linux/moduleparam.h>
38#include <linux/platform_device.h>
39#include <sound/core.h>
40#include <sound/control.h>
41#include <sound/pcm.h>
42#include <sound/info.h>
43#include <sound/initval.h>
44
45MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
46MODULE_DESCRIPTION("A loopback soundcard");
47MODULE_LICENSE("GPL");
48MODULE_SUPPORTED_DEVICE("{{ALSA,Loopback soundcard}}");
49
50#define MAX_PCM_SUBSTREAMS 8
51
52static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
53static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
54static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
55static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
56static int pcm_notify[SNDRV_CARDS];
57
58module_param_array(index, int, NULL, 0444);
59MODULE_PARM_DESC(index, "Index value for loopback soundcard.");
60module_param_array(id, charp, NULL, 0444);
61MODULE_PARM_DESC(id, "ID string for loopback soundcard.");
62module_param_array(enable, bool, NULL, 0444);
63MODULE_PARM_DESC(enable, "Enable this loopback soundcard.");
64module_param_array(pcm_substreams, int, NULL, 0444);
65MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver.");
66module_param_array(pcm_notify, int, NULL, 0444);
67MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes.");
68
69#define NO_PITCH 100000
70
71struct loopback_pcm;
72
73struct loopback_cable {
74 spinlock_t lock;
75 struct loopback_pcm *streams[2];
76 struct snd_pcm_hardware hw;
77 /* flags */
78 unsigned int valid;
79 unsigned int running;
80 unsigned int pause;
81};
82
83struct loopback_setup {
84 unsigned int notify: 1;
85 unsigned int rate_shift;
86 unsigned int format;
87 unsigned int rate;
88 unsigned int channels;
89 struct snd_ctl_elem_id active_id;
90 struct snd_ctl_elem_id format_id;
91 struct snd_ctl_elem_id rate_id;
92 struct snd_ctl_elem_id channels_id;
93};
94
95struct loopback {
96 struct snd_card *card;
97 struct mutex cable_lock;
98 struct loopback_cable *cables[MAX_PCM_SUBSTREAMS][2];
99 struct snd_pcm *pcm[2];
100 struct loopback_setup setup[MAX_PCM_SUBSTREAMS][2];
101};
102
103struct loopback_pcm {
104 struct loopback *loopback;
105 struct snd_pcm_substream *substream;
106 struct loopback_cable *cable;
107 unsigned int pcm_buffer_size;
108 unsigned int buf_pos; /* position in buffer */
109 unsigned int silent_size;
110 /* PCM parameters */
111 unsigned int pcm_period_size;
112 unsigned int pcm_bps; /* bytes per second */
113 unsigned int pcm_salign; /* bytes per sample * channels */
114 unsigned int pcm_rate_shift; /* rate shift value */
115 /* flags */
116 unsigned int period_update_pending :1;
117 /* timer stuff */
118 unsigned int irq_pos; /* fractional IRQ position */
119 unsigned int period_size_frac;
120 unsigned long last_jiffies;
121 struct timer_list timer;
122};
123
124static struct platform_device *devices[SNDRV_CARDS];
125
126static inline unsigned int byte_pos(struct loopback_pcm *dpcm, unsigned int x)
127{
128 if (dpcm->pcm_rate_shift == NO_PITCH) {
129 x /= HZ;
130 } else {
131 x = div_u64(NO_PITCH * (unsigned long long)x,
132 HZ * (unsigned long long)dpcm->pcm_rate_shift);
133 }
134 return x - (x % dpcm->pcm_salign);
135}
136
137static inline unsigned int frac_pos(struct loopback_pcm *dpcm, unsigned int x)
138{
139 if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */
140 return x * HZ;
141 } else {
142 x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ,
143 NO_PITCH);
144 }
145 return x;
146}
147
148static inline struct loopback_setup *get_setup(struct loopback_pcm *dpcm)
149{
150 int device = dpcm->substream->pstr->pcm->device;
151
152 if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
153 device ^= 1;
154 return &dpcm->loopback->setup[dpcm->substream->number][device];
155}
156
157static inline unsigned int get_notify(struct loopback_pcm *dpcm)
158{
159 return get_setup(dpcm)->notify;
160}
161
162static inline unsigned int get_rate_shift(struct loopback_pcm *dpcm)
163{
164 return get_setup(dpcm)->rate_shift;
165}
166
167static void loopback_timer_start(struct loopback_pcm *dpcm)
168{
169 unsigned long tick;
170 unsigned int rate_shift = get_rate_shift(dpcm);
171
172 if (rate_shift != dpcm->pcm_rate_shift) {
173 dpcm->pcm_rate_shift = rate_shift;
174 dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
175 }
176 if (dpcm->period_size_frac <= dpcm->irq_pos) {
177 dpcm->irq_pos %= dpcm->period_size_frac;
178 dpcm->period_update_pending = 1;
179 }
180 tick = dpcm->period_size_frac - dpcm->irq_pos;
181 tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
182 dpcm->timer.expires = jiffies + tick;
183 add_timer(&dpcm->timer);
184}
185
186static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
187{
188 del_timer(&dpcm->timer);
189 dpcm->timer.expires = 0;
190}
191
192#define CABLE_VALID_PLAYBACK (1 << SNDRV_PCM_STREAM_PLAYBACK)
193#define CABLE_VALID_CAPTURE (1 << SNDRV_PCM_STREAM_CAPTURE)
194#define CABLE_VALID_BOTH (CABLE_VALID_PLAYBACK|CABLE_VALID_CAPTURE)
195
196static int loopback_check_format(struct loopback_cable *cable, int stream)
197{
198 struct snd_pcm_runtime *runtime, *cruntime;
199 struct loopback_setup *setup;
200 struct snd_card *card;
201 int check;
202
203 if (cable->valid != CABLE_VALID_BOTH) {
204 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
205 goto __notify;
206 return 0;
207 }
208 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
209 substream->runtime;
210 cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
211 substream->runtime;
212 check = runtime->format != cruntime->format ||
213 runtime->rate != cruntime->rate ||
214 runtime->channels != cruntime->channels;
215 if (!check)
216 return 0;
217 if (stream == SNDRV_PCM_STREAM_CAPTURE) {
218 return -EIO;
219 } else {
220 snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]->
221 substream, SNDRV_PCM_STATE_DRAINING);
222 __notify:
223 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->
224 substream->runtime;
225 setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]);
226 card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card;
227 if (setup->format != runtime->format) {
228 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
229 &setup->format_id);
230 setup->format = runtime->format;
231 }
232 if (setup->rate != runtime->rate) {
233 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
234 &setup->rate_id);
235 setup->rate = runtime->rate;
236 }
237 if (setup->channels != runtime->channels) {
238 snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
239 &setup->channels_id);
240 setup->channels = runtime->channels;
241 }
242 }
243 return 0;
244}
245
246static void loopback_active_notify(struct loopback_pcm *dpcm)
247{
248 snd_ctl_notify(dpcm->loopback->card,
249 SNDRV_CTL_EVENT_MASK_VALUE,
250 &get_setup(dpcm)->active_id);
251}
252
253static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
254{
255 struct snd_pcm_runtime *runtime = substream->runtime;
256 struct loopback_pcm *dpcm = runtime->private_data;
257 struct loopback_cable *cable = dpcm->cable;
258 int err, stream = 1 << substream->stream;
259
260 switch (cmd) {
261 case SNDRV_PCM_TRIGGER_START:
262 err = loopback_check_format(cable, substream->stream);
263 if (err < 0)
264 return err;
265 dpcm->last_jiffies = jiffies;
266 dpcm->pcm_rate_shift = 0;
267 spin_lock(&cable->lock);
268 cable->running |= stream;
269 cable->pause &= ~stream;
270 spin_unlock(&cable->lock);
271 loopback_timer_start(dpcm);
272 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
273 loopback_active_notify(dpcm);
274 break;
275 case SNDRV_PCM_TRIGGER_STOP:
276 spin_lock(&cable->lock);
277 cable->running &= ~stream;
278 cable->pause &= ~stream;
279 spin_unlock(&cable->lock);
280 loopback_timer_stop(dpcm);
281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
282 loopback_active_notify(dpcm);
283 break;
284 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
285 spin_lock(&cable->lock);
286 cable->pause |= stream;
287 spin_unlock(&cable->lock);
288 loopback_timer_stop(dpcm);
289 break;
290 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
291 spin_lock(&cable->lock);
292 dpcm->last_jiffies = jiffies;
293 cable->pause &= ~stream;
294 spin_unlock(&cable->lock);
295 loopback_timer_start(dpcm);
296 break;
297 default:
298 return -EINVAL;
299 }
300 return 0;
301}
302
303static void params_change_substream(struct loopback_pcm *dpcm,
304 struct snd_pcm_runtime *runtime)
305{
306 struct snd_pcm_runtime *dst_runtime;
307
308 if (dpcm == NULL || dpcm->substream == NULL)
309 return;
310 dst_runtime = dpcm->substream->runtime;
311 if (dst_runtime == NULL)
312 return;
313 dst_runtime->hw = dpcm->cable->hw;
314}
315
316static void params_change(struct snd_pcm_substream *substream)
317{
318 struct snd_pcm_runtime *runtime = substream->runtime;
319 struct loopback_pcm *dpcm = runtime->private_data;
320 struct loopback_cable *cable = dpcm->cable;
321
322 cable->hw.formats = (1ULL << runtime->format);
323 cable->hw.rate_min = runtime->rate;
324 cable->hw.rate_max = runtime->rate;
325 cable->hw.channels_min = runtime->channels;
326 cable->hw.channels_max = runtime->channels;
327 params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
328 runtime);
329 params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
330 runtime);
331}
332
333static int loopback_prepare(struct snd_pcm_substream *substream)
334{
335 struct snd_pcm_runtime *runtime = substream->runtime;
336 struct loopback_pcm *dpcm = runtime->private_data;
337 struct loopback_cable *cable = dpcm->cable;
338 int bps, salign;
339
340 salign = (snd_pcm_format_width(runtime->format) *
341 runtime->channels) / 8;
342 bps = salign * runtime->rate;
343 if (bps <= 0 || salign <= 0)
344 return -EINVAL;
345
346 dpcm->buf_pos = 0;
347 dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
348 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
349 /* clear capture buffer */
350 dpcm->silent_size = dpcm->pcm_buffer_size;
351 snd_pcm_format_set_silence(runtime->format, runtime->dma_area,
352 runtime->buffer_size * runtime->channels);
353 }
354
355 dpcm->irq_pos = 0;
356 dpcm->period_update_pending = 0;
357 dpcm->pcm_bps = bps;
358 dpcm->pcm_salign = salign;
359 dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size);
360
361 mutex_lock(&dpcm->loopback->cable_lock);
362 if (!(cable->valid & ~(1 << substream->stream)) ||
363 (get_setup(dpcm)->notify &&
364 substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
365 params_change(substream);
366 cable->valid |= 1 << substream->stream;
367 mutex_unlock(&dpcm->loopback->cable_lock);
368
369 return 0;
370}
371
372static void clear_capture_buf(struct loopback_pcm *dpcm, unsigned int bytes)
373{
374 struct snd_pcm_runtime *runtime = dpcm->substream->runtime;
375 char *dst = runtime->dma_area;
376 unsigned int dst_off = dpcm->buf_pos;
377
378 if (dpcm->silent_size >= dpcm->pcm_buffer_size)
379 return;
380 if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size)
381 bytes = dpcm->pcm_buffer_size - dpcm->silent_size;
382
383 for (;;) {
384 unsigned int size = bytes;
385 if (dst_off + size > dpcm->pcm_buffer_size)
386 size = dpcm->pcm_buffer_size - dst_off;
387 snd_pcm_format_set_silence(runtime->format, dst + dst_off,
388 bytes_to_frames(runtime, size) *
389 runtime->channels);
390 dpcm->silent_size += size;
391 bytes -= size;
392 if (!bytes)
393 break;
394 dst_off = 0;
395 }
396}
397
398static void copy_play_buf(struct loopback_pcm *play,
399 struct loopback_pcm *capt,
400 unsigned int bytes)
401{
402 struct snd_pcm_runtime *runtime = play->substream->runtime;
403 char *src = runtime->dma_area;
404 char *dst = capt->substream->runtime->dma_area;
405 unsigned int src_off = play->buf_pos;
406 unsigned int dst_off = capt->buf_pos;
407 unsigned int clear_bytes = 0;
408
409 /* check if playback is draining, trim the capture copy size
410 * when our pointer is at the end of playback ring buffer */
411 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
412 snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) {
413 snd_pcm_uframes_t appl_ptr, appl_ptr1, diff;
414 appl_ptr = appl_ptr1 = runtime->control->appl_ptr;
415 appl_ptr1 -= appl_ptr1 % runtime->buffer_size;
416 appl_ptr1 += play->buf_pos / play->pcm_salign;
417 if (appl_ptr < appl_ptr1)
418 appl_ptr1 -= runtime->buffer_size;
419 diff = (appl_ptr - appl_ptr1) * play->pcm_salign;
420 if (diff < bytes) {
421 clear_bytes = bytes - diff;
422 bytes = diff;
423 }
424 }
425
426 for (;;) {
427 unsigned int size = bytes;
428 if (src_off + size > play->pcm_buffer_size)
429 size = play->pcm_buffer_size - src_off;
430 if (dst_off + size > capt->pcm_buffer_size)
431 size = capt->pcm_buffer_size - dst_off;
432 memcpy(dst + dst_off, src + src_off, size);
433 capt->silent_size = 0;
434 bytes -= size;
435 if (!bytes)
436 break;
437 src_off = (src_off + size) % play->pcm_buffer_size;
438 dst_off = (dst_off + size) % capt->pcm_buffer_size;
439 }
440
441 if (clear_bytes > 0) {
442 clear_capture_buf(capt, clear_bytes);
443 capt->silent_size = 0;
444 }
445}
446
447#define BYTEPOS_UPDATE_POSONLY 0
448#define BYTEPOS_UPDATE_CLEAR 1
449#define BYTEPOS_UPDATE_COPY 2
450
451static void loopback_bytepos_update(struct loopback_pcm *dpcm,
452 unsigned int delta,
453 unsigned int cmd)
454{
455 unsigned int count;
456 unsigned long last_pos;
457
458 last_pos = byte_pos(dpcm, dpcm->irq_pos);
459 dpcm->irq_pos += delta * dpcm->pcm_bps;
460 count = byte_pos(dpcm, dpcm->irq_pos) - last_pos;
461 if (!count)
462 return;
463 if (cmd == BYTEPOS_UPDATE_CLEAR)
464 clear_capture_buf(dpcm, count);
465 else if (cmd == BYTEPOS_UPDATE_COPY)
466 copy_play_buf(dpcm->cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
467 dpcm->cable->streams[SNDRV_PCM_STREAM_CAPTURE],
468 count);
469 dpcm->buf_pos += count;
470 dpcm->buf_pos %= dpcm->pcm_buffer_size;
471 if (dpcm->irq_pos >= dpcm->period_size_frac) {
472 dpcm->irq_pos %= dpcm->period_size_frac;
473 dpcm->period_update_pending = 1;
474 }
475}
476
477static unsigned int loopback_pos_update(struct loopback_cable *cable)
478{
479 struct loopback_pcm *dpcm_play =
480 cable->streams[SNDRV_PCM_STREAM_PLAYBACK];
481 struct loopback_pcm *dpcm_capt =
482 cable->streams[SNDRV_PCM_STREAM_CAPTURE];
483 unsigned long delta_play = 0, delta_capt = 0;
484 unsigned int running;
485
486 spin_lock(&cable->lock);
487 running = cable->running ^ cable->pause;
488 if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
489 delta_play = jiffies - dpcm_play->last_jiffies;
490 dpcm_play->last_jiffies += delta_play;
491 }
492
493 if (running & (1 << SNDRV_PCM_STREAM_CAPTURE)) {
494 delta_capt = jiffies - dpcm_capt->last_jiffies;
495 dpcm_capt->last_jiffies += delta_capt;
496 }
497
498 if (delta_play == 0 && delta_capt == 0) {
499 spin_unlock(&cable->lock);
500 return running;
501 }
502
503 if (delta_play > delta_capt) {
504 loopback_bytepos_update(dpcm_play, delta_play - delta_capt,
505 BYTEPOS_UPDATE_POSONLY);
506 delta_play = delta_capt;
507 } else if (delta_play < delta_capt) {
508 loopback_bytepos_update(dpcm_capt, delta_capt - delta_play,
509 BYTEPOS_UPDATE_CLEAR);
510 delta_capt = delta_play;
511 }
512
513 if (delta_play == 0 && delta_capt == 0) {
514 spin_unlock(&cable->lock);
515 return running;
516 }
517 /* note delta_capt == delta_play at this moment */
518 loopback_bytepos_update(dpcm_capt, delta_capt, BYTEPOS_UPDATE_COPY);
519 loopback_bytepos_update(dpcm_play, delta_play, BYTEPOS_UPDATE_POSONLY);
520 spin_unlock(&cable->lock);
521 return running;
522}
523
524static void loopback_timer_function(unsigned long data)
525{
526 struct loopback_pcm *dpcm = (struct loopback_pcm *)data;
527 unsigned int running;
528
529 running = loopback_pos_update(dpcm->cable);
530 if (running & (1 << dpcm->substream->stream)) {
531 loopback_timer_start(dpcm);
532 if (dpcm->period_update_pending) {
533 dpcm->period_update_pending = 0;
534 snd_pcm_period_elapsed(dpcm->substream);
535 }
536 }
537}
538
539static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
540{
541 struct snd_pcm_runtime *runtime = substream->runtime;
542 struct loopback_pcm *dpcm = runtime->private_data;
543
544 loopback_pos_update(dpcm->cable);
545 return bytes_to_frames(runtime, dpcm->buf_pos);
546}
547
548static struct snd_pcm_hardware loopback_pcm_hardware =
549{
550 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
551 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
552 .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
553 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |
554 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE),
555 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
556 .rate_min = 8000,
557 .rate_max = 192000,
558 .channels_min = 1,
559 .channels_max = 32,
560 .buffer_bytes_max = 2 * 1024 * 1024,
561 .period_bytes_min = 64,
562 /* note check overflow in frac_pos() using pcm_rate_shift before
563 changing period_bytes_max value */
564 .period_bytes_max = 1024 * 1024,
565 .periods_min = 1,
566 .periods_max = 1024,
567 .fifo_size = 0,
568};
569
570static void loopback_runtime_free(struct snd_pcm_runtime *runtime)
571{
572 struct loopback_pcm *dpcm = runtime->private_data;
573 kfree(dpcm);
574}
575
576static int loopback_hw_params(struct snd_pcm_substream *substream,
577 struct snd_pcm_hw_params *params)
578{
579 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
580}
581
582static int loopback_hw_free(struct snd_pcm_substream *substream)
583{
584 struct snd_pcm_runtime *runtime = substream->runtime;
585 struct loopback_pcm *dpcm = runtime->private_data;
586 struct loopback_cable *cable = dpcm->cable;
587
588 mutex_lock(&dpcm->loopback->cable_lock);
589 cable->valid &= ~(1 << substream->stream);
590 mutex_unlock(&dpcm->loopback->cable_lock);
591 return snd_pcm_lib_free_pages(substream);
592}
593
594static unsigned int get_cable_index(struct snd_pcm_substream *substream)
595{
596 if (!substream->pcm->device)
597 return substream->stream;
598 else
599 return !substream->stream;
600}
601
602static int rule_format(struct snd_pcm_hw_params *params,
603 struct snd_pcm_hw_rule *rule)
604{
605
606 struct snd_pcm_hardware *hw = rule->private;
607 struct snd_mask *maskp = hw_param_mask(params, rule->var);
608
609 maskp->bits[0] &= (u_int32_t)hw->formats;
610 maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
611 memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
612 if (! maskp->bits[0] && ! maskp->bits[1])
613 return -EINVAL;
614 return 0;
615}
616
617static int rule_rate(struct snd_pcm_hw_params *params,
618 struct snd_pcm_hw_rule *rule)
619{
620 struct snd_pcm_hardware *hw = rule->private;
621 struct snd_interval t;
622
623 t.min = hw->rate_min;
624 t.max = hw->rate_max;
625 t.openmin = t.openmax = 0;
626 t.integer = 0;
627 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
628}
629
630static int rule_channels(struct snd_pcm_hw_params *params,
631 struct snd_pcm_hw_rule *rule)
632{
633 struct snd_pcm_hardware *hw = rule->private;
634 struct snd_interval t;
635
636 t.min = hw->channels_min;
637 t.max = hw->channels_max;
638 t.openmin = t.openmax = 0;
639 t.integer = 0;
640 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
641}
642
643static int loopback_open(struct snd_pcm_substream *substream)
644{
645 struct snd_pcm_runtime *runtime = substream->runtime;
646 struct loopback *loopback = substream->private_data;
647 struct loopback_pcm *dpcm;
648 struct loopback_cable *cable;
649 int err = 0;
650 int dev = get_cable_index(substream);
651
652 mutex_lock(&loopback->cable_lock);
653 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
654 if (!dpcm) {
655 err = -ENOMEM;
656 goto unlock;
657 }
658 dpcm->loopback = loopback;
659 dpcm->substream = substream;
660 setup_timer(&dpcm->timer, loopback_timer_function,
661 (unsigned long)dpcm);
662
663 cable = loopback->cables[substream->number][dev];
664 if (!cable) {
665 cable = kzalloc(sizeof(*cable), GFP_KERNEL);
666 if (!cable) {
667 kfree(dpcm);
668 err = -ENOMEM;
669 goto unlock;
670 }
671 spin_lock_init(&cable->lock);
672 cable->hw = loopback_pcm_hardware;
673 loopback->cables[substream->number][dev] = cable;
674 }
675 dpcm->cable = cable;
676 cable->streams[substream->stream] = dpcm;
677
678 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
679
680 /* use dynamic rules based on actual runtime->hw values */
681 /* note that the default rules created in the PCM midlevel code */
682 /* are cached -> they do not reflect the actual state */
683 err = snd_pcm_hw_rule_add(runtime, 0,
684 SNDRV_PCM_HW_PARAM_FORMAT,
685 rule_format, &runtime->hw,
686 SNDRV_PCM_HW_PARAM_FORMAT, -1);
687 if (err < 0)
688 goto unlock;
689 err = snd_pcm_hw_rule_add(runtime, 0,
690 SNDRV_PCM_HW_PARAM_RATE,
691 rule_rate, &runtime->hw,
692 SNDRV_PCM_HW_PARAM_RATE, -1);
693 if (err < 0)
694 goto unlock;
695 err = snd_pcm_hw_rule_add(runtime, 0,
696 SNDRV_PCM_HW_PARAM_CHANNELS,
697 rule_channels, &runtime->hw,
698 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
699 if (err < 0)
700 goto unlock;
701
702 runtime->private_data = dpcm;
703 runtime->private_free = loopback_runtime_free;
704 if (get_notify(dpcm))
705 runtime->hw = loopback_pcm_hardware;
706 else
707 runtime->hw = cable->hw;
708 unlock:
709 mutex_unlock(&loopback->cable_lock);
710 return err;
711}
712
713static int loopback_close(struct snd_pcm_substream *substream)
714{
715 struct loopback *loopback = substream->private_data;
716 struct loopback_pcm *dpcm = substream->runtime->private_data;
717 struct loopback_cable *cable;
718 int dev = get_cable_index(substream);
719
720 loopback_timer_stop(dpcm);
721 mutex_lock(&loopback->cable_lock);
722 cable = loopback->cables[substream->number][dev];
723 if (cable->streams[!substream->stream]) {
724 /* other stream is still alive */
725 cable->streams[substream->stream] = NULL;
726 } else {
727 /* free the cable */
728 loopback->cables[substream->number][dev] = NULL;
729 kfree(cable);
730 }
731 mutex_unlock(&loopback->cable_lock);
732 return 0;
733}
734
735static struct snd_pcm_ops loopback_playback_ops = {
736 .open = loopback_open,
737 .close = loopback_close,
738 .ioctl = snd_pcm_lib_ioctl,
739 .hw_params = loopback_hw_params,
740 .hw_free = loopback_hw_free,
741 .prepare = loopback_prepare,
742 .trigger = loopback_trigger,
743 .pointer = loopback_pointer,
744};
745
746static struct snd_pcm_ops loopback_capture_ops = {
747 .open = loopback_open,
748 .close = loopback_close,
749 .ioctl = snd_pcm_lib_ioctl,
750 .hw_params = loopback_hw_params,
751 .hw_free = loopback_hw_free,
752 .prepare = loopback_prepare,
753 .trigger = loopback_trigger,
754 .pointer = loopback_pointer,
755};
756
757static int __devinit loopback_pcm_new(struct loopback *loopback,
758 int device, int substreams)
759{
760 struct snd_pcm *pcm;
761 int err;
762
763 err = snd_pcm_new(loopback->card, "Loopback PCM", device,
764 substreams, substreams, &pcm);
765 if (err < 0)
766 return err;
767 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &loopback_playback_ops);
768 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &loopback_capture_ops);
769
770 pcm->private_data = loopback;
771 pcm->info_flags = 0;
772 strcpy(pcm->name, "Loopback PCM");
773
774 loopback->pcm[device] = pcm;
775
776 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
777 snd_dma_continuous_data(GFP_KERNEL),
778 0, 2 * 1024 * 1024);
779 return 0;
780}
781
782static int loopback_rate_shift_info(struct snd_kcontrol *kcontrol,
783 struct snd_ctl_elem_info *uinfo)
784{
785 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
786 uinfo->count = 1;
787 uinfo->value.integer.min = 80000;
788 uinfo->value.integer.max = 120000;
789 uinfo->value.integer.step = 1;
790 return 0;
791}
792
793static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
795{
796 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
797
798 ucontrol->value.integer.value[0] =
799 loopback->setup[kcontrol->id.subdevice]
800 [kcontrol->id.device].rate_shift;
801 return 0;
802}
803
804static int loopback_rate_shift_put(struct snd_kcontrol *kcontrol,
805 struct snd_ctl_elem_value *ucontrol)
806{
807 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
808 unsigned int val;
809 int change = 0;
810
811 val = ucontrol->value.integer.value[0];
812 if (val < 80000)
813 val = 80000;
814 if (val > 120000)
815 val = 120000;
816 mutex_lock(&loopback->cable_lock);
817 if (val != loopback->setup[kcontrol->id.subdevice]
818 [kcontrol->id.device].rate_shift) {
819 loopback->setup[kcontrol->id.subdevice]
820 [kcontrol->id.device].rate_shift = val;
821 change = 1;
822 }
823 mutex_unlock(&loopback->cable_lock);
824 return change;
825}
826
827static int loopback_notify_get(struct snd_kcontrol *kcontrol,
828 struct snd_ctl_elem_value *ucontrol)
829{
830 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
831
832 ucontrol->value.integer.value[0] =
833 loopback->setup[kcontrol->id.subdevice]
834 [kcontrol->id.device].notify;
835 return 0;
836}
837
838static int loopback_notify_put(struct snd_kcontrol *kcontrol,
839 struct snd_ctl_elem_value *ucontrol)
840{
841 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
842 unsigned int val;
843 int change = 0;
844
845 val = ucontrol->value.integer.value[0] ? 1 : 0;
846 if (val != loopback->setup[kcontrol->id.subdevice]
847 [kcontrol->id.device].notify) {
848 loopback->setup[kcontrol->id.subdevice]
849 [kcontrol->id.device].notify = val;
850 change = 1;
851 }
852 return change;
853}
854
855static int loopback_active_get(struct snd_kcontrol *kcontrol,
856 struct snd_ctl_elem_value *ucontrol)
857{
858 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
859 struct loopback_cable *cable = loopback->cables
860 [kcontrol->id.subdevice][kcontrol->id.device ^ 1];
861 unsigned int val = 0;
862
863 if (cable != NULL)
864 val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ?
865 1 : 0;
866 ucontrol->value.integer.value[0] = val;
867 return 0;
868}
869
870static int loopback_format_info(struct snd_kcontrol *kcontrol,
871 struct snd_ctl_elem_info *uinfo)
872{
873 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
874 uinfo->count = 1;
875 uinfo->value.integer.min = 0;
876 uinfo->value.integer.max = SNDRV_PCM_FORMAT_LAST;
877 uinfo->value.integer.step = 1;
878 return 0;
879}
880
881static int loopback_format_get(struct snd_kcontrol *kcontrol,
882 struct snd_ctl_elem_value *ucontrol)
883{
884 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
885
886 ucontrol->value.integer.value[0] =
887 loopback->setup[kcontrol->id.subdevice]
888 [kcontrol->id.device].format;
889 return 0;
890}
891
892static int loopback_rate_info(struct snd_kcontrol *kcontrol,
893 struct snd_ctl_elem_info *uinfo)
894{
895 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
896 uinfo->count = 1;
897 uinfo->value.integer.min = 0;
898 uinfo->value.integer.max = 192000;
899 uinfo->value.integer.step = 1;
900 return 0;
901}
902
903static int loopback_rate_get(struct snd_kcontrol *kcontrol,
904 struct snd_ctl_elem_value *ucontrol)
905{
906 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
907
908 ucontrol->value.integer.value[0] =
909 loopback->setup[kcontrol->id.subdevice]
910 [kcontrol->id.device].rate;
911 return 0;
912}
913
914static int loopback_channels_info(struct snd_kcontrol *kcontrol,
915 struct snd_ctl_elem_info *uinfo)
916{
917 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
918 uinfo->count = 1;
919 uinfo->value.integer.min = 1;
920 uinfo->value.integer.max = 1024;
921 uinfo->value.integer.step = 1;
922 return 0;
923}
924
925static int loopback_channels_get(struct snd_kcontrol *kcontrol,
926 struct snd_ctl_elem_value *ucontrol)
927{
928 struct loopback *loopback = snd_kcontrol_chip(kcontrol);
929
930 ucontrol->value.integer.value[0] =
931 loopback->setup[kcontrol->id.subdevice]
932 [kcontrol->id.device].channels;
933 return 0;
934}
935
936static struct snd_kcontrol_new loopback_controls[] __devinitdata = {
937{
938 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
939 .name = "PCM Rate Shift 100000",
940 .info = loopback_rate_shift_info,
941 .get = loopback_rate_shift_get,
942 .put = loopback_rate_shift_put,
943},
944{
945 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
946 .name = "PCM Notify",
947 .info = snd_ctl_boolean_mono_info,
948 .get = loopback_notify_get,
949 .put = loopback_notify_put,
950},
951#define ACTIVE_IDX 2
952{
953 .access = SNDRV_CTL_ELEM_ACCESS_READ,
954 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
955 .name = "PCM Slave Active",
956 .info = snd_ctl_boolean_mono_info,
957 .get = loopback_active_get,
958},
959#define FORMAT_IDX 3
960{
961 .access = SNDRV_CTL_ELEM_ACCESS_READ,
962 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
963 .name = "PCM Slave Format",
964 .info = loopback_format_info,
965 .get = loopback_format_get
966},
967#define RATE_IDX 4
968{
969 .access = SNDRV_CTL_ELEM_ACCESS_READ,
970 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
971 .name = "PCM Slave Rate",
972 .info = loopback_rate_info,
973 .get = loopback_rate_get
974},
975#define CHANNELS_IDX 5
976{
977 .access = SNDRV_CTL_ELEM_ACCESS_READ,
978 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
979 .name = "PCM Slave Channels",
980 .info = loopback_channels_info,
981 .get = loopback_channels_get
982}
983};
984
985static int __devinit loopback_mixer_new(struct loopback *loopback, int notify)
986{
987 struct snd_card *card = loopback->card;
988 struct snd_pcm *pcm;
989 struct snd_kcontrol *kctl;
990 struct loopback_setup *setup;
991 int err, dev, substr, substr_count, idx;
992
993 strcpy(card->mixername, "Loopback Mixer");
994 for (dev = 0; dev < 2; dev++) {
995 pcm = loopback->pcm[dev];
996 substr_count =
997 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count;
998 for (substr = 0; substr < substr_count; substr++) {
999 setup = &loopback->setup[substr][dev];
1000 setup->notify = notify;
1001 setup->rate_shift = NO_PITCH;
1002 setup->format = SNDRV_PCM_FORMAT_S16_LE;
1003 setup->rate = 48000;
1004 setup->channels = 2;
1005 for (idx = 0; idx < ARRAY_SIZE(loopback_controls);
1006 idx++) {
1007 kctl = snd_ctl_new1(&loopback_controls[idx],
1008 loopback);
1009 if (!kctl)
1010 return -ENOMEM;
1011 kctl->id.device = dev;
1012 kctl->id.subdevice = substr;
1013 switch (idx) {
1014 case ACTIVE_IDX:
1015 setup->active_id = kctl->id;
1016 break;
1017 case FORMAT_IDX:
1018 setup->format_id = kctl->id;
1019 break;
1020 case RATE_IDX:
1021 setup->rate_id = kctl->id;
1022 break;
1023 case CHANNELS_IDX:
1024 setup->channels_id = kctl->id;
1025 break;
1026 default:
1027 break;
1028 }
1029 err = snd_ctl_add(card, kctl);
1030 if (err < 0)
1031 return err;
1032 }
1033 }
1034 }
1035 return 0;
1036}
1037
1038#ifdef CONFIG_PROC_FS
1039
1040static void print_dpcm_info(struct snd_info_buffer *buffer,
1041 struct loopback_pcm *dpcm,
1042 const char *id)
1043{
1044 snd_iprintf(buffer, " %s\n", id);
1045 if (dpcm == NULL) {
1046 snd_iprintf(buffer, " inactive\n");
1047 return;
1048 }
1049 snd_iprintf(buffer, " buffer_size:\t%u\n", dpcm->pcm_buffer_size);
1050 snd_iprintf(buffer, " buffer_pos:\t\t%u\n", dpcm->buf_pos);
1051 snd_iprintf(buffer, " silent_size:\t%u\n", dpcm->silent_size);
1052 snd_iprintf(buffer, " period_size:\t%u\n", dpcm->pcm_period_size);
1053 snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps);
1054 snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign);
1055 snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift);
1056 snd_iprintf(buffer, " update_pending:\t%u\n",
1057 dpcm->period_update_pending);
1058 snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos);
1059 snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac);
1060 snd_iprintf(buffer, " last_jiffies:\t%lu (%lu)\n",
1061 dpcm->last_jiffies, jiffies);
1062 snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires);
1063}
1064
1065static void print_substream_info(struct snd_info_buffer *buffer,
1066 struct loopback *loopback,
1067 int sub,
1068 int num)
1069{
1070 struct loopback_cable *cable = loopback->cables[sub][num];
1071
1072 snd_iprintf(buffer, "Cable %i substream %i:\n", num, sub);
1073 if (cable == NULL) {
1074 snd_iprintf(buffer, " inactive\n");
1075 return;
1076 }
1077 snd_iprintf(buffer, " valid: %u\n", cable->valid);
1078 snd_iprintf(buffer, " running: %u\n", cable->running);
1079 snd_iprintf(buffer, " pause: %u\n", cable->pause);
1080 print_dpcm_info(buffer, cable->streams[0], "Playback");
1081 print_dpcm_info(buffer, cable->streams[1], "Capture");
1082}
1083
1084static void print_cable_info(struct snd_info_entry *entry,
1085 struct snd_info_buffer *buffer)
1086{
1087 struct loopback *loopback = entry->private_data;
1088 int sub, num;
1089
1090 mutex_lock(&loopback->cable_lock);
1091 num = entry->name[strlen(entry->name)-1];
1092 num = num == '0' ? 0 : 1;
1093 for (sub = 0; sub < MAX_PCM_SUBSTREAMS; sub++)
1094 print_substream_info(buffer, loopback, sub, num);
1095 mutex_unlock(&loopback->cable_lock);
1096}
1097
1098static int __devinit loopback_proc_new(struct loopback *loopback, int cidx)
1099{
1100 char name[32];
1101 struct snd_info_entry *entry;
1102 int err;
1103
1104 snprintf(name, sizeof(name), "cable#%d", cidx);
1105 err = snd_card_proc_new(loopback->card, name, &entry);
1106 if (err < 0)
1107 return err;
1108
1109 snd_info_set_text_ops(entry, loopback, print_cable_info);
1110 return 0;
1111}
1112
1113#else /* !CONFIG_PROC_FS */
1114
1115#define loopback_proc_new(loopback, cidx) do { } while (0)
1116
1117#endif
1118
1119static int __devinit loopback_probe(struct platform_device *devptr)
1120{
1121 struct snd_card *card;
1122 struct loopback *loopback;
1123 int dev = devptr->id;
1124 int err;
1125
1126 err = snd_card_create(index[dev], id[dev], THIS_MODULE,
1127 sizeof(struct loopback), &card);
1128 if (err < 0)
1129 return err;
1130 loopback = card->private_data;
1131
1132 if (pcm_substreams[dev] < 1)
1133 pcm_substreams[dev] = 1;
1134 if (pcm_substreams[dev] > MAX_PCM_SUBSTREAMS)
1135 pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
1136
1137 loopback->card = card;
1138 mutex_init(&loopback->cable_lock);
1139
1140 err = loopback_pcm_new(loopback, 0, pcm_substreams[dev]);
1141 if (err < 0)
1142 goto __nodev;
1143 err = loopback_pcm_new(loopback, 1, pcm_substreams[dev]);
1144 if (err < 0)
1145 goto __nodev;
1146 err = loopback_mixer_new(loopback, pcm_notify[dev] ? 1 : 0);
1147 if (err < 0)
1148 goto __nodev;
1149 loopback_proc_new(loopback, 0);
1150 loopback_proc_new(loopback, 1);
1151 strcpy(card->driver, "Loopback");
1152 strcpy(card->shortname, "Loopback");
1153 sprintf(card->longname, "Loopback %i", dev + 1);
1154 err = snd_card_register(card);
1155 if (!err) {
1156 platform_set_drvdata(devptr, card);
1157 return 0;
1158 }
1159 __nodev:
1160 snd_card_free(card);
1161 return err;
1162}
1163
1164static int __devexit loopback_remove(struct platform_device *devptr)
1165{
1166 snd_card_free(platform_get_drvdata(devptr));
1167 platform_set_drvdata(devptr, NULL);
1168 return 0;
1169}
1170
1171#ifdef CONFIG_PM
1172static int loopback_suspend(struct platform_device *pdev,
1173 pm_message_t state)
1174{
1175 struct snd_card *card = platform_get_drvdata(pdev);
1176 struct loopback *loopback = card->private_data;
1177
1178 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1179
1180 snd_pcm_suspend_all(loopback->pcm[0]);
1181 snd_pcm_suspend_all(loopback->pcm[1]);
1182 return 0;
1183}
1184
1185static int loopback_resume(struct platform_device *pdev)
1186{
1187 struct snd_card *card = platform_get_drvdata(pdev);
1188
1189 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1190 return 0;
1191}
1192#endif
1193
1194#define SND_LOOPBACK_DRIVER "snd_aloop"
1195
1196static struct platform_driver loopback_driver = {
1197 .probe = loopback_probe,
1198 .remove = __devexit_p(loopback_remove),
1199#ifdef CONFIG_PM
1200 .suspend = loopback_suspend,
1201 .resume = loopback_resume,
1202#endif
1203 .driver = {
1204 .name = SND_LOOPBACK_DRIVER
1205 },
1206};
1207
1208static void loopback_unregister_all(void)
1209{
1210 int i;
1211
1212 for (i = 0; i < ARRAY_SIZE(devices); ++i)
1213 platform_device_unregister(devices[i]);
1214 platform_driver_unregister(&loopback_driver);
1215}
1216
1217static int __init alsa_card_loopback_init(void)
1218{
1219 int i, err, cards;
1220
1221 err = platform_driver_register(&loopback_driver);
1222 if (err < 0)
1223 return err;
1224
1225
1226 cards = 0;
1227 for (i = 0; i < SNDRV_CARDS; i++) {
1228 struct platform_device *device;
1229 if (!enable[i])
1230 continue;
1231 device = platform_device_register_simple(SND_LOOPBACK_DRIVER,
1232 i, NULL, 0);
1233 if (IS_ERR(device))
1234 continue;
1235 if (!platform_get_drvdata(device)) {
1236 platform_device_unregister(device);
1237 continue;
1238 }
1239 devices[i] = device;
1240 cards++;
1241 }
1242 if (!cards) {
1243#ifdef MODULE
1244 printk(KERN_ERR "aloop: No loopback enabled\n");
1245#endif
1246 loopback_unregister_all();
1247 return -ENODEV;
1248 }
1249 return 0;
1250}
1251
1252static void __exit alsa_card_loopback_exit(void)
1253{
1254 loopback_unregister_all();
1255}
1256
1257module_init(alsa_card_loopback_init)
1258module_exit(alsa_card_loopback_exit)
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 0e631c3221e3..f4cd49336f33 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -94,7 +94,7 @@ static int __devinit snd_virmidi_probe(struct platform_device *devptr)
94 sizeof(struct snd_card_virmidi), &card); 94 sizeof(struct snd_card_virmidi), &card);
95 if (err < 0) 95 if (err < 0)
96 return err; 96 return err;
97 vmidi = (struct snd_card_virmidi *)card->private_data; 97 vmidi = card->private_data;
98 vmidi->card = card; 98 vmidi->card = card;
99 99
100 if (midi_devs[dev] > MAX_MIDI_DEVICES) { 100 if (midi_devs[dev] > MAX_MIDI_DEVICES) {
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index 42d7844ecd0b..57ccba88700d 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -878,7 +878,7 @@ static int build_deemphasis(struct snd_akm4xxx *ak, int num_emphs)
878static void proc_regs_read(struct snd_info_entry *entry, 878static void proc_regs_read(struct snd_info_entry *entry,
879 struct snd_info_buffer *buffer) 879 struct snd_info_buffer *buffer)
880{ 880{
881 struct snd_akm4xxx *ak = (struct snd_akm4xxx *)entry->private_data; 881 struct snd_akm4xxx *ak = entry->private_data;
882 int reg, val, chip; 882 int reg, val, chip;
883 for (chip = 0; chip < ak->num_chips; chip++) { 883 for (chip = 0; chip < ak->num_chips; chip++) {
884 for (reg = 0; reg < ak->total_regs; reg++) { 884 for (reg = 0; reg < ak->total_regs; reg++) {
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index c6990c680796..52064cfa91f3 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -77,6 +77,32 @@ config SND_ALS100
77 To compile this driver as a module, choose M here: the module 77 To compile this driver as a module, choose M here: the module
78 will be called snd-als100. 78 will be called snd-als100.
79 79
80config SND_AZT1605
81 tristate "Aztech AZT1605 Driver"
82 depends on SND
83 select SND_WSS_LIB
84 select SND_MPU401_UART
85 select SND_OPL3_LIB
86 help
87 Say Y here to include support for Aztech Sound Galaxy cards
88 based on the AZT1605 chipset.
89
90 To compile this driver as a module, choose M here: the module
91 will be called snd-azt1605.
92
93config SND_AZT2316
94 tristate "Aztech AZT2316 Driver"
95 depends on SND
96 select SND_WSS_LIB
97 select SND_MPU401_UART
98 select SND_OPL3_LIB
99 help
100 Say Y here to include support for Aztech Sound Galaxy cards
101 based on the AZT2316 chipset.
102
103 To compile this driver as a module, choose M here: the module
104 will be called snd-azt2316.
105
80config SND_AZT2320 106config SND_AZT2320
81 tristate "Aztech Systems AZT2320" 107 tristate "Aztech Systems AZT2320"
82 depends on PNP 108 depends on PNP
@@ -351,16 +377,6 @@ config SND_SB16_CSP
351 coprocessor can do variable tasks like various compression and 377 coprocessor can do variable tasks like various compression and
352 decompression algorithms. 378 decompression algorithms.
353 379
354config SND_SGALAXY
355 tristate "Aztech Sound Galaxy"
356 select SND_WSS_LIB
357 help
358 Say Y here to include support for Aztech Sound Galaxy
359 soundcards.
360
361 To compile this driver as a module, choose M here: the module
362 will be called snd-sgalaxy.
363
364config SND_SSCAPE 380config SND_SSCAPE
365 tristate "Ensoniq SoundScape driver" 381 tristate "Ensoniq SoundScape driver"
366 select SND_MPU401_UART 382 select SND_MPU401_UART
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index c73d30c4f462..8d781e419e2e 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -10,7 +10,6 @@ snd-cmi8330-objs := cmi8330.o
10snd-es18xx-objs := es18xx.o 10snd-es18xx-objs := es18xx.o
11snd-opl3sa2-objs := opl3sa2.o 11snd-opl3sa2-objs := opl3sa2.o
12snd-sc6000-objs := sc6000.o 12snd-sc6000-objs := sc6000.o
13snd-sgalaxy-objs := sgalaxy.o
14snd-sscape-objs := sscape.o 13snd-sscape-objs := sscape.o
15 14
16# Toplevel Module Dependency 15# Toplevel Module Dependency
@@ -21,8 +20,7 @@ obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
21obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o 20obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
22obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o 21obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
23obj-$(CONFIG_SND_SC6000) += snd-sc6000.o 22obj-$(CONFIG_SND_SC6000) += snd-sc6000.o
24obj-$(CONFIG_SND_SGALAXY) += snd-sgalaxy.o
25obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o 23obj-$(CONFIG_SND_SSCAPE) += snd-sscape.o
26 24
27obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ gus/ msnd/ opti9xx/ \ 25obj-$(CONFIG_SND) += ad1816a/ ad1848/ cs423x/ es1688/ galaxy/ gus/ msnd/ opti9xx/ \
28 sb/ wavefront/ wss/ 26 sb/ wavefront/ wss/
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index bbcbf92a8ebe..3cb75bc97699 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -162,7 +162,7 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard
162 sizeof(struct snd_card_ad1816a), &card); 162 sizeof(struct snd_card_ad1816a), &card);
163 if (error < 0) 163 if (error < 0)
164 return error; 164 return error;
165 acard = (struct snd_card_ad1816a *)card->private_data; 165 acard = card->private_data;
166 166
167 if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) { 167 if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) {
168 snd_card_free(card); 168 snd_card_free(card);
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index f7aa637b0d18..aac8dc15c2fe 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -188,7 +188,7 @@ static int __devinit snd_card_azt2320_probe(int dev,
188 sizeof(struct snd_card_azt2320), &card); 188 sizeof(struct snd_card_azt2320), &card);
189 if (error < 0) 189 if (error < 0)
190 return error; 190 return error;
191 acard = (struct snd_card_azt2320 *)card->private_data; 191 acard = card->private_data;
192 192
193 if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) { 193 if ((error = snd_card_azt2320_pnp(dev, acard, pcard, pid))) {
194 snd_card_free(card); 194 snd_card_free(card);
diff --git a/sound/isa/galaxy/Makefile b/sound/isa/galaxy/Makefile
new file mode 100644
index 000000000000..e307066d4315
--- /dev/null
+++ b/sound/isa/galaxy/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for ALSA
3# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
4#
5
6snd-azt1605-objs := azt1605.o
7snd-azt2316-objs := azt2316.o
8
9obj-$(CONFIG_SND_AZT1605) += snd-azt1605.o
10obj-$(CONFIG_SND_AZT2316) += snd-azt2316.o
diff --git a/sound/isa/galaxy/azt1605.c b/sound/isa/galaxy/azt1605.c
new file mode 100644
index 000000000000..9a97643cb713
--- /dev/null
+++ b/sound/isa/galaxy/azt1605.c
@@ -0,0 +1,91 @@
1/*
2 * Aztech AZT1605 Driver
3 * Copyright (C) 2007,2010 Rene Herman
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#define AZT1605
21
22#define CRD_NAME "Aztech AZT1605"
23#define DRV_NAME "AZT1605"
24#define DEV_NAME "azt1605"
25
26#define GALAXY_DSP_MAJOR 2
27#define GALAXY_DSP_MINOR 1
28
29#define GALAXY_CONFIG_SIZE 3
30
31/*
32 * 24-bit config register
33 */
34
35#define GALAXY_CONFIG_SBA_220 (0 << 0)
36#define GALAXY_CONFIG_SBA_240 (1 << 0)
37#define GALAXY_CONFIG_SBA_260 (2 << 0)
38#define GALAXY_CONFIG_SBA_280 (3 << 0)
39#define GALAXY_CONFIG_SBA_MASK GALAXY_CONFIG_SBA_280
40
41#define GALAXY_CONFIG_MPUA_300 (0 << 2)
42#define GALAXY_CONFIG_MPUA_330 (1 << 2)
43
44#define GALAXY_CONFIG_MPU_ENABLE (1 << 3)
45
46#define GALAXY_CONFIG_GAME_ENABLE (1 << 4)
47
48#define GALAXY_CONFIG_CD_PANASONIC (1 << 5)
49#define GALAXY_CONFIG_CD_MITSUMI (1 << 6)
50#define GALAXY_CONFIG_CD_MASK (\
51 GALAXY_CONFIG_CD_PANASONIC | GALAXY_CONFIG_CD_MITSUMI)
52
53#define GALAXY_CONFIG_UNUSED (1 << 7)
54#define GALAXY_CONFIG_UNUSED_MASK GALAXY_CONFIG_UNUSED
55
56#define GALAXY_CONFIG_SBIRQ_2 (1 << 8)
57#define GALAXY_CONFIG_SBIRQ_3 (1 << 9)
58#define GALAXY_CONFIG_SBIRQ_5 (1 << 10)
59#define GALAXY_CONFIG_SBIRQ_7 (1 << 11)
60
61#define GALAXY_CONFIG_MPUIRQ_2 (1 << 12)
62#define GALAXY_CONFIG_MPUIRQ_3 (1 << 13)
63#define GALAXY_CONFIG_MPUIRQ_5 (1 << 14)
64#define GALAXY_CONFIG_MPUIRQ_7 (1 << 15)
65
66#define GALAXY_CONFIG_WSSA_530 (0 << 16)
67#define GALAXY_CONFIG_WSSA_604 (1 << 16)
68#define GALAXY_CONFIG_WSSA_E80 (2 << 16)
69#define GALAXY_CONFIG_WSSA_F40 (3 << 16)
70
71#define GALAXY_CONFIG_WSS_ENABLE (1 << 18)
72
73#define GALAXY_CONFIG_CDIRQ_11 (1 << 19)
74#define GALAXY_CONFIG_CDIRQ_12 (1 << 20)
75#define GALAXY_CONFIG_CDIRQ_15 (1 << 21)
76#define GALAXY_CONFIG_CDIRQ_MASK (\
77 GALAXY_CONFIG_CDIRQ_11 | GALAXY_CONFIG_CDIRQ_12 |\
78 GALAXY_CONFIG_CDIRQ_15)
79
80#define GALAXY_CONFIG_CDDMA_DISABLE (0 << 22)
81#define GALAXY_CONFIG_CDDMA_0 (1 << 22)
82#define GALAXY_CONFIG_CDDMA_1 (2 << 22)
83#define GALAXY_CONFIG_CDDMA_3 (3 << 22)
84#define GALAXY_CONFIG_CDDMA_MASK GALAXY_CONFIG_CDDMA_3
85
86#define GALAXY_CONFIG_MASK (\
87 GALAXY_CONFIG_SBA_MASK | GALAXY_CONFIG_CD_MASK |\
88 GALAXY_CONFIG_UNUSED_MASK | GALAXY_CONFIG_CDIRQ_MASK |\
89 GALAXY_CONFIG_CDDMA_MASK)
90
91#include "galaxy.c"
diff --git a/sound/isa/galaxy/azt2316.c b/sound/isa/galaxy/azt2316.c
new file mode 100644
index 000000000000..189441141df6
--- /dev/null
+++ b/sound/isa/galaxy/azt2316.c
@@ -0,0 +1,111 @@
1/*
2 * Aztech AZT2316 Driver
3 * Copyright (C) 2007,2010 Rene Herman
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#define AZT2316
21
22#define CRD_NAME "Aztech AZT2316"
23#define DRV_NAME "AZT2316"
24#define DEV_NAME "azt2316"
25
26#define GALAXY_DSP_MAJOR 3
27#define GALAXY_DSP_MINOR 1
28
29#define GALAXY_CONFIG_SIZE 4
30
31/*
32 * 32-bit config register
33 */
34
35#define GALAXY_CONFIG_SBA_220 (0 << 0)
36#define GALAXY_CONFIG_SBA_240 (1 << 0)
37#define GALAXY_CONFIG_SBA_260 (2 << 0)
38#define GALAXY_CONFIG_SBA_280 (3 << 0)
39#define GALAXY_CONFIG_SBA_MASK GALAXY_CONFIG_SBA_280
40
41#define GALAXY_CONFIG_SBIRQ_2 (1 << 2)
42#define GALAXY_CONFIG_SBIRQ_5 (1 << 3)
43#define GALAXY_CONFIG_SBIRQ_7 (1 << 4)
44#define GALAXY_CONFIG_SBIRQ_10 (1 << 5)
45
46#define GALAXY_CONFIG_SBDMA_DISABLE (0 << 6)
47#define GALAXY_CONFIG_SBDMA_0 (1 << 6)
48#define GALAXY_CONFIG_SBDMA_1 (2 << 6)
49#define GALAXY_CONFIG_SBDMA_3 (3 << 6)
50
51#define GALAXY_CONFIG_WSSA_530 (0 << 8)
52#define GALAXY_CONFIG_WSSA_604 (1 << 8)
53#define GALAXY_CONFIG_WSSA_E80 (2 << 8)
54#define GALAXY_CONFIG_WSSA_F40 (3 << 8)
55
56#define GALAXY_CONFIG_WSS_ENABLE (1 << 10)
57
58#define GALAXY_CONFIG_GAME_ENABLE (1 << 11)
59
60#define GALAXY_CONFIG_MPUA_300 (0 << 12)
61#define GALAXY_CONFIG_MPUA_330 (1 << 12)
62
63#define GALAXY_CONFIG_MPU_ENABLE (1 << 13)
64
65#define GALAXY_CONFIG_CDA_310 (0 << 14)
66#define GALAXY_CONFIG_CDA_320 (1 << 14)
67#define GALAXY_CONFIG_CDA_340 (2 << 14)
68#define GALAXY_CONFIG_CDA_350 (3 << 14)
69#define GALAXY_CONFIG_CDA_MASK GALAXY_CONFIG_CDA_350
70
71#define GALAXY_CONFIG_CD_DISABLE (0 << 16)
72#define GALAXY_CONFIG_CD_PANASONIC (1 << 16)
73#define GALAXY_CONFIG_CD_SONY (2 << 16)
74#define GALAXY_CONFIG_CD_MITSUMI (3 << 16)
75#define GALAXY_CONFIG_CD_AZTECH (4 << 16)
76#define GALAXY_CONFIG_CD_UNUSED_5 (5 << 16)
77#define GALAXY_CONFIG_CD_UNUSED_6 (6 << 16)
78#define GALAXY_CONFIG_CD_UNUSED_7 (7 << 16)
79#define GALAXY_CONFIG_CD_MASK GALAXY_CONFIG_CD_UNUSED_7
80
81#define GALAXY_CONFIG_CDDMA8_DISABLE (0 << 20)
82#define GALAXY_CONFIG_CDDMA8_0 (1 << 20)
83#define GALAXY_CONFIG_CDDMA8_1 (2 << 20)
84#define GALAXY_CONFIG_CDDMA8_3 (3 << 20)
85#define GALAXY_CONFIG_CDDMA8_MASK GALAXY_CONFIG_CDDMA8_3
86
87#define GALAXY_CONFIG_CDDMA16_DISABLE (0 << 22)
88#define GALAXY_CONFIG_CDDMA16_5 (1 << 22)
89#define GALAXY_CONFIG_CDDMA16_6 (2 << 22)
90#define GALAXY_CONFIG_CDDMA16_7 (3 << 22)
91#define GALAXY_CONFIG_CDDMA16_MASK GALAXY_CONFIG_CDDMA16_7
92
93#define GALAXY_CONFIG_MPUIRQ_2 (1 << 24)
94#define GALAXY_CONFIG_MPUIRQ_5 (1 << 25)
95#define GALAXY_CONFIG_MPUIRQ_7 (1 << 26)
96#define GALAXY_CONFIG_MPUIRQ_10 (1 << 27)
97
98#define GALAXY_CONFIG_CDIRQ_5 (1 << 28)
99#define GALAXY_CONFIG_CDIRQ_11 (1 << 29)
100#define GALAXY_CONFIG_CDIRQ_12 (1 << 30)
101#define GALAXY_CONFIG_CDIRQ_15 (1 << 31)
102#define GALAXY_CONFIG_CDIRQ_MASK (\
103 GALAXY_CONFIG_CDIRQ_5 | GALAXY_CONFIG_CDIRQ_11 |\
104 GALAXY_CONFIG_CDIRQ_12 | GALAXY_CONFIG_CDIRQ_15)
105
106#define GALAXY_CONFIG_MASK (\
107 GALAXY_CONFIG_SBA_MASK | GALAXY_CONFIG_CDA_MASK |\
108 GALAXY_CONFIG_CD_MASK | GALAXY_CONFIG_CDDMA16_MASK |\
109 GALAXY_CONFIG_CDDMA8_MASK | GALAXY_CONFIG_CDIRQ_MASK)
110
111#include "galaxy.c"
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c
new file mode 100644
index 000000000000..ee54df082b9c
--- /dev/null
+++ b/sound/isa/galaxy/galaxy.c
@@ -0,0 +1,652 @@
1/*
2 * Aztech AZT1605/AZT2316 Driver
3 * Copyright (C) 2007,2010 Rene Herman
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/isa.h>
23#include <linux/delay.h>
24#include <linux/io.h>
25#include <asm/processor.h>
26#include <sound/core.h>
27#include <sound/initval.h>
28#include <sound/wss.h>
29#include <sound/mpu401.h>
30#include <sound/opl3.h>
31
32MODULE_DESCRIPTION(CRD_NAME);
33MODULE_AUTHOR("Rene Herman");
34MODULE_LICENSE("GPL");
35
36static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
37static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
38static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
39
40module_param_array(index, int, NULL, 0444);
41MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
42module_param_array(id, charp, NULL, 0444);
43MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
44module_param_array(enable, bool, NULL, 0444);
45MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
46
47static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
48static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
49static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
50static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
51static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
52static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
53static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
54static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
55
56module_param_array(port, long, NULL, 0444);
57MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
58module_param_array(wss_port, long, NULL, 0444);
59MODULE_PARM_DESC(wss_port, "WSS port # for " CRD_NAME " driver.");
60module_param_array(mpu_port, long, NULL, 0444);
61MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
62module_param_array(fm_port, long, NULL, 0444);
63MODULE_PARM_DESC(fm_port, "FM port # for " CRD_NAME " driver.");
64module_param_array(irq, int, NULL, 0444);
65MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
66module_param_array(mpu_irq, int, NULL, 0444);
67MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
68module_param_array(dma1, int, NULL, 0444);
69MODULE_PARM_DESC(dma1, "Playback DMA # for " CRD_NAME " driver.");
70module_param_array(dma2, int, NULL, 0444);
71MODULE_PARM_DESC(dma2, "Capture DMA # for " CRD_NAME " driver.");
72
73/*
74 * Generic SB DSP support routines
75 */
76
77#define DSP_PORT_RESET 0x6
78#define DSP_PORT_READ 0xa
79#define DSP_PORT_COMMAND 0xc
80#define DSP_PORT_STATUS 0xc
81#define DSP_PORT_DATA_AVAIL 0xe
82
83#define DSP_SIGNATURE 0xaa
84
85#define DSP_COMMAND_GET_VERSION 0xe1
86
87static int __devinit dsp_get_byte(void __iomem *port, u8 *val)
88{
89 int loops = 1000;
90
91 while (!(ioread8(port + DSP_PORT_DATA_AVAIL) & 0x80)) {
92 if (!loops--)
93 return -EIO;
94 cpu_relax();
95 }
96 *val = ioread8(port + DSP_PORT_READ);
97 return 0;
98}
99
100static int __devinit dsp_reset(void __iomem *port)
101{
102 u8 val;
103
104 iowrite8(1, port + DSP_PORT_RESET);
105 udelay(10);
106 iowrite8(0, port + DSP_PORT_RESET);
107
108 if (dsp_get_byte(port, &val) < 0 || val != DSP_SIGNATURE)
109 return -ENODEV;
110
111 return 0;
112}
113
114static int __devinit dsp_command(void __iomem *port, u8 cmd)
115{
116 int loops = 1000;
117
118 while (ioread8(port + DSP_PORT_STATUS) & 0x80) {
119 if (!loops--)
120 return -EIO;
121 cpu_relax();
122 }
123 iowrite8(cmd, port + DSP_PORT_COMMAND);
124 return 0;
125}
126
127static int __devinit dsp_get_version(void __iomem *port, u8 *major, u8 *minor)
128{
129 int err;
130
131 err = dsp_command(port, DSP_COMMAND_GET_VERSION);
132 if (err < 0)
133 return err;
134
135 err = dsp_get_byte(port, major);
136 if (err < 0)
137 return err;
138
139 err = dsp_get_byte(port, minor);
140 if (err < 0)
141 return err;
142
143 return 0;
144}
145
146/*
147 * Generic WSS support routines
148 */
149
150#define WSS_CONFIG_DMA_0 (1 << 0)
151#define WSS_CONFIG_DMA_1 (2 << 0)
152#define WSS_CONFIG_DMA_3 (3 << 0)
153#define WSS_CONFIG_DUPLEX (1 << 2)
154#define WSS_CONFIG_IRQ_7 (1 << 3)
155#define WSS_CONFIG_IRQ_9 (2 << 3)
156#define WSS_CONFIG_IRQ_10 (3 << 3)
157#define WSS_CONFIG_IRQ_11 (4 << 3)
158
159#define WSS_PORT_CONFIG 0
160#define WSS_PORT_SIGNATURE 3
161
162#define WSS_SIGNATURE 4
163
164static int __devinit wss_detect(void __iomem *wss_port)
165{
166 if ((ioread8(wss_port + WSS_PORT_SIGNATURE) & 0x3f) != WSS_SIGNATURE)
167 return -ENODEV;
168
169 return 0;
170}
171
172static void wss_set_config(void __iomem *wss_port, u8 wss_config)
173{
174 iowrite8(wss_config, wss_port + WSS_PORT_CONFIG);
175}
176
177/*
178 * Aztech Sound Galaxy specifics
179 */
180
181#define GALAXY_PORT_CONFIG 1024
182#define CONFIG_PORT_SET 4
183
184#define DSP_COMMAND_GALAXY_8 8
185#define GALAXY_COMMAND_GET_TYPE 5
186
187#define DSP_COMMAND_GALAXY_9 9
188#define GALAXY_COMMAND_WSSMODE 0
189#define GALAXY_COMMAND_SB8MODE 1
190
191#define GALAXY_MODE_WSS GALAXY_COMMAND_WSSMODE
192#define GALAXY_MODE_SB8 GALAXY_COMMAND_SB8MODE
193
194struct snd_galaxy {
195 void __iomem *port;
196 void __iomem *config_port;
197 void __iomem *wss_port;
198 u32 config;
199 struct resource *res_port;
200 struct resource *res_config_port;
201 struct resource *res_wss_port;
202};
203
204static u32 config[SNDRV_CARDS];
205static u8 wss_config[SNDRV_CARDS];
206
207static int __devinit snd_galaxy_match(struct device *dev, unsigned int n)
208{
209 if (!enable[n])
210 return 0;
211
212 switch (port[n]) {
213 case SNDRV_AUTO_PORT:
214 dev_err(dev, "please specify port\n");
215 return 0;
216 case 0x220:
217 config[n] |= GALAXY_CONFIG_SBA_220;
218 break;
219 case 0x240:
220 config[n] |= GALAXY_CONFIG_SBA_240;
221 break;
222 case 0x260:
223 config[n] |= GALAXY_CONFIG_SBA_260;
224 break;
225 case 0x280:
226 config[n] |= GALAXY_CONFIG_SBA_280;
227 break;
228 default:
229 dev_err(dev, "invalid port %#lx\n", port[n]);
230 return 0;
231 }
232
233 switch (wss_port[n]) {
234 case SNDRV_AUTO_PORT:
235 dev_err(dev, "please specify wss_port\n");
236 return 0;
237 case 0x530:
238 config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_530;
239 break;
240 case 0x604:
241 config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_604;
242 break;
243 case 0xe80:
244 config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_E80;
245 break;
246 case 0xf40:
247 config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_F40;
248 break;
249 default:
250 dev_err(dev, "invalid WSS port %#lx\n", wss_port[n]);
251 return 0;
252 }
253
254 switch (irq[n]) {
255 case SNDRV_AUTO_IRQ:
256 dev_err(dev, "please specify irq\n");
257 return 0;
258 case 7:
259 wss_config[n] |= WSS_CONFIG_IRQ_7;
260 break;
261 case 2:
262 irq[n] = 9;
263 case 9:
264 wss_config[n] |= WSS_CONFIG_IRQ_9;
265 break;
266 case 10:
267 wss_config[n] |= WSS_CONFIG_IRQ_10;
268 break;
269 case 11:
270 wss_config[n] |= WSS_CONFIG_IRQ_11;
271 break;
272 default:
273 dev_err(dev, "invalid IRQ %d\n", irq[n]);
274 return 0;
275 }
276
277 switch (dma1[n]) {
278 case SNDRV_AUTO_DMA:
279 dev_err(dev, "please specify dma1\n");
280 return 0;
281 case 0:
282 wss_config[n] |= WSS_CONFIG_DMA_0;
283 break;
284 case 1:
285 wss_config[n] |= WSS_CONFIG_DMA_1;
286 break;
287 case 3:
288 wss_config[n] |= WSS_CONFIG_DMA_3;
289 break;
290 default:
291 dev_err(dev, "invalid playback DMA %d\n", dma1[n]);
292 return 0;
293 }
294
295 if (dma2[n] == SNDRV_AUTO_DMA || dma2[n] == dma1[n]) {
296 dma2[n] = -1;
297 goto mpu;
298 }
299
300 wss_config[n] |= WSS_CONFIG_DUPLEX;
301 switch (dma2[n]) {
302 case 0:
303 break;
304 case 1:
305 if (dma1[n] == 0)
306 break;
307 default:
308 dev_err(dev, "invalid capture DMA %d\n", dma2[n]);
309 return 0;
310 }
311
312mpu:
313 switch (mpu_port[n]) {
314 case SNDRV_AUTO_PORT:
315 dev_warn(dev, "mpu_port not specified; not using MPU-401\n");
316 mpu_port[n] = -1;
317 goto fm;
318 case 0x300:
319 config[n] |= GALAXY_CONFIG_MPU_ENABLE | GALAXY_CONFIG_MPUA_300;
320 break;
321 case 0x330:
322 config[n] |= GALAXY_CONFIG_MPU_ENABLE | GALAXY_CONFIG_MPUA_330;
323 break;
324 default:
325 dev_err(dev, "invalid MPU port %#lx\n", mpu_port[n]);
326 return 0;
327 }
328
329 switch (mpu_irq[n]) {
330 case SNDRV_AUTO_IRQ:
331 dev_warn(dev, "mpu_irq not specified: using polling mode\n");
332 mpu_irq[n] = -1;
333 break;
334 case 2:
335 mpu_irq[n] = 9;
336 case 9:
337 config[n] |= GALAXY_CONFIG_MPUIRQ_2;
338 break;
339#ifdef AZT1605
340 case 3:
341 config[n] |= GALAXY_CONFIG_MPUIRQ_3;
342 break;
343#endif
344 case 5:
345 config[n] |= GALAXY_CONFIG_MPUIRQ_5;
346 break;
347 case 7:
348 config[n] |= GALAXY_CONFIG_MPUIRQ_7;
349 break;
350#ifdef AZT2316
351 case 10:
352 config[n] |= GALAXY_CONFIG_MPUIRQ_10;
353 break;
354#endif
355 default:
356 dev_err(dev, "invalid MPU IRQ %d\n", mpu_irq[n]);
357 return 0;
358 }
359
360 if (mpu_irq[n] == irq[n]) {
361 dev_err(dev, "cannot share IRQ between WSS and MPU-401\n");
362 return 0;
363 }
364
365fm:
366 switch (fm_port[n]) {
367 case SNDRV_AUTO_PORT:
368 dev_warn(dev, "fm_port not specified: not using OPL3\n");
369 fm_port[n] = -1;
370 break;
371 case 0x388:
372 break;
373 default:
374 dev_err(dev, "illegal FM port %#lx\n", fm_port[n]);
375 return 0;
376 }
377
378 config[n] |= GALAXY_CONFIG_GAME_ENABLE;
379 return 1;
380}
381
382static int __devinit galaxy_init(struct snd_galaxy *galaxy, u8 *type)
383{
384 u8 major;
385 u8 minor;
386 int err;
387
388 err = dsp_reset(galaxy->port);
389 if (err < 0)
390 return err;
391
392 err = dsp_get_version(galaxy->port, &major, &minor);
393 if (err < 0)
394 return err;
395
396 if (major != GALAXY_DSP_MAJOR || minor != GALAXY_DSP_MINOR)
397 return -ENODEV;
398
399 err = dsp_command(galaxy->port, DSP_COMMAND_GALAXY_8);
400 if (err < 0)
401 return err;
402
403 err = dsp_command(galaxy->port, GALAXY_COMMAND_GET_TYPE);
404 if (err < 0)
405 return err;
406
407 err = dsp_get_byte(galaxy->port, type);
408 if (err < 0)
409 return err;
410
411 return 0;
412}
413
414static int __devinit galaxy_set_mode(struct snd_galaxy *galaxy, u8 mode)
415{
416 int err;
417
418 err = dsp_command(galaxy->port, DSP_COMMAND_GALAXY_9);
419 if (err < 0)
420 return err;
421
422 err = dsp_command(galaxy->port, mode);
423 if (err < 0)
424 return err;
425
426#ifdef AZT1605
427 /*
428 * Needed for MPU IRQ on AZT1605, but AZT2316 loses WSS again
429 */
430 err = dsp_reset(galaxy->port);
431 if (err < 0)
432 return err;
433#endif
434
435 return 0;
436}
437
438static void galaxy_set_config(struct snd_galaxy *galaxy, u32 config)
439{
440 u8 tmp = ioread8(galaxy->config_port + CONFIG_PORT_SET);
441 int i;
442
443 iowrite8(tmp | 0x80, galaxy->config_port + CONFIG_PORT_SET);
444 for (i = 0; i < GALAXY_CONFIG_SIZE; i++) {
445 iowrite8(config, galaxy->config_port + i);
446 config >>= 8;
447 }
448 iowrite8(tmp & 0x7f, galaxy->config_port + CONFIG_PORT_SET);
449 msleep(10);
450}
451
452static void __devinit galaxy_config(struct snd_galaxy *galaxy, u32 config)
453{
454 int i;
455
456 for (i = GALAXY_CONFIG_SIZE; i; i--) {
457 u8 tmp = ioread8(galaxy->config_port + i - 1);
458 galaxy->config = (galaxy->config << 8) | tmp;
459 }
460 config |= galaxy->config & GALAXY_CONFIG_MASK;
461 galaxy_set_config(galaxy, config);
462}
463
464static int __devinit galaxy_wss_config(struct snd_galaxy *galaxy, u8 wss_config)
465{
466 int err;
467
468 err = wss_detect(galaxy->wss_port);
469 if (err < 0)
470 return err;
471
472 wss_set_config(galaxy->wss_port, wss_config);
473
474 err = galaxy_set_mode(galaxy, GALAXY_MODE_WSS);
475 if (err < 0)
476 return err;
477
478 return 0;
479}
480
481static void snd_galaxy_free(struct snd_card *card)
482{
483 struct snd_galaxy *galaxy = card->private_data;
484
485 if (galaxy->wss_port) {
486 wss_set_config(galaxy->wss_port, 0);
487 ioport_unmap(galaxy->wss_port);
488 release_and_free_resource(galaxy->res_wss_port);
489 }
490 if (galaxy->config_port) {
491 galaxy_set_config(galaxy, galaxy->config);
492 ioport_unmap(galaxy->config_port);
493 release_and_free_resource(galaxy->res_config_port);
494 }
495 if (galaxy->port) {
496 ioport_unmap(galaxy->port);
497 release_and_free_resource(galaxy->res_port);
498 }
499}
500
501static int __devinit snd_galaxy_probe(struct device *dev, unsigned int n)
502{
503 struct snd_galaxy *galaxy;
504 struct snd_wss *chip;
505 struct snd_card *card;
506 u8 type;
507 int err;
508
509 err = snd_card_create(index[n], id[n], THIS_MODULE, sizeof *galaxy,
510 &card);
511 if (err < 0)
512 return err;
513
514 snd_card_set_dev(card, dev);
515
516 card->private_free = snd_galaxy_free;
517 galaxy = card->private_data;
518
519 galaxy->res_port = request_region(port[n], 16, DRV_NAME);
520 if (!galaxy->res_port) {
521 dev_err(dev, "could not grab ports %#lx-%#lx\n", port[n],
522 port[n] + 15);
523 err = -EBUSY;
524 goto error;
525 }
526 galaxy->port = ioport_map(port[n], 16);
527
528 err = galaxy_init(galaxy, &type);
529 if (err < 0) {
530 dev_err(dev, "did not find a Sound Galaxy at %#lx\n", port[n]);
531 goto error;
532 }
533 dev_info(dev, "Sound Galaxy (type %d) found at %#lx\n", type, port[n]);
534
535 galaxy->res_config_port = request_region(port[n] + GALAXY_PORT_CONFIG,
536 16, DRV_NAME);
537 if (!galaxy->res_config_port) {
538 dev_err(dev, "could not grab ports %#lx-%#lx\n",
539 port[n] + GALAXY_PORT_CONFIG,
540 port[n] + GALAXY_PORT_CONFIG + 15);
541 err = -EBUSY;
542 goto error;
543 }
544 galaxy->config_port = ioport_map(port[n] + GALAXY_PORT_CONFIG, 16);
545
546 galaxy_config(galaxy, config[n]);
547
548 galaxy->res_wss_port = request_region(wss_port[n], 4, DRV_NAME);
549 if (!galaxy->res_wss_port) {
550 dev_err(dev, "could not grab ports %#lx-%#lx\n", wss_port[n],
551 wss_port[n] + 3);
552 err = -EBUSY;
553 goto error;
554 }
555 galaxy->wss_port = ioport_map(wss_port[n], 4);
556
557 err = galaxy_wss_config(galaxy, wss_config[n]);
558 if (err < 0) {
559 dev_err(dev, "could not configure WSS\n");
560 goto error;
561 }
562
563 strcpy(card->driver, DRV_NAME);
564 strcpy(card->shortname, DRV_NAME);
565 sprintf(card->longname, "%s at %#lx/%#lx, irq %d, dma %d/%d",
566 card->shortname, port[n], wss_port[n], irq[n], dma1[n],
567 dma2[n]);
568
569 err = snd_wss_create(card, wss_port[n] + 4, -1, irq[n], dma1[n],
570 dma2[n], WSS_HW_DETECT, 0, &chip);
571 if (err < 0)
572 goto error;
573
574 err = snd_wss_pcm(chip, 0, NULL);
575 if (err < 0)
576 goto error;
577
578 err = snd_wss_mixer(chip);
579 if (err < 0)
580 goto error;
581
582 err = snd_wss_timer(chip, 0, NULL);
583 if (err < 0)
584 goto error;
585
586 if (mpu_port[n] >= 0) {
587 err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
588 mpu_port[n], 0, mpu_irq[n],
589 IRQF_DISABLED, NULL);
590 if (err < 0)
591 goto error;
592 }
593
594 if (fm_port[n] >= 0) {
595 struct snd_opl3 *opl3;
596
597 err = snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
598 OPL3_HW_AUTO, 0, &opl3);
599 if (err < 0) {
600 dev_err(dev, "no OPL device at %#lx\n", fm_port[n]);
601 goto error;
602 }
603 err = snd_opl3_timer_new(opl3, 1, 2);
604 if (err < 0)
605 goto error;
606
607 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
608 if (err < 0)
609 goto error;
610 }
611
612 err = snd_card_register(card);
613 if (err < 0)
614 goto error;
615
616 dev_set_drvdata(dev, card);
617 return 0;
618
619error:
620 snd_card_free(card);
621 return err;
622}
623
624static int __devexit snd_galaxy_remove(struct device *dev, unsigned int n)
625{
626 snd_card_free(dev_get_drvdata(dev));
627 dev_set_drvdata(dev, NULL);
628 return 0;
629}
630
631static struct isa_driver snd_galaxy_driver = {
632 .match = snd_galaxy_match,
633 .probe = snd_galaxy_probe,
634 .remove = __devexit_p(snd_galaxy_remove),
635
636 .driver = {
637 .name = DEV_NAME
638 }
639};
640
641static int __init alsa_card_galaxy_init(void)
642{
643 return isa_register_driver(&snd_galaxy_driver, SNDRV_CARDS);
644}
645
646static void __exit alsa_card_galaxy_exit(void)
647{
648 isa_unregister_driver(&snd_galaxy_driver);
649}
650
651module_init(alsa_card_galaxy_init);
652module_exit(alsa_card_galaxy_exit);
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index f26eac8d8110..3e4a58b72913 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -191,7 +191,7 @@ static int __devinit snd_gusmax_mixer(struct snd_wss *chip)
191 191
192static void snd_gusmax_free(struct snd_card *card) 192static void snd_gusmax_free(struct snd_card *card)
193{ 193{
194 struct snd_gusmax *maxcard = (struct snd_gusmax *)card->private_data; 194 struct snd_gusmax *maxcard = card->private_data;
195 195
196 if (maxcard == NULL) 196 if (maxcard == NULL)
197 return; 197 return;
@@ -219,7 +219,7 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev)
219 if (err < 0) 219 if (err < 0)
220 return err; 220 return err;
221 card->private_free = snd_gusmax_free; 221 card->private_free = snd_gusmax_free;
222 maxcard = (struct snd_gusmax *)card->private_data; 222 maxcard = card->private_data;
223 maxcard->card = card; 223 maxcard->card = card;
224 maxcard->irq = -1; 224 maxcard->irq = -1;
225 225
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 81284a8fa0ce..2259e3f726a7 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -72,7 +72,7 @@ static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id)
72 72
73static void snd_sb8_free(struct snd_card *card) 73static void snd_sb8_free(struct snd_card *card)
74{ 74{
75 struct snd_sb8 *acard = (struct snd_sb8 *)card->private_data; 75 struct snd_sb8 *acard = card->private_data;
76 76
77 if (acard == NULL) 77 if (acard == NULL)
78 return; 78 return;
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
deleted file mode 100644
index 6fe27b9d9440..000000000000
--- a/sound/isa/sgalaxy.c
+++ /dev/null
@@ -1,369 +0,0 @@
1/*
2 * Driver for Aztech Sound Galaxy cards
3 * Copyright (c) by Christopher Butler <chrisb@sandy.force9.co.uk.
4 *
5 * I don't have documentation for this card, I based this driver on the
6 * driver for OSS/Free included in the kernel source (drivers/sound/sgalaxy.c)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/init.h>
25#include <linux/err.h>
26#include <linux/isa.h>
27#include <linux/delay.h>
28#include <linux/time.h>
29#include <linux/interrupt.h>
30#include <linux/moduleparam.h>
31#include <asm/dma.h>
32#include <sound/core.h>
33#include <sound/sb.h>
34#include <sound/wss.h>
35#include <sound/control.h>
36#define SNDRV_LEGACY_FIND_FREE_IRQ
37#define SNDRV_LEGACY_FIND_FREE_DMA
38#include <sound/initval.h>
39
40MODULE_AUTHOR("Christopher Butler <chrisb@sandy.force9.co.uk>");
41MODULE_DESCRIPTION("Aztech Sound Galaxy");
42MODULE_LICENSE("GPL");
43MODULE_SUPPORTED_DEVICE("{{Aztech Systems,Sound Galaxy}}");
44
45static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
46static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
47static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
48static long sbport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240 */
49static long wssport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x530,0xe80,0xf40,0x604 */
50static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 7,9,10,11 */
51static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */
52
53module_param_array(index, int, NULL, 0444);
54MODULE_PARM_DESC(index, "Index value for Sound Galaxy soundcard.");
55module_param_array(id, charp, NULL, 0444);
56MODULE_PARM_DESC(id, "ID string for Sound Galaxy soundcard.");
57module_param_array(sbport, long, NULL, 0444);
58MODULE_PARM_DESC(sbport, "Port # for Sound Galaxy SB driver.");
59module_param_array(wssport, long, NULL, 0444);
60MODULE_PARM_DESC(wssport, "Port # for Sound Galaxy WSS driver.");
61module_param_array(irq, int, NULL, 0444);
62MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver.");
63module_param_array(dma1, int, NULL, 0444);
64MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
65
66#define SGALAXY_AUXC_LEFT 18
67#define SGALAXY_AUXC_RIGHT 19
68
69#define PFX "sgalaxy: "
70
71/*
72
73 */
74
75#define AD1848P1( port, x ) ( port + c_d_c_AD1848##x )
76
77/* from lowlevel/sb/sb.c - to avoid having to allocate a struct snd_sb for the */
78/* short time we actually need it.. */
79
80static int snd_sgalaxy_sbdsp_reset(unsigned long port)
81{
82 int i;
83
84 outb(1, SBP1(port, RESET));
85 udelay(10);
86 outb(0, SBP1(port, RESET));
87 udelay(30);
88 for (i = 0; i < 1000 && !(inb(SBP1(port, DATA_AVAIL)) & 0x80); i++);
89 if (inb(SBP1(port, READ)) != 0xaa) {
90 snd_printd("sb_reset: failed at 0x%lx!!!\n", port);
91 return -ENODEV;
92 }
93 return 0;
94}
95
96static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port,
97 unsigned char val)
98{
99 int i;
100
101 for (i = 10000; i; i--)
102 if ((inb(SBP1(port, STATUS)) & 0x80) == 0) {
103 outb(val, SBP1(port, COMMAND));
104 return 1;
105 }
106
107 return 0;
108}
109
110static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id)
111{
112 return IRQ_NONE;
113}
114
115static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma)
116{
117 static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1,
118 0x10, 0x18, 0x20, -1, -1, -1, -1};
119 static int dma_bits[] = {1, 2, 0, 3};
120 int tmp, tmp1;
121
122 if ((tmp = inb(port + 3)) == 0xff)
123 {
124 snd_printdd("I/O address dead (0x%lx)\n", port);
125 return 0;
126 }
127#if 0
128 snd_printdd("WSS signature = 0x%x\n", tmp);
129#endif
130
131 if ((tmp & 0x3f) != 0x04 &&
132 (tmp & 0x3f) != 0x0f &&
133 (tmp & 0x3f) != 0x00) {
134 snd_printdd("No WSS signature detected on port 0x%lx\n",
135 port + 3);
136 return 0;
137 }
138
139#if 0
140 snd_printdd(PFX "setting up IRQ/DMA for WSS\n");
141#endif
142
143 /* initialize IRQ for WSS codec */
144 tmp = interrupt_bits[irq % 16];
145 if (tmp < 0)
146 return -EINVAL;
147
148 if (request_irq(irq, snd_sgalaxy_dummy_interrupt, IRQF_DISABLED, "sgalaxy", NULL)) {
149 snd_printk(KERN_ERR "sgalaxy: can't grab irq %d\n", irq);
150 return -EIO;
151 }
152
153 outb(tmp | 0x40, port);
154 tmp1 = dma_bits[dma % 4];
155 outb(tmp | tmp1, port);
156
157 free_irq(irq, NULL);
158
159 return 0;
160}
161
162static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma)
163{
164#if 0
165 snd_printdd(PFX "switching to WSS mode\n");
166#endif
167
168 /* switch to WSS mode */
169 snd_sgalaxy_sbdsp_reset(sbport[dev]);
170
171 snd_sgalaxy_sbdsp_command(sbport[dev], 9);
172 snd_sgalaxy_sbdsp_command(sbport[dev], 0);
173
174 udelay(400);
175 return snd_sgalaxy_setup_wss(wssport[dev], irq, dma);
176}
177
178static struct snd_kcontrol_new snd_sgalaxy_controls[] = {
179WSS_DOUBLE("Aux Playback Switch", 0,
180 SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7, 7, 1, 1),
181WSS_DOUBLE("Aux Playback Volume", 0,
182 SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
183};
184
185static int __devinit snd_sgalaxy_mixer(struct snd_wss *chip)
186{
187 struct snd_card *card = chip->card;
188 struct snd_ctl_elem_id id1, id2;
189 unsigned int idx;
190 int err;
191
192 memset(&id1, 0, sizeof(id1));
193 memset(&id2, 0, sizeof(id2));
194 id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
195 /* reassign AUX0 to LINE */
196 strcpy(id1.name, "Aux Playback Switch");
197 strcpy(id2.name, "Line Playback Switch");
198 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
199 return err;
200 strcpy(id1.name, "Aux Playback Volume");
201 strcpy(id2.name, "Line Playback Volume");
202 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
203 return err;
204 /* reassign AUX1 to FM */
205 strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
206 strcpy(id2.name, "FM Playback Switch");
207 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
208 return err;
209 strcpy(id1.name, "Aux Playback Volume");
210 strcpy(id2.name, "FM Playback Volume");
211 if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
212 return err;
213 /* build AUX2 input */
214 for (idx = 0; idx < ARRAY_SIZE(snd_sgalaxy_controls); idx++) {
215 err = snd_ctl_add(card,
216 snd_ctl_new1(&snd_sgalaxy_controls[idx], chip));
217 if (err < 0)
218 return err;
219 }
220 return 0;
221}
222
223static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev)
224{
225 if (!enable[dev])
226 return 0;
227 if (sbport[dev] == SNDRV_AUTO_PORT) {
228 snd_printk(KERN_ERR PFX "specify SB port\n");
229 return 0;
230 }
231 if (wssport[dev] == SNDRV_AUTO_PORT) {
232 snd_printk(KERN_ERR PFX "specify WSS port\n");
233 return 0;
234 }
235 return 1;
236}
237
238static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev)
239{
240 static int possible_irqs[] = {7, 9, 10, 11, -1};
241 static int possible_dmas[] = {1, 3, 0, -1};
242 int err, xirq, xdma1;
243 struct snd_card *card;
244 struct snd_wss *chip;
245
246 err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
247 if (err < 0)
248 return err;
249
250 xirq = irq[dev];
251 if (xirq == SNDRV_AUTO_IRQ) {
252 if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
253 snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
254 err = -EBUSY;
255 goto _err;
256 }
257 }
258 xdma1 = dma1[dev];
259 if (xdma1 == SNDRV_AUTO_DMA) {
260 if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
261 snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
262 err = -EBUSY;
263 goto _err;
264 }
265 }
266
267 if ((err = snd_sgalaxy_detect(dev, xirq, xdma1)) < 0)
268 goto _err;
269
270 err = snd_wss_create(card, wssport[dev] + 4, -1,
271 xirq, xdma1, -1,
272 WSS_HW_DETECT, 0, &chip);
273 if (err < 0)
274 goto _err;
275 card->private_data = chip;
276
277 err = snd_wss_pcm(chip, 0, NULL);
278 if (err < 0) {
279 snd_printdd(PFX "error creating new WSS PCM device\n");
280 goto _err;
281 }
282 err = snd_wss_mixer(chip);
283 if (err < 0) {
284 snd_printdd(PFX "error creating new WSS mixer\n");
285 goto _err;
286 }
287 if ((err = snd_sgalaxy_mixer(chip)) < 0) {
288 snd_printdd(PFX "the mixer rewrite failed\n");
289 goto _err;
290 }
291
292 strcpy(card->driver, "Sound Galaxy");
293 strcpy(card->shortname, "Sound Galaxy");
294 sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
295 wssport[dev], xirq, xdma1);
296
297 snd_card_set_dev(card, devptr);
298
299 if ((err = snd_card_register(card)) < 0)
300 goto _err;
301
302 dev_set_drvdata(devptr, card);
303 return 0;
304
305 _err:
306 snd_card_free(card);
307 return err;
308}
309
310static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev)
311{
312 snd_card_free(dev_get_drvdata(devptr));
313 dev_set_drvdata(devptr, NULL);
314 return 0;
315}
316
317#ifdef CONFIG_PM
318static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n,
319 pm_message_t state)
320{
321 struct snd_card *card = dev_get_drvdata(pdev);
322 struct snd_wss *chip = card->private_data;
323
324 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
325 chip->suspend(chip);
326 return 0;
327}
328
329static int snd_sgalaxy_resume(struct device *pdev, unsigned int n)
330{
331 struct snd_card *card = dev_get_drvdata(pdev);
332 struct snd_wss *chip = card->private_data;
333
334 chip->resume(chip);
335 snd_wss_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]);
336 snd_wss_out(chip, SGALAXY_AUXC_RIGHT, chip->image[SGALAXY_AUXC_RIGHT]);
337
338 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
339 return 0;
340}
341#endif
342
343#define DEV_NAME "sgalaxy"
344
345static struct isa_driver snd_sgalaxy_driver = {
346 .match = snd_sgalaxy_match,
347 .probe = snd_sgalaxy_probe,
348 .remove = __devexit_p(snd_sgalaxy_remove),
349#ifdef CONFIG_PM
350 .suspend = snd_sgalaxy_suspend,
351 .resume = snd_sgalaxy_resume,
352#endif
353 .driver = {
354 .name = DEV_NAME
355 },
356};
357
358static int __init alsa_card_sgalaxy_init(void)
359{
360 return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS);
361}
362
363static void __exit alsa_card_sgalaxy_exit(void)
364{
365 isa_unregister_driver(&snd_sgalaxy_driver);
366}
367
368module_init(alsa_card_sgalaxy_init)
369module_exit(alsa_card_sgalaxy_exit)
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index a513651fa149..76c090218073 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -545,11 +545,3 @@ config SOUND_KAHLUA
545 545
546endif # SOUND_OSS 546endif # SOUND_OSS
547 547
548config SOUND_SH_DAC_AUDIO
549 tristate "SuperH DAC audio support"
550 depends on CPU_SH3 && HIGH_RES_TIMERS
551
552config SOUND_SH_DAC_AUDIO_CHANNEL
553 int "DAC channel"
554 default "1"
555 depends on SOUND_SH_DAC_AUDIO
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
index 567b8a74178a..96f14dcd0cd1 100644
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_SOUND_OSS) += sound.o
9 9
10# Please leave it as is, cause the link order is significant ! 10# Please leave it as is, cause the link order is significant !
11 11
12obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o
13obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o 12obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o
14obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o 13obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
15obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o 14obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index c6f2621221ba..a8f626d99c5b 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -43,7 +43,6 @@
43#include <linux/sound.h> 43#include <linux/sound.h>
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/soundcard.h> 45#include <linux/soundcard.h>
46#include <linux/smp_lock.h>
47#include <linux/init.h> 46#include <linux/init.h>
48#include <linux/interrupt.h> 47#include <linux/interrupt.h>
49#include <linux/kernel.h> 48#include <linux/kernel.h>
@@ -77,6 +76,7 @@
77/* Boot options 76/* Boot options
78 * 0 = no VRA, 1 = use VRA if codec supports it 77 * 0 = no VRA, 1 = use VRA if codec supports it
79 */ 78 */
79static DEFINE_MUTEX(au1550_ac97_mutex);
80static int vra = 1; 80static int vra = 1;
81module_param(vra, bool, 0); 81module_param(vra, bool, 0);
82MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it"); 82MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
@@ -171,7 +171,7 @@ au1550_delay(int msec)
171static u16 171static u16
172rdcodec(struct ac97_codec *codec, u8 addr) 172rdcodec(struct ac97_codec *codec, u8 addr)
173{ 173{
174 struct au1550_state *s = (struct au1550_state *)codec->private_data; 174 struct au1550_state *s = codec->private_data;
175 unsigned long flags; 175 unsigned long flags;
176 u32 cmd, val; 176 u32 cmd, val;
177 u16 data; 177 u16 data;
@@ -239,7 +239,7 @@ rdcodec(struct ac97_codec *codec, u8 addr)
239static void 239static void
240wrcodec(struct ac97_codec *codec, u8 addr, u16 data) 240wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
241{ 241{
242 struct au1550_state *s = (struct au1550_state *)codec->private_data; 242 struct au1550_state *s = codec->private_data;
243 unsigned long flags; 243 unsigned long flags;
244 u32 cmd, val; 244 u32 cmd, val;
245 int i; 245 int i;
@@ -798,9 +798,9 @@ au1550_llseek(struct file *file, loff_t offset, int origin)
798static int 798static int
799au1550_open_mixdev(struct inode *inode, struct file *file) 799au1550_open_mixdev(struct inode *inode, struct file *file)
800{ 800{
801 lock_kernel(); 801 mutex_lock(&au1550_ac97_mutex);
802 file->private_data = &au1550_state; 802 file->private_data = &au1550_state;
803 unlock_kernel(); 803 mutex_unlock(&au1550_ac97_mutex);
804 return 0; 804 return 0;
805} 805}
806 806
@@ -820,13 +820,13 @@ mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
820static long 820static long
821au1550_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg) 821au1550_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg)
822{ 822{
823 struct au1550_state *s = (struct au1550_state *)file->private_data; 823 struct au1550_state *s = file->private_data;
824 struct ac97_codec *codec = s->codec; 824 struct ac97_codec *codec = s->codec;
825 int ret; 825 int ret;
826 826
827 lock_kernel(); 827 mutex_lock(&au1550_ac97_mutex);
828 ret = mixdev_ioctl(codec, cmd, arg); 828 ret = mixdev_ioctl(codec, cmd, arg);
829 unlock_kernel(); 829 mutex_unlock(&au1550_ac97_mutex);
830 830
831 return ret; 831 return ret;
832} 832}
@@ -1031,7 +1031,7 @@ copy_dmabuf_user(struct dmabuf *db, char* userbuf, int count, int to_user)
1031static ssize_t 1031static ssize_t
1032au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos) 1032au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
1033{ 1033{
1034 struct au1550_state *s = (struct au1550_state *)file->private_data; 1034 struct au1550_state *s = file->private_data;
1035 struct dmabuf *db = &s->dma_adc; 1035 struct dmabuf *db = &s->dma_adc;
1036 DECLARE_WAITQUEUE(wait, current); 1036 DECLARE_WAITQUEUE(wait, current);
1037 ssize_t ret; 1037 ssize_t ret;
@@ -1111,7 +1111,7 @@ out2:
1111static ssize_t 1111static ssize_t
1112au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) 1112au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
1113{ 1113{
1114 struct au1550_state *s = (struct au1550_state *)file->private_data; 1114 struct au1550_state *s = file->private_data;
1115 struct dmabuf *db = &s->dma_dac; 1115 struct dmabuf *db = &s->dma_dac;
1116 DECLARE_WAITQUEUE(wait, current); 1116 DECLARE_WAITQUEUE(wait, current);
1117 ssize_t ret = 0; 1117 ssize_t ret = 0;
@@ -1211,7 +1211,7 @@ out2:
1211static unsigned int 1211static unsigned int
1212au1550_poll(struct file *file, struct poll_table_struct *wait) 1212au1550_poll(struct file *file, struct poll_table_struct *wait)
1213{ 1213{
1214 struct au1550_state *s = (struct au1550_state *)file->private_data; 1214 struct au1550_state *s = file->private_data;
1215 unsigned long flags; 1215 unsigned long flags;
1216 unsigned int mask = 0; 1216 unsigned int mask = 0;
1217 1217
@@ -1250,12 +1250,12 @@ au1550_poll(struct file *file, struct poll_table_struct *wait)
1250static int 1250static int
1251au1550_mmap(struct file *file, struct vm_area_struct *vma) 1251au1550_mmap(struct file *file, struct vm_area_struct *vma)
1252{ 1252{
1253 struct au1550_state *s = (struct au1550_state *)file->private_data; 1253 struct au1550_state *s = file->private_data;
1254 struct dmabuf *db; 1254 struct dmabuf *db;
1255 unsigned long size; 1255 unsigned long size;
1256 int ret = 0; 1256 int ret = 0;
1257 1257
1258 lock_kernel(); 1258 mutex_lock(&au1550_ac97_mutex);
1259 mutex_lock(&s->sem); 1259 mutex_lock(&s->sem);
1260 if (vma->vm_flags & VM_WRITE) 1260 if (vma->vm_flags & VM_WRITE)
1261 db = &s->dma_dac; 1261 db = &s->dma_dac;
@@ -1283,7 +1283,7 @@ au1550_mmap(struct file *file, struct vm_area_struct *vma)
1283 db->mapped = 1; 1283 db->mapped = 1;
1284out: 1284out:
1285 mutex_unlock(&s->sem); 1285 mutex_unlock(&s->sem);
1286 unlock_kernel(); 1286 mutex_unlock(&au1550_ac97_mutex);
1287 return ret; 1287 return ret;
1288} 1288}
1289 1289
@@ -1342,7 +1342,7 @@ dma_count_done(struct dmabuf *db)
1342static int 1342static int
1343au1550_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1343au1550_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1344{ 1344{
1345 struct au1550_state *s = (struct au1550_state *)file->private_data; 1345 struct au1550_state *s = file->private_data;
1346 unsigned long flags; 1346 unsigned long flags;
1347 audio_buf_info abinfo; 1347 audio_buf_info abinfo;
1348 count_info cinfo; 1348 count_info cinfo;
@@ -1781,9 +1781,9 @@ au1550_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1781{ 1781{
1782 int ret; 1782 int ret;
1783 1783
1784 lock_kernel(); 1784 mutex_lock(&au1550_ac97_mutex);
1785 ret = au1550_ioctl(file, cmd, arg); 1785 ret = au1550_ioctl(file, cmd, arg);
1786 unlock_kernel(); 1786 mutex_unlock(&au1550_ac97_mutex);
1787 1787
1788 return ret; 1788 return ret;
1789} 1789}
@@ -1804,7 +1804,7 @@ au1550_open(struct inode *inode, struct file *file)
1804#endif 1804#endif
1805 1805
1806 file->private_data = s; 1806 file->private_data = s;
1807 lock_kernel(); 1807 mutex_lock(&au1550_ac97_mutex);
1808 /* wait for device to become free */ 1808 /* wait for device to become free */
1809 mutex_lock(&s->open_mutex); 1809 mutex_lock(&s->open_mutex);
1810 while (s->open_mode & file->f_mode) { 1810 while (s->open_mode & file->f_mode) {
@@ -1861,21 +1861,21 @@ au1550_open(struct inode *inode, struct file *file)
1861out: 1861out:
1862 mutex_unlock(&s->open_mutex); 1862 mutex_unlock(&s->open_mutex);
1863out2: 1863out2:
1864 unlock_kernel(); 1864 mutex_unlock(&au1550_ac97_mutex);
1865 return ret; 1865 return ret;
1866} 1866}
1867 1867
1868static int 1868static int
1869au1550_release(struct inode *inode, struct file *file) 1869au1550_release(struct inode *inode, struct file *file)
1870{ 1870{
1871 struct au1550_state *s = (struct au1550_state *)file->private_data; 1871 struct au1550_state *s = file->private_data;
1872 1872
1873 lock_kernel(); 1873 mutex_lock(&au1550_ac97_mutex);
1874 1874
1875 if (file->f_mode & FMODE_WRITE) { 1875 if (file->f_mode & FMODE_WRITE) {
1876 unlock_kernel(); 1876 mutex_unlock(&au1550_ac97_mutex);
1877 drain_dac(s, file->f_flags & O_NONBLOCK); 1877 drain_dac(s, file->f_flags & O_NONBLOCK);
1878 lock_kernel(); 1878 mutex_lock(&au1550_ac97_mutex);
1879 } 1879 }
1880 1880
1881 mutex_lock(&s->open_mutex); 1881 mutex_lock(&s->open_mutex);
@@ -1892,7 +1892,7 @@ au1550_release(struct inode *inode, struct file *file)
1892 s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE)); 1892 s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
1893 mutex_unlock(&s->open_mutex); 1893 mutex_unlock(&s->open_mutex);
1894 wake_up(&s->open_wait); 1894 wake_up(&s->open_wait);
1895 unlock_kernel(); 1895 mutex_unlock(&au1550_ac97_mutex);
1896 return 0; 1896 return 0;
1897} 1897}
1898 1898
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index 6ecd41abb066..87e2c72651f5 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -181,7 +181,7 @@
181#include <linux/init.h> 181#include <linux/init.h>
182#include <linux/soundcard.h> 182#include <linux/soundcard.h>
183#include <linux/poll.h> 183#include <linux/poll.h>
184#include <linux/smp_lock.h> 184#include <linux/mutex.h>
185 185
186#include <asm/uaccess.h> 186#include <asm/uaccess.h>
187 187
@@ -194,6 +194,7 @@
194 * Declarations 194 * Declarations
195 */ 195 */
196 196
197static DEFINE_MUTEX(dmasound_core_mutex);
197int dmasound_catchRadius = 0; 198int dmasound_catchRadius = 0;
198module_param(dmasound_catchRadius, int, 0); 199module_param(dmasound_catchRadius, int, 0);
199 200
@@ -323,22 +324,22 @@ static struct {
323 324
324static int mixer_open(struct inode *inode, struct file *file) 325static int mixer_open(struct inode *inode, struct file *file)
325{ 326{
326 lock_kernel(); 327 mutex_lock(&dmasound_core_mutex);
327 if (!try_module_get(dmasound.mach.owner)) { 328 if (!try_module_get(dmasound.mach.owner)) {
328 unlock_kernel(); 329 mutex_unlock(&dmasound_core_mutex);
329 return -ENODEV; 330 return -ENODEV;
330 } 331 }
331 mixer.busy = 1; 332 mixer.busy = 1;
332 unlock_kernel(); 333 mutex_unlock(&dmasound_core_mutex);
333 return 0; 334 return 0;
334} 335}
335 336
336static int mixer_release(struct inode *inode, struct file *file) 337static int mixer_release(struct inode *inode, struct file *file)
337{ 338{
338 lock_kernel(); 339 mutex_lock(&dmasound_core_mutex);
339 mixer.busy = 0; 340 mixer.busy = 0;
340 module_put(dmasound.mach.owner); 341 module_put(dmasound.mach.owner);
341 unlock_kernel(); 342 mutex_unlock(&dmasound_core_mutex);
342 return 0; 343 return 0;
343} 344}
344 345
@@ -370,9 +371,9 @@ static long mixer_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
370{ 371{
371 int ret; 372 int ret;
372 373
373 lock_kernel(); 374 mutex_lock(&dmasound_core_mutex);
374 ret = mixer_ioctl(file, cmd, arg); 375 ret = mixer_ioctl(file, cmd, arg);
375 unlock_kernel(); 376 mutex_unlock(&dmasound_core_mutex);
376 377
377 return ret; 378 return ret;
378} 379}
@@ -752,9 +753,9 @@ static int sq_open(struct inode *inode, struct file *file)
752{ 753{
753 int rc; 754 int rc;
754 755
755 lock_kernel(); 756 mutex_lock(&dmasound_core_mutex);
756 if (!try_module_get(dmasound.mach.owner)) { 757 if (!try_module_get(dmasound.mach.owner)) {
757 unlock_kernel(); 758 mutex_unlock(&dmasound_core_mutex);
758 return -ENODEV; 759 return -ENODEV;
759 } 760 }
760 761
@@ -799,11 +800,11 @@ static int sq_open(struct inode *inode, struct file *file)
799 sound_set_format(AFMT_MU_LAW); 800 sound_set_format(AFMT_MU_LAW);
800 } 801 }
801#endif 802#endif
802 unlock_kernel(); 803 mutex_unlock(&dmasound_core_mutex);
803 return 0; 804 return 0;
804 out: 805 out:
805 module_put(dmasound.mach.owner); 806 module_put(dmasound.mach.owner);
806 unlock_kernel(); 807 mutex_unlock(&dmasound_core_mutex);
807 return rc; 808 return rc;
808} 809}
809 810
@@ -869,7 +870,7 @@ static int sq_release(struct inode *inode, struct file *file)
869{ 870{
870 int rc = 0; 871 int rc = 0;
871 872
872 lock_kernel(); 873 mutex_lock(&dmasound_core_mutex);
873 874
874 if (file->f_mode & FMODE_WRITE) { 875 if (file->f_mode & FMODE_WRITE) {
875 if (write_sq.busy) 876 if (write_sq.busy)
@@ -900,7 +901,7 @@ static int sq_release(struct inode *inode, struct file *file)
900 write_sq_wake_up(file); /* checks f_mode */ 901 write_sq_wake_up(file); /* checks f_mode */
901#endif /* blocking open() */ 902#endif /* blocking open() */
902 903
903 unlock_kernel(); 904 mutex_unlock(&dmasound_core_mutex);
904 905
905 return rc; 906 return rc;
906} 907}
@@ -1141,9 +1142,9 @@ static long sq_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
1141{ 1142{
1142 int ret; 1143 int ret;
1143 1144
1144 lock_kernel(); 1145 mutex_lock(&dmasound_core_mutex);
1145 ret = sq_ioctl(file, cmd, arg); 1146 ret = sq_ioctl(file, cmd, arg);
1146 unlock_kernel(); 1147 mutex_unlock(&dmasound_core_mutex);
1147 1148
1148 return ret; 1149 return ret;
1149} 1150}
@@ -1257,7 +1258,7 @@ static int state_open(struct inode *inode, struct file *file)
1257 int len = 0; 1258 int len = 0;
1258 int ret; 1259 int ret;
1259 1260
1260 lock_kernel(); 1261 mutex_lock(&dmasound_core_mutex);
1261 ret = -EBUSY; 1262 ret = -EBUSY;
1262 if (state.busy) 1263 if (state.busy)
1263 goto out; 1264 goto out;
@@ -1329,16 +1330,16 @@ printk("dmasound: stat buffer used %d bytes\n", len) ;
1329 state.len = len; 1330 state.len = len;
1330 ret = 0; 1331 ret = 0;
1331out: 1332out:
1332 unlock_kernel(); 1333 mutex_unlock(&dmasound_core_mutex);
1333 return ret; 1334 return ret;
1334} 1335}
1335 1336
1336static int state_release(struct inode *inode, struct file *file) 1337static int state_release(struct inode *inode, struct file *file)
1337{ 1338{
1338 lock_kernel(); 1339 mutex_lock(&dmasound_core_mutex);
1339 state.busy = 0; 1340 state.busy = 0;
1340 module_put(dmasound.mach.owner); 1341 module_put(dmasound.mach.owner);
1341 unlock_kernel(); 1342 mutex_unlock(&dmasound_core_mutex);
1342 return 0; 1343 return 0;
1343} 1344}
1344 1345
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c
index 2e48b17667d0..b4c1eb504c22 100644
--- a/sound/oss/msnd_pinnacle.c
+++ b/sound/oss/msnd_pinnacle.c
@@ -39,7 +39,7 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/smp_lock.h> 42#include <linux/mutex.h>
43#include <linux/gfp.h> 43#include <linux/gfp.h>
44#include <asm/irq.h> 44#include <asm/irq.h>
45#include <asm/io.h> 45#include <asm/io.h>
@@ -79,6 +79,7 @@
79 dev.rec_sample_rate / \ 79 dev.rec_sample_rate / \
80 dev.rec_channels) 80 dev.rec_channels)
81 81
82static DEFINE_MUTEX(msnd_pinnacle_mutex);
82static multisound_dev_t dev; 83static multisound_dev_t dev;
83 84
84#ifndef HAVE_DSPCODEH 85#ifndef HAVE_DSPCODEH
@@ -651,12 +652,12 @@ static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
651 652
652 ret = -EINVAL; 653 ret = -EINVAL;
653 654
654 lock_kernel(); 655 mutex_lock(&msnd_pinnacle_mutex);
655 if (minor == dev.dsp_minor) 656 if (minor == dev.dsp_minor)
656 ret = dsp_ioctl(file, cmd, arg); 657 ret = dsp_ioctl(file, cmd, arg);
657 else if (minor == dev.mixer_minor) 658 else if (minor == dev.mixer_minor)
658 ret = mixer_ioctl(cmd, arg); 659 ret = mixer_ioctl(cmd, arg);
659 unlock_kernel(); 660 mutex_unlock(&msnd_pinnacle_mutex);
660 661
661 return ret; 662 return ret;
662} 663}
@@ -761,7 +762,7 @@ static int dev_open(struct inode *inode, struct file *file)
761 int minor = iminor(inode); 762 int minor = iminor(inode);
762 int err = 0; 763 int err = 0;
763 764
764 lock_kernel(); 765 mutex_lock(&msnd_pinnacle_mutex);
765 if (minor == dev.dsp_minor) { 766 if (minor == dev.dsp_minor) {
766 if ((file->f_mode & FMODE_WRITE && 767 if ((file->f_mode & FMODE_WRITE &&
767 test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) || 768 test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) ||
@@ -791,7 +792,7 @@ static int dev_open(struct inode *inode, struct file *file)
791 } else 792 } else
792 err = -EINVAL; 793 err = -EINVAL;
793out: 794out:
794 unlock_kernel(); 795 mutex_unlock(&msnd_pinnacle_mutex);
795 return err; 796 return err;
796} 797}
797 798
@@ -800,14 +801,14 @@ static int dev_release(struct inode *inode, struct file *file)
800 int minor = iminor(inode); 801 int minor = iminor(inode);
801 int err = 0; 802 int err = 0;
802 803
803 lock_kernel(); 804 mutex_lock(&msnd_pinnacle_mutex);
804 if (minor == dev.dsp_minor) 805 if (minor == dev.dsp_minor)
805 err = dsp_release(file); 806 err = dsp_release(file);
806 else if (minor == dev.mixer_minor) { 807 else if (minor == dev.mixer_minor) {
807 /* nothing */ 808 /* nothing */
808 } else 809 } else
809 err = -EINVAL; 810 err = -EINVAL;
810 unlock_kernel(); 811 mutex_unlock(&msnd_pinnacle_mutex);
811 return err; 812 return err;
812} 813}
813 814
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
deleted file mode 100644
index 479e3025a8a3..000000000000
--- a/sound/oss/sh_dac_audio.c
+++ /dev/null
@@ -1,325 +0,0 @@
1/*
2 * sound/oss/sh_dac_audio.c
3 *
4 * SH DAC based sound :(
5 *
6 * Copyright (C) 2004,2005 Andriy Skulysh
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/sched.h>
15#include <linux/linkage.h>
16#include <linux/slab.h>
17#include <linux/fs.h>
18#include <linux/sound.h>
19#include <linux/smp_lock.h>
20#include <linux/soundcard.h>
21#include <linux/interrupt.h>
22#include <linux/hrtimer.h>
23#include <asm/io.h>
24#include <asm/uaccess.h>
25#include <asm/irq.h>
26#include <asm/delay.h>
27#include <asm/clock.h>
28#include <cpu/dac.h>
29#include <asm/machvec.h>
30#include <mach/hp6xx.h>
31#include <asm/hd64461.h>
32
33#define MODNAME "sh_dac_audio"
34
35#define BUFFER_SIZE 48000
36
37static int rate;
38static int empty;
39static char *data_buffer, *buffer_begin, *buffer_end;
40static int in_use, device_major;
41static struct hrtimer hrtimer;
42static ktime_t wakeups_per_second;
43
44static void dac_audio_start_timer(void)
45{
46 hrtimer_start(&hrtimer, wakeups_per_second, HRTIMER_MODE_REL);
47}
48
49static void dac_audio_stop_timer(void)
50{
51 hrtimer_cancel(&hrtimer);
52}
53
54static void dac_audio_reset(void)
55{
56 dac_audio_stop_timer();
57 buffer_begin = buffer_end = data_buffer;
58 empty = 1;
59}
60
61static void dac_audio_sync(void)
62{
63 while (!empty)
64 schedule();
65}
66
67static void dac_audio_start(void)
68{
69 if (mach_is_hp6xx()) {
70 u16 v = __raw_readw(HD64461_GPADR);
71 v &= ~HD64461_GPADR_SPEAKER;
72 __raw_writew(v, HD64461_GPADR);
73 }
74
75 sh_dac_enable(CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL);
76}
77static void dac_audio_stop(void)
78{
79 dac_audio_stop_timer();
80
81 if (mach_is_hp6xx()) {
82 u16 v = __raw_readw(HD64461_GPADR);
83 v |= HD64461_GPADR_SPEAKER;
84 __raw_writew(v, HD64461_GPADR);
85 }
86
87 sh_dac_output(0, CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL);
88 sh_dac_disable(CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL);
89}
90
91static void dac_audio_set_rate(void)
92{
93 wakeups_per_second = ktime_set(0, 1000000000 / rate);
94}
95
96static int dac_audio_ioctl(struct file *file,
97 unsigned int cmd, unsigned long arg)
98{
99 int val;
100
101 switch (cmd) {
102 case OSS_GETVERSION:
103 return put_user(SOUND_VERSION, (int *)arg);
104
105 case SNDCTL_DSP_SYNC:
106 dac_audio_sync();
107 return 0;
108
109 case SNDCTL_DSP_RESET:
110 dac_audio_reset();
111 return 0;
112
113 case SNDCTL_DSP_GETFMTS:
114 return put_user(AFMT_U8, (int *)arg);
115
116 case SNDCTL_DSP_SETFMT:
117 return put_user(AFMT_U8, (int *)arg);
118
119 case SNDCTL_DSP_NONBLOCK:
120 spin_lock(&file->f_lock);
121 file->f_flags |= O_NONBLOCK;
122 spin_unlock(&file->f_lock);
123 return 0;
124
125 case SNDCTL_DSP_GETCAPS:
126 return 0;
127
128 case SOUND_PCM_WRITE_RATE:
129 val = *(int *)arg;
130 if (val > 0) {
131 rate = val;
132 dac_audio_set_rate();
133 }
134 return put_user(rate, (int *)arg);
135
136 case SNDCTL_DSP_STEREO:
137 return put_user(0, (int *)arg);
138
139 case SOUND_PCM_WRITE_CHANNELS:
140 return put_user(1, (int *)arg);
141
142 case SNDCTL_DSP_SETDUPLEX:
143 return -EINVAL;
144
145 case SNDCTL_DSP_PROFILE:
146 return -EINVAL;
147
148 case SNDCTL_DSP_GETBLKSIZE:
149 return put_user(BUFFER_SIZE, (int *)arg);
150
151 case SNDCTL_DSP_SETFRAGMENT:
152 return 0;
153
154 default:
155 printk(KERN_ERR "sh_dac_audio: unimplemented ioctl=0x%x\n",
156 cmd);
157 return -EINVAL;
158 }
159 return -EINVAL;
160}
161
162static long dac_audio_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
163{
164 int ret;
165
166 lock_kernel();
167 ret = dac_audio_ioctl(file, cmd, arg);
168 unlock_kernel();
169
170 return ret;
171}
172
173static ssize_t dac_audio_write(struct file *file, const char *buf, size_t count,
174 loff_t * ppos)
175{
176 int free;
177 int nbytes;
178
179 if (!count) {
180 dac_audio_sync();
181 return 0;
182 }
183
184 free = buffer_begin - buffer_end;
185
186 if (free < 0)
187 free += BUFFER_SIZE;
188 if ((free == 0) && (empty))
189 free = BUFFER_SIZE;
190 if (count > free)
191 count = free;
192 if (buffer_begin > buffer_end) {
193 if (copy_from_user((void *)buffer_end, buf, count))
194 return -EFAULT;
195
196 buffer_end += count;
197 } else {
198 nbytes = data_buffer + BUFFER_SIZE - buffer_end;
199 if (nbytes > count) {
200 if (copy_from_user((void *)buffer_end, buf, count))
201 return -EFAULT;
202 buffer_end += count;
203 } else {
204 if (copy_from_user((void *)buffer_end, buf, nbytes))
205 return -EFAULT;
206 if (copy_from_user
207 ((void *)data_buffer, buf + nbytes, count - nbytes))
208 return -EFAULT;
209 buffer_end = data_buffer + count - nbytes;
210 }
211 }
212
213 if (empty) {
214 empty = 0;
215 dac_audio_start_timer();
216 }
217
218 return count;
219}
220
221static ssize_t dac_audio_read(struct file *file, char *buf, size_t count,
222 loff_t * ppos)
223{
224 return -EINVAL;
225}
226
227static int dac_audio_open(struct inode *inode, struct file *file)
228{
229 if (file->f_mode & FMODE_READ)
230 return -ENODEV;
231
232 lock_kernel();
233 if (in_use) {
234 unlock_kernel();
235 return -EBUSY;
236 }
237
238 in_use = 1;
239
240 dac_audio_start();
241 unlock_kernel();
242 return 0;
243}
244
245static int dac_audio_release(struct inode *inode, struct file *file)
246{
247 dac_audio_sync();
248 dac_audio_stop();
249 in_use = 0;
250
251 return 0;
252}
253
254const struct file_operations dac_audio_fops = {
255 .read = dac_audio_read,
256 .write = dac_audio_write,
257 .unlocked_ioctl = dac_audio_unlocked_ioctl,
258 .open = dac_audio_open,
259 .release = dac_audio_release,
260};
261
262static enum hrtimer_restart sh_dac_audio_timer(struct hrtimer *handle)
263{
264 if (!empty) {
265 sh_dac_output(*buffer_begin, CONFIG_SOUND_SH_DAC_AUDIO_CHANNEL);
266 buffer_begin++;
267
268 if (buffer_begin == data_buffer + BUFFER_SIZE)
269 buffer_begin = data_buffer;
270 if (buffer_begin == buffer_end)
271 empty = 1;
272 }
273
274 if (!empty)
275 hrtimer_start(&hrtimer, wakeups_per_second, HRTIMER_MODE_REL);
276
277 return HRTIMER_NORESTART;
278}
279
280static int __init dac_audio_init(void)
281{
282 if ((device_major = register_sound_dsp(&dac_audio_fops, -1)) < 0) {
283 printk(KERN_ERR "Cannot register dsp device");
284 return device_major;
285 }
286
287 in_use = 0;
288
289 data_buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
290 if (data_buffer == NULL)
291 return -ENOMEM;
292
293 dac_audio_reset();
294 rate = 8000;
295 dac_audio_set_rate();
296
297 /* Today: High Resolution Timer driven DAC playback.
298 * The timer callback gets called once per sample. Ouch.
299 *
300 * Future: A much better approach would be to use the
301 * SH7720 CMT+DMAC+DAC hardware combination like this:
302 * - Program sample rate using CMT0 or CMT1
303 * - Program DMAC to use CMT for timing and output to DAC
304 * - Play sound using DMAC, let CPU sleep.
305 * - While at it, rewrite this driver to use ALSA.
306 */
307
308 hrtimer_init(&hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
309 hrtimer.function = sh_dac_audio_timer;
310
311 return 0;
312}
313
314static void __exit dac_audio_exit(void)
315{
316 unregister_sound_dsp(device_major);
317 kfree((void *)data_buffer);
318}
319
320module_init(dac_audio_init);
321module_exit(dac_audio_exit);
322
323MODULE_AUTHOR("Andriy Skulysh, askulysh@image.kiev.ua");
324MODULE_DESCRIPTION("SH DAC sound driver");
325MODULE_LICENSE("GPL");
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 07f803e6d203..46c0d03dbecc 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -40,7 +40,7 @@
40#include <linux/major.h> 40#include <linux/major.h>
41#include <linux/delay.h> 41#include <linux/delay.h>
42#include <linux/proc_fs.h> 42#include <linux/proc_fs.h>
43#include <linux/smp_lock.h> 43#include <linux/mutex.h>
44#include <linux/module.h> 44#include <linux/module.h>
45#include <linux/mm.h> 45#include <linux/mm.h>
46#include <linux/device.h> 46#include <linux/device.h>
@@ -56,6 +56,7 @@
56 * Table for permanently allocated memory (used when unloading the module) 56 * Table for permanently allocated memory (used when unloading the module)
57 */ 57 */
58void * sound_mem_blocks[MAX_MEM_BLOCKS]; 58void * sound_mem_blocks[MAX_MEM_BLOCKS];
59static DEFINE_MUTEX(soundcard_mutex);
59int sound_nblocks = 0; 60int sound_nblocks = 0;
60 61
61/* Persistent DMA buffers */ 62/* Persistent DMA buffers */
@@ -151,7 +152,7 @@ static ssize_t sound_read(struct file *file, char __user *buf, size_t count, lof
151 * big one anyway, we might as well bandage here.. 152 * big one anyway, we might as well bandage here..
152 */ 153 */
153 154
154 lock_kernel(); 155 mutex_lock(&soundcard_mutex);
155 156
156 DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count)); 157 DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
157 switch (dev & 0x0f) { 158 switch (dev & 0x0f) {
@@ -169,7 +170,7 @@ static ssize_t sound_read(struct file *file, char __user *buf, size_t count, lof
169 case SND_DEV_MIDIN: 170 case SND_DEV_MIDIN:
170 ret = MIDIbuf_read(dev, file, buf, count); 171 ret = MIDIbuf_read(dev, file, buf, count);
171 } 172 }
172 unlock_kernel(); 173 mutex_unlock(&soundcard_mutex);
173 return ret; 174 return ret;
174} 175}
175 176
@@ -178,7 +179,7 @@ static ssize_t sound_write(struct file *file, const char __user *buf, size_t cou
178 int dev = iminor(file->f_path.dentry->d_inode); 179 int dev = iminor(file->f_path.dentry->d_inode);
179 int ret = -EINVAL; 180 int ret = -EINVAL;
180 181
181 lock_kernel(); 182 mutex_lock(&soundcard_mutex);
182 DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count)); 183 DEB(printk("sound_write(dev=%d, count=%d)\n", dev, count));
183 switch (dev & 0x0f) { 184 switch (dev & 0x0f) {
184 case SND_DEV_SEQ: 185 case SND_DEV_SEQ:
@@ -196,7 +197,7 @@ static ssize_t sound_write(struct file *file, const char __user *buf, size_t cou
196 ret = MIDIbuf_write(dev, file, buf, count); 197 ret = MIDIbuf_write(dev, file, buf, count);
197 break; 198 break;
198 } 199 }
199 unlock_kernel(); 200 mutex_unlock(&soundcard_mutex);
200 return ret; 201 return ret;
201} 202}
202 203
@@ -210,7 +211,7 @@ static int sound_open(struct inode *inode, struct file *file)
210 printk(KERN_ERR "Invalid minor device %d\n", dev); 211 printk(KERN_ERR "Invalid minor device %d\n", dev);
211 return -ENXIO; 212 return -ENXIO;
212 } 213 }
213 lock_kernel(); 214 mutex_lock(&soundcard_mutex);
214 switch (dev & 0x0f) { 215 switch (dev & 0x0f) {
215 case SND_DEV_CTL: 216 case SND_DEV_CTL:
216 dev >>= 4; 217 dev >>= 4;
@@ -247,15 +248,15 @@ static int sound_open(struct inode *inode, struct file *file)
247 retval = -ENXIO; 248 retval = -ENXIO;
248 } 249 }
249 250
250 unlock_kernel(); 251 mutex_unlock(&soundcard_mutex);
251 return 0; 252 return retval;
252} 253}
253 254
254static int sound_release(struct inode *inode, struct file *file) 255static int sound_release(struct inode *inode, struct file *file)
255{ 256{
256 int dev = iminor(inode); 257 int dev = iminor(inode);
257 258
258 lock_kernel(); 259 mutex_lock(&soundcard_mutex);
259 DEB(printk("sound_release(dev=%d)\n", dev)); 260 DEB(printk("sound_release(dev=%d)\n", dev));
260 switch (dev & 0x0f) { 261 switch (dev & 0x0f) {
261 case SND_DEV_CTL: 262 case SND_DEV_CTL:
@@ -280,7 +281,7 @@ static int sound_release(struct inode *inode, struct file *file)
280 default: 281 default:
281 printk(KERN_ERR "Sound error: Releasing unknown device 0x%02x\n", dev); 282 printk(KERN_ERR "Sound error: Releasing unknown device 0x%02x\n", dev);
282 } 283 }
283 unlock_kernel(); 284 mutex_unlock(&soundcard_mutex);
284 285
285 return 0; 286 return 0;
286} 287}
@@ -354,7 +355,7 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
354 if (cmd == OSS_GETVERSION) 355 if (cmd == OSS_GETVERSION)
355 return __put_user(SOUND_VERSION, (int __user *)p); 356 return __put_user(SOUND_VERSION, (int __user *)p);
356 357
357 lock_kernel(); 358 mutex_lock(&soundcard_mutex);
358 if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */ 359 if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */
359 (dev & 0x0f) != SND_DEV_CTL) { 360 (dev & 0x0f) != SND_DEV_CTL) {
360 dtype = dev & 0x0f; 361 dtype = dev & 0x0f;
@@ -369,7 +370,7 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
369 ret = sound_mixer_ioctl(dev >> 4, cmd, p); 370 ret = sound_mixer_ioctl(dev >> 4, cmd, p);
370 break; 371 break;
371 } 372 }
372 unlock_kernel(); 373 mutex_unlock(&soundcard_mutex);
373 return ret; 374 return ret;
374 } 375 }
375 376
@@ -399,7 +400,7 @@ static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
399 break; 400 break;
400 401
401 } 402 }
402 unlock_kernel(); 403 mutex_unlock(&soundcard_mutex);
403 return ret; 404 return ret;
404} 405}
405 406
@@ -439,35 +440,35 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
439 printk(KERN_ERR "Sound: mmap() not supported for other than audio devices\n"); 440 printk(KERN_ERR "Sound: mmap() not supported for other than audio devices\n");
440 return -EINVAL; 441 return -EINVAL;
441 } 442 }
442 lock_kernel(); 443 mutex_lock(&soundcard_mutex);
443 if (vma->vm_flags & VM_WRITE) /* Map write and read/write to the output buf */ 444 if (vma->vm_flags & VM_WRITE) /* Map write and read/write to the output buf */
444 dmap = audio_devs[dev]->dmap_out; 445 dmap = audio_devs[dev]->dmap_out;
445 else if (vma->vm_flags & VM_READ) 446 else if (vma->vm_flags & VM_READ)
446 dmap = audio_devs[dev]->dmap_in; 447 dmap = audio_devs[dev]->dmap_in;
447 else { 448 else {
448 printk(KERN_ERR "Sound: Undefined mmap() access\n"); 449 printk(KERN_ERR "Sound: Undefined mmap() access\n");
449 unlock_kernel(); 450 mutex_unlock(&soundcard_mutex);
450 return -EINVAL; 451 return -EINVAL;
451 } 452 }
452 453
453 if (dmap == NULL) { 454 if (dmap == NULL) {
454 printk(KERN_ERR "Sound: mmap() error. dmap == NULL\n"); 455 printk(KERN_ERR "Sound: mmap() error. dmap == NULL\n");
455 unlock_kernel(); 456 mutex_unlock(&soundcard_mutex);
456 return -EIO; 457 return -EIO;
457 } 458 }
458 if (dmap->raw_buf == NULL) { 459 if (dmap->raw_buf == NULL) {
459 printk(KERN_ERR "Sound: mmap() called when raw_buf == NULL\n"); 460 printk(KERN_ERR "Sound: mmap() called when raw_buf == NULL\n");
460 unlock_kernel(); 461 mutex_unlock(&soundcard_mutex);
461 return -EIO; 462 return -EIO;
462 } 463 }
463 if (dmap->mapping_flags) { 464 if (dmap->mapping_flags) {
464 printk(KERN_ERR "Sound: mmap() called twice for the same DMA buffer\n"); 465 printk(KERN_ERR "Sound: mmap() called twice for the same DMA buffer\n");
465 unlock_kernel(); 466 mutex_unlock(&soundcard_mutex);
466 return -EIO; 467 return -EIO;
467 } 468 }
468 if (vma->vm_pgoff != 0) { 469 if (vma->vm_pgoff != 0) {
469 printk(KERN_ERR "Sound: mmap() offset must be 0.\n"); 470 printk(KERN_ERR "Sound: mmap() offset must be 0.\n");
470 unlock_kernel(); 471 mutex_unlock(&soundcard_mutex);
471 return -EINVAL; 472 return -EINVAL;
472 } 473 }
473 size = vma->vm_end - vma->vm_start; 474 size = vma->vm_end - vma->vm_start;
@@ -478,7 +479,7 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
478 if (remap_pfn_range(vma, vma->vm_start, 479 if (remap_pfn_range(vma, vma->vm_start,
479 virt_to_phys(dmap->raw_buf) >> PAGE_SHIFT, 480 virt_to_phys(dmap->raw_buf) >> PAGE_SHIFT,
480 vma->vm_end - vma->vm_start, vma->vm_page_prot)) { 481 vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
481 unlock_kernel(); 482 mutex_unlock(&soundcard_mutex);
482 return -EAGAIN; 483 return -EAGAIN;
483 } 484 }
484 485
@@ -490,7 +491,7 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
490 memset(dmap->raw_buf, 491 memset(dmap->raw_buf,
491 dmap->neutral_byte, 492 dmap->neutral_byte,
492 dmap->bytes_in_use); 493 dmap->bytes_in_use);
493 unlock_kernel(); 494 mutex_unlock(&soundcard_mutex);
494 return 0; 495 return 0;
495} 496}
496 497
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index b15840ad2527..44357d877a27 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -68,7 +68,6 @@
68#include <linux/delay.h> 68#include <linux/delay.h>
69#include <linux/sound.h> 69#include <linux/sound.h>
70#include <linux/slab.h> 70#include <linux/slab.h>
71#include <linux/smp_lock.h>
72#include <linux/soundcard.h> 71#include <linux/soundcard.h>
73#include <linux/ac97_codec.h> 72#include <linux/ac97_codec.h>
74#include <linux/pci.h> 73#include <linux/pci.h>
@@ -94,6 +93,7 @@
94 93
95struct cs4297a_state; 94struct cs4297a_state;
96 95
96static DEFINE_MUTEX(swarm_cs4297a_mutex);
97static void stop_dac(struct cs4297a_state *s); 97static void stop_dac(struct cs4297a_state *s);
98static void stop_adc(struct cs4297a_state *s); 98static void stop_adc(struct cs4297a_state *s);
99static void start_dac(struct cs4297a_state *s); 99static void start_dac(struct cs4297a_state *s);
@@ -1535,7 +1535,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
1535 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, 1535 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
1536 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n")); 1536 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n"));
1537 1537
1538 lock_kernel(); 1538 mutex_lock(&swarm_cs4297a_mutex);
1539 list_for_each(entry, &cs4297a_devs) 1539 list_for_each(entry, &cs4297a_devs)
1540 { 1540 {
1541 s = list_entry(entry, struct cs4297a_state, list); 1541 s = list_entry(entry, struct cs4297a_state, list);
@@ -1547,7 +1547,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
1547 CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2, 1547 CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
1548 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n")); 1548 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n"));
1549 1549
1550 unlock_kernel(); 1550 mutex_unlock(&swarm_cs4297a_mutex);
1551 return -ENODEV; 1551 return -ENODEV;
1552 } 1552 }
1553 VALIDATE_STATE(s); 1553 VALIDATE_STATE(s);
@@ -1555,7 +1555,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
1555 1555
1556 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4, 1556 CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
1557 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n")); 1557 printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n"));
1558 unlock_kernel(); 1558 mutex_unlock(&swarm_cs4297a_mutex);
1559 1559
1560 return nonseekable_open(inode, file); 1560 return nonseekable_open(inode, file);
1561} 1561}
@@ -1575,10 +1575,10 @@ static int cs4297a_ioctl_mixdev(struct file *file,
1575 unsigned int cmd, unsigned long arg) 1575 unsigned int cmd, unsigned long arg)
1576{ 1576{
1577 int ret; 1577 int ret;
1578 lock_kernel(); 1578 mutex_lock(&swarm_cs4297a_mutex);
1579 ret = mixer_ioctl((struct cs4297a_state *) file->private_data, cmd, 1579 ret = mixer_ioctl((struct cs4297a_state *) file->private_data, cmd,
1580 arg); 1580 arg);
1581 unlock_kernel(); 1581 mutex_unlock(&swarm_cs4297a_mutex);
1582 return ret; 1582 return ret;
1583} 1583}
1584 1584
@@ -2350,9 +2350,9 @@ static long cs4297a_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
2350{ 2350{
2351 int ret; 2351 int ret;
2352 2352
2353 lock_kernel(); 2353 mutex_lock(&swarm_cs4297a_mutex);
2354 ret = cs4297a_ioctl(file, cmd, arg); 2354 ret = cs4297a_ioctl(file, cmd, arg);
2355 unlock_kernel(); 2355 mutex_unlock(&swarm_cs4297a_mutex);
2356 2356
2357 return ret; 2357 return ret;
2358} 2358}
@@ -2509,9 +2509,9 @@ static int cs4297a_open(struct inode *inode, struct file *file)
2509{ 2509{
2510 int ret; 2510 int ret;
2511 2511
2512 lock_kernel(); 2512 mutex_lock(&swarm_cs4297a_mutex);
2513 ret = cs4297a_open(inode, file); 2513 ret = cs4297a_open(inode, file);
2514 unlock_kernel(); 2514 mutex_unlock(&swarm_cs4297a_mutex);
2515 2515
2516 return ret; 2516 return ret;
2517} 2517}
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 8cd73cdd88af..643f1113b1d8 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -145,7 +145,6 @@
145#include <linux/init.h> 145#include <linux/init.h>
146 146
147#include <linux/spinlock.h> 147#include <linux/spinlock.h>
148#include <linux/smp_lock.h>
149#include <linux/wait.h> 148#include <linux/wait.h>
150#include <linux/interrupt.h> 149#include <linux/interrupt.h>
151#include <linux/mutex.h> 150#include <linux/mutex.h>
@@ -160,6 +159,7 @@
160 159
161#ifdef VWSND_DEBUG 160#ifdef VWSND_DEBUG
162 161
162static DEFINE_MUTEX(vwsnd_mutex);
163static int shut_up = 1; 163static int shut_up = 1;
164 164
165/* 165/*
@@ -2891,11 +2891,11 @@ static long vwsnd_audio_ioctl(struct file *file,
2891 vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data; 2891 vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
2892 int ret; 2892 int ret;
2893 2893
2894 lock_kernel(); 2894 mutex_lock(&vwsnd_mutex);
2895 mutex_lock(&devc->io_mutex); 2895 mutex_lock(&devc->io_mutex);
2896 ret = vwsnd_audio_do_ioctl(file, cmd, arg); 2896 ret = vwsnd_audio_do_ioctl(file, cmd, arg);
2897 mutex_unlock(&devc->io_mutex); 2897 mutex_unlock(&devc->io_mutex);
2898 unlock_kernel(); 2898 mutex_unlock(&vwsnd_mutex);
2899 2899
2900 return ret; 2900 return ret;
2901} 2901}
@@ -2922,7 +2922,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2922 2922
2923 DBGE("(inode=0x%p, file=0x%p)\n", inode, file); 2923 DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
2924 2924
2925 lock_kernel(); 2925 mutex_lock(&vwsnd_mutex);
2926 INC_USE_COUNT; 2926 INC_USE_COUNT;
2927 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) 2927 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
2928 if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F)) 2928 if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F))
@@ -2930,7 +2930,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2930 2930
2931 if (devc == NULL) { 2931 if (devc == NULL) {
2932 DEC_USE_COUNT; 2932 DEC_USE_COUNT;
2933 unlock_kernel(); 2933 mutex_unlock(&vwsnd_mutex);
2934 return -ENODEV; 2934 return -ENODEV;
2935 } 2935 }
2936 2936
@@ -2939,13 +2939,13 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2939 mutex_unlock(&devc->open_mutex); 2939 mutex_unlock(&devc->open_mutex);
2940 if (file->f_flags & O_NONBLOCK) { 2940 if (file->f_flags & O_NONBLOCK) {
2941 DEC_USE_COUNT; 2941 DEC_USE_COUNT;
2942 unlock_kernel(); 2942 mutex_unlock(&vwsnd_mutex);
2943 return -EBUSY; 2943 return -EBUSY;
2944 } 2944 }
2945 interruptible_sleep_on(&devc->open_wait); 2945 interruptible_sleep_on(&devc->open_wait);
2946 if (signal_pending(current)) { 2946 if (signal_pending(current)) {
2947 DEC_USE_COUNT; 2947 DEC_USE_COUNT;
2948 unlock_kernel(); 2948 mutex_unlock(&vwsnd_mutex);
2949 return -ERESTARTSYS; 2949 return -ERESTARTSYS;
2950 } 2950 }
2951 mutex_lock(&devc->open_mutex); 2951 mutex_lock(&devc->open_mutex);
@@ -2998,7 +2998,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
2998 2998
2999 file->private_data = devc; 2999 file->private_data = devc;
3000 DBGRV(); 3000 DBGRV();
3001 unlock_kernel(); 3001 mutex_unlock(&vwsnd_mutex);
3002 return 0; 3002 return 0;
3003} 3003}
3004 3004
@@ -3012,7 +3012,7 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file)
3012 vwsnd_port_t *wport = NULL, *rport = NULL; 3012 vwsnd_port_t *wport = NULL, *rport = NULL;
3013 int err = 0; 3013 int err = 0;
3014 3014
3015 lock_kernel(); 3015 mutex_lock(&vwsnd_mutex);
3016 mutex_lock(&devc->io_mutex); 3016 mutex_lock(&devc->io_mutex);
3017 { 3017 {
3018 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); 3018 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
@@ -3040,7 +3040,7 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file)
3040 wake_up(&devc->open_wait); 3040 wake_up(&devc->open_wait);
3041 DEC_USE_COUNT; 3041 DEC_USE_COUNT;
3042 DBGR(); 3042 DBGR();
3043 unlock_kernel(); 3043 mutex_unlock(&vwsnd_mutex);
3044 return err; 3044 return err;
3045} 3045}
3046 3046
@@ -3068,18 +3068,18 @@ static int vwsnd_mixer_open(struct inode *inode, struct file *file)
3068 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); 3068 DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
3069 3069
3070 INC_USE_COUNT; 3070 INC_USE_COUNT;
3071 lock_kernel(); 3071 mutex_lock(&vwsnd_mutex);
3072 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev) 3072 for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
3073 if (devc->mixer_minor == iminor(inode)) 3073 if (devc->mixer_minor == iminor(inode))
3074 break; 3074 break;
3075 3075
3076 if (devc == NULL) { 3076 if (devc == NULL) {
3077 DEC_USE_COUNT; 3077 DEC_USE_COUNT;
3078 unlock_kernel(); 3078 mutex_unlock(&vwsnd_mutex);
3079 return -ENODEV; 3079 return -ENODEV;
3080 } 3080 }
3081 file->private_data = devc; 3081 file->private_data = devc;
3082 unlock_kernel(); 3082 mutex_unlock(&vwsnd_mutex);
3083 return 0; 3083 return 0;
3084} 3084}
3085 3085
@@ -3223,7 +3223,7 @@ static long vwsnd_mixer_ioctl(struct file *file,
3223 3223
3224 DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg); 3224 DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg);
3225 3225
3226 lock_kernel(); 3226 mutex_lock(&vwsnd_mutex);
3227 mutex_lock(&devc->mix_mutex); 3227 mutex_lock(&devc->mix_mutex);
3228 { 3228 {
3229 if ((cmd & ~nrmask) == MIXER_READ(0)) 3229 if ((cmd & ~nrmask) == MIXER_READ(0))
@@ -3234,7 +3234,7 @@ static long vwsnd_mixer_ioctl(struct file *file,
3234 retval = -EINVAL; 3234 retval = -EINVAL;
3235 } 3235 }
3236 mutex_unlock(&devc->mix_mutex); 3236 mutex_unlock(&devc->mix_mutex);
3237 unlock_kernel(); 3237 mutex_unlock(&vwsnd_mutex);
3238 return retval; 3238 return retval;
3239} 3239}
3240 3240
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index e7a8cd058efb..12e34653b8a8 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -207,12 +207,12 @@ config SND_CMIPCI
207 207
208config SND_OXYGEN_LIB 208config SND_OXYGEN_LIB
209 tristate 209 tristate
210 select SND_PCM
211 select SND_MPU401_UART
212 210
213config SND_OXYGEN 211config SND_OXYGEN
214 tristate "C-Media 8788 (Oxygen)" 212 tristate "C-Media 8788 (Oxygen)"
215 select SND_OXYGEN_LIB 213 select SND_OXYGEN_LIB
214 select SND_PCM
215 select SND_MPU401_UART
216 help 216 help
217 Say Y here to include support for sound cards based on the 217 Say Y here to include support for sound cards based on the
218 C-Media CMI8788 (Oxygen HD Audio) chip: 218 C-Media CMI8788 (Oxygen HD Audio) chip:
@@ -581,6 +581,8 @@ config SND_HDSPM
581config SND_HIFIER 581config SND_HIFIER
582 tristate "TempoTec HiFier Fantasia" 582 tristate "TempoTec HiFier Fantasia"
583 select SND_OXYGEN_LIB 583 select SND_OXYGEN_LIB
584 select SND_PCM
585 select SND_MPU401_UART
584 help 586 help
585 Say Y here to include support for the MediaTek/TempoTec HiFier 587 Say Y here to include support for the MediaTek/TempoTec HiFier
586 Fantasia sound card. 588 Fantasia sound card.
@@ -815,14 +817,17 @@ config SND_VIA82XX_MODEM
815 will be called snd-via82xx-modem. 817 will be called snd-via82xx-modem.
816 818
817config SND_VIRTUOSO 819config SND_VIRTUOSO
818 tristate "Asus Virtuoso 100/200 (Xonar)" 820 tristate "Asus Virtuoso 66/100/200 (Xonar)"
819 select SND_OXYGEN_LIB 821 select SND_OXYGEN_LIB
822 select SND_PCM
823 select SND_MPU401_UART
824 select SND_JACK if INPUT=y || INPUT=SND
820 help 825 help
821 Say Y here to include support for sound cards based on the 826 Say Y here to include support for sound cards based on the
822 Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, 827 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS,
823 Essence ST (Deluxe), and Essence STX. 828 Essence ST (Deluxe), and Essence STX.
824 Support for the DS is experimental. 829 Support for the HDAV1.3 (Deluxe) is incomplete; for the
825 Support for the HDAV1.3 (Deluxe) is very experimental. 830 HDAV1.3 Slim and Xense, missing.
826 831
827 To compile this driver as a module, choose M here: the module 832 To compile this driver as a module, choose M here: the module
828 will be called snd-virtuoso. 833 will be called snd-virtuoso.
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
index c92f493d341e..557c782ae4fc 100644
--- a/sound/pci/au88x0/au88x0_mixer.c
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -23,7 +23,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex)
23 if ((err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus)) < 0) 23 if ((err = snd_ac97_bus(vortex->card, 0, &ops, NULL, &pbus)) < 0)
24 return err; 24 return err;
25 memset(&ac97, 0, sizeof(ac97)); 25 memset(&ac97, 0, sizeof(ac97));
26 // Intialize AC97 codec stuff. 26 // Initialize AC97 codec stuff.
27 ac97.private_data = vortex; 27 ac97.private_data = vortex;
28 ac97.scaps = AC97_SCAP_NO_SPDIF; 28 ac97.scaps = AC97_SCAP_NO_SPDIF;
29 err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); 29 err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index 14b8d9a91aae..f19c11077255 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -670,8 +670,9 @@ struct snd_ca0106_details {
670 gpio_type = 2 -> shared side-out/line-in. */ 670 gpio_type = 2 -> shared side-out/line-in. */
671 int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume 671 int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume
672 controls, phone, mic, line-in and aux. */ 672 controls, phone, mic, line-in and aux. */
673 int spi_dac; /* spi_dac=1 adds the mute switch for each analog 673 u16 spi_dac; /* spi_dac = 0 -> no spi interface for DACs
674 output, front, rear, etc. */ 674 spi_dac = 0x<front><rear><center-lfe><side>
675 -> specifies DAC id for each channel pair. */
675}; 676};
676 677
677// definition of the chip-specific record 678// definition of the chip-specific record
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 0a3d3d6e77b4..d2d12c08f937 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -227,7 +227,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
227 .name = "Audigy SE [SB0570]", 227 .name = "Audigy SE [SB0570]",
228 .gpio_type = 1, 228 .gpio_type = 1,
229 .i2c_adc = 1, 229 .i2c_adc = 1,
230 .spi_dac = 1 } , 230 .spi_dac = 0x4021 } ,
231 /* New Audigy LS. Has a different DAC. */ 231 /* New Audigy LS. Has a different DAC. */
232 /* SB0570: 232 /* SB0570:
233 * CTRL:CA0106-DAT 233 * CTRL:CA0106-DAT
@@ -238,7 +238,17 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
238 .name = "Audigy SE OEM [SB0570a]", 238 .name = "Audigy SE OEM [SB0570a]",
239 .gpio_type = 1, 239 .gpio_type = 1,
240 .i2c_adc = 1, 240 .i2c_adc = 1,
241 .spi_dac = 1 } , 241 .spi_dac = 0x4021 } ,
242 /* Sound Blaster 5.1vx
243 * Tested: Playback on front, rear, center/lfe speakers
244 * Not-Tested: Capture
245 */
246 { .serial = 0x10041102,
247 .name = "Sound Blaster 5.1vx [SB1070]",
248 .gpio_type = 1,
249 .i2c_adc = 0,
250 .spi_dac = 0x0124
251 } ,
242 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */ 252 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
243 /* SB0438 253 /* SB0438
244 * CTRL:CA0106-DAT 254 * CTRL:CA0106-DAT
@@ -254,7 +264,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
254 .name = "MSI K8N Diamond MB", 264 .name = "MSI K8N Diamond MB",
255 .gpio_type = 2, 265 .gpio_type = 2,
256 .i2c_adc = 1, 266 .i2c_adc = 1,
257 .spi_dac = 1 } , 267 .spi_dac = 0x4021 } ,
258 /* Giga-byte GA-G1975X mobo 268 /* Giga-byte GA-G1975X mobo
259 * Novell bnc#395807 269 * Novell bnc#395807
260 */ 270 */
@@ -483,16 +493,18 @@ static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime)
483} 493}
484 494
485static const int spi_dacd_reg[] = { 495static const int spi_dacd_reg[] = {
486 [PCM_FRONT_CHANNEL] = SPI_DACD4_REG, 496 SPI_DACD0_REG,
487 [PCM_REAR_CHANNEL] = SPI_DACD0_REG, 497 SPI_DACD1_REG,
488 [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_REG, 498 SPI_DACD2_REG,
489 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_REG, 499 0,
500 SPI_DACD4_REG,
490}; 501};
491static const int spi_dacd_bit[] = { 502static const int spi_dacd_bit[] = {
492 [PCM_FRONT_CHANNEL] = SPI_DACD4_BIT, 503 SPI_DACD0_BIT,
493 [PCM_REAR_CHANNEL] = SPI_DACD0_BIT, 504 SPI_DACD1_BIT,
494 [PCM_CENTER_LFE_CHANNEL]= SPI_DACD2_BIT, 505 SPI_DACD2_BIT,
495 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT, 506 0,
507 SPI_DACD4_BIT,
496}; 508};
497 509
498static void restore_spdif_bits(struct snd_ca0106 *chip, int idx) 510static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
@@ -504,6 +516,45 @@ static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
504 } 516 }
505} 517}
506 518
519static int snd_ca0106_channel_dac(struct snd_ca0106_details *details,
520 int channel_id)
521{
522 switch (channel_id) {
523 case PCM_FRONT_CHANNEL:
524 return (details->spi_dac & 0xf000) >> (4 * 3);
525 case PCM_REAR_CHANNEL:
526 return (details->spi_dac & 0x0f00) >> (4 * 2);
527 case PCM_CENTER_LFE_CHANNEL:
528 return (details->spi_dac & 0x00f0) >> (4 * 1);
529 case PCM_UNKNOWN_CHANNEL:
530 return (details->spi_dac & 0x000f) >> (4 * 0);
531 default:
532 snd_printk(KERN_DEBUG "ca0106: unknown channel_id %d\n",
533 channel_id);
534 }
535 return 0;
536}
537
538static int snd_ca0106_pcm_power_dac(struct snd_ca0106 *chip, int channel_id,
539 int power)
540{
541 if (chip->details->spi_dac) {
542 const int dac = snd_ca0106_channel_dac(chip->details,
543 channel_id);
544 const int reg = spi_dacd_reg[dac];
545 const int bit = spi_dacd_bit[dac];
546
547 if (power)
548 /* Power up */
549 chip->spi_dac_reg[reg] &= ~bit;
550 else
551 /* Power down */
552 chip->spi_dac_reg[reg] |= bit;
553 return snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
554 }
555 return 0;
556}
557
507/* open_playback callback */ 558/* open_playback callback */
508static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, 559static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
509 int channel_id) 560 int channel_id)
@@ -543,12 +594,9 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
543 return err; 594 return err;
544 snd_pcm_set_sync(substream); 595 snd_pcm_set_sync(substream);
545 596
546 if (chip->details->spi_dac && channel_id != PCM_FRONT_CHANNEL) { 597 /* Front channel dac should already be on */
547 const int reg = spi_dacd_reg[channel_id]; 598 if (channel_id != PCM_FRONT_CHANNEL) {
548 599 err = snd_ca0106_pcm_power_dac(chip, channel_id, 1);
549 /* Power up dac */
550 chip->spi_dac_reg[reg] &= ~spi_dacd_bit[channel_id];
551 err = snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]);
552 if (err < 0) 600 if (err < 0)
553 return err; 601 return err;
554 } 602 }
@@ -568,13 +616,14 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
568 616
569 restore_spdif_bits(chip, epcm->channel_id); 617 restore_spdif_bits(chip, epcm->channel_id);
570 618
571 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) { 619 /* Front channel dac should stay on */
572 const int reg = spi_dacd_reg[epcm->channel_id]; 620 if (epcm->channel_id != PCM_FRONT_CHANNEL) {
573 621 int err;
574 /* Power down DAC */ 622 err = snd_ca0106_pcm_power_dac(chip, epcm->channel_id, 0);
575 chip->spi_dac_reg[reg] |= spi_dacd_bit[epcm->channel_id]; 623 if (err < 0)
576 snd_ca0106_spi_write(chip, chip->spi_dac_reg[reg]); 624 return err;
577 } 625 }
626
578 /* FIXME: maybe zero others */ 627 /* FIXME: maybe zero others */
579 return 0; 628 return 0;
580} 629}
@@ -1002,29 +1051,27 @@ snd_ca0106_pcm_pointer_playback(struct snd_pcm_substream *substream)
1002 struct snd_ca0106 *emu = snd_pcm_substream_chip(substream); 1051 struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
1003 struct snd_pcm_runtime *runtime = substream->runtime; 1052 struct snd_pcm_runtime *runtime = substream->runtime;
1004 struct snd_ca0106_pcm *epcm = runtime->private_data; 1053 struct snd_ca0106_pcm *epcm = runtime->private_data;
1005 snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0; 1054 unsigned int ptr, prev_ptr;
1006 int channel = epcm->channel_id; 1055 int channel = epcm->channel_id;
1056 int timeout = 10;
1007 1057
1008 if (!epcm->running) 1058 if (!epcm->running)
1009 return 0; 1059 return 0;
1010 1060
1011 ptr3 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 1061 prev_ptr = -1;
1012 ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); 1062 do {
1013 ptr4 = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel); 1063 ptr = snd_ca0106_ptr_read(emu, PLAYBACK_LIST_PTR, channel);
1014 if (ptr3 != ptr4) ptr1 = snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel); 1064 ptr = (ptr >> 3) * runtime->period_size;
1015 ptr2 = bytes_to_frames(runtime, ptr1); 1065 ptr += bytes_to_frames(runtime,
1016 ptr2+= (ptr4 >> 3) * runtime->period_size; 1066 snd_ca0106_ptr_read(emu, PLAYBACK_POINTER, channel));
1017 ptr=ptr2; 1067 if (ptr >= runtime->buffer_size)
1018 if (ptr >= runtime->buffer_size) 1068 ptr -= runtime->buffer_size;
1019 ptr -= runtime->buffer_size; 1069 if (prev_ptr == ptr)
1020 /* 1070 return ptr;
1021 printk(KERN_DEBUG "ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, " 1071 prev_ptr = ptr;
1022 "buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", 1072 } while (--timeout);
1023 ptr1, ptr2, ptr, (int)runtime->buffer_size, 1073 snd_printk(KERN_WARNING "ca0106: unstable DMA pointer!\n");
1024 (int)runtime->period_size, (int)runtime->frame_bits, 1074 return 0;
1025 (int)runtime->rate);
1026 */
1027 return ptr;
1028} 1075}
1029 1076
1030/* pointer_capture callback */ 1077/* pointer_capture callback */
@@ -1362,7 +1409,7 @@ static unsigned int spi_dac_init[] = {
1362 SPI_REG(12, 0x00), 1409 SPI_REG(12, 0x00),
1363 SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB), 1410 SPI_REG(SPI_LDA4_REG, SPI_DA_BIT_0dB),
1364 SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE), 1411 SPI_REG(SPI_RDA4_REG, SPI_DA_BIT_0dB | SPI_DA_BIT_UPDATE),
1365 SPI_REG(SPI_DACD4_REG, 0x00), 1412 SPI_REG(SPI_DACD4_REG, SPI_DACD4_BIT),
1366}; 1413};
1367 1414
1368static unsigned int i2c_adc_init[][2] = { 1415static unsigned int i2c_adc_init[][2] = {
@@ -1541,7 +1588,7 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
1541 /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */ 1588 /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */
1542 } 1589 }
1543 1590
1544 if (chip->details->spi_dac == 1) { 1591 if (chip->details->spi_dac) {
1545 /* The SB0570 use SPI to control DAC. */ 1592 /* The SB0570 use SPI to control DAC. */
1546 int size, n; 1593 int size, n;
1547 1594
@@ -1553,6 +1600,9 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
1553 if (reg < ARRAY_SIZE(chip->spi_dac_reg)) 1600 if (reg < ARRAY_SIZE(chip->spi_dac_reg))
1554 chip->spi_dac_reg[reg] = spi_dac_init[n]; 1601 chip->spi_dac_reg[reg] = spi_dac_init[n];
1555 } 1602 }
1603
1604 /* Enable front dac only */
1605 snd_ca0106_pcm_power_dac(chip, PCM_FRONT_CHANNEL, 1);
1556 } 1606 }
1557} 1607}
1558 1608
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 85fd315d9999..630aa4998189 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -676,28 +676,65 @@ static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata =
676 I2C_VOLUME("Aux Capture Volume", 3), 676 I2C_VOLUME("Aux Capture Volume", 3),
677}; 677};
678 678
679#define SPI_SWITCH(xname,reg,bit) \ 679static const int spi_dmute_reg[] = {
680{ \ 680 SPI_DMUTE0_REG,
681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 681 SPI_DMUTE1_REG,
682 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 682 SPI_DMUTE2_REG,
683 .info = spi_mute_info, \ 683 0,
684 .get = spi_mute_get, \ 684 SPI_DMUTE4_REG,
685 .put = spi_mute_put, \ 685};
686 .private_value = (reg<<SPI_REG_SHIFT) | (bit) \ 686static const int spi_dmute_bit[] = {
687} 687 SPI_DMUTE0_BIT,
688 688 SPI_DMUTE1_BIT,
689static struct snd_kcontrol_new snd_ca0106_volume_spi_dac_ctls[] 689 SPI_DMUTE2_BIT,
690__devinitdata = { 690 0,
691 SPI_SWITCH("Analog Front Playback Switch", 691 SPI_DMUTE4_BIT,
692 SPI_DMUTE4_REG, SPI_DMUTE4_BIT),
693 SPI_SWITCH("Analog Rear Playback Switch",
694 SPI_DMUTE0_REG, SPI_DMUTE0_BIT),
695 SPI_SWITCH("Analog Center/LFE Playback Switch",
696 SPI_DMUTE2_REG, SPI_DMUTE2_BIT),
697 SPI_SWITCH("Analog Side Playback Switch",
698 SPI_DMUTE1_REG, SPI_DMUTE1_BIT),
699}; 692};
700 693
694static struct snd_kcontrol_new __devinit
695snd_ca0106_volume_spi_dac_ctl(struct snd_ca0106_details *details,
696 int channel_id)
697{
698 struct snd_kcontrol_new spi_switch = {0};
699 int reg, bit;
700 int dac_id;
701
702 spi_switch.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
703 spi_switch.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
704 spi_switch.info = spi_mute_info;
705 spi_switch.get = spi_mute_get;
706 spi_switch.put = spi_mute_put;
707
708 switch (channel_id) {
709 case PCM_FRONT_CHANNEL:
710 spi_switch.name = "Analog Front Playback Switch";
711 dac_id = (details->spi_dac & 0xf000) >> (4 * 3);
712 break;
713 case PCM_REAR_CHANNEL:
714 spi_switch.name = "Analog Rear Playback Switch";
715 dac_id = (details->spi_dac & 0x0f00) >> (4 * 2);
716 break;
717 case PCM_CENTER_LFE_CHANNEL:
718 spi_switch.name = "Analog Center/LFE Playback Switch";
719 dac_id = (details->spi_dac & 0x00f0) >> (4 * 1);
720 break;
721 case PCM_UNKNOWN_CHANNEL:
722 spi_switch.name = "Analog Side Playback Switch";
723 dac_id = (details->spi_dac & 0x000f) >> (4 * 0);
724 break;
725 default:
726 /* Unused channel */
727 spi_switch.name = NULL;
728 dac_id = 0;
729 }
730 reg = spi_dmute_reg[dac_id];
731 bit = spi_dmute_bit[dac_id];
732
733 spi_switch.private_value = (reg << SPI_REG_SHIFT) | bit;
734
735 return spi_switch;
736}
737
701static int __devinit remove_ctl(struct snd_card *card, const char *name) 738static int __devinit remove_ctl(struct snd_card *card, const char *name)
702{ 739{
703 struct snd_ctl_elem_id id; 740 struct snd_ctl_elem_id id;
@@ -832,8 +869,18 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
832 if (err < 0) 869 if (err < 0)
833 return err; 870 return err;
834 } 871 }
835 if (emu->details->spi_dac == 1) 872 if (emu->details->spi_dac) {
836 ADD_CTLS(emu, snd_ca0106_volume_spi_dac_ctls); 873 int i;
874 for (i = 0;; i++) {
875 struct snd_kcontrol_new ctl;
876 ctl = snd_ca0106_volume_spi_dac_ctl(emu->details, i);
877 if (!ctl.name)
878 break;
879 err = snd_ctl_add(card, snd_ctl_new1(&ctl, emu));
880 if (err < 0)
881 return err;
882 }
883 }
837 884
838 /* Create virtual master controls */ 885 /* Create virtual master controls */
839 vmaster = snd_ctl_make_virtual_master("Master Playback Volume", 886 vmaster = snd_ctl_make_virtual_master("Master Playback Volume",
@@ -845,7 +892,7 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
845 return err; 892 return err;
846 add_slaves(card, vmaster, slave_vols); 893 add_slaves(card, vmaster, slave_vols);
847 894
848 if (emu->details->spi_dac == 1) { 895 if (emu->details->spi_dac) {
849 vmaster = snd_ctl_make_virtual_master("Master Playback Switch", 896 vmaster = snd_ctl_make_virtual_master("Master Playback Switch",
850 NULL); 897 NULL);
851 if (!vmaster) 898 if (!vmaster)
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index 8578c70c61f2..bab564824efe 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -321,7 +321,7 @@ static struct snd_rawmidi_ops snd_emu10k1_midi_input =
321 321
322static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi) 322static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi)
323{ 323{
324 struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)rmidi->private_data; 324 struct snd_emu10k1_midi *midi = rmidi->private_data;
325 midi->interrupt = NULL; 325 midi->interrupt = NULL;
326 midi->rmidi = NULL; 326 midi->rmidi = NULL;
327} 327}
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index d216362626d0..712c1710f9a2 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -563,6 +563,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
563 case ICE1712_SUBDEVICE_DELTA1010E: 563 case ICE1712_SUBDEVICE_DELTA1010E:
564 case ICE1712_SUBDEVICE_DELTA1010LT: 564 case ICE1712_SUBDEVICE_DELTA1010LT:
565 case ICE1712_SUBDEVICE_MEDIASTATION: 565 case ICE1712_SUBDEVICE_MEDIASTATION:
566 case ICE1712_SUBDEVICE_EDIROLDA2496:
566 ice->num_total_dacs = 8; 567 ice->num_total_dacs = 8;
567 ice->num_total_adcs = 8; 568 ice->num_total_adcs = 8;
568 break; 569 break;
@@ -635,6 +636,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
635 err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice); 636 err = snd_ice1712_akm4xxx_init(ak, &akm_delta410, &akm_delta410_priv, ice);
636 break; 637 break;
637 case ICE1712_SUBDEVICE_DELTA1010LT: 638 case ICE1712_SUBDEVICE_DELTA1010LT:
639 case ICE1712_SUBDEVICE_EDIROLDA2496:
638 err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice); 640 err = snd_ice1712_akm4xxx_init(ak, &akm_delta1010lt, &akm_delta1010lt_priv, ice);
639 break; 641 break;
640 case ICE1712_SUBDEVICE_DELTA66: 642 case ICE1712_SUBDEVICE_DELTA66:
@@ -734,6 +736,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
734 case ICE1712_SUBDEVICE_DELTA66: 736 case ICE1712_SUBDEVICE_DELTA66:
735 case ICE1712_SUBDEVICE_VX442: 737 case ICE1712_SUBDEVICE_VX442:
736 case ICE1712_SUBDEVICE_DELTA66E: 738 case ICE1712_SUBDEVICE_DELTA66E:
739 case ICE1712_SUBDEVICE_EDIROLDA2496:
737 err = snd_ice1712_akm4xxx_build_controls(ice); 740 err = snd_ice1712_akm4xxx_build_controls(ice);
738 if (err < 0) 741 if (err < 0)
739 return err; 742 return err;
@@ -813,5 +816,12 @@ struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
813 .chip_init = snd_ice1712_delta_init, 816 .chip_init = snd_ice1712_delta_init,
814 .build_controls = snd_ice1712_delta_add_controls, 817 .build_controls = snd_ice1712_delta_add_controls,
815 }, 818 },
819 {
820 .subvendor = ICE1712_SUBDEVICE_EDIROLDA2496,
821 .name = "Edirol DA2496",
822 .model = "da2496",
823 .chip_init = snd_ice1712_delta_init,
824 .build_controls = snd_ice1712_delta_add_controls,
825 },
816 { } /* terminator */ 826 { } /* terminator */
817}; 827};
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index f7f14df81f26..1a0ac6cd6501 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -34,7 +34,8 @@
34 "{MidiMan M Audio,Delta 410},"\ 34 "{MidiMan M Audio,Delta 410},"\
35 "{MidiMan M Audio,Audiophile 24/96},"\ 35 "{MidiMan M Audio,Audiophile 24/96},"\
36 "{Digigram,VX442},"\ 36 "{Digigram,VX442},"\
37 "{Lionstracs,Mediastation}," 37 "{Lionstracs,Mediastation},"\
38 "{Edirol,DA2496},"
38 39
39#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6 40#define ICE1712_SUBDEVICE_DELTA1010 0x121430d6
40#define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6 41#define ICE1712_SUBDEVICE_DELTA1010E 0xff1430d6
@@ -47,6 +48,7 @@
47#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6 48#define ICE1712_SUBDEVICE_DELTA1010LT 0x12143bd6
48#define ICE1712_SUBDEVICE_VX442 0x12143cd6 49#define ICE1712_SUBDEVICE_VX442 0x12143cd6
49#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 50#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
51#define ICE1712_SUBDEVICE_EDIROLDA2496 0xce164010
50 52
51/* entry point */ 53/* entry point */
52extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; 54extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 6bc3f91b7281..cdb873f5da50 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -638,7 +638,7 @@ static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
638 */ 638 */
639static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 639static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
640{ 640{
641 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 641 struct snd_ice1712 *ice = entry->private_data;
642 char line[64]; 642 char line[64];
643 unsigned int reg, val; 643 unsigned int reg, val;
644 mutex_lock(&ice->gpio_mutex); 644 mutex_lock(&ice->gpio_mutex);
@@ -653,7 +653,7 @@ static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buf
653 653
654static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 654static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
655{ 655{
656 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 656 struct snd_ice1712 *ice = entry->private_data;
657 int reg, val; 657 int reg, val;
658 658
659 mutex_lock(&ice->gpio_mutex); 659 mutex_lock(&ice->gpio_mutex);
@@ -676,7 +676,7 @@ static void wm_proc_init(struct snd_ice1712 *ice)
676 676
677static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 677static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
678{ 678{
679 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 679 struct snd_ice1712 *ice = entry->private_data;
680 int reg, val; 680 int reg, val;
681 681
682 mutex_lock(&ice->gpio_mutex); 682 mutex_lock(&ice->gpio_mutex);
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index 2a8e5cd8f2d8..e36ddb94c382 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -654,7 +654,7 @@ static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
654static void stac9460_proc_regs_read(struct snd_info_entry *entry, 654static void stac9460_proc_regs_read(struct snd_info_entry *entry,
655 struct snd_info_buffer *buffer) 655 struct snd_info_buffer *buffer)
656{ 656{
657 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data; 657 struct snd_ice1712 *ice = entry->private_data;
658 int reg, val; 658 int reg, val;
659 /* registers 0x0 - 0x14 */ 659 /* registers 0x0 - 0x14 */
660 for (reg = 0; reg <= 0x15; reg++) { 660 for (reg = 0; reg <= 0x15; reg++) {
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 6c0a11adb2a8..98a8eb3c92f7 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -79,6 +79,7 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
79 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, 79 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
80 { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, 80 { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF },
81 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, 81 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
82 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF },
82 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, 83 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
83 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 84 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
84 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 85 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
@@ -505,7 +506,8 @@ static const struct oxygen_model model_generic = {
505 PLAYBACK_2_TO_AC97_1 | 506 PLAYBACK_2_TO_AC97_1 |
506 CAPTURE_0_FROM_I2S_1 | 507 CAPTURE_0_FROM_I2S_1 |
507 CAPTURE_1_FROM_SPDIF | 508 CAPTURE_1_FROM_SPDIF |
508 CAPTURE_2_FROM_AC97_1, 509 CAPTURE_2_FROM_AC97_1 |
510 AC97_CD_INPUT,
509 .dac_channels = 8, 511 .dac_channels = 8,
510 .dac_volume_min = 0, 512 .dac_volume_min = 0,
511 .dac_volume_max = 255, 513 .dac_volume_max = 255,
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index a3409edcfb50..7d5222caa0a9 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -34,6 +34,7 @@
34 /* CAPTURE_3_FROM_I2S_3 not implemented */ 34 /* CAPTURE_3_FROM_I2S_3 not implemented */
35#define MIDI_OUTPUT 0x0800 35#define MIDI_OUTPUT 0x0800
36#define MIDI_INPUT 0x1000 36#define MIDI_INPUT 0x1000
37#define AC97_CD_INPUT 0x2000
37 38
38enum { 39enum {
39 CONTROL_SPDIF_PCM, 40 CONTROL_SPDIF_PCM,
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 7e93cf884437..e5ebe56fb0c5 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -308,25 +308,46 @@ static void oxygen_restore_eeprom(struct oxygen *chip,
308 } 308 }
309} 309}
310 310
311static void pci_bridge_magic(void) 311static void configure_pcie_bridge(struct pci_dev *pci)
312{ 312{
313 struct pci_dev *pci = NULL; 313 enum { PEX811X, PI7C9X110 };
314 static const struct pci_device_id bridge_ids[] = {
315 { PCI_VDEVICE(PLX, 0x8111), .driver_data = PEX811X },
316 { PCI_VDEVICE(PLX, 0x8112), .driver_data = PEX811X },
317 { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 },
318 { }
319 };
320 struct pci_dev *bridge;
321 const struct pci_device_id *id;
314 u32 tmp; 322 u32 tmp;
315 323
316 for (;;) { 324 if (!pci->bus || !pci->bus->self)
317 /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */ 325 return;
318 pci = pci_get_device(0x12d8, 0xe110, pci); 326 bridge = pci->bus->self;
319 if (!pci) 327
320 break; 328 id = pci_match_id(bridge_ids, bridge);
321 /* 329 if (!id)
322 * ... configure its secondary internal arbiter to park to 330 return;
323 * the secondary port, instead of to the last master. 331
324 */ 332 switch (id->driver_data) {
325 if (!pci_read_config_dword(pci, 0x40, &tmp)) { 333 case PEX811X: /* PLX PEX8111/PEX8112 PCIe/PCI bridge */
326 tmp |= 1; 334 pci_read_config_dword(bridge, 0x48, &tmp);
327 pci_write_config_dword(pci, 0x40, tmp); 335 tmp |= 1; /* enable blind prefetching */
328 } 336 tmp |= 1 << 11; /* enable beacon generation */
329 /* Why? Try asking C-Media. */ 337 pci_write_config_dword(bridge, 0x48, tmp);
338
339 pci_write_config_dword(bridge, 0x84, 0x0c);
340 pci_read_config_dword(bridge, 0x88, &tmp);
341 tmp &= ~(7 << 27);
342 tmp |= 2 << 27; /* set prefetch size to 128 bytes */
343 pci_write_config_dword(bridge, 0x88, tmp);
344 break;
345
346 case PI7C9X110: /* Pericom PI7C9X110 PCIe/PCI bridge */
347 pci_read_config_dword(bridge, 0x40, &tmp);
348 tmp |= 1; /* park the PCI arbiter to the sound chip */
349 pci_write_config_dword(bridge, 0x40, tmp);
350 break;
330 } 351 }
331} 352}
332 353
@@ -613,7 +634,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
613 snd_card_set_dev(card, &pci->dev); 634 snd_card_set_dev(card, &pci->dev);
614 card->private_free = oxygen_card_free; 635 card->private_free = oxygen_card_free;
615 636
616 pci_bridge_magic(); 637 configure_pcie_bridge(pci);
617 oxygen_init(chip); 638 oxygen_init(chip);
618 chip->model.init(chip); 639 chip->model.init(chip);
619 640
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index f375b8a27862..2849b36f5f7e 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -708,7 +708,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl,
708 .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \ 708 .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \
709 } 709 }
710 710
711static DECLARE_TLV_DB_SCALE(monitor_db_scale, -1000, 1000, 0); 711static DECLARE_TLV_DB_SCALE(monitor_db_scale, -600, 600, 0);
712static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0); 712static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0);
713static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0); 713static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0);
714 714
@@ -972,6 +972,9 @@ static int add_controls(struct oxygen *chip,
972 if (!strcmp(template.name, "Stereo Upmixing") && 972 if (!strcmp(template.name, "Stereo Upmixing") &&
973 chip->model.dac_channels == 2) 973 chip->model.dac_channels == 2)
974 continue; 974 continue;
975 if (!strncmp(template.name, "CD Capture ", 11) &&
976 !(chip->model.device_config & AC97_CD_INPUT))
977 continue;
975 if (!strcmp(template.name, "Master Playback Volume") && 978 if (!strcmp(template.name, "Master Playback Volume") &&
976 chip->model.dac_tlv) { 979 chip->model.dac_tlv) {
977 template.tlv.p = chip->model.dac_tlv; 980 template.tlv.p = chip->model.dac_tlv;
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index 9dff6954c397..814667442eb0 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -56,8 +56,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
56 .channels_max = 2, 56 .channels_max = 2,
57 .buffer_bytes_max = BUFFER_BYTES_MAX, 57 .buffer_bytes_max = BUFFER_BYTES_MAX,
58 .period_bytes_min = PERIOD_BYTES_MIN, 58 .period_bytes_min = PERIOD_BYTES_MIN,
59 .period_bytes_max = BUFFER_BYTES_MAX / 2, 59 .period_bytes_max = BUFFER_BYTES_MAX,
60 .periods_min = 2, 60 .periods_min = 1,
61 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, 61 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
62}; 62};
63static const struct snd_pcm_hardware oxygen_multichannel_hardware = { 63static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
@@ -82,8 +82,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
82 .channels_max = 8, 82 .channels_max = 8,
83 .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH, 83 .buffer_bytes_max = BUFFER_BYTES_MAX_MULTICH,
84 .period_bytes_min = PERIOD_BYTES_MIN, 84 .period_bytes_min = PERIOD_BYTES_MIN,
85 .period_bytes_max = BUFFER_BYTES_MAX_MULTICH / 2, 85 .period_bytes_max = BUFFER_BYTES_MAX_MULTICH,
86 .periods_min = 2, 86 .periods_min = 1,
87 .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN, 87 .periods_max = BUFFER_BYTES_MAX_MULTICH / PERIOD_BYTES_MIN,
88}; 88};
89static const struct snd_pcm_hardware oxygen_ac97_hardware = { 89static const struct snd_pcm_hardware oxygen_ac97_hardware = {
@@ -100,8 +100,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
100 .channels_max = 2, 100 .channels_max = 2,
101 .buffer_bytes_max = BUFFER_BYTES_MAX, 101 .buffer_bytes_max = BUFFER_BYTES_MAX,
102 .period_bytes_min = PERIOD_BYTES_MIN, 102 .period_bytes_min = PERIOD_BYTES_MIN,
103 .period_bytes_max = BUFFER_BYTES_MAX / 2, 103 .period_bytes_max = BUFFER_BYTES_MAX,
104 .periods_min = 2, 104 .periods_min = 1,
105 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, 105 .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
106}; 106};
107 107
diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h
index 72de159d4567..4dcd41b78258 100644
--- a/sound/pci/oxygen/oxygen_regs.h
+++ b/sound/pci/oxygen/oxygen_regs.h
@@ -436,13 +436,15 @@
436/* OXYGEN_CHANNEL_* */ 436/* OXYGEN_CHANNEL_* */
437 437
438#define OXYGEN_CODEC_VERSION 0xe4 438#define OXYGEN_CODEC_VERSION 0xe4
439#define OXYGEN_XCID_MASK 0x07 439#define OXYGEN_CODEC_ID_MASK 0x07
440 440
441#define OXYGEN_REVISION 0xe6 441#define OXYGEN_REVISION 0xe6
442#define OXYGEN_REVISION_XPKGID_MASK 0x0007 442#define OXYGEN_PACKAGE_ID_MASK 0x0007
443#define OXYGEN_PACKAGE_ID_8786 0x0004
444#define OXYGEN_PACKAGE_ID_8787 0x0006
445#define OXYGEN_PACKAGE_ID_8788 0x0007
443#define OXYGEN_REVISION_MASK 0xfff8 446#define OXYGEN_REVISION_MASK 0xfff8
444#define OXYGEN_REVISION_2 0x0008 /* bit flag */ 447#define OXYGEN_REVISION_2 0x0008
445#define OXYGEN_REVISION_8787 0x0014 /* 8 bits */
446 448
447#define OXYGEN_OFFSIN_48K 0xe8 449#define OXYGEN_OFFSIN_48K 0xe8
448#define OXYGEN_OFFSBASE_48K 0xe9 450#define OXYGEN_OFFSBASE_48K 0xe9
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 06c863e86e3d..469010a8b849 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -25,9 +25,9 @@
25#include "xonar.h" 25#include "xonar.h"
26 26
27MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 27MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
28MODULE_DESCRIPTION("Asus AVx00 driver"); 28MODULE_DESCRIPTION("Asus Virtuoso driver");
29MODULE_LICENSE("GPL v2"); 29MODULE_LICENSE("GPL v2");
30MODULE_SUPPORTED_DEVICE("{{Asus,AV100},{Asus,AV200}}"); 30MODULE_SUPPORTED_DEVICE("{{Asus,AV66},{Asus,AV100},{Asus,AV200}}");
31 31
32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 32static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 33static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -49,6 +49,7 @@ static DEFINE_PCI_DEVICE_TABLE(xonar_ids) = {
49 { OXYGEN_PCI_SUBID(0x1043, 0x834f) }, 49 { OXYGEN_PCI_SUBID(0x1043, 0x834f) },
50 { OXYGEN_PCI_SUBID(0x1043, 0x835c) }, 50 { OXYGEN_PCI_SUBID(0x1043, 0x835c) },
51 { OXYGEN_PCI_SUBID(0x1043, 0x835d) }, 51 { OXYGEN_PCI_SUBID(0x1043, 0x835d) },
52 { OXYGEN_PCI_SUBID(0x1043, 0x835e) },
52 { OXYGEN_PCI_SUBID(0x1043, 0x838e) }, 53 { OXYGEN_PCI_SUBID(0x1043, 0x838e) },
53 { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, 54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
54 { } 55 { }
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index 7c4986b27f2b..aa27c31049af 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -367,13 +367,6 @@ static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip,
367 367
368static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0); 368static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0);
369 369
370static int xonar_d1_control_filter(struct snd_kcontrol_new *template)
371{
372 if (!strncmp(template->name, "CD Capture ", 11))
373 return 1; /* no CD input */
374 return 0;
375}
376
377static int xonar_d1_mixer_init(struct oxygen *chip) 370static int xonar_d1_mixer_init(struct oxygen *chip)
378{ 371{
379 int err; 372 int err;
@@ -391,7 +384,6 @@ static const struct oxygen_model model_xonar_d1 = {
391 .longname = "Asus Virtuoso 100", 384 .longname = "Asus Virtuoso 100",
392 .chip = "AV200", 385 .chip = "AV200",
393 .init = xonar_d1_init, 386 .init = xonar_d1_init,
394 .control_filter = xonar_d1_control_filter,
395 .mixer_init = xonar_d1_mixer_init, 387 .mixer_init = xonar_d1_mixer_init,
396 .cleanup = xonar_d1_cleanup, 388 .cleanup = xonar_d1_cleanup,
397 .suspend = xonar_d1_suspend, 389 .suspend = xonar_d1_suspend,
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index ba18fb546b4f..d491fd6c0be2 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -132,6 +132,18 @@
132 * GPIO 5 <- 0 132 * GPIO 5 <- 0
133 */ 133 */
134 134
135/*
136 * Xonar HDAV1.3 Slim
137 * ------------------
138 *
139 * CMI8788:
140 *
141 * GPIO 1 -> enable output
142 *
143 * TXD -> HDMI controller
144 * RXD <- HDMI controller
145 */
146
135#include <linux/pci.h> 147#include <linux/pci.h>
136#include <linux/delay.h> 148#include <linux/delay.h>
137#include <linux/mutex.h> 149#include <linux/mutex.h>
@@ -362,7 +374,6 @@ static void xonar_st_init_common(struct oxygen *chip)
362{ 374{
363 struct xonar_pcm179x *data = chip->model_data; 375 struct xonar_pcm179x *data = chip->model_data;
364 376
365 data->generic.anti_pop_delay = 100;
366 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; 377 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE;
367 data->dacs = chip->model.private_data ? 4 : 1; 378 data->dacs = chip->model.private_data ? 4 : 1;
368 data->hp_gain_offset = 2*-18; 379 data->hp_gain_offset = 2*-18;
@@ -408,6 +419,7 @@ static void xonar_st_init(struct oxygen *chip)
408{ 419{
409 struct xonar_pcm179x *data = chip->model_data; 420 struct xonar_pcm179x *data = chip->model_data;
410 421
422 data->generic.anti_pop_delay = 100;
411 data->has_cs2000 = 1; 423 data->has_cs2000 = 1;
412 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; 424 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1;
413 425
@@ -428,6 +440,7 @@ static void xonar_stx_init(struct oxygen *chip)
428 struct xonar_pcm179x *data = chip->model_data; 440 struct xonar_pcm179x *data = chip->model_data;
429 441
430 xonar_st_init_i2c(chip); 442 xonar_st_init_i2c(chip);
443 data->generic.anti_pop_delay = 800;
431 data->generic.ext_power_reg = OXYGEN_GPI_DATA; 444 data->generic.ext_power_reg = OXYGEN_GPI_DATA;
432 data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 445 data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
433 data->generic.ext_power_bit = GPI_EXT_POWER; 446 data->generic.ext_power_bit = GPI_EXT_POWER;
@@ -915,13 +928,6 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
915 return 0; 928 return 0;
916} 929}
917 930
918static int xonar_st_control_filter(struct snd_kcontrol_new *template)
919{
920 if (!strncmp(template->name, "CD Capture ", 11))
921 return 1; /* no CD input */
922 return 0;
923}
924
925static int add_pcm1796_controls(struct oxygen *chip) 931static int add_pcm1796_controls(struct oxygen *chip)
926{ 932{
927 int err; 933 int err;
@@ -991,7 +997,8 @@ static const struct oxygen_model model_xonar_d2 = {
991 CAPTURE_0_FROM_I2S_2 | 997 CAPTURE_0_FROM_I2S_2 |
992 CAPTURE_1_FROM_SPDIF | 998 CAPTURE_1_FROM_SPDIF |
993 MIDI_OUTPUT | 999 MIDI_OUTPUT |
994 MIDI_INPUT, 1000 MIDI_INPUT |
1001 AC97_CD_INPUT,
995 .dac_channels = 8, 1002 .dac_channels = 8,
996 .dac_volume_min = 255 - 2*60, 1003 .dac_volume_min = 255 - 2*60,
997 .dac_volume_max = 255, 1004 .dac_volume_max = 255,
@@ -1037,7 +1044,6 @@ static const struct oxygen_model model_xonar_st = {
1037 .longname = "Asus Virtuoso 100", 1044 .longname = "Asus Virtuoso 100",
1038 .chip = "AV200", 1045 .chip = "AV200",
1039 .init = xonar_st_init, 1046 .init = xonar_st_init,
1040 .control_filter = xonar_st_control_filter,
1041 .mixer_init = xonar_st_mixer_init, 1047 .mixer_init = xonar_st_mixer_init,
1042 .cleanup = xonar_st_cleanup, 1048 .cleanup = xonar_st_cleanup,
1043 .suspend = xonar_st_suspend, 1049 .suspend = xonar_st_suspend,
@@ -1108,6 +1114,9 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1108 chip->model.resume = xonar_stx_resume; 1114 chip->model.resume = xonar_stx_resume;
1109 chip->model.set_dac_params = set_pcm1796_params; 1115 chip->model.set_dac_params = set_pcm1796_params;
1110 break; 1116 break;
1117 case 0x835e:
1118 snd_printk(KERN_ERR "the HDAV1.3 Slim is not supported\n");
1119 return -ENODEV;
1111 default: 1120 default:
1112 return -EINVAL; 1121 return -EINVAL;
1113 } 1122 }
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index b82c1cfa96f5..200f7601276f 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -25,16 +25,24 @@
25 * SPI 0 -> WM8766 (surround, center/LFE, back) 25 * SPI 0 -> WM8766 (surround, center/LFE, back)
26 * SPI 1 -> WM8776 (front, input) 26 * SPI 1 -> WM8776 (front, input)
27 * 27 *
28 * GPIO 4 <- headphone detect 28 * GPIO 4 <- headphone detect, 0 = plugged
29 * GPIO 6 -> route input jack to input 1/2 (1/0) 29 * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
30 * GPIO 7 -> enable output to speakers 30 * GPIO 7 -> enable output to front L/R speaker channels
31 * GPIO 8 -> enable output to speakers 31 * GPIO 8 -> enable output to other speaker channels and front panel headphone
32 *
33 * WM8766:
34 *
35 * input 1 <- line
36 * input 2 <- mic
37 * input 3 <- front mic
38 * input 4 <- aux
32 */ 39 */
33 40
34#include <linux/pci.h> 41#include <linux/pci.h>
35#include <linux/delay.h> 42#include <linux/delay.h>
36#include <sound/control.h> 43#include <sound/control.h>
37#include <sound/core.h> 44#include <sound/core.h>
45#include <sound/jack.h>
38#include <sound/pcm.h> 46#include <sound/pcm.h>
39#include <sound/pcm_params.h> 47#include <sound/pcm_params.h>
40#include <sound/tlv.h> 48#include <sound/tlv.h>
@@ -44,7 +52,8 @@
44 52
45#define GPIO_DS_HP_DETECT 0x0010 53#define GPIO_DS_HP_DETECT 0x0010
46#define GPIO_DS_INPUT_ROUTE 0x0040 54#define GPIO_DS_INPUT_ROUTE 0x0040
47#define GPIO_DS_OUTPUT_ENABLE 0x0180 55#define GPIO_DS_OUTPUT_FRONTLR 0x0080
56#define GPIO_DS_OUTPUT_ENABLE 0x0100
48 57
49#define LC_CONTROL_LIMITER 0x40000000 58#define LC_CONTROL_LIMITER 0x40000000
50#define LC_CONTROL_ALC 0x20000000 59#define LC_CONTROL_ALC 0x20000000
@@ -56,6 +65,7 @@ struct xonar_wm87x6 {
56 struct snd_kcontrol *line_adcmux_control; 65 struct snd_kcontrol *line_adcmux_control;
57 struct snd_kcontrol *mic_adcmux_control; 66 struct snd_kcontrol *mic_adcmux_control;
58 struct snd_kcontrol *lc_controls[13]; 67 struct snd_kcontrol *lc_controls[13];
68 struct snd_jack *hp_jack;
59}; 69};
60 70
61static void wm8776_write(struct oxygen *chip, 71static void wm8776_write(struct oxygen *chip,
@@ -97,8 +107,12 @@ static void wm8766_write(struct oxygen *chip,
97 (0 << OXYGEN_SPI_CODEC_SHIFT) | 107 (0 << OXYGEN_SPI_CODEC_SHIFT) |
98 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 108 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
99 (reg << 9) | value); 109 (reg << 9) | value);
100 if (reg < ARRAY_SIZE(data->wm8766_regs)) 110 if (reg < ARRAY_SIZE(data->wm8766_regs)) {
111 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
112 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
113 value &= ~WM8766_UPDATE;
101 data->wm8766_regs[reg] = value; 114 data->wm8766_regs[reg] = value;
115 }
102} 116}
103 117
104static void wm8766_write_cached(struct oxygen *chip, 118static void wm8766_write_cached(struct oxygen *chip,
@@ -107,12 +121,8 @@ static void wm8766_write_cached(struct oxygen *chip,
107 struct xonar_wm87x6 *data = chip->model_data; 121 struct xonar_wm87x6 *data = chip->model_data;
108 122
109 if (reg >= ARRAY_SIZE(data->wm8766_regs) || 123 if (reg >= ARRAY_SIZE(data->wm8766_regs) ||
110 value != data->wm8766_regs[reg]) { 124 value != data->wm8766_regs[reg])
111 if ((reg >= WM8766_LDA1 && reg <= WM8766_RDA1) ||
112 (reg >= WM8766_LDA2 && reg <= WM8766_MASTDA))
113 value &= ~WM8766_UPDATE;
114 wm8766_write(chip, reg, value); 125 wm8766_write(chip, reg, value);
115 }
116} 126}
117 127
118static void wm8776_registers_init(struct oxygen *chip) 128static void wm8776_registers_init(struct oxygen *chip)
@@ -141,7 +151,10 @@ static void wm8776_registers_init(struct oxygen *chip)
141 151
142static void wm8766_registers_init(struct oxygen *chip) 152static void wm8766_registers_init(struct oxygen *chip)
143{ 153{
154 struct xonar_wm87x6 *data = chip->model_data;
155
144 wm8766_write(chip, WM8766_RESET, 0); 156 wm8766_write(chip, WM8766_RESET, 0);
157 wm8766_write(chip, WM8766_DAC_CTRL, data->wm8766_regs[WM8766_DAC_CTRL]);
145 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24); 158 wm8766_write(chip, WM8766_INT_CTRL, WM8766_FMT_LJUST | WM8766_IWL_24);
146 wm8766_write(chip, WM8766_DAC_CTRL2, 159 wm8766_write(chip, WM8766_DAC_CTRL2,
147 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 160 WM8766_ZCD | (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
@@ -170,6 +183,40 @@ static void wm8776_init(struct oxygen *chip)
170 wm8776_registers_init(chip); 183 wm8776_registers_init(chip);
171} 184}
172 185
186static void wm8766_init(struct oxygen *chip)
187{
188 struct xonar_wm87x6 *data = chip->model_data;
189
190 data->wm8766_regs[WM8766_DAC_CTRL] =
191 WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
192 wm8766_registers_init(chip);
193}
194
195static void xonar_ds_handle_hp_jack(struct oxygen *chip)
196{
197 struct xonar_wm87x6 *data = chip->model_data;
198 bool hp_plugged;
199 unsigned int reg;
200
201 mutex_lock(&chip->mutex);
202
203 hp_plugged = !(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
204 GPIO_DS_HP_DETECT);
205
206 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
207 hp_plugged ? 0 : GPIO_DS_OUTPUT_FRONTLR,
208 GPIO_DS_OUTPUT_FRONTLR);
209
210 reg = data->wm8766_regs[WM8766_DAC_CTRL] & ~WM8766_MUTEALL;
211 if (hp_plugged)
212 reg |= WM8766_MUTEALL;
213 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
214
215 snd_jack_report(data->hp_jack, hp_plugged ? SND_JACK_HEADPHONE : 0);
216
217 mutex_unlock(&chip->mutex);
218}
219
173static void xonar_ds_init(struct oxygen *chip) 220static void xonar_ds_init(struct oxygen *chip)
174{ 221{
175 struct xonar_wm87x6 *data = chip->model_data; 222 struct xonar_wm87x6 *data = chip->model_data;
@@ -178,16 +225,22 @@ static void xonar_ds_init(struct oxygen *chip)
178 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE; 225 data->generic.output_enable_bit = GPIO_DS_OUTPUT_ENABLE;
179 226
180 wm8776_init(chip); 227 wm8776_init(chip);
181 wm8766_registers_init(chip); 228 wm8766_init(chip);
182 229
183 oxygen_write16_masked(chip, OXYGEN_GPIO_CONTROL, GPIO_DS_INPUT_ROUTE, 230 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
184 GPIO_DS_HP_DETECT | GPIO_DS_INPUT_ROUTE); 231 GPIO_DS_INPUT_ROUTE | GPIO_DS_OUTPUT_FRONTLR);
232 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
233 GPIO_DS_HP_DETECT);
185 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE); 234 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DS_INPUT_ROUTE);
186 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT); 235 oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, GPIO_DS_HP_DETECT);
187 chip->interrupt_mask |= OXYGEN_INT_GPIO; 236 chip->interrupt_mask |= OXYGEN_INT_GPIO;
188 237
189 xonar_enable_output(chip); 238 xonar_enable_output(chip);
190 239
240 snd_jack_new(chip->card, "Headphone",
241 SND_JACK_HEADPHONE, &data->hp_jack);
242 xonar_ds_handle_hp_jack(chip);
243
191 snd_component_add(chip->card, "WM8776"); 244 snd_component_add(chip->card, "WM8776");
192 snd_component_add(chip->card, "WM8766"); 245 snd_component_add(chip->card, "WM8766");
193} 246}
@@ -208,6 +261,7 @@ static void xonar_ds_resume(struct oxygen *chip)
208 wm8776_registers_init(chip); 261 wm8776_registers_init(chip);
209 wm8766_registers_init(chip); 262 wm8766_registers_init(chip);
210 xonar_enable_output(chip); 263 xonar_enable_output(chip);
264 xonar_ds_handle_hp_jack(chip);
211} 265}
212 266
213static void wm8776_adc_hardware_filter(unsigned int channel, 267static void wm8776_adc_hardware_filter(unsigned int channel,
@@ -323,12 +377,27 @@ static void update_wm87x6_mute(struct oxygen *chip)
323 (chip->dac_mute ? WM8766_DMUTE_MASK : 0)); 377 (chip->dac_mute ? WM8766_DMUTE_MASK : 0));
324} 378}
325 379
326static void xonar_ds_gpio_changed(struct oxygen *chip) 380static void update_wm8766_center_lfe_mix(struct oxygen *chip, bool mixed)
327{ 381{
328 u16 bits; 382 struct xonar_wm87x6 *data = chip->model_data;
383 unsigned int reg;
329 384
330 bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 385 /*
331 snd_printk(KERN_INFO "HP detect: %d\n", !!(bits & GPIO_DS_HP_DETECT)); 386 * The WM8766 can mix left and right channels, but this setting
387 * applies to all three stereo pairs.
388 */
389 reg = data->wm8766_regs[WM8766_DAC_CTRL] &
390 ~(WM8766_PL_LEFT_MASK | WM8766_PL_RIGHT_MASK);
391 if (mixed)
392 reg |= WM8766_PL_LEFT_LRMIX | WM8766_PL_RIGHT_LRMIX;
393 else
394 reg |= WM8766_PL_LEFT_LEFT | WM8766_PL_RIGHT_RIGHT;
395 wm8766_write_cached(chip, WM8766_DAC_CTRL, reg);
396}
397
398static void xonar_ds_gpio_changed(struct oxygen *chip)
399{
400 xonar_ds_handle_hp_jack(chip);
332} 401}
333 402
334static int wm8776_bit_switch_get(struct snd_kcontrol *ctl, 403static int wm8776_bit_switch_get(struct snd_kcontrol *ctl,
@@ -896,7 +965,10 @@ static const struct snd_kcontrol_new ds_controls[] = {
896 .put = wm8776_input_mux_put, 965 .put = wm8776_input_mux_put,
897 .private_value = 1 << 1, 966 .private_value = 1 << 1,
898 }, 967 },
899 WM8776_BIT_SWITCH("Aux", WM8776_ADCMUX, 1 << 2, 0, 0), 968 WM8776_BIT_SWITCH("Front Mic Capture Switch",
969 WM8776_ADCMUX, 1 << 2, 0, 0),
970 WM8776_BIT_SWITCH("Aux Capture Switch",
971 WM8776_ADCMUX, 1 << 3, 0, 0),
900 { 972 {
901 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 973 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
902 .name = "ADC Filter Capture Enum", 974 .name = "ADC Filter Capture Enum",
@@ -956,13 +1028,6 @@ static const struct snd_kcontrol_new lc_controls[] = {
956 LC_CONTROL_ALC, wm8776_ngth_db_scale), 1028 LC_CONTROL_ALC, wm8776_ngth_db_scale),
957}; 1029};
958 1030
959static int xonar_ds_control_filter(struct snd_kcontrol_new *template)
960{
961 if (!strncmp(template->name, "CD Capture ", 11))
962 return 1; /* no CD input */
963 return 0;
964}
965
966static int xonar_ds_mixer_init(struct oxygen *chip) 1031static int xonar_ds_mixer_init(struct oxygen *chip)
967{ 1032{
968 struct xonar_wm87x6 *data = chip->model_data; 1033 struct xonar_wm87x6 *data = chip->model_data;
@@ -999,10 +1064,9 @@ static int xonar_ds_mixer_init(struct oxygen *chip)
999 1064
1000static const struct oxygen_model model_xonar_ds = { 1065static const struct oxygen_model model_xonar_ds = {
1001 .shortname = "Xonar DS", 1066 .shortname = "Xonar DS",
1002 .longname = "Asus Virtuoso 200", 1067 .longname = "Asus Virtuoso 66",
1003 .chip = "AV200", 1068 .chip = "AV200",
1004 .init = xonar_ds_init, 1069 .init = xonar_ds_init,
1005 .control_filter = xonar_ds_control_filter,
1006 .mixer_init = xonar_ds_mixer_init, 1070 .mixer_init = xonar_ds_mixer_init,
1007 .cleanup = xonar_ds_cleanup, 1071 .cleanup = xonar_ds_cleanup,
1008 .suspend = xonar_ds_suspend, 1072 .suspend = xonar_ds_suspend,
@@ -1013,6 +1077,7 @@ static const struct oxygen_model model_xonar_ds = {
1013 .set_adc_params = set_wm8776_adc_params, 1077 .set_adc_params = set_wm8776_adc_params,
1014 .update_dac_volume = update_wm87x6_volume, 1078 .update_dac_volume = update_wm87x6_volume,
1015 .update_dac_mute = update_wm87x6_mute, 1079 .update_dac_mute = update_wm87x6_mute,
1080 .update_center_lfe_mix = update_wm8766_center_lfe_mix,
1016 .gpio_changed = xonar_ds_gpio_changed, 1081 .gpio_changed = xonar_ds_gpio_changed,
1017 .dac_tlv = wm87x6_dac_db_scale, 1082 .dac_tlv = wm87x6_dac_db_scale,
1018 .model_data_size = sizeof(struct xonar_wm87x6), 1083 .model_data_size = sizeof(struct xonar_wm87x6),
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index d19dc052c391..d5f5b440fc40 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -1527,14 +1527,14 @@ snd_rme96_free(void *private_data)
1527static void 1527static void
1528snd_rme96_free_spdif_pcm(struct snd_pcm *pcm) 1528snd_rme96_free_spdif_pcm(struct snd_pcm *pcm)
1529{ 1529{
1530 struct rme96 *rme96 = (struct rme96 *) pcm->private_data; 1530 struct rme96 *rme96 = pcm->private_data;
1531 rme96->spdif_pcm = NULL; 1531 rme96->spdif_pcm = NULL;
1532} 1532}
1533 1533
1534static void 1534static void
1535snd_rme96_free_adat_pcm(struct snd_pcm *pcm) 1535snd_rme96_free_adat_pcm(struct snd_pcm *pcm)
1536{ 1536{
1537 struct rme96 *rme96 = (struct rme96 *) pcm->private_data; 1537 struct rme96 *rme96 = pcm->private_data;
1538 rme96->adat_pcm = NULL; 1538 rme96->adat_pcm = NULL;
1539} 1539}
1540 1540
@@ -1661,7 +1661,7 @@ static void
1661snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1661snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
1662{ 1662{
1663 int n; 1663 int n;
1664 struct rme96 *rme96 = (struct rme96 *)entry->private_data; 1664 struct rme96 *rme96 = entry->private_data;
1665 1665
1666 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); 1666 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1667 1667
@@ -2348,7 +2348,7 @@ snd_rme96_probe(struct pci_dev *pci,
2348 if (err < 0) 2348 if (err < 0)
2349 return err; 2349 return err;
2350 card->private_free = snd_rme96_card_free; 2350 card->private_free = snd_rme96_card_free;
2351 rme96 = (struct rme96 *)card->private_data; 2351 rme96 = card->private_data;
2352 rme96->card = card; 2352 rme96->card = card;
2353 rme96->pci = pci; 2353 rme96->pci = pci;
2354 snd_card_set_dev(card, &pci->dev); 2354 snd_card_set_dev(card, &pci->dev);
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index d6fa7bfd9aa1..0b720cf7783e 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -3284,7 +3284,7 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
3284static void 3284static void
3285snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 3285snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3286{ 3286{
3287 struct hdsp *hdsp = (struct hdsp *) entry->private_data; 3287 struct hdsp *hdsp = entry->private_data;
3288 unsigned int status; 3288 unsigned int status;
3289 unsigned int status2; 3289 unsigned int status2;
3290 char *pref_sync_ref; 3290 char *pref_sync_ref;
@@ -4566,7 +4566,7 @@ static int hdsp_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rm
4566 4566
4567static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg) 4567static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
4568{ 4568{
4569 struct hdsp *hdsp = (struct hdsp *)hw->private_data; 4569 struct hdsp *hdsp = hw->private_data;
4570 void __user *argp = (void __user *)arg; 4570 void __user *argp = (void __user *)arg;
4571 int err; 4571 int err;
4572 4572
@@ -5156,7 +5156,7 @@ static int snd_hdsp_free(struct hdsp *hdsp)
5156 5156
5157static void snd_hdsp_card_free(struct snd_card *card) 5157static void snd_hdsp_card_free(struct snd_card *card)
5158{ 5158{
5159 struct hdsp *hdsp = (struct hdsp *) card->private_data; 5159 struct hdsp *hdsp = card->private_data;
5160 5160
5161 if (hdsp) 5161 if (hdsp)
5162 snd_hdsp_free(hdsp); 5162 snd_hdsp_free(hdsp);
@@ -5182,7 +5182,7 @@ static int __devinit snd_hdsp_probe(struct pci_dev *pci,
5182 if (err < 0) 5182 if (err < 0)
5183 return err; 5183 return err;
5184 5184
5185 hdsp = (struct hdsp *) card->private_data; 5185 hdsp = card->private_data;
5186 card->private_free = snd_hdsp_card_free; 5186 card->private_free = snd_hdsp_card_free;
5187 hdsp->dev = dev; 5187 hdsp->dev = dev;
5188 hdsp->pci = pci; 5188 hdsp->pci = pci;
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index 20afdf9772ee..961d98297695 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -785,7 +785,7 @@ static int snapper_set_capture_source(struct pmac_tumbler *mix)
785 if (! mix->i2c.client) 785 if (! mix->i2c.client)
786 return -ENODEV; 786 return -ENODEV;
787 if (mix->capture_source) 787 if (mix->capture_source)
788 mix->acs = mix->acs |= 2; 788 mix->acs |= 2;
789 else 789 else
790 mix->acs &= ~2; 790 mix->acs &= ~2;
791 return i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs); 791 return i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs);
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 40eccfe9e358..4948a79f86a0 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -150,7 +150,7 @@ static int __init sffsdr_init(void)
150 sffsdr_snd_resources, 150 sffsdr_snd_resources,
151 ARRAY_SIZE(sffsdr_snd_resources)); 151 ARRAY_SIZE(sffsdr_snd_resources));
152 if (ret) { 152 if (ret) {
153 printk(KERN_ERR "platform device add ressources failed\n"); 153 printk(KERN_ERR "platform device add resources failed\n");
154 goto error; 154 goto error;
155 } 155 }
156 156
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
index 209c25994c7e..4719558289d4 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
@@ -182,7 +182,7 @@ static int neo1973_gta02_voice_hw_params(
182 if (ret < 0) 182 if (ret < 0)
183 return ret; 183 return ret;
184 184
185 /* configue and enable PLL for 12.288MHz output */ 185 /* configure and enable PLL for 12.288MHz output */
186 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 186 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
187 iis_clkrate / 4, 12288000); 187 iis_clkrate / 4, 12288000);
188 if (ret < 0) 188 if (ret < 0)
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 0cb4f86f6d1e..4ac620988e7c 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -201,7 +201,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
201 if (ret < 0) 201 if (ret < 0)
202 return ret; 202 return ret;
203 203
204 /* configue and enable PLL for 12.288MHz output */ 204 /* configure and enable PLL for 12.288MHz output */
205 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 205 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
206 iis_clkrate / 4, 12288000); 206 iis_clkrate / 4, 12288000);
207 if (ret < 0) 207 if (ret < 0)
diff --git a/sound/synth/emux/emux_hwdep.c b/sound/synth/emux/emux_hwdep.c
index ff0b2a8fd25b..5ae1eae9f6db 100644
--- a/sound/synth/emux/emux_hwdep.c
+++ b/sound/synth/emux/emux_hwdep.c
@@ -128,6 +128,9 @@ snd_emux_init_hwdep(struct snd_emux *emu)
128 strcpy(hw->name, SNDRV_EMUX_HWDEP_NAME); 128 strcpy(hw->name, SNDRV_EMUX_HWDEP_NAME);
129 hw->iface = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE; 129 hw->iface = SNDRV_HWDEP_IFACE_EMUX_WAVETABLE;
130 hw->ops.ioctl = snd_emux_hwdep_ioctl; 130 hw->ops.ioctl = snd_emux_hwdep_ioctl;
131 /* The ioctl parameter types are compatible between 32- and
132 * 64-bit architectures, so use the same function. */
133 hw->ops.ioctl_compat = snd_emux_hwdep_ioctl;
131 hw->exclusive = 1; 134 hw->exclusive = 1;
132 hw->private_data = emu; 135 hw->private_data = emu;
133 if ((err = snd_card_register(emu->card)) < 0) 136 if ((err = snd_card_register(emu->card)) < 0)
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
index 44d6d2ec964f..112984f4080f 100644
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -65,6 +65,7 @@ config SND_USB_CAIAQ
65 * Native Instruments Guitar Rig Session I/O 65 * Native Instruments Guitar Rig Session I/O
66 * Native Instruments Guitar Rig mobile 66 * Native Instruments Guitar Rig mobile
67 * Native Instruments Traktor Kontrol X1 67 * Native Instruments Traktor Kontrol X1
68 * Native Instruments Traktor Kontrol S4
68 69
69 To compile this driver as a module, choose M here: the module 70 To compile this driver as a module, choose M here: the module
70 will be called snd-usb-caiaq. 71 will be called snd-usb-caiaq.
@@ -82,6 +83,7 @@ config SND_USB_CAIAQ_INPUT
82 * Native Instruments Kore Controller 83 * Native Instruments Kore Controller
83 * Native Instruments Kore Controller 2 84 * Native Instruments Kore Controller 2
84 * Native Instruments Audio Kontrol 1 85 * Native Instruments Audio Kontrol 1
86 * Native Instruments Traktor Kontrol S4
85 87
86config SND_USB_US122L 88config SND_USB_US122L
87 tristate "Tascam US-122L USB driver" 89 tristate "Tascam US-122L USB driver"
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 4328cad6c3a2..68b97477577b 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -111,7 +111,7 @@ static int stream_start(struct snd_usb_caiaqdev *dev)
111 memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); 111 memset(dev->sub_capture, 0, sizeof(dev->sub_capture));
112 dev->input_panic = 0; 112 dev->input_panic = 0;
113 dev->output_panic = 0; 113 dev->output_panic = 0;
114 dev->first_packet = 1; 114 dev->first_packet = 4;
115 dev->streaming = 1; 115 dev->streaming = 1;
116 dev->warned = 0; 116 dev->warned = 0;
117 117
@@ -169,7 +169,7 @@ static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream)
169} 169}
170 170
171static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, 171static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub,
172 struct snd_pcm_hw_params *hw_params) 172 struct snd_pcm_hw_params *hw_params)
173{ 173{
174 debug("%s(%p)\n", __func__, sub); 174 debug("%s(%p)\n", __func__, sub);
175 return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); 175 return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params));
@@ -189,7 +189,7 @@ static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub)
189#endif 189#endif
190 190
191static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, 191static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
192 48000, 64000, 88200, 96000, 176400, 192000 }; 192 48000, 64000, 88200, 96000, 176400, 192000 };
193 193
194static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) 194static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
195{ 195{
@@ -201,12 +201,39 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
201 debug("%s(%p)\n", __func__, substream); 201 debug("%s(%p)\n", __func__, substream);
202 202
203 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 203 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
204 dev->period_out_count[index] = BYTES_PER_SAMPLE + 1; 204 int out_pos;
205 dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1; 205
206 switch (dev->spec.data_alignment) {
207 case 0:
208 case 2:
209 out_pos = BYTES_PER_SAMPLE + 1;
210 break;
211 case 3:
212 default:
213 out_pos = 0;
214 break;
215 }
216
217 dev->period_out_count[index] = out_pos;
218 dev->audio_out_buf_pos[index] = out_pos;
206 } else { 219 } else {
207 int in_pos = (dev->spec.data_alignment == 2) ? 0 : 2; 220 int in_pos;
208 dev->period_in_count[index] = BYTES_PER_SAMPLE + in_pos; 221
209 dev->audio_in_buf_pos[index] = BYTES_PER_SAMPLE + in_pos; 222 switch (dev->spec.data_alignment) {
223 case 0:
224 in_pos = BYTES_PER_SAMPLE + 2;
225 break;
226 case 2:
227 in_pos = BYTES_PER_SAMPLE;
228 break;
229 case 3:
230 default:
231 in_pos = 0;
232 break;
233 }
234
235 dev->period_in_count[index] = in_pos;
236 dev->audio_in_buf_pos[index] = in_pos;
210 } 237 }
211 238
212 if (dev->streaming) 239 if (dev->streaming)
@@ -221,7 +248,7 @@ static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream)
221 snd_pcm_limit_hw_rates(runtime); 248 snd_pcm_limit_hw_rates(runtime);
222 249
223 bytes_per_sample = BYTES_PER_SAMPLE; 250 bytes_per_sample = BYTES_PER_SAMPLE;
224 if (dev->spec.data_alignment == 2) 251 if (dev->spec.data_alignment >= 2)
225 bytes_per_sample++; 252 bytes_per_sample++;
226 253
227 bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) 254 bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE)
@@ -253,6 +280,8 @@ static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd)
253{ 280{
254 struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); 281 struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
255 282
283 debug("%s(%p) cmd %d\n", __func__, sub, cmd);
284
256 switch (cmd) { 285 switch (cmd) {
257 case SNDRV_PCM_TRIGGER_START: 286 case SNDRV_PCM_TRIGGER_START:
258 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 287 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
@@ -402,6 +431,61 @@ static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev,
402 } 431 }
403} 432}
404 433
434static void read_in_urb_mode3(struct snd_usb_caiaqdev *dev,
435 const struct urb *urb,
436 const struct usb_iso_packet_descriptor *iso)
437{
438 unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
439 int stream, i;
440
441 /* paranoia check */
442 if (iso->actual_length % (BYTES_PER_SAMPLE_USB * CHANNELS_PER_STREAM))
443 return;
444
445 for (i = 0; i < iso->actual_length;) {
446 for (stream = 0; stream < dev->n_streams; stream++) {
447 struct snd_pcm_substream *sub = dev->sub_capture[stream];
448 char *audio_buf = NULL;
449 int c, n, sz = 0;
450
451 if (sub && !dev->input_panic) {
452 struct snd_pcm_runtime *rt = sub->runtime;
453 audio_buf = rt->dma_area;
454 sz = frames_to_bytes(rt, rt->buffer_size);
455 }
456
457 for (c = 0; c < CHANNELS_PER_STREAM; c++) {
458 /* 3 audio data bytes, followed by 1 check byte */
459 if (audio_buf) {
460 for (n = 0; n < BYTES_PER_SAMPLE; n++) {
461 audio_buf[dev->audio_in_buf_pos[stream]++] = usb_buf[i+n];
462
463 if (dev->audio_in_buf_pos[stream] == sz)
464 dev->audio_in_buf_pos[stream] = 0;
465 }
466
467 dev->period_in_count[stream] += BYTES_PER_SAMPLE;
468 }
469
470 i += BYTES_PER_SAMPLE;
471
472 if (usb_buf[i] != ((stream << 1) | c) &&
473 !dev->first_packet) {
474 if (!dev->input_panic)
475 printk(" EXPECTED: %02x got %02x, c %d, stream %d, i %d\n",
476 ((stream << 1) | c), usb_buf[i], c, stream, i);
477 dev->input_panic = 1;
478 }
479
480 i++;
481 }
482 }
483 }
484
485 if (dev->first_packet > 0)
486 dev->first_packet--;
487}
488
405static void read_in_urb(struct snd_usb_caiaqdev *dev, 489static void read_in_urb(struct snd_usb_caiaqdev *dev,
406 const struct urb *urb, 490 const struct urb *urb,
407 const struct usb_iso_packet_descriptor *iso) 491 const struct usb_iso_packet_descriptor *iso)
@@ -419,6 +503,9 @@ static void read_in_urb(struct snd_usb_caiaqdev *dev,
419 case 2: 503 case 2:
420 read_in_urb_mode2(dev, urb, iso); 504 read_in_urb_mode2(dev, urb, iso);
421 break; 505 break;
506 case 3:
507 read_in_urb_mode3(dev, urb, iso);
508 break;
422 } 509 }
423 510
424 if ((dev->input_panic || dev->output_panic) && !dev->warned) { 511 if ((dev->input_panic || dev->output_panic) && !dev->warned) {
@@ -429,9 +516,9 @@ static void read_in_urb(struct snd_usb_caiaqdev *dev,
429 } 516 }
430} 517}
431 518
432static void fill_out_urb(struct snd_usb_caiaqdev *dev, 519static void fill_out_urb_mode_0(struct snd_usb_caiaqdev *dev,
433 struct urb *urb, 520 struct urb *urb,
434 const struct usb_iso_packet_descriptor *iso) 521 const struct usb_iso_packet_descriptor *iso)
435{ 522{
436 unsigned char *usb_buf = urb->transfer_buffer + iso->offset; 523 unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
437 struct snd_pcm_substream *sub; 524 struct snd_pcm_substream *sub;
@@ -457,9 +544,67 @@ static void fill_out_urb(struct snd_usb_caiaqdev *dev,
457 /* fill in the check bytes */ 544 /* fill in the check bytes */
458 if (dev->spec.data_alignment == 2 && 545 if (dev->spec.data_alignment == 2 &&
459 i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 546 i % (dev->n_streams * BYTES_PER_SAMPLE_USB) ==
460 (dev->n_streams * CHANNELS_PER_STREAM)) 547 (dev->n_streams * CHANNELS_PER_STREAM))
461 for (stream = 0; stream < dev->n_streams; stream++, i++) 548 for (stream = 0; stream < dev->n_streams; stream++, i++)
462 usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); 549 usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i);
550 }
551}
552
553static void fill_out_urb_mode_3(struct snd_usb_caiaqdev *dev,
554 struct urb *urb,
555 const struct usb_iso_packet_descriptor *iso)
556{
557 unsigned char *usb_buf = urb->transfer_buffer + iso->offset;
558 int stream, i;
559
560 for (i = 0; i < iso->length;) {
561 for (stream = 0; stream < dev->n_streams; stream++) {
562 struct snd_pcm_substream *sub = dev->sub_playback[stream];
563 char *audio_buf = NULL;
564 int c, n, sz = 0;
565
566 if (sub) {
567 struct snd_pcm_runtime *rt = sub->runtime;
568 audio_buf = rt->dma_area;
569 sz = frames_to_bytes(rt, rt->buffer_size);
570 }
571
572 for (c = 0; c < CHANNELS_PER_STREAM; c++) {
573 for (n = 0; n < BYTES_PER_SAMPLE; n++) {
574 if (audio_buf) {
575 usb_buf[i+n] = audio_buf[dev->audio_out_buf_pos[stream]++];
576
577 if (dev->audio_out_buf_pos[stream] == sz)
578 dev->audio_out_buf_pos[stream] = 0;
579 } else {
580 usb_buf[i+n] = 0;
581 }
582 }
583
584 if (audio_buf)
585 dev->period_out_count[stream] += BYTES_PER_SAMPLE;
586
587 i += BYTES_PER_SAMPLE;
588
589 /* fill in the check byte pattern */
590 usb_buf[i++] = (stream << 1) | c;
591 }
592 }
593 }
594}
595
596static inline void fill_out_urb(struct snd_usb_caiaqdev *dev,
597 struct urb *urb,
598 const struct usb_iso_packet_descriptor *iso)
599{
600 switch (dev->spec.data_alignment) {
601 case 0:
602 case 2:
603 fill_out_urb_mode_0(dev, urb, iso);
604 break;
605 case 3:
606 fill_out_urb_mode_3(dev, urb, iso);
607 break;
463 } 608 }
464} 609}
465 610
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c
index 91c804cd2782..00e5d0a469e1 100644
--- a/sound/usb/caiaq/control.c
+++ b/sound/usb/caiaq/control.c
@@ -55,6 +55,10 @@ static int control_info(struct snd_kcontrol *kcontrol,
55 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 55 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
56 maxval = 127; 56 maxval = 127;
57 break; 57 break;
58
59 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
60 maxval = 31;
61 break;
58 } 62 }
59 63
60 if (is_intval) { 64 if (is_intval) {
@@ -93,6 +97,7 @@ static int control_put(struct snd_kcontrol *kcontrol,
93 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); 97 struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol);
94 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); 98 struct snd_usb_caiaqdev *dev = caiaqdev(chip->card);
95 int pos = kcontrol->private_value; 99 int pos = kcontrol->private_value;
100 int v = ucontrol->value.integer.value[0];
96 unsigned char cmd = EP1_CMD_WRITE_IO; 101 unsigned char cmd = EP1_CMD_WRITE_IO;
97 102
98 if (dev->chip.usb_id == 103 if (dev->chip.usb_id ==
@@ -100,12 +105,27 @@ static int control_put(struct snd_kcontrol *kcontrol,
100 cmd = EP1_CMD_DIMM_LEDS; 105 cmd = EP1_CMD_DIMM_LEDS;
101 106
102 if (pos & CNT_INTVAL) { 107 if (pos & CNT_INTVAL) {
103 dev->control_state[pos & ~CNT_INTVAL] 108 int i = pos & ~CNT_INTVAL;
104 = ucontrol->value.integer.value[0]; 109
105 snd_usb_caiaq_send_command(dev, cmd, 110 dev->control_state[i] = v;
106 dev->control_state, sizeof(dev->control_state)); 111
112 if (dev->chip.usb_id ==
113 USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4)) {
114 int actual_len;
115
116 dev->ep8_out_buf[0] = i;
117 dev->ep8_out_buf[1] = v;
118
119 usb_bulk_msg(dev->chip.dev,
120 usb_sndbulkpipe(dev->chip.dev, 8),
121 dev->ep8_out_buf, sizeof(dev->ep8_out_buf),
122 &actual_len, 200);
123 } else {
124 snd_usb_caiaq_send_command(dev, cmd,
125 dev->control_state, sizeof(dev->control_state));
126 }
107 } else { 127 } else {
108 if (ucontrol->value.integer.value[0]) 128 if (v)
109 dev->control_state[pos / 8] |= 1 << (pos % 8); 129 dev->control_state[pos / 8] |= 1 << (pos % 8);
110 else 130 else
111 dev->control_state[pos / 8] &= ~(1 << (pos % 8)); 131 dev->control_state[pos / 8] &= ~(1 << (pos % 8));
@@ -296,6 +316,179 @@ static struct caiaq_controller kontrolx1_controller[] = {
296 { "LED Deck B: SYNC", 8 | CNT_INTVAL }, 316 { "LED Deck B: SYNC", 8 | CNT_INTVAL },
297}; 317};
298 318
319static struct caiaq_controller kontrols4_controller[] = {
320 { "LED: Master: Quant", 10 | CNT_INTVAL },
321 { "LED: Master: Headphone", 11 | CNT_INTVAL },
322 { "LED: Master: Master", 12 | CNT_INTVAL },
323 { "LED: Master: Snap", 14 | CNT_INTVAL },
324 { "LED: Master: Warning", 15 | CNT_INTVAL },
325 { "LED: Master: Master button", 112 | CNT_INTVAL },
326 { "LED: Master: Snap button", 113 | CNT_INTVAL },
327 { "LED: Master: Rec", 118 | CNT_INTVAL },
328 { "LED: Master: Size", 119 | CNT_INTVAL },
329 { "LED: Master: Quant button", 120 | CNT_INTVAL },
330 { "LED: Master: Browser button", 121 | CNT_INTVAL },
331 { "LED: Master: Play button", 126 | CNT_INTVAL },
332 { "LED: Master: Undo button", 127 | CNT_INTVAL },
333
334 { "LED: Channel A: >", 4 | CNT_INTVAL },
335 { "LED: Channel A: <", 5 | CNT_INTVAL },
336 { "LED: Channel A: Meter 1", 97 | CNT_INTVAL },
337 { "LED: Channel A: Meter 2", 98 | CNT_INTVAL },
338 { "LED: Channel A: Meter 3", 99 | CNT_INTVAL },
339 { "LED: Channel A: Meter 4", 100 | CNT_INTVAL },
340 { "LED: Channel A: Meter 5", 101 | CNT_INTVAL },
341 { "LED: Channel A: Meter 6", 102 | CNT_INTVAL },
342 { "LED: Channel A: Meter clip", 103 | CNT_INTVAL },
343 { "LED: Channel A: Active", 114 | CNT_INTVAL },
344 { "LED: Channel A: Cue", 116 | CNT_INTVAL },
345 { "LED: Channel A: FX1", 149 | CNT_INTVAL },
346 { "LED: Channel A: FX2", 148 | CNT_INTVAL },
347
348 { "LED: Channel B: >", 2 | CNT_INTVAL },
349 { "LED: Channel B: <", 3 | CNT_INTVAL },
350 { "LED: Channel B: Meter 1", 89 | CNT_INTVAL },
351 { "LED: Channel B: Meter 2", 90 | CNT_INTVAL },
352 { "LED: Channel B: Meter 3", 91 | CNT_INTVAL },
353 { "LED: Channel B: Meter 4", 92 | CNT_INTVAL },
354 { "LED: Channel B: Meter 5", 93 | CNT_INTVAL },
355 { "LED: Channel B: Meter 6", 94 | CNT_INTVAL },
356 { "LED: Channel B: Meter clip", 95 | CNT_INTVAL },
357 { "LED: Channel B: Active", 122 | CNT_INTVAL },
358 { "LED: Channel B: Cue", 125 | CNT_INTVAL },
359 { "LED: Channel B: FX1", 147 | CNT_INTVAL },
360 { "LED: Channel B: FX2", 146 | CNT_INTVAL },
361
362 { "LED: Channel C: >", 6 | CNT_INTVAL },
363 { "LED: Channel C: <", 7 | CNT_INTVAL },
364 { "LED: Channel C: Meter 1", 105 | CNT_INTVAL },
365 { "LED: Channel C: Meter 2", 106 | CNT_INTVAL },
366 { "LED: Channel C: Meter 3", 107 | CNT_INTVAL },
367 { "LED: Channel C: Meter 4", 108 | CNT_INTVAL },
368 { "LED: Channel C: Meter 5", 109 | CNT_INTVAL },
369 { "LED: Channel C: Meter 6", 110 | CNT_INTVAL },
370 { "LED: Channel C: Meter clip", 111 | CNT_INTVAL },
371 { "LED: Channel C: Active", 115 | CNT_INTVAL },
372 { "LED: Channel C: Cue", 117 | CNT_INTVAL },
373 { "LED: Channel C: FX1", 151 | CNT_INTVAL },
374 { "LED: Channel C: FX2", 150 | CNT_INTVAL },
375
376 { "LED: Channel D: >", 0 | CNT_INTVAL },
377 { "LED: Channel D: <", 1 | CNT_INTVAL },
378 { "LED: Channel D: Meter 1", 81 | CNT_INTVAL },
379 { "LED: Channel D: Meter 2", 82 | CNT_INTVAL },
380 { "LED: Channel D: Meter 3", 83 | CNT_INTVAL },
381 { "LED: Channel D: Meter 4", 84 | CNT_INTVAL },
382 { "LED: Channel D: Meter 5", 85 | CNT_INTVAL },
383 { "LED: Channel D: Meter 6", 86 | CNT_INTVAL },
384 { "LED: Channel D: Meter clip", 87 | CNT_INTVAL },
385 { "LED: Channel D: Active", 123 | CNT_INTVAL },
386 { "LED: Channel D: Cue", 124 | CNT_INTVAL },
387 { "LED: Channel D: FX1", 145 | CNT_INTVAL },
388 { "LED: Channel D: FX2", 144 | CNT_INTVAL },
389
390 { "LED: Deck A: 1 (blue)", 22 | CNT_INTVAL },
391 { "LED: Deck A: 1 (green)", 23 | CNT_INTVAL },
392 { "LED: Deck A: 2 (blue)", 20 | CNT_INTVAL },
393 { "LED: Deck A: 2 (green)", 21 | CNT_INTVAL },
394 { "LED: Deck A: 3 (blue)", 18 | CNT_INTVAL },
395 { "LED: Deck A: 3 (green)", 19 | CNT_INTVAL },
396 { "LED: Deck A: 4 (blue)", 16 | CNT_INTVAL },
397 { "LED: Deck A: 4 (green)", 17 | CNT_INTVAL },
398 { "LED: Deck A: Load", 44 | CNT_INTVAL },
399 { "LED: Deck A: Deck C button", 45 | CNT_INTVAL },
400 { "LED: Deck A: In", 47 | CNT_INTVAL },
401 { "LED: Deck A: Out", 46 | CNT_INTVAL },
402 { "LED: Deck A: Shift", 24 | CNT_INTVAL },
403 { "LED: Deck A: Sync", 27 | CNT_INTVAL },
404 { "LED: Deck A: Cue", 26 | CNT_INTVAL },
405 { "LED: Deck A: Play", 25 | CNT_INTVAL },
406 { "LED: Deck A: Tempo up", 33 | CNT_INTVAL },
407 { "LED: Deck A: Tempo down", 32 | CNT_INTVAL },
408 { "LED: Deck A: Master", 34 | CNT_INTVAL },
409 { "LED: Deck A: Keylock", 35 | CNT_INTVAL },
410 { "LED: Deck A: Deck A", 37 | CNT_INTVAL },
411 { "LED: Deck A: Deck C", 36 | CNT_INTVAL },
412 { "LED: Deck A: Samples", 38 | CNT_INTVAL },
413 { "LED: Deck A: On Air", 39 | CNT_INTVAL },
414 { "LED: Deck A: Sample 1", 31 | CNT_INTVAL },
415 { "LED: Deck A: Sample 2", 30 | CNT_INTVAL },
416 { "LED: Deck A: Sample 3", 29 | CNT_INTVAL },
417 { "LED: Deck A: Sample 4", 28 | CNT_INTVAL },
418 { "LED: Deck A: Digit 1 - A", 55 | CNT_INTVAL },
419 { "LED: Deck A: Digit 1 - B", 54 | CNT_INTVAL },
420 { "LED: Deck A: Digit 1 - C", 53 | CNT_INTVAL },
421 { "LED: Deck A: Digit 1 - D", 52 | CNT_INTVAL },
422 { "LED: Deck A: Digit 1 - E", 51 | CNT_INTVAL },
423 { "LED: Deck A: Digit 1 - F", 50 | CNT_INTVAL },
424 { "LED: Deck A: Digit 1 - G", 49 | CNT_INTVAL },
425 { "LED: Deck A: Digit 1 - dot", 48 | CNT_INTVAL },
426 { "LED: Deck A: Digit 2 - A", 63 | CNT_INTVAL },
427 { "LED: Deck A: Digit 2 - B", 62 | CNT_INTVAL },
428 { "LED: Deck A: Digit 2 - C", 61 | CNT_INTVAL },
429 { "LED: Deck A: Digit 2 - D", 60 | CNT_INTVAL },
430 { "LED: Deck A: Digit 2 - E", 59 | CNT_INTVAL },
431 { "LED: Deck A: Digit 2 - F", 58 | CNT_INTVAL },
432 { "LED: Deck A: Digit 2 - G", 57 | CNT_INTVAL },
433 { "LED: Deck A: Digit 2 - dot", 56 | CNT_INTVAL },
434
435 { "LED: Deck B: 1 (blue)", 78 | CNT_INTVAL },
436 { "LED: Deck B: 1 (green)", 79 | CNT_INTVAL },
437 { "LED: Deck B: 2 (blue)", 76 | CNT_INTVAL },
438 { "LED: Deck B: 2 (green)", 77 | CNT_INTVAL },
439 { "LED: Deck B: 3 (blue)", 74 | CNT_INTVAL },
440 { "LED: Deck B: 3 (green)", 75 | CNT_INTVAL },
441 { "LED: Deck B: 4 (blue)", 72 | CNT_INTVAL },
442 { "LED: Deck B: 4 (green)", 73 | CNT_INTVAL },
443 { "LED: Deck B: Load", 180 | CNT_INTVAL },
444 { "LED: Deck B: Deck D button", 181 | CNT_INTVAL },
445 { "LED: Deck B: In", 183 | CNT_INTVAL },
446 { "LED: Deck B: Out", 182 | CNT_INTVAL },
447 { "LED: Deck B: Shift", 64 | CNT_INTVAL },
448 { "LED: Deck B: Sync", 67 | CNT_INTVAL },
449 { "LED: Deck B: Cue", 66 | CNT_INTVAL },
450 { "LED: Deck B: Play", 65 | CNT_INTVAL },
451 { "LED: Deck B: Tempo up", 185 | CNT_INTVAL },
452 { "LED: Deck B: Tempo down", 184 | CNT_INTVAL },
453 { "LED: Deck B: Master", 186 | CNT_INTVAL },
454 { "LED: Deck B: Keylock", 187 | CNT_INTVAL },
455 { "LED: Deck B: Deck B", 189 | CNT_INTVAL },
456 { "LED: Deck B: Deck D", 188 | CNT_INTVAL },
457 { "LED: Deck B: Samples", 190 | CNT_INTVAL },
458 { "LED: Deck B: On Air", 191 | CNT_INTVAL },
459 { "LED: Deck B: Sample 1", 71 | CNT_INTVAL },
460 { "LED: Deck B: Sample 2", 70 | CNT_INTVAL },
461 { "LED: Deck B: Sample 3", 69 | CNT_INTVAL },
462 { "LED: Deck B: Sample 4", 68 | CNT_INTVAL },
463 { "LED: Deck B: Digit 1 - A", 175 | CNT_INTVAL },
464 { "LED: Deck B: Digit 1 - B", 174 | CNT_INTVAL },
465 { "LED: Deck B: Digit 1 - C", 173 | CNT_INTVAL },
466 { "LED: Deck B: Digit 1 - D", 172 | CNT_INTVAL },
467 { "LED: Deck B: Digit 1 - E", 171 | CNT_INTVAL },
468 { "LED: Deck B: Digit 1 - F", 170 | CNT_INTVAL },
469 { "LED: Deck B: Digit 1 - G", 169 | CNT_INTVAL },
470 { "LED: Deck B: Digit 1 - dot", 168 | CNT_INTVAL },
471 { "LED: Deck B: Digit 2 - A", 167 | CNT_INTVAL },
472 { "LED: Deck B: Digit 2 - B", 166 | CNT_INTVAL },
473 { "LED: Deck B: Digit 2 - C", 165 | CNT_INTVAL },
474 { "LED: Deck B: Digit 2 - D", 164 | CNT_INTVAL },
475 { "LED: Deck B: Digit 2 - E", 163 | CNT_INTVAL },
476 { "LED: Deck B: Digit 2 - F", 162 | CNT_INTVAL },
477 { "LED: Deck B: Digit 2 - G", 161 | CNT_INTVAL },
478 { "LED: Deck B: Digit 2 - dot", 160 | CNT_INTVAL },
479
480 { "LED: FX1: dry/wet", 153 | CNT_INTVAL },
481 { "LED: FX1: 1", 154 | CNT_INTVAL },
482 { "LED: FX1: 2", 155 | CNT_INTVAL },
483 { "LED: FX1: 3", 156 | CNT_INTVAL },
484 { "LED: FX1: Mode", 157 | CNT_INTVAL },
485 { "LED: FX2: dry/wet", 129 | CNT_INTVAL },
486 { "LED: FX2: 1", 130 | CNT_INTVAL },
487 { "LED: FX2: 2", 131 | CNT_INTVAL },
488 { "LED: FX2: 3", 132 | CNT_INTVAL },
489 { "LED: FX2: Mode", 133 | CNT_INTVAL },
490};
491
299static int __devinit add_controls(struct caiaq_controller *c, int num, 492static int __devinit add_controls(struct caiaq_controller *c, int num,
300 struct snd_usb_caiaqdev *dev) 493 struct snd_usb_caiaqdev *dev)
301{ 494{
@@ -354,6 +547,11 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
354 ret = add_controls(kontrolx1_controller, 547 ret = add_controls(kontrolx1_controller,
355 ARRAY_SIZE(kontrolx1_controller), dev); 548 ARRAY_SIZE(kontrolx1_controller), dev);
356 break; 549 break;
550
551 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
552 ret = add_controls(kontrols4_controller,
553 ARRAY_SIZE(kontrols4_controller), dev);
554 break;
357 } 555 }
358 556
359 return ret; 557 return ret;
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index cdfb856bddd2..6480c3283c05 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -36,7 +36,7 @@
36#include "input.h" 36#include "input.h"
37 37
38MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 38MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
39MODULE_DESCRIPTION("caiaq USB audio, version 1.3.21"); 39MODULE_DESCRIPTION("caiaq USB audio");
40MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
41MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," 41MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
42 "{Native Instruments, RigKontrol3}," 42 "{Native Instruments, RigKontrol3},"
@@ -48,7 +48,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
48 "{Native Instruments, Audio 8 DJ}," 48 "{Native Instruments, Audio 8 DJ},"
49 "{Native Instruments, Session I/O}," 49 "{Native Instruments, Session I/O},"
50 "{Native Instruments, GuitarRig mobile}" 50 "{Native Instruments, GuitarRig mobile}"
51 "{Native Instruments, Traktor Kontrol X1}"); 51 "{Native Instruments, Traktor Kontrol X1}"
52 "{Native Instruments, Traktor Kontrol S4}");
52 53
53static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ 54static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */
54static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ 55static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */
@@ -134,6 +135,11 @@ static struct usb_device_id snd_usb_id_table[] = {
134 .idVendor = USB_VID_NATIVEINSTRUMENTS, 135 .idVendor = USB_VID_NATIVEINSTRUMENTS,
135 .idProduct = USB_PID_TRAKTORKONTROLX1 136 .idProduct = USB_PID_TRAKTORKONTROLX1
136 }, 137 },
138 {
139 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
140 .idVendor = USB_VID_NATIVEINSTRUMENTS,
141 .idProduct = USB_PID_TRAKTORKONTROLS4
142 },
137 { /* terminator */ } 143 { /* terminator */ }
138}; 144};
139 145
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index f1117ecc84fd..e3d8a3efb35b 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -16,6 +16,7 @@
16#define USB_PID_SESSIONIO 0x1915 16#define USB_PID_SESSIONIO 0x1915
17#define USB_PID_GUITARRIGMOBILE 0x0d8d 17#define USB_PID_GUITARRIGMOBILE 0x0d8d
18#define USB_PID_TRAKTORKONTROLX1 0x2305 18#define USB_PID_TRAKTORKONTROLX1 0x2305
19#define USB_PID_TRAKTORKONTROLS4 0xbaff
19 20
20#define EP1_BUFSIZE 64 21#define EP1_BUFSIZE 64
21#define EP4_BUFSIZE 512 22#define EP4_BUFSIZE 512
@@ -99,13 +100,14 @@ struct snd_usb_caiaqdev {
99 struct snd_pcm_substream *sub_capture[MAX_STREAMS]; 100 struct snd_pcm_substream *sub_capture[MAX_STREAMS];
100 101
101 /* Controls */ 102 /* Controls */
102 unsigned char control_state[64]; 103 unsigned char control_state[256];
104 unsigned char ep8_out_buf[2];
103 105
104 /* Linux input */ 106 /* Linux input */
105#ifdef CONFIG_SND_USB_CAIAQ_INPUT 107#ifdef CONFIG_SND_USB_CAIAQ_INPUT
106 struct input_dev *input_dev; 108 struct input_dev *input_dev;
107 char phys[64]; /* physical device path */ 109 char phys[64]; /* physical device path */
108 unsigned short keycode[64]; 110 unsigned short keycode[128];
109 struct urb *ep4_in_urb; 111 struct urb *ep4_in_urb;
110 unsigned char ep4_in_buf[EP4_BUFSIZE]; 112 unsigned char ep4_in_buf[EP4_BUFSIZE];
111#endif 113#endif
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index dcb620796d9e..4432ef7a70a9 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -67,7 +67,12 @@ static unsigned short keycode_kore[] = {
67 KEY_BRL_DOT5 67 KEY_BRL_DOT5
68}; 68};
69 69
70#define KONTROLX1_INPUTS 40 70#define KONTROLX1_INPUTS (40)
71#define KONTROLS4_BUTTONS (12 * 8)
72#define KONTROLS4_AXIS (46)
73
74#define KONTROLS4_BUTTON(X) ((X) + BTN_MISC)
75#define KONTROLS4_ABS(X) ((X) + ABS_HAT0X)
71 76
72#define DEG90 (range / 2) 77#define DEG90 (range / 2)
73#define DEG180 (range) 78#define DEG180 (range)
@@ -139,6 +144,13 @@ static unsigned int decode_erp(unsigned char a, unsigned char b)
139#undef HIGH_PEAK 144#undef HIGH_PEAK
140#undef LOW_PEAK 145#undef LOW_PEAK
141 146
147static inline void snd_caiaq_input_report_abs(struct snd_usb_caiaqdev *dev,
148 int axis, const unsigned char *buf,
149 int offset)
150{
151 input_report_abs(dev->input_dev, axis,
152 (buf[offset * 2] << 8) | buf[offset * 2 + 1]);
153}
142 154
143static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, 155static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
144 const unsigned char *buf, 156 const unsigned char *buf,
@@ -148,36 +160,30 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev,
148 160
149 switch (dev->chip.usb_id) { 161 switch (dev->chip.usb_id) {
150 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 162 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
151 input_report_abs(input_dev, ABS_X, (buf[4] << 8) | buf[5]); 163 snd_caiaq_input_report_abs(dev, ABS_X, buf, 2);
152 input_report_abs(input_dev, ABS_Y, (buf[0] << 8) | buf[1]); 164 snd_caiaq_input_report_abs(dev, ABS_Y, buf, 0);
153 input_report_abs(input_dev, ABS_Z, (buf[2] << 8) | buf[3]); 165 snd_caiaq_input_report_abs(dev, ABS_Z, buf, 1);
154 input_sync(input_dev);
155 break; 166 break;
156 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 167 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
157 input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]);
158 input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]);
159 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]);
160 input_sync(input_dev);
161 break;
162 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): 168 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
163 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): 169 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
164 input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]); 170 snd_caiaq_input_report_abs(dev, ABS_X, buf, 0);
165 input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]); 171 snd_caiaq_input_report_abs(dev, ABS_Y, buf, 1);
166 input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); 172 snd_caiaq_input_report_abs(dev, ABS_Z, buf, 2);
167 input_sync(input_dev);
168 break; 173 break;
169 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 174 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
170 input_report_abs(input_dev, ABS_HAT0X, (buf[8] << 8) | buf[9]); 175 snd_caiaq_input_report_abs(dev, ABS_HAT0X, buf, 4);
171 input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]); 176 snd_caiaq_input_report_abs(dev, ABS_HAT0Y, buf, 2);
172 input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]); 177 snd_caiaq_input_report_abs(dev, ABS_HAT1X, buf, 6);
173 input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]); 178 snd_caiaq_input_report_abs(dev, ABS_HAT1Y, buf, 1);
174 input_report_abs(input_dev, ABS_HAT2X, (buf[14] << 8) | buf[15]); 179 snd_caiaq_input_report_abs(dev, ABS_HAT2X, buf, 7);
175 input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]); 180 snd_caiaq_input_report_abs(dev, ABS_HAT2Y, buf, 0);
176 input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]); 181 snd_caiaq_input_report_abs(dev, ABS_HAT3X, buf, 5);
177 input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]); 182 snd_caiaq_input_report_abs(dev, ABS_HAT3Y, buf, 3);
178 input_sync(input_dev);
179 break; 183 break;
180 } 184 }
185
186 input_sync(input_dev);
181} 187}
182 188
183static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, 189static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev,
@@ -250,6 +256,150 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev,
250 input_sync(input_dev); 256 input_sync(input_dev);
251} 257}
252 258
259#define TKS4_MSGBLOCK_SIZE 16
260
261static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev,
262 const unsigned char *buf,
263 unsigned int len)
264{
265 while (len) {
266 unsigned int i, block_id = (buf[0] << 8) | buf[1];
267
268 switch (block_id) {
269 case 0:
270 /* buttons */
271 for (i = 0; i < KONTROLS4_BUTTONS; i++)
272 input_report_key(dev->input_dev, KONTROLS4_BUTTON(i),
273 (buf[4 + (i / 8)] >> (i % 8)) & 1);
274 break;
275
276 case 1:
277 /* left wheel */
278 input_report_abs(dev->input_dev, KONTROLS4_ABS(36), buf[9] | ((buf[8] & 0x3) << 8));
279 /* right wheel */
280 input_report_abs(dev->input_dev, KONTROLS4_ABS(37), buf[13] | ((buf[12] & 0x3) << 8));
281
282 /* rotary encoders */
283 input_report_abs(dev->input_dev, KONTROLS4_ABS(38), buf[3] & 0xf);
284 input_report_abs(dev->input_dev, KONTROLS4_ABS(39), buf[4] >> 4);
285 input_report_abs(dev->input_dev, KONTROLS4_ABS(40), buf[4] & 0xf);
286 input_report_abs(dev->input_dev, KONTROLS4_ABS(41), buf[5] >> 4);
287 input_report_abs(dev->input_dev, KONTROLS4_ABS(42), buf[5] & 0xf);
288 input_report_abs(dev->input_dev, KONTROLS4_ABS(43), buf[6] >> 4);
289 input_report_abs(dev->input_dev, KONTROLS4_ABS(44), buf[6] & 0xf);
290 input_report_abs(dev->input_dev, KONTROLS4_ABS(45), buf[7] >> 4);
291 input_report_abs(dev->input_dev, KONTROLS4_ABS(46), buf[7] & 0xf);
292
293 break;
294 case 2:
295 /* Volume Fader Channel D */
296 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(0), buf, 1);
297 /* Volume Fader Channel B */
298 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(1), buf, 2);
299 /* Volume Fader Channel A */
300 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(2), buf, 3);
301 /* Volume Fader Channel C */
302 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(3), buf, 4);
303 /* Loop Volume */
304 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(4), buf, 6);
305 /* Crossfader */
306 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(7), buf, 7);
307
308 break;
309
310 case 3:
311 /* Tempo Fader R */
312 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(6), buf, 3);
313 /* Tempo Fader L */
314 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(5), buf, 4);
315 /* Mic Volume */
316 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(8), buf, 6);
317 /* Cue Mix */
318 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(9), buf, 7);
319
320 break;
321
322 case 4:
323 /* Wheel distance sensor L */
324 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(10), buf, 1);
325 /* Wheel distance sensor R */
326 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(11), buf, 2);
327 /* Channel D EQ - Filter */
328 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(12), buf, 3);
329 /* Channel D EQ - Low */
330 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(13), buf, 4);
331 /* Channel D EQ - Mid */
332 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(14), buf, 5);
333 /* Channel D EQ - Hi */
334 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(15), buf, 6);
335 /* FX2 - dry/wet */
336 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(16), buf, 7);
337
338 break;
339
340 case 5:
341 /* FX2 - 1 */
342 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(17), buf, 1);
343 /* FX2 - 2 */
344 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(18), buf, 2);
345 /* FX2 - 3 */
346 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(19), buf, 3);
347 /* Channel B EQ - Filter */
348 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(20), buf, 4);
349 /* Channel B EQ - Low */
350 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(21), buf, 5);
351 /* Channel B EQ - Mid */
352 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(22), buf, 6);
353 /* Channel B EQ - Hi */
354 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(23), buf, 7);
355
356 break;
357
358 case 6:
359 /* Channel A EQ - Filter */
360 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(24), buf, 1);
361 /* Channel A EQ - Low */
362 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(25), buf, 2);
363 /* Channel A EQ - Mid */
364 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(26), buf, 3);
365 /* Channel A EQ - Hi */
366 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(27), buf, 4);
367 /* Channel C EQ - Filter */
368 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(28), buf, 5);
369 /* Channel C EQ - Low */
370 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(29), buf, 6);
371 /* Channel C EQ - Mid */
372 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(30), buf, 7);
373
374 break;
375
376 case 7:
377 /* Channel C EQ - Hi */
378 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(31), buf, 1);
379 /* FX1 - wet/dry */
380 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(32), buf, 2);
381 /* FX1 - 1 */
382 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(33), buf, 3);
383 /* FX1 - 2 */
384 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(34), buf, 4);
385 /* FX1 - 3 */
386 snd_caiaq_input_report_abs(dev, KONTROLS4_ABS(35), buf, 5);
387
388 break;
389
390 default:
391 debug("%s(): bogus block (id %d)\n",
392 __func__, block_id);
393 return;
394 }
395
396 len -= TKS4_MSGBLOCK_SIZE;
397 buf += TKS4_MSGBLOCK_SIZE;
398 }
399
400 input_sync(dev->input_dev);
401}
402
253static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) 403static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
254{ 404{
255 struct snd_usb_caiaqdev *dev = urb->context; 405 struct snd_usb_caiaqdev *dev = urb->context;
@@ -259,11 +409,11 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
259 if (urb->status || !dev || urb != dev->ep4_in_urb) 409 if (urb->status || !dev || urb != dev->ep4_in_urb)
260 return; 410 return;
261 411
262 if (urb->actual_length < 24)
263 goto requeue;
264
265 switch (dev->chip.usb_id) { 412 switch (dev->chip.usb_id) {
266 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 413 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
414 if (urb->actual_length < 24)
415 goto requeue;
416
267 if (buf[0] & 0x3) 417 if (buf[0] & 0x3)
268 snd_caiaq_input_read_io(dev, buf + 1, 7); 418 snd_caiaq_input_read_io(dev, buf + 1, 7);
269 419
@@ -271,6 +421,10 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb)
271 snd_caiaq_input_read_analog(dev, buf + 8, 16); 421 snd_caiaq_input_read_analog(dev, buf + 8, 16);
272 422
273 break; 423 break;
424
425 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
426 snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length);
427 break;
274 } 428 }
275 429
276requeue: 430requeue:
@@ -289,6 +443,7 @@ static int snd_usb_caiaq_input_open(struct input_dev *idev)
289 443
290 switch (dev->chip.usb_id) { 444 switch (dev->chip.usb_id) {
291 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 445 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
446 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
292 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) 447 if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0)
293 return -EIO; 448 return -EIO;
294 break; 449 break;
@@ -306,6 +461,7 @@ static void snd_usb_caiaq_input_close(struct input_dev *idev)
306 461
307 switch (dev->chip.usb_id) { 462 switch (dev->chip.usb_id) {
308 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): 463 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1):
464 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
309 usb_kill_urb(dev->ep4_in_urb); 465 usb_kill_urb(dev->ep4_in_urb);
310 break; 466 break;
311 } 467 }
@@ -456,6 +612,46 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
456 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); 612 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
457 613
458 break; 614 break;
615
616 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4):
617 input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
618 BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLS4_BUTTONS);
619 for (i = 0; i < KONTROLS4_BUTTONS; i++)
620 dev->keycode[i] = KONTROLS4_BUTTON(i);
621 input->keycodemax = KONTROLS4_BUTTONS;
622
623 for (i = 0; i < KONTROLS4_AXIS; i++) {
624 int axis = KONTROLS4_ABS(i);
625 input->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
626 }
627
628 /* 36 analog potentiometers and faders */
629 for (i = 0; i < 36; i++)
630 input_set_abs_params(input, KONTROLS4_ABS(i), 0, 0xfff, 0, 10);
631
632 /* 2 encoder wheels */
633 input_set_abs_params(input, KONTROLS4_ABS(36), 0, 0x3ff, 0, 1);
634 input_set_abs_params(input, KONTROLS4_ABS(37), 0, 0x3ff, 0, 1);
635
636 /* 9 rotary encoders */
637 for (i = 0; i < 9; i++)
638 input_set_abs_params(input, KONTROLS4_ABS(38+i), 0, 0xf, 0, 1);
639
640 dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL);
641 if (!dev->ep4_in_urb) {
642 ret = -ENOMEM;
643 goto exit_free_idev;
644 }
645
646 usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev,
647 usb_rcvbulkpipe(usb_dev, 0x4),
648 dev->ep4_in_buf, EP4_BUFSIZE,
649 snd_usb_caiaq_ep4_reply_dispatch, dev);
650
651 snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
652
653 break;
654
459 default: 655 default:
460 /* no input methods supported on this device */ 656 /* no input methods supported on this device */
461 goto exit_free_idev; 657 goto exit_free_idev;
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 4eabafa5b037..800f7cb4f251 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -300,9 +300,13 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
300 300
301 *rchip = NULL; 301 *rchip = NULL;
302 302
303 if (snd_usb_get_speed(dev) != USB_SPEED_LOW && 303 switch (snd_usb_get_speed(dev)) {
304 snd_usb_get_speed(dev) != USB_SPEED_FULL && 304 case USB_SPEED_LOW:
305 snd_usb_get_speed(dev) != USB_SPEED_HIGH) { 305 case USB_SPEED_FULL:
306 case USB_SPEED_HIGH:
307 case USB_SPEED_SUPER:
308 break;
309 default:
306 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev)); 310 snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
307 return -ENXIO; 311 return -ENXIO;
308 } 312 }
@@ -378,11 +382,22 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
378 if (len < sizeof(card->longname)) 382 if (len < sizeof(card->longname))
379 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len); 383 usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
380 384
381 strlcat(card->longname, 385 switch (snd_usb_get_speed(dev)) {
382 snd_usb_get_speed(dev) == USB_SPEED_LOW ? ", low speed" : 386 case USB_SPEED_LOW:
383 snd_usb_get_speed(dev) == USB_SPEED_FULL ? ", full speed" : 387 strlcat(card->longname, ", low speed", sizeof(card->longname));
384 ", high speed", 388 break;
385 sizeof(card->longname)); 389 case USB_SPEED_FULL:
390 strlcat(card->longname, ", full speed", sizeof(card->longname));
391 break;
392 case USB_SPEED_HIGH:
393 strlcat(card->longname, ", high speed", sizeof(card->longname));
394 break;
395 case USB_SPEED_SUPER:
396 strlcat(card->longname, ", super speed", sizeof(card->longname));
397 break;
398 default:
399 break;
400 }
386 401
387 snd_usb_audio_create_proc(chip); 402 snd_usb_audio_create_proc(chip);
388 403
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index ef0a07e34844..b0ef9f501896 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -405,8 +405,6 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
405 break; 405 break;
406 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ 406 case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
407 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ 407 case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
408 case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra 8 */
409 case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */
410 /* doesn't set the sample rate attribute, but supports it */ 408 /* doesn't set the sample rate attribute, but supports it */
411 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; 409 fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
412 break; 410 break;
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
index d48d6f8f6ac9..f280c1903c25 100644
--- a/sound/usb/helper.c
+++ b/sound/usb/helper.c
@@ -103,11 +103,16 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
103unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, 103unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip,
104 struct usb_host_interface *alts) 104 struct usb_host_interface *alts)
105{ 105{
106 if (snd_usb_get_speed(chip->dev) == USB_SPEED_HIGH && 106 switch (snd_usb_get_speed(chip->dev)) {
107 get_endpoint(alts, 0)->bInterval >= 1 && 107 case USB_SPEED_HIGH:
108 get_endpoint(alts, 0)->bInterval <= 4) 108 case USB_SPEED_SUPER:
109 return get_endpoint(alts, 0)->bInterval - 1; 109 if (get_endpoint(alts, 0)->bInterval >= 1 &&
110 else 110 get_endpoint(alts, 0)->bInterval <= 4)
111 return 0; 111 return get_endpoint(alts, 0)->bInterval - 1;
112 break;
113 default:
114 break;
115 }
116 return 0;
112} 117}
113 118
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index b9c2bc65f51a..25bce7e5b1af 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -784,7 +784,7 @@ static struct usb_protocol_ops snd_usbmidi_novation_ops = {
784}; 784};
785 785
786/* 786/*
787 * "raw" protocol: used by the MOTU FastLane. 787 * "raw" protocol: just move raw MIDI bytes from/to the endpoint
788 */ 788 */
789 789
790static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep, 790static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep,
@@ -834,7 +834,14 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
834 834
835 if (!ep->ports[0].active) 835 if (!ep->ports[0].active)
836 return; 836 return;
837 count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2; 837 switch (snd_usb_get_speed(ep->umidi->dev)) {
838 case USB_SPEED_HIGH:
839 case USB_SPEED_SUPER:
840 count = 1;
841 break;
842 default:
843 count = 2;
844 }
838 count = snd_rawmidi_transmit(ep->ports[0].substream, 845 count = snd_rawmidi_transmit(ep->ports[0].substream,
839 urb->transfer_buffer, 846 urb->transfer_buffer,
840 count); 847 count);
@@ -2115,7 +2122,7 @@ int snd_usbmidi_create(struct snd_card *card,
2115 umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; 2122 umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
2116 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); 2123 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
2117 break; 2124 break;
2118 case QUIRK_MIDI_FASTLANE: 2125 case QUIRK_MIDI_RAW_BYTES:
2119 umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; 2126 umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
2120 /* 2127 /*
2121 * Interface 1 contains isochronous endpoints, but with the same 2128 * Interface 1 contains isochronous endpoints, but with the same
@@ -2126,7 +2133,8 @@ int snd_usbmidi_create(struct snd_card *card,
2126 * interface 0, so we have to make sure that the USB core looks 2133 * interface 0, so we have to make sure that the USB core looks
2127 * again at interface 0 by calling usb_set_interface() on it. 2134 * again at interface 0 by calling usb_set_interface() on it.
2128 */ 2135 */
2129 usb_set_interface(umidi->dev, 0, 0); 2136 if (umidi->usb_id == USB_ID(0x07fd, 0x0001)) /* MOTU Fastlane */
2137 usb_set_interface(umidi->dev, 0, 0);
2130 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); 2138 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
2131 break; 2139 break;
2132 case QUIRK_MIDI_EMAGIC: 2140 case QUIRK_MIDI_EMAGIC:
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 3ed3901369ce..f2d74d654b3c 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -759,8 +759,6 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
759 */ 759 */
760static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) 760static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
761{ 761{
762 struct snd_usb_audio *chip = cval->mixer->chip;
763
764 /* for failsafe */ 762 /* for failsafe */
765 cval->min = default_min; 763 cval->min = default_min;
766 cval->max = cval->min + 1; 764 cval->max = cval->min + 1;
@@ -783,7 +781,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
783 if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 || 781 if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
784 get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { 782 get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
785 snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", 783 snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
786 cval->id, snd_usb_ctrl_intf(chip), cval->control, cval->id); 784 cval->id, snd_usb_ctrl_intf(cval->mixer->chip), cval->control, cval->id);
787 return -EINVAL; 785 return -EINVAL;
788 } 786 }
789 if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) { 787 if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
@@ -1642,9 +1640,10 @@ static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl
1642 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1640 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1643 uinfo->count = 1; 1641 uinfo->count = 1;
1644 uinfo->value.enumerated.items = cval->max; 1642 uinfo->value.enumerated.items = cval->max;
1645 if ((int)uinfo->value.enumerated.item >= cval->max) 1643 if (uinfo->value.enumerated.item >= cval->max)
1646 uinfo->value.enumerated.item = cval->max - 1; 1644 uinfo->value.enumerated.item = cval->max - 1;
1647 strcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item]); 1645 strlcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item],
1646 sizeof(uinfo->value.enumerated.name));
1648 return 0; 1647 return 0;
1649} 1648}
1650 1649
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index e7df1e5e3f2e..7dae05d8783e 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -60,6 +60,7 @@ static const struct rc_config {
60 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */ 60 { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */
61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ 61 { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */
62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ 62 { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */
63 { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi */
63 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ 64 { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */
64}; 65};
65 66
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 3b5135c93062..f49756c1b837 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -466,7 +466,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs,
466 return 0; 466 return 0;
467 } 467 }
468 /* check whether the period time is >= the data packet interval */ 468 /* check whether the period time is >= the data packet interval */
469 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) { 469 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) {
470 ptime = 125 * (1 << fp->datainterval); 470 ptime = 125 * (1 << fp->datainterval);
471 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { 471 if (ptime > pt->max || (ptime == pt->max && pt->openmax)) {
472 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); 472 hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max);
@@ -734,7 +734,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
734 } 734 }
735 735
736 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; 736 param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME;
737 if (snd_usb_get_speed(subs->dev) != USB_SPEED_HIGH) 737 if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
738 /* full speed devices have fixed data packet interval */ 738 /* full speed devices have fixed data packet interval */
739 ptmin = 1000; 739 ptmin = 1000;
740 if (ptmin == 1000) 740 if (ptmin == 1000)
diff --git a/sound/usb/proc.c b/sound/usb/proc.c
index f5e3f356b95f..3c650ab3c91d 100644
--- a/sound/usb/proc.c
+++ b/sound/usb/proc.c
@@ -107,7 +107,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
107 } 107 }
108 snd_iprintf(buffer, "\n"); 108 snd_iprintf(buffer, "\n");
109 } 109 }
110 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) 110 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
111 snd_iprintf(buffer, " Data packet interval: %d us\n", 111 snd_iprintf(buffer, " Data packet interval: %d us\n",
112 125 * (1 << fp->datainterval)); 112 125 * (1 << fp->datainterval));
113 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); 113 // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 2e8003f98fca..ad7079d1676c 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -240,9 +240,21 @@ YAMAHA_DEVICE(0x104f, NULL),
240YAMAHA_DEVICE(0x1050, NULL), 240YAMAHA_DEVICE(0x1050, NULL),
241YAMAHA_DEVICE(0x1051, NULL), 241YAMAHA_DEVICE(0x1051, NULL),
242YAMAHA_DEVICE(0x1052, NULL), 242YAMAHA_DEVICE(0x1052, NULL),
243YAMAHA_INTERFACE(0x1053, 0, NULL),
244YAMAHA_INTERFACE(0x1054, 0, NULL),
245YAMAHA_DEVICE(0x1055, NULL),
246YAMAHA_DEVICE(0x1056, NULL),
247YAMAHA_DEVICE(0x1057, NULL),
248YAMAHA_DEVICE(0x1058, NULL),
249YAMAHA_DEVICE(0x1059, NULL),
250YAMAHA_DEVICE(0x105a, NULL),
251YAMAHA_DEVICE(0x105b, NULL),
252YAMAHA_DEVICE(0x105c, NULL),
253YAMAHA_DEVICE(0x105d, NULL),
243YAMAHA_DEVICE(0x2000, "DGP-7"), 254YAMAHA_DEVICE(0x2000, "DGP-7"),
244YAMAHA_DEVICE(0x2001, "DGP-5"), 255YAMAHA_DEVICE(0x2001, "DGP-5"),
245YAMAHA_DEVICE(0x2002, NULL), 256YAMAHA_DEVICE(0x2002, NULL),
257YAMAHA_DEVICE(0x2003, NULL),
246YAMAHA_DEVICE(0x5000, "CS1D"), 258YAMAHA_DEVICE(0x5000, "CS1D"),
247YAMAHA_DEVICE(0x5001, "DSP1D"), 259YAMAHA_DEVICE(0x5001, "DSP1D"),
248YAMAHA_DEVICE(0x5002, "DME32"), 260YAMAHA_DEVICE(0x5002, "DME32"),
@@ -1136,11 +1148,34 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1136 } 1148 }
1137}, 1149},
1138{ 1150{
1151 /* has ID 0x0066 when not in "Advanced Driver" mode */
1152 USB_DEVICE(0x0582, 0x0064),
1153 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1154 /* .vendor_name = "EDIROL", */
1155 /* .product_name = "PCR-1", */
1156 .ifnum = QUIRK_ANY_INTERFACE,
1157 .type = QUIRK_COMPOSITE,
1158 .data = (const struct snd_usb_audio_quirk[]) {
1159 {
1160 .ifnum = 1,
1161 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1162 },
1163 {
1164 .ifnum = 2,
1165 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1166 },
1167 {
1168 .ifnum = -1
1169 }
1170 }
1171 }
1172},
1173{
1139 /* has ID 0x0067 when not in "Advanced Driver" mode */ 1174 /* has ID 0x0067 when not in "Advanced Driver" mode */
1140 USB_DEVICE(0x0582, 0x0065), 1175 USB_DEVICE(0x0582, 0x0065),
1141 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1176 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1142 .vendor_name = "EDIROL", 1177 /* .vendor_name = "EDIROL", */
1143 .product_name = "PCR-1", 1178 /* .product_name = "PCR-1", */
1144 .ifnum = 0, 1179 .ifnum = 0,
1145 .type = QUIRK_MIDI_FIXED_ENDPOINT, 1180 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1146 .data = & (const struct snd_usb_midi_endpoint_info) { 1181 .data = & (const struct snd_usb_midi_endpoint_info) {
@@ -1525,6 +1560,50 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1525 } 1560 }
1526 } 1561 }
1527}, 1562},
1563{
1564 /* has ID 0x0110 when not in Advanced Driver mode */
1565 USB_DEVICE_VENDOR_SPEC(0x0582, 0x010f),
1566 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1567 /* .vendor_name = "Roland", */
1568 /* .product_name = "A-PRO", */
1569 .ifnum = 1,
1570 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1571 .data = & (const struct snd_usb_midi_endpoint_info) {
1572 .out_cables = 0x0003,
1573 .in_cables = 0x0007
1574 }
1575 }
1576},
1577{
1578 USB_DEVICE(0x0582, 0x0113),
1579 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1580 /* .vendor_name = "BOSS", */
1581 /* .product_name = "ME-25", */
1582 .ifnum = QUIRK_ANY_INTERFACE,
1583 .type = QUIRK_COMPOSITE,
1584 .data = (const struct snd_usb_audio_quirk[]) {
1585 {
1586 .ifnum = 0,
1587 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1588 },
1589 {
1590 .ifnum = 1,
1591 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1592 },
1593 {
1594 .ifnum = 2,
1595 .type = QUIRK_MIDI_FIXED_ENDPOINT,
1596 .data = & (const struct snd_usb_midi_endpoint_info) {
1597 .out_cables = 0x0001,
1598 .in_cables = 0x0001
1599 }
1600 },
1601 {
1602 .ifnum = -1
1603 }
1604 }
1605 }
1606},
1528 1607
1529/* Guillemot devices */ 1608/* Guillemot devices */
1530{ 1609{
@@ -1830,7 +1909,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1830 USB_DEVICE(0x0763, 0x2080), 1909 USB_DEVICE(0x0763, 0x2080),
1831 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 1910 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1832 /* .vendor_name = "M-Audio", */ 1911 /* .vendor_name = "M-Audio", */
1833 /* .product_name = "Fast Track Ultra 8", */ 1912 /* .product_name = "Fast Track Ultra", */
1834 .ifnum = QUIRK_ANY_INTERFACE, 1913 .ifnum = QUIRK_ANY_INTERFACE,
1835 .type = QUIRK_COMPOSITE, 1914 .type = QUIRK_COMPOSITE,
1836 .data = & (const struct snd_usb_audio_quirk[]) { 1915 .data = & (const struct snd_usb_audio_quirk[]) {
@@ -1840,11 +1919,51 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1840 }, 1919 },
1841 { 1920 {
1842 .ifnum = 1, 1921 .ifnum = 1,
1843 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1922 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1923 .data = & (const struct audioformat) {
1924 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
1925 .channels = 8,
1926 .iface = 1,
1927 .altsetting = 1,
1928 .altset_idx = 1,
1929 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
1930 .endpoint = 0x01,
1931 .ep_attr = 0x09,
1932 .rates = SNDRV_PCM_RATE_44100 |
1933 SNDRV_PCM_RATE_48000 |
1934 SNDRV_PCM_RATE_88200 |
1935 SNDRV_PCM_RATE_96000,
1936 .rate_min = 44100,
1937 .rate_max = 96000,
1938 .nr_rates = 4,
1939 .rate_table = (unsigned int[]) {
1940 44100, 48000, 88200, 96000
1941 }
1942 }
1844 }, 1943 },
1845 { 1944 {
1846 .ifnum = 2, 1945 .ifnum = 2,
1847 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1946 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1947 .data = & (const struct audioformat) {
1948 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
1949 .channels = 8,
1950 .iface = 2,
1951 .altsetting = 1,
1952 .altset_idx = 1,
1953 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
1954 .endpoint = 0x81,
1955 .ep_attr = 0x05,
1956 .rates = SNDRV_PCM_RATE_44100 |
1957 SNDRV_PCM_RATE_48000 |
1958 SNDRV_PCM_RATE_88200 |
1959 SNDRV_PCM_RATE_96000,
1960 .rate_min = 44100,
1961 .rate_max = 96000,
1962 .nr_rates = 4,
1963 .rate_table = (unsigned int[]) {
1964 44100, 48000, 88200, 96000
1965 }
1966 }
1848 }, 1967 },
1849 /* interface 3 (MIDI) is standard compliant */ 1968 /* interface 3 (MIDI) is standard compliant */
1850 { 1969 {
@@ -1867,11 +1986,51 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1867 }, 1986 },
1868 { 1987 {
1869 .ifnum = 1, 1988 .ifnum = 1,
1870 .type = QUIRK_AUDIO_STANDARD_INTERFACE 1989 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
1990 .data = & (const struct audioformat) {
1991 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
1992 .channels = 8,
1993 .iface = 1,
1994 .altsetting = 1,
1995 .altset_idx = 1,
1996 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
1997 .endpoint = 0x01,
1998 .ep_attr = 0x09,
1999 .rates = SNDRV_PCM_RATE_44100 |
2000 SNDRV_PCM_RATE_48000 |
2001 SNDRV_PCM_RATE_88200 |
2002 SNDRV_PCM_RATE_96000,
2003 .rate_min = 44100,
2004 .rate_max = 96000,
2005 .nr_rates = 4,
2006 .rate_table = (unsigned int[]) {
2007 44100, 48000, 88200, 96000
2008 }
2009 }
1871 }, 2010 },
1872 { 2011 {
1873 .ifnum = 2, 2012 .ifnum = 2,
1874 .type = QUIRK_AUDIO_STANDARD_INTERFACE 2013 .type = QUIRK_AUDIO_FIXED_ENDPOINT,
2014 .data = & (const struct audioformat) {
2015 .formats = SNDRV_PCM_FMTBIT_S24_3LE,
2016 .channels = 8,
2017 .iface = 2,
2018 .altsetting = 1,
2019 .altset_idx = 1,
2020 .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
2021 .endpoint = 0x81,
2022 .ep_attr = 0x05,
2023 .rates = SNDRV_PCM_RATE_44100 |
2024 SNDRV_PCM_RATE_48000 |
2025 SNDRV_PCM_RATE_88200 |
2026 SNDRV_PCM_RATE_96000,
2027 .rate_min = 44100,
2028 .rate_max = 96000,
2029 .nr_rates = 4,
2030 .rate_table = (unsigned int[]) {
2031 44100, 48000, 88200, 96000
2032 }
2033 }
1875 }, 2034 },
1876 /* interface 3 (MIDI) is standard compliant */ 2035 /* interface 3 (MIDI) is standard compliant */
1877 { 2036 {
@@ -1919,7 +2078,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1919 .data = & (const struct snd_usb_audio_quirk[]) { 2078 .data = & (const struct snd_usb_audio_quirk[]) {
1920 { 2079 {
1921 .ifnum = 0, 2080 .ifnum = 0,
1922 .type = QUIRK_MIDI_FASTLANE 2081 .type = QUIRK_MIDI_RAW_BYTES
1923 }, 2082 },
1924 { 2083 {
1925 .ifnum = 1, 2084 .ifnum = 1,
@@ -2068,6 +2227,15 @@ YAMAHA_DEVICE(0x7010, "UB99"),
2068 } 2227 }
2069}, 2228},
2070{ 2229{
2230 USB_DEVICE(0x1235, 0x000e),
2231 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2232 /* .vendor_name = "Novation", */
2233 /* .product_name = "Launchpad", */
2234 .ifnum = 0,
2235 .type = QUIRK_MIDI_RAW_BYTES
2236 }
2237},
2238{
2071 USB_DEVICE_VENDOR_SPEC(0x1235, 0x4661), 2239 USB_DEVICE_VENDOR_SPEC(0x1235, 0x4661),
2072 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { 2240 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
2073 .vendor_name = "Novation", 2241 .vendor_name = "Novation",
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 9a9da09586a5..cf8bf088394b 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -287,7 +287,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
287 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk, 287 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
288 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk, 288 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
289 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk, 289 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
290 [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk, 290 [QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
291 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, 291 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
292 [QUIRK_MIDI_CME] = create_any_midi_quirk, 292 [QUIRK_MIDI_CME] = create_any_midi_quirk,
293 [QUIRK_MIDI_AKAI] = create_any_midi_quirk, 293 [QUIRK_MIDI_AKAI] = create_any_midi_quirk,
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
index de607d4411ac..8deeaad10f10 100644
--- a/sound/usb/urb.c
+++ b/sound/usb/urb.c
@@ -244,7 +244,7 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
244 else 244 else
245 subs->curpacksize = maxsize; 245 subs->curpacksize = maxsize;
246 246
247 if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH) 247 if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL)
248 packs_per_ms = 8 >> subs->datainterval; 248 packs_per_ms = 8 >> subs->datainterval;
249 else 249 else
250 packs_per_ms = 1; 250 packs_per_ms = 1;
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 24d3319cc34d..db3eb21627ee 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -70,7 +70,7 @@ enum quirk_type {
70 QUIRK_MIDI_YAMAHA, 70 QUIRK_MIDI_YAMAHA,
71 QUIRK_MIDI_MIDIMAN, 71 QUIRK_MIDI_MIDIMAN,
72 QUIRK_MIDI_NOVATION, 72 QUIRK_MIDI_NOVATION,
73 QUIRK_MIDI_FASTLANE, 73 QUIRK_MIDI_RAW_BYTES,
74 QUIRK_MIDI_EMAGIC, 74 QUIRK_MIDI_EMAGIC,
75 QUIRK_MIDI_CME, 75 QUIRK_MIDI_CME,
76 QUIRK_MIDI_AKAI, 76 QUIRK_MIDI_AKAI,
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 2a528e56afd5..287ef73b1237 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -36,9 +36,9 @@
36 plain usx2y alsa mode is able to achieve 64frames, 4periods, but only at the 36 plain usx2y alsa mode is able to achieve 64frames, 4periods, but only at the
37 cost of easier triggered i.e. aeolus xruns (128 or 256frames, 37 cost of easier triggered i.e. aeolus xruns (128 or 256frames,
38 2periods works but is useless cause of crackling). 38 2periods works but is useless cause of crackling).
39 39
40 This is a first "proof of concept" implementation. 40 This is a first "proof of concept" implementation.
41 Later, funcionalities should migrate to more apropriate places: 41 Later, functionalities should migrate to more apropriate places:
42 Userland: 42 Userland:
43 - The jackd could mmap its float-pcm buffers directly from alsa-lib. 43 - The jackd could mmap its float-pcm buffers directly from alsa-lib.
44 - alsa-lib could provide power of 2 period sized shaping combined with int/float 44 - alsa-lib could provide power of 2 period sized shaping combined with int/float
@@ -54,7 +54,7 @@
54#include <linux/gfp.h> 54#include <linux/gfp.h>
55#include "usbusx2yaudio.c" 55#include "usbusx2yaudio.c"
56 56
57#if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) && USX2Y_NRPACKS == 1) 57#if defined(USX2Y_NRPACKS_VARIABLE) || USX2Y_NRPACKS == 1
58 58
59#include <sound/hwdep.h> 59#include <sound/hwdep.h>
60 60