📄 cs4231.c
字号:
/* normalize for where we are. */ thisdir->samples = ((count - nextcount) + (length - curcount));}static int cs4231_open(struct inode * inode, struct file * file, struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; /* Set the default audio parameters if not already in use. */ if (file->f_mode & FMODE_WRITE) { if (!(drv->flags & SDF_OPEN_WRITE) && (cs4231_chip->perchip_info.play.active == 0)) { cs4231_chip->perchip_info.play.open = 1; cs4231_chip->perchip_info.play.samples = cs4231_chip->perchip_info.play.error = 0; } } if (file->f_mode & FMODE_READ) { if (!(drv->flags & SDF_OPEN_READ) && (cs4231_chip->perchip_info.record.active == 0)) { cs4231_chip->perchip_info.record.open = 1; cs4231_chip->perchip_info.record.samples = cs4231_chip->perchip_info.record.error = 0; } } cs4231_ready(drv); CHIP_READY(); MOD_INC_USE_COUNT; return 0;}static void cs4231_release(struct inode * inode, struct file * file, struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private; void (*dma_unmap_single)(struct sbus_dev *, dma_addr_t, size_t, int) = sbus_unmap_single;#ifdef EB4231_SUPPORT if (cs4231_chip->status & CS_STATUS_IS_EBUS) dma_unmap_single = (void (*)(struct sbus_dev *, dma_addr_t, size_t, int)) pci_unmap_single;#endif /* zero out any info about what data we have as well */ if (file->f_mode & FMODE_READ) { /* stop capture here or midlevel? */ cs4231_chip->perchip_info.record.open = 0; if (cs4231_chip->input_dma_handle) { dma_unmap_single(drv->dev, cs4231_chip->input_dma_handle, cs4231_chip->input_dma_size, SBUS_DMA_FROMDEVICE); cs4231_chip->input_dma_handle = 0; cs4231_chip->input_dma_size = 0; } if (cs4231_chip->input_next_dma_handle) { dma_unmap_single(drv->dev, cs4231_chip->input_next_dma_handle, cs4231_chip->input_next_dma_size, SBUS_DMA_FROMDEVICE); cs4231_chip->input_next_dma_handle = 0; cs4231_chip->input_next_dma_size = 0; } } if (file->f_mode & FMODE_WRITE) { cs4231_chip->perchip_info.play.active = cs4231_chip->perchip_info.play.open = 0; if (cs4231_chip->output_dma_handle) { dma_unmap_single(drv->dev, cs4231_chip->output_dma_handle, cs4231_chip->output_dma_size, SBUS_DMA_TODEVICE); cs4231_chip->output_dma_handle = 0; cs4231_chip->output_dma_size = 0; } if (cs4231_chip->output_next_dma_handle) { dma_unmap_single(drv->dev, cs4231_chip->output_next_dma_handle, cs4231_chip->output_next_dma_size, SBUS_DMA_TODEVICE); cs4231_chip->output_next_dma_handle = 0; cs4231_chip->output_next_dma_size = 0; } } if (!cs4231_chip->perchip_info.play.open && !cs4231_chip->perchip_info.record.open && (cs4231_chip->status & CS_STATUS_INIT_ON_CLOSE)) { cs4231_chip_reset(drv); cs4231_chip->status &= ~CS_STATUS_INIT_ON_CLOSE; } MOD_DEC_USE_COUNT;}static void cs4231_playintr(struct sparcaudio_driver *drv, int push){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; int status = 0; if (!push) { if (!cs4231_chip->perchip_info.play.active) { sbus_writel(cs4231_chip->output_next_dma_handle, cs4231_chip->regs + APCPNVA); sbus_writel(cs4231_chip->output_next_dma_size, cs4231_chip->regs + APCPNC); } sparcaudio_output_done(drv, 0); return; } if (cs4231_chip->playlen == 0 && cs4231_chip->output_size > 0) cs4231_chip->playlen = cs4231_chip->output_size; if (cs4231_chip->output_dma_handle) { sbus_unmap_single(drv->dev, cs4231_chip->output_dma_handle, cs4231_chip->output_dma_size, SBUS_DMA_TODEVICE); cs4231_chip->output_dma_handle = 0; cs4231_chip->output_dma_size = 0; cs4231_chip->playing_count--; status++; } if (cs4231_chip->output_next_dma_handle) { cs4231_chip->output_dma_handle = cs4231_chip->output_next_dma_handle; cs4231_chip->output_dma_size = cs4231_chip->output_next_dma_size; cs4231_chip->output_next_dma_size = 0; cs4231_chip->output_next_dma_handle = 0; } if ((cs4231_chip->output_ptr && cs4231_chip->output_size > 0) && !(cs4231_chip->perchip_info.play.pause)) { cs4231_chip->output_next_dma_handle = sbus_map_single(drv->dev, (char *)cs4231_chip->output_ptr, cs4231_chip->output_size, SBUS_DMA_TODEVICE); cs4231_chip->output_next_dma_size = cs4231_chip->output_size; sbus_writel(cs4231_chip->output_next_dma_handle, cs4231_chip->regs + APCPNVA); sbus_writel(cs4231_chip->output_next_dma_size, cs4231_chip->regs + APCPNC); cs4231_chip->output_size = 0; cs4231_chip->output_ptr = NULL; cs4231_chip->playing_count++; status += 2; } else { sbus_writel(0, cs4231_chip->regs + APCPNVA); sbus_writel(0, cs4231_chip->regs + APCPNC); } sparcaudio_output_done(drv, status);}#ifdef EB4231_SUPPORTstatic void eb4231_playintr(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; int status = 0; if (cs4231_chip->playlen == 0 && cs4231_chip->output_size > 0) cs4231_chip->playlen = cs4231_chip->output_size; if (cs4231_chip->output_dma_handle) { pci_unmap_single((struct pci_dev *)drv->dev, cs4231_chip->output_dma_handle, cs4231_chip->output_dma_size, PCI_DMA_TODEVICE); cs4231_chip->output_dma_handle = 0; cs4231_chip->output_dma_size = 0; cs4231_chip->playing_count--; status++; } if(cs4231_chip->output_next_dma_handle) { cs4231_chip->output_dma_handle = cs4231_chip->output_next_dma_handle; cs4231_chip->output_dma_size = cs4231_chip->output_next_dma_size; cs4231_chip->output_next_dma_handle = 0; cs4231_chip->output_next_dma_size = 0; } if ((cs4231_chip->output_ptr && cs4231_chip->output_size > 0) && !(cs4231_chip->perchip_info.play.pause)) { cs4231_chip->output_next_dma_handle = pci_map_single((struct pci_dev *)drv->dev, (char *)cs4231_chip->output_ptr, cs4231_chip->output_size, PCI_DMA_TODEVICE); cs4231_chip->output_next_dma_size = cs4231_chip->output_size; writel(cs4231_chip->output_next_dma_size, cs4231_chip->eb2p + EBDMA_COUNT); writel(cs4231_chip->output_next_dma_handle, cs4231_chip->eb2p + EBDMA_ADDR); cs4231_chip->output_size = 0; cs4231_chip->output_ptr = NULL; cs4231_chip->playing_count++; status += 2; } sparcaudio_output_done(drv, status);}#endifstatic void cs4231_recclear(int fmt, char *dmabuf, int length){ switch (fmt) { case AUDIO_ENCODING_LINEAR: memset(dmabuf, 0x00, length); break; case AUDIO_ENCODING_ALAW: memset(dmabuf, 0xd5, length); break; case AUDIO_ENCODING_ULAW: memset(dmabuf, 0xff, length); break; }}static int cs4231_recintr(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; int status = 0; if (cs4231_chip->perchip_info.record.active == 0) { dprintk(("going inactive\n")); cs4231_pollinput(drv); cs4231_disable_rec(drv); } if (cs4231_chip->input_dma_handle) { sbus_unmap_single(drv->dev, cs4231_chip->input_dma_handle, cs4231_chip->input_dma_size, SBUS_DMA_FROMDEVICE); cs4231_chip->input_dma_handle = 0; cs4231_chip->input_dma_size = 0; cs4231_chip->recording_count--; status++; } if (cs4231_chip->input_next_dma_handle) { cs4231_chip->input_dma_handle = cs4231_chip->input_next_dma_handle; cs4231_chip->input_dma_size = cs4231_chip->input_next_dma_size; cs4231_chip->input_next_dma_size = 0; cs4231_chip->input_next_dma_handle = 0; } if ((cs4231_chip->input_ptr && cs4231_chip->input_size > 0) && !(cs4231_chip->perchip_info.record.pause)) { cs4231_recclear(cs4231_chip->perchip_info.record.encoding, (char *)cs4231_chip->input_ptr, cs4231_chip->input_size); cs4231_chip->input_next_dma_handle = sbus_map_single(drv->dev, (char *)cs4231_chip->input_ptr, cs4231_chip->input_size, SBUS_DMA_FROMDEVICE); cs4231_chip->input_next_dma_size = cs4231_chip->input_size; sbus_writel(cs4231_chip->input_next_dma_handle, cs4231_chip->regs + APCCNVA); sbus_writel(cs4231_chip->input_next_dma_size, cs4231_chip->regs + APCCNC); cs4231_chip->input_size = 0; cs4231_chip->input_ptr = NULL; cs4231_chip->recording_count++; status += 2; } else { sbus_writel(0, cs4231_chip->regs + APCCNVA); sbus_writel(0, cs4231_chip->regs + APCCNC); } sparcaudio_input_done(drv, status); return 1;}#ifdef EB4231_SUPPORTstatic int eb4231_recintr(struct sparcaudio_driver *drv){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; int status = 0; if (cs4231_chip->perchip_info.record.active == 0) { dprintk(("going inactive\n")); eb4231_pollinput(drv); cs4231_disable_rec(drv); } if (cs4231_chip->input_dma_handle) { pci_unmap_single((struct pci_dev *)drv->dev, cs4231_chip->input_dma_handle, cs4231_chip->input_dma_size, PCI_DMA_FROMDEVICE); cs4231_chip->input_dma_handle = 0; cs4231_chip->input_dma_size = 0; cs4231_chip->recording_count--; status++; } if (cs4231_chip->input_next_dma_handle) { cs4231_chip->input_dma_handle = cs4231_chip->input_next_dma_handle; cs4231_chip->input_dma_size = cs4231_chip->input_next_dma_size; cs4231_chip->input_next_dma_size = 0; cs4231_chip->input_next_dma_handle = 0; } if ((cs4231_chip->input_ptr && cs4231_chip->input_size > 0) && !(cs4231_chip->perchip_info.record.pause)) { cs4231_recclear(cs4231_chip->perchip_info.record.encoding, (char *)cs4231_chip->input_ptr, cs4231_chip->input_size); cs4231_chip->input_next_dma_handle = pci_map_single((struct pci_dev *)drv->dev, (char *)cs4231_chip->input_ptr, cs4231_chip->input_size, PCI_DMA_FROMDEVICE); cs4231_chip->input_next_dma_size = cs4231_chip->input_size; writel(cs4231_chip->input_next_dma_size, cs4231_chip->eb2c + EBDMA_COUNT); writel(cs4231_chip->input_next_dma_handle, cs4231_chip->eb2c + EBDMA_ADDR); cs4231_chip->input_size = 0; cs4231_chip->input_ptr = NULL; cs4231_chip->recording_count++; status += 2; } sparcaudio_input_done(drv, status); return 1;}#endif#ifdef EB4231_SUPPORTstatic void eb4231_start_output(struct sparcaudio_driver *drv, __u8 * buffer, unsigned long count){ struct cs4231_chip *cs4231_chip = (struct cs4231_chip *) drv->private; u32 dcsr; cs4231_chip->output_ptr = buffer; cs4231_chip->output_size = count; if (cs4231_chip->perchip_info.play.active || (cs4231_chip->perchip_info.play.pause)) return; cs4231_ready(drv); cs4231_chip->perchip_info.play.active = 1; cs4231_chip->playing_count = 0; dcsr = readl(cs4231_chip->eb2p + EBDMA_CSR); if (!(dcsr & EBUS_DCSR_EN_DMA)) { writel(EBUS_DCSR_RESET, cs4231_chip->eb2p + EBDMA_CSR); writel(EBUS_DCSR_BURST_SZ_16, cs4231_chip->eb2p + EBDMA_CSR); eb4231_playintr(drv); writel(EBUS_DCSR_BURST_SZ_16 | (EBUS_DCSR_EN_DMA | EBUS_DCSR_INT_EN | EBUS_DCSR_EN_CNT | EBUS_DCSR_EN_NEXT), cs4231_chip->eb2p + EBDMA_CSR); cs4231_enable_play(drv); cs4231_ready(drv); } else { eb4231_playintr(drv); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -