/* hw_params callback */ static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { int err; struct snd_pcm_runtime *runtime = substream->runtime; bcm2835_alsa_stream_t *alsa_stream = (bcm2835_alsa_stream_t *) runtime->private_data; audio_info(" .. IN\n"); err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); if (err < 0) { audio_error (" pcm_lib_malloc failed to allocated pages for buffers\n"); return err; } err = bcm2835_audio_set_params(alsa_stream, params_channels(params), params_rate(params), snd_pcm_format_width(params_format (params))); if (err < 0) { audio_error(" error setting hw params\n"); } bcm2835_audio_setup(alsa_stream); audio_info(" .. OUT\n"); return err; }
/* prepare callback */ static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) { struct bcm2835_chip *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; int channels; int err; audio_info(" .. IN\n"); if (mutex_lock_interruptible(&chip->audio_mutex)) return -EINTR; /* notify the vchiq that it should enter spdif passthrough mode by * setting channels=0 (see * https://github.com/raspberrypi/linux/issues/528) */ if (chip->spdif_status & IEC958_AES0_NONAUDIO) channels = 0; else channels = alsa_stream->channels; err = bcm2835_audio_set_params(alsa_stream, channels, alsa_stream->params_rate, alsa_stream->pcm_format_width); if (err < 0) { audio_error(" error setting hw params\n"); } bcm2835_audio_setup(alsa_stream); /* in preparation of the stream, set the controls (volume level) of the stream */ bcm2835_audio_set_ctls(alsa_stream->chip); memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); alsa_stream->pcm_indirect.hw_buffer_size = alsa_stream->pcm_indirect.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); alsa_stream->pos = 0; audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", alsa_stream->buffer_size, alsa_stream->period_size, alsa_stream->pos, runtime->frame_bits); mutex_unlock(&chip->audio_mutex); audio_info(" .. OUT\n"); return 0; }