Merge branch 'master' into sim-target-tree
[kugel-rb.git] / firmware / sound.c
blobdccca122644f282db4137ebb0ce1dfa8134e074d
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 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
22 #include <stdbool.h>
23 #include <stdio.h>
24 #include "config.h"
25 #include "sound.h"
26 #include "logf.h"
27 #include "system.h"
28 #include "i2c.h"
29 #include "mas.h"
30 #ifndef SIMULATOR
31 #if CONFIG_CPU == PNX0101
32 #include "pnx0101.h"
33 #endif
34 #include "dac.h"
35 #if CONFIG_CODEC == SWCODEC
36 #include "pcm.h"
37 #endif
38 #endif
40 /* TODO
41 * find a nice way to handle 1.5db steps -> see wm8751 ifdef in sound_set_bass/treble
44 extern bool audio_is_initialized;
46 const char *sound_unit(int setting)
48 return audiohw_settings[setting].unit;
51 int sound_numdecimals(int setting)
53 return audiohw_settings[setting].numdecimals;
56 int sound_steps(int setting)
58 return audiohw_settings[setting].steps;
61 int sound_min(int setting)
63 return audiohw_settings[setting].minval;
66 int sound_max(int setting)
68 return audiohw_settings[setting].maxval;
71 int sound_default(int setting)
73 return audiohw_settings[setting].defaultval;
76 static sound_set_type * const sound_set_fns[] =
78 [0 ... SOUND_LAST_SETTING-1] = NULL,
79 [SOUND_VOLUME] = sound_set_volume,
80 #if defined(AUDIOHW_HAVE_BASS)
81 [SOUND_BASS] = sound_set_bass,
82 #endif
83 #if defined(AUDIOHW_HAVE_TREBLE)
84 [SOUND_TREBLE] = sound_set_treble,
85 #endif
86 [SOUND_BALANCE] = sound_set_balance,
87 [SOUND_CHANNELS] = sound_set_channels,
88 [SOUND_STEREO_WIDTH] = sound_set_stereo_width,
89 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
90 [SOUND_LOUDNESS] = sound_set_loudness,
91 [SOUND_AVC] = sound_set_avc,
92 [SOUND_MDB_STRENGTH] = sound_set_mdb_strength,
93 [SOUND_MDB_HARMONICS] = sound_set_mdb_harmonics,
94 [SOUND_MDB_CENTER] = sound_set_mdb_center,
95 [SOUND_MDB_SHAPE] = sound_set_mdb_shape,
96 [SOUND_MDB_ENABLE] = sound_set_mdb_enable,
97 [SOUND_SUPERBASS] = sound_set_superbass,
98 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
99 #if defined(AUDIOHW_HAVE_BASS_CUTOFF)
100 [SOUND_BASS_CUTOFF] = sound_set_bass_cutoff,
101 #endif
102 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
103 [SOUND_TREBLE_CUTOFF] = sound_set_treble_cutoff,
104 #endif
105 #if defined(AUDIOHW_HAVE_DEPTH_3D)
106 [SOUND_DEPTH_3D] = sound_set_depth_3d,
107 #endif
108 /* Hardware EQ tone controls */
109 #if defined(AUDIOHW_HAVE_EQ)
110 [SOUND_EQ_BAND1_GAIN] = sound_set_hw_eq_band1_gain,
111 #if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
112 [SOUND_EQ_BAND1_FREQUENCY] = sound_set_hw_eq_band1_frequency,
113 #endif
114 #if defined(AUDIOHW_HAVE_EQ_BAND2)
115 [SOUND_EQ_BAND2_GAIN] = sound_set_hw_eq_band2_gain,
116 #if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
117 [SOUND_EQ_BAND2_FREQUENCY] = sound_set_hw_eq_band2_frequency,
118 #endif
119 #if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
120 [SOUND_EQ_BAND2_WIDTH] = sound_set_hw_eq_band2_width,
121 #endif
122 #endif /* AUDIOHW_HAVE_EQ_BAND2 */
123 #if defined(AUDIOHW_HAVE_EQ_BAND3)
124 [SOUND_EQ_BAND3_GAIN] = sound_set_hw_eq_band3_gain,
125 #if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
126 [SOUND_EQ_BAND3_FREQUENCY] = sound_set_hw_eq_band3_frequency,
127 #endif
128 #if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
129 [SOUND_EQ_BAND3_WIDTH] = sound_set_hw_eq_band3_width,
130 #endif
131 #endif /* AUDIOHW_HAVE_EQ_BAND3 */
132 #if defined(AUDIOHW_HAVE_EQ_BAND4)
133 [SOUND_EQ_BAND4_GAIN] = sound_set_hw_eq_band4_gain,
134 #if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
135 [SOUND_EQ_BAND4_FREQUENCY] = sound_set_hw_eq_band4_frequency,
136 #endif
137 #if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
138 [SOUND_EQ_BAND4_WIDTH] = sound_set_hw_eq_band4_width,
139 #endif
140 #endif /* AUDIOHW_HAVE_EQ_BAND4 */
141 #if defined(AUDIOHW_HAVE_EQ_BAND5)
142 [SOUND_EQ_BAND5_GAIN] = sound_set_hw_eq_band5_gain,
143 #if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
144 [SOUND_EQ_BAND5_FREQUENCY] = sound_set_hw_eq_band5_frequency,
145 #endif
146 #endif /* AUDIOHW_HAVE_EQ_BAND5 */
147 #endif /* AUDIOHW_HAVE_EQ */
150 sound_set_type* sound_get_fn(int setting)
152 return ((unsigned)setting >= ARRAYLEN(sound_set_fns)?
153 NULL : sound_set_fns[setting]);
156 #if CONFIG_CODEC == SWCODEC
157 static int (*dsp_callback)(int, intptr_t) = NULL;
159 void sound_set_dsp_callback(int (*func)(int, intptr_t))
161 dsp_callback = func;
163 #endif
165 #if (CONFIG_CODEC == MAS3507D) && !defined(SIMULATOR)
166 /* convert tenth of dB volume (-780..+180) to dac3550 register value */
167 static int tenthdb2reg(int db)
169 if (db < -540) /* 3 dB steps */
170 return (db + 780) / 30;
171 else /* 1.5 dB steps */
172 return (db + 660) / 15;
174 #endif
177 #if !defined(AUDIOHW_HAVE_CLIPPING)
179 * The prescaler compensates for any kind of boosts, to prevent clipping.
181 * It's basically just a measure to make sure that audio does not clip during
182 * tone controls processing, like if i want to boost bass 12 dB, i can decrease
183 * the audio amplitude by -12 dB before processing, then increase master gain
184 * by 12 dB after processing.
187 /* all values in tenth of dB MAS3507D UDA1380 */
188 int current_volume = 0; /* -780..+180 -840.. 0 */
189 int current_balance = 0; /* -960..+960 -840..+840 */
190 #ifdef AUDIOHW_HAVE_TREBLE
191 int current_treble = 0; /* -150..+150 0.. +60 */
192 #endif
193 #ifdef AUDIOHW_HAVE_BASS
194 int current_bass = 0; /* -150..+150 0..+240 */
195 #endif
196 #ifdef AUDIOHW_HAVE_EQ
197 int current_eq_band_gain[AUDIOHW_EQ_BAND_NUM];
198 #endif
200 static void set_prescaled_volume(void)
202 int prescale = 0;
203 int l, r;
205 /* The codecs listed use HW tone controls but don't have suitable prescaler
206 * functionality, so we let the prescaler stay at 0 for these, unless
207 * SW tone controls are in use. This is to avoid needing the SW DSP just for
208 * the prescaling.
210 #if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
211 || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
212 || defined(HAVE_WM8758) || defined(HAVE_WM8985) || defined(HAVE_UDA1341))
214 #if defined(AUDIOHW_HAVE_BASS) && defined(AUDIOHW_HAVE_TREBLE)
215 prescale = MAX(current_bass, current_treble);
216 #endif
217 #if defined(AUDIOHW_HAVE_EQ)
218 int i;
219 for (i = 0; i < AUDIOHW_EQ_BAND_NUM; i++)
220 prescale = MAX(current_eq_band_gain[i], prescale);
221 #endif
223 if (prescale < 0)
224 prescale = 0; /* no need to prescale if we don't boost
225 bass, treble or eq band */
227 /* Gain up the analog volume to compensate the prescale gain reduction,
228 * but if this would push the volume over the top, reduce prescaling
229 * instead (might cause clipping). */
230 if (current_volume + prescale > VOLUME_MAX)
231 prescale = VOLUME_MAX - current_volume;
232 #endif
234 #if defined(AUDIOHW_HAVE_PRESCALER)
235 audiohw_set_prescaler(prescale);
236 #else
237 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
238 #endif
240 if (current_volume == VOLUME_MIN)
241 prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */
243 l = r = current_volume + prescale;
245 /* Balance the channels scaled by the current volume and min volume. */
246 /* Subtract a dB from VOLUME_MIN to get it to a mute level */
247 if (current_balance > 0)
249 l -= ((l - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE;
251 else if (current_balance < 0)
253 r += ((r - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE;
256 #ifdef HAVE_SW_VOLUME_CONTROL
257 dsp_callback(DSP_CALLBACK_SET_SW_VOLUME, 0);
258 #endif
260 #ifndef SIMULATOR
261 #if CONFIG_CODEC == MAS3507D
262 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
263 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
264 || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
265 || defined(HAVE_WM8750) || defined(HAVE_WM8751) || defined(HAVE_AS3514) \
266 || defined(HAVE_TSC2100) || defined(HAVE_AK4537) || defined(HAVE_UDA1341)
267 audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
268 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
269 || defined(HAVE_WM8750) || (defined(HAVE_WM8751) && !defined(MROBE_100)) \
270 || defined(HAVE_WM8985)
271 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
272 #endif
274 #elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985)
275 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r));
276 #elif defined(HAVE_JZ4740_CODEC) || defined(HAVE_SDL_AUDIO)
277 audiohw_set_volume(current_volume);
278 #endif
279 #else /* SIMULATOR */
280 audiohw_set_volume(current_volume);
281 #endif /* !SIMULATOR */
283 #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
286 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
287 unsigned long mdb_shape_shadow = 0;
288 unsigned long loudness_shadow = 0;
289 #endif
291 void sound_set_volume(int value)
293 if(!audio_is_initialized)
294 return;
296 #if defined(AUDIOHW_HAVE_CLIPPING)
297 audiohw_set_volume(value);
298 #elif CONFIG_CPU == PNX0101
299 int tmp = (60 - value * 4) & 0xff;
300 CODECVOL = tmp | (tmp << 8);
301 #else
302 current_volume = value * 10; /* tenth of dB */
303 set_prescaled_volume();
304 #endif
307 void sound_set_balance(int value)
309 if(!audio_is_initialized)
310 return;
312 #ifdef AUDIOHW_HAVE_BALANCE
313 audiohw_set_balance(value);
314 #else
315 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
316 set_prescaled_volume();
317 #endif
320 #ifdef AUDIOHW_HAVE_BASS
321 void sound_set_bass(int value)
323 if(!audio_is_initialized)
324 return;
326 #if !defined(AUDIOHW_HAVE_CLIPPING)
327 #if defined(HAVE_WM8750) || defined(HAVE_WM8751)
328 current_bass = value;
329 #else
330 current_bass = value * 10;
331 #endif
332 #endif
334 #if defined(HAVE_SW_TONE_CONTROLS)
335 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
336 #else
337 audiohw_set_bass(value);
338 #endif
340 #if !defined(AUDIOHW_HAVE_CLIPPING)
341 set_prescaled_volume();
342 #endif
344 #endif /* AUDIOHW_HAVE_BASS */
346 #ifdef AUDIOHW_HAVE_TREBLE
347 void sound_set_treble(int value)
349 if(!audio_is_initialized)
350 return;
352 #if !defined(AUDIOHW_HAVE_CLIPPING)
353 #if defined(HAVE_WM8750) || defined(HAVE_WM8751)
354 current_treble = value;
355 #else
356 current_treble = value * 10;
357 #endif
358 #endif
360 #if defined(HAVE_SW_TONE_CONTROLS)
361 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
362 #else
363 audiohw_set_treble(value);
364 #endif
366 #if !defined(AUDIOHW_HAVE_CLIPPING)
367 set_prescaled_volume();
368 #endif
370 #endif /* AUDIOHW_HAVE_TREBLE */
372 #if defined(AUDIOHW_HAVE_BASS_CUTOFF)
373 void sound_set_bass_cutoff(int value)
375 if(!audio_is_initialized)
376 return;
378 audiohw_set_bass_cutoff(value);
380 #endif
382 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
383 void sound_set_treble_cutoff(int value)
385 if(!audio_is_initialized)
386 return;
388 audiohw_set_treble_cutoff(value);
390 #endif
392 void sound_set_channels(int value)
394 if(!audio_is_initialized)
395 return;
397 #if CONFIG_CODEC == SWCODEC
398 dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value);
399 #else
400 audiohw_set_channel(value);
401 #endif
404 void sound_set_stereo_width(int value)
406 if(!audio_is_initialized)
407 return;
409 #if CONFIG_CODEC == SWCODEC
410 dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH, value);
411 #else
412 audiohw_set_stereo_width(value);
413 #endif
416 #if defined(AUDIOHW_HAVE_DEPTH_3D)
417 void sound_set_depth_3d(int value)
419 if(!audio_is_initialized)
420 return;
422 audiohw_set_depth_3d(value);
424 #endif
426 #if defined(AUDIOHW_HAVE_EQ)
427 int sound_enum_hw_eq_band_setting(unsigned int band,
428 unsigned int band_setting)
430 static const int8_t
431 sound_hw_eq_band_setting[AUDIOHW_EQ_SETTING_NUM][AUDIOHW_EQ_BAND_NUM] =
433 [AUDIOHW_EQ_GAIN] =
435 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
436 [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_GAIN,
437 #ifdef AUDIOHW_HAVE_EQ_BAND2
438 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_GAIN,
439 #endif
440 #ifdef AUDIOHW_HAVE_EQ_BAND3
441 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_GAIN,
442 #endif
443 #ifdef AUDIOHW_HAVE_EQ_BAND4
444 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_GAIN,
445 #endif
446 #ifdef AUDIOHW_HAVE_EQ_BAND5
447 [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_GAIN,
448 #endif
450 #ifdef AUDIOHW_HAVE_EQ_FREQUENCY
451 [AUDIOHW_EQ_FREQUENCY] =
453 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
454 #ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
455 [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_FREQUENCY,
456 #endif
457 #ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
458 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_FREQUENCY,
459 #endif
460 #ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
461 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_FREQUENCY,
462 #endif
463 #ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
464 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_FREQUENCY,
465 #endif
466 #ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
467 [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_FREQUENCY,
468 #endif
470 #endif /* AUDIOHW_HAVE_EQ_FREQUENCY */
471 #ifdef AUDIOHW_HAVE_EQ_WIDTH
472 [AUDIOHW_EQ_WIDTH] =
474 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
475 #ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
476 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_WIDTH,
477 #endif
478 #ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH
479 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_WIDTH,
480 #endif
481 #ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
482 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_WIDTH,
483 #endif
485 #endif /* AUDIOHW_HAVE_EQ_WIDTH */
488 if (band < AUDIOHW_EQ_BAND_NUM && band_setting < AUDIOHW_EQ_SETTING_NUM)
489 return sound_hw_eq_band_setting[band_setting][band];
491 return -1;
494 static void sound_set_hw_eq_band_gain(unsigned int band, int value)
496 if(!audio_is_initialized)
497 return;
499 current_eq_band_gain[band] = value;
500 audiohw_set_eq_band_gain(band, value);
501 set_prescaled_volume();
504 void sound_set_hw_eq_band1_gain(int value)
506 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND1, value);
509 #if defined(AUDIOHW_HAVE_EQ_BAND2)
510 void sound_set_hw_eq_band2_gain(int value)
512 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND2, value);
514 #endif
516 #if defined(AUDIOHW_HAVE_EQ_BAND3)
517 void sound_set_hw_eq_band3_gain(int value)
519 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND3, value);
521 #endif
523 #if defined(AUDIOHW_HAVE_EQ_BAND4)
524 void sound_set_hw_eq_band4_gain(int value)
526 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND4, value);
528 #endif
530 #if defined(AUDIOHW_HAVE_EQ_BAND5)
531 void sound_set_hw_eq_band5_gain(int value)
533 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND5, value);
535 #endif
537 #if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
538 void sound_set_hw_eq_band1_frequency(int value)
540 if(!audio_is_initialized)
541 return;
543 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND1, value);
545 #endif
547 #if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
548 void sound_set_hw_eq_band2_frequency(int value)
550 if(!audio_is_initialized)
551 return;
553 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND2, value);
555 #endif
557 #if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
558 void sound_set_hw_eq_band3_frequency(int value)
560 if(!audio_is_initialized)
561 return;
563 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND3, value);
565 #endif
567 #if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
568 void sound_set_hw_eq_band4_frequency(int value)
570 if(!audio_is_initialized)
571 return;
573 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND4, value);
575 #endif
577 #if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
578 void sound_set_hw_eq_band5_frequency(int value)
580 if(!audio_is_initialized)
581 return;
583 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND5, value);
585 #endif
587 #if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
588 void sound_set_hw_eq_band2_width(int value)
590 if(!audio_is_initialized)
591 return;
593 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND2, value);
595 #endif
597 #if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
598 void sound_set_hw_eq_band3_width(int value)
600 if(!audio_is_initialized)
601 return;
603 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND3, value);
605 #endif
607 #if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
608 void sound_set_hw_eq_band4_width(int value)
610 if(!audio_is_initialized)
611 return;
613 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND4, value);
615 #endif
616 #endif /* AUDIOHW_HAVE_EQ */
618 #if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F))
619 void sound_set_loudness(int value)
621 if(!audio_is_initialized)
622 return;
623 loudness_shadow = (loudness_shadow & 0x04) |
624 (MAX(MIN(value * 4, 0x44), 0) << 8);
625 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
628 void sound_set_avc(int value)
630 if(!audio_is_initialized)
631 return;
632 int tmp;
634 static const uint16_t avc_vals[] =
636 (0x1 << 8) | (0x8 << 12), /* 20ms */
637 (0x2 << 8) | (0x8 << 12), /* 2s */
638 (0x4 << 8) | (0x8 << 12), /* 4s */
639 (0x8 << 8) | (0x8 << 12), /* 8s */
641 switch (value) {
642 case 1:
643 case 2:
644 case 3:
645 case 4:
646 tmp = avc_vals[value -1];
647 break;
648 case -1: /* turn off and then turn on again to decay quickly */
649 tmp = mas_codec_readreg(MAS_REG_KAVC);
650 mas_codec_writereg(MAS_REG_KAVC, 0);
651 break;
652 default: /* off */
653 tmp = 0;
654 break;
656 mas_codec_writereg(MAS_REG_KAVC, tmp);
659 void sound_set_mdb_strength(int value)
661 if(!audio_is_initialized)
662 return;
663 mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
666 void sound_set_mdb_harmonics(int value)
668 if(!audio_is_initialized)
669 return;
670 int tmp = value * 127 / 100;
671 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
674 void sound_set_mdb_center(int value)
676 if(!audio_is_initialized)
677 return;
678 mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
681 void sound_set_mdb_shape(int value)
683 if(!audio_is_initialized)
684 return;
685 mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
686 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
689 void sound_set_mdb_enable(int value)
691 if(!audio_is_initialized)
692 return;
693 mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
694 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
697 void sound_set_superbass(int value)
699 if(!audio_is_initialized)
700 return;
701 loudness_shadow = (loudness_shadow & ~0x04) | (value?4:0);
702 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
704 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
706 void sound_set(int setting, int value)
708 sound_set_type* sound_set_val = sound_get_fn(setting);
709 if (sound_set_val)
710 sound_set_val(value);
713 #if (!defined(HAVE_AS3514) && !defined(HAVE_WM8975) \
714 && !defined(HAVE_WM8758) && !defined(HAVE_TSC2100) \
715 && !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \
716 && !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \
717 && !defined(HAVE_AK4537)) || defined(SIMULATOR)
718 int sound_val2phys(int setting, int value)
720 #if CONFIG_CODEC == MAS3587F
721 int result = 0;
723 switch(setting)
725 case SOUND_LEFT_GAIN:
726 case SOUND_RIGHT_GAIN:
727 result = (value - 2) * 15;
728 break;
730 case SOUND_MIC_GAIN:
731 result = value * 15 + 210;
732 break;
734 default:
735 result = value;
736 break;
738 return result;
739 #elif defined(HAVE_UDA1380)
740 int result = 0;
742 switch(setting)
744 #ifdef HAVE_RECORDING
745 case SOUND_LEFT_GAIN:
746 case SOUND_RIGHT_GAIN:
747 case SOUND_MIC_GAIN:
748 result = value * 5; /* (1/2) * 10 */
749 break;
750 #endif
751 default:
752 result = value;
753 break;
755 return result;
756 #elif defined(HAVE_TLV320) || defined(HAVE_WM8711) \
757 || defined(HAVE_WM8721) || defined(HAVE_WM8731)
758 int result = 0;
760 switch(setting)
762 #ifdef HAVE_RECORDING
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;
771 #endif
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 #ifdef HAVE_RECORDING
784 case SOUND_LEFT_GAIN:
785 case SOUND_RIGHT_GAIN:
786 case SOUND_MIC_GAIN:
787 result = (value - 23) * 15;
788 break;
789 #endif
790 default:
791 result = value;
792 break;
795 return result;
796 #elif defined(HAVE_WM8978)
797 int result;
799 switch (setting)
801 #ifdef HAVE_RECORDING
802 case SOUND_LEFT_GAIN:
803 case SOUND_RIGHT_GAIN:
804 case SOUND_MIC_GAIN:
805 result = value * 5;
806 break;
807 #endif
809 case SOUND_DEPTH_3D:
810 result = (100 * value + 8) / 15;
811 break;
813 default:
814 result = value;
817 return result;
818 #else
819 (void)setting;
820 return value;
821 #endif
823 #endif /* !defined(HAVE_AS3514) || defined(SIMULATOR) */
825 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
826 /* This function works by telling the decoder that we have another
827 crystal frequency than we actually have. It will adjust its internal
828 parameters and the result is that the audio is played at another pitch.
830 The pitch value precision is based on PITCH_SPEED_PRECISION (in dsp.h)
833 #ifdef SIMULATOR
834 static
835 #else
836 extern
837 #endif
838 unsigned long shadow_io_control_main;
839 static int last_pitch = PITCH_SPEED_100;
841 void sound_set_pitch(int32_t pitch)
843 unsigned long val;
845 if (pitch != last_pitch)
847 /* Calculate the new (bogus) frequency */
848 val = 18432 * PITCH_SPEED_100 / pitch;
850 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
852 /* We must tell the MAS that the frequency has changed.
853 * This will unfortunately cause a short silence. */
854 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
856 last_pitch = pitch;
860 int32_t sound_get_pitch(void)
862 return last_pitch;
864 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */