diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2010-05-24 16:42:32 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2010-05-24 16:42:32 +0000 |
commit | d56999890f2aacf197d9ae4383313271499509a9 (patch) | |
tree | 76a0177e2cf19bb15a065199b812ef20158422e1 | |
parent | 6688988ec42aa2254c8e370ec1932033a258b6fa (diff) | |
download | rockbox-d56999890f2aacf197d9ae4383313271499509a9.tar.gz rockbox-d56999890f2aacf197d9ae4383313271499509a9.zip |
Make PCM->driver interface about as simple as it will get. Registered callback, zero data, alignment and stops are handled entirely inside pcm.c; driver merely calls fixed pcm.c callback. Remove pcm_record_more and do it just like playback; the original reason behind it isn't very practical in general. Everything checks out on supported targets. There wer some compat changes I can't check out on many unsupoorted but if there's a problem it will be a minor oops. Plugins become incompatible due to recording tweak-- full update. Sorted API.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26253 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugin.c | 30 | ||||
-rw-r--r-- | apps/plugin.h | 46 | ||||
-rw-r--r-- | apps/plugins/pitch_detector.c | 7 | ||||
-rw-r--r-- | apps/recorder/pcm_record.c | 10 | ||||
-rw-r--r-- | apps/voice_thread.c | 4 | ||||
-rw-r--r-- | firmware/export/pcm.h | 30 | ||||
-rw-r--r-- | firmware/pcm.c | 150 | ||||
-rw-r--r-- | firmware/target/arm/as3525/pcm-as3525.c | 43 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c | 81 | ||||
-rw-r--r-- | firmware/target/arm/pcm-pp.c | 83 | ||||
-rw-r--r-- | firmware/target/arm/pcm-telechips.c | 43 | ||||
-rw-r--r-- | firmware/target/arm/pnx0101/pcm-pnx0101.c | 7 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c | 34 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c | 34 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/pcm-s5l8700.c | 22 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c | 15 | ||||
-rw-r--r-- | firmware/target/coldfire/pcm-coldfire.c | 63 | ||||
-rw-r--r-- | firmware/target/hosted/sdl/pcm-sdl.c | 18 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c | 21 |
19 files changed, 279 insertions, 462 deletions
diff --git a/apps/plugin.c b/apps/plugin.c index b45220acdb..83f27ea249 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -177,6 +177,9 @@ static const struct plugin_api rockbox_api = { | |||
177 | &button_queue, | 177 | &button_queue, |
178 | #endif | 178 | #endif |
179 | bidi_l2v, | 179 | bidi_l2v, |
180 | #ifdef HAVE_LCD_BITMAP | ||
181 | is_diacritic, | ||
182 | #endif | ||
180 | font_get_bits, | 183 | font_get_bits, |
181 | font_load, | 184 | font_load, |
182 | font_get, | 185 | font_get, |
@@ -461,6 +464,9 @@ static const struct plugin_api rockbox_api = { | |||
461 | sound_max, | 464 | sound_max, |
462 | sound_unit, | 465 | sound_unit, |
463 | sound_val2phys, | 466 | sound_val2phys, |
467 | #ifdef AUDIOHW_HAVE_EQ | ||
468 | sound_enum_hw_eq_band_setting, | ||
469 | #endif | ||
464 | #ifndef SIMULATOR | 470 | #ifndef SIMULATOR |
465 | mp3_play_data, | 471 | mp3_play_data, |
466 | mp3_play_pause, | 472 | mp3_play_pause, |
@@ -491,7 +497,6 @@ static const struct plugin_api rockbox_api = { | |||
491 | pcm_init_recording, | 497 | pcm_init_recording, |
492 | pcm_close_recording, | 498 | pcm_close_recording, |
493 | pcm_record_data, | 499 | pcm_record_data, |
494 | pcm_record_more, | ||
495 | pcm_stop_recording, | 500 | pcm_stop_recording, |
496 | pcm_calculate_rec_peaks, | 501 | pcm_calculate_rec_peaks, |
497 | audio_set_recording_gain, | 502 | audio_set_recording_gain, |
@@ -630,7 +635,12 @@ static const struct plugin_api rockbox_api = { | |||
630 | codec_thread_do_callback, | 635 | codec_thread_do_callback, |
631 | codec_load_file, | 636 | codec_load_file, |
632 | get_codec_filename, | 637 | get_codec_filename, |
638 | find_array_ptr, | ||
639 | remove_array_ptr, | ||
640 | #if defined(HAVE_RECORDING) && (defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN)) | ||
641 | round_value_to_list32, | ||
633 | #endif | 642 | #endif |
643 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
634 | get_metadata, | 644 | get_metadata, |
635 | mp3info, | 645 | mp3info, |
636 | count_mp3_frames, | 646 | count_mp3_frames, |
@@ -711,24 +721,6 @@ static const struct plugin_api rockbox_api = { | |||
711 | appsversion, | 721 | appsversion, |
712 | /* new stuff at the end, sort into place next time | 722 | /* new stuff at the end, sort into place next time |
713 | the API gets incompatible */ | 723 | the API gets incompatible */ |
714 | |||
715 | #ifdef HAVE_LCD_BITMAP | ||
716 | is_diacritic, | ||
717 | #endif | ||
718 | |||
719 | #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && \ | ||
720 | (defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN)) | ||
721 | round_value_to_list32, | ||
722 | #endif | ||
723 | |||
724 | #ifdef AUDIOHW_HAVE_EQ | ||
725 | sound_enum_hw_eq_band_setting, | ||
726 | #endif | ||
727 | |||
728 | #if CONFIG_CODEC == SWCODEC | ||
729 | find_array_ptr, | ||
730 | remove_array_ptr, | ||
731 | #endif | ||
732 | }; | 724 | }; |
733 | 725 | ||
734 | int plugin_load(const char* plugin, const void* parameter) | 726 | int plugin_load(const char* plugin, const void* parameter) |
diff --git a/apps/plugin.h b/apps/plugin.h index 6727ca4caf..7e198c97bd 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -144,12 +144,12 @@ void* plugin_get_buffer(size_t *buffer_size); | |||
144 | #define PLUGIN_MAGIC 0x526F634B /* RocK */ | 144 | #define PLUGIN_MAGIC 0x526F634B /* RocK */ |
145 | 145 | ||
146 | /* increase this every time the api struct changes */ | 146 | /* increase this every time the api struct changes */ |
147 | #define PLUGIN_API_VERSION 186 | 147 | #define PLUGIN_API_VERSION 187 |
148 | 148 | ||
149 | /* update this to latest version if a change to the api struct breaks | 149 | /* update this to latest version if a change to the api struct breaks |
150 | backwards compatibility (and please take the opportunity to sort in any | 150 | backwards compatibility (and please take the opportunity to sort in any |
151 | new function which are "waiting" at the end of the function table) */ | 151 | new function which are "waiting" at the end of the function table) */ |
152 | #define PLUGIN_MIN_API_VERSION 182 | 152 | #define PLUGIN_MIN_API_VERSION 187 |
153 | 153 | ||
154 | /* plugin return codes */ | 154 | /* plugin return codes */ |
155 | enum plugin_status { | 155 | enum plugin_status { |
@@ -259,6 +259,9 @@ struct plugin_api { | |||
259 | struct event_queue *button_queue; | 259 | struct event_queue *button_queue; |
260 | #endif | 260 | #endif |
261 | unsigned short *(*bidi_l2v)( const unsigned char *str, int orientation ); | 261 | unsigned short *(*bidi_l2v)( const unsigned char *str, int orientation ); |
262 | #ifdef HAVE_LCD_BITMAP | ||
263 | bool (*is_diacritic)(const unsigned short char_code, bool *is_rtl); | ||
264 | #endif | ||
262 | const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code ); | 265 | const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code ); |
263 | int (*font_load)(struct font*, const char *path); | 266 | int (*font_load)(struct font*, const char *path); |
264 | struct font* (*font_get)(int font); | 267 | struct font* (*font_get)(int font); |
@@ -577,6 +580,10 @@ struct plugin_api { | |||
577 | int (*sound_max)(int setting); | 580 | int (*sound_max)(int setting); |
578 | const char * (*sound_unit)(int setting); | 581 | const char * (*sound_unit)(int setting); |
579 | int (*sound_val2phys)(int setting, int value); | 582 | int (*sound_val2phys)(int setting, int value); |
583 | #ifdef AUDIOHW_HAVE_EQ | ||
584 | int (*sound_enum_hw_eq_band_setting)(unsigned int band, | ||
585 | unsigned int band_setting); | ||
586 | #endif /* AUDIOHW_HAVE_EQ */ | ||
580 | #ifndef SIMULATOR | 587 | #ifndef SIMULATOR |
581 | void (*mp3_play_data)(const unsigned char* start, int size, | 588 | void (*mp3_play_data)(const unsigned char* start, int size, |
582 | void (*get_more)(unsigned char** start, size_t* size)); | 589 | void (*get_more)(unsigned char** start, size_t* size)); |
@@ -591,7 +598,7 @@ struct plugin_api { | |||
591 | const unsigned long *audio_master_sampr_list; | 598 | const unsigned long *audio_master_sampr_list; |
592 | const unsigned long *hw_freq_sampr; | 599 | const unsigned long *hw_freq_sampr; |
593 | void (*pcm_apply_settings)(void); | 600 | void (*pcm_apply_settings)(void); |
594 | void (*pcm_play_data)(pcm_more_callback_type get_more, | 601 | void (*pcm_play_data)(pcm_play_callback_type get_more, |
595 | unsigned char* start, size_t size); | 602 | unsigned char* start, size_t size); |
596 | void (*pcm_play_stop)(void); | 603 | void (*pcm_play_stop)(void); |
597 | void (*pcm_set_frequency)(unsigned int frequency); | 604 | void (*pcm_set_frequency)(unsigned int frequency); |
@@ -610,9 +617,8 @@ struct plugin_api { | |||
610 | const unsigned long *rec_freq_sampr; | 617 | const unsigned long *rec_freq_sampr; |
611 | void (*pcm_init_recording)(void); | 618 | void (*pcm_init_recording)(void); |
612 | void (*pcm_close_recording)(void); | 619 | void (*pcm_close_recording)(void); |
613 | void (*pcm_record_data)(pcm_more_callback_type2 more_ready, | 620 | void (*pcm_record_data)(pcm_rec_callback_type more_ready, |
614 | void *start, size_t size); | 621 | void *start, size_t size); |
615 | void (*pcm_record_more)(void *start, size_t size); | ||
616 | void (*pcm_stop_recording)(void); | 622 | void (*pcm_stop_recording)(void); |
617 | void (*pcm_calculate_rec_peaks)(int *left, int *right); | 623 | void (*pcm_calculate_rec_peaks)(int *left, int *right); |
618 | void (*audio_set_recording_gain)(int left, int right, int type); | 624 | void (*audio_set_recording_gain)(int left, int right, int type); |
@@ -774,7 +780,15 @@ struct plugin_api { | |||
774 | unsigned int *audio_thread_id); | 780 | unsigned int *audio_thread_id); |
775 | int (*codec_load_file)(const char* codec, struct codec_api *api); | 781 | int (*codec_load_file)(const char* codec, struct codec_api *api); |
776 | const char *(*get_codec_filename)(int cod_spec); | 782 | const char *(*get_codec_filename)(int cod_spec); |
783 | void ** (*find_array_ptr)(void **arr, void *ptr); | ||
784 | int (*remove_array_ptr)(void **arr, void *ptr); | ||
785 | #if defined(HAVE_RECORDING) && (defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN)) | ||
786 | int (*round_value_to_list32)(unsigned long value, | ||
787 | const unsigned long list[], | ||
788 | int count, | ||
789 | bool signd); | ||
777 | #endif | 790 | #endif |
791 | #endif /* CONFIG_CODEC == SWCODEC */ | ||
778 | bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname); | 792 | bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname); |
779 | bool (*mp3info)(struct mp3entry *entry, const char *filename); | 793 | bool (*mp3info)(struct mp3entry *entry, const char *filename); |
780 | int (*count_mp3_frames)(int fd, int startpos, int filesize, | 794 | int (*count_mp3_frames)(int fd, int startpos, int filesize, |
@@ -874,28 +888,6 @@ struct plugin_api { | |||
874 | const char *appsversion; | 888 | const char *appsversion; |
875 | /* new stuff at the end, sort into place next time | 889 | /* new stuff at the end, sort into place next time |
876 | the API gets incompatible */ | 890 | the API gets incompatible */ |
877 | |||
878 | #ifdef HAVE_LCD_BITMAP | ||
879 | bool (*is_diacritic)(const unsigned short char_code, bool *is_rtl); | ||
880 | #endif | ||
881 | |||
882 | #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && \ | ||
883 | (defined(HAVE_LINE_IN) || defined(HAVE_MIC_IN)) | ||
884 | int (*round_value_to_list32)(unsigned long value, | ||
885 | const unsigned long list[], | ||
886 | int count, | ||
887 | bool signd); | ||
888 | #endif | ||
889 | |||
890 | #ifdef AUDIOHW_HAVE_EQ | ||
891 | int (*sound_enum_hw_eq_band_setting)(unsigned int band, | ||
892 | unsigned int band_setting); | ||
893 | #endif /* AUDIOHW_HAVE_EQ */ | ||
894 | |||
895 | #if CONFIG_CODEC == SWCODEC | ||
896 | void ** (*find_array_ptr)(void **arr, void *ptr); | ||
897 | int (*remove_array_ptr)(void **arr, void *ptr); | ||
898 | #endif | ||
899 | }; | 891 | }; |
900 | 892 | ||
901 | /* plugin header */ | 893 | /* plugin header */ |
diff --git a/apps/plugins/pitch_detector.c b/apps/plugins/pitch_detector.c index 538e0886fa..208b146c4e 100644 --- a/apps/plugins/pitch_detector.c +++ b/apps/plugins/pitch_detector.c | |||
@@ -982,7 +982,7 @@ uint32_t ICODE_ATTR buffer_magnitude(int16_t *input) | |||
982 | 982 | ||
983 | /* Stop the recording when the buffer is full */ | 983 | /* Stop the recording when the buffer is full */ |
984 | #ifndef SIMULATOR | 984 | #ifndef SIMULATOR |
985 | int recording_callback(int status) | 985 | void recording_callback(int status, void **start, size_t *size) |
986 | { | 986 | { |
987 | int tail = audio_tail ^ 1; | 987 | int tail = audio_tail ^ 1; |
988 | 988 | ||
@@ -991,10 +991,9 @@ int recording_callback(int status) | |||
991 | audio_tail = tail; | 991 | audio_tail = tail; |
992 | 992 | ||
993 | /* Always record full buffer, even if not required */ | 993 | /* Always record full buffer, even if not required */ |
994 | rb->pcm_record_more(audio_data[tail], | 994 | *start = audio_data[tail]; |
995 | BUFFER_SIZE * sizeof (int16_t)); | 995 | *size = BUFFER_SIZE * sizeof (int16_t); |
996 | 996 | ||
997 | return 0; | ||
998 | (void)status; | 997 | (void)status; |
999 | } | 998 | } |
1000 | #endif | 999 | #endif |
diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c index 2567b56ef3..687a70664d 100644 --- a/apps/recorder/pcm_record.c +++ b/apps/recorder/pcm_record.c | |||
@@ -256,7 +256,7 @@ enum | |||
256 | /*******************************************************************/ | 256 | /*******************************************************************/ |
257 | 257 | ||
258 | /* Callback for when more data is ready - called in interrupt context */ | 258 | /* Callback for when more data is ready - called in interrupt context */ |
259 | static int pcm_rec_have_more(int status) | 259 | static void pcm_rec_have_more(int status, void **start, size_t *size) |
260 | { | 260 | { |
261 | if (status < 0) | 261 | if (status < 0) |
262 | { | 262 | { |
@@ -265,9 +265,9 @@ static int pcm_rec_have_more(int status) | |||
265 | { | 265 | { |
266 | /* Flush recorded data to disk and stop recording */ | 266 | /* Flush recorded data to disk and stop recording */ |
267 | queue_post(&pcmrec_queue, PCMREC_STOP, 0); | 267 | queue_post(&pcmrec_queue, PCMREC_STOP, 0); |
268 | return -1; | 268 | return; |
269 | } | 269 | } |
270 | /* else try again next transmission */ | 270 | /* else try again next transmission - frame is invalid */ |
271 | } | 271 | } |
272 | else if (!dma_lock) | 272 | else if (!dma_lock) |
273 | { | 273 | { |
@@ -282,8 +282,8 @@ static int pcm_rec_have_more(int status) | |||
282 | dma_wr_pos = next_pos; | 282 | dma_wr_pos = next_pos; |
283 | } | 283 | } |
284 | 284 | ||
285 | pcm_record_more(GET_PCM_CHUNK(dma_wr_pos), PCM_CHUNK_SIZE); | 285 | *start = GET_PCM_CHUNK(dma_wr_pos); |
286 | return 0; | 286 | *size = PCM_CHUNK_SIZE; |
287 | } /* pcm_rec_have_more */ | 287 | } /* pcm_rec_have_more */ |
288 | 288 | ||
289 | static void reset_hardware(void) | 289 | static void reset_hardware(void) |
diff --git a/apps/voice_thread.c b/apps/voice_thread.c index 076bd2ea1b..a65ec566d1 100644 --- a/apps/voice_thread.c +++ b/apps/voice_thread.c | |||
@@ -89,7 +89,7 @@ enum voice_thread_messages | |||
89 | /* Structure to store clip data callback info */ | 89 | /* Structure to store clip data callback info */ |
90 | struct voice_info | 90 | struct voice_info |
91 | { | 91 | { |
92 | pcm_more_callback_type get_more; /* Callback to get more clips */ | 92 | pcm_play_callback_type get_more; /* Callback to get more clips */ |
93 | unsigned char *start; /* Start of clip */ | 93 | unsigned char *start; /* Start of clip */ |
94 | size_t size; /* Size of clip */ | 94 | size_t size; /* Size of clip */ |
95 | }; | 95 | }; |
@@ -117,7 +117,7 @@ static inline bool playback_is_playing(void) | |||
117 | 117 | ||
118 | /* Stop any current clip and start playing a new one */ | 118 | /* Stop any current clip and start playing a new one */ |
119 | void mp3_play_data(const unsigned char* start, int size, | 119 | void mp3_play_data(const unsigned char* start, int size, |
120 | pcm_more_callback_type get_more) | 120 | pcm_play_callback_type get_more) |
121 | { | 121 | { |
122 | /* Shared struct to get data to the thread - once it replies, it has | 122 | /* Shared struct to get data to the thread - once it replies, it has |
123 | * safely cached it in its own private data */ | 123 | * safely cached it in its own private data */ |
diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h index 0d2d39b03d..40bfe6fa46 100644 --- a/firmware/export/pcm.h +++ b/firmware/export/pcm.h | |||
@@ -50,9 +50,9 @@ | |||
50 | /** RAW PCM routines used with playback and recording **/ | 50 | /** RAW PCM routines used with playback and recording **/ |
51 | 51 | ||
52 | /* Typedef for registered callback */ | 52 | /* Typedef for registered callback */ |
53 | typedef void (*pcm_more_callback_type)(unsigned char **start, | 53 | typedef void (*pcm_play_callback_type)(unsigned char **start, |
54 | size_t *size); | 54 | size_t *size); |
55 | typedef int (*pcm_more_callback_type2)(int status); | 55 | typedef void (*pcm_rec_callback_type)(int status, void **start, size_t *size); |
56 | 56 | ||
57 | /* set the pcm frequency - use values in hw_sampr_list | 57 | /* set the pcm frequency - use values in hw_sampr_list |
58 | * use -1 for the default frequency | 58 | * use -1 for the default frequency |
@@ -71,7 +71,7 @@ void pcm_init(void); | |||
71 | void pcm_postinit(void); | 71 | void pcm_postinit(void); |
72 | 72 | ||
73 | /* This is for playing "raw" PCM data */ | 73 | /* This is for playing "raw" PCM data */ |
74 | void pcm_play_data(pcm_more_callback_type get_more, | 74 | void pcm_play_data(pcm_play_callback_type get_more, |
75 | unsigned char* start, size_t size); | 75 | unsigned char* start, size_t size); |
76 | 76 | ||
77 | void pcm_calculate_peaks(int *left, int *right); | 77 | void pcm_calculate_peaks(int *left, int *right); |
@@ -86,6 +86,11 @@ bool pcm_is_playing(void); | |||
86 | /** The following are for internal use between pcm.c and target- | 86 | /** The following are for internal use between pcm.c and target- |
87 | specific portion **/ | 87 | specific portion **/ |
88 | 88 | ||
89 | /* Called by the bottom layer ISR when more data is needed. Returns non- | ||
90 | * zero size if more data is to be played. Setting start to NULL | ||
91 | * forces stop. */ | ||
92 | void pcm_play_get_more_callback(void **start, size_t *size); | ||
93 | |||
89 | extern unsigned long pcm_curr_sampr; | 94 | extern unsigned long pcm_curr_sampr; |
90 | extern unsigned long pcm_sampr; | 95 | extern unsigned long pcm_sampr; |
91 | extern int pcm_fsel; | 96 | extern int pcm_fsel; |
@@ -94,10 +99,8 @@ extern int pcm_fsel; | |||
94 | void * pcm_dma_addr(void *addr); | 99 | void * pcm_dma_addr(void *addr); |
95 | #endif | 100 | #endif |
96 | 101 | ||
97 | /* the registered callback function to ask for more mp3 data */ | 102 | extern volatile bool pcm_playing; |
98 | extern volatile pcm_more_callback_type pcm_callback_for_more; | 103 | extern volatile bool pcm_paused; |
99 | extern volatile bool pcm_playing; | ||
100 | extern volatile bool pcm_paused; | ||
101 | 104 | ||
102 | void pcm_play_dma_lock(void); | 105 | void pcm_play_dma_lock(void); |
103 | void pcm_play_dma_unlock(void); | 106 | void pcm_play_dma_unlock(void); |
@@ -105,7 +108,6 @@ void pcm_play_dma_init(void); | |||
105 | void pcm_play_dma_start(const void *addr, size_t size); | 108 | void pcm_play_dma_start(const void *addr, size_t size); |
106 | void pcm_play_dma_stop(void); | 109 | void pcm_play_dma_stop(void); |
107 | void pcm_play_dma_pause(bool pause); | 110 | void pcm_play_dma_pause(bool pause); |
108 | void pcm_play_dma_stopped_callback(void); | ||
109 | const void * pcm_play_dma_get_peak_buffer(int *count); | 111 | const void * pcm_play_dma_get_peak_buffer(int *count); |
110 | 112 | ||
111 | void pcm_dma_apply_settings(void); | 113 | void pcm_dma_apply_settings(void); |
@@ -124,7 +126,7 @@ void pcm_init_recording(void); | |||
124 | void pcm_close_recording(void); | 126 | void pcm_close_recording(void); |
125 | 127 | ||
126 | /* Start recording "raw" PCM data */ | 128 | /* Start recording "raw" PCM data */ |
127 | void pcm_record_data(pcm_more_callback_type2 more_ready, | 129 | void pcm_record_data(pcm_rec_callback_type more_ready, |
128 | void *start, size_t size); | 130 | void *start, size_t size); |
129 | 131 | ||
130 | /* Stop tranferring data into supplied buffer */ | 132 | /* Stop tranferring data into supplied buffer */ |
@@ -133,17 +135,16 @@ void pcm_stop_recording(void); | |||
133 | /* Is pcm currently recording? */ | 135 | /* Is pcm currently recording? */ |
134 | bool pcm_is_recording(void); | 136 | bool pcm_is_recording(void); |
135 | 137 | ||
136 | /* Continue transferring data in - call during interrupt handler */ | 138 | /* Called by bottom layer ISR when transfer is complete. Returns non-zero |
137 | void pcm_record_more(void *start, size_t size); | 139 | * size if successful. Setting start to NULL forces stop. */ |
140 | void pcm_rec_more_ready_callback(int status, void **start, size_t *size); | ||
138 | 141 | ||
139 | void pcm_calculate_rec_peaks(int *left, int *right); | 142 | void pcm_calculate_rec_peaks(int *left, int *right); |
140 | 143 | ||
141 | /** The following are for internal use between pcm.c and target- | 144 | /** The following are for internal use between pcm.c and target- |
142 | specific portion **/ | 145 | specific portion **/ |
143 | /* the registered callback function for when more data is available */ | ||
144 | extern volatile pcm_more_callback_type2 pcm_callback_more_ready; | ||
145 | /* DMA transfer in is currently active */ | 146 | /* DMA transfer in is currently active */ |
146 | extern volatile bool pcm_recording; | 147 | extern volatile bool pcm_recording; |
147 | 148 | ||
148 | /* APIs implemented in the target-specific portion */ | 149 | /* APIs implemented in the target-specific portion */ |
149 | void pcm_rec_dma_init(void); | 150 | void pcm_rec_dma_init(void); |
@@ -151,7 +152,6 @@ void pcm_rec_dma_close(void); | |||
151 | void pcm_rec_dma_start(void *addr, size_t size); | 152 | void pcm_rec_dma_start(void *addr, size_t size); |
152 | void pcm_rec_dma_record_more(void *start, size_t size); | 153 | void pcm_rec_dma_record_more(void *start, size_t size); |
153 | void pcm_rec_dma_stop(void); | 154 | void pcm_rec_dma_stop(void); |
154 | void pcm_rec_dma_stopped_callback(void); | ||
155 | const void * pcm_rec_dma_get_peak_buffer(void); | 155 | const void * pcm_rec_dma_get_peak_buffer(void); |
156 | 156 | ||
157 | #endif /* HAVE_RECORDING */ | 157 | #endif /* HAVE_RECORDING */ |
diff --git a/firmware/pcm.c b/firmware/pcm.c index a69f0a8232..8080823077 100644 --- a/firmware/pcm.c +++ b/firmware/pcm.c | |||
@@ -39,6 +39,7 @@ | |||
39 | * pcm_play_lock | 39 | * pcm_play_lock |
40 | * pcm_play_unlock | 40 | * pcm_play_unlock |
41 | * Semi-private - | 41 | * Semi-private - |
42 | * pcm_play_get_more_callback | ||
42 | * pcm_play_dma_init | 43 | * pcm_play_dma_init |
43 | * pcm_play_dma_start | 44 | * pcm_play_dma_start |
44 | * pcm_play_dma_stop | 45 | * pcm_play_dma_stop |
@@ -48,28 +49,27 @@ | |||
48 | * pcm_sampr (R) | 49 | * pcm_sampr (R) |
49 | * pcm_fsel (R) | 50 | * pcm_fsel (R) |
50 | * pcm_curr_sampr (R) | 51 | * pcm_curr_sampr (R) |
51 | * pcm_callback_for_more (R) | ||
52 | * pcm_playing (R) | 52 | * pcm_playing (R) |
53 | * pcm_paused (R) | 53 | * pcm_paused (R) |
54 | * | 54 | * |
55 | * ==Playback/Recording== | 55 | * ==Playback/Recording== |
56 | * Public - | ||
57 | * pcm_dma_addr | ||
56 | * Semi-private - | 58 | * Semi-private - |
57 | * pcm_dma_apply_settings | 59 | * pcm_dma_apply_settings |
58 | * pcm_dma_addr | ||
59 | * | 60 | * |
60 | * ==Recording== | 61 | * ==Recording== |
61 | * Public - | 62 | * Public - |
62 | * pcm_rec_lock | 63 | * pcm_rec_lock |
63 | * pcm_rec_unlock | 64 | * pcm_rec_unlock |
64 | * Semi-private - | 65 | * Semi-private - |
66 | * pcm_rec_more_ready_callback | ||
65 | * pcm_rec_dma_init | 67 | * pcm_rec_dma_init |
66 | * pcm_rec_dma_close | 68 | * pcm_rec_dma_close |
67 | * pcm_rec_dma_start | 69 | * pcm_rec_dma_start |
68 | * pcm_rec_dma_record_more | ||
69 | * pcm_rec_dma_stop | 70 | * pcm_rec_dma_stop |
70 | * pcm_rec_dma_get_peak_buffer | 71 | * pcm_rec_dma_get_peak_buffer |
71 | * Data Read/Written within TSP - | 72 | * Data Read/Written within TSP - |
72 | * pcm_callback_more_ready (R) | ||
73 | * pcm_recording (R) | 73 | * pcm_recording (R) |
74 | * | 74 | * |
75 | * States are set _after_ the target's pcm driver is called so that it may | 75 | * States are set _after_ the target's pcm driver is called so that it may |
@@ -78,7 +78,7 @@ | |||
78 | */ | 78 | */ |
79 | 79 | ||
80 | /* the registered callback function to ask for more mp3 data */ | 80 | /* the registered callback function to ask for more mp3 data */ |
81 | volatile pcm_more_callback_type pcm_callback_for_more | 81 | static volatile pcm_play_callback_type pcm_callback_for_more |
82 | SHAREDBSS_ATTR = NULL; | 82 | SHAREDBSS_ATTR = NULL; |
83 | /* PCM playback state */ | 83 | /* PCM playback state */ |
84 | volatile bool pcm_playing SHAREDBSS_ATTR = false; | 84 | volatile bool pcm_playing SHAREDBSS_ATTR = false; |
@@ -91,6 +91,14 @@ unsigned long pcm_sampr SHAREDBSS_ATTR = HW_SAMPR_DEFAULT; | |||
91 | /* samplerate frequency selection index */ | 91 | /* samplerate frequency selection index */ |
92 | int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT; | 92 | int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT; |
93 | 93 | ||
94 | /* Called internally by functions to reset the state */ | ||
95 | static void pcm_play_stopped(void) | ||
96 | { | ||
97 | pcm_callback_for_more = NULL; | ||
98 | pcm_paused = false; | ||
99 | pcm_playing = false; | ||
100 | } | ||
101 | |||
94 | /** | 102 | /** |
95 | * Perform peak calculation on a buffer of packed 16-bit samples. | 103 | * Perform peak calculation on a buffer of packed 16-bit samples. |
96 | * | 104 | * |
@@ -187,6 +195,16 @@ const void* pcm_get_peak_buffer(int * count) | |||
187 | return pcm_play_dma_get_peak_buffer(count); | 195 | return pcm_play_dma_get_peak_buffer(count); |
188 | } | 196 | } |
189 | 197 | ||
198 | bool pcm_is_playing(void) | ||
199 | { | ||
200 | return pcm_playing; | ||
201 | } | ||
202 | |||
203 | bool pcm_is_paused(void) | ||
204 | { | ||
205 | return pcm_paused; | ||
206 | } | ||
207 | |||
190 | /**************************************************************************** | 208 | /**************************************************************************** |
191 | * Functions that do not require targeted implementation but only a targeted | 209 | * Functions that do not require targeted implementation but only a targeted |
192 | * interface | 210 | * interface |
@@ -198,7 +216,7 @@ void pcm_init(void) | |||
198 | { | 216 | { |
199 | logf("pcm_init"); | 217 | logf("pcm_init"); |
200 | 218 | ||
201 | pcm_play_dma_stopped_callback(); | 219 | pcm_play_stopped(); |
202 | 220 | ||
203 | pcm_set_frequency(HW_SAMPR_DEFAULT); | 221 | pcm_set_frequency(HW_SAMPR_DEFAULT); |
204 | 222 | ||
@@ -214,7 +232,7 @@ static void pcm_play_data_start(unsigned char *start, size_t size) | |||
214 | 232 | ||
215 | if (!(start && size)) | 233 | if (!(start && size)) |
216 | { | 234 | { |
217 | pcm_more_callback_type get_more = pcm_callback_for_more; | 235 | pcm_play_callback_type get_more = pcm_callback_for_more; |
218 | size = 0; | 236 | size = 0; |
219 | if (get_more) | 237 | if (get_more) |
220 | { | 238 | { |
@@ -239,10 +257,10 @@ static void pcm_play_data_start(unsigned char *start, size_t size) | |||
239 | /* Force a stop */ | 257 | /* Force a stop */ |
240 | logf(" pcm_play_dma_stop"); | 258 | logf(" pcm_play_dma_stop"); |
241 | pcm_play_dma_stop(); | 259 | pcm_play_dma_stop(); |
242 | pcm_play_dma_stopped_callback(); | 260 | pcm_play_stopped(); |
243 | } | 261 | } |
244 | 262 | ||
245 | void pcm_play_data(pcm_more_callback_type get_more, | 263 | void pcm_play_data(pcm_play_callback_type get_more, |
246 | unsigned char *start, size_t size) | 264 | unsigned char *start, size_t size) |
247 | { | 265 | { |
248 | logf("pcm_play_data"); | 266 | logf("pcm_play_data"); |
@@ -257,6 +275,29 @@ void pcm_play_data(pcm_more_callback_type get_more, | |||
257 | pcm_play_unlock(); | 275 | pcm_play_unlock(); |
258 | } | 276 | } |
259 | 277 | ||
278 | void pcm_play_get_more_callback(void **start, size_t *size) | ||
279 | { | ||
280 | pcm_play_callback_type get_more = pcm_callback_for_more; | ||
281 | |||
282 | *size = 0; | ||
283 | |||
284 | if (get_more && start) | ||
285 | { | ||
286 | /* Call registered callback */ | ||
287 | get_more((unsigned char **)start, size); | ||
288 | |||
289 | *start = (void *)(((uintptr_t)*start + 3) & ~3); | ||
290 | *size &= ~3; | ||
291 | |||
292 | if (*start && *size) | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | /* Error, callback missing or no more DMA to do */ | ||
297 | pcm_play_dma_stop(); | ||
298 | pcm_play_stopped(); | ||
299 | } | ||
300 | |||
260 | void pcm_play_pause(bool play) | 301 | void pcm_play_pause(bool play) |
261 | { | 302 | { |
262 | logf("pcm_play_pause: %s", play ? "play" : "pause"); | 303 | logf("pcm_play_pause: %s", play ? "play" : "pause"); |
@@ -302,7 +343,7 @@ void pcm_play_stop(void) | |||
302 | { | 343 | { |
303 | logf(" pcm_play_dma_stop"); | 344 | logf(" pcm_play_dma_stop"); |
304 | pcm_play_dma_stop(); | 345 | pcm_play_dma_stop(); |
305 | pcm_play_dma_stopped_callback(); | 346 | pcm_play_stopped(); |
306 | } | 347 | } |
307 | else | 348 | else |
308 | { | 349 | { |
@@ -312,13 +353,6 @@ void pcm_play_stop(void) | |||
312 | pcm_play_unlock(); | 353 | pcm_play_unlock(); |
313 | } | 354 | } |
314 | 355 | ||
315 | void pcm_play_dma_stopped_callback(void) | ||
316 | { | ||
317 | pcm_callback_for_more = NULL; | ||
318 | pcm_paused = false; | ||
319 | pcm_playing = false; | ||
320 | } | ||
321 | |||
322 | /**/ | 356 | /**/ |
323 | 357 | ||
324 | /* set frequency next frequency used by the audio hardware - | 358 | /* set frequency next frequency used by the audio hardware - |
@@ -350,27 +384,24 @@ void pcm_apply_settings(void) | |||
350 | } | 384 | } |
351 | } | 385 | } |
352 | 386 | ||
353 | bool pcm_is_playing(void) | ||
354 | { | ||
355 | return pcm_playing; | ||
356 | } | ||
357 | |||
358 | bool pcm_is_paused(void) | ||
359 | { | ||
360 | return pcm_paused; | ||
361 | } | ||
362 | |||
363 | #ifdef HAVE_RECORDING | 387 | #ifdef HAVE_RECORDING |
364 | /** Low level pcm recording apis **/ | 388 | /** Low level pcm recording apis **/ |
365 | 389 | ||
366 | /* Next start for recording peaks */ | 390 | /* Next start for recording peaks */ |
367 | static const void * volatile pcm_rec_peak_addr SHAREDBSS_ATTR = NULL; | 391 | static const void * volatile pcm_rec_peak_addr SHAREDBSS_ATTR = NULL; |
368 | /* the registered callback function for when more data is available */ | 392 | /* the registered callback function for when more data is available */ |
369 | volatile pcm_more_callback_type2 | 393 | static volatile pcm_rec_callback_type |
370 | pcm_callback_more_ready SHAREDBSS_ATTR = NULL; | 394 | pcm_callback_more_ready SHAREDBSS_ATTR = NULL; |
371 | /* DMA transfer in is currently active */ | 395 | /* DMA transfer in is currently active */ |
372 | volatile bool pcm_recording SHAREDBSS_ATTR = false; | 396 | volatile bool pcm_recording SHAREDBSS_ATTR = false; |
373 | 397 | ||
398 | /* Called internally by functions to reset the state */ | ||
399 | static void pcm_recording_stopped(void) | ||
400 | { | ||
401 | pcm_recording = false; | ||
402 | pcm_callback_more_ready = NULL; | ||
403 | } | ||
404 | |||
374 | /** | 405 | /** |
375 | * Return recording peaks - From the end of the last peak up to | 406 | * Return recording peaks - From the end of the last peak up to |
376 | * current write position. | 407 | * current write position. |
@@ -410,10 +441,16 @@ void pcm_calculate_rec_peaks(int *left, int *right) | |||
410 | *right = peaks[1]; | 441 | *right = peaks[1]; |
411 | } /* pcm_calculate_rec_peaks */ | 442 | } /* pcm_calculate_rec_peaks */ |
412 | 443 | ||
444 | bool pcm_is_recording(void) | ||
445 | { | ||
446 | return pcm_recording; | ||
447 | } | ||
448 | |||
413 | /**************************************************************************** | 449 | /**************************************************************************** |
414 | * Functions that do not require targeted implementation but only a targeted | 450 | * Functions that do not require targeted implementation but only a targeted |
415 | * interface | 451 | * interface |
416 | */ | 452 | */ |
453 | |||
417 | void pcm_init_recording(void) | 454 | void pcm_init_recording(void) |
418 | { | 455 | { |
419 | logf("pcm_init_recording"); | 456 | logf("pcm_init_recording"); |
@@ -424,7 +461,7 @@ void pcm_init_recording(void) | |||
424 | pcm_rec_lock(); | 461 | pcm_rec_lock(); |
425 | 462 | ||
426 | logf(" pcm_rec_dma_init"); | 463 | logf(" pcm_rec_dma_init"); |
427 | pcm_rec_dma_stopped_callback(); | 464 | pcm_recording_stopped(); |
428 | pcm_rec_dma_init(); | 465 | pcm_rec_dma_init(); |
429 | 466 | ||
430 | pcm_rec_unlock(); | 467 | pcm_rec_unlock(); |
@@ -440,7 +477,7 @@ void pcm_close_recording(void) | |||
440 | { | 477 | { |
441 | logf(" pcm_rec_dma_stop"); | 478 | logf(" pcm_rec_dma_stop"); |
442 | pcm_rec_dma_stop(); | 479 | pcm_rec_dma_stop(); |
443 | pcm_rec_dma_stopped_callback(); | 480 | pcm_recording_stopped(); |
444 | } | 481 | } |
445 | 482 | ||
446 | logf(" pcm_rec_dma_close"); | 483 | logf(" pcm_rec_dma_close"); |
@@ -449,7 +486,7 @@ void pcm_close_recording(void) | |||
449 | pcm_rec_unlock(); | 486 | pcm_rec_unlock(); |
450 | } | 487 | } |
451 | 488 | ||
452 | void pcm_record_data(pcm_more_callback_type2 more_ready, | 489 | void pcm_record_data(pcm_rec_callback_type more_ready, |
453 | void *start, size_t size) | 490 | void *start, size_t size) |
454 | { | 491 | { |
455 | logf("pcm_record_data"); | 492 | logf("pcm_record_data"); |
@@ -493,43 +530,40 @@ void pcm_stop_recording(void) | |||
493 | { | 530 | { |
494 | logf(" pcm_rec_dma_stop"); | 531 | logf(" pcm_rec_dma_stop"); |
495 | pcm_rec_dma_stop(); | 532 | pcm_rec_dma_stop(); |
496 | pcm_rec_dma_stopped_callback(); | 533 | pcm_recording_stopped(); |
497 | } | 534 | } |
498 | 535 | ||
499 | pcm_rec_unlock(); | 536 | pcm_rec_unlock(); |
500 | } /* pcm_stop_recording */ | 537 | } /* pcm_stop_recording */ |
501 | 538 | ||
502 | void pcm_record_more(void *start, size_t size) | 539 | void pcm_rec_more_ready_callback(int status, void **start, size_t *size) |
503 | { | 540 | { |
504 | start = (void *)(((uintptr_t)start + 3) & ~3); | 541 | pcm_rec_callback_type have_more = pcm_callback_more_ready; |
505 | size = size & ~3; | ||
506 | |||
507 | if (!size) | ||
508 | { | ||
509 | pcm_rec_dma_stop(); | ||
510 | pcm_rec_dma_stopped_callback(); | ||
511 | return; | ||
512 | } | ||
513 | 542 | ||
514 | #ifdef HAVE_PCM_REC_DMA_ADDRESS | 543 | *size = 0; |
515 | /* Need a physical DMA address translation, if not already physical. */ | ||
516 | pcm_rec_peak_addr = pcm_dma_addr(start); | ||
517 | #else | ||
518 | pcm_rec_peak_addr = start; | ||
519 | #endif | ||
520 | 544 | ||
521 | pcm_rec_dma_record_more(start, size); | 545 | if (have_more && start) |
522 | } | 546 | { |
547 | have_more(status, start, size); | ||
548 | *start = (void *)(((uintptr_t)*start + 3) & ~3); | ||
549 | *size &= ~3; | ||
523 | 550 | ||
524 | bool pcm_is_recording(void) | 551 | if (*start && *size) |
525 | { | 552 | { |
526 | return pcm_recording; | 553 | #ifdef HAVE_PCM_REC_DMA_ADDRESS |
527 | } | 554 | /* Need a physical DMA address translation, if not already |
555 | * physical. */ | ||
556 | pcm_rec_peak_addr = pcm_dma_addr(*start); | ||
557 | #else | ||
558 | pcm_rec_peak_addr = *start; | ||
559 | #endif | ||
560 | return; | ||
561 | } | ||
562 | } | ||
528 | 563 | ||
529 | void pcm_rec_dma_stopped_callback(void) | 564 | /* Error, callback missing or no more DMA to do */ |
530 | { | 565 | pcm_rec_dma_stop(); |
531 | pcm_recording = false; | 566 | pcm_recording_stopped(); |
532 | pcm_callback_more_ready = NULL; | ||
533 | } | 567 | } |
534 | 568 | ||
535 | #endif /* HAVE_RECORDING */ | 569 | #endif /* HAVE_RECORDING */ |
diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c index cefca0fbe5..a2e3cfbf9f 100644 --- a/firmware/target/arm/as3525/pcm-as3525.c +++ b/firmware/target/arm/as3525/pcm-as3525.c | |||
@@ -74,18 +74,13 @@ static void dma_callback(void) | |||
74 | { | 74 | { |
75 | if(!dma_size) | 75 | if(!dma_size) |
76 | { | 76 | { |
77 | register pcm_more_callback_type get_more = pcm_callback_for_more; | 77 | pcm_play_get_more_callback(&dma_start_addr, &dma_size); |
78 | if(get_more) | ||
79 | get_more(&dma_start_addr, &dma_size); | ||
80 | } | ||
81 | 78 | ||
82 | if(!dma_size) | 79 | if (!dma_size) |
83 | { | 80 | return; |
84 | pcm_play_dma_stop(); | ||
85 | pcm_play_dma_stopped_callback(); | ||
86 | } | 81 | } |
87 | else | 82 | |
88 | play_start_pcm(); | 83 | play_start_pcm(); |
89 | } | 84 | } |
90 | 85 | ||
91 | void pcm_play_dma_start(const void *addr, size_t size) | 86 | void pcm_play_dma_start(const void *addr, size_t size) |
@@ -275,31 +270,19 @@ static void rec_dma_callback(void) | |||
275 | 270 | ||
276 | if(!rec_dma_size) | 271 | if(!rec_dma_size) |
277 | { | 272 | { |
278 | register pcm_more_callback_type2 more_ready = pcm_callback_more_ready; | 273 | pcm_rec_more_ready_callback(0, &rec_dma_start_addr, &rec_dma_size); |
279 | if (!more_ready || more_ready(0) < 0) | ||
280 | { | ||
281 | /* Finished recording */ | ||
282 | pcm_rec_dma_stop(); | ||
283 | pcm_rec_dma_stopped_callback(); | ||
284 | return; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | rec_dma_start(); | ||
289 | } | ||
290 | |||
291 | 274 | ||
292 | void pcm_rec_dma_record_more(void *start, size_t size) | 275 | if(rec_dma_size != 0) |
293 | { | 276 | { |
294 | dump_dcache_range(start, size); | 277 | dump_dcache_range(rec_dma_start_addr, rec_dma_size); |
295 | rec_dma_start_addr = start; | ||
296 | #if CONFIG_CPU == AS3525 | 278 | #if CONFIG_CPU == AS3525 |
297 | mono_samples = AS3525_UNCACHED_ADDR(start); | 279 | mono_samples = AS3525_UNCACHED_ADDR(rec_dma_start_addr); |
298 | #endif | 280 | #endif |
299 | rec_dma_size = size; | 281 | rec_dma_start(); |
282 | } | ||
283 | } | ||
300 | } | 284 | } |
301 | 285 | ||
302 | |||
303 | void pcm_rec_dma_stop(void) | 286 | void pcm_rec_dma_stop(void) |
304 | { | 287 | { |
305 | dma_disable_channel(1); | 288 | dma_disable_channel(1); |
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c index 02051fad90..2c65c70360 100644 --- a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c | |||
@@ -52,9 +52,9 @@ static struct dma_data dma_play_data = | |||
52 | 52 | ||
53 | static void play_dma_callback(void) | 53 | static void play_dma_callback(void) |
54 | { | 54 | { |
55 | unsigned char *start; | 55 | void *start; |
56 | size_t size = 0; | 56 | size_t size; |
57 | pcm_more_callback_type get_more = pcm_callback_for_more; | 57 | bool rror; |
58 | 58 | ||
59 | if (dma_play_data.locked != 0) | 59 | if (dma_play_data.locked != 0) |
60 | { | 60 | { |
@@ -63,28 +63,20 @@ static void play_dma_callback(void) | |||
63 | return; | 63 | return; |
64 | } | 64 | } |
65 | 65 | ||
66 | if (dma_play_bd.mode.status & BD_RROR) | 66 | rror = dma_play_bd.mode.status & BD_RROR; |
67 | { | 67 | |
68 | /* Stop on error */ | 68 | pcm_play_get_more_callback(rror ? NULL : &start, &size); |
69 | } | 69 | |
70 | else if (get_more != NULL && (get_more(&start, &size), size != 0)) | 70 | if (size == 0) |
71 | { | ||
72 | start = (void*)(((unsigned long)start + 3) & ~3); | ||
73 | size &= ~3; | ||
74 | |||
75 | /* Flush any pending cache writes */ | ||
76 | clean_dcache_range(start, size); | ||
77 | dma_play_bd.buf_addr = (void *)addr_virt_to_phys((unsigned long)start); | ||
78 | dma_play_bd.mode.count = size; | ||
79 | dma_play_bd.mode.command = TRANSFER_16BIT; | ||
80 | dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR; | ||
81 | sdma_channel_run(DMA_PLAY_CH_NUM); | ||
82 | return; | 71 | return; |
83 | } | ||
84 | 72 | ||
85 | /* Error, callback missing or no more DMA to do */ | 73 | /* Flush any pending cache writes */ |
86 | pcm_play_dma_stop(); | 74 | clean_dcache_range(start, size); |
87 | pcm_play_dma_stopped_callback(); | 75 | dma_play_bd.buf_addr = (void *)addr_virt_to_phys((unsigned long)start); |
76 | dma_play_bd.mode.count = size; | ||
77 | dma_play_bd.mode.command = TRANSFER_16BIT; | ||
78 | dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR; | ||
79 | sdma_channel_run(DMA_PLAY_CH_NUM); | ||
88 | } | 80 | } |
89 | 81 | ||
90 | void pcm_play_lock(void) | 82 | void pcm_play_lock(void) |
@@ -272,12 +264,6 @@ void pcm_play_dma_start(const void *addr, size_t size) | |||
272 | SSI_STCR2 &= ~SSI_STCR_TFEN0; | 264 | SSI_STCR2 &= ~SSI_STCR_TFEN0; |
273 | SSI_SCR2 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN); | 265 | SSI_SCR2 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN); |
274 | 266 | ||
275 | addr = (void *)(((unsigned long)addr + 3) & ~3); | ||
276 | size &= ~3; | ||
277 | |||
278 | if (size <= 0) | ||
279 | return; | ||
280 | |||
281 | if (!sdma_channel_reset(DMA_PLAY_CH_NUM)) | 267 | if (!sdma_channel_reset(DMA_PLAY_CH_NUM)) |
282 | return; | 268 | return; |
283 | 269 | ||
@@ -383,8 +369,9 @@ static struct dma_data dma_rec_data = | |||
383 | 369 | ||
384 | static void rec_dma_callback(void) | 370 | static void rec_dma_callback(void) |
385 | { | 371 | { |
386 | pcm_more_callback_type2 more_ready; | ||
387 | int status = 0; | 372 | int status = 0; |
373 | void *start; | ||
374 | size_t size; | ||
388 | 375 | ||
389 | if (dma_rec_data.locked != 0) | 376 | if (dma_rec_data.locked != 0) |
390 | { | 377 | { |
@@ -395,17 +382,22 @@ static void rec_dma_callback(void) | |||
395 | if (dma_rec_bd.mode.status & BD_RROR) | 382 | if (dma_rec_bd.mode.status & BD_RROR) |
396 | status = DMA_REC_ERROR_DMA; | 383 | status = DMA_REC_ERROR_DMA; |
397 | 384 | ||
398 | more_ready = pcm_callback_more_ready; | 385 | pcm_rec_more_ready_callback(status, &start, &size); |
399 | 386 | ||
400 | if (more_ready != NULL && more_ready(status) >= 0) | 387 | if (size == 0) |
401 | { | ||
402 | sdma_channel_run(DMA_REC_CH_NUM); | ||
403 | return; | 388 | return; |
404 | } | ||
405 | 389 | ||
406 | /* Finished recording */ | 390 | /* Invalidate - buffer must be coherent */ |
407 | pcm_rec_dma_stop(); | 391 | dump_dcache_range(start, size); |
408 | pcm_rec_dma_stopped_callback(); | 392 | |
393 | start = (void *)addr_virt_to_phys((unsigned long)start); | ||
394 | |||
395 | dma_rec_bd.buf_addr = start; | ||
396 | dma_rec_bd.mode.count = size; | ||
397 | dma_rec_bd.mode.command = TRANSFER_16BIT; | ||
398 | dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR; | ||
399 | |||
400 | sdma_channel_run(DMA_REC_CH_NUM); | ||
409 | } | 401 | } |
410 | 402 | ||
411 | void pcm_rec_lock(void) | 403 | void pcm_rec_lock(void) |
@@ -432,19 +424,6 @@ void pcm_rec_unlock(void) | |||
432 | } | 424 | } |
433 | } | 425 | } |
434 | 426 | ||
435 | void pcm_rec_dma_record_more(void *start, size_t size) | ||
436 | { | ||
437 | /* Invalidate - buffer must be coherent */ | ||
438 | dump_dcache_range(start, size); | ||
439 | |||
440 | start = (void *)addr_virt_to_phys((unsigned long)start); | ||
441 | |||
442 | dma_rec_bd.buf_addr = start; | ||
443 | dma_rec_bd.mode.count = size; | ||
444 | dma_rec_bd.mode.command = TRANSFER_16BIT; | ||
445 | dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR; | ||
446 | } | ||
447 | |||
448 | void pcm_rec_dma_stop(void) | 427 | void pcm_rec_dma_stop(void) |
449 | { | 428 | { |
450 | /* Stop receiving data */ | 429 | /* Stop receiving data */ |
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c index e0b603c81f..6289b4c730 100644 --- a/firmware/target/arm/pcm-pp.c +++ b/firmware/target/arm/pcm-pp.c | |||
@@ -115,7 +115,6 @@ void pcm_dma_apply_settings(void) | |||
115 | /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ | 115 | /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ |
116 | void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) | 116 | void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) |
117 | { | 117 | { |
118 | register pcm_more_callback_type get_more; | ||
119 | register size_t size; | 118 | register size_t size; |
120 | 119 | ||
121 | DMA0_STATUS; /* Clear any pending interrupt */ | 120 | DMA0_STATUS; /* Clear any pending interrupt */ |
@@ -141,15 +140,12 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) | |||
141 | } | 140 | } |
142 | 141 | ||
143 | /* Buffer empty. Try to get more. */ | 142 | /* Buffer empty. Try to get more. */ |
144 | get_more = pcm_callback_for_more; | 143 | pcm_play_get_more_callback((void **)&dma_play_data.addr, |
145 | if (get_more) { | 144 | &dma_play_data.size); |
146 | get_more((unsigned char **)&dma_play_data.addr, &dma_play_data.size); | ||
147 | dma_play_data.addr = (dma_play_data.addr + 2) & ~3; | ||
148 | dma_play_data.size &= ~3; | ||
149 | } | ||
150 | 145 | ||
151 | if (dma_play_data.size == 0) { | 146 | if (dma_play_data.size == 0) { |
152 | break; | 147 | /* No more data */ |
148 | return; | ||
153 | } | 149 | } |
154 | 150 | ||
155 | if (dma_play_data.addr < UNCACHED_BASE_ADDR) { | 151 | if (dma_play_data.addr < UNCACHED_BASE_ADDR) { |
@@ -158,10 +154,6 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) | |||
158 | cpucache_flush(); | 154 | cpucache_flush(); |
159 | } | 155 | } |
160 | } | 156 | } |
161 | |||
162 | /* Callback missing or no more DMA to do */ | ||
163 | pcm_play_dma_stop(); | ||
164 | pcm_play_dma_stopped_callback(); | ||
165 | } | 157 | } |
166 | #else | 158 | #else |
167 | /* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by | 159 | /* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by |
@@ -247,28 +239,16 @@ void fiq_playback(void) | |||
247 | #endif | 239 | #endif |
248 | 240 | ||
249 | ".more_data: \n" | 241 | ".more_data: \n" |
250 | "ldr r2, =pcm_callback_for_more \n" | 242 | "ldr r2, =pcm_play_get_more_callback \n" |
251 | "ldr r2, [r2] \n" /* get callback address */ | ||
252 | "cmp r2, #0 \n" /* check for null pointer */ | ||
253 | "beq .stop \n" /* callback removed, stop */ | ||
254 | "stmia r11, { r8-r9 } \n" /* save internal copies of variables back */ | ||
255 | "mov r0, r11 \n" /* r0 = &p */ | 243 | "mov r0, r11 \n" /* r0 = &p */ |
256 | "add r1, r11, #4 \n" /* r1 = &size */ | 244 | "add r1, r11, #4 \n" /* r1 = &size */ |
257 | "mov lr, pc \n" /* call pcm_callback_for_more */ | 245 | "mov lr, pc \n" /* call pcm_play_get_more_callback */ |
258 | "bx r2 \n" | 246 | "bx r2 \n" |
259 | "ldmia r11, { r8-r9 } \n" /* reload p and size */ | 247 | "ldmia r11, { r8-r9 } \n" /* load new p and size */ |
260 | "cmp r9, #0 \n" /* did we actually get more data? */ | 248 | "cmp r9, #0 \n" |
261 | "bne .check_fifo \n" | 249 | "bne .check_fifo \n" /* size != 0? refill */ |
262 | 250 | ||
263 | ".stop: \n" /* call termination routines */ | 251 | ".exit: \n" /* (r9=0 if stopping, look above) */ |
264 | "ldr r12, =pcm_play_dma_stop \n" | ||
265 | "mov lr, pc \n" | ||
266 | "bx r12 \n" | ||
267 | "ldr r12, =pcm_play_dma_stopped_callback \n" | ||
268 | "mov lr, pc \n" | ||
269 | "bx r12 \n" | ||
270 | |||
271 | ".exit: \n" /* (r8=0 if stopping, look above) */ | ||
272 | "stmia r11, { r8-r9 } \n" /* save p and size */ | 252 | "stmia r11, { r8-r9 } \n" /* save p and size */ |
273 | "ldmfd sp!, { r0-r3, lr } \n" | 253 | "ldmfd sp!, { r0-r3, lr } \n" |
274 | "subs pc, lr, #4 \n" /* FIQ specific return sequence */ | 254 | "subs pc, lr, #4 \n" /* FIQ specific return sequence */ |
@@ -284,8 +264,6 @@ void fiq_playback(void) __attribute__((interrupt ("FIQ"))) ICODE_ATTR; | |||
284 | /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ | 264 | /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ |
285 | void fiq_playback(void) | 265 | void fiq_playback(void) |
286 | { | 266 | { |
287 | register pcm_more_callback_type get_more; | ||
288 | |||
289 | #if CONFIG_CPU == PP5002 | 267 | #if CONFIG_CPU == PP5002 |
290 | inl(0xcf001040); | 268 | inl(0xcf001040); |
291 | #endif | 269 | #endif |
@@ -305,16 +283,11 @@ void fiq_playback(void) | |||
305 | } | 283 | } |
306 | 284 | ||
307 | /* p is empty, get some more data */ | 285 | /* p is empty, get some more data */ |
308 | get_more = pcm_callback_for_more; | 286 | pcm_play_get_more_callback((void **)&dma_play_data.addr, |
309 | if (get_more) { | 287 | &dma_play_data.size); |
310 | get_more((unsigned char**)&dma_play_data.addr, | ||
311 | &dma_play_data.size); | ||
312 | } | ||
313 | } while (dma_play_data.size); | 288 | } while (dma_play_data.size); |
314 | 289 | ||
315 | /* No more data, so disable the FIFO/interrupt */ | 290 | /* No more data */ |
316 | pcm_play_dma_stop(); | ||
317 | pcm_play_dma_stopped_callback(); | ||
318 | } | 291 | } |
319 | #endif /* ASM / C selection */ | 292 | #endif /* ASM / C selection */ |
320 | #endif /* CPU_PP502x */ | 293 | #endif /* CPU_PP502x */ |
@@ -589,7 +562,6 @@ void fiq_record(void) ICODE_ATTR __attribute__((interrupt ("FIQ"))); | |||
589 | #if defined(SANSA_C200) || defined(SANSA_E200) | 562 | #if defined(SANSA_C200) || defined(SANSA_E200) |
590 | void fiq_record(void) | 563 | void fiq_record(void) |
591 | { | 564 | { |
592 | register pcm_more_callback_type2 more_ready; | ||
593 | register int32_t value; | 565 | register int32_t value; |
594 | 566 | ||
595 | if (audio_channels == 2) { | 567 | if (audio_channels == 2) { |
@@ -648,20 +620,13 @@ void fiq_record(void) | |||
648 | } | 620 | } |
649 | } | 621 | } |
650 | 622 | ||
651 | more_ready = pcm_callback_more_ready; | 623 | pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr, |
652 | 624 | &dma_rec_data.size); | |
653 | if (more_ready == NULL || more_ready(0) < 0) { | ||
654 | /* Finished recording */ | ||
655 | pcm_rec_dma_stop(); | ||
656 | pcm_rec_dma_stopped_callback(); | ||
657 | } | ||
658 | } | 625 | } |
659 | 626 | ||
660 | #else | 627 | #else |
661 | void fiq_record(void) | 628 | void fiq_record(void) |
662 | { | 629 | { |
663 | register pcm_more_callback_type2 more_ready; | ||
664 | |||
665 | while (dma_rec_data.size > 0) { | 630 | while (dma_rec_data.size > 0) { |
666 | if (IIS_RX_FULL_COUNT < 2) { | 631 | if (IIS_RX_FULL_COUNT < 2) { |
667 | return; | 632 | return; |
@@ -676,24 +641,12 @@ void fiq_record(void) | |||
676 | dma_rec_data.size -= 4; | 641 | dma_rec_data.size -= 4; |
677 | } | 642 | } |
678 | 643 | ||
679 | more_ready = pcm_callback_more_ready; | 644 | pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr, |
680 | 645 | &dma_rec_data.size); | |
681 | if (more_ready == NULL || more_ready(0) < 0) { | ||
682 | /* Finished recording */ | ||
683 | pcm_rec_dma_stop(); | ||
684 | pcm_rec_dma_stopped_callback(); | ||
685 | } | ||
686 | } | 646 | } |
687 | 647 | ||
688 | #endif /* SANSA_E200 */ | 648 | #endif /* SANSA_E200 */ |
689 | 649 | ||
690 | /* Continue transferring data in */ | ||
691 | void pcm_rec_dma_record_more(void *start, size_t size) | ||
692 | { | ||
693 | dma_rec_data.addr = (unsigned long)start; /* Start of RX buffer */ | ||
694 | dma_rec_data.size = size; /* Bytes to transfer */ | ||
695 | } | ||
696 | |||
697 | void pcm_rec_dma_stop(void) | 650 | void pcm_rec_dma_stop(void) |
698 | { | 651 | { |
699 | /* disable interrupt */ | 652 | /* disable interrupt */ |
diff --git a/firmware/target/arm/pcm-telechips.c b/firmware/target/arm/pcm-telechips.c index 3ce038ffcd..d718ca38ac 100644 --- a/firmware/target/arm/pcm-telechips.c +++ b/firmware/target/arm/pcm-telechips.c | |||
@@ -233,12 +233,6 @@ const void * pcm_rec_dma_get_peak_buffer(void) | |||
233 | { | 233 | { |
234 | return NULL; | 234 | return NULL; |
235 | } | 235 | } |
236 | |||
237 | void pcm_record_more(void *start, size_t size) | ||
238 | { | ||
239 | (void) start; | ||
240 | (void) size; | ||
241 | } | ||
242 | #endif | 236 | #endif |
243 | 237 | ||
244 | #if defined(CPU_TCC77X) || defined(CPU_TCC780X) | 238 | #if defined(CPU_TCC77X) || defined(CPU_TCC780X) |
@@ -289,21 +283,14 @@ void fiq_handler(void) | |||
289 | 283 | ||
290 | ".more_data: \n" | 284 | ".more_data: \n" |
291 | "stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */ | 285 | "stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */ |
292 | "ldr r2, =pcm_callback_for_more \n" | 286 | "ldr r2, =pcm_play_get_more_callback \n" |
293 | "ldr r2, [r2] \n" /* get callback address */ | 287 | "mov r0, r11 \n" /* r0 = &p */ |
294 | "cmp r2, #0 \n" /* check for null pointer */ | 288 | "add r1, r11, #4 \n" /* r1 = &size */ |
295 | "movne r0, r11 \n" /* r0 = &p */ | 289 | "blx r2 \n" /* call pcm_play_get_more_callback */ |
296 | "addne r1, r11, #4 \n" /* r1 = &size */ | 290 | "ldmia r11, { r8-r9 } \n" /* load new p and size */ |
297 | "blxne r2 \n" /* call pcm_callback_for_more */ | 291 | "cmp r9, #0x10 \n" /* did we actually get enough data? */ |
298 | "ldmia r11, { r8-r9 } \n" /* reload p and size */ | ||
299 | "cmp r9, #0x10 \n" /* did we actually get more data? */ | ||
300 | "ldmgefd sp!, { r0-r3, lr } \n" | ||
301 | "bge .fill_fifo \n" /* yes: fill the fifo */ | ||
302 | "ldr r12, =pcm_play_dma_stop \n" | ||
303 | "blx r12 \n" /* no: stop playback */ | ||
304 | "ldr r12, =pcm_play_dma_stopped_callback \n" | ||
305 | "blx r12 \n" | ||
306 | "ldmfd sp!, { r0-r3, lr } \n" | 292 | "ldmfd sp!, { r0-r3, lr } \n" |
293 | "bpl .fill_fifo \n" /* not stop and enough? refill */ | ||
307 | "b .exit \n" | 294 | "b .exit \n" |
308 | ".ltorg \n" | 295 | ".ltorg \n" |
309 | ); | 296 | ); |
@@ -315,17 +302,11 @@ void fiq_handler(void) | |||
315 | asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ | 302 | asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ |
316 | "sub sp, sp, #8 \n"); /* Reserve stack */ | 303 | "sub sp, sp, #8 \n"); /* Reserve stack */ |
317 | 304 | ||
318 | register pcm_more_callback_type get_more; | ||
319 | |||
320 | if (dma_play_data.size < 16) | 305 | if (dma_play_data.size < 16) |
321 | { | 306 | { |
322 | /* p is empty, get some more data */ | 307 | /* p is empty, get some more data */ |
323 | get_more = pcm_callback_for_more; | 308 | pcm_play_get_more_callback((void**)&dma_play_data.p, |
324 | if (get_more) | 309 | &dma_play_data.size); |
325 | { | ||
326 | get_more((unsigned char**)&dma_play_data.p, | ||
327 | &dma_play_data.size); | ||
328 | } | ||
329 | } | 310 | } |
330 | 311 | ||
331 | if (dma_play_data.size >= 16) | 312 | if (dma_play_data.size >= 16) |
@@ -341,12 +322,6 @@ void fiq_handler(void) | |||
341 | 322 | ||
342 | dma_play_data.size -= 16; | 323 | dma_play_data.size -= 16; |
343 | } | 324 | } |
344 | else | ||
345 | { | ||
346 | /* No more data, so disable the FIFO/interrupt */ | ||
347 | pcm_play_dma_stop(); | ||
348 | pcm_play_dma_stopped_callback(); | ||
349 | } | ||
350 | 325 | ||
351 | /* Clear FIQ status */ | 326 | /* Clear FIQ status */ |
352 | CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK; | 327 | CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK; |
diff --git a/firmware/target/arm/pnx0101/pcm-pnx0101.c b/firmware/target/arm/pnx0101/pcm-pnx0101.c index fe1e05b79a..9d4ffbd773 100644 --- a/firmware/target/arm/pnx0101/pcm-pnx0101.c +++ b/firmware/target/arm/pnx0101/pcm-pnx0101.c | |||
@@ -104,13 +104,10 @@ static inline void fill_dma_buf(int offset) | |||
104 | p = tmp_p; | 104 | p = tmp_p; |
105 | if (l >= lend) | 105 | if (l >= lend) |
106 | return; | 106 | return; |
107 | else if (pcm_callback_for_more) | 107 | |
108 | pcm_callback_for_more((unsigned char**)&p, | 108 | pcm_play_get_more_callback((void**)&p, &p_size); |
109 | &p_size); | ||
110 | } | 109 | } |
111 | while (p_size); | 110 | while (p_size); |
112 | |||
113 | pcm_play_dma_stopped_callback(); | ||
114 | } | 111 | } |
115 | 112 | ||
116 | if (l < lend) | 113 | if (l < lend) |
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c index bb1b2d9eaa..e9f55479c7 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c | |||
@@ -214,35 +214,27 @@ void pcm_play_dma_pause(bool pause) | |||
214 | 214 | ||
215 | void fiq_handler(void) | 215 | void fiq_handler(void) |
216 | { | 216 | { |
217 | static unsigned char *start; | 217 | static void *start; |
218 | static size_t size; | 218 | static size_t size; |
219 | register pcm_more_callback_type get_more; /* No stack for this */ | ||
220 | 219 | ||
221 | /* clear any pending interrupt */ | 220 | /* clear any pending interrupt */ |
222 | SRCPND = DMA2_MASK; | 221 | SRCPND = DMA2_MASK; |
223 | 222 | ||
224 | /* Buffer empty. Try to get more. */ | 223 | /* Buffer empty. Try to get more. */ |
225 | get_more = pcm_callback_for_more; | 224 | pcm_play_get_more_callback(&start, &size); |
226 | size = 0; | ||
227 | 225 | ||
228 | if (get_more == NULL || (get_more(&start, &size), size == 0)) | 226 | if (size == 0) |
229 | { | 227 | return; |
230 | /* Callback missing or no more DMA to do */ | ||
231 | pcm_play_dma_stop(); | ||
232 | pcm_play_dma_stopped_callback(); | ||
233 | } | ||
234 | else | ||
235 | { | ||
236 | /* Flush any pending cache writes */ | ||
237 | clean_dcache_range(start, size); | ||
238 | 228 | ||
239 | /* set the new DMA values */ | 229 | /* Flush any pending cache writes */ |
240 | DCON2 = DMA_CONTROL_SETUP | (size >> 1); | 230 | clean_dcache_range(start, size); |
241 | DISRC2 = (unsigned int)start + 0x30000000; | ||
242 | 231 | ||
243 | /* Re-Activate the channel */ | 232 | /* set the new DMA values */ |
244 | DMASKTRIG2 = 0x2; | 233 | DCON2 = DMA_CONTROL_SETUP | (size >> 1); |
245 | } | 234 | DISRC2 = (unsigned int)start + 0x30000000; |
235 | |||
236 | /* Re-Activate the channel */ | ||
237 | DMASKTRIG2 = 0x2; | ||
246 | } | 238 | } |
247 | 239 | ||
248 | size_t pcm_get_bytes_waiting(void) | 240 | size_t pcm_get_bytes_waiting(void) |
diff --git a/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c b/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c index 486a235614..30db29c42c 100644 --- a/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c +++ b/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c | |||
@@ -254,35 +254,27 @@ void pcm_play_dma_pause(bool pause) | |||
254 | 254 | ||
255 | void fiq_handler(void) | 255 | void fiq_handler(void) |
256 | { | 256 | { |
257 | static unsigned char *start; | 257 | static void *start; |
258 | static size_t size; | 258 | static size_t size; |
259 | register pcm_more_callback_type get_more; /* No stack for this */ | ||
260 | 259 | ||
261 | /* clear any pending interrupt */ | 260 | /* clear any pending interrupt */ |
262 | SRCPND = DMA2_MASK; | 261 | SRCPND = DMA2_MASK; |
263 | 262 | ||
264 | /* Buffer empty. Try to get more. */ | 263 | /* Buffer empty. Try to get more. */ |
265 | get_more = pcm_callback_for_more; | 264 | pcm_play_get_more_callback(&start, &size); |
266 | size = 0; | ||
267 | 265 | ||
268 | if (get_more == NULL || (get_more(&start, &size), size == 0)) | 266 | if (size == 0) |
269 | { | 267 | return; |
270 | /* Callback missing or no more DMA to do */ | ||
271 | pcm_play_dma_stop(); | ||
272 | pcm_play_dma_stopped_callback(); | ||
273 | } | ||
274 | else | ||
275 | { | ||
276 | /* Flush any pending cache writes */ | ||
277 | clean_dcache_range(start, size); | ||
278 | 268 | ||
279 | /* set the new DMA values */ | 269 | /* Flush any pending cache writes */ |
280 | DCON2 = DMA_CONTROL_SETUP | (size >> 1); | 270 | clean_dcache_range(start, size); |
281 | DISRC2 = (unsigned int)start + 0x30000000; | ||
282 | 271 | ||
283 | /* Re-Activate the channel */ | 272 | /* set the new DMA values */ |
284 | DMASKTRIG2 = 0x2; | 273 | DCON2 = DMA_CONTROL_SETUP | (size >> 1); |
285 | } | 274 | DISRC2 = (unsigned int)start + 0x30000000; |
275 | |||
276 | /* Re-Activate the channel */ | ||
277 | DMASKTRIG2 = 0x2; | ||
286 | } | 278 | } |
287 | 279 | ||
288 | size_t pcm_get_bytes_waiting(void) | 280 | size_t pcm_get_bytes_waiting(void) |
diff --git a/firmware/target/arm/s5l8700/pcm-s5l8700.c b/firmware/target/arm/s5l8700/pcm-s5l8700.c index 7798f41d11..4d24b327af 100644 --- a/firmware/target/arm/s5l8700/pcm-s5l8700.c +++ b/firmware/target/arm/s5l8700/pcm-s5l8700.c | |||
@@ -102,11 +102,11 @@ static const void* dma_callback(void) | |||
102 | { | 102 | { |
103 | if (dmamode) | 103 | if (dmamode) |
104 | { | 104 | { |
105 | unsigned char *dma_start_addr; | 105 | void *dma_start_addr; |
106 | register pcm_more_callback_type get_more = pcm_callback_for_more; | 106 | pcm_play_get_more_callback(&dma_start_addr, &nextsize); |
107 | if (get_more) | 107 | |
108 | if (nextsize != 0) | ||
108 | { | 109 | { |
109 | get_more(&dma_start_addr, &nextsize); | ||
110 | if (nextsize >= 4096) | 110 | if (nextsize >= 4096) |
111 | { | 111 | { |
112 | dblbufsize = (nextsize >> 4) & ~3; | 112 | dblbufsize = (nextsize >> 4) & ~3; |
@@ -148,7 +148,6 @@ void fiq_handler(void) | |||
148 | "mov r10, #0x00000400 \n" /* INT_DMA */ | 148 | "mov r10, #0x00000400 \n" /* INT_DMA */ |
149 | "str r10, [r11] \n" /* ACK FIQ */ | 149 | "str r10, [r11] \n" /* ACK FIQ */ |
150 | "stmfd sp!, {r0-r3,lr} \n" | 150 | "stmfd sp!, {r0-r3,lr} \n" |
151 | "ldreq r0, =pcm_play_dma_stopped_callback \n" | ||
152 | "ldrne r0, =dma_callback \n" | 151 | "ldrne r0, =dma_callback \n" |
153 | "mov lr, pc \n" | 152 | "mov lr, pc \n" |
154 | "bx r0 \n" | 153 | "bx r0 \n" |
@@ -225,13 +224,6 @@ void pcm_play_dma_start(const void *addr_in, size_t size) | |||
225 | #endif | 224 | #endif |
226 | 225 | ||
227 | /* S3: DMA channel 0 on */ | 226 | /* S3: DMA channel 0 on */ |
228 | if (!size) | ||
229 | { | ||
230 | register pcm_more_callback_type get_more = pcm_callback_for_more; | ||
231 | if (get_more) get_more(&addr, &size); | ||
232 | else return; /* Nothing to play!? */ | ||
233 | } | ||
234 | if (!size) return; /* Nothing to play!? */ | ||
235 | clean_dcache(); | 227 | clean_dcache(); |
236 | if (size >= 4096) | 228 | if (size >= 4096) |
237 | { | 229 | { |
@@ -367,12 +359,6 @@ void pcm_rec_unlock(void) | |||
367 | { | 359 | { |
368 | } | 360 | } |
369 | 361 | ||
370 | void pcm_rec_dma_record_more(void *start, size_t size) | ||
371 | { | ||
372 | (void)start; | ||
373 | (void)size; | ||
374 | } | ||
375 | |||
376 | void pcm_rec_dma_stop(void) | 362 | void pcm_rec_dma_stop(void) |
377 | { | 363 | { |
378 | } | 364 | } |
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c index ab3ceba0f3..d7d8f92a0c 100644 --- a/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c +++ b/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c | |||
@@ -132,8 +132,6 @@ char buffer[80]; | |||
132 | void DSPHINT(void) __attribute__ ((section(".icode"))); | 132 | void DSPHINT(void) __attribute__ ((section(".icode"))); |
133 | void DSPHINT(void) | 133 | void DSPHINT(void) |
134 | { | 134 | { |
135 | register pcm_more_callback_type get_more; /* No stack for this */ | ||
136 | |||
137 | unsigned int i; | 135 | unsigned int i; |
138 | 136 | ||
139 | IO_INTC_FIQ0 = 1 << 11; | 137 | IO_INTC_FIQ0 = 1 << 11; |
@@ -152,16 +150,9 @@ void DSPHINT(void) | |||
152 | 150 | ||
153 | case MSG_REFILL: | 151 | case MSG_REFILL: |
154 | /* Buffer empty. Try to get more. */ | 152 | /* Buffer empty. Try to get more. */ |
155 | get_more = pcm_callback_for_more; | 153 | pcm_play_get_more_callback(&start, &size); |
156 | size = 0; | 154 | |
157 | 155 | if (size != 0) | |
158 | if (get_more == NULL || (get_more(&start, &size), size == 0)) | ||
159 | { | ||
160 | /* Callback missing or no more DMA to do */ | ||
161 | pcm_play_dma_stop(); | ||
162 | pcm_play_dma_stopped_callback(); | ||
163 | } | ||
164 | |||
165 | { | 156 | { |
166 | unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START; | 157 | unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START; |
167 | /* Flush any pending cache writes */ | 158 | /* Flush any pending cache writes */ |
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c index f9c0764d64..06f17d1170 100644 --- a/firmware/target/coldfire/pcm-coldfire.c +++ b/firmware/target/coldfire/pcm-coldfire.c | |||
@@ -288,13 +288,14 @@ void DMA0(void) __attribute__ ((interrupt_handler, section(".icode"))); | |||
288 | void DMA0(void) | 288 | void DMA0(void) |
289 | { | 289 | { |
290 | unsigned long res = DSR0; | 290 | unsigned long res = DSR0; |
291 | void *start; | ||
292 | size_t size; | ||
291 | 293 | ||
292 | and_l(~(DMA_EEXT | DMA_INT), &DCR0); /* per request and int OFF */ | 294 | and_l(~(DMA_EEXT | DMA_INT), &DCR0); /* per request and int OFF */ |
293 | DSR0 = 1; /* Clear interrupt and errors */ | 295 | DSR0 = 1; /* Clear interrupt and errors */ |
294 | 296 | ||
295 | if (res & 0x70) | 297 | if (res & 0x70) |
296 | { | 298 | { |
297 | /* Stop on error */ | ||
298 | logf("DMA0 err: %02x", res); | 299 | logf("DMA0 err: %02x", res); |
299 | #if 0 | 300 | #if 0 |
300 | logf(" SAR0: %08x", SAR0); | 301 | logf(" SAR0: %08x", SAR0); |
@@ -303,32 +304,17 @@ void DMA0(void) | |||
303 | logf(" DCR0: %08x", DCR0); | 304 | logf(" DCR0: %08x", DCR0); |
304 | #endif | 305 | #endif |
305 | } | 306 | } |
306 | else | 307 | |
308 | /* Force stop on error */ | ||
309 | pcm_play_get_more_callback((res & 0x70) ? NULL : &start, &size); | ||
310 | |||
311 | if (size != 0) | ||
307 | { | 312 | { |
308 | pcm_more_callback_type get_more = pcm_callback_for_more; | 313 | SAR0 = (unsigned long)start; /* Source address */ |
309 | unsigned char *start; | 314 | BCR0 = size; /* Bytes to transfer */ |
310 | size_t size = 0; | 315 | or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */ |
311 | |||
312 | if (get_more) | ||
313 | get_more(&start, &size); | ||
314 | |||
315 | start = (unsigned char *)(((long)start + 3) & ~3); | ||
316 | size &= ~3; | ||
317 | |||
318 | if (size > 0) | ||
319 | { | ||
320 | SAR0 = (unsigned long)start; /* Source address */ | ||
321 | BCR0 = size; /* Bytes to transfer */ | ||
322 | or_l(DMA_EEXT | DMA_INT, &DCR0); /* per request and int ON */ | ||
323 | return; | ||
324 | } | ||
325 | /* Finished playing */ | ||
326 | } | 316 | } |
327 | 317 | /* else inished playing */ | |
328 | /* Stop interrupt and futher transfers */ | ||
329 | pcm_play_dma_stop(); | ||
330 | /* Inform PCM that we're done */ | ||
331 | pcm_play_dma_stopped_callback(); | ||
332 | } /* DMA0 */ | 318 | } /* DMA0 */ |
333 | 319 | ||
334 | const void * pcm_play_dma_get_peak_buffer(int *count) | 320 | const void * pcm_play_dma_get_peak_buffer(int *count) |
@@ -436,7 +422,8 @@ void DMA1(void) | |||
436 | { | 422 | { |
437 | unsigned long res = DSR1; | 423 | unsigned long res = DSR1; |
438 | int status = 0; | 424 | int status = 0; |
439 | pcm_more_callback_type2 more_ready; | 425 | void *start; |
426 | size_t size; | ||
440 | 427 | ||
441 | and_l(~(DMA_EEXT | DMA_INT), &DCR1); /* per request and int OFF */ | 428 | and_l(~(DMA_EEXT | DMA_INT), &DCR1); /* per request and int OFF */ |
442 | DSR1 = 1; /* Clear interrupt and errors */ | 429 | DSR1 = 1; /* Clear interrupt and errors */ |
@@ -465,25 +452,17 @@ void DMA1(void) | |||
465 | } | 452 | } |
466 | #endif | 453 | #endif |
467 | 454 | ||
468 | more_ready = pcm_callback_more_ready; | 455 | /* Inform PCM we have more data (or error) */ |
469 | 456 | pcm_rec_more_ready_callback(status, &start, &size); | |
470 | if (more_ready != NULL && more_ready(status) >= 0) | ||
471 | return; | ||
472 | 457 | ||
473 | /* Finished recording */ | 458 | if (size != 0) |
474 | pcm_rec_dma_stop(); | 459 | { |
475 | /* Inform PCM that we're done */ | 460 | DAR1 = (unsigned long)start; /* Destination address */ |
476 | pcm_rec_dma_stopped_callback(); | 461 | BCR1 = (unsigned long)size; /* Bytes to transfer */ |
462 | or_l(DMA_EEXT | DMA_INT, &DCR1); /* per request and int ON */ | ||
463 | } | ||
477 | } /* DMA1 */ | 464 | } /* DMA1 */ |
478 | 465 | ||
479 | /* Continue transferring data in - call from interrupt callback */ | ||
480 | void pcm_rec_dma_record_more(void *start, size_t size) | ||
481 | { | ||
482 | DAR1 = (unsigned long)start; /* Destination address */ | ||
483 | BCR1 = (unsigned long)size; /* Bytes to transfer */ | ||
484 | or_l(DMA_EEXT | DMA_INT, &DCR1); /* per request and int ON */ | ||
485 | } /* pcm_record_more */ | ||
486 | |||
487 | const void * pcm_rec_dma_get_peak_buffer(void) | 466 | const void * pcm_rec_dma_get_peak_buffer(void) |
488 | { | 467 | { |
489 | return (void *)(DAR1 & ~3); | 468 | return (void *)(DAR1 & ~3); |
diff --git a/firmware/target/hosted/sdl/pcm-sdl.c b/firmware/target/hosted/sdl/pcm-sdl.c index ee92fa208d..03e6e1336c 100644 --- a/firmware/target/hosted/sdl/pcm-sdl.c +++ b/firmware/target/hosted/sdl/pcm-sdl.c | |||
@@ -228,15 +228,9 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len) | |||
228 | 228 | ||
229 | /* Audio card wants more? Get some more then. */ | 229 | /* Audio card wants more? Get some more then. */ |
230 | while (len > 0) { | 230 | while (len > 0) { |
231 | if ((ssize_t)pcm_data_size <= 0) { | 231 | pcm_play_get_more_callback(&pcm_data, &pcm_data_size); |
232 | pcm_data_size = 0; | ||
233 | |||
234 | if (pcm_callback_for_more) | ||
235 | pcm_callback_for_more(&pcm_data, &pcm_data_size); | ||
236 | } | ||
237 | |||
238 | if (pcm_data_size > 0) { | ||
239 | start: | 232 | start: |
233 | if (pcm_data_size != 0) { | ||
240 | udata->num_in = pcm_data_size / pcm_sample_bytes; | 234 | udata->num_in = pcm_data_size / pcm_sample_bytes; |
241 | udata->num_out = len / pcm_sample_bytes; | 235 | udata->num_out = len / pcm_sample_bytes; |
242 | 236 | ||
@@ -251,8 +245,6 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len) | |||
251 | len -= udata->num_out; | 245 | len -= udata->num_out; |
252 | } else { | 246 | } else { |
253 | DEBUGF("sdl_audio_callback: No Data.\n"); | 247 | DEBUGF("sdl_audio_callback: No Data.\n"); |
254 | pcm_play_dma_stop(); | ||
255 | pcm_play_dma_stopped_callback(); | ||
256 | break; | 248 | break; |
257 | } | 249 | } |
258 | } | 250 | } |
@@ -292,12 +284,6 @@ void pcm_rec_dma_stop(void) | |||
292 | { | 284 | { |
293 | } | 285 | } |
294 | 286 | ||
295 | void pcm_rec_dma_record_more(void *start, size_t size) | ||
296 | { | ||
297 | (void)start; | ||
298 | (void)size; | ||
299 | } | ||
300 | |||
301 | unsigned long pcm_rec_status(void) | 287 | unsigned long pcm_rec_status(void) |
302 | { | 288 | { |
303 | return 0; | 289 | return 0; |
diff --git a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c index 993f70bad8..4cf43471eb 100644 --- a/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/pcm-jz4740.c | |||
@@ -100,23 +100,16 @@ static inline void set_dma(const void *addr, size_t size) | |||
100 | 100 | ||
101 | static inline void play_dma_callback(void) | 101 | static inline void play_dma_callback(void) |
102 | { | 102 | { |
103 | unsigned char *start = NULL; | 103 | unsigned char *start; |
104 | size_t size = 0; | 104 | size_t size; |
105 | 105 | ||
106 | if(pcm_callback_for_more) | 106 | pcm_play_get_more_callback(&start, &size); |
107 | pcm_callback_for_more(&start, &size); | ||
108 | 107 | ||
109 | if(LIKELY(size > 0 && start)) | 108 | if (size != 0) |
110 | { | 109 | { |
111 | set_dma(start, size); | 110 | set_dma(start, size); |
112 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN; | 111 | REG_DMAC_DCCSR(DMA_AIC_TX_CHANNEL) |= DMAC_DCCSR_EN; |
113 | } | 112 | } |
114 | else | ||
115 | { | ||
116 | /* Error, callback missing or no more DMA to do */ | ||
117 | pcm_play_dma_stop(); | ||
118 | pcm_play_dma_stopped_callback(); | ||
119 | } | ||
120 | } | 113 | } |
121 | 114 | ||
122 | void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void) __attribute__ ((section(".icode"))); | 115 | void DMA_CALLBACK(DMA_AIC_TX_CHANNEL)(void) __attribute__ ((section(".icode"))); |
@@ -292,10 +285,4 @@ const void * pcm_rec_dma_get_peak_buffer(void) | |||
292 | { | 285 | { |
293 | return NULL; | 286 | return NULL; |
294 | } | 287 | } |
295 | |||
296 | void pcm_rec_dma_record_more(void *start, size_t size) | ||
297 | { | ||
298 | (void) start; | ||
299 | (void) size; | ||
300 | } | ||
301 | #endif | 288 | #endif |