[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