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