[alsa-devel] [PATCH - hdsp.c 1/1] HDSP fixes for RPM
Karl Grill
kgrill at chello.at
Wed Nov 21 22:33:52 CET 2012
- changed iobox recognition and firmware loading to mimick XP driver
- added loop to check_for_iobox() to fix timing issues
Signed-off-by: Karl Grill <kgrill at chello.at>
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 0d6930c..4229b0d 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -155,10 +155,11 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#define HDSP_BIGENDIAN_MODE 0x200
#define HDSP_RD_MULTIPLE 0x400
#define HDSP_9652_ENABLE_MIXER 0x800
+#define HDSP_DUNNO 0x1000
#define HDSP_TDO 0x10000000
-#define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
-#define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
+#define HDSP_S_PROGRAM (HDSP_DUNNO|HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
+#define HDSP_S_LOAD (HDSP_DUNNO|HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
/* Control Register bits */
@@ -676,13 +677,20 @@ static unsigned int hdsp_read(struct hdsp *hdsp, int reg)
static int hdsp_check_for_iobox (struct hdsp *hdsp)
{
+ int i;
+
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
- if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
- snd_printk("Hammerfall-DSP: no IO box connected!\n");
- hdsp->state &= ~HDSP_FirmwareLoaded;
- return -EIO;
+ for(i=0; i<10000; i++) {
+ if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError)==0) {
+ if(i)
+ snd_printk("Hammerfall-DSP: IO box found after %d ms\n", i);
+ return 0;
+ }
+ msleep(1);
}
- return 0;
+ snd_printk("Hammerfall-DSP: no IO box connected!\n");
+ hdsp->state &= ~HDSP_FirmwareLoaded;
+ return -EIO;
}
static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
@@ -722,6 +730,7 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
+ hdsp_write (hdsp, HDSP_control2Reg, 0x800);
return -EIO;
}
@@ -731,25 +740,25 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
hdsp_write(hdsp, HDSP_fifoData, hdsp->firmware_cache[i]);
if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
+ hdsp_write (hdsp, HDSP_control2Reg, 0x800);
return -EIO;
}
}
- ssleep(3);
-
- if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
- snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
- return -EIO;
- }
+ hdsp_fifo_wait (hdsp, 3, HDSP_LONG_WAIT);
+ hdsp_write (hdsp, HDSP_control2Reg, 0x800);
+ ssleep(3);
#ifdef SNDRV_BIG_ENDIAN
hdsp->control2_register = HDSP_BIGENDIAN_MODE;
#else
hdsp->control2_register = 0;
#endif
+
hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
snd_printk ("Hammerfall-DSP: finished firmware loading\n");
+
}
if (hdsp->state & HDSP_InitializationComplete) {
snd_printk(KERN_INFO "Hammerfall-DSP: firmware loaded from cache, restoring defaults\n");
@@ -767,24 +776,46 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
{
if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
+ hdsp_write (hdsp, HDSP_control2Reg, 0x10a0);
hdsp_write (hdsp, HDSP_fifoData, 0);
- if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
- return -EIO;
-
- hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+ hdsp_write(hdsp, HDSP_control2Reg, 0x900);
+ hdsp_write(hdsp, HDSP_control2Reg, 0x10a0);
+ }
+ hdsp_write(hdsp, HDSP_control2Reg, 0x820);
hdsp_write (hdsp, HDSP_fifoData, 0);
-
- if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) {
- hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
- hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
- if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
- hdsp->io_type = RPM;
- else
- hdsp->io_type = Multiface;
- } else {
- hdsp->io_type = Digiface;
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+ hdsp->io_type=Multiface;
+ snd_printk("Hammerfall-DSP: Multiface found\n");
+ return 0;
+ }
+ hdsp_write(hdsp, HDSP_control2Reg, 0x10a0);
+ hdsp_write (hdsp, HDSP_fifoData, 0);
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) == 0) {
+ hdsp->io_type=Digiface;
+ snd_printk("Hammerfall-DSP: Digiface found\n");
+ return 0;
+ }
+ hdsp_write(hdsp, HDSP_control2Reg, 0x900);
+ hdsp_write(hdsp, HDSP_control2Reg, 0x10a0);
+ hdsp_write (hdsp, HDSP_fifoData, 0);
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) == 0) {
+ hdsp->io_type=Multiface;
+ snd_printk("Hammerfall-DSP: Multiface found\n");
+ return 0;
+ }
+ hdsp_write(hdsp, HDSP_control2Reg, 0x900);
+ hdsp_write(hdsp, HDSP_control2Reg, 0x10a0);
+ hdsp_write (hdsp, HDSP_fifoData, 0);
+ if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0) {
+ hdsp->io_type=Multiface;
+ snd_printk("Hammerfall-DSP: Multiface found\n");
+ return 0;
}
+ hdsp->io_type=RPM;
+ snd_printk("Hammerfall-DSP: RPM found\n");
+ return 0;
+
} else {
/* firmware was already loaded, get iobox type */
if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
--
1.7.2.5
More information about the Alsa-devel
mailing list