blob: cd772f5e9fa1be62e7559eb6ea3c3f1bb5a32c67 [file] [log] [blame]
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdbool.h>
Linus Nielsen Feltzingd6f297e2005-06-05 23:46:09 +000020#include <stdio.h>
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000021#include "config.h"
22#include "sound.h"
23#ifndef SIMULATOR
24#include "i2c.h"
25#include "mas.h"
Thom Johansen38c9d752005-06-15 19:56:44 +000026#ifdef HAVE_UDA1380
27#include "uda1380.h"
Christian Gmeiner14e80672005-08-06 10:12:19 +000028#elif HAVE_TLV320
29#include "tlv320.h"
Thom Johansen38c9d752005-06-15 19:56:44 +000030#endif
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000031#include "dac.h"
32#include "system.h"
33#include "hwcompat.h"
Linus Nielsen Feltzingd6f297e2005-06-05 23:46:09 +000034#if CONFIG_HWCODEC == MASNONE
35#include "pcm_playback.h"
36#endif
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000037#endif
38
39#ifndef SIMULATOR
40extern bool audio_is_initialized;
41#endif
42
43#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
44extern unsigned long shadow_io_control_main;
45extern unsigned shadow_codec_reg0;
46#endif
47
48static const char* const units[] =
49{
50 "%", /* Volume */
51 "dB", /* Bass */
52 "dB", /* Treble */
53 "%", /* Balance */
54 "dB", /* Loudness */
55 "", /* AVC */
56 "", /* Channels */
57 "%", /* Stereo width */
58 "dB", /* Left gain */
59 "dB", /* Right gain */
60 "dB", /* Mic gain */
61 "dB", /* MDB Strength */
62 "%", /* MDB Harmonics */
63 "Hz", /* MDB Center */
64 "Hz", /* MDB Shape */
65 "", /* MDB Enable */
66 "", /* Super bass */
67};
68
69static const int numdecimals[] =
70{
71 0, /* Volume */
72 0, /* Bass */
73 0, /* Treble */
74 0, /* Balance */
75 0, /* Loudness */
76 0, /* AVC */
77 0, /* Channels */
78 0, /* Stereo width */
79 1, /* Left gain */
80 1, /* Right gain */
81 1, /* Mic gain */
82 0, /* MDB Strength */
83 0, /* MDB Harmonics */
84 0, /* MDB Center */
85 0, /* MDB Shape */
86 0, /* MDB Enable */
87 0, /* Super bass */
88};
89
90static const int steps[] =
91{
92 1, /* Volume */
Thom Johansen38c9d752005-06-15 19:56:44 +000093#ifdef HAVE_UDA1380
94 2, /* Bass */
95 2, /* Treble */
Thom Johanseneadceed2005-06-15 20:09:09 +000096#else
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000097 1, /* Bass */
98 1, /* Treble */
Thom Johanseneadceed2005-06-15 20:09:09 +000099#endif
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000100 1, /* Balance */
101 1, /* Loudness */
102 1, /* AVC */
103 1, /* Channels */
104 1, /* Stereo width */
105 1, /* Left gain */
106 1, /* Right gain */
107 1, /* Mic gain */
108 1, /* MDB Strength */
109 1, /* MDB Harmonics */
110 10, /* MDB Center */
111 10, /* MDB Shape */
112 1, /* MDB Enable */
113 1, /* Super bass */
114};
115
116static const int minval[] =
117{
118 0, /* Volume */
119#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
120 -12, /* Bass */
121 -12, /* Treble */
Thom Johansen38c9d752005-06-15 19:56:44 +0000122#elif defined(HAVE_UDA1380)
123 0, /* Bass */
124 0, /* Treble */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000125#else
126 -15, /* Bass */
127 -15, /* Treble */
128#endif
129 -100, /* Balance */
130 0, /* Loudness */
131 -1, /* AVC */
132 0, /* Channels */
133 0, /* Stereo width */
134 0, /* Left gain */
135 0, /* Right gain */
136 0, /* Mic gain */
137 0, /* MDB Strength */
138 0, /* MDB Harmonics */
139 20, /* MDB Center */
140 50, /* MDB Shape */
141 0, /* MDB Enable */
142 0, /* Super bass */
143};
144
145static const int maxval[] =
146{
147 100, /* Volume */
148#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
149 12, /* Bass */
150 12, /* Treble */
Thom Johansen38c9d752005-06-15 19:56:44 +0000151#elif defined(HAVE_UDA1380)
152 24, /* Bass */
153 6, /* Treble */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000154#else
155 15, /* Bass */
156 15, /* Treble */
157#endif
158 100, /* Balance */
159 17, /* Loudness */
160 4, /* AVC */
161 5, /* Channels */
162 255, /* Stereo width */
163 15, /* Left gain */
164 15, /* Right gain */
165 15, /* Mic gain */
166 127, /* MDB Strength */
167 100, /* MDB Harmonics */
168 300, /* MDB Center */
169 300, /* MDB Shape */
170 1, /* MDB Enable */
171 1, /* Super bass */
172};
173
174static const int defaultval[] =
175{
176 70, /* Volume */
177#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
178 6, /* Bass */
179 6, /* Treble */
Thom Johanseneadceed2005-06-15 20:09:09 +0000180#elif defined(HAVE_UDA1380)
181 0, /* Bass */
182 0, /* Treble */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000183#else
184 7, /* Bass */
185 7, /* Treble */
186#endif
187 0, /* Balance */
188 0, /* Loudness */
189 0, /* AVC */
190 0, /* Channels */
191 100, /* Stereo width */
192 8, /* Left gain */
193 8, /* Right gain */
194 2, /* Mic gain */
195 50, /* MDB Strength */
196 48, /* MDB Harmonics */
197 60, /* MDB Center */
198 90, /* MDB Shape */
199 0, /* MDB Enable */
200 0, /* Super bass */
201};
202
203const char *sound_unit(int setting)
204{
205 return units[setting];
206}
207
208int sound_numdecimals(int setting)
209{
210 return numdecimals[setting];
211}
212
213int sound_steps(int setting)
214{
215 return steps[setting];
216}
217
218int sound_min(int setting)
219{
220 return minval[setting];
221}
222
223int sound_max(int setting)
224{
225 return maxval[setting];
226}
227
228int sound_default(int setting)
229{
230 return defaultval[setting];
231}
232
233#ifndef SIMULATOR
Jens Arnold12a0e222005-06-19 23:33:23 +0000234#if CONFIG_HWCODEC == MAS3507D /* volume/balance/treble/bass interdependency */
235#define VOLUME_MIN -780
236#define VOLUME_MAX 180
237
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000238static const unsigned int bass_table[] =
239{
240 0x9e400, /* -15dB */
241 0xa2800, /* -14dB */
242 0xa7400, /* -13dB */
243 0xac400, /* -12dB */
244 0xb1800, /* -11dB */
245 0xb7400, /* -10dB */
246 0xbd400, /* -9dB */
247 0xc3c00, /* -8dB */
248 0xca400, /* -7dB */
249 0xd1800, /* -6dB */
250 0xd8c00, /* -5dB */
251 0xe0400, /* -4dB */
252 0xe8000, /* -3dB */
253 0xefc00, /* -2dB */
254 0xf7c00, /* -1dB */
255 0,
256 0x800, /* 1dB */
257 0x10000, /* 2dB */
258 0x17c00, /* 3dB */
259 0x1f800, /* 4dB */
260 0x27000, /* 5dB */
261 0x2e400, /* 6dB */
262 0x35800, /* 7dB */
263 0x3c000, /* 8dB */
264 0x42800, /* 9dB */
265 0x48800, /* 10dB */
266 0x4e400, /* 11dB */
267 0x53800, /* 12dB */
268 0x58800, /* 13dB */
269 0x5d400, /* 14dB */
270 0x61800 /* 15dB */
271};
272
273static const unsigned int treble_table[] =
274{
275 0xb2c00, /* -15dB */
276 0xbb400, /* -14dB */
277 0xc1800, /* -13dB */
278 0xc6c00, /* -12dB */
279 0xcbc00, /* -11dB */
280 0xd0400, /* -10dB */
281 0xd5000, /* -9dB */
282 0xd9800, /* -8dB */
283 0xde000, /* -7dB */
284 0xe2800, /* -6dB */
285 0xe7e00, /* -5dB */
286 0xec000, /* -4dB */
287 0xf0c00, /* -3dB */
288 0xf5c00, /* -2dB */
289 0xfac00, /* -1dB */
290 0,
291 0x5400, /* 1dB */
292 0xac00, /* 2dB */
293 0x10400, /* 3dB */
294 0x16000, /* 4dB */
295 0x1c000, /* 5dB */
296 0x22400, /* 6dB */
297 0x28400, /* 7dB */
298 0x2ec00, /* 8dB */
299 0x35400, /* 9dB */
300 0x3c000, /* 10dB */
301 0x42c00, /* 11dB */
302 0x49c00, /* 12dB */
303 0x51800, /* 13dB */
304 0x58400, /* 14dB */
305 0x5f800 /* 15dB */
306};
307
308static const unsigned int prescale_table[] =
309{
310 0x80000, /* 0db */
311 0x8e000, /* 1dB */
312 0x9a400, /* 2dB */
313 0xa5800, /* 3dB */
314 0xaf400, /* 4dB */
315 0xb8000, /* 5dB */
316 0xbfc00, /* 6dB */
317 0xc6c00, /* 7dB */
318 0xcd000, /* 8dB */
319 0xd25c0, /* 9dB */
320 0xd7800, /* 10dB */
321 0xdc000, /* 11dB */
322 0xdfc00, /* 12dB */
323 0xe3400, /* 13dB */
324 0xe6800, /* 14dB */
325 0xe9400 /* 15dB */
326};
327
Jens Arnold12a0e222005-06-19 23:33:23 +0000328/* convert tenth of dB volume to dac3550 register value */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000329static int tenthdb2reg(int db) {
330 if (db < -540)
331 return (db + 780) / 30;
332 else
333 return (db + 660) / 15;
334}
Jens Arnold12a0e222005-06-19 23:33:23 +0000335#endif
336
337#ifdef HAVE_UDA1380 /* volume/balance/treble/bass interdependency */
338#define VOLUME_MIN -840
339#define VOLUME_MAX 0
340
341/* convert tenth of dB volume to master volume register value */
342static int tenthdb2master(int db) {
343 if (db < -720) /* 1.5 dB steps */
344 return (2940 - db) / 15;
345 else if (db < -660) /* 0.75 dB steps */
346 return (1110 - db) * 2 / 15;
347 else if (db < -520) /* 0.5 dB steps */
348 return (520 - db) / 5;
349 else /* 0.25 dB steps */
350 return -db * 2 / 5;
351}
352#endif
353
354#if (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380
355 /* volume/balance/treble/bass interdependency main part */
356#define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
357
358/* all values in tenth of dB MAS3507D UDA1380 */
359int current_volume = 0; /* -780..+180 -840.. 0 */
360int current_balance = 0; /* -960..+960 -840..+840 */
361int current_treble = 0; /* -150..+150 0.. +60 */
362int current_bass = 0; /* -150..+150 0..+240 */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000363
Jens Arnold4c7da882005-06-18 01:25:47 +0000364static void set_prescaled_volume(void)
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000365{
366 int prescale;
367 int l, r;
368
369 prescale = MAX(current_bass, current_treble);
370 if (prescale < 0)
371 prescale = 0; /* no need to prescale if we don't boost
372 bass or treble */
373
Jens Arnold12a0e222005-06-19 23:33:23 +0000374#if CONFIG_HWCODEC == MAS3507D
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000375 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
Jens Arnold12a0e222005-06-19 23:33:23 +0000376#else /* UDA1380 */
377 uda1380_set_mixer_vol(prescale*2/5, prescale*2/5);
378 /* The needed range of 0..-24 dB is fortunately linear */
379#endif
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000380
Jens Arnold12a0e222005-06-19 23:33:23 +0000381 /* gain up the analog volume to compensate the prescale gain reduction,
382 * but limit to the possible maximum */
383 if (current_volume + prescale > VOLUME_MAX)
384 prescale = VOLUME_MAX - current_volume;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000385 l = r = current_volume + prescale;
386
387 if (current_balance > 0)
388 {
389 l -= current_balance;
Jens Arnold12a0e222005-06-19 23:33:23 +0000390 if (l < VOLUME_MIN)
391 l = VOLUME_MIN;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000392 }
393 if (current_balance < 0)
394 {
395 r += current_balance;
Jens Arnold12a0e222005-06-19 23:33:23 +0000396 if (r < VOLUME_MIN)
397 r = VOLUME_MIN;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000398 }
399
Jens Arnold12a0e222005-06-19 23:33:23 +0000400#if CONFIG_HWCODEC == MAS3507D
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000401 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
Jens Arnold12a0e222005-06-19 23:33:23 +0000402#else /* UDA1380 */
403 uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r));
Jens Arnold4c7da882005-06-18 01:25:47 +0000404#endif
Jens Arnold12a0e222005-06-19 23:33:23 +0000405}
406#endif /* (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000407#endif /* !SIMULATOR */
408
409int channel_configuration = SOUND_CHAN_STEREO;
410int stereo_width = 100;
411
412#ifndef SIMULATOR
413static void set_channel_config(void)
414{
415 /* default values: stereo */
416 unsigned long val_ll = 0x80000;
417 unsigned long val_lr = 0;
418 unsigned long val_rl = 0;
419 unsigned long val_rr = 0x80000;
420
421 switch(channel_configuration)
422 {
423 /* case SOUND_CHAN_STEREO unnecessary */
424
425 case SOUND_CHAN_MONO:
426 val_ll = 0xc0000;
427 val_lr = 0xc0000;
428 val_rl = 0xc0000;
429 val_rr = 0xc0000;
430 break;
431
432 case SOUND_CHAN_CUSTOM:
433 {
434 /* fixed point variables (matching MAS internal format)
435 integer part: upper 13 bits (inlcuding sign)
436 fractional part: lower 19 bits */
437 long fp_width, fp_straight, fp_cross;
438
439 fp_width = (stereo_width << 19) / 100;
440 if (stereo_width <= 100)
441 {
442 fp_straight = - ((1<<19) + fp_width) / 2;
443 fp_cross = fp_straight + fp_width;
444 }
445 else
446 {
447 fp_straight = - (1<<19);
448 fp_cross = ((2 * fp_width / (((1<<19) + fp_width) >> 10))
449 << 9) - (1<<19);
450 }
451 val_ll = val_rr = fp_straight & 0xFFFFF;
452 val_lr = val_rl = fp_cross & 0xFFFFF;
453 }
454 break;
455
456 case SOUND_CHAN_MONO_LEFT:
457 val_ll = 0x80000;
458 val_lr = 0x80000;
459 val_rl = 0;
460 val_rr = 0;
461 break;
462
463 case SOUND_CHAN_MONO_RIGHT:
464 val_ll = 0;
465 val_lr = 0;
466 val_rl = 0x80000;
467 val_rr = 0x80000;
468 break;
469
470 case SOUND_CHAN_KARAOKE:
471 val_ll = 0x80001;
472 val_lr = 0x7ffff;
473 val_rl = 0x7ffff;
474 val_rr = 0x80001;
475 break;
476 }
477
478#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
479 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */
480 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */
481 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */
482 mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */
483#elif CONFIG_HWCODEC == MAS3507D
484 mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */
485 mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */
486 mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */
487 mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */
488#endif
489}
490#endif /* !SIMULATOR */
491
492#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
493unsigned long mdb_shape_shadow = 0;
494unsigned long loudness_shadow = 0;
495#endif
496
497void sound_set(int setting, int value)
498{
499#ifdef SIMULATOR
500 setting = value;
501#else
502#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
503 int tmp;
504#endif
505
506 if(!audio_is_initialized)
507 return;
508
509 switch(setting)
510 {
511 case SOUND_VOLUME:
512#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
513 tmp = 0x7f00 * value / 100;
514 mas_codec_writereg(0x10, tmp & 0xff00);
Jens Arnold12a0e222005-06-19 23:33:23 +0000515#elif (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380
516 current_volume = VOLUME_MIN + (value * VOLUME_RANGE / 100);
517 set_prescaled_volume(); /* tenth of dB */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000518#endif
519 break;
520
521 case SOUND_BALANCE:
522#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
523 tmp = ((value * 127 / 100) & 0xff) << 8;
524 mas_codec_writereg(0x11, tmp & 0xff00);
Jens Arnold12a0e222005-06-19 23:33:23 +0000525#elif CONFIG_HWCODEC == MAS3507D || defined HAVE_UDA1380
526 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000527 set_prescaled_volume();
528#endif
529 break;
530
531 case SOUND_BASS:
532#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
533 tmp = ((value * 8) & 0xff) << 8;
534 mas_codec_writereg(0x14, tmp & 0xff00);
535#elif CONFIG_HWCODEC == MAS3507D
536 mas_writereg(MAS_REG_KBASS, bass_table[value+15]);
537 current_bass = value * 10;
538 set_prescaled_volume();
Jens Arnold4c7da882005-06-18 01:25:47 +0000539#elif defined(HAVE_UDA1380)
540 uda1380_set_bass(value >> 1);
Jens Arnold12a0e222005-06-19 23:33:23 +0000541 current_bass = value * 10;
542 set_prescaled_volume();
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000543#endif
544 break;
545
546 case SOUND_TREBLE:
547#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
548 tmp = ((value * 8) & 0xff) << 8;
549 mas_codec_writereg(0x15, tmp & 0xff00);
550#elif CONFIG_HWCODEC == MAS3507D
551 mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]);
552 current_treble = value * 10;
553 set_prescaled_volume();
Jens Arnold4c7da882005-06-18 01:25:47 +0000554#elif defined(HAVE_UDA1380)
555 uda1380_set_treble(value >> 1);
Jens Arnold12a0e222005-06-19 23:33:23 +0000556 current_treble = value * 10;
557 set_prescaled_volume();
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000558#endif
559 break;
560
561#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
562 case SOUND_LOUDNESS:
563 loudness_shadow = (loudness_shadow & 0x04) |
564 (MAX(MIN(value * 4, 0x44), 0) << 8);
565 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
566 break;
567
568 case SOUND_AVC:
569 switch (value) {
570 case 1: /* 20ms */
571 tmp = (0x1 << 8) | (0x8 << 12);
572 break;
573 case 2: /* 2s */
574 tmp = (0x2 << 8) | (0x8 << 12);
575 break;
576 case 3: /* 4s */
577 tmp = (0x4 << 8) | (0x8 << 12);
578 break;
579 case 4: /* 8s */
580 tmp = (0x8 << 8) | (0x8 << 12);
581 break;
582 case -1: /* turn off and then turn on again to decay quickly */
583 tmp = mas_codec_readreg(MAS_REG_KAVC);
584 mas_codec_writereg(MAS_REG_KAVC, 0);
585 break;
586 default: /* off */
587 tmp = 0;
588 break;
589 }
590 mas_codec_writereg(MAS_REG_KAVC, tmp);
591 break;
592
593 case SOUND_MDB_STRENGTH:
594 mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
595 break;
596
597 case SOUND_MDB_HARMONICS:
598 tmp = value * 127 / 100;
599 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
600 break;
601
602 case SOUND_MDB_CENTER:
603 mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
604 break;
605
606 case SOUND_MDB_SHAPE:
607 mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
608 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
609 break;
610
611 case SOUND_MDB_ENABLE:
612 mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
613 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
614 break;
615
616 case SOUND_SUPERBASS:
617 loudness_shadow = (loudness_shadow & ~0x04) |
618 (value?4:0);
619 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
620 break;
621#endif
622 case SOUND_CHANNELS:
623 channel_configuration = value;
624 set_channel_config();
625 break;
626
627 case SOUND_STEREO_WIDTH:
628 stereo_width = value;
629 if (channel_configuration == SOUND_CHAN_CUSTOM)
630 set_channel_config();
631 break;
632 }
633#endif /* SIMULATOR */
634}
635
636int sound_val2phys(int setting, int value)
637{
638#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
639 int result = 0;
640
641 switch(setting)
642 {
643 case SOUND_LEFT_GAIN:
644 case SOUND_RIGHT_GAIN:
645 result = (value - 2) * 15;
646 break;
647
648 case SOUND_MIC_GAIN:
649 result = value * 15 + 210;
650 break;
651
652 default:
653 result = value;
654 break;
655 }
656 return result;
657#else
658 (void)setting;
659 return value;
660#endif
661}
662
663#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
664/* This function works by telling the decoder that we have another
665 crystal frequency than we actually have. It will adjust its internal
666 parameters and the result is that the audio is played at another pitch.
667
668 The pitch value is in tenths of percent.
669*/
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000670static int last_pitch = 1000;
671
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000672void sound_set_pitch(int pitch)
673{
674 unsigned long val;
675
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000676 if (pitch != last_pitch)
677 {
678 /* Calculate the new (bogus) frequency */
679 val = 18432 * 1000 / pitch;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000680
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000681 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000682
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000683 /* We must tell the MAS that the frequency has changed.
684 * This will unfortunately cause a short silence. */
685 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
686
687 last_pitch = pitch;
688 }
689}
690
691int sound_get_pitch(void)
692{
693 return last_pitch;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000694}
695#elif defined SIMULATOR
696void sound_set_pitch(int pitch)
697{
698 (void)pitch;
699}
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000700
701int sound_get_pitch(void)
702{
703 return 1000;
704}
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000705#endif
706