i.MX31: Issue some NOP's immediately after MCR WFI to prevent premature execution...
[kugel-rb.git] / firmware / sound.c
blobfb2f353d71f9a8d33417d7916d4f87e36dcdb292
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 #ifdef SIMULATOR
47 extern void audiohw_set_volume(int value);
48 /* dummy for sim */
49 const struct sound_settings_info audiohw_settings[] = {
50 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
51 /* Bass and treble tone controls */
52 #ifdef AUDIOHW_HAVE_BASS
53 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
54 #endif
55 #ifdef AUDIOHW_HAVE_TREBLE
56 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
57 #endif
58 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
59 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
60 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
61 #if defined(HAVE_RECORDING)
62 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
63 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
64 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
65 #endif
66 #if defined(AUDIOHW_HAVE_BASS_CUTOFF)
67 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
68 #endif
69 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
70 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
71 #endif
72 #if defined(AUDIOHW_HAVE_DEPTH_3D)
73 [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
74 #endif
75 /* Hardware EQ tone controls */
76 #if defined(AUDIOHW_HAVE_EQ_BAND1)
77 [SOUND_EQ_BAND1_GAIN] = {"dB", 0, 1, -12, 12, 0},
78 #endif
79 #if defined(AUDIOHW_HAVE_EQ_BAND2)
80 [SOUND_EQ_BAND2_GAIN] = {"dB", 0, 1, -12, 12, 0},
81 #endif
82 #if defined(AUDIOHW_HAVE_EQ_BAND3)
83 [SOUND_EQ_BAND3_GAIN] = {"dB", 0, 1, -12, 12, 0},
84 #endif
85 #if defined(AUDIOHW_HAVE_EQ_BAND4)
86 [SOUND_EQ_BAND4_GAIN] = {"dB", 0, 1, -12, 12, 0},
87 #endif
88 #if defined(AUDIOHW_HAVE_EQ_BAND5)
89 [SOUND_EQ_BAND5_GAIN] = {"dB", 0, 1, -12, 12, 0},
90 #endif
91 #if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
92 [SOUND_EQ_BAND1_FREQUENCY] = {"", 0, 1, 1, 4, 1},
93 #endif
94 #if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
95 [SOUND_EQ_BAND2_FREQUENCY] = {"", 0, 1, 1, 4, 1},
96 #endif
97 #if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
98 [SOUND_EQ_BAND3_FREQUENCY] = {"", 0, 1, 1, 4, 1},
99 #endif
100 #if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
101 [SOUND_EQ_BAND4_FREQUENCY] = {"", 0, 1, 1, 4, 1},
102 #endif
103 #if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
104 [SOUND_EQ_BAND5_FREQUENCY] = {"", 0, 1, 1, 4, 1},
105 #endif
106 #if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
107 [SOUND_EQ_BAND2_WIDTH] = {"", 0, 1, 0, 1, 0},
108 #endif
109 #if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
110 [SOUND_EQ_BAND3_WIDTH] = {"", 0, 1, 0, 1, 0},
111 #endif
112 #if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
113 [SOUND_EQ_BAND4_WIDTH] = {"", 0, 1, 0, 1, 0},
114 #endif
116 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
117 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0},
118 [SOUND_AVC] = {"", 0, 1, -1, 4, 0},
119 [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48},
120 [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50},
121 [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60},
122 [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90},
123 [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0},
124 [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0},
125 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
127 #endif
129 const char *sound_unit(int setting)
131 return audiohw_settings[setting].unit;
134 int sound_numdecimals(int setting)
136 return audiohw_settings[setting].numdecimals;
139 int sound_steps(int setting)
141 return audiohw_settings[setting].steps;
144 int sound_min(int setting)
146 return audiohw_settings[setting].minval;
149 int sound_max(int setting)
151 return audiohw_settings[setting].maxval;
154 int sound_default(int setting)
156 return audiohw_settings[setting].defaultval;
159 static sound_set_type * const sound_set_fns[] =
161 [0 ... SOUND_LAST_SETTING-1] = NULL,
162 [SOUND_VOLUME] = sound_set_volume,
163 #if defined(AUDIOHW_HAVE_BASS)
164 [SOUND_BASS] = sound_set_bass,
165 #endif
166 #if defined(AUDIOHW_HAVE_TREBLE)
167 [SOUND_TREBLE] = sound_set_treble,
168 #endif
169 [SOUND_BALANCE] = sound_set_balance,
170 [SOUND_CHANNELS] = sound_set_channels,
171 [SOUND_STEREO_WIDTH] = sound_set_stereo_width,
172 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
173 [SOUND_LOUDNESS] = sound_set_loudness,
174 [SOUND_AVC] = sound_set_avc,
175 [SOUND_MDB_STRENGTH] = sound_set_mdb_strength,
176 [SOUND_MDB_HARMONICS] = sound_set_mdb_harmonics,
177 [SOUND_MDB_CENTER] = sound_set_mdb_center,
178 [SOUND_MDB_SHAPE] = sound_set_mdb_shape,
179 [SOUND_MDB_ENABLE] = sound_set_mdb_enable,
180 [SOUND_SUPERBASS] = sound_set_superbass,
181 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
182 #if defined(AUDIOHW_HAVE_BASS_CUTOFF)
183 [SOUND_BASS_CUTOFF] = sound_set_bass_cutoff,
184 #endif
185 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
186 [SOUND_TREBLE_CUTOFF] = sound_set_treble_cutoff,
187 #endif
188 #if defined(AUDIOHW_HAVE_DEPTH_3D)
189 [SOUND_DEPTH_3D] = sound_set_depth_3d,
190 #endif
191 /* Hardware EQ tone controls */
192 #if defined(AUDIOHW_HAVE_EQ)
193 [SOUND_EQ_BAND1_GAIN] = sound_set_hw_eq_band1_gain,
194 #if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
195 [SOUND_EQ_BAND1_FREQUENCY] = sound_set_hw_eq_band1_frequency,
196 #endif
197 #if defined(AUDIOHW_HAVE_EQ_BAND2)
198 [SOUND_EQ_BAND2_GAIN] = sound_set_hw_eq_band2_gain,
199 #if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
200 [SOUND_EQ_BAND2_FREQUENCY] = sound_set_hw_eq_band2_frequency,
201 #endif
202 #if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
203 [SOUND_EQ_BAND2_WIDTH] = sound_set_hw_eq_band2_width,
204 #endif
205 #endif /* AUDIOHW_HAVE_EQ_BAND2 */
206 #if defined(AUDIOHW_HAVE_EQ_BAND3)
207 [SOUND_EQ_BAND3_GAIN] = sound_set_hw_eq_band3_gain,
208 #if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
209 [SOUND_EQ_BAND3_FREQUENCY] = sound_set_hw_eq_band3_frequency,
210 #endif
211 #if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
212 [SOUND_EQ_BAND3_WIDTH] = sound_set_hw_eq_band3_width,
213 #endif
214 #endif /* AUDIOHW_HAVE_EQ_BAND3 */
215 #if defined(AUDIOHW_HAVE_EQ_BAND4)
216 [SOUND_EQ_BAND4_GAIN] = sound_set_hw_eq_band4_gain,
217 #if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
218 [SOUND_EQ_BAND4_FREQUENCY] = sound_set_hw_eq_band4_frequency,
219 #endif
220 #if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
221 [SOUND_EQ_BAND4_WIDTH] = sound_set_hw_eq_band4_width,
222 #endif
223 #endif /* AUDIOHW_HAVE_EQ_BAND4 */
224 #if defined(AUDIOHW_HAVE_EQ_BAND5)
225 [SOUND_EQ_BAND5_GAIN] = sound_set_hw_eq_band5_gain,
226 #if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
227 [SOUND_EQ_BAND5_FREQUENCY] = sound_set_hw_eq_band5_frequency,
228 #endif
229 #endif /* AUDIOHW_HAVE_EQ_BAND5 */
230 #endif /* AUDIOHW_HAVE_EQ */
233 sound_set_type* sound_get_fn(int setting)
235 return ((unsigned)setting >= ARRAYLEN(sound_set_fns)?
236 NULL : sound_set_fns[setting]);
239 #if CONFIG_CODEC == SWCODEC
240 static int (*dsp_callback)(int, intptr_t) = NULL;
242 void sound_set_dsp_callback(int (*func)(int, intptr_t))
244 dsp_callback = func;
246 #endif
248 #if (CONFIG_CODEC == MAS3507D) && !defined(SIMULATOR)
249 /* convert tenth of dB volume (-780..+180) to dac3550 register value */
250 static int tenthdb2reg(int db)
252 if (db < -540) /* 3 dB steps */
253 return (db + 780) / 30;
254 else /* 1.5 dB steps */
255 return (db + 660) / 15;
257 #endif
260 #if !defined(AUDIOHW_HAVE_CLIPPING)
262 * The prescaler compensates for any kind of boosts, to prevent clipping.
264 * It's basically just a measure to make sure that audio does not clip during
265 * tone controls processing, like if i want to boost bass 12 dB, i can decrease
266 * the audio amplitude by -12 dB before processing, then increase master gain
267 * by 12 dB after processing.
270 /* all values in tenth of dB MAS3507D UDA1380 */
271 int current_volume = 0; /* -780..+180 -840.. 0 */
272 int current_balance = 0; /* -960..+960 -840..+840 */
273 #ifdef AUDIOHW_HAVE_TREBLE
274 int current_treble = 0; /* -150..+150 0.. +60 */
275 #endif
276 #ifdef AUDIOHW_HAVE_BASS
277 int current_bass = 0; /* -150..+150 0..+240 */
278 #endif
279 #ifdef AUDIOHW_HAVE_EQ
280 int current_eq_band_gain[AUDIOHW_EQ_BAND_NUM];
281 #endif
283 static void set_prescaled_volume(void)
285 int prescale = 0;
286 int l, r;
288 /* The codecs listed use HW tone controls but don't have suitable prescaler
289 * functionality, so we let the prescaler stay at 0 for these, unless
290 * SW tone controls are in use. This is to avoid needing the SW DSP just for
291 * the prescaling.
293 #if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
294 || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
295 || defined(HAVE_WM8758) || defined(HAVE_WM8985) || defined(HAVE_UDA1341))
297 #if defined(AUDIOHW_HAVE_BASS) && defined(AUDIOHW_HAVE_TREBLE)
298 prescale = MAX(current_bass, current_treble);
299 #endif
300 #if defined(AUDIOHW_HAVE_EQ)
301 int i;
302 for (i = 0; i < AUDIOHW_EQ_BAND_NUM; i++)
303 prescale = MAX(current_eq_band_gain[i], prescale);
304 #endif
306 if (prescale < 0)
307 prescale = 0; /* no need to prescale if we don't boost
308 bass, treble or eq band */
310 /* Gain up the analog volume to compensate the prescale gain reduction,
311 * but if this would push the volume over the top, reduce prescaling
312 * instead (might cause clipping). */
313 if (current_volume + prescale > VOLUME_MAX)
314 prescale = VOLUME_MAX - current_volume;
315 #endif
317 #if defined(AUDIOHW_HAVE_PRESCALER)
318 audiohw_set_prescaler(prescale);
319 #else
320 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
321 #endif
323 if (current_volume == VOLUME_MIN)
324 prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */
326 l = r = current_volume + prescale;
328 /* Balance the channels scaled by the current volume and min volume. */
329 /* Subtract a dB from VOLUME_MIN to get it to a mute level */
330 if (current_balance > 0)
332 l -= ((l - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE;
334 else if (current_balance < 0)
336 r += ((r - (VOLUME_MIN - ONE_DB)) * current_balance) / VOLUME_RANGE;
339 #ifdef HAVE_SW_VOLUME_CONTROL
340 dsp_callback(DSP_CALLBACK_SET_SW_VOLUME, 0);
341 #endif
343 #ifndef SIMULATOR
344 #if CONFIG_CODEC == MAS3507D
345 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
346 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
347 || defined(HAVE_WM8711) || defined(HAVE_WM8721) || defined(HAVE_WM8731) \
348 || defined(HAVE_WM8750) || defined(HAVE_WM8751) || defined(HAVE_AS3514) \
349 || defined(HAVE_TSC2100) || defined(HAVE_AK4537) || defined(HAVE_UDA1341)
350 audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
351 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
352 || defined(HAVE_WM8750) || (defined(HAVE_WM8751) && !defined(MROBE_100)) \
353 || defined(HAVE_WM8985)
354 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
355 #endif
357 #elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985)
358 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r));
359 #elif defined(HAVE_JZ4740_CODEC)
360 audiohw_set_volume(current_volume);
361 #endif
362 #else /* SIMULATOR */
363 audiohw_set_volume(current_volume);
364 #endif /* !SIMULATOR */
366 #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
369 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
370 unsigned long mdb_shape_shadow = 0;
371 unsigned long loudness_shadow = 0;
372 #endif
374 void sound_set_volume(int value)
376 if(!audio_is_initialized)
377 return;
379 #if defined(AUDIOHW_HAVE_CLIPPING)
380 audiohw_set_volume(value);
381 #elif CONFIG_CPU == PNX0101
382 int tmp = (60 - value * 4) & 0xff;
383 CODECVOL = tmp | (tmp << 8);
384 #else
385 current_volume = value * 10; /* tenth of dB */
386 set_prescaled_volume();
387 #endif
390 void sound_set_balance(int value)
392 if(!audio_is_initialized)
393 return;
395 #ifdef AUDIOHW_HAVE_BALANCE
396 audiohw_set_balance(value);
397 #else
398 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
399 set_prescaled_volume();
400 #endif
403 #ifdef AUDIOHW_HAVE_BASS
404 void sound_set_bass(int value)
406 if(!audio_is_initialized)
407 return;
409 #if !defined(AUDIOHW_HAVE_CLIPPING)
410 #if defined(HAVE_WM8750) || defined(HAVE_WM8751)
411 current_bass = value;
412 #else
413 current_bass = value * 10;
414 #endif
415 #endif
417 #if defined(HAVE_SW_TONE_CONTROLS)
418 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
419 #else
420 audiohw_set_bass(value);
421 #endif
423 #if !defined(AUDIOHW_HAVE_CLIPPING)
424 set_prescaled_volume();
425 #endif
427 #endif /* AUDIOHW_HAVE_BASS */
429 #ifdef AUDIOHW_HAVE_TREBLE
430 void sound_set_treble(int value)
432 if(!audio_is_initialized)
433 return;
435 #if !defined(AUDIOHW_HAVE_CLIPPING)
436 #if defined(HAVE_WM8750) || defined(HAVE_WM8751)
437 current_treble = value;
438 #else
439 current_treble = value * 10;
440 #endif
441 #endif
443 #if defined(HAVE_SW_TONE_CONTROLS)
444 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
445 #else
446 audiohw_set_treble(value);
447 #endif
449 #if !defined(AUDIOHW_HAVE_CLIPPING)
450 set_prescaled_volume();
451 #endif
453 #endif /* AUDIOHW_HAVE_TREBLE */
455 #if defined(AUDIOHW_HAVE_BASS_CUTOFF)
456 void sound_set_bass_cutoff(int value)
458 if(!audio_is_initialized)
459 return;
461 audiohw_set_bass_cutoff(value);
463 #endif
465 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
466 void sound_set_treble_cutoff(int value)
468 if(!audio_is_initialized)
469 return;
471 audiohw_set_treble_cutoff(value);
473 #endif
475 void sound_set_channels(int value)
477 if(!audio_is_initialized)
478 return;
480 #if CONFIG_CODEC == SWCODEC
481 dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value);
482 #else
483 audiohw_set_channel(value);
484 #endif
487 void sound_set_stereo_width(int value)
489 if(!audio_is_initialized)
490 return;
492 #if CONFIG_CODEC == SWCODEC
493 dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH, value);
494 #else
495 audiohw_set_stereo_width(value);
496 #endif
499 #if defined(AUDIOHW_HAVE_DEPTH_3D)
500 void sound_set_depth_3d(int value)
502 if(!audio_is_initialized)
503 return;
505 audiohw_set_depth_3d(value);
507 #endif
509 #if defined(AUDIOHW_HAVE_EQ)
510 int sound_enum_hw_eq_band_setting(unsigned int band,
511 unsigned int band_setting)
513 static const int8_t
514 sound_hw_eq_band_setting[AUDIOHW_EQ_SETTING_NUM][AUDIOHW_EQ_BAND_NUM] =
516 [AUDIOHW_EQ_GAIN] =
518 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
519 [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_GAIN,
520 #ifdef AUDIOHW_HAVE_EQ_BAND2
521 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_GAIN,
522 #endif
523 #ifdef AUDIOHW_HAVE_EQ_BAND3
524 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_GAIN,
525 #endif
526 #ifdef AUDIOHW_HAVE_EQ_BAND4
527 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_GAIN,
528 #endif
529 #ifdef AUDIOHW_HAVE_EQ_BAND5
530 [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_GAIN,
531 #endif
533 #ifdef AUDIOHW_HAVE_EQ_FREQUENCY
534 [AUDIOHW_EQ_FREQUENCY] =
536 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
537 #ifdef AUDIOHW_HAVE_EQ_BAND1_FREQUENCY
538 [AUDIOHW_EQ_BAND1] = SOUND_EQ_BAND1_FREQUENCY,
539 #endif
540 #ifdef AUDIOHW_HAVE_EQ_BAND2_FREQUENCY
541 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_FREQUENCY,
542 #endif
543 #ifdef AUDIOHW_HAVE_EQ_BAND3_FREQUENCY
544 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_FREQUENCY,
545 #endif
546 #ifdef AUDIOHW_HAVE_EQ_BAND4_FREQUENCY
547 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_FREQUENCY,
548 #endif
549 #ifdef AUDIOHW_HAVE_EQ_BAND5_FREQUENCY
550 [AUDIOHW_EQ_BAND5] = SOUND_EQ_BAND5_FREQUENCY,
551 #endif
553 #endif /* AUDIOHW_HAVE_EQ_FREQUENCY */
554 #ifdef AUDIOHW_HAVE_EQ_WIDTH
555 [AUDIOHW_EQ_WIDTH] =
557 [0 ... AUDIOHW_EQ_BAND_NUM-1] = -1,
558 #ifdef AUDIOHW_HAVE_EQ_BAND2_WIDTH
559 [AUDIOHW_EQ_BAND2] = SOUND_EQ_BAND2_WIDTH,
560 #endif
561 #ifdef AUDIOHW_HAVE_EQ_BAND3_WIDTH
562 [AUDIOHW_EQ_BAND3] = SOUND_EQ_BAND3_WIDTH,
563 #endif
564 #ifdef AUDIOHW_HAVE_EQ_BAND4_WIDTH
565 [AUDIOHW_EQ_BAND4] = SOUND_EQ_BAND4_WIDTH,
566 #endif
568 #endif /* AUDIOHW_HAVE_EQ_WIDTH */
571 if (band < AUDIOHW_EQ_BAND_NUM && band_setting < AUDIOHW_EQ_SETTING_NUM)
572 return sound_hw_eq_band_setting[band_setting][band];
574 return -1;
577 static void sound_set_hw_eq_band_gain(unsigned int band, int value)
579 if(!audio_is_initialized)
580 return;
582 current_eq_band_gain[band] = value;
583 audiohw_set_eq_band_gain(band, value);
584 set_prescaled_volume();
587 void sound_set_hw_eq_band1_gain(int value)
589 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND1, value);
592 #if defined(AUDIOHW_HAVE_EQ_BAND2)
593 void sound_set_hw_eq_band2_gain(int value)
595 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND2, value);
597 #endif
599 #if defined(AUDIOHW_HAVE_EQ_BAND3)
600 void sound_set_hw_eq_band3_gain(int value)
602 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND3, value);
604 #endif
606 #if defined(AUDIOHW_HAVE_EQ_BAND4)
607 void sound_set_hw_eq_band4_gain(int value)
609 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND4, value);
611 #endif
613 #if defined(AUDIOHW_HAVE_EQ_BAND5)
614 void sound_set_hw_eq_band5_gain(int value)
616 sound_set_hw_eq_band_gain(AUDIOHW_EQ_BAND5, value);
618 #endif
620 #if defined(AUDIOHW_HAVE_EQ_BAND1_FREQUENCY)
621 void sound_set_hw_eq_band1_frequency(int value)
623 if(!audio_is_initialized)
624 return;
626 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND1, value);
628 #endif
630 #if defined(AUDIOHW_HAVE_EQ_BAND2_FREQUENCY)
631 void sound_set_hw_eq_band2_frequency(int value)
633 if(!audio_is_initialized)
634 return;
636 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND2, value);
638 #endif
640 #if defined(AUDIOHW_HAVE_EQ_BAND3_FREQUENCY)
641 void sound_set_hw_eq_band3_frequency(int value)
643 if(!audio_is_initialized)
644 return;
646 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND3, value);
648 #endif
650 #if defined(AUDIOHW_HAVE_EQ_BAND4_FREQUENCY)
651 void sound_set_hw_eq_band4_frequency(int value)
653 if(!audio_is_initialized)
654 return;
656 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND4, value);
658 #endif
660 #if defined(AUDIOHW_HAVE_EQ_BAND5_FREQUENCY)
661 void sound_set_hw_eq_band5_frequency(int value)
663 if(!audio_is_initialized)
664 return;
666 audiohw_set_eq_band_frequency(AUDIOHW_EQ_BAND5, value);
668 #endif
670 #if defined(AUDIOHW_HAVE_EQ_BAND2_WIDTH)
671 void sound_set_hw_eq_band2_width(int value)
673 if(!audio_is_initialized)
674 return;
676 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND2, value);
678 #endif
680 #if defined(AUDIOHW_HAVE_EQ_BAND3_WIDTH)
681 void sound_set_hw_eq_band3_width(int value)
683 if(!audio_is_initialized)
684 return;
686 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND3, value);
688 #endif
690 #if defined(AUDIOHW_HAVE_EQ_BAND4_WIDTH)
691 void sound_set_hw_eq_band4_width(int value)
693 if(!audio_is_initialized)
694 return;
696 audiohw_set_eq_band_width(AUDIOHW_EQ_BAND4, value);
698 #endif
699 #endif /* AUDIOHW_HAVE_EQ */
701 #if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F))
702 void sound_set_loudness(int value)
704 if(!audio_is_initialized)
705 return;
706 loudness_shadow = (loudness_shadow & 0x04) |
707 (MAX(MIN(value * 4, 0x44), 0) << 8);
708 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
711 void sound_set_avc(int value)
713 if(!audio_is_initialized)
714 return;
715 int tmp;
717 static const uint16_t avc_vals[] =
719 (0x1 << 8) | (0x8 << 12), /* 20ms */
720 (0x2 << 8) | (0x8 << 12), /* 2s */
721 (0x4 << 8) | (0x8 << 12), /* 4s */
722 (0x8 << 8) | (0x8 << 12), /* 8s */
724 switch (value) {
725 case 1:
726 case 2:
727 case 3:
728 case 4:
729 tmp = avc_vals[value -1];
730 break;
731 case -1: /* turn off and then turn on again to decay quickly */
732 tmp = mas_codec_readreg(MAS_REG_KAVC);
733 mas_codec_writereg(MAS_REG_KAVC, 0);
734 break;
735 default: /* off */
736 tmp = 0;
737 break;
739 mas_codec_writereg(MAS_REG_KAVC, tmp);
742 void sound_set_mdb_strength(int value)
744 if(!audio_is_initialized)
745 return;
746 mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
749 void sound_set_mdb_harmonics(int value)
751 if(!audio_is_initialized)
752 return;
753 int tmp = value * 127 / 100;
754 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
757 void sound_set_mdb_center(int value)
759 if(!audio_is_initialized)
760 return;
761 mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
764 void sound_set_mdb_shape(int value)
766 if(!audio_is_initialized)
767 return;
768 mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
769 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
772 void sound_set_mdb_enable(int value)
774 if(!audio_is_initialized)
775 return;
776 mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
777 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
780 void sound_set_superbass(int value)
782 if(!audio_is_initialized)
783 return;
784 loudness_shadow = (loudness_shadow & ~0x04) | (value?4:0);
785 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
787 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
789 void sound_set(int setting, int value)
791 sound_set_type* sound_set_val = sound_get_fn(setting);
792 if (sound_set_val)
793 sound_set_val(value);
796 #if (!defined(HAVE_AS3514) && !defined(HAVE_WM8975) \
797 && !defined(HAVE_WM8758) && !defined(HAVE_TSC2100) \
798 && !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \
799 && !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \
800 && !defined(HAVE_AK4537)) || defined(SIMULATOR)
801 int sound_val2phys(int setting, int value)
803 #if CONFIG_CODEC == MAS3587F
804 int result = 0;
806 switch(setting)
808 case SOUND_LEFT_GAIN:
809 case SOUND_RIGHT_GAIN:
810 result = (value - 2) * 15;
811 break;
813 case SOUND_MIC_GAIN:
814 result = value * 15 + 210;
815 break;
817 default:
818 result = value;
819 break;
821 return result;
822 #elif defined(HAVE_UDA1380)
823 int result = 0;
825 switch(setting)
827 #ifdef HAVE_RECORDING
828 case SOUND_LEFT_GAIN:
829 case SOUND_RIGHT_GAIN:
830 case SOUND_MIC_GAIN:
831 result = value * 5; /* (1/2) * 10 */
832 break;
833 #endif
834 default:
835 result = value;
836 break;
838 return result;
839 #elif defined(HAVE_TLV320) || defined(HAVE_WM8711) \
840 || defined(HAVE_WM8721) || defined(HAVE_WM8731)
841 int result = 0;
843 switch(setting)
845 #ifdef HAVE_RECORDING
846 case SOUND_LEFT_GAIN:
847 case SOUND_RIGHT_GAIN:
848 result = (value - 23) * 15; /* (x - 23)/1.5 *10 */
849 break;
851 case SOUND_MIC_GAIN:
852 result = value * 200; /* 0 or 20 dB */
853 break;
854 #endif
855 default:
856 result = value;
857 break;
859 return result;
860 #elif defined(HAVE_AS3514)
861 /* This is here for the sim only and the audio driver has its own */
862 int result;
864 switch(setting)
866 #ifdef HAVE_RECORDING
867 case SOUND_LEFT_GAIN:
868 case SOUND_RIGHT_GAIN:
869 case SOUND_MIC_GAIN:
870 result = (value - 23) * 15;
871 break;
872 #endif
873 default:
874 result = value;
875 break;
878 return result;
879 #elif defined(HAVE_WM8978)
880 int result;
882 switch (setting)
884 #ifdef HAVE_RECORDING
885 case SOUND_LEFT_GAIN:
886 case SOUND_RIGHT_GAIN:
887 case SOUND_MIC_GAIN:
888 result = value * 5;
889 break;
890 #endif
892 case SOUND_DEPTH_3D:
893 result = (100 * value + 8) / 15;
894 break;
896 default:
897 result = value;
900 return result;
901 #else
902 (void)setting;
903 return value;
904 #endif
906 #endif /* !defined(HAVE_AS3514) || defined(SIMULATOR) */
908 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
909 /* This function works by telling the decoder that we have another
910 crystal frequency than we actually have. It will adjust its internal
911 parameters and the result is that the audio is played at another pitch.
913 The pitch value precision is based on PITCH_SPEED_PRECISION (in dsp.h)
916 #ifdef SIMULATOR
917 static
918 #else
919 extern
920 #endif
921 unsigned long shadow_io_control_main;
922 static int last_pitch = PITCH_SPEED_100;
924 void sound_set_pitch(int32_t pitch)
926 unsigned long val;
928 if (pitch != last_pitch)
930 /* Calculate the new (bogus) frequency */
931 val = 18432 * PITCH_SPEED_100 / pitch;
933 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
935 /* We must tell the MAS that the frequency has changed.
936 * This will unfortunately cause a short silence. */
937 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
939 last_pitch = pitch;
943 int32_t sound_get_pitch(void)
945 return last_pitch;
947 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */