📄 hdsp.c
字号:
u32 control_register; /* cached value */ u32 control2_register; /* cached value */ u32 creg_spdif; u32 creg_spdif_stream; char *card_name; /* digiface/multiface */ HDSP_IO_Type io_type; /* ditto, but for code use */ unsigned short firmware_rev; unsigned short state; /* stores state bits */ u32 firmware_cache[24413]; /* this helps recover from accidental iobox power failure */ 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; void *capture_buffer_unaligned; /* original buffer addresses */ void *playback_buffer_unaligned; /* original buffer addresses */ unsigned char *capture_buffer; /* suitably aligned address */ unsigned char *playback_buffer; /* suitably aligned address */ dma_addr_t capture_buffer_addr; dma_addr_t playback_buffer_addr; pid_t capture_pid; pid_t playback_pid; int running; int passthru; /* non-zero if doing pass-thru */ int system_sample_rate; char *channel_map; int dev; int irq; unsigned long port; struct resource *res_port; unsigned long 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};#define HDSP_PREALLOCATE_MEMORY /* via module snd-hdsp_mem */#ifdef HDSP_PREALLOCATE_MEMORYstatic void *snd_hammerfall_get_buffer(struct pci_dev *pci, size_t size, dma_addr_t *addrp, int capture){ struct snd_dma_device pdev; struct snd_dma_buffer dmbuf; memset(&pdev, 0, sizeof(pdev)); pdev.type = SNDRV_DMA_TYPE_DEV; pdev.dev = snd_dma_pci_data(pci); pdev.id = capture; dmbuf.bytes = 0; if (! snd_dma_get_reserved(&pdev, &dmbuf)) { if (snd_dma_alloc_pages(&pdev, size, &dmbuf) < 0) return NULL; snd_dma_set_reserved(&pdev, &dmbuf); } *addrp = dmbuf.addr; return dmbuf.area;}static void snd_hammerfall_free_buffer(struct pci_dev *pci, size_t size, void *ptr, dma_addr_t addr, int capture){ struct snd_dma_device pdev; memset(&pdev, 0, sizeof(pdev)); pdev.type = SNDRV_DMA_TYPE_DEV; pdev.dev = snd_dma_pci_data(pci); pdev.id = capture; snd_dma_free_reserved(&pdev);}#elsestatic void *snd_hammerfall_get_buffer(struct pci_dev *pci, size_t size, dma_addr_t *addrp, int capture){ return snd_malloc_pci_pages(pci, size, addrp);}static void snd_hammerfall_free_buffer(struct pci_dev *pci, size_t size, void *ptr, dma_addr_t addr, int capture){ snd_free_pci_pages(pci, size, ptr, addr);}#endifstatic 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 __devinit snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp);static int __devinit snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp);static inline int snd_hdsp_enable_io (hdsp_t *hdsp);static inline void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp);static inline void snd_hdsp_initialize_channels (hdsp_t *hdsp);static inline 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 inline void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp);static inline 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 inline 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 inline void hdsp_write(hdsp_t *hdsp, int reg, int val){ writel(val, hdsp->iobase + reg);}static inline unsigned int hdsp_read(hdsp_t *hdsp, int reg){ return readl (hdsp->iobase + reg);}static inline 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 ("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 ("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 ("timeout during firmware loading\n"); return -EIO; } } if ((1000 / HZ) < 3000) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((3000 * HZ + 999) / 1000); } else { mdelay(3000); } if (hdsp_fifo_wait (hdsp, 0, HDSP_LONG_WAIT)) { snd_printk ("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 ("finished firmware loading\n"); } if (hdsp->state & HDSP_InitializationComplete) { snd_printk("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 inline int hdsp_get_iobox_version (hdsp_t *hdsp){ int err; if (hdsp_check_for_iobox (hdsp)) { return -EIO; } if ((err = snd_hdsp_enable_io(hdsp)) < 0) { return err; } 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 inline int hdsp_check_for_firmware (hdsp_t *hdsp){ if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { snd_printk("firmware not present.\n"); hdsp->state &= ~HDSP_FirmwareLoaded; return -EIO; } return 0;}static inline 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 ("wait for FIFO status <= %d failed after %d iterations\n", count, timeout); return -1;}static inline int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr){ if (addr >= HDSP_MATRIX_MIXER_SIZE) { return 0; } return hdsp->mixer_matrix[addr];}static inline 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 bj鰎nsen: "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 inline int snd_hdsp_use_is_exclusive(hdsp_t *hdsp){ unsigned long flags;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -