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>
This commit is contained in:
Родитель
6ab317419c
Коммит
0c2bc7c7d8
|
@ -154,10 +154,13 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
|
||||||
#define HDSP_BIGENDIAN_MODE 0x200
|
#define HDSP_BIGENDIAN_MODE 0x200
|
||||||
#define HDSP_RD_MULTIPLE 0x400
|
#define HDSP_RD_MULTIPLE 0x400
|
||||||
#define HDSP_9652_ENABLE_MIXER 0x800
|
#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_TDO 0x10000000
|
||||||
|
|
||||||
#define HDSP_S_PROGRAM (HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
|
#define HDSP_S_PROGRAM (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_0)
|
||||||
#define HDSP_S_LOAD (HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
|
#define HDSP_S_LOAD (HDSP_CYCLIC_MODE|HDSP_PROGRAM|HDSP_CONFIG_MODE_1)
|
||||||
|
|
||||||
/* Control Register bits */
|
/* Control Register bits */
|
||||||
|
|
||||||
|
@ -671,13 +674,23 @@ static unsigned int hdsp_read(struct hdsp *hdsp, int reg)
|
||||||
|
|
||||||
static int hdsp_check_for_iobox (struct hdsp *hdsp)
|
static int hdsp_check_for_iobox (struct hdsp *hdsp)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
|
if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
|
||||||
if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
|
for (i = 0; i < 500; i++) {
|
||||||
snd_printk("Hammerfall-DSP: no IO box connected!\n");
|
if (0 == (hdsp_read(hdsp, HDSP_statusRegister) &
|
||||||
hdsp->state &= ~HDSP_FirmwareLoaded;
|
HDSP_ConfigError)) {
|
||||||
return -EIO;
|
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,
|
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) {
|
||||||
|
|
||||||
if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
|
if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
|
||||||
snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
|
snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");
|
||||||
|
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,17 +751,15 @@ static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
|
||||||
hdsp_write(hdsp, HDSP_fifoData, cache[i]);
|
hdsp_write(hdsp, HDSP_fifoData, cache[i]);
|
||||||
if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
|
if (hdsp_fifo_wait (hdsp, 127, HDSP_LONG_WAIT)) {
|
||||||
snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
|
snd_printk ("Hammerfall-DSP: timeout during firmware loading\n");
|
||||||
|
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdsp_fifo_wait(hdsp, 3, HDSP_LONG_WAIT);
|
||||||
|
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200);
|
||||||
|
|
||||||
ssleep(3);
|
ssleep(3);
|
||||||
|
|
||||||
if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {
|
|
||||||
snd_printk ("Hammerfall-DSP: timeout at end of firmware loading\n");
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SNDRV_BIG_ENDIAN
|
#ifdef SNDRV_BIG_ENDIAN
|
||||||
hdsp->control2_register = HDSP_BIGENDIAN_MODE;
|
hdsp->control2_register = HDSP_BIGENDIAN_MODE;
|
||||||
#else
|
#else
|
||||||
|
@ -773,24 +785,51 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
|
||||||
{
|
{
|
||||||
if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
|
if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
|
||||||
|
|
||||||
hdsp_write (hdsp, HDSP_control2Reg, HDSP_PROGRAM);
|
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
|
||||||
hdsp_write (hdsp, HDSP_fifoData, 0);
|
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_fifoData, 0);
|
hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300);
|
||||||
|
|
||||||
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);
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
} else {
|
||||||
/* firmware was already loaded, get iobox type */
|
/* firmware was already loaded, get iobox type */
|
||||||
if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
|
if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче