diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c | 114 |
1 files changed, 95 insertions, 19 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c index 73bd9fef14..c29c4b2930 100644 --- a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c | |||
@@ -25,69 +25,145 @@ | |||
25 | #include "file.h" | 25 | #include "file.h" |
26 | #include "mmu-imx31.h" | 26 | #include "mmu-imx31.h" |
27 | 27 | ||
28 | static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ | ||
29 | |||
28 | void fiq_handler(void) __attribute__((naked)); | 30 | void fiq_handler(void) __attribute__((naked)); |
29 | 31 | ||
32 | /* Implement separately on recording and playback - simply disable the | ||
33 | specific DMA interrupt. Disable the FIQ itself only temporarily to sync | ||
34 | with the DMA interrupt and restore its previous state. The pcm routines | ||
35 | will call the lockout first then call into these low-level routines. */ | ||
36 | struct dma_lock | ||
37 | { | ||
38 | int locked; | ||
39 | unsigned long state; | ||
40 | }; | ||
41 | |||
42 | static struct dma_play_lock = | ||
43 | { | ||
44 | .locked = 0, | ||
45 | .state = 0, /* Initialize this as disabled */ | ||
46 | }; | ||
47 | |||
48 | void pcm_play_lock(void) | ||
49 | { | ||
50 | int status = set_fiq_status(FIQ_DISABLED); | ||
51 | if (++dma_play_lock.locked == 1) | ||
52 | ; /* Mask the DMA interrupt */ | ||
53 | set_fiq_status(status); | ||
54 | } | ||
55 | |||
56 | void pcm_play_unlock(void) | ||
57 | { | ||
58 | int status = set_fiq_status(FIQ_DISABLED); | ||
59 | if (--dma_play_lock.locked == 0) | ||
60 | ; /* Unmask the DMA interrupt if enabled */ | ||
61 | set_fiq_status(status); | ||
62 | } | ||
63 | |||
30 | static void _pcm_apply_settings(void) | 64 | static void _pcm_apply_settings(void) |
31 | { | 65 | { |
66 | if (pcm_freq != pcm_curr_sampr) | ||
67 | { | ||
68 | pcm_curr_sampr = pcm_freq; | ||
69 | /* Change hardware sample rate */ | ||
70 | /* */ | ||
71 | } | ||
32 | } | 72 | } |
33 | 73 | ||
34 | void pcm_apply_settings(void) | 74 | void pcm_apply_settings(void) |
35 | { | 75 | { |
76 | /* Lockout FIQ and sync the hardware to the settings */ | ||
77 | int oldstatus = set_fiq_status(FIQ_DISABLED); | ||
78 | _pcm_apply_settings(); | ||
79 | set_fiq_status(oldstatus); | ||
36 | } | 80 | } |
37 | 81 | ||
38 | void pcm_init(void) | 82 | void pcm_play_dma_init(void) |
39 | { | 83 | { |
84 | pcm_set_frequency(SAMPR_44); | ||
85 | |||
86 | #if 0 | ||
87 | /* Do basic init enable output in pcm_postinit if popping is a | ||
88 | problem at boot to enable a lenghy delay and let the boot | ||
89 | process continue */ | ||
90 | audiohw_init(); | ||
91 | #endif | ||
40 | } | 92 | } |
41 | 93 | ||
42 | void pcm_postinit(void) | 94 | void pcm_postinit(void) |
43 | { | 95 | { |
44 | } | 96 | } |
45 | 97 | ||
46 | void pcm_play_dma_start(const void *addr, size_t size) | 98 | /* Connect the DMA and start filling the FIFO */ |
99 | static void play_start_pcm(void) | ||
47 | { | 100 | { |
48 | (void)addr; | 101 | #if 0 |
49 | (void)size; | 102 | /* unmask DMA interrupt when unlocking */ |
103 | dma_play_lock.state = 0; /* Set to allow pcm_play_unlock to unmask interrupt */ | ||
104 | #endif | ||
50 | } | 105 | } |
51 | 106 | ||
52 | static void pcm_play_dma_stop_fiq(void) | 107 | /* Disconnect the DMA and wait for the FIFO to clear */ |
108 | static void play_stop_pcm(void) | ||
53 | { | 109 | { |
110 | #if 0 | ||
111 | /* Keep interrupt masked when unlocking */ | ||
112 | dma_play_lock.state = 0; /* Set to keep pcm_play_unlock from unmasking interrupt */ | ||
113 | #endif | ||
54 | } | 114 | } |
55 | 115 | ||
56 | void fiq_handler(void) | 116 | void pcm_play_dma_start(const void *addr, size_t size) |
57 | { | 117 | { |
118 | (void)addr; | ||
119 | (void)size; | ||
58 | } | 120 | } |
59 | 121 | ||
60 | /* Disconnect the DMA and wait for the FIFO to clear */ | ||
61 | void pcm_play_dma_stop(void) | 122 | void pcm_play_dma_stop(void) |
62 | { | 123 | { |
124 | play_stop_pcm(); | ||
63 | } | 125 | } |
64 | 126 | ||
65 | void pcm_play_pause_pause(void) | 127 | void pcm_play_dma_pause(bool pause) |
66 | { | 128 | { |
129 | if (pause) | ||
130 | { | ||
131 | play_stop_pcm(); | ||
132 | } | ||
133 | else | ||
134 | { | ||
135 | play_start_pcm(); | ||
136 | } | ||
67 | } | 137 | } |
68 | 138 | ||
69 | void pcm_play_pause_unpause(void) | 139 | /* Get more samples to play out - call pcm_play_dma_stop and |
140 | pcm_play_dma_stopped_callback if the data runs out */ | ||
141 | void fiq_handler(void) | ||
70 | { | 142 | { |
143 | #if 0 | ||
144 | /* Callback missing or no more DMA to do */ | ||
145 | pcm_play_dma_stop(); | ||
146 | pcm_play_dma_stopped_callback(); | ||
147 | #endif | ||
71 | } | 148 | } |
72 | 149 | ||
150 | /* Set the pcm frequency hardware will use when play is next started or | ||
151 | when pcm_apply_settings is called. Do not apply the setting to the | ||
152 | hardware here but simply cache it. */ | ||
73 | void pcm_set_frequency(unsigned int frequency) | 153 | void pcm_set_frequency(unsigned int frequency) |
74 | { | 154 | { |
75 | (void)frequency; | 155 | pcm_freq = frequency; |
76 | } | 156 | } |
77 | 157 | ||
158 | /* Return the number of bytes waiting - full L-R sample pairs only */ | ||
78 | size_t pcm_get_bytes_waiting(void) | 159 | size_t pcm_get_bytes_waiting(void) |
79 | { | 160 | { |
80 | } | 161 | } |
81 | 162 | ||
82 | void pcm_mute(bool mute) | 163 | /* Return a pointer to the samples and the number of them in *count */ |
164 | const void * pcm_play_dma_get_peak_buffer(int *count) | ||
83 | { | 165 | { |
166 | (void)count; | ||
84 | } | 167 | } |
85 | 168 | ||
86 | /** | 169 | /* Any recording functionality should be implemented similarly */ |
87 | * Return playback peaks - Peaks ahead in the DMA buffer based upon the | ||
88 | * calling period to attempt to compensate for | ||
89 | * delay. | ||
90 | */ | ||
91 | void pcm_calculate_peaks(int *left, int *right) | ||
92 | { | ||
93 | } | ||