summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2005-08-06 10:12:19 +0000
committerChristian Gmeiner <christian.gmeiner@gmail.com>2005-08-06 10:12:19 +0000
commit14e80671afca494b26354753c8fddc3c3a787d4c (patch)
tree68fa16731953a3bff3fcb531dc0ef61cddad6f89
parent095854b98925f5b01643b78f664dc4e6eace72be (diff)
downloadrockbox-14e80671afca494b26354753c8fddc3c3a787d4c.tar.gz
rockbox-14e80671afca494b26354753c8fddc3c3a787d4c.zip
iAudio: First unfinished attempt for tlv320 driver and rockbox integration
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7286 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/pcm_recording.c79
-rw-r--r--firmware/SOURCES4
-rw-r--r--firmware/drivers/tlv320.c223
-rw-r--r--firmware/export/tlv320.h19
-rw-r--r--firmware/pcm_playback.c56
-rw-r--r--firmware/pcm_record.c194
-rw-r--r--firmware/powermgmt.c6
-rw-r--r--firmware/sound.c2
8 files changed, 441 insertions, 142 deletions
diff --git a/apps/pcm_recording.c b/apps/pcm_recording.c
index 67f7d4da3c..9df44a5b30 100644
--- a/apps/pcm_recording.c
+++ b/apps/pcm_recording.c
@@ -48,10 +48,14 @@
48#include "sound.h" 48#include "sound.h"
49#include "ata.h" 49#include "ata.h"
50#include "logf.h" 50#include "logf.h"
51#if defined(HAVE_UDA1380)
51#include "uda1380.h" 52#include "uda1380.h"
53#elif defined(HAVE_TLV320)
54#include "tlv320.h"
55#endif
52#include "pcm_record.h" 56#include "pcm_record.h"
53 57
54#ifdef HAVE_UDA1380 58#if defined(HAVE_UDA1380) || defined(HAVE_TLV320)
55 59
56bool pcm_rec_screen(void) 60bool pcm_rec_screen(void)
57{ 61{
@@ -64,36 +68,45 @@ bool pcm_rec_screen(void)
64 int rec_time; 68 int rec_time;
65 int done, button; 69 int done, button;
66 int w, h; 70 int w, h;
67 71
68 lcd_setfont(FONT_SYSFIXED); 72 lcd_setfont(FONT_SYSFIXED);
69 lcd_getstringsize("M", &w, &h); 73 lcd_getstringsize("M", &w, &h);
70 lcd_setmargins(global_settings.invert_cursor ? 0 : w, 8); 74 lcd_setmargins(global_settings.invert_cursor ? 0 : w, 8);
71 75
72 play_vol = 120; 76 play_vol = 120;
73 77
74 //cpu_boost(true); 78 //cpu_boost(true);
75 79
80#if defined(HAVE_UDA1380)
76 uda1380_enable_output(true); 81 uda1380_enable_output(true);
82#elif defined(HAVE_TLV320)
83 tlv320_enable_output(true);
84#endif
85
86#if defined(HAVE_UDA1380)
77 uda1380_set_master_vol(play_vol, play_vol); 87 uda1380_set_master_vol(play_vol, play_vol);
78 88#elif defined(HAVE_TLV320)
89 tlv320_set_headphone_vol(play_vol, play_vol);
90#endif
91
79 rec_monitor = 0; // No record feedback 92 rec_monitor = 0; // No record feedback
80 rec_source = 1; // Mic 93 rec_source = 1; // Mic
81 rec_gain = 0; // 0-15 94 rec_gain = 0; // 0-15
82 rec_vol = 0; // 0-255 95 rec_vol = 0; // 0-255
83 rec_count = 0; 96 rec_count = 0;
84 rec_waveform = 0; 97 rec_waveform = 0;
85 98
86 pcm_open_recording(); 99 pcm_open_recording();
87 pcm_set_recording_options(rec_source, rec_waveform); 100 pcm_set_recording_options(rec_source, rec_waveform);
88 pcm_set_recording_gain(rec_gain, rec_vol); 101 pcm_set_recording_gain(rec_gain, rec_vol);
89 102
90 //rec_create_directory(); 103 //rec_create_directory();
91 104
92 done = 0; 105 done = 0;
93 while(!done) 106 while(!done)
94 { 107 {
95 line = 0; 108 line = 0;
96 109
97 snprintf(buf, sizeof(buf), "PlayVolume: %3d", play_vol); 110 snprintf(buf, sizeof(buf), "PlayVolume: %3d", play_vol);
98 lcd_puts(0,line++, buf); 111 lcd_puts(0,line++, buf);
99 snprintf(buf, sizeof(buf), "Gain : %2d Volume : %2d", rec_gain, rec_vol); 112 snprintf(buf, sizeof(buf), "Gain : %2d Volume : %2d", rec_gain, rec_vol);
@@ -112,10 +125,10 @@ bool pcm_rec_screen(void)
112 snprintf(buf, sizeof(buf), "File : %s", filename); 125 snprintf(buf, sizeof(buf), "File : %s", filename);
113 lcd_puts(0,line++, buf); 126 lcd_puts(0,line++, buf);
114 snprintf(buf, sizeof(buf), "Time : %02d:%02d.%02d", rec_time/HZ/60, (rec_time/HZ)%60, rec_time%HZ); 127 snprintf(buf, sizeof(buf), "Time : %02d:%02d.%02d", rec_time/HZ/60, (rec_time/HZ)%60, rec_time%HZ);
115 lcd_puts(0,line++, buf); 128 lcd_puts(0,line++, buf);
116 129
117 line++; 130 line++;
118 131
119 snprintf(buf, sizeof(buf), "MODE : Select source"); 132 snprintf(buf, sizeof(buf), "MODE : Select source");
120 lcd_puts(0,line++, buf); 133 lcd_puts(0,line++, buf);
121 snprintf(buf, sizeof(buf), "UP/DOWN : Record volume"); 134 snprintf(buf, sizeof(buf), "UP/DOWN : Record volume");
@@ -127,10 +140,10 @@ bool pcm_rec_screen(void)
127 snprintf(buf, sizeof(buf), "RMT PLAY: Toggle waveform"); 140 snprintf(buf, sizeof(buf), "RMT PLAY: Toggle waveform");
128 lcd_puts(0,line++, buf); 141 lcd_puts(0,line++, buf);
129 142
130 143
131 lcd_update(); 144 lcd_update();
132 145
133 146
134 button = button_get_w_tmo(HZ/8); 147 button = button_get_w_tmo(HZ/8);
135 switch (button) 148 switch (button)
136 { 149 {
@@ -142,14 +155,14 @@ bool pcm_rec_screen(void)
142 if (pcm_status() & AUDIO_STATUS_RECORD) 155 if (pcm_status() & AUDIO_STATUS_RECORD)
143 { 156 {
144 pcm_stop_recording(); 157 pcm_stop_recording();
145 158
146 } else 159 } else
147 { 160 {
148 snprintf(filename, MAX_PATH, "/record-%0d.wav", rec_count++); 161 snprintf(filename, MAX_PATH, "/record-%0d.wav", rec_count++);
149 pcm_record(filename); 162 pcm_record(filename);
150 } 163 }
151 break; 164 break;
152 165
153 case BUTTON_ON: 166 case BUTTON_ON:
154 break; 167 break;
155 168
@@ -162,7 +175,7 @@ bool pcm_rec_screen(void)
162 case BUTTON_RIGHT | BUTTON_REPEAT: 175 case BUTTON_RIGHT | BUTTON_REPEAT:
163 if (rec_gain < 15) 176 if (rec_gain < 15)
164 rec_gain++; 177 rec_gain++;
165 178
166 pcm_set_recording_gain(rec_gain, rec_vol); 179 pcm_set_recording_gain(rec_gain, rec_vol);
167 break; 180 break;
168 181
@@ -170,20 +183,22 @@ bool pcm_rec_screen(void)
170 case BUTTON_LEFT | BUTTON_REPEAT: 183 case BUTTON_LEFT | BUTTON_REPEAT:
171 if (rec_gain > 0) 184 if (rec_gain > 0)
172 rec_gain--; 185 rec_gain--;
173 186
174 pcm_set_recording_gain(rec_gain, rec_vol); 187 pcm_set_recording_gain(rec_gain, rec_vol);
175 break; 188 break;
176 189
177 case BUTTON_RC_MENU: 190 case BUTTON_RC_MENU:
178 rec_monitor = 1 - rec_monitor; 191 rec_monitor = 1 - rec_monitor;
192#if defined(HAVE_UDA1380)
179 uda1380_set_monitor(rec_monitor); 193 uda1380_set_monitor(rec_monitor);
194#endif
180 break; 195 break;
181 196
182 case BUTTON_RC_ON: 197 case BUTTON_RC_ON:
183 rec_waveform = 1 - rec_waveform; 198 rec_waveform = 1 - rec_waveform;
184 pcm_set_recording_options(rec_source, rec_waveform); 199 pcm_set_recording_options(rec_source, rec_waveform);
185 break; 200 break;
186 201
187 case BUTTON_UP: 202 case BUTTON_UP:
188 case BUTTON_UP | BUTTON_REPEAT: 203 case BUTTON_UP | BUTTON_REPEAT:
189 if (rec_vol<255) 204 if (rec_vol<255)
@@ -205,23 +220,29 @@ bool pcm_rec_screen(void)
205 } else 220 } else
206 { 221 {
207 pcm_stop_recording(); 222 pcm_stop_recording();
208 223#if defined(HAVE_UDA1380)
209 uda1380_enable_output(false); 224 uda1380_enable_output(false);
210 225#elif defined(HAVE_TLV320)
226 tlv320_enable_output(false);
227#endif
211 default_event_handler(SYS_USB_CONNECTED); 228 default_event_handler(SYS_USB_CONNECTED);
212 return false; 229 return false;
213 } 230 }
214 break; 231 break;
215 232
216 } 233 }
217 234
218 } 235 }
219 236
220 pcm_stop_recording(); 237 pcm_stop_recording();
221 pcm_close_recording(); 238 pcm_close_recording();
222 239
240#if defined(HAVE_UDA1380)
223 uda1380_enable_output(false); 241 uda1380_enable_output(false);
224 242#elif defined(HAVE_TLV320)
243 tlv320_enable_output(false);
244#endif
245
225 return true; 246 return true;
226} 247}
227 248
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 937bb0bfb6..be471fb51b 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -126,6 +126,8 @@ drivers/lcd-h100-remote.c
126#endif 126#endif
127#if defined(HAVE_UDA1380) && !defined(SIMULATOR) 127#if defined(HAVE_UDA1380) && !defined(SIMULATOR)
128drivers/uda1380.c 128drivers/uda1380.c
129#elif defined(HAVE_TLV320) && !defined(SIMULATOR)
130drivers/tlv320.c
129#endif 131#endif
130#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR) 132#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR)
131pcm_playback.c 133pcm_playback.c
@@ -133,7 +135,7 @@ pcm_playback.c
133#if CONFIG_HWCODEC == MASNONE 135#if CONFIG_HWCODEC == MASNONE
134replaygain.c 136replaygain.c
135#endif 137#endif
136#if defined(HAVE_UDA1380) && !defined(SIMULATOR) 138#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
137pcm_record.c 139pcm_record.c
138#endif 140#endif
139sound.c 141sound.c
diff --git a/firmware/drivers/tlv320.c b/firmware/drivers/tlv320.c
new file mode 100644
index 0000000000..bafd77cd39
--- /dev/null
+++ b/firmware/drivers/tlv320.c
@@ -0,0 +1,223 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Christian Gmeiner
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "lcd.h"
20#include "cpu.h"
21#include "kernel.h"
22#include "thread.h"
23#include "power.h"
24#include "debug.h"
25#include "system.h"
26#include "sprintf.h"
27#include "button.h"
28#include "string.h"
29#include "file.h"
30#include "buffer.h"
31
32#include "i2c-coldfire.h"
33#include "tlv320.h"
34
35/* local functions and definations */
36#define TLV320_ADDR 0x34
37
38struct tlv320_info
39{
40 int vol_l;
41 int vol_r;
42} tlv320;
43
44/* Definition of a playback configuration to start with */
45#define NUM_DEFAULT_REGS 10
46unsigned tlv320_defaults[2*NUM_DEFAULT_REGS] =
47{
48 REG_PC, PC_ON | PC_OSC | PC_CLK | PC_DAC | ~PC_OUT, /* do we need to enable osciliator and clock? */
49 REG_LLIV, LLIV_LIM, /* mute adc input */
50 REG_RLIV, RLIV_RIM, /* mute adc input */
51 REG_LHV, LHV_LHV(HEADPHONE_MUTE), /* mute headphone */
52 REG_RHV, RHV_RHV(HEADPHONE_MUTE), /* mute headphone */
53 REG_AAP, AAP_MICM, /* mute microphone */
54 REG_DAP, DAP_DEEMP_DIS, /* de-emphasis control: disabled */
55 REG_DAIF, DAIF_FOR_I2S | DAIF_IWL_24 | ~DAIF_MS, /* i2s with 24 bit data len and slave mode */
56 REG_SRC, 0, /* ToDo */
57 REG_DIA, DIA_ACT, /* activate digital interface */
58};
59unsigned tlv320_regs[0xf];
60
61void tlv320_write_reg(unsigned reg, unsigned value)
62{
63 unsigned data[3];
64
65 data[0] = TLV320_ADDR;
66 data[1] = reg << 1;
67 data[2] = value & 0xff;
68
69 if (i2c_write(1, data, 3) != 3)
70 {
71 DEBUGF("tlv320 error reg=0x%x", reg);
72 return;
73 }
74
75 tlv320_regs[reg] = value;
76}
77
78/* Returns 0 if successful or -1 if some register failed */
79void tlv320_set_regs()
80{
81 int i;
82 memset(tlv320_regs, 0, sizeof(tlv320_regs));
83
84 /* Initialize all registers */
85 for (i=0; i<NUM_DEFAULT_REGS; i++)
86 {
87 unsigned reg = tlv320_defaults[i*2+0];
88 unsigned value = tlv320_defaults[i*2+1];
89
90 tlv320_write_reg(reg, value);
91 }
92}
93
94/* public functions */
95
96/**
97 * Init our tlv with default values
98 */
99void tlv320_init()
100{
101 tlv320_reset();
102 tlv320_set_regs();
103}
104
105/**
106 * Resets tlv320 to default values
107 */
108void tlv320_reset()
109{
110 tlv320_write_reg(REG_RR, RR_RESET):
111}
112
113void tlv320_enable_output(bool enable)
114{
115 unsigned value = tlv320regs[REG_PC];
116
117 if (enable)
118 value |= PC_OUT;
119 else
120 value &= ~PC_OUT;
121
122 tlv320_write_reg(REG_PC, value);
123}
124
125/**
126 * Sets left and right headphone volume (127(max) to 48(muted))
127 */
128void tlv320_set_headphone_vol(int vol_l, int vol_r)
129{
130 unsigned value_l = tlv320_regs[REG_LHV];
131 unsigned value_r = tlv320_regs[REG_RHV];
132
133 /* keep track of current setting */
134 tlv320.vol_l = vol_l;
135 tlv320.vol_r = vol_r;
136
137 /* set new values in local register holders */
138 value_l |= LHV_LHV(vol_l);
139 value_r |= LHV_LHV(vol_r);
140
141 /* update */
142 tlv320_write_reg(REG_LHV, value_l);
143 tlv320_write_reg(REG_RHV, value_r);
144}
145
146/**
147 * Sets left and right linein volume (31(max) to 0(muted))
148 */
149void tlv320_set_linein_vol(int vol_l, int vol_r)
150{
151 unsigned value_l = tlv320regs[REG_LLIV];
152 unsigned value_r = tlv320regs[REG_RLIV];
153
154 value_l |= LLIV_LHV(vol_l);
155 value_r |= RLIV_RHV(vol_r);
156
157 tlv320_write_reg(REG_LLIV, value_l);
158 tlv320_write_reg(REG_RLIV, value_r);
159}
160
161/**
162 * Mute (mute=true) or enable sound (mute=false)
163 *
164 */
165void tlv320_mute(bool mute)
166{
167 unsigned value_l = tlv320regs[REG_LHV];
168 unsigned value_r = tlv320regs[REG_RHV];
169
170 if (mute)
171 {
172 value_l |= LHV_LHV(HEADPHONE_MUTE);
173 value_r |= RHV_RHV(HEADPHONE_MUTE);
174 }
175 else
176 {
177 value_l |= LHV_LHV(tlv320.vol_l);
178 value_r |= RHV_RHV(tlv320.vol_r);
179 }
180
181 tlv320_write_reg(REG_LHV, value_r);
182 tlv320_write_reg(REG_RHV, value_r);
183}
184
185void tlv320_close()
186{
187 /* todo */
188}
189
190void tlv320_enable_recording(bool source_mic)
191{
192 unsigned value_pc = tlv320regs[REG_PC];
193 unsigned value_aap = tlv320regs[REG_AAP];
194
195 /* select source*/
196 if (source_mic)
197 {
198 value_aap &= ~AAP_INSEL;
199 value_pc |= PC_MIC;
200 }
201 else
202 {
203 value_aap |= AAP_INSEL;
204 value_pc |= PC_LINE;
205 }
206
207 /* poweron adc */
208 value_pc |= PC_ADC;
209
210 tlv320_write_reg(REG_AAP, value_aap);
211 tlv320_write_reg(REG_PC, value_pc);
212}
213
214void tlv320_disable_recording()
215{
216 unsigned value = tlv320regs[REG_PC];
217
218 /* powerdown mic, linein and adc */
219 value &= ~(PC_MIC | PC_LINE | PC_ADC);
220
221 /* powerdown mic, linein and adc */
222 tlv320_write_reg(REG_PC, value);
223} \ No newline at end of file
diff --git a/firmware/export/tlv320.h b/firmware/export/tlv320.h
index 0e50e4f6d1..70ba56e3e2 100644
--- a/firmware/export/tlv320.h
+++ b/firmware/export/tlv320.h
@@ -22,10 +22,15 @@
22 22
23/*** definitions ***/ 23/*** definitions ***/
24 24
25extern void tlv320_reset(void); 25extern void tlv320_init();
26extern int tlv320_init(void); 26extern void tlv320_reset();
27extern int tlv320_set_headphone_vol(int vol_l, int vol_r); 27extern void tlv320_enable_output(bool enable);
28extern int tlv320_mute(bool mute); 28extern void tlv320_set_headphone_vol(int vol_l, int vol_r);
29extern void tlv320_set_linein_vol(int vol_l, int vol_r);
30extern void tlv320_mute(bool mute);
31extern void tlv320_close();
32extern void tlv320_enable_recording(bool source_mic);
33extern void tlv320_disable_recording();
29 34
30#define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */ 35#define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */
31 36
@@ -35,8 +40,8 @@ extern int tlv320_mute(bool mute);
35/* REG_LLIV: Left line input channel volume control */ 40/* REG_LLIV: Left line input channel volume control */
36#define REG_LLIV 0x0 41#define REG_LLIV 0x0
37#define LLIV_LRS (0 << 8) /* simultaneous volume/mute update */ 42#define LLIV_LRS (0 << 8) /* simultaneous volume/mute update */
38#define LIM (1 << 7) /* Left line input mute */ 43#define LLIV_LIM (1 << 7) /* Left line input mute */
39#define LIV ((x) & 0x1f)/* Left line input volume control */ 44#define LLIV_LIV ((x) & 0x1f)/* Left line input volume control */
40 45
41/* REG_RLIV: Right line input channel volume control */ 46/* REG_RLIV: Right line input channel volume control */
42#define REG_RLIV 0x1 47#define REG_RLIV 0x1
@@ -75,7 +80,7 @@ extern int tlv320_mute(bool mute);
75 80
76/* REG_PC: Power Down Control */ 81/* REG_PC: Power Down Control */
77#define REG_PC 0x6 82#define REG_PC 0x6
78#define PC_OFF (0 << 7) /* Device power */ 83#define PC_ON (0 << 7) /* Device power */
79#define PC_CLK (0 << 6) /* Clock */ 84#define PC_CLK (0 << 6) /* Clock */
80#define PC_OSC (0 << 5) /* Oscillator */ 85#define PC_OSC (0 << 5) /* Oscillator */
81#define PC_OUT (0 << 4) /* Outputs */ 86#define PC_OUT (0 << 4) /* Outputs */
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index 17350edfb5..c79902845a 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -24,7 +24,11 @@
24#ifndef SIMULATOR 24#ifndef SIMULATOR
25#include "cpu.h" 25#include "cpu.h"
26#include "i2c.h" 26#include "i2c.h"
27#if defined(HAVE_UDA1380)
27#include "uda1380.h" 28#include "uda1380.h"
29#elif defined(HAVE_TLV320)
30#include "tlv320.h"
31#endif
28#include "system.h" 32#include "system.h"
29#endif 33#endif
30#include "logf.h" 34#include "logf.h"
@@ -181,13 +185,18 @@ void pcm_play_data(void (*get_more)(unsigned char** start, long* size))
181{ 185{
182 unsigned char *start; 186 unsigned char *start;
183 long size; 187 long size;
184 188
185 callback_for_more = get_more; 189 callback_for_more = get_more;
186 190
187 get_more((unsigned char **)&start, (long *)&size); 191 get_more((unsigned char **)&start, (long *)&size);
188 get_more(&next_start, &next_size); 192 get_more(&next_start, &next_size);
189 dma_start(start, size); 193 dma_start(start, size);
194
195#if defined(HAVE_UDA1380)
190 uda1380_mute(false); 196 uda1380_mute(false);
197#elif defined(HAVE_TLV320)
198 tlv320_mute(false);
199#endif
191} 200}
192 201
193long pcm_get_bytes_waiting(void) 202long pcm_get_bytes_waiting(void)
@@ -198,7 +207,12 @@ long pcm_get_bytes_waiting(void)
198void pcm_play_stop(void) 207void pcm_play_stop(void)
199{ 208{
200 if (pcm_playing) { 209 if (pcm_playing) {
210
211#if defined(HAVE_UDA1380)
201 uda1380_mute(true); 212 uda1380_mute(true);
213#elif defined(HAVE_TLV320)
214 tlv320_mute(true);
215#endif
202 dma_stop(); 216 dma_stop();
203 } 217 }
204} 218}
@@ -216,14 +230,23 @@ void pcm_play_pause(bool play)
216 IIS2CONFIG = (pcm_freq << 12) | 0x300 | 4 << 2; 230 IIS2CONFIG = (pcm_freq << 12) | 0x300 | 4 << 2;
217 EBU1CONFIG = (7 << 12) | (3 << 8) | (1 << 5) | (5 << 2); 231 EBU1CONFIG = (7 << 12) | (3 << 8) | (1 << 5) | (5 << 2);
218 DCR0 |= DMA_EEXT | DMA_START; 232 DCR0 |= DMA_EEXT | DMA_START;
219 233
234#if defined(HAVE_UDA1380)
220 uda1380_mute(false); 235 uda1380_mute(false);
236#elif defined(HAVE_TLV320)
237 tlv320_mute(false);
238#endif
221 } 239 }
222 else if(!pcm_paused && !play) 240 else if(!pcm_paused && !play)
223 { 241 {
224 logf("pause"); 242 logf("pause");
243
244#if defined(HAVE_UDA1380)
225 uda1380_mute(true); 245 uda1380_mute(true);
226 246#elif defined(HAVE_TLV320)
247 tlv320_mute(true);
248#endif
249
227 /* Disable DMA peripheral request. */ 250 /* Disable DMA peripheral request. */
228 DCR0 &= ~DMA_EEXT; 251 DCR0 &= ~DMA_EEXT;
229 IIS2CONFIG = 0x800; 252 IIS2CONFIG = 0x800;
@@ -250,7 +273,7 @@ void DMA0(void)
250 273
251 DSR0 = 1; /* Clear interrupt */ 274 DSR0 = 1; /* Clear interrupt */
252 DCR0 &= ~DMA_EEXT; 275 DCR0 &= ~DMA_EEXT;
253 276
254 /* Stop on error */ 277 /* Stop on error */
255 if(res & 0x70) 278 if(res & 0x70)
256 { 279 {
@@ -274,7 +297,7 @@ void DMA0(void)
274 logf("DMA No Data:0x%04x", res); 297 logf("DMA No Data:0x%04x", res);
275 } 298 }
276 } 299 }
277 300
278 IPR |= (1<<14); /* Clear pending interrupt request */ 301 IPR |= (1<<14); /* Clear pending interrupt request */
279} 302}
280 303
@@ -282,8 +305,12 @@ void pcm_init(void)
282{ 305{
283 pcm_playing = false; 306 pcm_playing = false;
284 pcm_paused = false; 307 pcm_paused = false;
285 308
309#if defined(HAVE_UDA1380)
286 uda1380_init(); 310 uda1380_init();
311#elif defined(HAVE_TLV320)
312 tlv320_init();
313#endif
287 314
288 BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */ 315 BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */
289 DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */ 316 DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */
@@ -292,18 +319,25 @@ void pcm_init(void)
292 319
293 /* Reset the audio FIFO */ 320 /* Reset the audio FIFO */
294 IIS2CONFIG = 0x800; 321 IIS2CONFIG = 0x800;
295 322
296 /* Enable interrupt at level 7, priority 0 */ 323 /* Enable interrupt at level 7, priority 0 */
297 ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00; 324 ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00;
298 IMR &= ~(1<<14); /* bit 14 is DMA0 */ 325 IMR &= ~(1<<14); /* bit 14 is DMA0 */
299 326
300 pcm_set_frequency(44100); 327 pcm_set_frequency(44100);
301 328
302 /* Turn on headphone power with audio output muted. */ 329 /* Turn on headphone power with audio output muted. */
330#if defined(HAVE_UDA1380)
303 uda1380_mute(true); 331 uda1380_mute(true);
332#elif defined(HAVE_TLV320)
333 tlv320_mute(true);
334#endif
304 sleep(HZ/4); 335 sleep(HZ/4);
336#if defined(HAVE_UDA1380)
305 uda1380_enable_output(true); 337 uda1380_enable_output(true);
306 338#elif defined(HAVE_TLV320)
339 tlv320_enable_output(true);
340#endif
307 /* Call dma_stop to initialize everything. */ 341 /* Call dma_stop to initialize everything. */
308 dma_stop(); 342 dma_stop();
309} 343}
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c
index 7ecd1d1bbb..3101a16e02 100644
--- a/firmware/pcm_record.c
+++ b/firmware/pcm_record.c
@@ -30,7 +30,11 @@
30 30
31#include "cpu.h" 31#include "cpu.h"
32#include "i2c.h" 32#include "i2c.h"
33#if defined(HAVE_UDA1380)
33#include "uda1380.h" 34#include "uda1380.h"
35#elif defined(HAVE_TLV320)
36#include "tlv320.h"
37#endif
34#include "system.h" 38#include "system.h"
35#include "usb.h" 39#include "usb.h"
36 40
@@ -61,7 +65,7 @@ static unsigned long record_start_time; /* Value of current_tick when re
61static unsigned long pause_start_time; /* Value of current_tick when pause was started */ 65static unsigned long pause_start_time; /* Value of current_tick when pause was started */
62 66
63static int rec_gain, rec_volume; 67static int rec_gain, rec_volume;
64static bool show_waveform; 68static bool show_waveform;
65static int init_done = 0; 69static int init_done = 0;
66static int wav_file; 70static int wav_file;
67static char recording_filename[MAX_PATH]; 71static char recording_filename[MAX_PATH];
@@ -72,12 +76,12 @@ static char recording_filename[MAX_PATH];
72 Some estimates: 76 Some estimates:
73 44100 HZ * 4 = 176400 bytes/s 77 44100 HZ * 4 = 176400 bytes/s
74 Refresh LCD 10 HZ = 176400 / 10 = 17640 bytes ~=~ 1024*16 bytes 78 Refresh LCD 10 HZ = 176400 / 10 = 17640 bytes ~=~ 1024*16 bytes
75 79
76 If NUM_BUFFERS is 80 we can hold ~8 sec of data in memory 80 If NUM_BUFFERS is 80 we can hold ~8 sec of data in memory
77 ALL_BUFFER_SIZE will be 1024*16 * 80 = 1310720 bytes 81 ALL_BUFFER_SIZE will be 1024*16 * 80 = 1310720 bytes
78*/ 82*/
79 83
80#define NUM_BUFFERS 80 84#define NUM_BUFFERS 80
81#define EACH_BUFFER_SIZE (1024*16) /* Multiple of 4. Use small value to get responsive waveform */ 85#define EACH_BUFFER_SIZE (1024*16) /* Multiple of 4. Use small value to get responsive waveform */
82#define ALL_BUFFERS_SIZE (NUM_BUFFERS * EACH_BUFFER_SIZE) 86#define ALL_BUFFERS_SIZE (NUM_BUFFERS * EACH_BUFFER_SIZE)
83 87
@@ -130,7 +134,7 @@ void pcm_init_recording(void)
130 wav_file = -1; 134 wav_file = -1;
131 read_index = 0; 135 read_index = 0;
132 write_index = 0; 136 write_index = 0;
133 137
134 queue_init(&pcmrec_queue); 138 queue_init(&pcmrec_queue);
135 create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack), pcmrec_thread_name); 139 create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack), pcmrec_thread_name);
136} 140}
@@ -138,16 +142,16 @@ void pcm_init_recording(void)
138void pcm_open_recording(void) 142void pcm_open_recording(void)
139{ 143{
140 init_done = 0; 144 init_done = 0;
141 145
142 logf("pcm_open_rec"); 146 logf("pcm_open_rec");
143 147
144 queue_post(&pcmrec_queue, PCMREC_OPEN, 0); 148 queue_post(&pcmrec_queue, PCMREC_OPEN, 0);
145 149
146 while (init_done) 150 while (init_done)
147 { 151 {
148 sleep(HZ >> 8); 152 sleep(HZ >> 8);
149 } 153 }
150 154
151 logf("pcm_open_rec done"); 155 logf("pcm_open_rec done");
152} 156}
153 157
@@ -162,10 +166,10 @@ void pcm_close_recording(void)
162unsigned long pcm_status(void) 166unsigned long pcm_status(void)
163{ 167{
164 unsigned long ret = 0; 168 unsigned long ret = 0;
165 169
166 if (is_recording) 170 if (is_recording)
167 ret |= AUDIO_STATUS_RECORD; 171 ret |= AUDIO_STATUS_RECORD;
168 172
169 return ret; 173 return ret;
170} 174}
171 175
@@ -193,7 +197,7 @@ unsigned long pcm_recorded_time(void)
193 197
194unsigned long pcm_num_recorded_bytes(void) 198unsigned long pcm_num_recorded_bytes(void)
195{ 199{
196 200
197 if (is_recording) 201 if (is_recording)
198 { 202 {
199 return num_rec_bytes; 203 return num_rec_bytes;
@@ -222,10 +226,12 @@ void pcm_resume_recording(void)
222 */ 226 */
223void pcm_set_recording_options(int source, bool enable_waveform) 227void pcm_set_recording_options(int source, bool enable_waveform)
224{ 228{
229#if defined(HAVE_UDA1380)
225 uda1380_enable_recording(source); 230 uda1380_enable_recording(source);
226 231#elif defined(HAVE_TLV320)
232 tlv320_enable_recording(source);
233#endif
227 show_waveform = enable_waveform; 234 show_waveform = enable_waveform;
228
229} 235}
230 236
231 237
@@ -238,21 +244,20 @@ void pcm_set_recording_gain(int gain, int volume)
238{ 244{
239 rec_gain = gain; 245 rec_gain = gain;
240 rec_volume = volume; 246 rec_volume = volume;
241 247
242 queue_post(&pcmrec_queue, PCMREC_SET_GAIN, 0); 248 queue_post(&pcmrec_queue, PCMREC_SET_GAIN, 0);
243
244} 249}
245 250
246/** 251/**
247 * Start recording 252 * Start recording
248 * 253 *
249 * Use pcm_set_recording_options before calling record 254 * Use pcm_set_recording_options before calling record
250 */ 255 */
251void pcm_record(const char *filename) 256void pcm_record(const char *filename)
252{ 257{
253 strncpy(recording_filename, filename, MAX_PATH - 1); 258 strncpy(recording_filename, filename, MAX_PATH - 1);
254 recording_filename[MAX_PATH - 1] = 0; 259 recording_filename[MAX_PATH - 1] = 0;
255 260
256 queue_post(&pcmrec_queue, PCMREC_START, 0); 261 queue_post(&pcmrec_queue, PCMREC_START, 0);
257} 262}
258 263
@@ -263,19 +268,17 @@ void pcm_stop_recording(void)
263{ 268{
264 if (is_recording) 269 if (is_recording)
265 is_stopping = 1; 270 is_stopping = 1;
266 271
267 queue_post(&pcmrec_queue, PCMREC_STOP, 0); 272 queue_post(&pcmrec_queue, PCMREC_STOP, 0);
268 273
269 logf("pcm_stop_recording"); 274 logf("pcm_stop_recording");
270 275
271 while (is_stopping) 276 while (is_stopping)
272 { 277 {
273 sleep(HZ >> 4); 278 sleep(HZ >> 4);
274 } 279 }
275 280
276 logf("pcm_stop_recording done"); 281 logf("pcm_stop_recording done");
277
278
279} 282}
280 283
281 284
@@ -303,40 +306,40 @@ void pcmrec_callback(bool flush)
303 num_ready += NUM_BUFFERS; 306 num_ready += NUM_BUFFERS;
304 307
305 /* we can consume up to num_ready buffers */ 308 /* we can consume up to num_ready buffers */
306 309
307#ifdef HAVE_REMOTE_LCD 310#ifdef HAVE_REMOTE_LCD
308 /* Draw waveform on remote LCD */ 311 /* Draw waveform on remote LCD */
309 if (show_waveform && num_ready>0) 312 if (show_waveform && num_ready>0)
310 { 313 {
311 short *buf; 314 short *buf;
312 long x,y,offset; 315 long x,y,offset;
313 int show_index; 316 int show_index;
314 317
315 /* Just display the last buffer (most recent one) */ 318 /* Just display the last buffer (most recent one) */
316 show_index = read_index + num_ready - 1; 319 show_index = read_index + num_ready - 1;
317 buf = (short*)rec_buffers[show_index]; 320 buf = (short*)rec_buffers[show_index];
318 321
319 lcd_remote_clear_display(); 322 lcd_remote_clear_display();
320 323
321 offset = 0; 324 offset = 0;
322 for (x=0; x<LCD_REMOTE_WIDTH-1; x++) 325 for (x=0; x<LCD_REMOTE_WIDTH-1; x++)
323 { 326 {
324 y = buf[offset] * (LCD_REMOTE_HEIGHT / 2) *5; /* The 5 is just 'zooming' */ 327 y = buf[offset] * (LCD_REMOTE_HEIGHT / 2) *5; /* The 5 is just 'zooming' */
325 y = y >> 15; /* Divide with SHRT_MAX */ 328 y = y >> 15; /* Divide with SHRT_MAX */
326 y += LCD_REMOTE_HEIGHT/2; 329 y += LCD_REMOTE_HEIGHT/2;
327 330
328 if (y < 2) y=2; 331 if (y < 2) y=2;
329 if (y >= LCD_REMOTE_HEIGHT-2) y = LCD_REMOTE_HEIGHT-2; 332 if (y >= LCD_REMOTE_HEIGHT-2) y = LCD_REMOTE_HEIGHT-2;
330 333
331 lcd_remote_drawpixel(x,y); 334 lcd_remote_drawpixel(x,y);
332 335
333 offset += (EACH_BUFFER_SIZE/2) / LCD_REMOTE_WIDTH; 336 offset += (EACH_BUFFER_SIZE/2) / LCD_REMOTE_WIDTH;
334 } 337 }
335 338
336 lcd_remote_update(); 339 lcd_remote_update();
337 } 340 }
338 341
339#endif 342#endif
340 343
341 /* Note: This might be a good place to call the 'codec' later */ 344 /* Note: This might be a good place to call the 'codec' later */
342 345
@@ -348,43 +351,41 @@ void pcmrec_callback(bool flush)
348 { 351 {
349 unsigned long *ptr = (unsigned long*)rec_buffers[read_index]; 352 unsigned long *ptr = (unsigned long*)rec_buffers[read_index];
350 int i; 353 int i;
351 354
352 for (i=0; i<EACH_BUFFER_SIZE * num_ready / 4; i++) 355 for (i=0; i<EACH_BUFFER_SIZE * num_ready / 4; i++)
353 { 356 {
354 *ptr = SWAB32(*ptr); 357 *ptr = SWAB32(*ptr);
355 ptr++; 358 ptr++;
356 } 359 }
357 360
358 write(wav_file, rec_buffers[read_index], EACH_BUFFER_SIZE * num_ready); 361 write(wav_file, rec_buffers[read_index], EACH_BUFFER_SIZE * num_ready);
359 362
360 read_index+=num_ready; 363 read_index+=num_ready;
361 if (read_index >= NUM_BUFFERS) 364 if (read_index >= NUM_BUFFERS)
362 read_index -= NUM_BUFFERS; 365 read_index -= NUM_BUFFERS;
363 } 366 }
364 367
365 } else 368 } else
366 { 369 {
367 /* In this case we must consume the buffers otherwise we will */ 370 /* In this case we must consume the buffers otherwise we will */
368 /* get 'dma1 overrun' pretty fast */ 371 /* get 'dma1 overrun' pretty fast */
369 372
370 read_index+=num_ready; 373 read_index+=num_ready;
371 if (read_index >= NUM_BUFFERS) 374 if (read_index >= NUM_BUFFERS)
372 read_index -= NUM_BUFFERS; 375 read_index -= NUM_BUFFERS;
373 } 376 }
374} 377}
375 378
376
377
378 379
379void pcmrec_dma_start(void) 380void pcmrec_dma_start(void)
380{ 381{
381 DAR1 = (unsigned long)rec_buffers[write_index++]; /* Destination address */ 382 DAR1 = (unsigned long)rec_buffers[write_index++]; /* Destination address */
382 SAR1 = (unsigned long)&PDIR2; /* Source address */ 383 SAR1 = (unsigned long)&PDIR2; /* Source address */
383 BCR1 = EACH_BUFFER_SIZE; /* Bytes to transfer */ 384 BCR1 = EACH_BUFFER_SIZE; /* Bytes to transfer */
384 385
385 /* Start the DMA transfer.. */ 386 /* Start the DMA transfer.. */
386 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START; 387 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
387 388
388 logf("dma1 started"); 389 logf("dma1 started");
389} 390}
390 391
@@ -396,7 +397,7 @@ void DMA1(void)
396 int res = DSR1; 397 int res = DSR1;
397 398
398 DSR1 = 1; /* Clear interrupt */ 399 DSR1 = 1; /* Clear interrupt */
399 400
400 int_count++; 401 int_count++;
401 402
402 if (res & 0x70) 403 if (res & 0x70)
@@ -404,41 +405,41 @@ void DMA1(void)
404 DCR1 = 0; /* Stop DMA transfer */ 405 DCR1 = 0; /* Stop DMA transfer */
405 error_count++; 406 error_count++;
406 is_recording = 0; 407 is_recording = 0;
407 408
408 logf("dma1 err 0x%x", res); 409 logf("dma1 err 0x%x", res);
409 410
410 } else 411 } else
411 { 412 {
412 num_rec_bytes += EACH_BUFFER_SIZE; 413 num_rec_bytes += EACH_BUFFER_SIZE;
413 414
414 write_index++; 415 write_index++;
415 if (write_index >= NUM_BUFFERS) 416 if (write_index >= NUM_BUFFERS)
416 write_index = 0; 417 write_index = 0;
417 418
418 if (is_stopping || !is_recording) 419 if (is_stopping || !is_recording)
419 { 420 {
420 DCR1 = 0; /* Stop DMA transfer */ 421 DCR1 = 0; /* Stop DMA transfer */
421 is_recording = 0; 422 is_recording = 0;
422 423
423 logf("dma1 stopping"); 424 logf("dma1 stopping");
424 425
425 } else if (write_index == read_index) 426 } else if (write_index == read_index)
426 { 427 {
427 DCR1 = 0; /* Stop DMA transfer */ 428 DCR1 = 0; /* Stop DMA transfer */
428 is_recording = 0; 429 is_recording = 0;
429 430
430 logf("dma1 overrun"); 431 logf("dma1 overrun");
431 432
432 } else 433 } else
433 { 434 {
434 DAR1 = (unsigned long)rec_buffers[write_index]; /* Destination address */ 435 DAR1 = (unsigned long)rec_buffers[write_index]; /* Destination address */
435 BCR1 = EACH_BUFFER_SIZE; 436 BCR1 = EACH_BUFFER_SIZE;
436 437
437 queue_post(&pcmrec_queue, PCMREC_GOT_DATA, NULL); 438 queue_post(&pcmrec_queue, PCMREC_GOT_DATA, NULL);
438 439
439 } 440 }
440 } 441 }
441 442
442 IPR |= (1<<15); /* Clear pending interrupt request */ 443 IPR |= (1<<15); /* Clear pending interrupt request */
443} 444}
444 445
@@ -450,7 +451,7 @@ static int start_wave(void)
450 0x10,0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0, 451 0x10,0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0,
451 4,0,0x10,0,'d','a','t','a',0,0,0,0 452 4,0,0x10,0,'d','a','t','a',0,0,0,0
452 }; 453 };
453 454
454 wav_file = open(recording_filename, O_RDWR|O_CREAT|O_TRUNC); 455 wav_file = open(recording_filename, O_RDWR|O_CREAT|O_TRUNC);
455 if (wav_file < 0) 456 if (wav_file < 0)
456 { 457 {
@@ -458,7 +459,7 @@ static int start_wave(void)
458 logf("create failed: %d", wav_file); 459 logf("create failed: %d", wav_file);
459 return -1; 460 return -1;
460 } 461 }
461 462
462 if (sizeof(header) != write(wav_file, header, sizeof(header))) 463 if (sizeof(header) != write(wav_file, header, sizeof(header)))
463 { 464 {
464 close(wav_file); 465 close(wav_file);
@@ -466,7 +467,7 @@ static int start_wave(void)
466 logf("write failed"); 467 logf("write failed");
467 return -2; 468 return -2;
468 } 469 }
469 470
470 return 0; 471 return 0;
471} 472}
472 473
@@ -474,15 +475,15 @@ static int start_wave(void)
474static void close_wave(void) 475static void close_wave(void)
475{ 476{
476 long l; 477 long l;
477 478
478 l = SWAB32(num_rec_bytes + 36); 479 l = SWAB32(num_rec_bytes + 36);
479 lseek(wav_file, 4, SEEK_SET); 480 lseek(wav_file, 4, SEEK_SET);
480 write(wav_file, &l, 4); 481 write(wav_file, &l, 4);
481 482
482 l = SWAB32(num_rec_bytes); 483 l = SWAB32(num_rec_bytes);
483 lseek(wav_file, 40, SEEK_SET); 484 lseek(wav_file, 40, SEEK_SET);
484 write(wav_file, &l, 4); 485 write(wav_file, &l, 4);
485 486
486 close(wav_file); 487 close(wav_file);
487 wav_file = -1; 488 wav_file = -1;
488} 489}
@@ -490,19 +491,19 @@ static void close_wave(void)
490static void pcmrec_start(void) 491static void pcmrec_start(void)
491{ 492{
492 logf("pcmrec_start"); 493 logf("pcmrec_start");
493 494
494 if (is_recording) 495 if (is_recording)
495 return; 496 return;
496 497
497 if (wav_file != -1) 498 if (wav_file != -1)
498 close(wav_file); 499 close(wav_file);
499 500
500 logf("rec: %s", recording_filename); 501 logf("rec: %s", recording_filename);
501 502
502 start_wave(); /* todo: send signal to pcm_record if we have failed */ 503 start_wave(); /* todo: send signal to pcm_record if we have failed */
503 504
504 num_rec_bytes = 0; 505 num_rec_bytes = 0;
505 506
506 /* Store the current time */ 507 /* Store the current time */
507 record_start_time = current_tick; 508 record_start_time = current_tick;
508 509
@@ -514,29 +515,29 @@ static void pcmrec_start(void)
514 is_recording = 1; 515 is_recording = 1;
515 516
516 pcmrec_dma_start(); 517 pcmrec_dma_start();
517 518
518} 519}
519 520
520static void pcmrec_stop(void) 521static void pcmrec_stop(void)
521{ 522{
522 /* wait for recording to finish */ 523 /* wait for recording to finish */
523 524
524 /* todo: Abort current DMA transfer using DCR1.. */ 525 /* todo: Abort current DMA transfer using DCR1.. */
525 526
526 logf("pcmrec_stop"); 527 logf("pcmrec_stop");
527 528
528 while (is_recording) 529 while (is_recording)
529 { 530 {
530 sleep(HZ >> 4); 531 sleep(HZ >> 4);
531 } 532 }
532 533
533 logf("pcmrec_stop done"); 534 logf("pcmrec_stop done");
534 535
535 /* Write unfinished buffers to file */ 536 /* Write unfinished buffers to file */
536 pcmrec_callback(true); 537 pcmrec_callback(true);
537 538
538 close_wave(); 539 close_wave();
539 540
540 is_stopping = 0; 541 is_stopping = 0;
541} 542}
542 543
@@ -544,7 +545,7 @@ static void pcmrec_open(void)
544{ 545{
545 unsigned long buffer_start; 546 unsigned long buffer_start;
546 int i; 547 int i;
547 548
548 show_waveform = 0; 549 show_waveform = 0;
549 is_recording = 0; 550 is_recording = 0;
550 is_stopping = 0; 551 is_stopping = 0;
@@ -555,7 +556,7 @@ static void pcmrec_open(void)
555 556
556 buffer_start = (unsigned long)(&audiobuf[(audiobufend - audiobuf) - (ALL_BUFFERS_SIZE + 16)]); 557 buffer_start = (unsigned long)(&audiobuf[(audiobufend - audiobuf) - (ALL_BUFFERS_SIZE + 16)]);
557 buffer_start &= ~3; 558 buffer_start &= ~3;
558 559
559 for (i=0; i<NUM_BUFFERS; i++) 560 for (i=0; i<NUM_BUFFERS; i++)
560 { 561 {
561 rec_buffers[i] = (unsigned char*)(buffer_start + EACH_BUFFER_SIZE * i); 562 rec_buffers[i] = (unsigned char*)(buffer_start + EACH_BUFFER_SIZE * i);
@@ -572,61 +573,69 @@ static void pcmrec_open(void)
572 ICR4 = (ICR4 & 0xffffff00) | 0x0000001c; /* Enable interrupt at level 7, priority 0 */ 573 ICR4 = (ICR4 & 0xffffff00) | 0x0000001c; /* Enable interrupt at level 7, priority 0 */
573 IMR &= ~(1<<15); /* bit 15 is DMA1 */ 574 IMR &= ~(1<<15); /* bit 15 is DMA1 */
574 575
575 init_done = 1; 576 init_done = 1;
576} 577}
577 578
578static void pcmrec_close(void) 579static void pcmrec_close(void)
579{ 580{
581#if defined(HAVE_UDA1380)
580 uda1380_disable_recording(); 582 uda1380_disable_recording();
583#elif defined(HAVE_TLV320)
584 tlv320_disable_recording();
585#endif
581 586
582 DMAROUTE = (DMAROUTE & 0xffff00ff); 587 DMAROUTE = (DMAROUTE & 0xffff00ff);
583 ICR4 = (ICR4 & 0xffffff00); /* Disable interrupt */ 588 ICR4 = (ICR4 & 0xffffff00); /* Disable interrupt */
584 IMR |= (1<<15); /* bit 15 is DMA1 */ 589 IMR |= (1<<15); /* bit 15 is DMA1 */
585 590
586} 591}
587 592
588static void pcmrec_thread(void) 593static void pcmrec_thread(void)
589{ 594{
590 struct event ev; 595 struct event ev;
591 596
592 logf("thread pcmrec start"); 597 logf("thread pcmrec start");
593 598
594 while (1) 599 while (1)
595 { 600 {
596 queue_wait(&pcmrec_queue, &ev); 601 queue_wait(&pcmrec_queue, &ev);
597 602
598 switch (ev.id) 603 switch (ev.id)
599 { 604 {
600 case PCMREC_OPEN: 605 case PCMREC_OPEN:
601 pcmrec_open(); 606 pcmrec_open();
602 break; 607 break;
603 608
604 case PCMREC_CLOSE: 609 case PCMREC_CLOSE:
605 pcmrec_close(); 610 pcmrec_close();
606 break; 611 break;
607 612
608 case PCMREC_START: 613 case PCMREC_START:
609 pcmrec_start(); 614 pcmrec_start();
610 break; 615 break;
611 616
612 case PCMREC_STOP: 617 case PCMREC_STOP:
613 pcmrec_stop(); 618 pcmrec_stop();
614 break; 619 break;
615 620
616 case PCMREC_PAUSE: 621 case PCMREC_PAUSE:
617 /* todo */ 622 /* todo */
618 break; 623 break;
619 624
620 case PCMREC_RESUME: 625 case PCMREC_RESUME:
621 /* todo */ 626 /* todo */
622 break; 627 break;
623 628
624 case PCMREC_NEW_FILE: 629 case PCMREC_NEW_FILE:
625 /* todo */ 630 /* todo */
626 break; 631 break;
627 632
628 case PCMREC_SET_GAIN: 633 case PCMREC_SET_GAIN:
634#if defined(HAVE_UDA1380)
629 uda1380_set_recvol(rec_gain, rec_gain, rec_volume); 635 uda1380_set_recvol(rec_gain, rec_gain, rec_volume);
636#elif defined(HAVE_TLV320)
637 /* ToDo */
638#endif
630 break; 639 break;
631 640
632 case PCMREC_GOT_DATA: 641 case PCMREC_GOT_DATA:
@@ -637,13 +646,12 @@ static void pcmrec_thread(void)
637 if (!is_recording && !is_stopping) 646 if (!is_recording && !is_stopping)
638 { 647 {
639 usb_acknowledge(SYS_USB_CONNECTED_ACK); 648 usb_acknowledge(SYS_USB_CONNECTED_ACK);
640 usb_wait_for_disconnect(&pcmrec_queue); 649 usb_wait_for_disconnect(&pcmrec_queue);
641 } 650 }
642
643 break; 651 break;
644 } 652 }
645 } 653 }
646 654
647 logf("thread pcmrec done"); 655 logf("thread pcmrec done");
648} 656}
649 657
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 40640cd032..6cd2fbdd3b 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -43,6 +43,8 @@
43#endif 43#endif
44#ifdef HAVE_UDA1380 44#ifdef HAVE_UDA1380
45#include "uda1380.h" 45#include "uda1380.h"
46#eilf HAVE_TLV320
47#include "tlv320.h"
46#endif 48#endif
47#include "logf.h" 49#include "logf.h"
48 50
@@ -377,7 +379,7 @@ static void handle_auto_poweroff(void)
377 last_event_tick = current_tick; 379 last_event_tick = current_tick;
378 } 380 }
379#endif 381#endif
380 382
381 if(timeout && 383 if(timeout &&
382#ifdef CONFIG_TUNER 384#ifdef CONFIG_TUNER
383 (radio_get_status() != FMRADIO_PLAYING) && 385 (radio_get_status() != FMRADIO_PLAYING) &&
@@ -903,6 +905,8 @@ void shutdown_hw(void)
903 mp3_shutdown(); 905 mp3_shutdown();
904#ifdef HAVE_UDA1380 906#ifdef HAVE_UDA1380
905 uda1380_close(); 907 uda1380_close();
908#eilf HAVE_TLV320
909 tlv320_close();
906#endif 910#endif
907#if CONFIG_KEYPAD == ONDIO_PAD 911#if CONFIG_KEYPAD == ONDIO_PAD
908 backlight_off(); 912 backlight_off();
diff --git a/firmware/sound.c b/firmware/sound.c
index 9cac7cbd02..8fb015c27a 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -25,6 +25,8 @@
25#include "mas.h" 25#include "mas.h"
26#ifdef HAVE_UDA1380 26#ifdef HAVE_UDA1380
27#include "uda1380.h" 27#include "uda1380.h"
28#elif HAVE_TLV320
29#include "tlv320.h"
28#endif 30#endif
29#include "dac.h" 31#include "dac.h"
30#include "system.h" 32#include "system.h"