Merged in first part of ffmpeg accuracy improvments. No change on my samples, but...
[kugel-rb.git] / firmware / sound.c
blob30b9b6a2d28a7f402f36f126f6ea7195b4f5d667
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 * Copyright (C) 2007 by Christian Gmeiner
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
19 ****************************************************************************/
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include "config.h"
23 #include "sound.h"
24 #include "logf.h"
25 #ifndef SIMULATOR
26 #include "i2c.h"
27 #include "mas.h"
28 #if CONFIG_CPU == PNX0101
29 #include "pnx0101.h"
30 #endif
31 #include "dac.h"
32 #include "system.h"
33 #if CONFIG_CODEC == SWCODEC
34 #include "pcm_playback.h"
35 #endif
36 #endif
38 #ifndef SIMULATOR
39 extern bool audio_is_initialized;
41 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
42 extern unsigned long shadow_io_control_main;
43 extern unsigned shadow_codec_reg0;
44 #endif
45 #endif /* SIMULATOR */
47 #ifdef SIMULATOR
48 /* dummy for sim */
49 const struct sound_settings_info audiohw_settings[] = {
50 [SOUND_VOLUME] = {"dB", 0, 1, -40, 6, -25},
51 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
52 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
53 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
54 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
55 [SOUND_STEREO_WIDTH] = {"%", 0, 1, 0, 255, 100},
56 #if CONFIG_CODEC == MAS3587F || defined(HAVE_UDA1380) || defined(HAVE_TLV320)\
57 || defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731)
58 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
59 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
60 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
61 #endif
63 #endif
65 const char *sound_unit(int setting)
67 return audiohw_settings[setting].unit;
70 int sound_numdecimals(int setting)
72 return audiohw_settings[setting].numdecimals;
75 int sound_steps(int setting)
77 return audiohw_settings[setting].steps;
80 int sound_min(int setting)
82 return audiohw_settings[setting].minval;
85 int sound_max(int setting)
87 return audiohw_settings[setting].maxval;
90 int sound_default(int setting)
92 return audiohw_settings[setting].defaultval;
95 sound_set_type* sound_get_fn(int setting)
97 sound_set_type* result = NULL;
99 switch (setting) {
100 case SOUND_VOLUME:
101 result = sound_set_volume;
102 break;
104 case SOUND_BASS:
105 result = sound_set_bass;
106 break;
108 case SOUND_TREBLE:
109 result = sound_set_treble;
110 break;
112 case SOUND_BALANCE:
113 result = sound_set_balance;
114 break;
116 case SOUND_CHANNELS:
117 result = sound_set_channels;
118 break;
120 case SOUND_STEREO_WIDTH:
121 result = sound_set_stereo_width;
122 break;
124 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
125 case SOUND_LOUDNESS:
126 result = sound_set_loudness;
127 break;
129 case SOUND_AVC:
130 result = sound_set_avc;
131 break;
133 case SOUND_MDB_STRENGTH:
134 result = sound_set_mdb_strength;
135 break;
137 case SOUND_MDB_HARMONICS:
138 result = sound_set_mdb_harmonics;
139 break;
141 case SOUND_MDB_CENTER:
142 result = sound_set_mdb_center;
143 break;
145 case SOUND_MDB_SHAPE:
146 result = sound_set_mdb_shape;
147 break;
149 case SOUND_MDB_ENABLE:
150 result = sound_set_mdb_enable;
151 break;
153 case SOUND_SUPERBASS:
154 result = sound_set_superbass;
155 break;
156 #endif
159 return result;
162 #if CONFIG_CODEC == SWCODEC
163 /* Copied from dsp.h, nasty nasty, but we don't want to include dsp.h */
164 enum {
165 DSP_CALLBACK_SET_PRESCALE = 0,
166 DSP_CALLBACK_SET_BASS,
167 DSP_CALLBACK_SET_TREBLE,
168 DSP_CALLBACK_SET_CHANNEL_CONFIG,
169 DSP_CALLBACK_SET_STEREO_WIDTH
172 static int (*dsp_callback)(int, intptr_t) = NULL;
174 void sound_set_dsp_callback(int (*func)(int, intptr_t))
176 dsp_callback = func;
178 #endif
180 #ifndef SIMULATOR
181 #if CONFIG_CODEC == MAS3507D /* volume/balance/treble/bass interdependency */
182 #define VOLUME_MIN -780
183 #define VOLUME_MAX 180
185 static const unsigned int bass_table[] =
187 0x9e400, /* -15dB */
188 0xa2800, /* -14dB */
189 0xa7400, /* -13dB */
190 0xac400, /* -12dB */
191 0xb1800, /* -11dB */
192 0xb7400, /* -10dB */
193 0xbd400, /* -9dB */
194 0xc3c00, /* -8dB */
195 0xca400, /* -7dB */
196 0xd1800, /* -6dB */
197 0xd8c00, /* -5dB */
198 0xe0400, /* -4dB */
199 0xe8000, /* -3dB */
200 0xefc00, /* -2dB */
201 0xf7c00, /* -1dB */
203 0x800, /* 1dB */
204 0x10000, /* 2dB */
205 0x17c00, /* 3dB */
206 0x1f800, /* 4dB */
207 0x27000, /* 5dB */
208 0x2e400, /* 6dB */
209 0x35800, /* 7dB */
210 0x3c000, /* 8dB */
211 0x42800, /* 9dB */
212 0x48800, /* 10dB */
213 0x4e400, /* 11dB */
214 0x53800, /* 12dB */
215 0x58800, /* 13dB */
216 0x5d400, /* 14dB */
217 0x61800 /* 15dB */
220 static const unsigned int treble_table[] =
222 0xb2c00, /* -15dB */
223 0xbb400, /* -14dB */
224 0xc1800, /* -13dB */
225 0xc6c00, /* -12dB */
226 0xcbc00, /* -11dB */
227 0xd0400, /* -10dB */
228 0xd5000, /* -9dB */
229 0xd9800, /* -8dB */
230 0xde000, /* -7dB */
231 0xe2800, /* -6dB */
232 0xe7e00, /* -5dB */
233 0xec000, /* -4dB */
234 0xf0c00, /* -3dB */
235 0xf5c00, /* -2dB */
236 0xfac00, /* -1dB */
238 0x5400, /* 1dB */
239 0xac00, /* 2dB */
240 0x10400, /* 3dB */
241 0x16000, /* 4dB */
242 0x1c000, /* 5dB */
243 0x22400, /* 6dB */
244 0x28400, /* 7dB */
245 0x2ec00, /* 8dB */
246 0x35400, /* 9dB */
247 0x3c000, /* 10dB */
248 0x42c00, /* 11dB */
249 0x49c00, /* 12dB */
250 0x51800, /* 13dB */
251 0x58400, /* 14dB */
252 0x5f800 /* 15dB */
255 static const unsigned int prescale_table[] =
257 0x80000, /* 0db */
258 0x8e000, /* 1dB */
259 0x9a400, /* 2dB */
260 0xa5800, /* 3dB */
261 0xaf400, /* 4dB */
262 0xb8000, /* 5dB */
263 0xbfc00, /* 6dB */
264 0xc6c00, /* 7dB */
265 0xcd000, /* 8dB */
266 0xd25c0, /* 9dB */
267 0xd7800, /* 10dB */
268 0xdc000, /* 11dB */
269 0xdfc00, /* 12dB */
270 0xe3400, /* 13dB */
271 0xe6800, /* 14dB */
272 0xe9400 /* 15dB */
275 /* convert tenth of dB volume (-780..+180) to dac3550 register value */
276 static int tenthdb2reg(int db)
278 if (db < -540) /* 3 dB steps */
279 return (db + 780) / 30;
280 else /* 1.5 dB steps */
281 return (db + 660) / 15;
283 #endif
285 #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
286 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_WM8731) \
287 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
288 || defined(HAVE_AS3514)
289 /* volume/balance/treble/bass interdependency main part */
290 #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
292 /* all values in tenth of dB MAS3507D UDA1380 */
293 int current_volume = 0; /* -780..+180 -840.. 0 */
294 int current_balance = 0; /* -960..+960 -840..+840 */
295 int current_treble = 0; /* -150..+150 0.. +60 */
296 int current_bass = 0; /* -150..+150 0..+240 */
298 static void set_prescaled_volume(void)
300 int prescale = 0;
301 int l, r;
303 /* The WM codecs listed don't have suitable prescaler functionality, so we let
304 * the prescaler stay at 0 for these unless SW tone controls are in use */
305 #if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
306 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751))
308 prescale = MAX(current_bass, current_treble);
309 if (prescale < 0)
310 prescale = 0; /* no need to prescale if we don't boost
311 bass or treble */
313 /* Gain up the analog volume to compensate the prescale gain reduction,
314 * but if this would push the volume over the top, reduce prescaling
315 * instead (might cause clipping). */
316 if (current_volume + prescale > VOLUME_MAX)
317 prescale = VOLUME_MAX - current_volume;
318 #endif
320 #if defined(HAVE_SW_TONE_CONTROLS)
321 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
322 #elif CONFIG_CODEC == MAS3507D
323 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
324 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8758)
325 audiohw_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale));
326 #endif
328 if (current_volume == VOLUME_MIN)
329 prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */
331 l = r = current_volume + prescale;
333 if (current_balance > 0)
335 l -= current_balance;
336 if (l < VOLUME_MIN)
337 l = VOLUME_MIN;
339 if (current_balance < 0)
341 r += current_balance;
342 if (r < VOLUME_MIN)
343 r = VOLUME_MIN;
346 #if CONFIG_CODEC == MAS3507D
347 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
348 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
349 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
350 || defined(HAVE_AS3514)
351 audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
352 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8751)
353 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
354 #endif
356 #elif defined(HAVE_TLV320)
357 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r));
358 #endif
360 #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
361 #endif /* !SIMULATOR */
363 #if CONFIG_CODEC != SWCODEC
364 int channel_configuration = SOUND_CHAN_STEREO;
365 int stereo_width = 100;
366 #endif
368 #ifndef SIMULATOR
370 #if CONFIG_CODEC != SWCODEC
371 static void set_channel_config(void)
373 /* default values: stereo */
374 unsigned long val_ll = 0x80000;
375 unsigned long val_lr = 0;
376 unsigned long val_rl = 0;
377 unsigned long val_rr = 0x80000;
379 switch(channel_configuration)
381 /* case SOUND_CHAN_STEREO unnecessary */
383 case SOUND_CHAN_MONO:
384 val_ll = 0xc0000;
385 val_lr = 0xc0000;
386 val_rl = 0xc0000;
387 val_rr = 0xc0000;
388 break;
390 case SOUND_CHAN_CUSTOM:
392 /* fixed point variables (matching MAS internal format)
393 integer part: upper 13 bits (inlcuding sign)
394 fractional part: lower 19 bits */
395 long fp_width, fp_straight, fp_cross;
397 fp_width = (stereo_width << 19) / 100;
398 if (stereo_width <= 100)
400 fp_straight = - ((1<<19) + fp_width) / 2;
401 fp_cross = fp_straight + fp_width;
403 else
405 /* straight = - (1 + width) / (2 * width) */
406 fp_straight = - ((((1<<19) + fp_width) / (fp_width >> 9)) << 9);
407 fp_cross = (1<<19) + fp_straight;
409 val_ll = val_rr = fp_straight & 0xfffff;
410 val_lr = val_rl = fp_cross & 0xfffff;
412 break;
414 case SOUND_CHAN_MONO_LEFT:
415 val_ll = 0x80000;
416 val_lr = 0x80000;
417 val_rl = 0;
418 val_rr = 0;
419 break;
421 case SOUND_CHAN_MONO_RIGHT:
422 val_ll = 0;
423 val_lr = 0;
424 val_rl = 0x80000;
425 val_rr = 0x80000;
426 break;
428 case SOUND_CHAN_KARAOKE:
429 val_ll = 0xc0000;
430 val_lr = 0x40000;
431 val_rl = 0x40000;
432 val_rr = 0xc0000;
433 break;
436 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
437 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
438 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
439 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
440 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
441 #elif CONFIG_CODEC == MAS3507D
442 mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */
443 mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */
444 mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */
445 mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */
446 #endif
449 #endif /* CONFIG_CODEC != SWCODEC */
451 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
452 unsigned long mdb_shape_shadow = 0;
453 unsigned long loudness_shadow = 0;
454 #endif
456 void sound_set_volume(int value)
458 if(!audio_is_initialized)
459 return;
460 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
461 unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8;
462 mas_codec_writereg(0x10, tmp);
463 #elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
464 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
465 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
466 || defined(HAVE_AS3514)
467 current_volume = value * 10; /* tenth of dB */
468 set_prescaled_volume();
469 #elif CONFIG_CPU == PNX0101
470 int tmp = (60 - value * 4) & 0xff;
471 CODECVOL = tmp | (tmp << 8);
472 #endif
475 void sound_set_balance(int value)
477 if(!audio_is_initialized)
478 return;
479 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
480 unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8;
481 mas_codec_writereg(0x11, tmp);
482 #elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 \
483 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
484 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
485 || defined(HAVE_AS3514)
486 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
487 set_prescaled_volume();
488 #elif CONFIG_CPU == PNX0101
489 /* TODO: implement for iFP */
490 (void)value;
491 #endif
494 void sound_set_bass(int value)
496 if(!audio_is_initialized)
497 return;
498 #if defined(HAVE_SW_TONE_CONTROLS)
499 current_bass = value * 10;
500 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
501 set_prescaled_volume();
502 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
503 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
504 mas_codec_writereg(0x14, tmp);
505 #elif CONFIG_CODEC == MAS3507D
506 mas_writereg(MAS_REG_KBASS, bass_table[value+15]);
507 current_bass = value * 10;
508 set_prescaled_volume();
509 #elif defined(HAVE_WM8751)
510 current_bass = value;
511 audiohw_set_bass(value);
512 set_prescaled_volume();
513 #elif defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_UDA1380) \
514 || defined HAVE_WM8731 || defined(HAVE_WM8721)
515 current_bass = value * 10;
516 audiohw_set_bass(value);
517 set_prescaled_volume();
518 #elif CONFIG_CPU == PNX0101
519 /* TODO: implement for iFP */
520 (void)value;
521 #endif
524 void sound_set_treble(int value)
526 if(!audio_is_initialized)
527 return;
528 #if defined(HAVE_SW_TONE_CONTROLS)
529 current_treble = value * 10;
530 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
531 set_prescaled_volume();
532 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
533 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
534 mas_codec_writereg(0x15, tmp);
535 #elif CONFIG_CODEC == MAS3507D
536 mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]);
537 current_treble = value * 10;
538 set_prescaled_volume();
539 #elif defined(HAVE_WM8751)
540 audiohw_set_treble(value);
541 current_treble = value;
542 set_prescaled_volume();
543 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_UDA1380) \
544 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
545 audiohw_set_treble(value);
546 current_treble = value * 10;
547 set_prescaled_volume();
548 #elif CONFIG_CPU == PNX0101
549 /* TODO: implement for iFP */
550 (void)value;
551 #endif
554 void sound_set_channels(int value)
556 #if CONFIG_CODEC == SWCODEC
557 dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value);
558 #else
559 if(!audio_is_initialized)
560 return;
561 channel_configuration = value;
562 set_channel_config();
563 #endif
566 void sound_set_stereo_width(int value)
568 #if CONFIG_CODEC == SWCODEC
569 dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH, value);
570 #else
571 if(!audio_is_initialized)
572 return;
573 stereo_width = value;
574 if (channel_configuration == SOUND_CHAN_CUSTOM)
575 set_channel_config();
576 #endif
579 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
580 void sound_set_loudness(int value)
582 if(!audio_is_initialized)
583 return;
584 loudness_shadow = (loudness_shadow & 0x04) |
585 (MAX(MIN(value * 4, 0x44), 0) << 8);
586 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
589 void sound_set_avc(int value)
591 if(!audio_is_initialized)
592 return;
593 int tmp;
594 switch (value) {
595 case 1: /* 20ms */
596 tmp = (0x1 << 8) | (0x8 << 12);
597 break;
598 case 2: /* 2s */
599 tmp = (0x2 << 8) | (0x8 << 12);
600 break;
601 case 3: /* 4s */
602 tmp = (0x4 << 8) | (0x8 << 12);
603 break;
604 case 4: /* 8s */
605 tmp = (0x8 << 8) | (0x8 << 12);
606 break;
607 case -1: /* turn off and then turn on again to decay quickly */
608 tmp = mas_codec_readreg(MAS_REG_KAVC);
609 mas_codec_writereg(MAS_REG_KAVC, 0);
610 break;
611 default: /* off */
612 tmp = 0;
613 break;
615 mas_codec_writereg(MAS_REG_KAVC, tmp);
618 void sound_set_mdb_strength(int value)
620 if(!audio_is_initialized)
621 return;
622 mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
625 void sound_set_mdb_harmonics(int value)
627 if(!audio_is_initialized)
628 return;
629 int tmp = value * 127 / 100;
630 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
633 void sound_set_mdb_center(int value)
635 if(!audio_is_initialized)
636 return;
637 mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
640 void sound_set_mdb_shape(int value)
642 if(!audio_is_initialized)
643 return;
644 mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
645 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
648 void sound_set_mdb_enable(int value)
650 if(!audio_is_initialized)
651 return;
652 mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
653 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
656 void sound_set_superbass(int value)
658 if(!audio_is_initialized)
659 return;
660 loudness_shadow = (loudness_shadow & ~0x04) | (value?4:0);
661 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
663 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
665 #else /* SIMULATOR */
666 void sound_set_volume(int value)
668 (void)value;
671 void sound_set_balance(int value)
673 (void)value;
676 void sound_set_bass(int value)
678 (void)value;
681 void sound_set_treble(int value)
683 (void)value;
686 void sound_set_channels(int value)
688 (void)value;
691 void sound_set_stereo_width(int value)
693 (void)value;
696 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
697 void sound_set_loudness(int value)
699 (void)value;
702 void sound_set_avc(int value)
704 (void)value;
707 void sound_set_mdb_strength(int value)
709 (void)value;
712 void sound_set_mdb_harmonics(int value)
714 (void)value;
717 void sound_set_mdb_center(int value)
719 (void)value;
722 void sound_set_mdb_shape(int value)
724 (void)value;
727 void sound_set_mdb_enable(int value)
729 (void)value;
732 void sound_set_superbass(int value)
734 (void)value;
736 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
737 #endif /* SIMULATOR */
739 void sound_set(int setting, int value)
741 sound_set_type* sound_set_val = sound_get_fn(setting);
742 if (sound_set_val)
743 sound_set_val(value);
746 #if !defined(HAVE_AS3514) || defined(SIMULATOR)
747 int sound_val2phys(int setting, int value)
749 #if CONFIG_CODEC == MAS3587F
750 int result = 0;
752 switch(setting)
754 case SOUND_LEFT_GAIN:
755 case SOUND_RIGHT_GAIN:
756 result = (value - 2) * 15;
757 break;
759 case SOUND_MIC_GAIN:
760 result = value * 15 + 210;
761 break;
763 default:
764 result = value;
765 break;
767 return result;
768 #elif defined(HAVE_UDA1380)
769 int result = 0;
771 switch(setting)
773 case SOUND_LEFT_GAIN:
774 case SOUND_RIGHT_GAIN:
775 case SOUND_MIC_GAIN:
776 result = value * 5; /* (1/2) * 10 */
777 break;
779 default:
780 result = value;
781 break;
783 return result;
784 #elif defined(HAVE_TLV320)
785 int result = 0;
787 switch(setting)
789 case SOUND_LEFT_GAIN:
790 case SOUND_RIGHT_GAIN:
791 result = (value - 23) * 15; /* (x - 23)/1.5 *10 */
792 break;
794 case SOUND_MIC_GAIN:
795 result = value * 200; /* 0 or 20 dB */
796 break;
798 default:
799 result = value;
800 break;
802 return result;
803 #elif defined(HAVE_AS3514)
804 /* This is here for the sim only and the audio driver has its own */
805 int result;
807 switch(setting)
809 case SOUND_LEFT_GAIN:
810 case SOUND_RIGHT_GAIN:
811 case SOUND_MIC_GAIN:
812 result = (value - 23) * 15;
813 break;
815 default:
816 result = value;
817 break;
820 return result;
821 #else
822 (void)setting;
823 return value;
824 #endif
826 #endif /* !defined(HAVE_AS3514) || defined(SIMULATOR) */
828 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
829 #ifndef SIMULATOR
830 /* This function works by telling the decoder that we have another
831 crystal frequency than we actually have. It will adjust its internal
832 parameters and the result is that the audio is played at another pitch.
834 The pitch value is in tenths of percent.
836 static int last_pitch = 1000;
838 void sound_set_pitch(int pitch)
840 unsigned long val;
842 if (pitch != last_pitch)
844 /* Calculate the new (bogus) frequency */
845 val = 18432 * 1000 / pitch;
847 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
849 /* We must tell the MAS that the frequency has changed.
850 * This will unfortunately cause a short silence. */
851 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
853 last_pitch = pitch;
857 int sound_get_pitch(void)
859 return last_pitch;
861 #else /* SIMULATOR */
862 void sound_set_pitch(int pitch)
864 (void)pitch;
867 int sound_get_pitch(void)
869 return 1000;
871 #endif /* SIMULATOR */
872 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */