summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter D'Hoye <peter.dhoye@gmail.com>2006-06-14 23:36:47 +0000
committerPeter D'Hoye <peter.dhoye@gmail.com>2006-06-14 23:36:47 +0000
commitdf686b89e700111a199dc2551813e1e349d64b26 (patch)
tree3d3349458efe71a4b23d6c2d5ab475604ce60861
parent5db5e6589b1fd62390448beadb15e16a8c52139c (diff)
downloadrockbox-df686b89e700111a199dc2551813e1e349d64b26.tar.gz
rockbox-df686b89e700111a199dc2551813e1e349d64b26.zip
Tweaks to reduce an iriver recording glitch to a minimum. Removed yields from i2c code as a means to shorten the duration, rearranged order of changing to always cause dips and never peaks. Also some code policing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10122 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/i2c-coldfire.c9
-rw-r--r--firmware/drivers/uda1380.c140
2 files changed, 104 insertions, 45 deletions
diff --git a/firmware/drivers/i2c-coldfire.c b/firmware/drivers/i2c-coldfire.c
index a9c3931d36..47aeba757f 100644
--- a/firmware/drivers/i2c-coldfire.c
+++ b/firmware/drivers/i2c-coldfire.c
@@ -120,10 +120,7 @@ int i2c_write_byte(int device, unsigned char data)
120 120
121 /* Wait for bus busy */ 121 /* Wait for bus busy */
122 while (!(regs[O_MBSR] & IBB) && count < MAX_LOOP) 122 while (!(regs[O_MBSR] & IBB) && count < MAX_LOOP)
123 {
124 yield();
125 count++; 123 count++;
126 }
127 124
128 if (count >= MAX_LOOP) 125 if (count >= MAX_LOOP)
129 return -1; 126 return -1;
@@ -132,10 +129,7 @@ int i2c_write_byte(int device, unsigned char data)
132 129
133 /* Wait for interrupt flag */ 130 /* Wait for interrupt flag */
134 while (!(regs[O_MBSR] & IFF) && count < MAX_LOOP) 131 while (!(regs[O_MBSR] & IFF) && count < MAX_LOOP)
135 {
136 yield();
137 count++; 132 count++;
138 }
139 133
140 if (count >= MAX_LOOP) 134 if (count >= MAX_LOOP)
141 return -2; 135 return -2;
@@ -160,10 +154,7 @@ int i2c_gen_start(int device)
160 154
161 /* Wait for bus to become free */ 155 /* Wait for bus to become free */
162 while ((regs[O_MBSR] & IBB) && (count < MAX_LOOP)) 156 while ((regs[O_MBSR] & IBB) && (count < MAX_LOOP))
163 {
164 yield();
165 count++; 157 count++;
166 }
167 158
168 if (count >= MAX_LOOP) 159 if (count >= MAX_LOOP)
169 return -1; 160 return -1;
diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c
index de3faddfe7..ef19dcf1c5 100644
--- a/firmware/drivers/uda1380.c
+++ b/firmware/drivers/uda1380.c
@@ -41,8 +41,8 @@
41 41
42int uda1380_write_reg(unsigned char reg, unsigned short value); 42int uda1380_write_reg(unsigned char reg, unsigned short value);
43unsigned short uda1380_regs[0x30]; 43unsigned short uda1380_regs[0x30];
44short uda1380_balance; 44short recgain_mic;
45short uda1380_volume; 45short recgain_line;
46 46
47/* Definition of a playback configuration to start with */ 47/* Definition of a playback configuration to start with */
48 48
@@ -51,13 +51,20 @@ unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] =
51{ 51{
52 REG_0, EN_DAC | EN_INT | EN_DEC | SYSCLK_256FS | WSPLL_25_50, 52 REG_0, EN_DAC | EN_INT | EN_DEC | SYSCLK_256FS | WSPLL_25_50,
53 REG_I2S, I2S_IFMT_IIS, 53 REG_I2S, I2S_IFMT_IIS,
54 REG_PWR, PON_BIAS, /* PON_HP & PON_DAC is enabled later */ 54 REG_PWR, PON_BIAS,
55 REG_AMIX, AMIX_RIGHT(0x3f) | AMIX_LEFT(0x3f), /* 00=max, 3f=mute */ 55 /* PON_HP & PON_DAC is enabled later */
56 REG_MASTER_VOL, MASTER_VOL_LEFT(0x20) | MASTER_VOL_RIGHT(0x20), /* 00=max, ff=mute */ 56 REG_AMIX, AMIX_RIGHT(0x3f) | AMIX_LEFT(0x3f),
57 REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff), /* 00=max, ff=mute */ 57 /* 00=max, 3f=mute */
58 REG_EQ, EQ_MODE_MAX, /* Bass and tremble = 0 dB */ 58 REG_MASTER_VOL, MASTER_VOL_LEFT(0x20) | MASTER_VOL_RIGHT(0x20),
59 REG_MUTE, MUTE_MASTER | MUTE_CH2, /* Mute everything to start with */ 59 /* 00=max, ff=mute */
60 REG_MIX_CTL, MIX_CTL_MIX, /* Enable mixer */ 60 REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff),
61 /* 00=max, ff=mute */
62 REG_EQ, EQ_MODE_MAX,
63 /* Bass and tremble = 0 dB */
64 REG_MUTE, MUTE_MASTER | MUTE_CH2,
65 /* Mute everything to start with */
66 REG_MIX_CTL, MIX_CTL_MIX,
67 /* Enable mixer */
61 REG_DEC_VOL, 0, 68 REG_DEC_VOL, 0,
62 REG_PGA, MUTE_ADC, 69 REG_PGA, MUTE_ADC,
63 REG_ADC, SKIP_DCFIL, 70 REG_ADC, SKIP_DCFIL,
@@ -110,7 +117,8 @@ int uda1380_set_mixer_vol(int channel1, int channel2)
110 */ 117 */
111void uda1380_set_bass(int value) 118void uda1380_set_bass(int value)
112{ 119{
113 uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~BASS_MASK) | BASSL(value) | BASSR(value)); 120 uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~BASS_MASK)
121 | BASSL(value) | BASSR(value));
114} 122}
115 123
116/** 124/**
@@ -118,7 +126,8 @@ void uda1380_set_bass(int value)
118 */ 126 */
119void uda1380_set_treble(int value) 127void uda1380_set_treble(int value)
120{ 128{
121 uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~TREBLE_MASK) | TREBLEL(value) | TREBLER(value)); 129 uda1380_write_reg(REG_EQ, (uda1380_regs[REG_EQ] & ~TREBLE_MASK)
130 | TREBLEL(value) | TREBLER(value));
122} 131}
123 132
124/** 133/**
@@ -187,12 +196,13 @@ void uda1380_reset(void)
187/* Initialize UDA1380 codec with default register values (uda1380_defaults) */ 196/* Initialize UDA1380 codec with default register values (uda1380_defaults) */
188int uda1380_init(void) 197int uda1380_init(void)
189{ 198{
199 recgain_mic = 0;
200 recgain_line = 0;
201
190 uda1380_reset(); 202 uda1380_reset();
191 203
192 if (uda1380_set_regs() == -1) 204 if (uda1380_set_regs() == -1)
193 return -1; 205 return -1;
194 uda1380_balance = 0;
195 uda1380_volume = 0x20; /* Taken from uda1380_defaults */
196 206
197 return 0; 207 return 0;
198} 208}
@@ -222,14 +232,19 @@ void uda1380_enable_recording(bool source_mic)
222 232
223 if (source_mic) 233 if (source_mic)
224 { 234 {
235 /* VGA_GAIN: 0=0 dB, F=30dB */
225 uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_LNA | PON_ADCL); 236 uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_LNA | PON_ADCL);
226 uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & VGA_GAIN_MASK) | SEL_LNA | SEL_MIC | EN_DCFIL); /* VGA_GAIN: 0=0 dB, F=30dB */ 237 uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & VGA_GAIN_MASK)
238 | SEL_LNA | SEL_MIC | EN_DCFIL);
227 uda1380_write_reg(REG_PGA, 0); 239 uda1380_write_reg(REG_PGA, 0);
228 } else 240 } else
229 { 241 {
230 uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_PGAL | PON_ADCL | PON_PGAR | PON_ADCR); 242 /* PGA_GAIN: 0=0 dB, F=24dB */
243 uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_PGAL | PON_ADCL
244 | PON_PGAR | PON_ADCR);
231 uda1380_write_reg(REG_ADC, EN_DCFIL); 245 uda1380_write_reg(REG_ADC, EN_DCFIL);
232 uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & PGA_GAIN_MASK) | PGA_GAINL(0) | PGA_GAINR(0)); /* PGA_GAIN: 0=0 dB, F=24dB */ 246 uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & PGA_GAIN_MASK)
247 | PGA_GAINL(0) | PGA_GAINR(0));
233 } 248 }
234 249
235 sleep(HZ/8); 250 sleep(HZ/8);
@@ -248,7 +263,9 @@ void uda1380_disable_recording(void)
248 sleep(HZ/8); 263 sleep(HZ/8);
249 264
250 uda1380_write_reg(REG_I2S, I2S_IFMT_IIS); 265 uda1380_write_reg(REG_I2S, I2S_IFMT_IIS);
251 uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] & ~(PON_LNA | PON_ADCL | PON_ADCR | PON_PGAL | PON_PGAR)); 266 uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] & ~(PON_LNA | PON_ADCL
267 | PON_ADCR | PON_PGAL
268 | PON_PGAR));
252 uda1380_write_reg(REG_0, uda1380_regs[REG_0] & ~EN_ADC); 269 uda1380_write_reg(REG_0, uda1380_regs[REG_0] & ~EN_ADC);
253 uda1380_write_reg(REG_ADC, SKIP_DCFIL); 270 uda1380_write_reg(REG_ADC, SKIP_DCFIL);
254} 271}
@@ -260,41 +277,89 @@ void uda1380_disable_recording(void)
260 * AUDIO_GAIN_MIC: left -128 .. 108 -> -64 .. 54 dB gain 277 * AUDIO_GAIN_MIC: left -128 .. 108 -> -64 .. 54 dB gain
261 * AUDIO_GAIN_LINEIN left & right -128 .. 96 -> -64 .. 48 dB gain 278 * AUDIO_GAIN_LINEIN left & right -128 .. 96 -> -64 .. 48 dB gain
262 * 279 *
263 * Note: For all types the value 0 gives 0 dB gain. 280 * Note: - For all types the value 0 gives 0 dB gain.
281 * - order of setting both values determines if the small glitch will
282 be a peak or a dip. The small glitch is caused by the time between
283 setting the two gains
264 */ 284 */
265void uda1380_set_recvol(int left, int right, int type) 285void uda1380_set_recvol(int left, int right, int type)
266{ 286{
267 int left_ag, right_ag; 287 int left_ag, right_ag;
268 /*int old_irq_level;*/
269 288
270 switch (type) 289 switch (type)
271 { 290 {
272 case AUDIO_GAIN_MIC: 291 case AUDIO_GAIN_MIC:
273 left_ag = MIN(MAX(0, left / 4), 15); 292 left_ag = MIN(MAX(0, left / 4), 15);
274 left -= left_ag * 4; 293 left -= left_ag * 4;
275 /* allow nothing in between the two calls */ 294
276 /*old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);*/ 295 if(left < recgain_mic)
277 uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & ~VGA_GAIN_MASK) 296 {
278 | VGA_GAIN(left_ag)); 297 uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left)
279 uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) | DEC_VOLR(left)); 298 | DEC_VOLR(left));
280 /*set_irq_level(old_irq_level);*/ 299 uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC]
300 & ~VGA_GAIN_MASK)
301 | VGA_GAIN(left_ag));
302 }
303 else
304 {
305 uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC]
306 & ~VGA_GAIN_MASK)
307 | VGA_GAIN(left_ag));
308 uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left)
309 | DEC_VOLR(left));
310 }
311 recgain_mic = left;
281 logf("Mic: %dA/%dD", left_ag, left); 312 logf("Mic: %dA/%dD", left_ag, left);
282 break; 313 break;
283 314
284 case AUDIO_GAIN_LINEIN: 315 case AUDIO_GAIN_LINEIN:
285 left_ag = MIN(MAX(0, left / 6), 8); 316 left_ag = MIN(MAX(0, left / 6), 8);
286 left -= left_ag * 6; 317 left -= left_ag * 6;
287 right_ag = MIN(MAX(0, right / 6), 8); 318 right_ag = MIN(MAX(0, right / 6), 8);
288 right -= right_ag * 6; 319 right -= right_ag * 6;
289 /* allow nothing in between the two calls */ 320
290 /*old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);*/ 321 if(left < recgain_line)
291 uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK) 322 {
292 | PGA_GAINL(left_ag) | PGA_GAINR(right_ag)); 323 /* for this order we can combine both registers,
293 uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left) | DEC_VOLR(right)); 324 making the glitch even smaller */
294 /*set_irq_level(old_irq_level);*/ 325 unsigned char data[6];
326 unsigned short value_dec;
327 unsigned short value_pga;
328 value_dec = DEC_VOLL(left) | DEC_VOLR(right);
329 value_pga = (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK)
330 | PGA_GAINL(left_ag) | PGA_GAINR(right_ag);
331
332 data[0] = UDA1380_ADDR;
333 data[1] = REG_DEC_VOL;
334 data[2] = value_dec >> 8;
335 data[3] = value_dec & 0xff;
336 data[4] = value_pga >> 8;
337 data[5] = value_pga & 0xff;
338
339 if (i2c_write(1, data, 6) != 6)
340 {
341 DEBUGF("uda1380 error reg=combi rec gain");
342 }
343 else
344 {
345 uda1380_regs[REG_DEC_VOL] = value_dec;
346 uda1380_regs[REG_PGA] = value_pga;
347 }
348 }
349 else
350 {
351 uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA]
352 & ~PGA_GAIN_MASK)
353 | PGA_GAINL(left_ag)
354 | PGA_GAINR(right_ag));
355 uda1380_write_reg(REG_DEC_VOL, DEC_VOLL(left)
356 | DEC_VOLR(right));
357 }
358
359 recgain_line = left;
295 logf("Line L: %dA/%dD", left_ag, left); 360 logf("Line L: %dA/%dD", left_ag, left);
296 logf("Line R: %dA/%dD", right_ag, right); 361 logf("Line R: %dA/%dD", right_ag, right);
297 break; 362 break;
298 } 363 }
299} 364}
300 365
@@ -311,16 +376,19 @@ void uda1380_set_monitor(int enable)
311 uda1380_write_reg(REG_MUTE, uda1380_regs[REG_MUTE] | MUTE_CH2); 376 uda1380_write_reg(REG_MUTE, uda1380_regs[REG_MUTE] | MUTE_CH2);
312} 377}
313 378
314/* Change the order of the noise chaper, 5th order is recommended above 32kHz */ 379/* Change the order of the noise chaper,
380 5th order is recommended above 32kHz */
315void uda1380_set_nsorder(int order) 381void uda1380_set_nsorder(int order)
316{ 382{
317 switch(order) 383 switch(order)
318 { 384 {
319 case 5: 385 case 5:
320 uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL] | MIX_CTL_SEL_NS); 386 uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL]
387 | MIX_CTL_SEL_NS);
321 break; 388 break;
322 case 3: 389 case 3:
323 default: 390 default:
324 uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL] & ~MIX_CTL_SEL_NS); 391 uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL]
392 & ~MIX_CTL_SEL_NS);
325 } 393 }
326} 394}