diff options
author | Adrian Knoth <adi@drcomp.erfurt.thur.de> | 2013-01-15 12:52:20 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-01-16 01:48:38 -0500 |
commit | 0c2bc7c7d8306bad0ec534852f1900140b80c956 (patch) | |
tree | f3bfd53313e2933a3218b166c69cbb4dcce8c58d /sound/pci/rme9652 | |
parent | 6ab317419c62850a71e2adfd1573e5ee87d8774f (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.c | 91 |
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 | ||
672 | static int hdsp_check_for_iobox (struct hdsp *hdsp) | 675 | static 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 | ||
683 | static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, | 696 | static 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) |