linux/sound/arm/pxa2xx-pcm.c
<<
>>
Prefs
   1/*
   2 * linux/sound/arm/pxa2xx-pcm.c -- ALSA PCM interface for the Intel PXA2xx chip
   3 *
   4 * Author:      Nicolas Pitre
   5 * Created:     Nov 30, 2004
   6 * Copyright:   (C) 2004 MontaVista Software, Inc.
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/dma-mapping.h>
  15#include <linux/dmaengine.h>
  16
  17#include <mach/dma.h>
  18
  19#include <sound/core.h>
  20#include <sound/pxa2xx-lib.h>
  21#include <sound/dmaengine_pcm.h>
  22
  23#include "pxa2xx-pcm.h"
  24
  25static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
  26{
  27        struct pxa2xx_pcm_client *client = substream->private_data;
  28
  29        __pxa2xx_pcm_prepare(substream);
  30
  31        return client->prepare(substream);
  32}
  33
  34static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
  35{
  36        struct pxa2xx_pcm_client *client = substream->private_data;
  37        struct snd_pcm_runtime *runtime = substream->runtime;
  38        struct pxa2xx_runtime_data *rtd;
  39        int ret;
  40
  41        ret = __pxa2xx_pcm_open(substream);
  42        if (ret)
  43                goto out;
  44
  45        rtd = runtime->private_data;
  46
  47        rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  48                      client->playback_params : client->capture_params;
  49
  50        ret = client->startup(substream);
  51        if (!ret)
  52                goto err2;
  53
  54        return 0;
  55
  56 err2:
  57        __pxa2xx_pcm_close(substream);
  58 out:
  59        return ret;
  60}
  61
  62static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
  63{
  64        struct pxa2xx_pcm_client *client = substream->private_data;
  65
  66        client->shutdown(substream);
  67
  68        return __pxa2xx_pcm_close(substream);
  69}
  70
  71static struct snd_pcm_ops pxa2xx_pcm_ops = {
  72        .open           = pxa2xx_pcm_open,
  73        .close          = pxa2xx_pcm_close,
  74        .ioctl          = snd_pcm_lib_ioctl,
  75        .hw_params      = __pxa2xx_pcm_hw_params,
  76        .hw_free        = __pxa2xx_pcm_hw_free,
  77        .prepare        = pxa2xx_pcm_prepare,
  78        .trigger        = pxa2xx_pcm_trigger,
  79        .pointer        = pxa2xx_pcm_pointer,
  80        .mmap           = pxa2xx_pcm_mmap,
  81};
  82
  83int pxa2xx_pcm_new(struct snd_card *card, struct pxa2xx_pcm_client *client,
  84                   struct snd_pcm **rpcm)
  85{
  86        struct snd_pcm *pcm;
  87        int play = client->playback_params ? 1 : 0;
  88        int capt = client->capture_params ? 1 : 0;
  89        int ret;
  90
  91        ret = snd_pcm_new(card, "PXA2xx-PCM", 0, play, capt, &pcm);
  92        if (ret)
  93                goto out;
  94
  95        pcm->private_data = client;
  96        pcm->private_free = pxa2xx_pcm_free_dma_buffers;
  97
  98        ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
  99        if (ret)
 100                goto out;
 101
 102        if (play) {
 103                int stream = SNDRV_PCM_STREAM_PLAYBACK;
 104                snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops);
 105                ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
 106                if (ret)
 107                        goto out;
 108        }
 109        if (capt) {
 110                int stream = SNDRV_PCM_STREAM_CAPTURE;
 111                snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops);
 112                ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
 113                if (ret)
 114                        goto out;
 115        }
 116
 117        if (rpcm)
 118                *rpcm = pcm;
 119        ret = 0;
 120
 121 out:
 122        return ret;
 123}
 124
 125EXPORT_SYMBOL(pxa2xx_pcm_new);
 126
 127MODULE_AUTHOR("Nicolas Pitre");
 128MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
 129MODULE_LICENSE("GPL");
 130