Revert previous commit (still learning to work with git...)
[Rockbox.git] / firmware / sound.c
blob5a1a1e97b7849a58550f914f9cd366dbada74086
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.h"
35 #endif
36 #endif
38 #if CONFIG_CODEC == MAS3507D /* volume/balance/treble/bass interdependency */
39 #define VOLUME_MIN -780
40 #define VOLUME_MAX 180
41 #elif !defined(VOLUME_MIN) && !defined(VOLUME_MAX)
42 #define VOLUME_MIN -400
43 #define VOLUME_MAX 600
44 #endif
46 /* volume/balance/treble/bass interdependency main part */
47 #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
49 #ifndef SIMULATOR
50 extern bool audio_is_initialized;
52 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
53 extern unsigned long shadow_io_control_main;
54 extern unsigned shadow_codec_reg0;
55 #endif
56 #endif /* SIMULATOR */
58 #ifdef SIMULATOR
59 /* dummy for sim */
60 const struct sound_settings_info audiohw_settings[] = {
61 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
62 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
63 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
64 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
65 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
66 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
67 #if CONFIG_CODEC == MAS3587F || defined(HAVE_UDA1380) || defined(HAVE_TLV320)\
68 || defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731)
69 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
70 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
71 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
72 #endif
73 #if defined(HAVE_WM8758)
74 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
75 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
76 #endif
77 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
78 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0},
79 [SOUND_AVC] = {"", 0, 1, -1, 4, 0},
80 [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48},
81 [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50},
82 [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60},
83 [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90},
84 [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0},
85 [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0},
86 #endif
88 #endif
90 const char *sound_unit(int setting)
92 return audiohw_settings[setting].unit;
95 int sound_numdecimals(int setting)
97 return audiohw_settings[setting].numdecimals;
100 int sound_steps(int setting)
102 return audiohw_settings[setting].steps;
105 int sound_min(int setting)
107 return audiohw_settings[setting].minval;
110 int sound_max(int setting)
112 return audiohw_settings[setting].maxval;
115 int sound_default(int setting)
117 return audiohw_settings[setting].defaultval;
120 sound_set_type* sound_get_fn(int setting)
122 sound_set_type* result = NULL;
124 switch (setting) {
125 case SOUND_VOLUME:
126 result = sound_set_volume;
127 break;
129 case SOUND_BASS:
130 result = sound_set_bass;
131 break;
133 case SOUND_TREBLE:
134 result = sound_set_treble;
135 break;
137 case SOUND_BALANCE:
138 result = sound_set_balance;
139 break;
141 case SOUND_CHANNELS:
142 result = sound_set_channels;
143 break;
145 case SOUND_STEREO_WIDTH:
146 result = sound_set_stereo_width;
147 break;
149 #ifdef HAVE_WM8758
150 case SOUND_BASS_CUTOFF:
151 result = sound_set_bass_cutoff;
152 break;
154 case SOUND_TREBLE_CUTOFF:
155 result = sound_set_treble_cutoff;
156 break;
157 #endif
159 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
160 case SOUND_LOUDNESS:
161 result = sound_set_loudness;
162 break;
164 case SOUND_AVC:
165 result = sound_set_avc;
166 break;
168 case SOUND_MDB_STRENGTH:
169 result = sound_set_mdb_strength;
170 break;
172 case SOUND_MDB_HARMONICS:
173 result = sound_set_mdb_harmonics;
174 break;
176 case SOUND_MDB_CENTER:
177 result = sound_set_mdb_center;
178 break;
180 case SOUND_MDB_SHAPE:
181 result = sound_set_mdb_shape;
182 break;
184 case SOUND_MDB_ENABLE:
185 result = sound_set_mdb_enable;
186 break;
188 case SOUND_SUPERBASS:
189 result = sound_set_superbass;
190 break;
191 #endif
194 return result;
197 #if CONFIG_CODEC == SWCODEC
198 /* Copied from dsp.h, nasty nasty, but we don't want to include dsp.h */
199 enum {
200 DSP_CALLBACK_SET_PRESCALE = 0,
201 DSP_CALLBACK_SET_BASS,
202 DSP_CALLBACK_SET_TREBLE,
203 DSP_CALLBACK_SET_CHANNEL_CONFIG,
204 DSP_CALLBACK_SET_STEREO_WIDTH
207 static int (*dsp_callback)(int, intptr_t) = NULL;
209 void sound_set_dsp_callback(int (*func)(int, intptr_t))
211 dsp_callback = func;
213 #endif
215 #ifndef SIMULATOR
216 #if CONFIG_CODEC == MAS3507D
217 /* convert tenth of dB volume (-780..+180) to dac3550 register value */
218 static int tenthdb2reg(int db)
220 if (db < -540) /* 3 dB steps */
221 return (db + 780) / 30;
222 else /* 1.5 dB steps */
223 return (db + 660) / 15;
225 #endif
227 #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
228 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_WM8731) \
229 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
230 || defined(HAVE_AS3514)
232 /* all values in tenth of dB MAS3507D UDA1380 */
233 int current_volume = 0; /* -780..+180 -840.. 0 */
234 int current_balance = 0; /* -960..+960 -840..+840 */
235 int current_treble = 0; /* -150..+150 0.. +60 */
236 int current_bass = 0; /* -150..+150 0..+240 */
238 static void set_prescaled_volume(void)
240 int prescale = 0;
241 int l, r;
243 /* The WM codecs listed don't have suitable prescaler functionality, so we let
244 * the prescaler stay at 0 for these unless SW tone controls are in use */
245 #if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
246 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
247 || defined(HAVE_WM8758))
249 prescale = MAX(current_bass, current_treble);
250 if (prescale < 0)
251 prescale = 0; /* no need to prescale if we don't boost
252 bass or treble */
254 /* Gain up the analog volume to compensate the prescale gain reduction,
255 * but if this would push the volume over the top, reduce prescaling
256 * instead (might cause clipping). */
257 if (current_volume + prescale > VOLUME_MAX)
258 prescale = VOLUME_MAX - current_volume;
259 #endif
261 #if defined(HAVE_SW_TONE_CONTROLS)
262 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
263 #elif CONFIG_CODEC == MAS3507D
264 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
265 #elif defined(HAVE_UDA1380)
266 audiohw_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale));
267 #endif
269 if (current_volume == VOLUME_MIN)
270 prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */
272 l = r = current_volume + prescale;
274 if (current_balance > 0)
276 l -= current_balance;
277 if (l < VOLUME_MIN)
278 l = VOLUME_MIN;
280 if (current_balance < 0)
282 r += current_balance;
283 if (r < VOLUME_MIN)
284 r = VOLUME_MIN;
287 #if CONFIG_CODEC == MAS3507D
288 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
289 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
290 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
291 || defined(HAVE_AS3514)
292 audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
293 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8751)
294 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
295 #endif
297 #elif defined(HAVE_TLV320)
298 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r));
299 #endif
301 #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
302 #endif /* !SIMULATOR */
304 #if CONFIG_CODEC != SWCODEC
305 int channel_configuration = SOUND_CHAN_STEREO;
306 int stereo_width = 100;
307 #endif
309 #ifndef SIMULATOR
311 #if CONFIG_CODEC != SWCODEC
312 static void set_channel_config(void)
314 /* default values: stereo */
315 unsigned long val_ll = 0x80000;
316 unsigned long val_lr = 0;
317 unsigned long val_rl = 0;
318 unsigned long val_rr = 0x80000;
320 switch(channel_configuration)
322 /* case SOUND_CHAN_STEREO unnecessary */
324 case SOUND_CHAN_MONO:
325 val_ll = 0xc0000;
326 val_lr = 0xc0000;
327 val_rl = 0xc0000;
328 val_rr = 0xc0000;
329 break;
331 case SOUND_CHAN_CUSTOM:
333 /* fixed point variables (matching MAS internal format)
334 integer part: upper 13 bits (inlcuding sign)
335 fractional part: lower 19 bits */
336 long fp_width, fp_straight, fp_cross;
338 fp_width = (stereo_width << 19) / 100;
339 if (stereo_width <= 100)
341 fp_straight = - ((1<<19) + fp_width) / 2;
342 fp_cross = fp_straight + fp_width;
344 else
346 /* straight = - (1 + width) / (2 * width) */
347 fp_straight = - ((((1<<19) + fp_width) / (fp_width >> 9)) << 9);
348 fp_cross = (1<<19) + fp_straight;
350 val_ll = val_rr = fp_straight & 0xfffff;
351 val_lr = val_rl = fp_cross & 0xfffff;
353 break;
355 case SOUND_CHAN_MONO_LEFT:
356 val_ll = 0x80000;
357 val_lr = 0x80000;
358 val_rl = 0;
359 val_rr = 0;
360 break;
362 case SOUND_CHAN_MONO_RIGHT:
363 val_ll = 0;
364 val_lr = 0;
365 val_rl = 0x80000;
366 val_rr = 0x80000;
367 break;
369 case SOUND_CHAN_KARAOKE:
370 val_ll = 0xc0000;
371 val_lr = 0x40000;
372 val_rl = 0x40000;
373 val_rr = 0xc0000;
374 break;
377 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
378 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
379 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
380 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
381 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
382 #elif CONFIG_CODEC == MAS3507D
383 mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */
384 mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */
385 mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */
386 mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */
387 #endif
390 #endif /* CONFIG_CODEC != SWCODEC */
392 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
393 unsigned long mdb_shape_shadow = 0;
394 unsigned long loudness_shadow = 0;
395 #endif
397 void sound_set_volume(int value)
399 if(!audio_is_initialized)
400 return;
401 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
402 unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8;
403 mas_codec_writereg(0x10, tmp);
404 #elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
405 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
406 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
407 || defined(HAVE_AS3514)
408 current_volume = value * 10; /* tenth of dB */
409 set_prescaled_volume();
410 #elif CONFIG_CPU == PNX0101
411 int tmp = (60 - value * 4) & 0xff;
412 CODECVOL = tmp | (tmp << 8);
413 #endif
416 void sound_set_balance(int value)
418 if(!audio_is_initialized)
419 return;
420 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
421 unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8;
422 mas_codec_writereg(0x11, tmp);
423 #elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 \
424 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
425 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
426 || defined(HAVE_AS3514)
427 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
428 set_prescaled_volume();
429 #elif CONFIG_CPU == PNX0101
430 /* TODO: implement for iFP */
431 (void)value;
432 #endif
435 void sound_set_bass(int value)
437 if(!audio_is_initialized)
438 return;
439 #if defined(HAVE_SW_TONE_CONTROLS)
440 current_bass = value * 10;
441 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
442 set_prescaled_volume();
443 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
444 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
445 mas_codec_writereg(0x14, tmp);
446 #elif CONFIG_CODEC == MAS3507D
447 mas_writereg(MAS_REG_KBASS, bass_table[value+15]);
448 current_bass = value * 10;
449 set_prescaled_volume();
450 #elif defined(HAVE_WM8751)
451 current_bass = value;
452 audiohw_set_bass(value);
453 set_prescaled_volume();
454 #elif defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_UDA1380) \
455 || defined HAVE_WM8731 || defined(HAVE_WM8721)
456 current_bass = value * 10;
457 audiohw_set_bass(value);
458 set_prescaled_volume();
459 #elif CONFIG_CPU == PNX0101
460 /* TODO: implement for iFP */
461 (void)value;
462 #endif
465 void sound_set_treble(int value)
467 if(!audio_is_initialized)
468 return;
469 #if defined(HAVE_SW_TONE_CONTROLS)
470 current_treble = value * 10;
471 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
472 set_prescaled_volume();
473 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
474 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
475 mas_codec_writereg(0x15, tmp);
476 #elif CONFIG_CODEC == MAS3507D
477 mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]);
478 current_treble = value * 10;
479 set_prescaled_volume();
480 #elif defined(HAVE_WM8751)
481 audiohw_set_treble(value);
482 current_treble = value;
483 set_prescaled_volume();
484 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_UDA1380) \
485 || defined(HAVE_WM8731) || defined(HAVE_WM8721)
486 audiohw_set_treble(value);
487 current_treble = value * 10;
488 set_prescaled_volume();
489 #elif CONFIG_CPU == PNX0101
490 /* TODO: implement for iFP */
491 (void)value;
492 #endif
495 void sound_set_channels(int value)
497 #if CONFIG_CODEC == SWCODEC
498 dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value);
499 #else
500 if(!audio_is_initialized)
501 return;
502 channel_configuration = value;
503 set_channel_config();
504 #endif
507 void sound_set_stereo_width(int value)
509 #if CONFIG_CODEC == SWCODEC
510 dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH, value);
511 #else
512 if(!audio_is_initialized)
513 return;
514 stereo_width = value;
515 if (channel_configuration == SOUND_CHAN_CUSTOM)
516 set_channel_config();
517 #endif
520 #ifdef HAVE_WM8758
521 void sound_set_bass_cutoff(int value)
523 if(!audio_is_initialized)
524 return;
526 audiohw_set_bass_cutoff(value);
529 void sound_set_treble_cutoff(int value)
531 if(!audio_is_initialized)
532 return;
534 audiohw_set_treble_cutoff(value);
536 #endif
538 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
539 void sound_set_loudness(int value)
541 if(!audio_is_initialized)
542 return;
543 loudness_shadow = (loudness_shadow & 0x04) |
544 (MAX(MIN(value * 4, 0x44), 0) << 8);
545 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
548 void sound_set_avc(int value)
550 if(!audio_is_initialized)
551 return;
552 int tmp;
553 switch (value) {
554 case 1: /* 20ms */
555 tmp = (0x1 << 8) | (0x8 << 12);
556 break;
557 case 2: /* 2s */
558 tmp = (0x2 << 8) | (0x8 << 12);
559 break;
560 case 3: /* 4s */
561 tmp = (0x4 << 8) | (0x8 << 12);
562 break;
563 case 4: /* 8s */
564 tmp = (0x8 << 8) | (0x8 << 12);
565 break;
566 case -1: /* turn off and then turn on again to decay quickly */
567 tmp = mas_codec_readreg(MAS_REG_KAVC);
568 mas_codec_writereg(MAS_REG_KAVC, 0);
569 break;
570 default: /* off */
571 tmp = 0;
572 break;
574 mas_codec_writereg(MAS_REG_KAVC, tmp);
577 void sound_set_mdb_strength(int value)
579 if(!audio_is_initialized)
580 return;
581 mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
584 void sound_set_mdb_harmonics(int value)
586 if(!audio_is_initialized)
587 return;
588 int tmp = value * 127 / 100;
589 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
592 void sound_set_mdb_center(int value)
594 if(!audio_is_initialized)
595 return;
596 mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
599 void sound_set_mdb_shape(int value)
601 if(!audio_is_initialized)
602 return;
603 mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
604 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
607 void sound_set_mdb_enable(int value)
609 if(!audio_is_initialized)
610 return;
611 mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
612 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
615 void sound_set_superbass(int value)
617 if(!audio_is_initialized)
618 return;
619 loudness_shadow = (loudness_shadow & ~0x04) | (value?4:0);
620 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
622 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
624 #else /* SIMULATOR */
625 int sim_volume;
626 void sound_set_volume(int value)
628 /* 128 is SDL_MIX_MAXVOLUME */
629 sim_volume = 128 * (value - VOLUME_MIN / 10) / (VOLUME_RANGE / 10);
632 void sound_set_balance(int value)
634 (void)value;
637 void sound_set_bass(int value)
639 (void)value;
642 void sound_set_treble(int value)
644 (void)value;
647 void sound_set_channels(int value)
649 (void)value;
652 void sound_set_stereo_width(int value)
654 (void)value;
657 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
658 void sound_set_loudness(int value)
660 (void)value;
663 void sound_set_avc(int value)
665 (void)value;
668 void sound_set_mdb_strength(int value)
670 (void)value;
673 void sound_set_mdb_harmonics(int value)
675 (void)value;
678 void sound_set_mdb_center(int value)
680 (void)value;
683 void sound_set_mdb_shape(int value)
685 (void)value;
688 void sound_set_mdb_enable(int value)
690 (void)value;
693 void sound_set_superbass(int value)
695 (void)value;
697 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
699 #ifdef HAVE_WM8758
700 void sound_set_bass_cutoff(int value)
702 (void) value;
705 void sound_set_treble_cutoff(int value)
707 (void) value;
709 #endif /* HAVE_WM8758 */
711 #endif /* SIMULATOR */
713 void sound_set(int setting, int value)
715 sound_set_type* sound_set_val = sound_get_fn(setting);
716 if (sound_set_val)
717 sound_set_val(value);
720 #if (!defined(HAVE_AS3514) && !defined (HAVE_WM8731)) || defined(SIMULATOR)
721 int sound_val2phys(int setting, int value)
723 #if CONFIG_CODEC == MAS3587F
724 int result = 0;
726 switch(setting)
728 case SOUND_LEFT_GAIN:
729 case SOUND_RIGHT_GAIN:
730 result = (value - 2) * 15;
731 break;
733 case SOUND_MIC_GAIN:
734 result = value * 15 + 210;
735 break;
737 default:
738 result = value;
739 break;
741 return result;
742 #elif defined(HAVE_UDA1380)
743 int result = 0;
745 switch(setting)
747 case SOUND_LEFT_GAIN:
748 case SOUND_RIGHT_GAIN:
749 case SOUND_MIC_GAIN:
750 result = value * 5; /* (1/2) * 10 */
751 break;
753 default:
754 result = value;
755 break;
757 return result;
758 #elif defined(HAVE_TLV320) || defined(HAVE_WM8731)
759 int result = 0;
761 switch(setting)
763 case SOUND_LEFT_GAIN:
764 case SOUND_RIGHT_GAIN:
765 result = (value - 23) * 15; /* (x - 23)/1.5 *10 */
766 break;
768 case SOUND_MIC_GAIN:
769 result = value * 200; /* 0 or 20 dB */
770 break;
772 default:
773 result = value;
774 break;
776 return result;
777 #elif defined(HAVE_AS3514)
778 /* This is here for the sim only and the audio driver has its own */
779 int result;
781 switch(setting)
783 case SOUND_LEFT_GAIN:
784 case SOUND_RIGHT_GAIN:
785 case SOUND_MIC_GAIN:
786 result = (value - 23) * 15;
787 break;
789 default:
790 result = value;
791 break;
794 return result;
795 #else
796 (void)setting;
797 return value;
798 #endif
800 #endif /* !defined(HAVE_AS3514) || defined(SIMULATOR) */
802 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
803 #ifndef SIMULATOR
804 /* This function works by telling the decoder that we have another
805 crystal frequency than we actually have. It will adjust its internal
806 parameters and the result is that the audio is played at another pitch.
808 The pitch value is in tenths of percent.
810 static int last_pitch = 1000;
812 void sound_set_pitch(int pitch)
814 unsigned long val;
816 if (pitch != last_pitch)
818 /* Calculate the new (bogus) frequency */
819 val = 18432 * 1000 / pitch;
821 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
823 /* We must tell the MAS that the frequency has changed.
824 * This will unfortunately cause a short silence. */
825 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
827 last_pitch = pitch;
831 int sound_get_pitch(void)
833 return last_pitch;
835 #else /* SIMULATOR */
836 void sound_set_pitch(int pitch)
838 (void)pitch;
841 int sound_get_pitch(void)
843 return 1000;
845 #endif /* SIMULATOR */
846 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */