Fix sim crashes on long filenames. Patch by Sean Morrisey with some minor changes...
[kugel-rb.git] / firmware / sound.c
blobcb8392743911c3b6802a637575bd12ef174b3ee7
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdbool.h>
20 #include <stdio.h>
21 #include "config.h"
22 #include "sound.h"
23 #include "logf.h"
24 #ifndef SIMULATOR
25 #include "i2c.h"
26 #include "mas.h"
27 #if CONFIG_CPU == PNX0101
28 #include "pnx0101.h"
29 #endif
30 #include "dac.h"
31 #include "system.h"
32 #if CONFIG_CODEC == SWCODEC
33 #include "pcm_playback.h"
34 #endif
35 #endif
37 #ifndef SIMULATOR
38 extern bool audio_is_initialized;
40 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
41 extern unsigned long shadow_io_control_main;
42 extern unsigned shadow_codec_reg0;
43 #endif
44 #endif /* SIMULATOR */
46 struct sound_settings_info {
47 const char *unit;
48 int numdecimals;
49 int steps;
50 int minval;
51 int maxval;
52 int defaultval;
53 sound_set_type *setfn;
56 static const struct sound_settings_info sound_settings_table[] = {
57 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
58 [SOUND_VOLUME] = {"dB", 0, 1,-100, 12, -25, sound_set_volume},
59 [SOUND_BASS] = {"dB", 0, 1, -12, 12, 6, sound_set_bass},
60 [SOUND_TREBLE] = {"dB", 0, 1, -12, 12, 6, sound_set_treble},
61 #elif defined(HAVE_UDA1380)
62 [SOUND_VOLUME] = {"dB", 0, 1, -84, 0, -25, sound_set_volume},
63 [SOUND_BASS] = {"dB", 0, 2, 0, 24, 0, sound_set_bass},
64 [SOUND_TREBLE] = {"dB", 0, 2, 0, 6, 0, sound_set_treble},
65 #elif defined(HAVE_TLV320)
66 [SOUND_VOLUME] = {"dB", 0, 1, -73, 6, -20, sound_set_volume},
67 #elif defined(HAVE_WM8975) || defined(HAVE_WM8751)
68 [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25, sound_set_volume},
69 [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass},
70 [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble},
71 #elif defined(HAVE_WM8758)
72 [SOUND_VOLUME] = {"dB", 0, 1, -58, 6, -25, sound_set_volume},
73 [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass},
74 [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble},
75 #elif defined(HAVE_WM8731) || defined(HAVE_WM8721)
76 [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25, sound_set_volume},
77 #elif (CONFIG_CPU == PNX0101)
78 [SOUND_VOLUME] = {"dB", 0, 1, -48, 15, 0, sound_set_volume},
79 #elif defined(HAVE_AS3514)
80 [SOUND_VOLUME] = {"dB", 0, 1, -45, 1, -25, sound_set_volume},
81 #else /* MAS3507D */
82 [SOUND_VOLUME] = {"dB", 0, 1, -78, 18, -18, sound_set_volume},
83 [SOUND_BASS] = {"dB", 0, 1, -15, 15, 7, sound_set_bass},
84 [SOUND_TREBLE] = {"dB", 0, 1, -15, 15, 7, sound_set_treble},
85 #endif
86 /* Override any other potentially existing treble/bass controllers if wanted */
87 #ifdef HAVE_SW_TONE_CONTROLS
88 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0, sound_set_bass},
89 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0, sound_set_treble},
90 #endif
91 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0, sound_set_balance},
92 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0, sound_set_channels},
93 [SOUND_STEREO_WIDTH] = {"%", 0, 1, 0, 255, 100, sound_set_stereo_width},
94 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
95 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0, sound_set_loudness},
96 [SOUND_AVC] = {"", 0, 1, -1, 4, 0, sound_set_avc},
97 [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48, sound_set_mdb_strength},
98 [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50, sound_set_mdb_harmonics},
99 [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60, sound_set_mdb_center},
100 [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90, sound_set_mdb_shape},
101 [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0, sound_set_mdb_enable},
102 [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0, sound_set_superbass},
103 #endif
104 #if CONFIG_CODEC == MAS3587F
105 [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 15, 8, NULL},
106 [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 15, 8, NULL},
107 [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 15, 2, NULL},
108 #elif defined(HAVE_UDA1380)
109 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
110 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
111 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16, NULL},
112 #elif defined(HAVE_TLV320)
113 [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23, NULL},
114 [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23, NULL},
115 [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 1, NULL},
116 #elif defined(HAVE_WM8975)
117 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
118 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
119 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16, NULL},
120 #elif defined(HAVE_WM8758)
121 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
122 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
123 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16, NULL},
124 #elif defined(HAVE_WM8731)
125 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
126 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
127 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16, NULL},
128 #endif
131 const char *sound_unit(int setting)
133 return sound_settings_table[setting].unit;
136 int sound_numdecimals(int setting)
138 return sound_settings_table[setting].numdecimals;
141 int sound_steps(int setting)
143 return sound_settings_table[setting].steps;
146 int sound_min(int setting)
148 return sound_settings_table[setting].minval;
151 int sound_max(int setting)
153 return sound_settings_table[setting].maxval;
156 int sound_default(int setting)
158 return sound_settings_table[setting].defaultval;
161 sound_set_type* sound_get_fn(int setting)
163 if ((unsigned)setting < (sizeof(sound_settings_table)
164 / sizeof(struct sound_settings_info)))
165 return sound_settings_table[setting].setfn;
166 else
167 return NULL;
170 #if CONFIG_CODEC == SWCODEC
171 /* Copied from dsp.h, nasty nasty, but we don't want to include dsp.h */
172 enum {
173 DSP_CALLBACK_SET_PRESCALE = 0,
174 DSP_CALLBACK_SET_BASS,
175 DSP_CALLBACK_SET_TREBLE,
176 DSP_CALLBACK_SET_CHANNEL_CONFIG,
177 DSP_CALLBACK_SET_STEREO_WIDTH
180 static int (*dsp_callback)(int, intptr_t) = NULL;
182 void sound_set_dsp_callback(int (*func)(int, intptr_t))
184 dsp_callback = func;
186 #endif
188 #ifndef SIMULATOR
189 #if CONFIG_CODEC == MAS3507D /* volume/balance/treble/bass interdependency */
190 #define VOLUME_MIN -780
191 #define VOLUME_MAX 180
193 static const unsigned int bass_table[] =
195 0x9e400, /* -15dB */
196 0xa2800, /* -14dB */
197 0xa7400, /* -13dB */
198 0xac400, /* -12dB */
199 0xb1800, /* -11dB */
200 0xb7400, /* -10dB */
201 0xbd400, /* -9dB */
202 0xc3c00, /* -8dB */
203 0xca400, /* -7dB */
204 0xd1800, /* -6dB */
205 0xd8c00, /* -5dB */
206 0xe0400, /* -4dB */
207 0xe8000, /* -3dB */
208 0xefc00, /* -2dB */
209 0xf7c00, /* -1dB */
211 0x800, /* 1dB */
212 0x10000, /* 2dB */
213 0x17c00, /* 3dB */
214 0x1f800, /* 4dB */
215 0x27000, /* 5dB */
216 0x2e400, /* 6dB */
217 0x35800, /* 7dB */
218 0x3c000, /* 8dB */
219 0x42800, /* 9dB */
220 0x48800, /* 10dB */
221 0x4e400, /* 11dB */
222 0x53800, /* 12dB */
223 0x58800, /* 13dB */
224 0x5d400, /* 14dB */
225 0x61800 /* 15dB */
228 static const unsigned int treble_table[] =
230 0xb2c00, /* -15dB */
231 0xbb400, /* -14dB */
232 0xc1800, /* -13dB */
233 0xc6c00, /* -12dB */
234 0xcbc00, /* -11dB */
235 0xd0400, /* -10dB */
236 0xd5000, /* -9dB */
237 0xd9800, /* -8dB */
238 0xde000, /* -7dB */
239 0xe2800, /* -6dB */
240 0xe7e00, /* -5dB */
241 0xec000, /* -4dB */
242 0xf0c00, /* -3dB */
243 0xf5c00, /* -2dB */
244 0xfac00, /* -1dB */
246 0x5400, /* 1dB */
247 0xac00, /* 2dB */
248 0x10400, /* 3dB */
249 0x16000, /* 4dB */
250 0x1c000, /* 5dB */
251 0x22400, /* 6dB */
252 0x28400, /* 7dB */
253 0x2ec00, /* 8dB */
254 0x35400, /* 9dB */
255 0x3c000, /* 10dB */
256 0x42c00, /* 11dB */
257 0x49c00, /* 12dB */
258 0x51800, /* 13dB */
259 0x58400, /* 14dB */
260 0x5f800 /* 15dB */
263 static const unsigned int prescale_table[] =
265 0x80000, /* 0db */
266 0x8e000, /* 1dB */
267 0x9a400, /* 2dB */
268 0xa5800, /* 3dB */
269 0xaf400, /* 4dB */
270 0xb8000, /* 5dB */
271 0xbfc00, /* 6dB */
272 0xc6c00, /* 7dB */
273 0xcd000, /* 8dB */
274 0xd25c0, /* 9dB */
275 0xd7800, /* 10dB */
276 0xdc000, /* 11dB */
277 0xdfc00, /* 12dB */
278 0xe3400, /* 13dB */
279 0xe6800, /* 14dB */
280 0xe9400 /* 15dB */
283 /* convert tenth of dB volume (-780..+180) to dac3550 register value */
284 static int tenthdb2reg(int db)
286 if (db < -540) /* 3 dB steps */
287 return (db + 780) / 30;
288 else /* 1.5 dB steps */
289 return (db + 660) / 15;
291 #endif
293 #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
294 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_WM8731) \
295 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
296 || defined(HAVE_AS3514)
297 /* volume/balance/treble/bass interdependency main part */
298 #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
300 /* all values in tenth of dB MAS3507D UDA1380 */
301 int current_volume = 0; /* -780..+180 -840.. 0 */
302 int current_balance = 0; /* -960..+960 -840..+840 */
303 int current_treble = 0; /* -150..+150 0.. +60 */
304 int current_bass = 0; /* -150..+150 0..+240 */
306 static void set_prescaled_volume(void)
308 int prescale = 0;
309 int l, r;
311 /* The WM codecs listed don't have suitable prescaler functionality, so we let
312 * the prescaler stay at 0 for these unless SW tone controls are in use */
313 #if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
314 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751))
316 prescale = MAX(current_bass, current_treble);
317 if (prescale < 0)
318 prescale = 0; /* no need to prescale if we don't boost
319 bass or treble */
321 /* Gain up the analog volume to compensate the prescale gain reduction,
322 * but if this would push the volume over the top, reduce prescaling
323 * instead (might cause clipping). */
324 if (current_volume + prescale > VOLUME_MAX)
325 prescale = VOLUME_MAX - current_volume;
326 #endif
328 #if defined(HAVE_SW_TONE_CONTROLS)
329 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
330 #elif CONFIG_CODEC == MAS3507D
331 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
332 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8758)
333 audiohw_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale));
334 #endif
336 if (current_volume == VOLUME_MIN)
337 prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */
339 l = r = current_volume + prescale;
341 if (current_balance > 0)
343 l -= current_balance;
344 if (l < VOLUME_MIN)
345 l = VOLUME_MIN;
347 if (current_balance < 0)
349 r += current_balance;
350 if (r < VOLUME_MIN)
351 r = VOLUME_MIN;
354 #if CONFIG_CODEC == MAS3507D
355 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
356 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
357 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
358 || defined(HAVE_AS3514)
359 audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
360 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8751)
361 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
362 #endif
364 #elif defined(HAVE_TLV320)
365 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r));
366 #endif
368 #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
369 #endif /* !SIMULATOR */
371 #if CONFIG_CODEC != SWCODEC
372 int channel_configuration = SOUND_CHAN_STEREO;
373 int stereo_width = 100;
374 #endif
376 #ifndef SIMULATOR
378 #if CONFIG_CODEC != SWCODEC
379 static void set_channel_config(void)
381 /* default values: stereo */
382 unsigned long val_ll = 0x80000;
383 unsigned long val_lr = 0;
384 unsigned long val_rl = 0;
385 unsigned long val_rr = 0x80000;
387 switch(channel_configuration)
389 /* case SOUND_CHAN_STEREO unnecessary */
391 case SOUND_CHAN_MONO:
392 val_ll = 0xc0000;
393 val_lr = 0xc0000;
394 val_rl = 0xc0000;
395 val_rr = 0xc0000;
396 break;
398 case SOUND_CHAN_CUSTOM:
400 /* fixed point variables (matching MAS internal format)
401 integer part: upper 13 bits (inlcuding sign)
402 fractional part: lower 19 bits */
403 long fp_width, fp_straight, fp_cross;
405 fp_width = (stereo_width << 19) / 100;
406 if (stereo_width <= 100)
408 fp_straight = - ((1<<19) + fp_width) / 2;
409 fp_cross = fp_straight + fp_width;
411 else
413 /* straight = - (1 + width) / (2 * width) */
414 fp_straight = - ((((1<<19) + fp_width) / (fp_width >> 9)) << 9);
415 fp_cross = (1<<19) + fp_straight;
417 val_ll = val_rr = fp_straight & 0xfffff;
418 val_lr = val_rl = fp_cross & 0xfffff;
420 break;
422 case SOUND_CHAN_MONO_LEFT:
423 val_ll = 0x80000;
424 val_lr = 0x80000;
425 val_rl = 0;
426 val_rr = 0;
427 break;
429 case SOUND_CHAN_MONO_RIGHT:
430 val_ll = 0;
431 val_lr = 0;
432 val_rl = 0x80000;
433 val_rr = 0x80000;
434 break;
436 case SOUND_CHAN_KARAOKE:
437 val_ll = 0xc0000;
438 val_lr = 0x40000;
439 val_rl = 0x40000;
440 val_rr = 0xc0000;
441 break;
444 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
445 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
446 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
447 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
448 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
449 #elif CONFIG_CODEC == MAS3507D
450 mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */
451 mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */
452 mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */
453 mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */
454 #endif
457 #endif /* CONFIG_CODEC != SWCODEC */
459 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
460 unsigned long mdb_shape_shadow = 0;
461 unsigned long loudness_shadow = 0;
462 #endif
464 void sound_set_volume(int value)
466 if(!audio_is_initialized)
467 return;
468 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
469 unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8;
470 mas_codec_writereg(0x10, tmp);
471 #elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 \
472 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
473 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
474 || defined(HAVE_AS3514)
475 current_volume = value * 10; /* tenth of dB */
476 set_prescaled_volume();
477 #elif CONFIG_CPU == PNX0101
478 int tmp = (60 - value * 4) & 0xff;
479 CODECVOL = tmp | (tmp << 8);
480 #endif
483 void sound_set_balance(int value)
485 if(!audio_is_initialized)
486 return;
487 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
488 unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8;
489 mas_codec_writereg(0x11, tmp);
490 #elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 \
491 || defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 \
492 || defined(HAVE_WM8721) || defined(HAVE_TLV320) || defined(HAVE_WM8751) \
493 || defined(HAVE_AS3514)
494 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
495 set_prescaled_volume();
496 #elif CONFIG_CPU == PNX0101
497 /* TODO: implement for iFP */
498 (void)value;
499 #endif
502 void sound_set_bass(int value)
504 if(!audio_is_initialized)
505 return;
506 #if defined(HAVE_SW_TONE_CONTROLS)
507 current_bass = value * 10;
508 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
509 set_prescaled_volume();
510 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
511 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
512 mas_codec_writereg(0x14, tmp);
513 #elif CONFIG_CODEC == MAS3507D
514 mas_writereg(MAS_REG_KBASS, bass_table[value+15]);
515 current_bass = value * 10;
516 set_prescaled_volume();
517 #elif defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_UDA1380) \
518 || defined HAVE_WM8731 || defined(HAVE_WM8721) || defined(HAVE_WM8751)
519 current_bass = value * 10;
520 audiohw_set_bass(value);
521 set_prescaled_volume();
522 #elif CONFIG_CPU == PNX0101
523 /* TODO: implement for iFP */
524 (void)value;
525 #endif
528 void sound_set_treble(int value)
530 if(!audio_is_initialized)
531 return;
532 #if defined(HAVE_SW_TONE_CONTROLS)
533 current_treble = value * 10;
534 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
535 set_prescaled_volume();
536 #elif (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
537 unsigned tmp = ((unsigned)(value * 8) & 0xff) << 8;
538 mas_codec_writereg(0x15, tmp);
539 #elif CONFIG_CODEC == MAS3507D
540 mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]);
541 current_treble = value * 10;
542 set_prescaled_volume();
543 #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_UDA1380) \
544 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751)
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 int sound_val2phys(int setting, int value)
748 #if CONFIG_CODEC == MAS3587F
749 int result = 0;
751 switch(setting)
753 case SOUND_LEFT_GAIN:
754 case SOUND_RIGHT_GAIN:
755 result = (value - 2) * 15;
756 break;
758 case SOUND_MIC_GAIN:
759 result = value * 15 + 210;
760 break;
762 default:
763 result = value;
764 break;
766 return result;
767 #elif defined(HAVE_UDA1380)
768 int result = 0;
770 switch(setting)
772 case SOUND_LEFT_GAIN:
773 case SOUND_RIGHT_GAIN:
774 case SOUND_MIC_GAIN:
775 result = value * 5; /* (1/2) * 10 */
776 break;
778 default:
779 result = value;
780 break;
782 return result;
783 #elif defined(HAVE_TLV320)
784 int result = 0;
786 switch(setting)
788 case SOUND_LEFT_GAIN:
789 case SOUND_RIGHT_GAIN:
790 result = (value - 23) * 15; /* (x - 23)/1.5 *10 */
791 break;
793 case SOUND_MIC_GAIN:
794 result = value * 200; /* 0 or 20 dB */
795 break;
797 default:
798 result = value;
799 break;
801 return result;
802 #else
803 (void)setting;
804 return value;
805 #endif
808 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
809 #ifndef SIMULATOR
810 /* This function works by telling the decoder that we have another
811 crystal frequency than we actually have. It will adjust its internal
812 parameters and the result is that the audio is played at another pitch.
814 The pitch value is in tenths of percent.
816 static int last_pitch = 1000;
818 void sound_set_pitch(int pitch)
820 unsigned long val;
822 if (pitch != last_pitch)
824 /* Calculate the new (bogus) frequency */
825 val = 18432 * 1000 / pitch;
827 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
829 /* We must tell the MAS that the frequency has changed.
830 * This will unfortunately cause a short silence. */
831 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
833 last_pitch = pitch;
837 int sound_get_pitch(void)
839 return last_pitch;
841 #else /* SIMULATOR */
842 void sound_set_pitch(int pitch)
844 (void)pitch;
847 int sound_get_pitch(void)
849 return 1000;
851 #endif /* SIMULATOR */
852 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */