summaryrefslogtreecommitdiff
path: root/firmware/sound.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/sound.c')
-rw-r--r--firmware/sound.c128
1 files changed, 60 insertions, 68 deletions
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
233static const unsigned int bass_table[] = 236static 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 */
324int current_volume = 0; /* -780..+180 */
325int current_balance = 0; /* -960..+960 */
326int current_treble = 0; /* -150..+150 */
327int current_bass = 0; /* -150..+150 */
328
329/* convert tenth of dB volume to register value */
330static int tenthdb2reg(int db) { 327static 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
337static 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 */
373int current_volume = 0; /* -840..0 */
374int 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 */
377static int tenthdb2reg(int db) { 340static 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 */
357int current_volume = 0; /* -780..+180 -840.. 0 */
358int current_balance = 0; /* -960..+960 -840..+840 */
359int current_treble = 0; /* -150..+150 0.. +60 */
360int current_bass = 0; /* -150..+150 0..+240 */
387 361
388static void set_volume(void) 362static 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
413int channel_configuration = SOUND_CHAN_STEREO; 407int 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