Skip to content

Commit

Permalink
ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Adrian Knoth authored and Takashi Iwai committed Jan 16, 2013
1 parent 6ab3174 commit 0c2bc7c
Showing 1 changed file with 65 additions and 26 deletions.
91 changes: 65 additions & 26 deletions sound/pci/rme9652/hdsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,13 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
#define HDSP_BIGENDIAN_MODE 0x200
#define HDSP_RD_MULTIPLE 0x400
#define HDSP_9652_ENABLE_MIXER 0x800
#define HDSP_S200 0x800
#define HDSP_S300 (0x100 | HDSP_S200) /* dummy, purpose of 0x100 unknown */
#define HDSP_CYCLIC_MODE 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_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
#define HDSP_S_LOAD (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_1)

/* Control Register bits */

Expand Down Expand Up @@ -671,13 +674,23 @@ 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 < 500; i++) {
if (0 == (hdsp_read(hdsp, HDSP_statusRegister) &
HDSP_ConfigError)) {
if (i) {
snd_printd("Hammerfall-DSP: IO box found after %d ms\n",
(20 * i));
}
return 0;
}
msleep(20);
}
return 0;
snd_printk(KERN_ERR "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,
Expand Down Expand Up @@ -728,6 +741,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, HDSP_S200);
return -EIO;
}

Expand All @@ -737,17 +751,15 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
hdsp_write(hdsp, HDSP_fifoData, 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, HDSP_S200);
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, HDSP_S200);

ssleep(3);
#ifdef SNDRV_BIG_ENDIAN
hdsp->control2_register = HDSP_BIGENDIAN_MODE;
#else
Expand All @@ -773,24 +785,51 @@ 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_fifoData, 0);
if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT) < 0)
return -EIO;
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
hdsp_write(hdsp, HDSP_fifoData, 0);

hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) {
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300);
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
}

hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200 | HDSP_PROGRAM);
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;
}

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_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
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, HDSP_S300);
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
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, HDSP_S300);
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
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)
Expand Down

0 comments on commit 0c2bc7c

Please sign in to comment.