[alsa-devel] [PATCH v3 1/4] ALSA: hdsp - Fix detection for RME RPM/Multiface/Digiface ioboxes
Takashi Iwai
tiwai at suse.de
Wed Jan 16 07:49:35 CET 2013
At Tue, 15 Jan 2013 18:52:20 +0100,
Adrian Knoth wrote:
>
> 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 at chello.at> and then modified to
> comply with kernel coding guidelines + current HEAD.
>
> Signed-off-by: Adrian Knoth <adi at drcomp.erfurt.thur.de>
Thanks, applied all patches to for-next branch.
Takashi
>
> diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
> index 4fae81f..866d684 100644
> --- a/sound/pci/rme9652/hdsp.c
> +++ b/sound/pci/rme9652/hdsp.c
> @@ -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 */
>
> @@ -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,
> @@ -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;
> }
>
> @@ -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
> @@ -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)
> --
> 1.7.10.4
>
More information about the Alsa-devel
mailing list