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