int __devinit snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; struct snd_pcm_substream *substream; int err; int capture=1; /* snd_printk(KERN_DEBUG "snd_p16v_pcm called. device=%d\n", device); */ emu->p16v_device_offset = device; if (rpcm) *rpcm = NULL; if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0) return err; pcm->private_data = emu; // Single playback 8 channel device. // Single capture 2 channel device. snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops); pcm->info_flags = 0; pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; strcpy(pcm->name, "p16v"); emu->pcm_p16v = pcm; for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next) { if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), ((65536 - 64) * 8), ((65536 - 64) * 8))) < 0) return err; /* snd_printk(KERN_DEBUG "preallocate playback substream: err=%d\n", err); */ } for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; substream; substream = substream->next) { if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 65536 - 64, 65536 - 64)) < 0) return err; /* snd_printk(KERN_DEBUG "preallocate capture substream: err=%d\n", err); */ } if (rpcm) *rpcm = pcm; return 0; }
/** * snd_pcm_lib_preallocate_pages_for_all - pre-allocation for continuous memory type (all substreams) * @pcm: the pcm instance * @type: DMA type (SNDRV_DMA_TYPE_*) * @data: DMA type dependent data * @size: the requested pre-allocation size in bytes * @max: the max. allowed pre-allocation size * * Do pre-allocation to all substreams of the given pcm for the * specified DMA type. * * Return: Zero if successful, or a negative error code on failure. */ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm, int type, void *data, size_t size, size_t max) { struct snd_pcm_substream *substream; int stream, err; for (stream = 0; stream < 2; stream++) for (substream = pcm->streams[stream].substream; substream; substream = substream->next) if ((err = snd_pcm_lib_preallocate_pages(substream, type, data, size, max)) < 0) return err; return 0; }
int oxygen_pcm_init(struct oxygen *chip) { struct snd_pcm *pcm; int outs, ins; int err; outs = !!(chip->model.device_config & PLAYBACK_0_TO_I2S); ins = !!(chip->model.device_config & (CAPTURE_0_FROM_I2S_1 | CAPTURE_0_FROM_I2S_2)); if (outs | ins) { err = snd_pcm_new(chip->card, "Multichannel", 0, outs, ins, &pcm); if (err < 0) return err; if (outs) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_multich_ops); if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_a_ops); else if (chip->model.device_config & CAPTURE_0_FROM_I2S_2) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_b_ops); pcm->private_data = chip; pcm->private_free = oxygen_pcm_free; strcpy(pcm->name, "Multichannel"); if (outs) snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), DEFAULT_BUFFER_BYTES_MULTICH, BUFFER_BYTES_MAX_MULTICH); if (ins) snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), DEFAULT_BUFFER_BYTES, BUFFER_BYTES_MAX); } outs = !!(chip->model.device_config & PLAYBACK_1_TO_SPDIF); ins = !!(chip->model.device_config & CAPTURE_1_FROM_SPDIF); if (outs | ins) { err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm); if (err < 0) return err; if (outs) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_spdif_ops); if (ins) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_c_ops); pcm->private_data = chip; pcm->private_free = oxygen_pcm_free; strcpy(pcm->name, "Digital"); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), DEFAULT_BUFFER_BYTES, BUFFER_BYTES_MAX); } if (chip->has_ac97_1) { outs = !!(chip->model.device_config & PLAYBACK_2_TO_AC97_1); ins = !!(chip->model.device_config & CAPTURE_2_FROM_AC97_1); } else { outs = 0; ins = !!(chip->model.device_config & CAPTURE_2_FROM_I2S_2); } if (outs | ins) { err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2", 2, outs, ins, &pcm); if (err < 0) return err; if (outs) { snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_ac97_ops); oxygen_write8_masked(chip, OXYGEN_REC_ROUTING, OXYGEN_REC_B_ROUTE_AC97_1, OXYGEN_REC_B_ROUTE_MASK); } if (ins) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_b_ops); pcm->private_data = chip; pcm->private_free = oxygen_pcm_free; strcpy(pcm->name, outs ? "Front Panel" : "Analog 2"); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), DEFAULT_BUFFER_BYTES, BUFFER_BYTES_MAX); } return 0; }
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++ * * Function Name: PcmDeviceNew * * Description: Create PCM playback and capture device * *------------------------------------------------------------ */ int __devinit PcmDeviceNew(struct snd_card *card) { struct snd_pcm *pcm; int err = 0; brcm_alsa_chip_t *pChip; struct snd_pcm_substream *substream; callMode = CALL_MODE_NONE; err = snd_pcm_new(card, "Broadcom CAPH", 0, NUM_PLAYBACK_SUBDEVICE, NUM_CAPTURE_SUBDEVICE, &pcm); if (err < 0) return err; pcm->private_data = card->private_data; strcpy(pcm->name, "Broadcom CAPH PCM"); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &brcm_alsa_omx_pcm_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &brcm_alsa_omx_pcm_capture_ops); pcm->info_flags = 0; /*pre-allocate memory for playback device */ substream = pcm->streams[0].substream; for (; substream; substream = substream->next) { err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, 0, (IS_PCM_MEM_PREALLOCATED) ? PCM_MAX_PLAYBACK_BUF_BYTES : 0, PCM_MAX_PLAYBACK_BUF_BYTES); if (err) aError ("\n Error : Error when allocate memory for" " playback device err=%d\n", err); } /*pre-allocate memory for capture device */ substream = pcm->streams[1].substream; for (; substream; substream = substream->next) { err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV, 0, (IS_PCM_MEM_PREALLOCATED) ? PCM_MAX_CAPTURE_BUF_BYTES : 0, PCM_MAX_CAPTURE_BUF_BYTES); if (err) aError ("\n Error : Error when allocate memory for" " capture device err=%d\n", err); } pChip = (brcm_alsa_chip_t *) card->private_data; /* Initialize the audio controller */ aTrace(LOG_ALSA_INTERFACE, "ALSA-CAPH PcmDeviceNew:call AUDIO_Init\n"); caph_audio_init(); #if defined(CONFIG_BCM_MODEM) DSPDRV_Init(); #endif AUDCTRL_Init(); #if defined(DYNAMIC_DMA_PLAYBACK) spin_lock_init(©_lock); #endif aTrace(LOG_ALSA_INTERFACE, "\n PcmDeviceNew : PcmDeviceNew err=%d\n", err); return err; }