diff options
Diffstat (limited to 'sound/soc/davinci/davinci-pcm.c')
-rw-r--r-- | sound/soc/davinci/davinci-pcm.c | 123 |
1 files changed, 59 insertions, 64 deletions
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index a49e667373bc..d5fe08cc5db7 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -180,7 +180,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
180 | { | 180 | { |
181 | struct davinci_runtime_data *prtd = substream->runtime->private_data; | 181 | struct davinci_runtime_data *prtd = substream->runtime->private_data; |
182 | struct snd_pcm_runtime *runtime = substream->runtime; | 182 | struct snd_pcm_runtime *runtime = substream->runtime; |
183 | int link = prtd->asp_link[0]; | ||
184 | unsigned int period_size; | 183 | unsigned int period_size; |
185 | unsigned int dma_offset; | 184 | unsigned int dma_offset; |
186 | dma_addr_t dma_pos; | 185 | dma_addr_t dma_pos; |
@@ -198,7 +197,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
198 | fifo_level = prtd->params->fifo_level; | 197 | fifo_level = prtd->params->fifo_level; |
199 | 198 | ||
200 | pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " | 199 | pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " |
201 | "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size); | 200 | "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos, |
201 | period_size); | ||
202 | 202 | ||
203 | data_type = prtd->params->data_type; | 203 | data_type = prtd->params->data_type; |
204 | count = period_size / data_type; | 204 | count = period_size / data_type; |
@@ -222,17 +222,19 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
222 | } | 222 | } |
223 | 223 | ||
224 | acnt = prtd->params->acnt; | 224 | acnt = prtd->params->acnt; |
225 | edma_set_src(link, src, INCR, W8BIT); | 225 | edma_set_src(prtd->asp_link[0], src, INCR, W8BIT); |
226 | edma_set_dest(link, dst, INCR, W8BIT); | 226 | edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT); |
227 | 227 | ||
228 | edma_set_src_index(link, src_bidx, src_cidx); | 228 | edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx); |
229 | edma_set_dest_index(link, dst_bidx, dst_cidx); | 229 | edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx); |
230 | 230 | ||
231 | if (!fifo_level) | 231 | if (!fifo_level) |
232 | edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC); | 232 | edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, |
233 | ASYNC); | ||
233 | else | 234 | else |
234 | edma_set_transfer_params(link, acnt, fifo_level, count, | 235 | edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, |
235 | fifo_level, ABSYNC); | 236 | count, fifo_level, |
237 | ABSYNC); | ||
236 | } | 238 | } |
237 | 239 | ||
238 | static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) | 240 | static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) |
@@ -305,7 +307,6 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) | |||
305 | unsigned int acnt = params->acnt; | 307 | unsigned int acnt = params->acnt; |
306 | /* divide by 2 for ping/pong */ | 308 | /* divide by 2 for ping/pong */ |
307 | unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; | 309 | unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; |
308 | int link = prtd->asp_link[1]; | ||
309 | unsigned int fifo_level = prtd->params->fifo_level; | 310 | unsigned int fifo_level = prtd->params->fifo_level; |
310 | unsigned int count; | 311 | unsigned int count; |
311 | if ((data_type == 0) || (data_type > 4)) { | 312 | if ((data_type == 0) || (data_type > 4)) { |
@@ -316,28 +317,26 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) | |||
316 | dma_addr_t asp_src_pong = iram_dma->addr + ping_size; | 317 | dma_addr_t asp_src_pong = iram_dma->addr + ping_size; |
317 | ram_src_cidx = ping_size; | 318 | ram_src_cidx = ping_size; |
318 | ram_dst_cidx = -ping_size; | 319 | ram_dst_cidx = -ping_size; |
319 | edma_set_src(link, asp_src_pong, INCR, W8BIT); | 320 | edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT); |
320 | 321 | ||
321 | link = prtd->asp_link[0]; | 322 | edma_set_src_index(prtd->asp_link[0], data_type, |
322 | edma_set_src_index(link, data_type, data_type * fifo_level); | 323 | data_type * fifo_level); |
323 | link = prtd->asp_link[1]; | 324 | edma_set_src_index(prtd->asp_link[1], data_type, |
324 | edma_set_src_index(link, data_type, data_type * fifo_level); | 325 | data_type * fifo_level); |
325 | 326 | ||
326 | link = prtd->ram_link; | 327 | edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); |
327 | edma_set_src(link, runtime->dma_addr, INCR, W32BIT); | ||
328 | } else { | 328 | } else { |
329 | dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; | 329 | dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; |
330 | ram_src_cidx = -ping_size; | 330 | ram_src_cidx = -ping_size; |
331 | ram_dst_cidx = ping_size; | 331 | ram_dst_cidx = ping_size; |
332 | edma_set_dest(link, asp_dst_pong, INCR, W8BIT); | 332 | edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT); |
333 | 333 | ||
334 | link = prtd->asp_link[0]; | 334 | edma_set_dest_index(prtd->asp_link[0], data_type, |
335 | edma_set_dest_index(link, data_type, data_type * fifo_level); | 335 | data_type * fifo_level); |
336 | link = prtd->asp_link[1]; | 336 | edma_set_dest_index(prtd->asp_link[1], data_type, |
337 | edma_set_dest_index(link, data_type, data_type * fifo_level); | 337 | data_type * fifo_level); |
338 | 338 | ||
339 | link = prtd->ram_link; | 339 | edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); |
340 | edma_set_dest(link, runtime->dma_addr, INCR, W32BIT); | ||
341 | } | 340 | } |
342 | 341 | ||
343 | if (!fifo_level) { | 342 | if (!fifo_level) { |
@@ -354,10 +353,9 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) | |||
354 | count, fifo_level, ABSYNC); | 353 | count, fifo_level, ABSYNC); |
355 | } | 354 | } |
356 | 355 | ||
357 | link = prtd->ram_link; | 356 | edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx); |
358 | edma_set_src_index(link, ping_size, ram_src_cidx); | 357 | edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx); |
359 | edma_set_dest_index(link, ping_size, ram_dst_cidx); | 358 | edma_set_transfer_params(prtd->ram_link, ping_size, 2, |
360 | edma_set_transfer_params(link, ping_size, 2, | ||
361 | runtime->periods, 2, ASYNC); | 359 | runtime->periods, 2, ASYNC); |
362 | 360 | ||
363 | /* init master params */ | 361 | /* init master params */ |
@@ -406,32 +404,32 @@ static int request_ping_pong(struct snd_pcm_substream *substream, | |||
406 | { | 404 | { |
407 | dma_addr_t asp_src_ping; | 405 | dma_addr_t asp_src_ping; |
408 | dma_addr_t asp_dst_ping; | 406 | dma_addr_t asp_dst_ping; |
409 | int link; | 407 | int ret; |
410 | struct davinci_pcm_dma_params *params = prtd->params; | 408 | struct davinci_pcm_dma_params *params = prtd->params; |
411 | 409 | ||
412 | /* Request ram master channel */ | 410 | /* Request ram master channel */ |
413 | link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, | 411 | ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, |
414 | davinci_pcm_dma_irq, substream, | 412 | davinci_pcm_dma_irq, substream, |
415 | prtd->params->ram_chan_q); | 413 | prtd->params->ram_chan_q); |
416 | if (link < 0) | 414 | if (ret < 0) |
417 | goto exit1; | 415 | goto exit1; |
418 | 416 | ||
419 | /* Request ram link channel */ | 417 | /* Request ram link channel */ |
420 | link = prtd->ram_link = edma_alloc_slot( | 418 | ret = prtd->ram_link = edma_alloc_slot( |
421 | EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); | 419 | EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); |
422 | if (link < 0) | 420 | if (ret < 0) |
423 | goto exit2; | 421 | goto exit2; |
424 | 422 | ||
425 | link = prtd->asp_link[1] = edma_alloc_slot( | 423 | ret = prtd->asp_link[1] = edma_alloc_slot( |
426 | EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); | 424 | EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); |
427 | if (link < 0) | 425 | if (ret < 0) |
428 | goto exit3; | 426 | goto exit3; |
429 | 427 | ||
430 | prtd->ram_link2 = -1; | 428 | prtd->ram_link2 = -1; |
431 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 429 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
432 | link = prtd->ram_link2 = edma_alloc_slot( | 430 | ret = prtd->ram_link2 = edma_alloc_slot( |
433 | EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); | 431 | EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); |
434 | if (link < 0) | 432 | if (ret < 0) |
435 | goto exit4; | 433 | goto exit4; |
436 | } | 434 | } |
437 | /* circle ping-pong buffers */ | 435 | /* circle ping-pong buffers */ |
@@ -448,36 +446,33 @@ static int request_ping_pong(struct snd_pcm_substream *substream, | |||
448 | asp_dst_ping = iram_dma->addr; | 446 | asp_dst_ping = iram_dma->addr; |
449 | } | 447 | } |
450 | /* ping */ | 448 | /* ping */ |
451 | link = prtd->asp_link[0]; | 449 | edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT); |
452 | edma_set_src(link, asp_src_ping, INCR, W16BIT); | 450 | edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT); |
453 | edma_set_dest(link, asp_dst_ping, INCR, W16BIT); | 451 | edma_set_src_index(prtd->asp_link[0], 0, 0); |
454 | edma_set_src_index(link, 0, 0); | 452 | edma_set_dest_index(prtd->asp_link[0], 0, 0); |
455 | edma_set_dest_index(link, 0, 0); | ||
456 | 453 | ||
457 | edma_read_slot(link, &prtd->asp_params); | 454 | edma_read_slot(prtd->asp_link[0], &prtd->asp_params); |
458 | prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); | 455 | prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); |
459 | prtd->asp_params.opt |= TCCHEN | | 456 | prtd->asp_params.opt |= TCCHEN | |
460 | EDMA_TCC(prtd->ram_channel & 0x3f); | 457 | EDMA_TCC(prtd->ram_channel & 0x3f); |
461 | edma_write_slot(link, &prtd->asp_params); | 458 | edma_write_slot(prtd->asp_link[0], &prtd->asp_params); |
462 | 459 | ||
463 | /* pong */ | 460 | /* pong */ |
464 | link = prtd->asp_link[1]; | 461 | edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT); |
465 | edma_set_src(link, asp_src_ping, INCR, W16BIT); | 462 | edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT); |
466 | edma_set_dest(link, asp_dst_ping, INCR, W16BIT); | 463 | edma_set_src_index(prtd->asp_link[1], 0, 0); |
467 | edma_set_src_index(link, 0, 0); | 464 | edma_set_dest_index(prtd->asp_link[1], 0, 0); |
468 | edma_set_dest_index(link, 0, 0); | ||
469 | 465 | ||
470 | edma_read_slot(link, &prtd->asp_params); | 466 | edma_read_slot(prtd->asp_link[1], &prtd->asp_params); |
471 | prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); | 467 | prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); |
472 | /* interrupt after every pong completion */ | 468 | /* interrupt after every pong completion */ |
473 | prtd->asp_params.opt |= TCINTEN | TCCHEN | | 469 | prtd->asp_params.opt |= TCINTEN | TCCHEN | |
474 | EDMA_TCC(prtd->ram_channel & 0x3f); | 470 | EDMA_TCC(prtd->ram_channel & 0x3f); |
475 | edma_write_slot(link, &prtd->asp_params); | 471 | edma_write_slot(prtd->asp_link[1], &prtd->asp_params); |
476 | 472 | ||
477 | /* ram */ | 473 | /* ram */ |
478 | link = prtd->ram_link; | 474 | edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT); |
479 | edma_set_src(link, iram_dma->addr, INCR, W32BIT); | 475 | edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT); |
480 | edma_set_dest(link, iram_dma->addr, INCR, W32BIT); | ||
481 | pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," | 476 | pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," |
482 | "for asp:%u %u %u\n", __func__, | 477 | "for asp:%u %u %u\n", __func__, |
483 | prtd->ram_channel, prtd->ram_link, prtd->ram_link2, | 478 | prtd->ram_channel, prtd->ram_link, prtd->ram_link2, |
@@ -494,7 +489,7 @@ exit2: | |||
494 | edma_free_channel(prtd->ram_channel); | 489 | edma_free_channel(prtd->ram_channel); |
495 | prtd->ram_channel = -1; | 490 | prtd->ram_channel = -1; |
496 | exit1: | 491 | exit1: |
497 | return link; | 492 | return ret; |
498 | } | 493 | } |
499 | 494 | ||
500 | static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) | 495 | static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) |
@@ -502,22 +497,22 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) | |||
502 | struct snd_dma_buffer *iram_dma; | 497 | struct snd_dma_buffer *iram_dma; |
503 | struct davinci_runtime_data *prtd = substream->runtime->private_data; | 498 | struct davinci_runtime_data *prtd = substream->runtime->private_data; |
504 | struct davinci_pcm_dma_params *params = prtd->params; | 499 | struct davinci_pcm_dma_params *params = prtd->params; |
505 | int link; | 500 | int ret; |
506 | 501 | ||
507 | if (!params) | 502 | if (!params) |
508 | return -ENODEV; | 503 | return -ENODEV; |
509 | 504 | ||
510 | /* Request asp master DMA channel */ | 505 | /* Request asp master DMA channel */ |
511 | link = prtd->asp_channel = edma_alloc_channel(params->channel, | 506 | ret = prtd->asp_channel = edma_alloc_channel(params->channel, |
512 | davinci_pcm_dma_irq, substream, | 507 | davinci_pcm_dma_irq, substream, |
513 | prtd->params->asp_chan_q); | 508 | prtd->params->asp_chan_q); |
514 | if (link < 0) | 509 | if (ret < 0) |
515 | goto exit1; | 510 | goto exit1; |
516 | 511 | ||
517 | /* Request asp link channels */ | 512 | /* Request asp link channels */ |
518 | link = prtd->asp_link[0] = edma_alloc_slot( | 513 | ret = prtd->asp_link[0] = edma_alloc_slot( |
519 | EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); | 514 | EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); |
520 | if (link < 0) | 515 | if (ret < 0) |
521 | goto exit2; | 516 | goto exit2; |
522 | 517 | ||
523 | iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; | 518 | iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; |
@@ -537,17 +532,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) | |||
537 | * the buffer and its length (ccnt) ... use it as a template | 532 | * the buffer and its length (ccnt) ... use it as a template |
538 | * so davinci_pcm_enqueue_dma() takes less time in IRQ. | 533 | * so davinci_pcm_enqueue_dma() takes less time in IRQ. |
539 | */ | 534 | */ |
540 | edma_read_slot(link, &prtd->asp_params); | 535 | edma_read_slot(prtd->asp_link[0], &prtd->asp_params); |
541 | prtd->asp_params.opt |= TCINTEN | | 536 | prtd->asp_params.opt |= TCINTEN | |
542 | EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); | 537 | EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); |
543 | prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5; | 538 | prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5; |
544 | edma_write_slot(link, &prtd->asp_params); | 539 | edma_write_slot(prtd->asp_link[0], &prtd->asp_params); |
545 | return 0; | 540 | return 0; |
546 | exit2: | 541 | exit2: |
547 | edma_free_channel(prtd->asp_channel); | 542 | edma_free_channel(prtd->asp_channel); |
548 | prtd->asp_channel = -1; | 543 | prtd->asp_channel = -1; |
549 | exit1: | 544 | exit1: |
550 | return link; | 545 | return ret; |
551 | } | 546 | } |
552 | 547 | ||
553 | static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 548 | static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |