linux/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
<<
>>
Prefs
   1/*****************************************************************************
   2 * Copyright 2011 Broadcom Corporation.  All rights reserved.
   3 *
   4 * Unless you and Broadcom execute a separate written software license
   5 * agreement governing use of this software, this software is licensed to you
   6 * under the terms of the GNU General Public License version 2, available at
   7 * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
   8 *
   9 * Notwithstanding the above, under no circumstances may you combine this
  10 * software in any way with any other Broadcom software provided under a
  11 * license other than the GPL, without Broadcom's express prior written
  12 * consent.
  13 *****************************************************************************/
  14
  15#include <linux/interrupt.h>
  16#include <linux/slab.h>
  17
  18#include <sound/asoundef.h>
  19
  20#include "bcm2835.h"
  21
  22/* hardware definition */
  23static const struct snd_pcm_hardware snd_bcm2835_playback_hw = {
  24        .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
  25        SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
  26        .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
  27        .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
  28        .rate_min = 8000,
  29        .rate_max = 48000,
  30        .channels_min = 1,
  31        .channels_max = 2,
  32        .buffer_bytes_max = 128 * 1024,
  33        .period_bytes_min = 1 * 1024,
  34        .period_bytes_max = 128 * 1024,
  35        .periods_min = 1,
  36        .periods_max = 128,
  37};
  38
  39static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = {
  40        .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
  41        SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
  42        .formats = SNDRV_PCM_FMTBIT_S16_LE,
  43        .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 |
  44        SNDRV_PCM_RATE_48000,
  45        .rate_min = 44100,
  46        .rate_max = 48000,
  47        .channels_min = 2,
  48        .channels_max = 2,
  49        .buffer_bytes_max = 128 * 1024,
  50        .period_bytes_min = 1 * 1024,
  51        .period_bytes_max = 128 * 1024,
  52        .periods_min = 1,
  53        .periods_max = 128,
  54};
  55
  56static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime)
  57{
  58        audio_info("Freeing up alsa stream here ..\n");
  59        kfree(runtime->private_data);
  60        runtime->private_data = NULL;
  61}
  62
  63void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream)
  64{
  65        unsigned int consumed = 0;
  66        int new_period = 0;
  67
  68
  69        audio_info("alsa_stream=%p substream=%p\n", alsa_stream,
  70                alsa_stream ? alsa_stream->substream : 0);
  71
  72        if (alsa_stream->open)
  73                consumed = bcm2835_audio_retrieve_buffers(alsa_stream);
  74
  75        /* We get called only if playback was triggered, So, the number of buffers we retrieve in
  76         * each iteration are the buffers that have been played out already
  77         */
  78
  79        if (alsa_stream->period_size) {
  80                if ((alsa_stream->pos / alsa_stream->period_size) !=
  81                        ((alsa_stream->pos + consumed) / alsa_stream->period_size))
  82                        new_period = 1;
  83        }
  84        audio_debug("updating pos cur: %d + %d max:%d period_bytes:%d, hw_ptr: %d new_period:%d\n",
  85                alsa_stream->pos,
  86                consumed,
  87                alsa_stream->buffer_size,
  88                (int) (alsa_stream->period_size * alsa_stream->substream->runtime->periods),
  89                frames_to_bytes(alsa_stream->substream->runtime, alsa_stream->substream->runtime->status->hw_ptr),
  90                new_period);
  91        if (alsa_stream->buffer_size) {
  92                alsa_stream->pos += consumed & ~(1 << 30);
  93                alsa_stream->pos %= alsa_stream->buffer_size;
  94        }
  95
  96        if (alsa_stream->substream) {
  97                if (new_period)
  98                        snd_pcm_period_elapsed(alsa_stream->substream);
  99        } else {
 100                audio_warning(" unexpected NULL substream\n");
 101        }
 102}
 103
 104/* open callback */
 105static int snd_bcm2835_playback_open_generic(
 106        struct snd_pcm_substream *substream, int spdif)
 107{
 108        struct bcm2835_chip *chip = snd_pcm_substream_chip(substream);
 109        struct snd_pcm_runtime *runtime = substream->runtime;
 110        struct bcm2835_alsa_stream *alsa_stream;
 111        int idx;
 112        int err;
 113
 114
 115        if (mutex_lock_interruptible(&chip->audio_mutex)) {
 116                audio_error("Interrupted whilst waiting for lock\n");
 117                return -EINTR;
 118        }
 119        audio_info("Alsa open (%d)\n", substream->number);
 120        idx = substream->number;
 121
 122        if (spdif && chip->opened) {
 123                err = -EBUSY;
 124                goto out;
 125        } else if (!spdif && (chip->opened & (1 << idx))) {
 126                err = -EBUSY;
 127                goto out;
 128        }
 129        if (idx >= MAX_SUBSTREAMS) {
 130                audio_error
 131                        ("substream(%d) device doesn't exist max(%d) substreams allowed\n",
 132                        idx, MAX_SUBSTREAMS);
 133                err = -ENODEV;
 134                goto out;
 135        }
 136
 137        /* Check if we are ready */
 138        if (!(chip->avail_substreams & (1 << idx))) {
 139                /* We are not ready yet */
 140                audio_error("substream(%d) device is not ready yet\n", idx);
 141                err = -EAGAIN;
 142                goto out;
 143        }
 144
 145        alsa_stream = kzalloc(sizeof(*alsa_stream), GFP_KERNEL);
 146        if (!alsa_stream) {
 147                err = -ENOMEM;
 148                goto out;
 149        }
 150
 151        /* Initialise alsa_stream */
 152        alsa_stream->chip = chip;
 153        alsa_stream->substream = substream;
 154        alsa_stream->idx = idx;
 155
 156        spin_lock_init(&alsa_stream->lock);
 157
 158        err = bcm2835_audio_open(alsa_stream);
 159        if (err) {
 160                kfree(alsa_stream);
 161                goto out;
 162        }
 163        runtime->private_data = alsa_stream;
 164        runtime->private_free = snd_bcm2835_playback_free;
 165        if (spdif) {
 166                runtime->hw = snd_bcm2835_playback_spdif_hw;
 167        } else {
 168                /* clear spdif status, as we are not in spdif mode */
 169                chip->spdif_status = 0;
 170                runtime->hw = snd_bcm2835_playback_hw;
 171        }
 172        /* minimum 16 bytes alignment (for vchiq bulk transfers) */
 173        snd_pcm_hw_constraint_step(runtime,
 174                                   0,
 175                                   SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
 176                                   16);
 177
 178        chip->alsa_stream[idx] = alsa_stream;
 179
 180        chip->opened |= (1 << idx);
 181        alsa_stream->open = 1;
 182        alsa_stream->draining = 1;
 183
 184out:
 185        mutex_unlock(&chip->audio_mutex);
 186
 187
 188        return err;
 189}
 190
 191static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream)
 192{
 193        return snd_bcm2835_playback_open_generic(substream, 0);
 194}
 195
 196static int snd_bcm2835_playback_spdif_open(struct snd_pcm_substream *substream)
 197{
 198        return snd_bcm2835_playback_open_generic(substream, 1);
 199}
 200
 201/* close callback */
 202static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream)
 203{
 204        /* the hardware-specific codes will be here */
 205
 206        struct bcm2835_chip *chip;
 207        struct snd_pcm_runtime *runtime;
 208        struct bcm2835_alsa_stream *alsa_stream;
 209
 210
 211        chip = snd_pcm_substream_chip(substream);
 212        if (mutex_lock_interruptible(&chip->audio_mutex)) {
 213                audio_error("Interrupted whilst waiting for lock\n");
 214                return -EINTR;
 215        }
 216        runtime = substream->runtime;
 217        alsa_stream = runtime->private_data;
 218
 219        audio_info("Alsa close\n");
 220
 221        /*
 222         * Call stop if it's still running. This happens when app
 223         * is force killed and we don't get a stop trigger.
 224         */
 225        if (alsa_stream->running) {
 226                int err;
 227                err = bcm2835_audio_stop(alsa_stream);
 228                alsa_stream->running = 0;
 229                if (err)
 230                        audio_error(" Failed to STOP alsa device\n");
 231        }
 232
 233        alsa_stream->period_size = 0;
 234        alsa_stream->buffer_size = 0;
 235
 236        if (alsa_stream->open) {
 237                alsa_stream->open = 0;
 238                bcm2835_audio_close(alsa_stream);
 239        }
 240        if (alsa_stream->chip)
 241                alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL;
 242        /*
 243         * Do not free up alsa_stream here, it will be freed up by
 244         * runtime->private_free callback we registered in *_open above
 245         */
 246
 247        chip->opened &= ~(1 << substream->number);
 248
 249        mutex_unlock(&chip->audio_mutex);
 250
 251        return 0;
 252}
 253
 254/* hw_params callback */
 255static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream,
 256        struct snd_pcm_hw_params *params)
 257{
 258        struct snd_pcm_runtime *runtime = substream->runtime;
 259        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
 260        int err;
 261
 262
 263        err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
 264        if (err < 0) {
 265                audio_error
 266                        (" pcm_lib_malloc failed to allocated pages for buffers\n");
 267                return err;
 268        }
 269
 270        alsa_stream->channels = params_channels(params);
 271        alsa_stream->params_rate = params_rate(params);
 272        alsa_stream->pcm_format_width = snd_pcm_format_width(params_format(params));
 273
 274        return err;
 275}
 276
 277/* hw_free callback */
 278static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream)
 279{
 280        return snd_pcm_lib_free_pages(substream);
 281}
 282
 283/* prepare callback */
 284static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
 285{
 286        struct bcm2835_chip *chip = snd_pcm_substream_chip(substream);
 287        struct snd_pcm_runtime *runtime = substream->runtime;
 288        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
 289        int channels;
 290        int err;
 291
 292
 293        if (mutex_lock_interruptible(&chip->audio_mutex))
 294                return -EINTR;
 295
 296        /* notify the vchiq that it should enter spdif passthrough mode by
 297         * setting channels=0 (see
 298         * https://github.com/raspberrypi/linux/issues/528) */
 299        if (chip->spdif_status & IEC958_AES0_NONAUDIO)
 300                channels = 0;
 301        else
 302                channels = alsa_stream->channels;
 303
 304        err = bcm2835_audio_set_params(alsa_stream, channels,
 305                alsa_stream->params_rate,
 306                alsa_stream->pcm_format_width);
 307        if (err < 0)
 308                audio_error(" error setting hw params\n");
 309
 310
 311        bcm2835_audio_setup(alsa_stream);
 312
 313        /* in preparation of the stream, set the controls (volume level) of the stream */
 314        bcm2835_audio_set_ctls(alsa_stream->chip);
 315
 316
 317        memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect));
 318
 319        alsa_stream->pcm_indirect.hw_buffer_size =
 320                alsa_stream->pcm_indirect.sw_buffer_size =
 321                snd_pcm_lib_buffer_bytes(substream);
 322
 323        alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream);
 324        alsa_stream->period_size = snd_pcm_lib_period_bytes(substream);
 325        alsa_stream->pos = 0;
 326
 327        audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n",
 328                alsa_stream->buffer_size, alsa_stream->period_size,
 329                alsa_stream->pos, runtime->frame_bits);
 330
 331        mutex_unlock(&chip->audio_mutex);
 332        return 0;
 333}
 334
 335static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream,
 336        struct snd_pcm_indirect *rec, size_t bytes)
 337{
 338        struct snd_pcm_runtime *runtime = substream->runtime;
 339        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
 340        void *src = (void *) (substream->runtime->dma_area + rec->sw_data);
 341        int err;
 342
 343        err = bcm2835_audio_write(alsa_stream, bytes, src);
 344        if (err)
 345                audio_error(" Failed to transfer to alsa device (%d)\n", err);
 346
 347}
 348
 349static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream)
 350{
 351        struct snd_pcm_runtime *runtime = substream->runtime;
 352        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
 353        struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect;
 354
 355        pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max;
 356        return snd_pcm_indirect_playback_transfer(substream, pcm_indirect,
 357                                                  snd_bcm2835_pcm_transfer);
 358}
 359
 360/* trigger callback */
 361static int snd_bcm2835_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 362{
 363        struct snd_pcm_runtime *runtime = substream->runtime;
 364        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
 365        int err = 0;
 366
 367
 368        switch (cmd) {
 369        case SNDRV_PCM_TRIGGER_START:
 370                audio_debug("bcm2835_AUDIO_TRIGGER_START running=%d\n",
 371                        alsa_stream->running);
 372                if (!alsa_stream->running) {
 373                        err = bcm2835_audio_start(alsa_stream);
 374                        if (!err) {
 375                                alsa_stream->pcm_indirect.hw_io =
 376                                        alsa_stream->pcm_indirect.hw_data =
 377                                        bytes_to_frames(runtime,
 378                                        alsa_stream->pos);
 379                                substream->ops->ack(substream);
 380                                alsa_stream->running = 1;
 381                                alsa_stream->draining = 1;
 382                        } else {
 383                                audio_error(" Failed to START alsa device (%d)\n", err);
 384                        }
 385                }
 386                break;
 387        case SNDRV_PCM_TRIGGER_STOP:
 388                audio_debug
 389                        ("bcm2835_AUDIO_TRIGGER_STOP running=%d draining=%d\n",
 390                        alsa_stream->running, runtime->status->state == SNDRV_PCM_STATE_DRAINING);
 391                if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
 392                        audio_info("DRAINING\n");
 393                        alsa_stream->draining = 1;
 394                } else {
 395                        audio_info("DROPPING\n");
 396                        alsa_stream->draining = 0;
 397                }
 398                if (alsa_stream->running) {
 399                        err = bcm2835_audio_stop(alsa_stream);
 400                        if (err != 0)
 401                                audio_error(" Failed to STOP alsa device (%d)\n", err);
 402                        alsa_stream->running = 0;
 403                }
 404                break;
 405        default:
 406                err = -EINVAL;
 407        }
 408
 409        return err;
 410}
 411
 412/* pointer callback */
 413static snd_pcm_uframes_t
 414snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream)
 415{
 416        struct snd_pcm_runtime *runtime = substream->runtime;
 417        struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
 418
 419
 420        audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0,
 421                frames_to_bytes(runtime, runtime->status->hw_ptr),
 422                frames_to_bytes(runtime, runtime->control->appl_ptr),
 423                alsa_stream->pos);
 424
 425        return snd_pcm_indirect_playback_pointer(substream,
 426                &alsa_stream->pcm_indirect,
 427                alsa_stream->pos);
 428}
 429
 430static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream,
 431        unsigned int cmd, void *arg)
 432{
 433        int ret = snd_pcm_lib_ioctl(substream, cmd, arg);
 434
 435        audio_info(" .. substream=%p, cmd=%d, arg=%p (%x) ret=%d\n", substream,
 436                cmd, arg, arg ? *(unsigned *) arg : 0, ret);
 437        return ret;
 438}
 439
 440/* operators */
 441static const struct snd_pcm_ops snd_bcm2835_playback_ops = {
 442        .open = snd_bcm2835_playback_open,
 443        .close = snd_bcm2835_playback_close,
 444        .ioctl = snd_bcm2835_pcm_lib_ioctl,
 445        .hw_params = snd_bcm2835_pcm_hw_params,
 446        .hw_free = snd_bcm2835_pcm_hw_free,
 447        .prepare = snd_bcm2835_pcm_prepare,
 448        .trigger = snd_bcm2835_pcm_trigger,
 449        .pointer = snd_bcm2835_pcm_pointer,
 450        .ack = snd_bcm2835_pcm_ack,
 451};
 452
 453static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
 454        .open = snd_bcm2835_playback_spdif_open,
 455        .close = snd_bcm2835_playback_close,
 456        .ioctl = snd_bcm2835_pcm_lib_ioctl,
 457        .hw_params = snd_bcm2835_pcm_hw_params,
 458        .hw_free = snd_bcm2835_pcm_hw_free,
 459        .prepare = snd_bcm2835_pcm_prepare,
 460        .trigger = snd_bcm2835_pcm_trigger,
 461        .pointer = snd_bcm2835_pcm_pointer,
 462        .ack = snd_bcm2835_pcm_ack,
 463};
 464
 465/* create a pcm device */
 466int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, u32 numchannels)
 467{
 468        struct snd_pcm *pcm;
 469        int err;
 470
 471        mutex_init(&chip->audio_mutex);
 472        if (mutex_lock_interruptible(&chip->audio_mutex)) {
 473                audio_error("Interrupted whilst waiting for lock\n");
 474                return -EINTR;
 475        }
 476        err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, numchannels, 0, &pcm);
 477        if (err < 0)
 478                goto out;
 479        pcm->private_data = chip;
 480        strcpy(pcm->name, "bcm2835 ALSA");
 481        chip->pcm = pcm;
 482        chip->dest = AUDIO_DEST_AUTO;
 483        chip->volume = alsa2chip(0);
 484        chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */
 485        /* set operators */
 486        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
 487                        &snd_bcm2835_playback_ops);
 488
 489        /* pre-allocation of buffers */
 490        /* NOTE: this may fail */
 491        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
 492                                              snd_dma_continuous_data(GFP_KERNEL),
 493                                              snd_bcm2835_playback_hw.buffer_bytes_max,
 494                                              snd_bcm2835_playback_hw.buffer_bytes_max);
 495
 496
 497out:
 498        mutex_unlock(&chip->audio_mutex);
 499
 500        return 0;
 501}
 502
 503int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip)
 504{
 505        struct snd_pcm *pcm;
 506        int err;
 507
 508        if (mutex_lock_interruptible(&chip->audio_mutex)) {
 509                audio_error("Interrupted whilst waiting for lock\n");
 510                return -EINTR;
 511        }
 512        err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm);
 513        if (err < 0)
 514                goto out;
 515
 516        pcm->private_data = chip;
 517        strcpy(pcm->name, "bcm2835 IEC958/HDMI");
 518        chip->pcm_spdif = pcm;
 519        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
 520                        &snd_bcm2835_playback_spdif_ops);
 521
 522        /* pre-allocation of buffers */
 523        /* NOTE: this may fail */
 524        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
 525                snd_dma_continuous_data(GFP_KERNEL),
 526                snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max);
 527out:
 528        mutex_unlock(&chip->audio_mutex);
 529
 530        return 0;
 531}
 532
 533int snd_bcm2835_new_simple_pcm(struct bcm2835_chip *chip,
 534                               const char *name,
 535                               enum snd_bcm2835_route route,
 536                               u32 numchannels)
 537{
 538        struct snd_pcm *pcm;
 539        int err;
 540
 541        mutex_init(&chip->audio_mutex);
 542
 543        err = snd_pcm_new(chip->card, name, 0, numchannels,
 544                          0, &pcm);
 545        if (err)
 546                return err;
 547
 548        pcm->private_data = chip;
 549        strcpy(pcm->name, name);
 550        chip->pcm = pcm;
 551        chip->dest = route;
 552        chip->volume = alsa2chip(0);
 553        chip->mute = CTRL_VOL_UNMUTE;
 554
 555        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
 556                        &snd_bcm2835_playback_ops);
 557
 558        snd_pcm_lib_preallocate_pages_for_all(
 559                pcm,
 560                SNDRV_DMA_TYPE_CONTINUOUS,
 561                snd_dma_continuous_data(GFP_KERNEL),
 562                snd_bcm2835_playback_hw.buffer_bytes_max,
 563                snd_bcm2835_playback_hw.buffer_bytes_max);
 564
 565        return 0;
 566}
 567
 568