aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/rme9652
diff options
context:
space:
mode:
authorAdrian Knoth <adi@drcomp.erfurt.thur.de>2013-01-15 12:52:20 -0500
committerTakashi Iwai <tiwai@suse.de>2013-01-16 01:48:38 -0500
commit0c2bc7c7d8306bad0ec534852f1900140b80c956 (patch)
treef3bfd53313e2933a3218b166c69cbb4dcce8c58d /sound/pci/rme9652
parent6ab317419c62850a71e2adfd1573e5ee87d8774f (diff)
ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes
The current iobox detection code reportedly fails for various users, so simply do what the Win32 driver does instead. Patch originally by Karl Grill <kgrill@chello.at> and then modified to comply with kernel coding guidelines + current HEAD. Signed-off-by: Adrian Knoth <adi@drcomp.erfurt.thur.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/rme9652')
-rw-r--r--sound/pci/rme9652/hdsp.c91
1 files changed, 65 insertions, 26 deletions
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 4fae81f21efb..866d68461b83 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -154,10 +154,13 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
154#define HDSP_BIGENDIAN_MODE 0x200 154#define HDSP_BIGENDIAN_MODE 0x200
155#define HDSP_RD_MULTIPLE 0x400 155#define HDSP_RD_MULTIPLE 0x400
156#define HDSP_9652_ENABLE_MIXER 0x800 156#define HDSP_9652_ENABLE_MIXER 0x800
157#define HDSP_S200 0x800
158#define HDSP_S300 (0x100 | HDSP_S200) /* dummy, purpose of 0x100 unknown */
159#define HDSP_CYCLIC_MODE 0x1000
157#define HDSP_TDO 0x10000000 160#define HDSP_TDO 0x10000000
158 161
159#define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0) 162#define HDSP_S_PROGRAM (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
160#define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1) 163#define HDSP_S_LOAD (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
161 164
162/* Control Register bits */ 165/* Control Register bits */
163 166
@@ -671,13 +674,23 @@ static unsigned int hdsp_read(struct hdsp *hdsp, int reg)
671 674
672static int hdsp_check_for_iobox (struct hdsp *hdsp) 675static int hdsp_check_for_iobox (struct hdsp *hdsp)
673{ 676{
677 int i;
678
674 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; 679 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
675 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { 680 for (i = 0; i < 500; i++) {
676 snd_printk("Hammerfall-DSP: no IO box connected!\n"); 681 if (0 == (hdsp_read(hdsp, HDSP_statusRegister) &
677 hdsp->state &= ~HDSP_FirmwareLoaded; 682 HDSP_ConfigError)) {
678 return -EIO; 683 if (i) {
684 snd_printd("Hammerfall-DSP: IO box found after %d ms\n",
685 (20 * i));
686 }
687 return 0;
688 }
689 msleep(20);
679 } 690 }
680 return 0; 691 snd_printk(KERN_ERR "Hammerfall-DSP: no IO box connected!\n");
692 hdsp->state &= ~HDSP_FirmwareLoaded;
693 return -EIO;
681} 694}
682 695
683static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, 696static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
@@ -728,6 +741,7 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
728 741
729 if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { 742 if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
730 snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n"); 743 snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
744 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
731 return -EIO; 745 return -EIO;
732 } 746 }
733 747
@@ -737,17 +751,15 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
737 hdsp_write(hdsp, HDSP_fifoData, cache[i]); 751 hdsp_write(hdsp, HDSP_fifoData, cache[i]);
738 if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) { 752 if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
739 snd_printk ("Hammerfall-DSP: timeout during firmware loading\n"); 753 snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
754 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
740 return -EIO; 755 return -EIO;
741 } 756 }
742 } 757 }
743 758
744 ssleep(3); 759 hdsp_fifo_wait(hdsp, 3, HDSP_LONG_WAIT);
745 760 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
746 if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
747 snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
748 return -EIO;
749 }
750 761
762 ssleep(3);
751#ifdef SNDRV_BIG_ENDIAN 763#ifdef SNDRV_BIG_ENDIAN
752 hdsp->control2_register = HDSP_BIGENDIAN_MODE; 764 hdsp->control2_register = HDSP_BIGENDIAN_MODE;
753#else 765#else
@@ -773,24 +785,51 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
773{ 785{
774 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { 786 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
775 787
776 hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM); 788 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
777 hdsp_write (hdsp, HDSP_fifoData, 0); 789 hdsp_write(hdsp, HDSP_fifoData, 0);
778 if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
779 return -EIO;
780 790
781 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 791 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) {
792 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300);
793 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
794 }
795
796 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200 | HDSP_PROGRAM);
782 hdsp_write (hdsp, HDSP_fifoData, 0); 797 hdsp_write (hdsp, HDSP_fifoData, 0);
798 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) {
799 hdsp->io_type = Multiface;
800 snd_printk("Hammerfall-DSP: Multiface found\n");
801 return 0;
802 }
783 803
784 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) { 804 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
785 hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); 805 hdsp_write(hdsp, HDSP_fifoData, 0);
786 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); 806 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) {
787 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
788 hdsp->io_type = RPM;
789 else
790 hdsp->io_type = Multiface;
791 } else {
792 hdsp->io_type = Digiface; 807 hdsp->io_type = Digiface;
808 snd_printk("Hammerfall-DSP: Digiface found\n");
809 return 0;
793 } 810 }
811
812 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300);
813 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
814 hdsp_write(hdsp, HDSP_fifoData, 0);
815 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) {
816 hdsp->io_type = Multiface;
817 snd_printk("Hammerfall-DSP: Multiface found\n");
818 return 0;
819 }
820
821 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300);
822 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
823 hdsp_write(hdsp, HDSP_fifoData, 0);
824 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) {
825 hdsp->io_type = Multiface;
826 snd_printk("Hammerfall-DSP: Multiface found\n");
827 return 0;
828 }
829
830 hdsp->io_type = RPM;
831 snd_printk("Hammerfall-DSP: RPM found\n");
832 return 0;
794 } else { 833 } else {
795 /* firmware was already loaded, get iobox type */ 834 /* firmware was already loaded, get iobox type */
796 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) 835 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)