⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdsp.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	size_t                period_bytes; 	     /* guess what this is */	unsigned char	      max_channels;	unsigned char	      qs_in_channels;	     /* quad speed mode for H9632 */	unsigned char         ds_in_channels;	unsigned char         ss_in_channels;	    /* different for multiface/digiface */	unsigned char	      qs_out_channels;	    	unsigned char         ds_out_channels;	unsigned char         ss_out_channels;	struct snd_dma_buffer capture_dma_buf;	struct snd_dma_buffer playback_dma_buf;	unsigned char        *capture_buffer;	    /* suitably aligned address */	unsigned char        *playback_buffer;	    /* suitably aligned address */	pid_t                 capture_pid;	pid_t                 playback_pid;	int                   running;	int                   system_sample_rate;	char                 *channel_map;	int                   dev;	int                   irq;	unsigned long         port;        void __iomem         *iobase;	snd_card_t           *card;	snd_pcm_t            *pcm;	snd_hwdep_t          *hwdep;	struct pci_dev       *pci;	snd_kcontrol_t       *spdif_ctl;        unsigned short        mixer_matrix[HDSP_MATRIX_MIXER_SIZE];};/* These tables map the ALSA channels 1..N to the channels that we   need to use in order to find the relevant channel buffer. RME   refer to this kind of mapping as between "the ADAT channel and   the DMA channel." We index it using the logical audio channel,   and the value is the DMA channel (i.e. channel buffer number)   where the data for that channel can be read/written from/to.*/static char channel_map_df_ss[HDSP_MAX_CHANNELS] = {	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,	18, 19, 20, 21, 22, 23, 24, 25};static char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */	/* Analog */	0, 1, 2, 3, 4, 5, 6, 7, 	/* ADAT 2 */	16, 17, 18, 19, 20, 21, 22, 23, 	/* SPDIF */	24, 25,	-1, -1, -1, -1, -1, -1, -1, -1};static char channel_map_ds[HDSP_MAX_CHANNELS] = {	/* ADAT channels are remapped */	1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,	/* channels 12 and 13 are S/PDIF */	24, 25,	/* others don't exist */	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};static char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {	/* ADAT channels */	0, 1, 2, 3, 4, 5, 6, 7,	/* SPDIF */	8, 9,	/* Analog */	10, 11, 	/* AO4S-192 and AI4S-192 extension boards */	12, 13, 14, 15,	/* others don't exist */	-1, -1, -1, -1, -1, -1, -1, -1, 	-1, -1};static char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {	/* ADAT */	1, 3, 5, 7,	/* SPDIF */	8, 9,	/* Analog */	10, 11, 	/* AO4S-192 and AI4S-192 extension boards */	12, 13, 14, 15,	/* others don't exist */	-1, -1, -1, -1, -1, -1, -1, -1,	-1, -1, -1, -1, -1, -1};static char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {	/* ADAT is disabled in this mode */	/* SPDIF */	8, 9,	/* Analog */	10, 11,	/* AO4S-192 and AI4S-192 extension boards */	12, 13, 14, 15,	/* others don't exist */	-1, -1, -1, -1, -1, -1, -1, -1,	-1, -1, -1, -1, -1, -1, -1, -1,	-1, -1};static int snd_hammerfall_get_buffer(struct pci_dev *pci, struct snd_dma_buffer *dmab, size_t size){	dmab->dev.type = SNDRV_DMA_TYPE_DEV;	dmab->dev.dev = snd_dma_pci_data(pci);	if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {		if (dmab->bytes >= size)			return 0;	}	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),				size, dmab) < 0)		return -ENOMEM;	return 0;}static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci){	if (dmab->area) {		dmab->dev.dev = NULL; /* make it anonymous */		snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));	}}static struct pci_device_id snd_hdsp_ids[] = {	{		.vendor = PCI_VENDOR_ID_XILINX,		.device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP, 		.subvendor = PCI_ANY_ID,		.subdevice = PCI_ANY_ID,	}, /* RME Hammerfall-DSP */	{ 0, },};MODULE_DEVICE_TABLE(pci, snd_hdsp_ids);/* prototypes */static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp);static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp);static int snd_hdsp_enable_io (hdsp_t *hdsp);static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp);static void snd_hdsp_initialize_channels (hdsp_t *hdsp);static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout);static int hdsp_autosync_ref(hdsp_t *hdsp);static int snd_hdsp_set_defaults(hdsp_t *hdsp);static void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp);static int hdsp_playback_to_output_key (hdsp_t *hdsp, int in, int out){	switch (hdsp->firmware_rev) {	case 0xa:		return (64 * out) + (32 + (in));	case 0x96:	case 0x97:		return (32 * out) + (16 + (in));	default:		return (52 * out) + (26 + (in));	}}static int hdsp_input_to_output_key (hdsp_t *hdsp, int in, int out){	switch (hdsp->firmware_rev) {	case 0xa:		return (64 * out) + in;	case 0x96:	case 0x97:		return (32 * out) + in;	default:		return (52 * out) + in;	}}static void hdsp_write(hdsp_t *hdsp, int reg, int val){	writel(val, hdsp->iobase + reg);}static unsigned int hdsp_read(hdsp_t *hdsp, int reg){	return readl (hdsp->iobase + reg);}static int hdsp_check_for_iobox (hdsp_t *hdsp){	if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;	if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {		snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n");		hdsp->state &= ~HDSP_FirmwareLoaded;		return -EIO;	}	return 0;}static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) {	int i;	unsigned long flags;	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {				snd_printk ("Hammerfall-DSP: loading firmware\n");		hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_PROGRAM);		hdsp_write (hdsp, HDSP_fifoData, 0);				if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) {			snd_printk ("Hammerfall-DSP: timeout waiting for download preparation\n");			return -EIO;		}				hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);				for (i = 0; i < 24413; ++i) {			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");				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;		}#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");		spin_lock_irqsave(&hdsp->lock, flags);		snd_hdsp_set_defaults(hdsp);		spin_unlock_irqrestore(&hdsp->lock, flags); 	}		hdsp->state |= HDSP_FirmwareLoaded;	return 0;}static int hdsp_get_iobox_version (hdsp_t *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);		if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) {			hdsp->io_type = Multiface;			hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);			hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);			hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT);		} else {			hdsp->io_type = Digiface;		} 	} else {		/* firmware was already loaded, get iobox type */		if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)			hdsp->io_type = Multiface;		else			hdsp->io_type = Digiface;	}	return 0;}static int hdsp_check_for_firmware (hdsp_t *hdsp, int show_err){	if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {		snd_printk(KERN_ERR "Hammerfall-DSP: firmware not present.\n");		hdsp->state &= ~HDSP_FirmwareLoaded;		if (! show_err)			return -EIO;		/* try to load firmware */		if (hdsp->state & HDSP_FirmwareCached) {			if (snd_hdsp_load_firmware_from_cache(hdsp) != 0)				snd_printk(KERN_ERR "Hammerfall-DSP: Firmware loading from cache failed, please upload manually.\n");		} else {			snd_printk(KERN_ERR "Hammerfall-DSP: No firmware loaded nor cached, please upload firmware.\n");		}		return -EIO;	}	return 0;}static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout){    	int i;	/* the fifoStatus registers reports on how many words	   are available in the command FIFO.	*/		for (i = 0; i < timeout; i++) {		if ((int)(hdsp_read (hdsp, HDSP_fifoStatus) & 0xff) <= count)			return 0;		/* not very friendly, but we only do this during a firmware		   load and changing the mixer, so we just put up with it.		*/		udelay (100);	}	snd_printk ("Hammerfall-DSP: wait for FIFO status <= %d failed after %d iterations\n",		    count, timeout);	return -1;}static int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr){	if (addr >= HDSP_MATRIX_MIXER_SIZE)		return 0;	return hdsp->mixer_matrix[addr];}static int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data){	unsigned int ad;	if (addr >= HDSP_MATRIX_MIXER_SIZE)		return -1;		if (hdsp->io_type == H9652 || hdsp->io_type == H9632) {		/* from martin bjornsen:		   		   "You can only write dwords to the		   mixer memory which contain two		   mixer values in the low and high		   word. So if you want to change		   value 0 you have to read value 1		   from the cache and write both to		   the first dword in the mixer		   memory."		*/		if (hdsp->io_type == H9632 && addr >= 512)			return 0;		if (hdsp->io_type == H9652 && addr >= 1352)			return 0;		hdsp->mixer_matrix[addr] = data;				/* `addr' addresses a 16-bit wide address, but		   the address space accessed via hdsp_write		   uses byte offsets. put another way, addr		   varies from 0 to 1351, but to access the		   corresponding memory location, we need		   to access 0 to 2703 ...		*/		ad = addr/2;			hdsp_write (hdsp, 4096 + (ad*4), 			    (hdsp->mixer_matrix[(addr&0x7fe)+1] << 16) + 			    hdsp->mixer_matrix[addr&0x7fe]);				return 0;	} else {		ad = (addr << 16) + data;				if (hdsp_fifo_wait(hdsp, 127, HDSP_LONG_WAIT))			return -1;		hdsp_write (hdsp, HDSP_fifoData, ad);		hdsp->mixer_matrix[addr] = data;	}	return 0;}static int snd_hdsp_use_is_exclusive(hdsp_t *hdsp){	unsigned long flags;	int ret = 1;	spin_lock_irqsave(&hdsp->lock, flags);	if ((hdsp->playback_pid != hdsp->capture_pid) &&	    (hdsp->playback_pid >= 0) && (hdsp->capture_pid >= 0))		ret = 0;	spin_unlock_irqrestore(&hdsp->lock, flags);	return ret;}static int hdsp_external_sample_rate (hdsp_t *hdsp){	unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);	unsigned int rate_bits = status2 & HDSP_systemFrequencyMask;	switch (rate_bits) {	case HDSP_systemFrequency32:   return 32000;	case HDSP_systemFrequency44_1: return 44100;	case HDSP_systemFrequency48:   return 48000;	case HDSP_systemFrequency64:   return 64000;	case HDSP_systemFrequency88_2: return 88200;	case HDSP_systemFrequency96:   return 96000;	default:		return 0;	}}static int hdsp_spdif_sample_rate(hdsp_t *hdsp){	unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);	unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);	if (status & HDSP_SPDIFErrorFlag)		return 0;		switch (rate_bits) {	case HDSP_spdifFrequency32KHz: return 32000;	case HDSP_spdifFrequency44_1KHz: return 44100;	case HDSP_spdifFrequency48KHz: return 48000;	case HDSP_spdifFrequency64KHz: return 64000;	case HDSP_spdifFrequency88_2KHz: return 88200;	case HDSP_spdifFrequency96KHz: return 96000;	case HDSP_spdifFrequency128KHz: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -