1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright 2011 Broadcom Corporation. All rights reserved. */
4 #include <linux/interrupt.h>
5 #include <linux/slab.h>
7 #include <sound/asoundef.h>
11 /* hardware definition */
12 static const struct snd_pcm_hardware snd_bcm2835_playback_hw = {
13 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
14 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
15 .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
16 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
21 .buffer_bytes_max = 128 * 1024,
22 .period_bytes_min = 1 * 1024,
23 .period_bytes_max = 128 * 1024,
28 static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = {
29 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
30 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
31 .formats = SNDRV_PCM_FMTBIT_S16_LE,
32 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 |
38 .buffer_bytes_max = 128 * 1024,
39 .period_bytes_min = 1 * 1024,
40 .period_bytes_max = 128 * 1024,
45 static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime)
47 audio_info("Freeing up alsa stream here ..\n");
48 kfree(runtime->private_data);
49 runtime->private_data = NULL;
52 void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream)
54 unsigned int consumed = 0;
57 audio_info("alsa_stream=%p substream=%p\n", alsa_stream,
58 alsa_stream ? alsa_stream->substream : 0);
60 consumed = bcm2835_audio_retrieve_buffers(alsa_stream);
62 /* We get called only if playback was triggered, So, the number of buffers we retrieve in
63 * each iteration are the buffers that have been played out already
66 if (alsa_stream->period_size) {
67 if ((alsa_stream->pos / alsa_stream->period_size) !=
68 ((alsa_stream->pos + consumed) / alsa_stream->period_size))
71 audio_debug("updating pos cur: %d + %d max:%d period_bytes:%d, hw_ptr: %d new_period:%d\n",
74 alsa_stream->buffer_size,
75 (int) (alsa_stream->period_size * alsa_stream->substream->runtime->periods),
76 frames_to_bytes(alsa_stream->substream->runtime, alsa_stream->substream->runtime->status->hw_ptr),
78 if (alsa_stream->buffer_size) {
79 alsa_stream->pos += consumed & ~(1 << 30);
80 alsa_stream->pos %= alsa_stream->buffer_size;
83 if (alsa_stream->substream) {
85 snd_pcm_period_elapsed(alsa_stream->substream);
87 audio_warning(" unexpected NULL substream\n");
92 static int snd_bcm2835_playback_open_generic(
93 struct snd_pcm_substream *substream, int spdif)
95 struct bcm2835_chip *chip = snd_pcm_substream_chip(substream);
96 struct snd_pcm_runtime *runtime = substream->runtime;
97 struct bcm2835_alsa_stream *alsa_stream;
101 mutex_lock(&chip->audio_mutex);
102 audio_info("Alsa open (%d)\n", substream->number);
103 idx = substream->number;
105 if (spdif && chip->opened) {
108 } else if (!spdif && (chip->opened & (1 << idx))) {
112 if (idx >= MAX_SUBSTREAMS) {
114 ("substream(%d) device doesn't exist max(%d) substreams allowed\n",
115 idx, MAX_SUBSTREAMS);
120 alsa_stream = kzalloc(sizeof(*alsa_stream), GFP_KERNEL);
126 /* Initialise alsa_stream */
127 alsa_stream->chip = chip;
128 alsa_stream->substream = substream;
129 alsa_stream->idx = idx;
131 spin_lock_init(&alsa_stream->lock);
133 err = bcm2835_audio_open(alsa_stream);
138 runtime->private_data = alsa_stream;
139 runtime->private_free = snd_bcm2835_playback_free;
141 runtime->hw = snd_bcm2835_playback_spdif_hw;
143 /* clear spdif status, as we are not in spdif mode */
144 chip->spdif_status = 0;
145 runtime->hw = snd_bcm2835_playback_hw;
147 /* minimum 16 bytes alignment (for vchiq bulk transfers) */
148 snd_pcm_hw_constraint_step(runtime,
150 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
153 chip->alsa_stream[idx] = alsa_stream;
155 chip->opened |= (1 << idx);
156 alsa_stream->draining = 1;
159 mutex_unlock(&chip->audio_mutex);
164 static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream)
166 return snd_bcm2835_playback_open_generic(substream, 0);
169 static int snd_bcm2835_playback_spdif_open(struct snd_pcm_substream *substream)
171 return snd_bcm2835_playback_open_generic(substream, 1);
175 static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream)
177 /* the hardware-specific codes will be here */
179 struct bcm2835_chip *chip;
180 struct snd_pcm_runtime *runtime;
181 struct bcm2835_alsa_stream *alsa_stream;
183 chip = snd_pcm_substream_chip(substream);
184 mutex_lock(&chip->audio_mutex);
185 runtime = substream->runtime;
186 alsa_stream = runtime->private_data;
188 audio_info("Alsa close\n");
190 alsa_stream->period_size = 0;
191 alsa_stream->buffer_size = 0;
193 bcm2835_audio_close(alsa_stream);
194 if (alsa_stream->chip)
195 alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL;
197 * Do not free up alsa_stream here, it will be freed up by
198 * runtime->private_free callback we registered in *_open above
201 chip->opened &= ~(1 << substream->number);
203 mutex_unlock(&chip->audio_mutex);
208 /* hw_params callback */
209 static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream,
210 struct snd_pcm_hw_params *params)
212 struct snd_pcm_runtime *runtime = substream->runtime;
213 struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
216 err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
219 (" pcm_lib_malloc failed to allocated pages for buffers\n");
223 alsa_stream->channels = params_channels(params);
224 alsa_stream->params_rate = params_rate(params);
225 alsa_stream->pcm_format_width = snd_pcm_format_width(params_format(params));
230 /* hw_free callback */
231 static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream)
233 return snd_pcm_lib_free_pages(substream);
236 /* prepare callback */
237 static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
239 struct bcm2835_chip *chip = snd_pcm_substream_chip(substream);
240 struct snd_pcm_runtime *runtime = substream->runtime;
241 struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
245 mutex_lock(&chip->audio_mutex);
247 /* notify the vchiq that it should enter spdif passthrough mode by
248 * setting channels=0 (see
249 * https://github.com/raspberrypi/linux/issues/528)
251 if (chip->spdif_status & IEC958_AES0_NONAUDIO)
254 channels = alsa_stream->channels;
256 err = bcm2835_audio_set_params(alsa_stream, channels,
257 alsa_stream->params_rate,
258 alsa_stream->pcm_format_width);
260 audio_error(" error setting hw params\n");
262 memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect));
264 alsa_stream->pcm_indirect.hw_buffer_size =
265 alsa_stream->pcm_indirect.sw_buffer_size =
266 snd_pcm_lib_buffer_bytes(substream);
268 alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream);
269 alsa_stream->period_size = snd_pcm_lib_period_bytes(substream);
270 alsa_stream->pos = 0;
272 audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n",
273 alsa_stream->buffer_size, alsa_stream->period_size,
274 alsa_stream->pos, runtime->frame_bits);
276 mutex_unlock(&chip->audio_mutex);
280 static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream,
281 struct snd_pcm_indirect *rec, size_t bytes)
283 struct snd_pcm_runtime *runtime = substream->runtime;
284 struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
285 void *src = (void *) (substream->runtime->dma_area + rec->sw_data);
288 err = bcm2835_audio_write(alsa_stream, bytes, src);
290 audio_error(" Failed to transfer to alsa device (%d)\n", err);
294 static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream)
296 struct snd_pcm_runtime *runtime = substream->runtime;
297 struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
298 struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect;
300 pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max;
301 return snd_pcm_indirect_playback_transfer(substream, pcm_indirect,
302 snd_bcm2835_pcm_transfer);
305 /* trigger callback */
306 static int snd_bcm2835_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
308 struct snd_pcm_runtime *runtime = substream->runtime;
309 struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
313 case SNDRV_PCM_TRIGGER_START:
314 err = bcm2835_audio_start(alsa_stream);
316 alsa_stream->draining = 1;
318 audio_error(" Failed to START alsa device (%d)\n", err);
320 case SNDRV_PCM_TRIGGER_STOP:
321 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
322 audio_info("DRAINING\n");
323 alsa_stream->draining = 1;
325 audio_info("DROPPING\n");
326 alsa_stream->draining = 0;
328 err = bcm2835_audio_stop(alsa_stream);
330 audio_error(" Failed to STOP alsa device (%d)\n", err);
339 /* pointer callback */
340 static snd_pcm_uframes_t
341 snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream)
343 struct snd_pcm_runtime *runtime = substream->runtime;
344 struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
346 audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0,
347 frames_to_bytes(runtime, runtime->status->hw_ptr),
348 frames_to_bytes(runtime, runtime->control->appl_ptr),
351 return snd_pcm_indirect_playback_pointer(substream,
352 &alsa_stream->pcm_indirect,
356 static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream,
357 unsigned int cmd, void *arg)
359 int ret = snd_pcm_lib_ioctl(substream, cmd, arg);
361 audio_info(" .. substream=%p, cmd=%d, arg=%p (%x) ret=%d\n", substream,
362 cmd, arg, arg ? *(unsigned int *)arg : 0, ret);
367 static const struct snd_pcm_ops snd_bcm2835_playback_ops = {
368 .open = snd_bcm2835_playback_open,
369 .close = snd_bcm2835_playback_close,
370 .ioctl = snd_bcm2835_pcm_lib_ioctl,
371 .hw_params = snd_bcm2835_pcm_hw_params,
372 .hw_free = snd_bcm2835_pcm_hw_free,
373 .prepare = snd_bcm2835_pcm_prepare,
374 .trigger = snd_bcm2835_pcm_trigger,
375 .pointer = snd_bcm2835_pcm_pointer,
376 .ack = snd_bcm2835_pcm_ack,
379 static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
380 .open = snd_bcm2835_playback_spdif_open,
381 .close = snd_bcm2835_playback_close,
382 .ioctl = snd_bcm2835_pcm_lib_ioctl,
383 .hw_params = snd_bcm2835_pcm_hw_params,
384 .hw_free = snd_bcm2835_pcm_hw_free,
385 .prepare = snd_bcm2835_pcm_prepare,
386 .trigger = snd_bcm2835_pcm_trigger,
387 .pointer = snd_bcm2835_pcm_pointer,
388 .ack = snd_bcm2835_pcm_ack,
391 /* create a pcm device */
392 int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, u32 numchannels)
397 err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, numchannels, 0, &pcm);
400 pcm->private_data = chip;
401 strcpy(pcm->name, "bcm2835 ALSA");
403 chip->dest = AUDIO_DEST_AUTO;
405 chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */
407 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
408 &snd_bcm2835_playback_ops);
410 /* pre-allocation of buffers */
411 /* NOTE: this may fail */
412 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
413 snd_dma_continuous_data(GFP_KERNEL),
414 snd_bcm2835_playback_hw.buffer_bytes_max,
415 snd_bcm2835_playback_hw.buffer_bytes_max);
420 int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip)
425 err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm);
429 pcm->private_data = chip;
430 strcpy(pcm->name, "bcm2835 IEC958/HDMI");
431 chip->pcm_spdif = pcm;
432 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
433 &snd_bcm2835_playback_spdif_ops);
435 /* pre-allocation of buffers */
436 /* NOTE: this may fail */
437 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
438 snd_dma_continuous_data(GFP_KERNEL),
439 snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max);
444 int snd_bcm2835_new_simple_pcm(struct bcm2835_chip *chip,
446 enum snd_bcm2835_route route,
452 err = snd_pcm_new(chip->card, name, 0, numchannels,
457 pcm->private_data = chip;
458 strcpy(pcm->name, name);
462 chip->mute = CTRL_VOL_UNMUTE;
464 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
465 &snd_bcm2835_playback_ops);
467 snd_pcm_lib_preallocate_pages_for_all(
469 SNDRV_DMA_TYPE_CONTINUOUS,
470 snd_dma_continuous_data(GFP_KERNEL),
471 snd_bcm2835_playback_hw.buffer_bytes_max,
472 snd_bcm2835_playback_hw.buffer_bytes_max);