diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/uda1380.c | 15 | ||||
-rw-r--r-- | firmware/export/uda1380.h | 3 | ||||
-rw-r--r-- | firmware/sound.c | 128 |
3 files changed, 74 insertions, 72 deletions
diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c index bba7d19d04..7fd65a75e2 100644 --- a/firmware/drivers/uda1380.c +++ b/firmware/drivers/uda1380.c | |||
@@ -54,7 +54,7 @@ unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] = | |||
54 | REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff), /* 00=max, ff=mute */ | 54 | REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff), /* 00=max, ff=mute */ |
55 | REG_EQ, EQ_MODE_MAX, /* Bass and tremble = 0 dB */ | 55 | REG_EQ, EQ_MODE_MAX, /* Bass and tremble = 0 dB */ |
56 | REG_MUTE, MUTE_MASTER, /* Mute everything to start with */ | 56 | REG_MUTE, MUTE_MASTER, /* Mute everything to start with */ |
57 | REG_MIX_CTL, 0, | 57 | REG_MIX_CTL, MIX_CTL_MIX, /* Enable mixer */ |
58 | REG_DEC_VOL, 0, | 58 | REG_DEC_VOL, 0, |
59 | REG_PGA, MUTE_ADC, | 59 | REG_PGA, MUTE_ADC, |
60 | REG_ADC, SKIP_DCFIL, | 60 | REG_ADC, SKIP_DCFIL, |
@@ -87,14 +87,23 @@ int uda1380_write_reg(unsigned char reg, unsigned short value) | |||
87 | /** | 87 | /** |
88 | * Sets left and right master volume (0(max) to 252(muted)) | 88 | * Sets left and right master volume (0(max) to 252(muted)) |
89 | */ | 89 | */ |
90 | int uda1380_setvol(int vol_l, int vol_r) | 90 | int uda1380_set_master_vol(int vol_l, int vol_r) |
91 | { | 91 | { |
92 | return uda1380_write_reg(REG_MASTER_VOL, | 92 | return uda1380_write_reg(REG_MASTER_VOL, |
93 | MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r)); | 93 | MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r)); |
94 | } | 94 | } |
95 | 95 | ||
96 | /** | 96 | /** |
97 | * Sets the bass value (0-15) | 97 | * Sets mixer volume for both channels (0(max) to 228(muted)) |
98 | */ | ||
99 | int uda1380_set_mixer_vol(int channel1, int channel2) | ||
100 | { | ||
101 | return uda1380_write_reg(REG_MIX_VOL, | ||
102 | MIX_VOL_CH_1(channel1) | MIX_VOL_CH_2(channel2)); | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * Sets the bass value (0-12) | ||
98 | */ | 107 | */ |
99 | void uda1380_set_bass(int value) | 108 | void uda1380_set_bass(int value) |
100 | { | 109 | { |
diff --git a/firmware/export/uda1380.h b/firmware/export/uda1380.h index 503b59d102..5a32a50356 100644 --- a/firmware/export/uda1380.h +++ b/firmware/export/uda1380.h | |||
@@ -22,7 +22,8 @@ | |||
22 | 22 | ||
23 | extern int uda1380_init(void); | 23 | extern int uda1380_init(void); |
24 | extern void uda1380_enable_output(bool enable); | 24 | extern void uda1380_enable_output(bool enable); |
25 | extern int uda1380_setvol(int vol_l, int vol_r); | 25 | extern int uda1380_set_master_vol(int vol_l, int vol_r); |
26 | extern int uda1380_set_mixer_vol(int channel1, int channel2); | ||
26 | extern void uda1380_set_bass(int value); | 27 | extern void uda1380_set_bass(int value); |
27 | extern void uda1380_set_treble(int value); | 28 | extern void uda1380_set_treble(int value); |
28 | extern int uda1380_mute(int mute); | 29 | extern int uda1380_mute(int mute); |
diff --git a/firmware/sound.c b/firmware/sound.c index 51244f90ac..9cac7cbd02 100644 --- a/firmware/sound.c +++ b/firmware/sound.c | |||
@@ -229,7 +229,10 @@ int sound_default(int setting) | |||
229 | } | 229 | } |
230 | 230 | ||
231 | #ifndef SIMULATOR | 231 | #ifndef SIMULATOR |
232 | #if CONFIG_HWCODEC == MAS3507D | 232 | #if CONFIG_HWCODEC == MAS3507D /* volume/balance/treble/bass interdependency */ |
233 | #define VOLUME_MIN -780 | ||
234 | #define VOLUME_MAX 180 | ||
235 | |||
233 | static const unsigned int bass_table[] = | 236 | static const unsigned int bass_table[] = |
234 | { | 237 | { |
235 | 0x9e400, /* -15dB */ | 238 | 0x9e400, /* -15dB */ |
@@ -320,61 +323,21 @@ static const unsigned int prescale_table[] = | |||
320 | 0xe9400 /* 15dB */ | 323 | 0xe9400 /* 15dB */ |
321 | }; | 324 | }; |
322 | 325 | ||
323 | /* all values in tenth of dB */ | 326 | /* convert tenth of dB volume to dac3550 register value */ |
324 | int current_volume = 0; /* -780..+180 */ | ||
325 | int current_balance = 0; /* -960..+960 */ | ||
326 | int current_treble = 0; /* -150..+150 */ | ||
327 | int current_bass = 0; /* -150..+150 */ | ||
328 | |||
329 | /* convert tenth of dB volume to register value */ | ||
330 | static int tenthdb2reg(int db) { | 327 | static int tenthdb2reg(int db) { |
331 | if (db < -540) | 328 | if (db < -540) |
332 | return (db + 780) / 30; | 329 | return (db + 780) / 30; |
333 | else | 330 | else |
334 | return (db + 660) / 15; | 331 | return (db + 660) / 15; |
335 | } | 332 | } |
333 | #endif | ||
336 | 334 | ||
337 | static void set_prescaled_volume(void) | 335 | #ifdef HAVE_UDA1380 /* volume/balance/treble/bass interdependency */ |
338 | { | 336 | #define VOLUME_MIN -840 |
339 | int prescale; | 337 | #define VOLUME_MAX 0 |
340 | int l, r; | ||
341 | |||
342 | prescale = MAX(current_bass, current_treble); | ||
343 | if (prescale < 0) | ||
344 | prescale = 0; /* no need to prescale if we don't boost | ||
345 | bass or treble */ | ||
346 | |||
347 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | ||
348 | |||
349 | /* gain up the analog volume to compensate the prescale reduction gain, | ||
350 | * but limit to +18 dB (the maximum the DAC can do */ | ||
351 | if (current_volume + prescale > 180) | ||
352 | prescale = 180 - current_volume; | ||
353 | l = r = current_volume + prescale; | ||
354 | |||
355 | if (current_balance > 0) | ||
356 | { | ||
357 | l -= current_balance; | ||
358 | if (l < -780) | ||
359 | l = -780; | ||
360 | } | ||
361 | if (current_balance < 0) | ||
362 | { | ||
363 | r += current_balance; | ||
364 | if (r < -780) | ||
365 | r = -780; | ||
366 | } | ||
367 | |||
368 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); | ||
369 | } | ||
370 | #elif CONFIG_HWCODEC == MASNONE | ||
371 | #ifdef HAVE_UDA1380 /* iriver H1x0 + H3x0 */ | ||
372 | /* all values in tenth of dB */ | ||
373 | int current_volume = 0; /* -840..0 */ | ||
374 | int current_balance = 0; /* -840..+840 */ | ||
375 | 338 | ||
376 | /* convert tenth of dB volume to register value */ | 339 | /* convert tenth of dB volume to master volume register value */ |
377 | static int tenthdb2reg(int db) { | 340 | static int tenthdb2master(int db) { |
378 | if (db < -720) /* 1.5 dB steps */ | 341 | if (db < -720) /* 1.5 dB steps */ |
379 | return (2940 - db) / 15; | 342 | return (2940 - db) / 15; |
380 | else if (db < -660) /* 0.75 dB steps */ | 343 | else if (db < -660) /* 0.75 dB steps */ |
@@ -384,30 +347,61 @@ static int tenthdb2reg(int db) { | |||
384 | else /* 0.25 dB steps */ | 347 | else /* 0.25 dB steps */ |
385 | return -db * 2 / 5; | 348 | return -db * 2 / 5; |
386 | } | 349 | } |
350 | #endif | ||
351 | |||
352 | #if (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 | ||
353 | /* volume/balance/treble/bass interdependency main part */ | ||
354 | #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) | ||
355 | |||
356 | /* all values in tenth of dB MAS3507D UDA1380 */ | ||
357 | int current_volume = 0; /* -780..+180 -840.. 0 */ | ||
358 | int current_balance = 0; /* -960..+960 -840..+840 */ | ||
359 | int current_treble = 0; /* -150..+150 0.. +60 */ | ||
360 | int current_bass = 0; /* -150..+150 0..+240 */ | ||
387 | 361 | ||
388 | static void set_volume(void) | 362 | static void set_prescaled_volume(void) |
389 | { | 363 | { |
364 | int prescale; | ||
390 | int l, r; | 365 | int l, r; |
391 | 366 | ||
392 | l = r = current_volume; | 367 | prescale = MAX(current_bass, current_treble); |
368 | if (prescale < 0) | ||
369 | prescale = 0; /* no need to prescale if we don't boost | ||
370 | bass or treble */ | ||
371 | |||
372 | #if CONFIG_HWCODEC == MAS3507D | ||
373 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | ||
374 | #else /* UDA1380 */ | ||
375 | uda1380_set_mixer_vol(prescale*2/5, prescale*2/5); | ||
376 | /* The needed range of 0..-24 dB is fortunately linear */ | ||
377 | #endif | ||
378 | |||
379 | /* gain up the analog volume to compensate the prescale gain reduction, | ||
380 | * but limit to the possible maximum */ | ||
381 | if (current_volume + prescale > VOLUME_MAX) | ||
382 | prescale = VOLUME_MAX - current_volume; | ||
383 | l = r = current_volume + prescale; | ||
393 | 384 | ||
394 | if (current_balance > 0) | 385 | if (current_balance > 0) |
395 | { | 386 | { |
396 | l -= current_balance; | 387 | l -= current_balance; |
397 | if (l < -840) | 388 | if (l < VOLUME_MIN) |
398 | l = -840; | 389 | l = VOLUME_MIN; |
399 | } | 390 | } |
400 | if (current_balance < 0) | 391 | if (current_balance < 0) |
401 | { | 392 | { |
402 | r += current_balance; | 393 | r += current_balance; |
403 | if (r < -840) | 394 | if (r < VOLUME_MIN) |
404 | r = -840; | 395 | r = VOLUME_MIN; |
405 | } | 396 | } |
406 | 397 | ||
407 | uda1380_setvol(tenthdb2reg(l), tenthdb2reg(r)); | 398 | #if CONFIG_HWCODEC == MAS3507D |
408 | } | 399 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); |
400 | #else /* UDA1380 */ | ||
401 | uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); | ||
409 | #endif | 402 | #endif |
410 | #endif /* MASNONE */ | 403 | } |
404 | #endif /* (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 */ | ||
411 | #endif /* !SIMULATOR */ | 405 | #endif /* !SIMULATOR */ |
412 | 406 | ||
413 | int channel_configuration = SOUND_CHAN_STEREO; | 407 | int channel_configuration = SOUND_CHAN_STEREO; |
@@ -516,12 +510,9 @@ void sound_set(int setting, int value) | |||
516 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | 510 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
517 | tmp = 0x7f00 * value / 100; | 511 | tmp = 0x7f00 * value / 100; |
518 | mas_codec_writereg(0x10, tmp & 0xff00); | 512 | mas_codec_writereg(0x10, tmp & 0xff00); |
519 | #elif CONFIG_HWCODEC == MAS3507D | 513 | #elif (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 |
520 | current_volume = -780 + (value * 960 / 100); /* tenth of dB */ | 514 | current_volume = VOLUME_MIN + (value * VOLUME_RANGE / 100); |
521 | set_prescaled_volume(); | 515 | set_prescaled_volume(); /* tenth of dB */ |
522 | #elif defined(HAVE_UDA1380) | ||
523 | current_volume = -840 + (value * 840 / 100); /* tenth of dB */ | ||
524 | set_volume(); | ||
525 | #endif | 516 | #endif |
526 | break; | 517 | break; |
527 | 518 | ||
@@ -529,12 +520,9 @@ void sound_set(int setting, int value) | |||
529 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | 520 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
530 | tmp = ((value * 127 / 100) & 0xff) << 8; | 521 | tmp = ((value * 127 / 100) & 0xff) << 8; |
531 | mas_codec_writereg(0x11, tmp & 0xff00); | 522 | mas_codec_writereg(0x11, tmp & 0xff00); |
532 | #elif CONFIG_HWCODEC == MAS3507D | 523 | #elif CONFIG_HWCODEC == MAS3507D || defined HAVE_UDA1380 |
533 | current_balance = value * 960 / 100; /* tenth of dB */ | 524 | current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ |
534 | set_prescaled_volume(); | 525 | set_prescaled_volume(); |
535 | #elif defined(HAVE_UDA1380) | ||
536 | current_balance = value * 840 / 100; /* tenth of dB */ | ||
537 | set_volume(); | ||
538 | #endif | 526 | #endif |
539 | break; | 527 | break; |
540 | 528 | ||
@@ -548,6 +536,8 @@ void sound_set(int setting, int value) | |||
548 | set_prescaled_volume(); | 536 | set_prescaled_volume(); |
549 | #elif defined(HAVE_UDA1380) | 537 | #elif defined(HAVE_UDA1380) |
550 | uda1380_set_bass(value >> 1); | 538 | uda1380_set_bass(value >> 1); |
539 | current_bass = value * 10; | ||
540 | set_prescaled_volume(); | ||
551 | #endif | 541 | #endif |
552 | break; | 542 | break; |
553 | 543 | ||
@@ -561,6 +551,8 @@ void sound_set(int setting, int value) | |||
561 | set_prescaled_volume(); | 551 | set_prescaled_volume(); |
562 | #elif defined(HAVE_UDA1380) | 552 | #elif defined(HAVE_UDA1380) |
563 | uda1380_set_treble(value >> 1); | 553 | uda1380_set_treble(value >> 1); |
554 | current_treble = value * 10; | ||
555 | set_prescaled_volume(); | ||
564 | #endif | 556 | #endif |
565 | break; | 557 | break; |
566 | 558 | ||