1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
28 #if CONFIG_CPU == PNX0101
33 #if CONFIG_CODEC == SWCODEC
39 * find a nice way to handle 1.5db steps -> see wm8751 ifdef in sound_set_bass/treble
42 #if !defined(VOLUME_MIN) && !defined(VOLUME_MAX)
43 #error define for VOLUME_MIN and VOLUME_MAX is missing!
46 /* volume/balance/treble/bass interdependency main part */
47 #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
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
;
56 #endif /* SIMULATOR */
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 defined(HAVE_RECORDING)
68 [SOUND_LEFT_GAIN
] = {"dB", 1, 1,-128, 96, 0},
69 [SOUND_RIGHT_GAIN
] = {"dB", 1, 1,-128, 96, 0},
70 [SOUND_MIC_GAIN
] = {"dB", 1, 1,-128, 108, 16},
72 #if defined(AUDIOHW_HAVE_BASS_CUTOFF)
73 [SOUND_BASS_CUTOFF
] = {"", 0, 1, 1, 4, 1},
75 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
76 [SOUND_TREBLE_CUTOFF
] = {"", 0, 1, 1, 4, 1},
78 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
79 [SOUND_LOUDNESS
] = {"dB", 0, 1, 0, 17, 0},
80 [SOUND_AVC
] = {"", 0, 1, -1, 4, 0},
81 [SOUND_MDB_STRENGTH
] = {"dB", 0, 1, 0, 127, 48},
82 [SOUND_MDB_HARMONICS
] = {"%", 0, 1, 0, 100, 50},
83 [SOUND_MDB_CENTER
] = {"Hz", 0, 10, 20, 300, 60},
84 [SOUND_MDB_SHAPE
] = {"Hz", 0, 10, 50, 300, 90},
85 [SOUND_MDB_ENABLE
] = {"", 0, 1, 0, 1, 0},
86 [SOUND_SUPERBASS
] = {"", 0, 1, 0, 1, 0},
91 const char *sound_unit(int setting
)
93 return audiohw_settings
[setting
].unit
;
96 int sound_numdecimals(int setting
)
98 return audiohw_settings
[setting
].numdecimals
;
101 int sound_steps(int setting
)
103 return audiohw_settings
[setting
].steps
;
106 int sound_min(int setting
)
108 return audiohw_settings
[setting
].minval
;
111 int sound_max(int setting
)
113 return audiohw_settings
[setting
].maxval
;
116 int sound_default(int setting
)
118 return audiohw_settings
[setting
].defaultval
;
121 sound_set_type
* sound_get_fn(int setting
)
123 sound_set_type
* result
= NULL
;
127 result
= sound_set_volume
;
131 result
= sound_set_bass
;
135 result
= sound_set_treble
;
139 result
= sound_set_balance
;
143 result
= sound_set_channels
;
146 case SOUND_STEREO_WIDTH
:
147 result
= sound_set_stereo_width
;
150 #if defined(AUDIOHW_HAVE_BASS_CUTOFF)
151 case SOUND_BASS_CUTOFF
:
152 result
= sound_set_bass_cutoff
;
156 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
157 case SOUND_TREBLE_CUTOFF
:
158 result
= sound_set_treble_cutoff
;
162 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
164 result
= sound_set_loudness
;
168 result
= sound_set_avc
;
171 case SOUND_MDB_STRENGTH
:
172 result
= sound_set_mdb_strength
;
175 case SOUND_MDB_HARMONICS
:
176 result
= sound_set_mdb_harmonics
;
179 case SOUND_MDB_CENTER
:
180 result
= sound_set_mdb_center
;
183 case SOUND_MDB_SHAPE
:
184 result
= sound_set_mdb_shape
;
187 case SOUND_MDB_ENABLE
:
188 result
= sound_set_mdb_enable
;
191 case SOUND_SUPERBASS
:
192 result
= sound_set_superbass
;
200 #if CONFIG_CODEC == SWCODEC
201 /* Copied from dsp.h, nasty nasty, but we don't want to include dsp.h */
203 DSP_CALLBACK_SET_PRESCALE
= 0,
204 DSP_CALLBACK_SET_BASS
,
205 DSP_CALLBACK_SET_TREBLE
,
206 DSP_CALLBACK_SET_CHANNEL_CONFIG
,
207 DSP_CALLBACK_SET_STEREO_WIDTH
210 static int (*dsp_callback
)(int, intptr_t) = NULL
;
212 void sound_set_dsp_callback(int (*func
)(int, intptr_t))
219 #if CONFIG_CODEC == MAS3507D
220 /* convert tenth of dB volume (-780..+180) to dac3550 register value */
221 static int tenthdb2reg(int db
)
223 if (db
< -540) /* 3 dB steps */
224 return (db
+ 780) / 30;
225 else /* 1.5 dB steps */
226 return (db
+ 660) / 15;
231 #if !defined(AUDIOHW_HAVE_CLIPPING)
233 * The prescaler compensates for any kind of boosts, to prevent clipping.
235 * It's basically just a measure to make sure that audio does not clip during
236 * tone controls processing, like if i want to boost bass 12 dB, i can decrease
237 * the audio amplitude by -12 dB before processing, then increase master gain
238 * by 12 dB after processing.
241 /* all values in tenth of dB MAS3507D UDA1380 */
242 int current_volume
= 0; /* -780..+180 -840.. 0 */
243 int current_balance
= 0; /* -960..+960 -840..+840 */
244 int current_treble
= 0; /* -150..+150 0.. +60 */
245 int current_bass
= 0; /* -150..+150 0..+240 */
247 static void set_prescaled_volume(void)
252 /* The WM codecs listed don't have suitable prescaler functionality, so we let
253 * the prescaler stay at 0 for these unless SW tone controls are in use */
254 #if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
255 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
256 || defined(HAVE_WM8758) || defined(HAVE_WM8985)) || defined(HAVE_TSC2100)
258 prescale
= MAX(current_bass
, current_treble
);
260 prescale
= 0; /* no need to prescale if we don't boost
263 /* Gain up the analog volume to compensate the prescale gain reduction,
264 * but if this would push the volume over the top, reduce prescaling
265 * instead (might cause clipping). */
266 if (current_volume
+ prescale
> VOLUME_MAX
)
267 prescale
= VOLUME_MAX
- current_volume
;
270 #if defined(AUDIOHW_HAVE_PRESCALER)
271 audiohw_set_prescaler(prescale
);
273 dsp_callback(DSP_CALLBACK_SET_PRESCALE
, prescale
);
276 if (current_volume
== VOLUME_MIN
)
277 prescale
= 0; /* Make sure the chip gets muted at VOLUME_MIN */
279 l
= r
= current_volume
+ prescale
;
281 if (current_balance
> 0)
283 l
-= current_balance
;
287 if (current_balance
< 0)
289 r
+= current_balance
;
294 #if CONFIG_CODEC == MAS3507D
295 dac_volume(tenthdb2reg(l
), tenthdb2reg(r
), false);
296 #elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
297 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
298 || defined(HAVE_AS3514) || defined(HAVE_TSC2100)
299 audiohw_set_master_vol(tenthdb2master(l
), tenthdb2master(r
));
300 #if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
301 || (defined(HAVE_WM8751) && !defined(MROBE_100)) \
302 || defined(HAVE_TSC2100)
303 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
306 #elif defined(HAVE_TLV320) || defined(HAVE_WM8978)
307 audiohw_set_headphone_vol(tenthdb2master(l
), tenthdb2master(r
));
310 #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
311 #endif /* !SIMULATOR */
316 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
317 unsigned long mdb_shape_shadow
= 0;
318 unsigned long loudness_shadow
= 0;
321 void sound_set_volume(int value
)
323 if(!audio_is_initialized
)
326 #if defined(AUDIOHW_HAVE_CLIPPING)
327 audiohw_set_volume(value
);
328 #elif CONFIG_CPU == PNX0101
329 int tmp
= (60 - value
* 4) & 0xff;
330 CODECVOL
= tmp
| (tmp
<< 8);
332 current_volume
= value
* 10; /* tenth of dB */
333 set_prescaled_volume();
337 void sound_set_balance(int value
)
339 if(!audio_is_initialized
)
342 #ifdef AUDIOHW_HAVE_BALANCE
343 audiohw_set_balance(value
);
345 current_balance
= value
* VOLUME_RANGE
/ 100; /* tenth of dB */
346 set_prescaled_volume();
350 void sound_set_bass(int value
)
352 if(!audio_is_initialized
)
355 #if !defined(AUDIOHW_HAVE_CLIPPING)
356 #if defined(HAVE_WM8751)
357 current_bass
= value
;
359 current_bass
= value
* 10;
363 #if defined(AUDIOHW_HAVE_BASS)
364 audiohw_set_bass(value
);
366 dsp_callback(DSP_CALLBACK_SET_BASS
, current_bass
);
369 #if !defined(AUDIOHW_HAVE_CLIPPING)
370 set_prescaled_volume();
374 void sound_set_treble(int value
)
376 if(!audio_is_initialized
)
379 #if !defined(AUDIOHW_HAVE_CLIPPING)
380 #if defined(HAVE_WM8751)
381 current_treble
= value
;
383 current_treble
= value
* 10;
387 #if defined(AUDIOHW_HAVE_TREBLE)
388 audiohw_set_treble(value
);
390 dsp_callback(DSP_CALLBACK_SET_TREBLE
, current_treble
);
393 #if !defined(AUDIOHW_HAVE_CLIPPING)
394 set_prescaled_volume();
398 void sound_set_channels(int value
)
400 if(!audio_is_initialized
)
403 #if CONFIG_CODEC == SWCODEC
404 dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG
, value
);
406 audiohw_set_channel(value
);
410 void sound_set_stereo_width(int value
)
412 if(!audio_is_initialized
)
415 #if CONFIG_CODEC == SWCODEC
416 dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH
, value
);
418 audiohw_set_stereo_width(value
);
422 #if defined(AUDIOHW_HAVE_BASS_CUTOFF)
423 void sound_set_bass_cutoff(int value
)
425 if(!audio_is_initialized
)
428 audiohw_set_bass_cutoff(value
);
432 #if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
433 void sound_set_treble_cutoff(int value
)
435 if(!audio_is_initialized
)
438 audiohw_set_treble_cutoff(value
);
442 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
443 void sound_set_loudness(int value
)
445 if(!audio_is_initialized
)
447 loudness_shadow
= (loudness_shadow
& 0x04) |
448 (MAX(MIN(value
* 4, 0x44), 0) << 8);
449 mas_codec_writereg(MAS_REG_KLOUDNESS
, loudness_shadow
);
452 void sound_set_avc(int value
)
454 if(!audio_is_initialized
)
459 tmp
= (0x1 << 8) | (0x8 << 12);
462 tmp
= (0x2 << 8) | (0x8 << 12);
465 tmp
= (0x4 << 8) | (0x8 << 12);
468 tmp
= (0x8 << 8) | (0x8 << 12);
470 case -1: /* turn off and then turn on again to decay quickly */
471 tmp
= mas_codec_readreg(MAS_REG_KAVC
);
472 mas_codec_writereg(MAS_REG_KAVC
, 0);
478 mas_codec_writereg(MAS_REG_KAVC
, tmp
);
481 void sound_set_mdb_strength(int value
)
483 if(!audio_is_initialized
)
485 mas_codec_writereg(MAS_REG_KMDB_STR
, (value
& 0x7f) << 8);
488 void sound_set_mdb_harmonics(int value
)
490 if(!audio_is_initialized
)
492 int tmp
= value
* 127 / 100;
493 mas_codec_writereg(MAS_REG_KMDB_HAR
, (tmp
& 0x7f) << 8);
496 void sound_set_mdb_center(int value
)
498 if(!audio_is_initialized
)
500 mas_codec_writereg(MAS_REG_KMDB_FC
, (value
/10) << 8);
503 void sound_set_mdb_shape(int value
)
505 if(!audio_is_initialized
)
507 mdb_shape_shadow
= (mdb_shape_shadow
& 0x02) | ((value
/10) << 8);
508 mas_codec_writereg(MAS_REG_KMDB_SWITCH
, mdb_shape_shadow
);
511 void sound_set_mdb_enable(int value
)
513 if(!audio_is_initialized
)
515 mdb_shape_shadow
= (mdb_shape_shadow
& ~0x02) | (value
?2:0);
516 mas_codec_writereg(MAS_REG_KMDB_SWITCH
, mdb_shape_shadow
);
519 void sound_set_superbass(int value
)
521 if(!audio_is_initialized
)
523 loudness_shadow
= (loudness_shadow
& ~0x04) | (value
?4:0);
524 mas_codec_writereg(MAS_REG_KLOUDNESS
, loudness_shadow
);
526 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
528 #else /* SIMULATOR */
530 void sound_set_volume(int value
)
532 /* 128 is SDL_MIX_MAXVOLUME */
533 sim_volume
= 128 * (value
- VOLUME_MIN
/ 10) / (VOLUME_RANGE
/ 10);
536 void sound_set_balance(int value
)
541 void sound_set_bass(int value
)
546 void sound_set_treble(int value
)
551 void sound_set_channels(int value
)
556 void sound_set_stereo_width(int value
)
561 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
562 void sound_set_loudness(int value
)
567 void sound_set_avc(int value
)
572 void sound_set_mdb_strength(int value
)
577 void sound_set_mdb_harmonics(int value
)
582 void sound_set_mdb_center(int value
)
587 void sound_set_mdb_shape(int value
)
592 void sound_set_mdb_enable(int value
)
597 void sound_set_superbass(int value
)
601 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
603 #if defined(HAVE_WM8758) || defined(HAVE_WM8985)
604 void sound_set_bass_cutoff(int value
)
609 void sound_set_treble_cutoff(int value
)
613 #endif /* HAVE_WM8758 */
615 #endif /* SIMULATOR */
617 void sound_set(int setting
, int value
)
619 sound_set_type
* sound_set_val
= sound_get_fn(setting
);
621 sound_set_val(value
);
624 #if (!defined(HAVE_AS3514) && !defined (HAVE_WM8731) && !defined(HAVE_TSC2100)) \
625 || defined(SIMULATOR)
626 int sound_val2phys(int setting
, int value
)
628 #if CONFIG_CODEC == MAS3587F
633 case SOUND_LEFT_GAIN
:
634 case SOUND_RIGHT_GAIN
:
635 result
= (value
- 2) * 15;
639 result
= value
* 15 + 210;
647 #elif defined(HAVE_UDA1380)
652 case SOUND_LEFT_GAIN
:
653 case SOUND_RIGHT_GAIN
:
655 result
= value
* 5; /* (1/2) * 10 */
663 #elif defined(HAVE_TLV320) || defined(HAVE_WM8731)
668 #ifdef HAVE_RECORDING
669 case SOUND_LEFT_GAIN
:
670 case SOUND_RIGHT_GAIN
:
671 result
= (value
- 23) * 15; /* (x - 23)/1.5 *10 */
675 result
= value
* 200; /* 0 or 20 dB */
683 #elif defined(HAVE_AS3514)
684 /* This is here for the sim only and the audio driver has its own */
689 case SOUND_LEFT_GAIN
:
690 case SOUND_RIGHT_GAIN
:
692 result
= (value
- 23) * 15;
706 #endif /* !defined(HAVE_AS3514) || defined(SIMULATOR) */
708 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
710 /* This function works by telling the decoder that we have another
711 crystal frequency than we actually have. It will adjust its internal
712 parameters and the result is that the audio is played at another pitch.
714 The pitch value is in tenths of percent.
716 static int last_pitch
= 1000;
718 void sound_set_pitch(int pitch
)
722 if (pitch
!= last_pitch
)
724 /* Calculate the new (bogus) frequency */
725 val
= 18432 * 1000 / pitch
;
727 mas_writemem(MAS_BANK_D0
, MAS_D0_OFREQ_CONTROL
, &val
, 1);
729 /* We must tell the MAS that the frequency has changed.
730 * This will unfortunately cause a short silence. */
731 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
737 int sound_get_pitch(void)
741 #else /* SIMULATOR */
742 void sound_set_pitch(int pitch
)
747 int sound_get_pitch(void)
751 #endif /* SIMULATOR */
752 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */