summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/playback.c14
-rw-r--r--apps/playback.h1
-rw-r--r--firmware/drivers/tlv320.c10
-rw-r--r--firmware/drivers/uda1380.c13
-rw-r--r--firmware/export/sound.h2
-rw-r--r--firmware/target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c4
-rw-r--r--firmware/target/arm/wmcodec-pp.c4
-rw-r--r--firmware/target/coldfire/pcm-coldfire.c22
8 files changed, 49 insertions, 21 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 2ea6e2f004..c3d28110dd 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -3443,6 +3443,11 @@ static bool ata_fillbuffer_callback(void)
3443static void audio_thread(void) 3443static void audio_thread(void)
3444{ 3444{
3445 struct event ev; 3445 struct event ev;
3446
3447 audiohw_postinit();
3448
3449 /* Unlock mutex that init stage locks before creating this thread */
3450 mutex_unlock(&mutex_codecthread);
3446 3451
3447 while (1) 3452 while (1)
3448 { 3453 {
@@ -3604,6 +3609,10 @@ void audio_init(void)
3604 starts running until ready if something yields such as talk_init. */ 3609 starts running until ready if something yields such as talk_init. */
3605#ifdef PLAYBACK_VOICE 3610#ifdef PLAYBACK_VOICE
3606 mutex_init(&mutex_codecthread); 3611 mutex_init(&mutex_codecthread);
3612 /* Take ownership of lock to prevent playback of anything before audio
3613 hardware is initialized - audio thread unlocks it after final init
3614 stage */
3615 mutex_lock(&mutex_codecthread);
3607#endif 3616#endif
3608 queue_init(&audio_queue, true); 3617 queue_init(&audio_queue, true);
3609 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list); 3618 queue_enable_queue_send(&audio_queue, &audio_queue_sender_list);
@@ -3656,6 +3665,7 @@ void audio_init(void)
3656 3665
3657 /* initialize the buffer */ 3666 /* initialize the buffer */
3658 filebuf = audiobuf; /* must be non-NULL for audio_set_crossfade */ 3667 filebuf = audiobuf; /* must be non-NULL for audio_set_crossfade */
3668
3659 /* audio_reset_buffer must to know the size of voice buffer so init 3669 /* audio_reset_buffer must to know the size of voice buffer so init
3660 voice first */ 3670 voice first */
3661 talk_init(); 3671 talk_init();
@@ -3670,9 +3680,9 @@ void audio_init(void)
3670 IF_COP(, CPU, false)); 3680 IF_COP(, CPU, false));
3671 3681
3672 audio_set_crossfade(global_settings.crossfade); 3682 audio_set_crossfade(global_settings.crossfade);
3673 3683
3674 audio_is_initialized = true; 3684 audio_is_initialized = true;
3675 3685
3676 sound_settings_apply(); 3686 sound_settings_apply();
3677 audio_set_buffer_margin(global_settings.buffer_margin); 3687 audio_set_buffer_margin(global_settings.buffer_margin);
3678} /* audio_init */ 3688} /* audio_init */
diff --git a/apps/playback.h b/apps/playback.h
index ccf8b58472..82179f1ee2 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -74,7 +74,6 @@ extern void audio_prev_dir(void);
74#define audio_next_dir() 74#define audio_next_dir()
75#define audio_prev_dir() 75#define audio_prev_dir()
76#endif 76#endif
77void audio_preinit(void);
78 77
79#endif 78#endif
80 79
diff --git a/firmware/drivers/tlv320.c b/firmware/drivers/tlv320.c
index a88eae5f26..c0f28d31d9 100644
--- a/firmware/drivers/tlv320.c
+++ b/firmware/drivers/tlv320.c
@@ -99,8 +99,18 @@ void audiohw_init(void)
99 tlv320_write_reg(REG_DAIF, DAIF_IWL_16 | DAIF_FOR_I2S); 99 tlv320_write_reg(REG_DAIF, DAIF_IWL_16 | DAIF_FOR_I2S);
100 tlv320_write_reg(REG_DIA, DIA_ACT); 100 tlv320_write_reg(REG_DIA, DIA_ACT);
101 audiohw_set_frequency(-1); /* default */ 101 audiohw_set_frequency(-1); /* default */
102}
103
104/**
105 * Switch outputs ON
106 */
107void audiohw_postinit(void)
108{
102 /* All ON except ADC, MIC and LINE */ 109 /* All ON except ADC, MIC and LINE */
110 sleep(HZ);
103 tlv320_write_reg(REG_PC, PC_ADC | PC_MIC | PC_LINE); 111 tlv320_write_reg(REG_PC, PC_ADC | PC_MIC | PC_LINE);
112 sleep(HZ/4);
113 audiohw_mute(false);
104} 114}
105 115
106/** 116/**
diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c
index 00019148c1..6984427fc9 100644
--- a/firmware/drivers/uda1380.c
+++ b/firmware/drivers/uda1380.c
@@ -270,6 +270,19 @@ int audiohw_init(void)
270 return 0; 270 return 0;
271} 271}
272 272
273void audiohw_postinit(void)
274{
275 /* Sleep a while so the power can stabilize (especially a long
276 delay is needed for the line out connector). */
277 sleep(HZ);
278 /* Power on FSDAC and HP amp. */
279 audiohw_enable_output(true);
280
281 /* UDA1380: Unmute the master channel
282 (DAC should be at zero point now). */
283 audiohw_mute(false);
284}
285
273/* Nice shutdown of UDA1380 codec */ 286/* Nice shutdown of UDA1380 codec */
274void audiohw_close(void) 287void audiohw_close(void)
275{ 288{
diff --git a/firmware/export/sound.h b/firmware/export/sound.h
index 192384031d..99741c24c1 100644
--- a/firmware/export/sound.h
+++ b/firmware/export/sound.h
@@ -32,6 +32,8 @@
32#include "tlv320.h" 32#include "tlv320.h"
33#endif 33#endif
34 34
35extern void audiohw_postinit(void);
36
35enum { 37enum {
36 SOUND_VOLUME = 0, 38 SOUND_VOLUME = 0,
37 SOUND_BASS, 39 SOUND_BASS,
diff --git a/firmware/target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c
index fd023e1be0..fe42b7527a 100644
--- a/firmware/target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c
+++ b/firmware/target/arm/gigabeat/meg-fx/wmcodec-meg-fx.c
@@ -61,6 +61,10 @@ int audiohw_init(void) {
61 return 0; 61 return 0;
62} 62}
63 63
64void audiohw_postinit(void)
65{
66}
67
64void wmcodec_write(int reg, int data) 68void wmcodec_write(int reg, int data)
65{ 69{
66 i2c_send(0x34, (reg<<1) | ((data&0x100)>>8), data&0xff); 70 i2c_send(0x34, (reg<<1) | ((data&0x100)>>8), data&0xff);
diff --git a/firmware/target/arm/wmcodec-pp.c b/firmware/target/arm/wmcodec-pp.c
index e252cf0ac1..505a31deb4 100644
--- a/firmware/target/arm/wmcodec-pp.c
+++ b/firmware/target/arm/wmcodec-pp.c
@@ -92,6 +92,10 @@ int audiohw_init(void) {
92 return 0; 92 return 0;
93} 93}
94 94
95void audiohw_postinit(void)
96{
97}
98
95void wmcodec_write(int reg, int data) 99void wmcodec_write(int reg, int data)
96{ 100{
97 pp_i2c_send(I2C_AUDIO_ADDRESS, (reg<<1) | ((data&0x100)>>8),data&0xff); 101 pp_i2c_send(I2C_AUDIO_ADDRESS, (reg<<1) | ((data&0x100)>>8),data&0xff);
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c
index ef847004ce..720c77e434 100644
--- a/firmware/target/coldfire/pcm-coldfire.c
+++ b/firmware/target/coldfire/pcm-coldfire.c
@@ -255,6 +255,10 @@ void pcm_init(void)
255 pcm_play_dma_stop(); 255 pcm_play_dma_stop();
256 /* Call pcm_close_recording to put in closed state */ 256 /* Call pcm_close_recording to put in closed state */
257 pcm_close_recording(); 257 pcm_close_recording();
258
259 /* Initialize default register values. */
260 audiohw_init();
261
258 audio_set_output_source(AUDIO_SRC_PLAYBACK); 262 audio_set_output_source(AUDIO_SRC_PLAYBACK);
259 audio_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); 263 audio_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
260 pcm_set_frequency(HW_FREQ_DEFAULT); 264 pcm_set_frequency(HW_FREQ_DEFAULT);
@@ -264,24 +268,6 @@ void pcm_init(void)
264#if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT) 268#if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT)
265 spdif_init(); 269 spdif_init();
266#endif 270#endif
267
268 /* Initialize default register values. */
269 audiohw_init();
270
271#if defined(HAVE_UDA1380)
272 /* Sleep a while so the power can stabilize (especially a long
273 delay is needed for the line out connector). */
274 sleep(HZ);
275 /* Power on FSDAC and HP amp. */
276 audiohw_enable_output(true);
277#elif defined(HAVE_TLV320)
278 sleep(HZ/4);
279#endif
280
281 /* UDA1380: Unmute the master channel
282 (DAC should be at zero point now). */
283 audiohw_mute(false);
284
285 /* Enable interrupt at level 6, priority 0 */ 271 /* Enable interrupt at level 6, priority 0 */
286 ICR6 = (6 << 2); 272 ICR6 = (6 << 2);
287 and_l(~(1 << 14), &IMR); /* bit 14 is DMA0 */ 273 and_l(~(1 << 14), &IMR); /* bit 14 is DMA0 */