linux/sound/soc/davinci/davinci-pcm.c
<<
>>
Prefs
   1/*
   2 * ALSA PCM interface for the TI DAVINCI processor
   3 *
   4 * Author:      Vladimir Barinov, <vbarinov@embeddedalley.com>
   5 * Copyright:   (C) 2007 MontaVista Software, Inc., <source@mvista.com>
   6 * added SRAM ping/pong (C) 2008 Troy Kisky <troy.kisky@boundarydevices.com>
   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/init.h>
  15#include <linux/platform_device.h>
  16#include <linux/slab.h>
  17#include <linux/dma-mapping.h>
  18#include <linux/kernel.h>
  19
  20#include <sound/core.h>
  21#include <sound/pcm.h>
  22#include <sound/pcm_params.h>
  23#include <sound/soc.h>
  24
  25#include <asm/dma.h>
  26#include <mach/edma.h>
  27#include <mach/sram.h>
  28
  29#include "davinci-pcm.h"
  30
  31#ifdef DEBUG
  32static void print_buf_info(int slot, char *name)
  33{
  34        struct edmacc_param p;
  35        if (slot < 0)
  36                return;
  37        edma_read_slot(slot, &p);
  38        printk(KERN_DEBUG "%s: 0x%x, opt=%x, src=%x, a_b_cnt=%x dst=%x\n",
  39                        name, slot, p.opt, p.src, p.a_b_cnt, p.dst);
  40        printk(KERN_DEBUG "    src_dst_bidx=%x link_bcntrld=%x src_dst_cidx=%x ccnt=%x\n",
  41                        p.src_dst_bidx, p.link_bcntrld, p.src_dst_cidx, p.ccnt);
  42}
  43#else
  44static void print_buf_info(int slot, char *name)
  45{
  46}
  47#endif
  48
  49#define DAVINCI_PCM_FMTBITS     (\
  50                                SNDRV_PCM_FMTBIT_S8     |\
  51                                SNDRV_PCM_FMTBIT_U8     |\
  52                                SNDRV_PCM_FMTBIT_S16_LE |\
  53                                SNDRV_PCM_FMTBIT_S16_BE |\
  54                                SNDRV_PCM_FMTBIT_U16_LE |\
  55                                SNDRV_PCM_FMTBIT_U16_BE |\
  56                                SNDRV_PCM_FMTBIT_S24_LE |\
  57                                SNDRV_PCM_FMTBIT_S24_BE |\
  58                                SNDRV_PCM_FMTBIT_U24_LE |\
  59                                SNDRV_PCM_FMTBIT_U24_BE |\
  60                                SNDRV_PCM_FMTBIT_S32_LE |\
  61                                SNDRV_PCM_FMTBIT_S32_BE |\
  62                                SNDRV_PCM_FMTBIT_U32_LE |\
  63                                SNDRV_PCM_FMTBIT_U32_BE)
  64
  65static struct snd_pcm_hardware pcm_hardware_playback = {
  66        .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
  67                 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
  68                 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME|
  69                 SNDRV_PCM_INFO_BATCH),
  70        .formats = DAVINCI_PCM_FMTBITS,
  71        .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
  72                  SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
  73                  SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
  74                  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
  75                  SNDRV_PCM_RATE_KNOT),
  76        .rate_min = 8000,
  77        .rate_max = 96000,
  78        .channels_min = 2,
  79        .channels_max = 384,
  80        .buffer_bytes_max = 128 * 1024,
  81        .period_bytes_min = 32,
  82        .period_bytes_max = 8 * 1024,
  83        .periods_min = 16,
  84        .periods_max = 255,
  85        .fifo_size = 0,
  86};
  87
  88static struct snd_pcm_hardware pcm_hardware_capture = {
  89        .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
  90                 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
  91                 SNDRV_PCM_INFO_PAUSE |
  92                 SNDRV_PCM_INFO_BATCH),
  93        .formats = DAVINCI_PCM_FMTBITS,
  94        .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
  95                  SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
  96                  SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
  97                  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
  98                  SNDRV_PCM_RATE_KNOT),
  99        .rate_min = 8000,
 100        .rate_max = 96000,
 101        .channels_min = 2,
 102        .channels_max = 384,
 103        .buffer_bytes_max = 128 * 1024,
 104        .period_bytes_min = 32,
 105        .period_bytes_max = 8 * 1024,
 106        .periods_min = 16,
 107        .periods_max = 255,
 108        .fifo_size = 0,
 109};
 110
 111/*
 112 * How ping/pong works....
 113 *
 114 * Playback:
 115 * ram_params - copys 2*ping_size from start of SDRAM to iram,
 116 *      links to ram_link2
 117 * ram_link2 - copys rest of SDRAM to iram in ping_size units,
 118 *      links to ram_link
 119 * ram_link - copys entire SDRAM to iram in ping_size uints,
 120 *      links to self
 121 *
 122 * asp_params - same as asp_link[0]
 123 * asp_link[0] - copys from lower half of iram to asp port
 124 *      links to asp_link[1], triggers iram copy event on completion
 125 * asp_link[1] - copys from upper half of iram to asp port
 126 *      links to asp_link[0], triggers iram copy event on completion
 127 *      triggers interrupt only needed to let upper SOC levels update position
 128 *      in stream on completion
 129 *
 130 * When playback is started:
 131 *      ram_params started
 132 *      asp_params started
 133 *
 134 * Capture:
 135 * ram_params - same as ram_link,
 136 *      links to ram_link
 137 * ram_link - same as playback
 138 *      links to self
 139 *
 140 * asp_params - same as playback
 141 * asp_link[0] - same as playback
 142 * asp_link[1] - same as playback
 143 *
 144 * When capture is started:
 145 *      asp_params started
 146 */
 147struct davinci_runtime_data {
 148        spinlock_t lock;
 149        int period;             /* current DMA period */
 150        int asp_channel;        /* Master DMA channel */
 151        int asp_link[2];        /* asp parameter link channel, ping/pong */
 152        struct davinci_pcm_dma_params *params;  /* DMA params */
 153        int ram_channel;
 154        int ram_link;
 155        int ram_link2;
 156        struct edmacc_param asp_params;
 157        struct edmacc_param ram_params;
 158};
 159
 160static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream)
 161{
 162        struct davinci_runtime_data *prtd = substream->runtime->private_data;
 163        struct snd_pcm_runtime *runtime = substream->runtime;
 164
 165        prtd->period++;
 166        if (unlikely(prtd->period >= runtime->periods))
 167                prtd->period = 0;
 168}
 169
 170static void davinci_pcm_period_reset(struct snd_pcm_substream *substream)
 171{
 172        struct davinci_runtime_data *prtd = substream->runtime->private_data;
 173
 174        prtd->period = 0;
 175}
 176/*
 177 * Not used with ping/pong
 178 */
 179static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
 180{
 181        struct davinci_runtime_data *prtd = substream->runtime->private_data;
 182        struct snd_pcm_runtime *runtime = substream->runtime;
 183        unsigned int period_size;
 184        unsigned int dma_offset;
 185        dma_addr_t dma_pos;
 186        dma_addr_t src, dst;
 187        unsigned short src_bidx, dst_bidx;
 188        unsigned short src_cidx, dst_cidx;
 189        unsigned int data_type;
 190        unsigned short acnt;
 191        unsigned int count;
 192        unsigned int fifo_level;
 193
 194        period_size = snd_pcm_lib_period_bytes(substream);
 195        dma_offset = prtd->period * period_size;
 196        dma_pos = runtime->dma_addr + dma_offset;
 197        fifo_level = prtd->params->fifo_level;
 198
 199        pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
 200                "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos,
 201                period_size);
 202
 203        data_type = prtd->params->data_type;
 204        count = period_size / data_type;
 205        if (fifo_level)
 206                count /= fifo_level;
 207
 208        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 209                src = dma_pos;
 210                dst = prtd->params->dma_addr;
 211                src_bidx = data_type;
 212                dst_bidx = 0;
 213                src_cidx = data_type * fifo_level;
 214                dst_cidx = 0;
 215        } else {
 216                src = prtd->params->dma_addr;
 217                dst = dma_pos;
 218                src_bidx = 0;
 219                dst_bidx = data_type;
 220                src_cidx = 0;
 221                dst_cidx = data_type * fifo_level;
 222        }
 223
 224        acnt = prtd->params->acnt;
 225        edma_set_src(prtd->asp_link[0], src, INCR, W8BIT);
 226        edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT);
 227
 228        edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx);
 229        edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx);
 230
 231        if (!fifo_level)
 232                edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0,
 233                                                        ASYNC);
 234        else
 235                edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
 236                                                        count, fifo_level,
 237                                                        ABSYNC);
 238}
 239
 240static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
 241{
 242        struct snd_pcm_substream *substream = data;
 243        struct davinci_runtime_data *prtd = substream->runtime->private_data;
 244
 245        print_buf_info(prtd->ram_channel, "i ram_channel");
 246        pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status);
 247
 248        if (unlikely(ch_status != DMA_COMPLETE))
 249                return;
 250
 251        if (snd_pcm_running(substream)) {
 252                spin_lock(&prtd->lock);
 253                if (prtd->ram_channel < 0) {
 254                        /* No ping/pong must fix up link dma data*/
 255                        davinci_pcm_enqueue_dma(substream);
 256                }
 257                davinci_pcm_period_elapsed(substream);
 258                spin_unlock(&prtd->lock);
 259                snd_pcm_period_elapsed(substream);
 260        }
 261}
 262
 263static int allocate_sram(struct snd_pcm_substream *substream, unsigned size,
 264                struct snd_pcm_hardware *ppcm)
 265{
 266        struct snd_dma_buffer *buf = &substream->dma_buffer;
 267        struct snd_dma_buffer *iram_dma = NULL;
 268        dma_addr_t iram_phys = 0;
 269        void *iram_virt = NULL;
 270
 271        if (buf->private_data || !size)
 272                return 0;
 273
 274        ppcm->period_bytes_max = size;
 275        iram_virt = sram_alloc(size, &iram_phys);
 276        if (!iram_virt)
 277                goto exit1;
 278        iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL);
 279        if (!iram_dma)
 280                goto exit2;
 281        iram_dma->area = iram_virt;
 282        iram_dma->addr = iram_phys;
 283        memset(iram_dma->area, 0, size);
 284        iram_dma->bytes = size;
 285        buf->private_data = iram_dma;
 286        return 0;
 287exit2:
 288        if (iram_virt)
 289                sram_free(iram_virt, size);
 290exit1:
 291        return -ENOMEM;
 292}
 293
 294/*
 295 * Only used with ping/pong.
 296 * This is called after runtime->dma_addr, period_bytes and data_type are valid
 297 */
 298static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
 299{
 300        unsigned short ram_src_cidx, ram_dst_cidx;
 301        struct snd_pcm_runtime *runtime = substream->runtime;
 302        struct davinci_runtime_data *prtd = runtime->private_data;
 303        struct snd_dma_buffer *iram_dma =
 304                (struct snd_dma_buffer *)substream->dma_buffer.private_data;
 305        struct davinci_pcm_dma_params *params = prtd->params;
 306        unsigned int data_type = params->data_type;
 307        unsigned int acnt = params->acnt;
 308        /* divide by 2 for ping/pong */
 309        unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
 310        unsigned int fifo_level = prtd->params->fifo_level;
 311        unsigned int count;
 312        if ((data_type == 0) || (data_type > 4)) {
 313                printk(KERN_ERR "%s: data_type=%i\n", __func__, data_type);
 314                return -EINVAL;
 315        }
 316        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 317                dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
 318                ram_src_cidx = ping_size;
 319                ram_dst_cidx = -ping_size;
 320                edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT);
 321
 322                edma_set_src_index(prtd->asp_link[0], data_type,
 323                                data_type * fifo_level);
 324                edma_set_src_index(prtd->asp_link[1], data_type,
 325                                data_type * fifo_level);
 326
 327                edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
 328        } else {
 329                dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
 330                ram_src_cidx = -ping_size;
 331                ram_dst_cidx = ping_size;
 332                edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT);
 333
 334                edma_set_dest_index(prtd->asp_link[0], data_type,
 335                                data_type * fifo_level);
 336                edma_set_dest_index(prtd->asp_link[1], data_type,
 337                                data_type * fifo_level);
 338
 339                edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT);
 340        }
 341
 342        if (!fifo_level) {
 343                count = ping_size / data_type;
 344                edma_set_transfer_params(prtd->asp_link[0], acnt, count,
 345                                1, 0, ASYNC);
 346                edma_set_transfer_params(prtd->asp_link[1], acnt, count,
 347                                1, 0, ASYNC);
 348        } else {
 349                count = ping_size / (data_type * fifo_level);
 350                edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
 351                                count, fifo_level, ABSYNC);
 352                edma_set_transfer_params(prtd->asp_link[1], acnt, fifo_level,
 353                                count, fifo_level, ABSYNC);
 354        }
 355
 356        edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx);
 357        edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx);
 358        edma_set_transfer_params(prtd->ram_link, ping_size, 2,
 359                        runtime->periods, 2, ASYNC);
 360
 361        /* init master params */
 362        edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
 363        edma_read_slot(prtd->ram_link, &prtd->ram_params);
 364        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 365                struct edmacc_param p_ram;
 366                /* Copy entire iram buffer before playback started */
 367                prtd->ram_params.a_b_cnt = (1 << 16) | (ping_size << 1);
 368                /* 0 dst_bidx */
 369                prtd->ram_params.src_dst_bidx = (ping_size << 1);
 370                /* 0 dst_cidx */
 371                prtd->ram_params.src_dst_cidx = (ping_size << 1);
 372                prtd->ram_params.ccnt = 1;
 373
 374                /* Skip 1st period */
 375                edma_read_slot(prtd->ram_link, &p_ram);
 376                p_ram.src += (ping_size << 1);
 377                p_ram.ccnt -= 1;
 378                edma_write_slot(prtd->ram_link2, &p_ram);
 379                /*
 380                 * When 1st started, ram -> iram dma channel will fill the
 381                 * entire iram.  Then, whenever a ping/pong asp buffer finishes,
 382                 * 1/2 iram will be filled.
 383                 */
 384                prtd->ram_params.link_bcntrld =
 385                        EDMA_CHAN_SLOT(prtd->ram_link2) << 5;
 386        }
 387        return 0;
 388}
 389
 390/* 1 asp tx or rx channel using 2 parameter channels
 391 * 1 ram to/from iram channel using 1 parameter channel
 392 *
 393 * Playback
 394 * ram copy channel kicks off first,
 395 * 1st ram copy of entire iram buffer completion kicks off asp channel
 396 * asp tcc always kicks off ram copy of 1/2 iram buffer
 397 *
 398 * Record
 399 * asp channel starts, tcc kicks off ram copy
 400 */
 401static int request_ping_pong(struct snd_pcm_substream *substream,
 402                struct davinci_runtime_data *prtd,
 403                struct snd_dma_buffer *iram_dma)
 404{
 405        dma_addr_t asp_src_ping;
 406        dma_addr_t asp_dst_ping;
 407        int ret;
 408        struct davinci_pcm_dma_params *params = prtd->params;
 409
 410        /* Request ram master channel */
 411        ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
 412                                  davinci_pcm_dma_irq, substream,
 413                                  prtd->params->ram_chan_q);
 414        if (ret < 0)
 415                goto exit1;
 416
 417        /* Request ram link channel */
 418        ret = prtd->ram_link = edma_alloc_slot(
 419                        EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
 420        if (ret < 0)
 421                goto exit2;
 422
 423        ret = prtd->asp_link[1] = edma_alloc_slot(
 424                        EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
 425        if (ret < 0)
 426                goto exit3;
 427
 428        prtd->ram_link2 = -1;
 429        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 430                ret = prtd->ram_link2 = edma_alloc_slot(
 431                        EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
 432                if (ret < 0)
 433                        goto exit4;
 434        }
 435        /* circle ping-pong buffers */
 436        edma_link(prtd->asp_link[0], prtd->asp_link[1]);
 437        edma_link(prtd->asp_link[1], prtd->asp_link[0]);
 438        /* circle ram buffers */
 439        edma_link(prtd->ram_link, prtd->ram_link);
 440
 441        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 442                asp_src_ping = iram_dma->addr;
 443                asp_dst_ping = params->dma_addr;        /* fifo */
 444        } else {
 445                asp_src_ping = params->dma_addr;        /* fifo */
 446                asp_dst_ping = iram_dma->addr;
 447        }
 448        /* ping */
 449        edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT);
 450        edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT);
 451        edma_set_src_index(prtd->asp_link[0], 0, 0);
 452        edma_set_dest_index(prtd->asp_link[0], 0, 0);
 453
 454        edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
 455        prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
 456        prtd->asp_params.opt |= TCCHEN |
 457                EDMA_TCC(prtd->ram_channel & 0x3f);
 458        edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
 459
 460        /* pong */
 461        edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT);
 462        edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT);
 463        edma_set_src_index(prtd->asp_link[1], 0, 0);
 464        edma_set_dest_index(prtd->asp_link[1], 0, 0);
 465
 466        edma_read_slot(prtd->asp_link[1], &prtd->asp_params);
 467        prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
 468        /* interrupt after every pong completion */
 469        prtd->asp_params.opt |= TCINTEN | TCCHEN |
 470                EDMA_TCC(prtd->ram_channel & 0x3f);
 471        edma_write_slot(prtd->asp_link[1], &prtd->asp_params);
 472
 473        /* ram */
 474        edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
 475        edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT);
 476        pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
 477                "for asp:%u %u %u\n", __func__,
 478                prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
 479                prtd->asp_channel, prtd->asp_link[0],
 480                prtd->asp_link[1]);
 481        return 0;
 482exit4:
 483        edma_free_channel(prtd->asp_link[1]);
 484        prtd->asp_link[1] = -1;
 485exit3:
 486        edma_free_channel(prtd->ram_link);
 487        prtd->ram_link = -1;
 488exit2:
 489        edma_free_channel(prtd->ram_channel);
 490        prtd->ram_channel = -1;
 491exit1:
 492        return ret;
 493}
 494
 495static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
 496{
 497        struct snd_dma_buffer *iram_dma;
 498        struct davinci_runtime_data *prtd = substream->runtime->private_data;
 499        struct davinci_pcm_dma_params *params = prtd->params;
 500        int ret;
 501
 502        if (!params)
 503                return -ENODEV;
 504
 505        /* Request asp master DMA channel */
 506        ret = prtd->asp_channel = edma_alloc_channel(params->channel,
 507                        davinci_pcm_dma_irq, substream,
 508                        prtd->params->asp_chan_q);
 509        if (ret < 0)
 510                goto exit1;
 511
 512        /* Request asp link channels */
 513        ret = prtd->asp_link[0] = edma_alloc_slot(
 514                        EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
 515        if (ret < 0)
 516                goto exit2;
 517
 518        iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
 519        if (iram_dma) {
 520                if (request_ping_pong(substream, prtd, iram_dma) == 0)
 521                        return 0;
 522                printk(KERN_WARNING "%s: dma channel allocation failed,"
 523                                "not using sram\n", __func__);
 524        }
 525
 526        /* Issue transfer completion IRQ when the channel completes a
 527         * transfer, then always reload from the same slot (by a kind
 528         * of loopback link).  The completion IRQ handler will update
 529         * the reload slot with a new buffer.
 530         *
 531         * REVISIT save p_ram here after setting up everything except
 532         * the buffer and its length (ccnt) ... use it as a template
 533         * so davinci_pcm_enqueue_dma() takes less time in IRQ.
 534         */
 535        edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
 536        prtd->asp_params.opt |= TCINTEN |
 537                EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
 538        prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5;
 539        edma_write_slot(prtd->asp_link[0], &prtd->asp_params);
 540        return 0;
 541exit2:
 542        edma_free_channel(prtd->asp_channel);
 543        prtd->asp_channel = -1;
 544exit1:
 545        return ret;
 546}
 547
 548static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 549{
 550        struct davinci_runtime_data *prtd = substream->runtime->private_data;
 551        int ret = 0;
 552
 553        spin_lock(&prtd->lock);
 554
 555        switch (cmd) {
 556        case SNDRV_PCM_TRIGGER_START:
 557                edma_start(prtd->asp_channel);
 558                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 559                    prtd->ram_channel >= 0) {
 560                        /* copy 1st iram buffer */
 561                        edma_start(prtd->ram_channel);
 562                }
 563                break;
 564        case SNDRV_PCM_TRIGGER_RESUME:
 565        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 566                edma_resume(prtd->asp_channel);
 567                break;
 568        case SNDRV_PCM_TRIGGER_STOP:
 569        case SNDRV_PCM_TRIGGER_SUSPEND:
 570        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 571                edma_pause(prtd->asp_channel);
 572                break;
 573        default:
 574                ret = -EINVAL;
 575                break;
 576        }
 577
 578        spin_unlock(&prtd->lock);
 579
 580        return ret;
 581}
 582
 583static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
 584{
 585        struct davinci_runtime_data *prtd = substream->runtime->private_data;
 586
 587        davinci_pcm_period_reset(substream);
 588        if (prtd->ram_channel >= 0) {
 589                int ret = ping_pong_dma_setup(substream);
 590                if (ret < 0)
 591                        return ret;
 592
 593                edma_write_slot(prtd->ram_channel, &prtd->ram_params);
 594                edma_write_slot(prtd->asp_channel, &prtd->asp_params);
 595
 596                print_buf_info(prtd->ram_channel, "ram_channel");
 597                print_buf_info(prtd->ram_link, "ram_link");
 598                print_buf_info(prtd->ram_link2, "ram_link2");
 599                print_buf_info(prtd->asp_channel, "asp_channel");
 600                print_buf_info(prtd->asp_link[0], "asp_link[0]");
 601                print_buf_info(prtd->asp_link[1], "asp_link[1]");
 602
 603                /*
 604                 * There is a phase offset of 2 periods between the position
 605                 * used by dma setup and the position reported in the pointer
 606                 * function.
 607                 *
 608                 * The phase offset, when not using ping-pong buffers, is due to
 609                 * the two consecutive calls to davinci_pcm_enqueue_dma() below.
 610                 *
 611                 * Whereas here, with ping-pong buffers, the phase is due to
 612                 * there being an entire buffer transfer complete before the
 613                 * first dma completion event triggers davinci_pcm_dma_irq().
 614                 */
 615                davinci_pcm_period_elapsed(substream);
 616                davinci_pcm_period_elapsed(substream);
 617
 618                return 0;
 619        }
 620        davinci_pcm_enqueue_dma(substream);
 621        davinci_pcm_period_elapsed(substream);
 622
 623        /* Copy self-linked parameter RAM entry into master channel */
 624        edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
 625        edma_write_slot(prtd->asp_channel, &prtd->asp_params);
 626        davinci_pcm_enqueue_dma(substream);
 627        davinci_pcm_period_elapsed(substream);
 628
 629        return 0;
 630}
 631
 632static snd_pcm_uframes_t
 633davinci_pcm_pointer(struct snd_pcm_substream *substream)
 634{
 635        struct snd_pcm_runtime *runtime = substream->runtime;
 636        struct davinci_runtime_data *prtd = runtime->private_data;
 637        unsigned int offset;
 638        int asp_count;
 639        unsigned int period_size = snd_pcm_lib_period_bytes(substream);
 640
 641        /*
 642         * There is a phase offset of 2 periods between the position used by dma
 643         * setup and the position reported in the pointer function. Either +2 in
 644         * the dma setup or -2 here in the pointer function (with wrapping,
 645         * both) accounts for this offset -- choose the latter since it makes
 646         * the first-time setup clearer.
 647         */
 648        spin_lock(&prtd->lock);
 649        asp_count = prtd->period - 2;
 650        spin_unlock(&prtd->lock);
 651
 652        if (asp_count < 0)
 653                asp_count += runtime->periods;
 654        asp_count *= period_size;
 655
 656        offset = bytes_to_frames(runtime, asp_count);
 657        if (offset >= runtime->buffer_size)
 658                offset = 0;
 659
 660        return offset;
 661}
 662
 663static int davinci_pcm_open(struct snd_pcm_substream *substream)
 664{
 665        struct snd_pcm_runtime *runtime = substream->runtime;
 666        struct davinci_runtime_data *prtd;
 667        struct snd_pcm_hardware *ppcm;
 668        int ret = 0;
 669        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 670        struct davinci_pcm_dma_params *pa;
 671        struct davinci_pcm_dma_params *params;
 672
 673        pa = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 674        if (!pa)
 675                return -ENODEV;
 676        params = &pa[substream->stream];
 677
 678        ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
 679                        &pcm_hardware_playback : &pcm_hardware_capture;
 680        allocate_sram(substream, params->sram_size, ppcm);
 681        snd_soc_set_runtime_hwparams(substream, ppcm);
 682        /* ensure that buffer size is a multiple of period size */
 683        ret = snd_pcm_hw_constraint_integer(runtime,
 684                                                SNDRV_PCM_HW_PARAM_PERIODS);
 685        if (ret < 0)
 686                return ret;
 687
 688        prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL);
 689        if (prtd == NULL)
 690                return -ENOMEM;
 691
 692        spin_lock_init(&prtd->lock);
 693        prtd->params = params;
 694        prtd->asp_channel = -1;
 695        prtd->asp_link[0] = prtd->asp_link[1] = -1;
 696        prtd->ram_channel = -1;
 697        prtd->ram_link = -1;
 698        prtd->ram_link2 = -1;
 699
 700        runtime->private_data = prtd;
 701
 702        ret = davinci_pcm_dma_request(substream);
 703        if (ret) {
 704                printk(KERN_ERR "davinci_pcm: Failed to get dma channels\n");
 705                kfree(prtd);
 706        }
 707
 708        return ret;
 709}
 710
 711static int davinci_pcm_close(struct snd_pcm_substream *substream)
 712{
 713        struct snd_pcm_runtime *runtime = substream->runtime;
 714        struct davinci_runtime_data *prtd = runtime->private_data;
 715
 716        if (prtd->ram_channel >= 0)
 717                edma_stop(prtd->ram_channel);
 718        if (prtd->asp_channel >= 0)
 719                edma_stop(prtd->asp_channel);
 720        if (prtd->asp_link[0] >= 0)
 721                edma_unlink(prtd->asp_link[0]);
 722        if (prtd->asp_link[1] >= 0)
 723                edma_unlink(prtd->asp_link[1]);
 724        if (prtd->ram_link >= 0)
 725                edma_unlink(prtd->ram_link);
 726
 727        if (prtd->asp_link[0] >= 0)
 728                edma_free_slot(prtd->asp_link[0]);
 729        if (prtd->asp_link[1] >= 0)
 730                edma_free_slot(prtd->asp_link[1]);
 731        if (prtd->asp_channel >= 0)
 732                edma_free_channel(prtd->asp_channel);
 733        if (prtd->ram_link >= 0)
 734                edma_free_slot(prtd->ram_link);
 735        if (prtd->ram_link2 >= 0)
 736                edma_free_slot(prtd->ram_link2);
 737        if (prtd->ram_channel >= 0)
 738                edma_free_channel(prtd->ram_channel);
 739
 740        kfree(prtd);
 741
 742        return 0;
 743}
 744
 745static int davinci_pcm_hw_params(struct snd_pcm_substream *substream,
 746                                 struct snd_pcm_hw_params *hw_params)
 747{
 748        return snd_pcm_lib_malloc_pages(substream,
 749                                        params_buffer_bytes(hw_params));
 750}
 751
 752static int davinci_pcm_hw_free(struct snd_pcm_substream *substream)
 753{
 754        return snd_pcm_lib_free_pages(substream);
 755}
 756
 757static int davinci_pcm_mmap(struct snd_pcm_substream *substream,
 758                            struct vm_area_struct *vma)
 759{
 760        struct snd_pcm_runtime *runtime = substream->runtime;
 761
 762        return dma_mmap_writecombine(substream->pcm->card->dev, vma,
 763                                     runtime->dma_area,
 764                                     runtime->dma_addr,
 765                                     runtime->dma_bytes);
 766}
 767
 768static struct snd_pcm_ops davinci_pcm_ops = {
 769        .open =         davinci_pcm_open,
 770        .close =        davinci_pcm_close,
 771        .ioctl =        snd_pcm_lib_ioctl,
 772        .hw_params =    davinci_pcm_hw_params,
 773        .hw_free =      davinci_pcm_hw_free,
 774        .prepare =      davinci_pcm_prepare,
 775        .trigger =      davinci_pcm_trigger,
 776        .pointer =      davinci_pcm_pointer,
 777        .mmap =         davinci_pcm_mmap,
 778};
 779
 780static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
 781                size_t size)
 782{
 783        struct snd_pcm_substream *substream = pcm->streams[stream].substream;
 784        struct snd_dma_buffer *buf = &substream->dma_buffer;
 785
 786        buf->dev.type = SNDRV_DMA_TYPE_DEV;
 787        buf->dev.dev = pcm->card->dev;
 788        buf->private_data = NULL;
 789        buf->area = dma_alloc_writecombine(pcm->card->dev, size,
 790                                           &buf->addr, GFP_KERNEL);
 791
 792        pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
 793                "size=%d\n", (void *) buf->area, (void *) buf->addr, size);
 794
 795        if (!buf->area)
 796                return -ENOMEM;
 797
 798        buf->bytes = size;
 799        return 0;
 800}
 801
 802static void davinci_pcm_free(struct snd_pcm *pcm)
 803{
 804        struct snd_pcm_substream *substream;
 805        struct snd_dma_buffer *buf;
 806        int stream;
 807
 808        for (stream = 0; stream < 2; stream++) {
 809                struct snd_dma_buffer *iram_dma;
 810                substream = pcm->streams[stream].substream;
 811                if (!substream)
 812                        continue;
 813
 814                buf = &substream->dma_buffer;
 815                if (!buf->area)
 816                        continue;
 817
 818                dma_free_writecombine(pcm->card->dev, buf->bytes,
 819                                      buf->area, buf->addr);
 820                buf->area = NULL;
 821                iram_dma = buf->private_data;
 822                if (iram_dma) {
 823                        sram_free(iram_dma->area, iram_dma->bytes);
 824                        kfree(iram_dma);
 825                }
 826        }
 827}
 828
 829static u64 davinci_pcm_dmamask = DMA_BIT_MASK(32);
 830
 831static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
 832{
 833        struct snd_card *card = rtd->card->snd_card;
 834        struct snd_pcm *pcm = rtd->pcm;
 835        int ret;
 836
 837        if (!card->dev->dma_mask)
 838                card->dev->dma_mask = &davinci_pcm_dmamask;
 839        if (!card->dev->coherent_dma_mask)
 840                card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
 841
 842        if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
 843                ret = davinci_pcm_preallocate_dma_buffer(pcm,
 844                        SNDRV_PCM_STREAM_PLAYBACK,
 845                        pcm_hardware_playback.buffer_bytes_max);
 846                if (ret)
 847                        return ret;
 848        }
 849
 850        if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
 851                ret = davinci_pcm_preallocate_dma_buffer(pcm,
 852                        SNDRV_PCM_STREAM_CAPTURE,
 853                        pcm_hardware_capture.buffer_bytes_max);
 854                if (ret)
 855                        return ret;
 856        }
 857
 858        return 0;
 859}
 860
 861static struct snd_soc_platform_driver davinci_soc_platform = {
 862        .ops =          &davinci_pcm_ops,
 863        .pcm_new =      davinci_pcm_new,
 864        .pcm_free =     davinci_pcm_free,
 865};
 866
 867static int __devinit davinci_soc_platform_probe(struct platform_device *pdev)
 868{
 869        return snd_soc_register_platform(&pdev->dev, &davinci_soc_platform);
 870}
 871
 872static int __devexit davinci_soc_platform_remove(struct platform_device *pdev)
 873{
 874        snd_soc_unregister_platform(&pdev->dev);
 875        return 0;
 876}
 877
 878static struct platform_driver davinci_pcm_driver = {
 879        .driver = {
 880                        .name = "davinci-pcm-audio",
 881                        .owner = THIS_MODULE,
 882        },
 883
 884        .probe = davinci_soc_platform_probe,
 885        .remove = __devexit_p(davinci_soc_platform_remove),
 886};
 887
 888module_platform_driver(davinci_pcm_driver);
 889
 890MODULE_AUTHOR("Vladimir Barinov");
 891MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
 892MODULE_LICENSE("GPL");
 893