Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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