aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/davinci')
-rw-r--r--sound/soc/davinci/davinci-pcm.c154
-rw-r--r--sound/soc/davinci/davinci-vcif.c9
2 files changed, 94 insertions, 69 deletions
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 9d35b8c1a62..a49e667373b 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -46,11 +46,28 @@ static void print_buf_info(int slot, char *name)
46} 46}
47#endif 47#endif
48 48
49#define DAVINCI_PCM_FMTBITS (\
50 SNDRV_PCM_FMTBIT_S8 |\
51 SNDRV_PCM_FMTBIT_U8 |\
52 SNDRV_PCM_FMTBIT_S16_LE |\
53 SNDRV_PCM_FMTBIT_S16_BE |\
54 SNDRV_PCM_FMTBIT_U16_LE |\
55 SNDRV_PCM_FMTBIT_U16_BE |\
56 SNDRV_PCM_FMTBIT_S24_LE |\
57 SNDRV_PCM_FMTBIT_S24_BE |\
58 SNDRV_PCM_FMTBIT_U24_LE |\
59 SNDRV_PCM_FMTBIT_U24_BE |\
60 SNDRV_PCM_FMTBIT_S32_LE |\
61 SNDRV_PCM_FMTBIT_S32_BE |\
62 SNDRV_PCM_FMTBIT_U32_LE |\
63 SNDRV_PCM_FMTBIT_U32_BE)
64
49static struct snd_pcm_hardware pcm_hardware_playback = { 65static struct snd_pcm_hardware pcm_hardware_playback = {
50 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 66 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
51 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 67 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
52 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), 68 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME|
53 .formats = (SNDRV_PCM_FMTBIT_S16_LE), 69 SNDRV_PCM_INFO_BATCH),
70 .formats = DAVINCI_PCM_FMTBITS,
54 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 71 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
55 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | 72 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
56 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 73 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
@@ -59,7 +76,7 @@ static struct snd_pcm_hardware pcm_hardware_playback = {
59 .rate_min = 8000, 76 .rate_min = 8000,
60 .rate_max = 96000, 77 .rate_max = 96000,
61 .channels_min = 2, 78 .channels_min = 2,
62 .channels_max = 2, 79 .channels_max = 384,
63 .buffer_bytes_max = 128 * 1024, 80 .buffer_bytes_max = 128 * 1024,
64 .period_bytes_min = 32, 81 .period_bytes_min = 32,
65 .period_bytes_max = 8 * 1024, 82 .period_bytes_max = 8 * 1024,
@@ -71,8 +88,9 @@ static struct snd_pcm_hardware pcm_hardware_playback = {
71static struct snd_pcm_hardware pcm_hardware_capture = { 88static struct snd_pcm_hardware pcm_hardware_capture = {
72 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 89 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
73 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 90 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
74 SNDRV_PCM_INFO_PAUSE), 91 SNDRV_PCM_INFO_PAUSE |
75 .formats = (SNDRV_PCM_FMTBIT_S16_LE), 92 SNDRV_PCM_INFO_BATCH),
93 .formats = DAVINCI_PCM_FMTBITS,
76 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 94 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
77 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | 95 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
78 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 96 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
@@ -81,7 +99,7 @@ static struct snd_pcm_hardware pcm_hardware_capture = {
81 .rate_min = 8000, 99 .rate_min = 8000,
82 .rate_max = 96000, 100 .rate_max = 96000,
83 .channels_min = 2, 101 .channels_min = 2,
84 .channels_max = 2, 102 .channels_max = 384,
85 .buffer_bytes_max = 128 * 1024, 103 .buffer_bytes_max = 128 * 1024,
86 .period_bytes_min = 32, 104 .period_bytes_min = 32,
87 .period_bytes_max = 8 * 1024, 105 .period_bytes_max = 8 * 1024,
@@ -139,6 +157,22 @@ struct davinci_runtime_data {
139 struct edmacc_param ram_params; 157 struct edmacc_param ram_params;
140}; 158};
141 159
160static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream)
161{
162 struct davinci_runtime_data *prtd = substream->runtime->private_data;
163 struct snd_pcm_runtime *runtime = substream->runtime;
164
165 prtd->period++;
166 if (unlikely(prtd->period >= runtime->periods))
167 prtd->period = 0;
168}
169
170static void davinci_pcm_period_reset(struct snd_pcm_substream *substream)
171{
172 struct davinci_runtime_data *prtd = substream->runtime->private_data;
173
174 prtd->period = 0;
175}
142/* 176/*
143 * Not used with ping/pong 177 * Not used with ping/pong
144 */ 178 */
@@ -199,10 +233,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
199 else 233 else
200 edma_set_transfer_params(link, acnt, fifo_level, count, 234 edma_set_transfer_params(link, acnt, fifo_level, count,
201 fifo_level, ABSYNC); 235 fifo_level, ABSYNC);
202
203 prtd->period++;
204 if (unlikely(prtd->period >= runtime->periods))
205 prtd->period = 0;
206} 236}
207 237
208static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) 238static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
@@ -217,12 +247,13 @@ static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
217 return; 247 return;
218 248
219 if (snd_pcm_running(substream)) { 249 if (snd_pcm_running(substream)) {
250 spin_lock(&prtd->lock);
220 if (prtd->ram_channel < 0) { 251 if (prtd->ram_channel < 0) {
221 /* No ping/pong must fix up link dma data*/ 252 /* No ping/pong must fix up link dma data*/
222 spin_lock(&prtd->lock);
223 davinci_pcm_enqueue_dma(substream); 253 davinci_pcm_enqueue_dma(substream);
224 spin_unlock(&prtd->lock);
225 } 254 }
255 davinci_pcm_period_elapsed(substream);
256 spin_unlock(&prtd->lock);
226 snd_pcm_period_elapsed(substream); 257 snd_pcm_period_elapsed(substream);
227 } 258 }
228} 259}
@@ -425,7 +456,8 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
425 456
426 edma_read_slot(link, &prtd->asp_params); 457 edma_read_slot(link, &prtd->asp_params);
427 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); 458 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
428 prtd->asp_params.opt |= TCCHEN | EDMA_TCC(prtd->ram_channel & 0x3f); 459 prtd->asp_params.opt |= TCCHEN |
460 EDMA_TCC(prtd->ram_channel & 0x3f);
429 edma_write_slot(link, &prtd->asp_params); 461 edma_write_slot(link, &prtd->asp_params);
430 462
431 /* pong */ 463 /* pong */
@@ -439,7 +471,7 @@ static int request_ping_pong(struct snd_pcm_substream *substream,
439 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); 471 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
440 /* interrupt after every pong completion */ 472 /* interrupt after every pong completion */
441 prtd->asp_params.opt |= TCINTEN | TCCHEN | 473 prtd->asp_params.opt |= TCINTEN | TCCHEN |
442 EDMA_TCC(EDMA_CHAN_SLOT(prtd->ram_channel)); 474 EDMA_TCC(prtd->ram_channel & 0x3f);
443 edma_write_slot(link, &prtd->asp_params); 475 edma_write_slot(link, &prtd->asp_params);
444 476
445 /* ram */ 477 /* ram */
@@ -527,6 +559,13 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
527 559
528 switch (cmd) { 560 switch (cmd) {
529 case SNDRV_PCM_TRIGGER_START: 561 case SNDRV_PCM_TRIGGER_START:
562 edma_start(prtd->asp_channel);
563 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
564 prtd->ram_channel >= 0) {
565 /* copy 1st iram buffer */
566 edma_start(prtd->ram_channel);
567 }
568 break;
530 case SNDRV_PCM_TRIGGER_RESUME: 569 case SNDRV_PCM_TRIGGER_RESUME:
531 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 570 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
532 edma_resume(prtd->asp_channel); 571 edma_resume(prtd->asp_channel);
@@ -550,6 +589,7 @@ static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
550{ 589{
551 struct davinci_runtime_data *prtd = substream->runtime->private_data; 590 struct davinci_runtime_data *prtd = substream->runtime->private_data;
552 591
592 davinci_pcm_period_reset(substream);
553 if (prtd->ram_channel >= 0) { 593 if (prtd->ram_channel >= 0) {
554 int ret = ping_pong_dma_setup(substream); 594 int ret = ping_pong_dma_setup(substream);
555 if (ret < 0) 595 if (ret < 0)
@@ -565,21 +605,31 @@ static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
565 print_buf_info(prtd->asp_link[0], "asp_link[0]"); 605 print_buf_info(prtd->asp_link[0], "asp_link[0]");
566 print_buf_info(prtd->asp_link[1], "asp_link[1]"); 606 print_buf_info(prtd->asp_link[1], "asp_link[1]");
567 607
568 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 608 /*
569 /* copy 1st iram buffer */ 609 * There is a phase offset of 2 periods between the position
570 edma_start(prtd->ram_channel); 610 * used by dma setup and the position reported in the pointer
571 } 611 * function.
572 edma_start(prtd->asp_channel); 612 *
613 * The phase offset, when not using ping-pong buffers, is due to
614 * the two consecutive calls to davinci_pcm_enqueue_dma() below.
615 *
616 * Whereas here, with ping-pong buffers, the phase is due to
617 * there being an entire buffer transfer complete before the
618 * first dma completion event triggers davinci_pcm_dma_irq().
619 */
620 davinci_pcm_period_elapsed(substream);
621 davinci_pcm_period_elapsed(substream);
622
573 return 0; 623 return 0;
574 } 624 }
575 prtd->period = 0;
576 davinci_pcm_enqueue_dma(substream); 625 davinci_pcm_enqueue_dma(substream);
626 davinci_pcm_period_elapsed(substream);
577 627
578 /* Copy self-linked parameter RAM entry into master channel */ 628 /* Copy self-linked parameter RAM entry into master channel */
579 edma_read_slot(prtd->asp_link[0], &prtd->asp_params); 629 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
580 edma_write_slot(prtd->asp_channel, &prtd->asp_params); 630 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
581 davinci_pcm_enqueue_dma(substream); 631 davinci_pcm_enqueue_dma(substream);
582 edma_start(prtd->asp_channel); 632 davinci_pcm_period_elapsed(substream);
583 633
584 return 0; 634 return 0;
585} 635}
@@ -591,51 +641,23 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream)
591 struct davinci_runtime_data *prtd = runtime->private_data; 641 struct davinci_runtime_data *prtd = runtime->private_data;
592 unsigned int offset; 642 unsigned int offset;
593 int asp_count; 643 int asp_count;
594 dma_addr_t asp_src, asp_dst; 644 unsigned int period_size = snd_pcm_lib_period_bytes(substream);
595 645
646 /*
647 * There is a phase offset of 2 periods between the position used by dma
648 * setup and the position reported in the pointer function. Either +2 in
649 * the dma setup or -2 here in the pointer function (with wrapping,
650 * both) accounts for this offset -- choose the latter since it makes
651 * the first-time setup clearer.
652 */
596 spin_lock(&prtd->lock); 653 spin_lock(&prtd->lock);
597 if (prtd->ram_channel >= 0) { 654 asp_count = prtd->period - 2;
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); 655 spin_unlock(&prtd->lock);
638 656
657 if (asp_count < 0)
658 asp_count += runtime->periods;
659 asp_count *= period_size;
660
639 offset = bytes_to_frames(runtime, asp_count); 661 offset = bytes_to_frames(runtime, asp_count);
640 if (offset >= runtime->buffer_size) 662 if (offset >= runtime->buffer_size)
641 offset = 0; 663 offset = 0;
@@ -811,9 +833,11 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
811 833
812static u64 davinci_pcm_dmamask = 0xffffffff; 834static u64 davinci_pcm_dmamask = 0xffffffff;
813 835
814static int davinci_pcm_new(struct snd_card *card, 836static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd)
815 struct snd_soc_dai *dai, struct snd_pcm *pcm)
816{ 837{
838 struct snd_card *card = rtd->card->snd_card;
839 struct snd_soc_dai *dai = rtd->cpu_dai;
840 struct snd_pcm *pcm = rtd->pcm;
817 int ret; 841 int ret;
818 842
819 if (!card->dev->dma_mask) 843 if (!card->dev->dma_mask)
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index 9259f1f3489..1f11525d97e 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -62,9 +62,9 @@ static void davinci_vcif_start(struct snd_pcm_substream *substream)
62 w = readl(davinci_vc->base + DAVINCI_VC_CTRL); 62 w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
63 63
64 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 64 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
65 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1); 65 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0);
66 else 66 else
67 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1); 67 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0);
68 68
69 writel(w, davinci_vc->base + DAVINCI_VC_CTRL); 69 writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
70} 70}
@@ -80,9 +80,9 @@ static void davinci_vcif_stop(struct snd_pcm_substream *substream)
80 /* Reset transmitter/receiver and sample rate/frame sync generators */ 80 /* Reset transmitter/receiver and sample rate/frame sync generators */
81 w = readl(davinci_vc->base + DAVINCI_VC_CTRL); 81 w = readl(davinci_vc->base + DAVINCI_VC_CTRL);
82 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 82 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
83 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0); 83 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1);
84 else 84 else
85 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0); 85 MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1);
86 86
87 writel(w, davinci_vc->base + DAVINCI_VC_CTRL); 87 writel(w, davinci_vc->base + DAVINCI_VC_CTRL);
88} 88}
@@ -159,6 +159,7 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
159 case SNDRV_PCM_TRIGGER_RESUME: 159 case SNDRV_PCM_TRIGGER_RESUME:
160 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 160 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
161 davinci_vcif_start(substream); 161 davinci_vcif_start(substream);
162 break;
162 case SNDRV_PCM_TRIGGER_STOP: 163 case SNDRV_PCM_TRIGGER_STOP:
163 case SNDRV_PCM_TRIGGER_SUSPEND: 164 case SNDRV_PCM_TRIGGER_SUSPEND:
164 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 165 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: