diff options
Diffstat (limited to 'firmware/target/arm/imx233/pcm-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/pcm-imx233.c | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/firmware/target/arm/imx233/pcm-imx233.c b/firmware/target/arm/imx233/pcm-imx233.c index 6dd678f506..fa13f9979e 100644 --- a/firmware/target/arm/imx233/pcm-imx233.c +++ b/firmware/target/arm/imx233/pcm-imx233.c | |||
@@ -22,32 +22,79 @@ | |||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include "audiohw.h" | 23 | #include "audiohw.h" |
24 | #include "pcm.h" | 24 | #include "pcm.h" |
25 | #include "audioin-imx233.h" | 25 | #include "dma-imx233.h" |
26 | #include "pcm-internal.h" | ||
26 | #include "audioout-imx233.h" | 27 | #include "audioout-imx233.h" |
27 | 28 | ||
29 | static int locked = 0; | ||
30 | static struct apb_dma_command_t dac_dma; | ||
31 | static bool pcm_freezed = false; | ||
32 | |||
33 | /** | ||
34 | * WARNING ! | ||
35 | * Never reset the dma channel, otherwise it will halt the DAC for some reason | ||
36 | * */ | ||
37 | |||
38 | static void play(const void *addr, size_t size) | ||
39 | { | ||
40 | dac_dma.next = NULL; | ||
41 | dac_dma.buffer = (void *)addr; | ||
42 | dac_dma.cmd = HW_APB_CHx_CMD__COMMAND__READ | | ||
43 | HW_APB_CHx_CMD__IRQONCMPLT | | ||
44 | HW_APB_CHx_CMD__SEMAPHORE | | ||
45 | size << HW_APB_CHx_CMD__XFER_COUNT_BP; | ||
46 | /* dma subsystem will make sure cached stuff is written to memory */ | ||
47 | imx233_dma_start_command(APB_AUDIO_DAC, &dac_dma); | ||
48 | } | ||
49 | |||
50 | void INT_DAC_DMA(void) | ||
51 | { | ||
52 | void *start; | ||
53 | size_t size; | ||
54 | |||
55 | pcm_play_get_more_callback(&start, &size); | ||
56 | |||
57 | if(size != 0) | ||
58 | { | ||
59 | play(start, size); | ||
60 | pcm_play_dma_started_callback(); | ||
61 | } | ||
62 | |||
63 | imx233_dma_clear_channel_interrupt(APB_AUDIO_DAC); | ||
64 | } | ||
65 | |||
66 | void INT_DAC_ERROR(void) | ||
67 | { | ||
68 | } | ||
69 | |||
28 | void pcm_play_lock(void) | 70 | void pcm_play_lock(void) |
29 | { | 71 | { |
72 | if(locked++ == 0) | ||
73 | imx233_dma_enable_channel_interrupt(APB_AUDIO_DAC, false); | ||
30 | } | 74 | } |
31 | 75 | ||
32 | void pcm_play_unlock(void) | 76 | void pcm_play_unlock(void) |
33 | { | 77 | { |
78 | if(--locked == 0) | ||
79 | imx233_dma_enable_channel_interrupt(APB_AUDIO_DAC, true); | ||
34 | } | 80 | } |
35 | 81 | ||
36 | void pcm_play_dma_stop(void) | 82 | void pcm_play_dma_stop(void) |
37 | { | 83 | { |
84 | |||
38 | } | 85 | } |
39 | 86 | ||
40 | void pcm_play_dma_start(const void *addr, size_t size) | 87 | void pcm_play_dma_start(const void *addr, size_t size) |
41 | { | 88 | { |
42 | pcm_play_dma_stop(); | 89 | pcm_play_dma_stop(); |
43 | 90 | ||
44 | (void) addr; | 91 | play(addr, size); |
45 | (void) size; | ||
46 | } | 92 | } |
47 | 93 | ||
48 | void pcm_play_dma_pause(bool pause) | 94 | void pcm_play_dma_pause(bool pause) |
49 | { | 95 | { |
50 | (void) pause; | 96 | imx233_dma_freeze_channel(APB_AUDIO_DAC, pause); |
97 | pcm_freezed = pause; | ||
51 | } | 98 | } |
52 | 99 | ||
53 | void pcm_play_dma_init(void) | 100 | void pcm_play_dma_init(void) |
@@ -58,22 +105,31 @@ void pcm_play_dma_init(void) | |||
58 | void pcm_play_dma_postinit(void) | 105 | void pcm_play_dma_postinit(void) |
59 | { | 106 | { |
60 | audiohw_postinit(); | 107 | audiohw_postinit(); |
108 | imx233_enable_interrupt(INT_SRC_DAC_DMA, true); | ||
109 | imx233_enable_interrupt(INT_SRC_DAC_ERROR, true); | ||
110 | imx233_dma_enable_channel_interrupt(APB_AUDIO_DAC, true); | ||
61 | } | 111 | } |
62 | 112 | ||
63 | void pcm_dma_apply_settings(void) | 113 | void pcm_dma_apply_settings(void) |
64 | { | 114 | { |
65 | return; | 115 | audiohw_set_frequency(pcm_fsel); |
66 | } | 116 | } |
67 | 117 | ||
68 | size_t pcm_get_bytes_waiting(void) | 118 | size_t pcm_get_bytes_waiting(void) |
69 | { | 119 | { |
70 | return 0; | 120 | struct imx233_dma_info_t info = imx233_dma_get_info(APB_AUDIO_DAC, DMA_INFO_AHB_BYTES); |
121 | return info.ahb_bytes; | ||
71 | } | 122 | } |
72 | 123 | ||
73 | const void *pcm_play_dma_get_peak_buffer(int *count) | 124 | const void *pcm_play_dma_get_peak_buffer(int *count) |
74 | { | 125 | { |
75 | (void) count; | 126 | if(!pcm_freezed) |
76 | return NULL; | 127 | imx233_dma_freeze_channel(APB_AUDIO_DAC, true); |
128 | struct imx233_dma_info_t info = imx233_dma_get_info(APB_AUDIO_DAC, DMA_INFO_AHB_BYTES | DMA_INFO_BAR); | ||
129 | if(!pcm_freezed) | ||
130 | imx233_dma_freeze_channel(APB_AUDIO_DAC, false); | ||
131 | *count = info.ahb_bytes; | ||
132 | return (void *)info.bar; | ||
77 | } | 133 | } |
78 | 134 | ||
79 | void pcm_rec_lock(void) | 135 | void pcm_rec_lock(void) |