diff options
Diffstat (limited to 'firmware/target/coldfire')
-rw-r--r-- | firmware/target/coldfire/pcm-coldfire.c | 4 | ||||
-rw-r--r-- | firmware/target/coldfire/pcm-mixer-coldfire.c | 134 |
2 files changed, 138 insertions, 0 deletions
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c index a06542c31f..85eeaec815 100644 --- a/firmware/target/coldfire/pcm-coldfire.c +++ b/firmware/target/coldfire/pcm-coldfire.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #if defined(HAVE_SPDIF_REC) || defined(HAVE_SPDIF_OUT) | 28 | #if defined(HAVE_SPDIF_REC) || defined(HAVE_SPDIF_OUT) |
29 | #include "spdif.h" | 29 | #include "spdif.h" |
30 | #endif | 30 | #endif |
31 | #include "pcm-internal.h" | ||
31 | 32 | ||
32 | #define IIS_PLAY_DEFPARM ( (freq_ent[FPARM_CLOCKSEL] << 12) | \ | 33 | #define IIS_PLAY_DEFPARM ( (freq_ent[FPARM_CLOCKSEL] << 12) | \ |
33 | (IIS_PLAY & (7 << 8)) | \ | 34 | (IIS_PLAY & (7 << 8)) | \ |
@@ -318,6 +319,9 @@ void DMA0(void) | |||
318 | SAR0 = (unsigned long)start; /* Source address */ | 319 | SAR0 = (unsigned long)start; /* Source address */ |
319 | BCR0 = size; /* Bytes to transfer */ | 320 | BCR0 = size; /* Bytes to transfer */ |
320 | or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */ | 321 | or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */ |
322 | |||
323 | /* Call buffer callback */ | ||
324 | pcm_play_dma_started_callback(); | ||
321 | } | 325 | } |
322 | /* else inished playing */ | 326 | /* else inished playing */ |
323 | } /* DMA0 */ | 327 | } /* DMA0 */ |
diff --git a/firmware/target/coldfire/pcm-mixer-coldfire.c b/firmware/target/coldfire/pcm-mixer-coldfire.c new file mode 100644 index 0000000000..d8318fffaf --- /dev/null +++ b/firmware/target/coldfire/pcm-mixer-coldfire.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2011 by Michael Sevakis | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #define MIXER_OPTIMIZED_MIX_SAMPLES | ||
23 | #define MIXER_OPTIMIZED_WRITE_SAMPLES | ||
24 | static struct emac_context | ||
25 | { | ||
26 | unsigned long r[4]; | ||
27 | } emac_context IBSS_ATTR; | ||
28 | |||
29 | /* Save emac context affected in ISR */ | ||
30 | static FORCE_INLINE void save_emac_context(void) | ||
31 | { | ||
32 | asm volatile ( | ||
33 | "move.l %%macsr, %%d0 \n" | ||
34 | "move.l %%accext01, %%d1 \n" | ||
35 | "movclr.l %%acc0, %%a0 \n" | ||
36 | "movclr.l %%acc1, %%a1 \n" | ||
37 | "movem.l %%d0-%%d1/%%a0-%%a1, (%0) \n" | ||
38 | : | ||
39 | : "a"(&emac_context) | ||
40 | : "d0", "d1", "a0", "a1"); | ||
41 | } | ||
42 | |||
43 | /* Restore emac context affected in ISR */ | ||
44 | static FORCE_INLINE void restore_emac_context(void) | ||
45 | { | ||
46 | asm volatile ( | ||
47 | "movem.l (%0), %%d0-%%d1/%%a0-%%a1 \n" | ||
48 | "move.l %%a1, %%acc1 \n" | ||
49 | "move.l %%a0, %%acc0 \n" | ||
50 | "move.l %%d1, %%accext01 \n" | ||
51 | "move.l %%d0, %%macsr \n" | ||
52 | : | ||
53 | : "a"(&emac_context) | ||
54 | : "d0", "d1", "a0", "a1"); | ||
55 | } | ||
56 | |||
57 | /* Mix channels' samples and apply gain factors */ | ||
58 | static FORCE_INLINE void mix_samples(void *out, | ||
59 | void *src0, | ||
60 | int32_t src0_amp, | ||
61 | void *src1, | ||
62 | int32_t src1_amp, | ||
63 | size_t size) | ||
64 | { | ||
65 | uint32_t s0, s1, s2, s3; | ||
66 | save_emac_context(); | ||
67 | coldfire_set_macsr(EMAC_ROUND | EMAC_SATURATE); | ||
68 | |||
69 | asm volatile ( | ||
70 | "move.l (%1)+, %5 \n" | ||
71 | "1: \n" | ||
72 | "movea.w %5, %4 \n" | ||
73 | "asr.l %10, %5 \n" | ||
74 | "mac.l %4, %8, %%acc0 \n" | ||
75 | "mac.l %5, %8, (%2)+, %5, %%acc1 \n" | ||
76 | "movea.w %5, %4 \n" | ||
77 | "asr.l %10, %5 \n" | ||
78 | "mac.l %4, %9, %%acc0 \n" | ||
79 | "mac.l %5, %9, (%1)+, %5, %%acc1 \n" | ||
80 | "movclr.l %%acc0, %6 \n" | ||
81 | "movclr.l %%acc1, %7 \n" | ||
82 | "swap.w %6 \n" | ||
83 | "move.w %6, %7 \n" | ||
84 | "move.l %7, (%0)+ \n" | ||
85 | "subq.l #4, %3 \n" | ||
86 | "bhi.b 1b \n" | ||
87 | : "+a"(out), "+a"(src0), "+a"(src1), "+d"(size), | ||
88 | "=&a"(s0), "=&d"(s1), "=&d"(s2), "=&d"(s3) | ||
89 | : "r"(src0_amp), "r"(src1_amp), "d"(16) | ||
90 | ); | ||
91 | |||
92 | restore_emac_context(); | ||
93 | } | ||
94 | |||
95 | /* Write channel's samples and apply gain factor */ | ||
96 | static FORCE_INLINE void write_samples(void *out, | ||
97 | void *src, | ||
98 | int32_t amp, | ||
99 | size_t size) | ||
100 | { | ||
101 | if (LIKELY(amp == MIX_AMP_UNITY)) | ||
102 | { | ||
103 | /* Channel is unity amplitude */ | ||
104 | memcpy(out, src, size); | ||
105 | } | ||
106 | else | ||
107 | { | ||
108 | /* Channel needs amplitude cut */ | ||
109 | uint32_t s0, s1, s2, s3; | ||
110 | save_emac_context(); | ||
111 | coldfire_set_macsr(EMAC_ROUND | EMAC_SATURATE); | ||
112 | |||
113 | asm volatile ( | ||
114 | "move.l (%1)+, %4 \n" | ||
115 | "1: \n" | ||
116 | "movea.w %4, %3 \n" | ||
117 | "asr.l %8, %4 \n" | ||
118 | "mac.l %3, %7, %%acc0 \n" | ||
119 | "mac.l %4, %7, (%1)+, %4, %%acc1 \n" | ||
120 | "movclr.l %%acc0, %5 \n" | ||
121 | "movclr.l %%acc1, %6 \n" | ||
122 | "swap.w %5 \n" | ||
123 | "move.w %5, %6 \n" | ||
124 | "move.l %6, (%0)+ \n" | ||
125 | "subq.l #4, %2 \n" | ||
126 | "bhi.b 1b \n" | ||
127 | : "+a"(out), "+a"(src), "+d"(size), | ||
128 | "=&a"(s0), "=&d"(s1), "=&d"(s2), "=&d"(s3) | ||
129 | : "r"(amp), "d"(16) | ||
130 | ); | ||
131 | |||
132 | restore_emac_context(); | ||
133 | } | ||
134 | } | ||