int videobuf_sg_dma_map(struct device *dev, struct videobuf_dmabuf *dma) { struct videobuf_queue q; q.dev = dev; return videobuf_dma_map(&q, dma); }
int videobuf_pci_dma_map(struct pci_dev *pci,struct videobuf_dmabuf *dma) { struct videobuf_queue q; q.dev=pci; return (videobuf_dma_map(&q,dma)); }
int tw686x_audio_create(struct tw686x_adev *dev) { unsigned int period_size, periods; int err; daprintk(DPRT_LEVEL0, dev, "%s()\n", __func__); mutex_init(&dev->lock); period_size = TW686X_AUDIO_PERIOD_SIZE; //固定为4096 periods = 4; //最小为2 daprintk(DPRT_LEVEL0, dev, "%s(bufsize=%d)\n", __func__, period_size * periods); dev->blocks = periods; dev->blksize = period_size; dev->bufsize = period_size * periods; dev->period_idx = 0; dev->read_offset = 0; dev->substream = NULL; dev->card = NULL; err = tw686x_audio_buffer_init(dev); if (0 != err) { dev->blocks = 0; dev->blksize = 0; dev->bufsize = 0; return err; } #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) if (0 != (err = videobuf_dma_map(&dev->chip->pci->dev, &dev->dma))) { #else if (0 != (err = videobuf_sg_dma_map(&dev->chip->pci->dev, &dev->dma))) { #endif tw686x_audio_buffer_free(dev); return err; } daprintk(DPRT_LEVEL0, dev, "%s_%d: period_size %d, periods %d, sglen %d.\n", __func__, dev->channel_id, period_size, periods, dev->dma.sglen); return 0; } int tw686x_audio_free(struct tw686x_adev *dev) { if (dev->substream != NULL) { #if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) videobuf_dma_unmap(&dev->chip->pci->dev, &dev->dma); #else videobuf_sg_dma_unmap(&dev->chip->pci->dev, &dev->dma); #endif tw686x_audio_buffer_free(dev); dev->substream = NULL; } return 0; }
/* * hw_params callback */ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream); struct videobuf_dmabuf *dma; struct cx23885_audio_buffer *buf; int ret; if (substream->runtime->dma_area) { dsp_buffer_free(chip); substream->runtime->dma_area = NULL; } chip->period_size = params_period_bytes(hw_params); chip->num_periods = params_periods(hw_params); chip->dma_size = chip->period_size * params_periods(hw_params); BUG_ON(!chip->dma_size); BUG_ON(chip->num_periods & (chip->num_periods-1)); buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (NULL == buf) return -ENOMEM; buf->bpl = chip->period_size; dma = &buf->dma; videobuf_dma_init(dma); ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE, (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); if (ret < 0) goto error; ret = videobuf_dma_map(&chip->pci->dev, dma); if (ret < 0) goto error; ret = cx23885_risc_databuffer(chip->pci, &buf->risc, dma->sglist, chip->period_size, chip->num_periods, 1); if (ret < 0) goto error; /* Loop back to start of program */ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC); buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ chip->buf = buf; chip->dma_risc = dma; substream->runtime->dma_area = chip->dma_risc->vaddr; substream->runtime->dma_bytes = chip->dma_size; substream->runtime->dma_addr = 0; return 0; error: kfree(buf); return ret; }