[alsa-devel] [PATCH - hdsp.c 1/1] HDSP fixes for RPM
- 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@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)
On 11/21/2012 10:33 PM, Karl Grill wrote:
Hi!
- changed iobox recognition and firmware loading to mimick XP driver
- added loop to check_for_iobox() to fix timing issues
Did you have the opportunity to test with Multiface and/or Digiface?
I can test with a Multiface next Tuesday, but I have no Digiface.
Cheers
On 11/21/2012 10:33 PM, Karl Grill wrote:
hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
hdsp_write (hdsp, HDSP_control2Reg, 0x10a0);
Where did you get the constant(s) from? Bus snooping?
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;
Question: I see two sequences of 0x900, 0x10a0 that detect the Multiface. Is the duplicate intended or just a copy&paste error?
Cheers
participants (2)
-
Adrian Knoth
-
Karl Grill