blob: 95c67a1a3c43df580cf846809cd0ef65aa9e40fb [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
Christian Gmeinercdbf33a2007-05-22 15:56:05 +000011 * Copyright (C) 2007 by Christian Gmeiner
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000012 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000013 * 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.
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000017 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include <stdbool.h>
Linus Nielsen Feltzingd6f297e2005-06-05 23:46:09 +000023#include <stdio.h>
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000024#include "config.h"
25#include "sound.h"
Dave Chapman5ffa8c52006-01-30 21:12:31 +000026#include "logf.h"
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000027#ifndef SIMULATOR
28#include "i2c.h"
29#include "mas.h"
Marcoen Hirschberg1b967f42006-12-06 13:34:15 +000030#if CONFIG_CPU == PNX0101
Tomasz Malesinski4e5f4ee2006-08-12 21:03:23 +000031#include "pnx0101.h"
Thom Johansen38c9d752005-06-15 19:56:44 +000032#endif
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000033#include "dac.h"
34#include "system.h"
Jens Arnoldd6c05452005-08-29 21:15:27 +000035#if CONFIG_CODEC == SWCODEC
Michael Sevakis6077e5b2007-10-06 22:27:27 +000036#include "pcm.h"
Linus Nielsen Feltzingd6f297e2005-06-05 23:46:09 +000037#endif
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000038#endif
39
Christian Gmeinera6100fb2008-04-28 22:15:52 +000040/* TODO
41 * find a nice way to handle 1.5db steps -> see wm8751 ifdef in sound_set_bass/treble
42*/
43
Christian Gmeiner365c3b92008-04-22 09:42:02 +000044#if !defined(VOLUME_MIN) && !defined(VOLUME_MAX)
Dave Chapman5e973232008-05-24 08:03:15 +000045#warning define for VOLUME_MIN and VOLUME_MAX is missing
46#define VOLUME_MIN -700
47#define VOLUME_MAX 0
Dan Evertona5371142007-10-13 23:18:30 +000048#endif
49
50/* volume/balance/treble/bass interdependency main part */
51#define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN)
52
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000053#ifndef SIMULATOR
54extern bool audio_is_initialized;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000055
Jens Arnoldd6c05452005-08-29 21:15:27 +000056#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000057extern unsigned long shadow_io_control_main;
58extern unsigned shadow_codec_reg0;
59#endif
Jens Arnold8051a0b2005-11-06 23:12:11 +000060#endif /* SIMULATOR */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000061
Christian Gmeinercdbf33a2007-05-22 15:56:05 +000062#ifdef SIMULATOR
63/* dummy for sim */
64const struct sound_settings_info audiohw_settings[] = {
Dan Everton003a4a12007-10-13 23:01:10 +000065 [SOUND_VOLUME] = {"dB", 0, 1, VOLUME_MIN / 10, VOLUME_MAX / 10, -25},
Christian Gmeinercdbf33a2007-05-22 15:56:05 +000066 [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0},
67 [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0},
Marcoen Hirschbergdf31f5f2007-12-10 11:14:28 +000068 [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
Christian Gmeinercdbf33a2007-05-22 15:56:05 +000069 [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
Thom Johansen8f721922007-10-09 21:29:20 +000070 [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
Christian Gmeiner48f3eed2008-05-16 19:53:01 +000071#if defined(HAVE_RECORDING)
Jonathan Gordon43c299e2007-05-27 04:00:56 +000072 [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0},
73 [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0},
74 [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16},
75#endif
Christian Gmeiner59357d42008-05-16 19:28:45 +000076#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
Dan Evertond7e1f772007-11-24 07:51:00 +000077 [SOUND_BASS_CUTOFF] = {"", 0, 1, 1, 4, 1},
Christian Gmeiner59357d42008-05-16 19:28:45 +000078#endif
79#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
Dan Evertond7e1f772007-11-24 07:51:00 +000080 [SOUND_TREBLE_CUTOFF] = {"", 0, 1, 1, 4, 1},
81#endif
Dan Evertonf666a7e2007-11-27 10:52:03 +000082#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
83 [SOUND_LOUDNESS] = {"dB", 0, 1, 0, 17, 0},
84 [SOUND_AVC] = {"", 0, 1, -1, 4, 0},
85 [SOUND_MDB_STRENGTH] = {"dB", 0, 1, 0, 127, 48},
86 [SOUND_MDB_HARMONICS] = {"%", 0, 1, 0, 100, 50},
87 [SOUND_MDB_CENTER] = {"Hz", 0, 10, 20, 300, 60},
88 [SOUND_MDB_SHAPE] = {"Hz", 0, 10, 50, 300, 90},
89 [SOUND_MDB_ENABLE] = {"", 0, 1, 0, 1, 0},
90 [SOUND_SUPERBASS] = {"", 0, 1, 0, 1, 0},
91#endif
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000092};
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000093#endif
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000094
95const char *sound_unit(int setting)
96{
Christian Gmeinercdbf33a2007-05-22 15:56:05 +000097 return audiohw_settings[setting].unit;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +000098}
99
100int sound_numdecimals(int setting)
101{
Christian Gmeinercdbf33a2007-05-22 15:56:05 +0000102 return audiohw_settings[setting].numdecimals;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000103}
104
105int sound_steps(int setting)
106{
Christian Gmeinercdbf33a2007-05-22 15:56:05 +0000107 return audiohw_settings[setting].steps;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000108}
109
110int sound_min(int setting)
111{
Christian Gmeinercdbf33a2007-05-22 15:56:05 +0000112 return audiohw_settings[setting].minval;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000113}
114
115int sound_max(int setting)
116{
Christian Gmeinercdbf33a2007-05-22 15:56:05 +0000117 return audiohw_settings[setting].maxval;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000118}
119
120int sound_default(int setting)
121{
Christian Gmeinercdbf33a2007-05-22 15:56:05 +0000122 return audiohw_settings[setting].defaultval;
Jens Arnold8051a0b2005-11-06 23:12:11 +0000123}
124
125sound_set_type* sound_get_fn(int setting)
126{
Christian Gmeinercdbf33a2007-05-22 15:56:05 +0000127 sound_set_type* result = NULL;
128
129 switch (setting) {
130 case SOUND_VOLUME:
131 result = sound_set_volume;
132 break;
133
134 case SOUND_BASS:
135 result = sound_set_bass;
136 break;
137
138 case SOUND_TREBLE:
139 result = sound_set_treble;
140 break;
141
142 case SOUND_BALANCE:
143 result = sound_set_balance;
144 break;
145
146 case SOUND_CHANNELS:
147 result = sound_set_channels;
148 break;
149
150 case SOUND_STEREO_WIDTH:
151 result = sound_set_stereo_width;
152 break;
153
Christian Gmeiner59357d42008-05-16 19:28:45 +0000154#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
Dan Evertond7e1f772007-11-24 07:51:00 +0000155 case SOUND_BASS_CUTOFF:
156 result = sound_set_bass_cutoff;
157 break;
Christian Gmeiner59357d42008-05-16 19:28:45 +0000158#endif
Dan Evertond7e1f772007-11-24 07:51:00 +0000159
Christian Gmeiner59357d42008-05-16 19:28:45 +0000160#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
Dan Evertond7e1f772007-11-24 07:51:00 +0000161 case SOUND_TREBLE_CUTOFF:
162 result = sound_set_treble_cutoff;
163 break;
164#endif
165
Christian Gmeinercdbf33a2007-05-22 15:56:05 +0000166#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
167 case SOUND_LOUDNESS:
168 result = sound_set_loudness;
169 break;
170
171 case SOUND_AVC:
172 result = sound_set_avc;
173 break;
174
175 case SOUND_MDB_STRENGTH:
176 result = sound_set_mdb_strength;
177 break;
178
179 case SOUND_MDB_HARMONICS:
180 result = sound_set_mdb_harmonics;
181 break;
182
183 case SOUND_MDB_CENTER:
184 result = sound_set_mdb_center;
185 break;
186
187 case SOUND_MDB_SHAPE:
188 result = sound_set_mdb_shape;
189 break;
190
191 case SOUND_MDB_ENABLE:
192 result = sound_set_mdb_enable;
193 break;
194
195 case SOUND_SUPERBASS:
196 result = sound_set_superbass;
197 break;
198#endif
199 }
200
201 return result;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000202}
203
Thom Johansen99b27422007-03-07 19:11:16 +0000204#if CONFIG_CODEC == SWCODEC
Thom Johansena7fabf02007-02-26 00:41:26 +0000205/* Copied from dsp.h, nasty nasty, but we don't want to include dsp.h */
206enum {
207 DSP_CALLBACK_SET_PRESCALE = 0,
208 DSP_CALLBACK_SET_BASS,
Thom Johansen99b27422007-03-07 19:11:16 +0000209 DSP_CALLBACK_SET_TREBLE,
210 DSP_CALLBACK_SET_CHANNEL_CONFIG,
211 DSP_CALLBACK_SET_STEREO_WIDTH
Thom Johansena7fabf02007-02-26 00:41:26 +0000212};
213
214static int (*dsp_callback)(int, intptr_t) = NULL;
215
216void sound_set_dsp_callback(int (*func)(int, intptr_t))
217{
218 dsp_callback = func;
219}
220#endif
221
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000222#ifndef SIMULATOR
Christian Gmeiner7197d9d2007-11-15 23:32:56 +0000223#if CONFIG_CODEC == MAS3507D
Jens Arnold2993ae62005-12-07 23:07:07 +0000224/* convert tenth of dB volume (-780..+180) to dac3550 register value */
Jens Arnold8636e692007-04-11 23:51:00 +0000225static int tenthdb2reg(int db)
Jens Arnold2993ae62005-12-07 23:07:07 +0000226{
227 if (db < -540) /* 3 dB steps */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000228 return (db + 780) / 30;
Jens Arnold2993ae62005-12-07 23:07:07 +0000229 else /* 1.5 dB steps */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000230 return (db + 660) / 15;
231}
Jens Arnold12a0e222005-06-19 23:33:23 +0000232#endif
233
Christian Gmeiner83915262008-04-28 08:37:18 +0000234
Christian Gmeiner785e7762008-05-13 06:19:16 +0000235#if !defined(AUDIOHW_HAVE_CLIPPING)
Christian Gmeiner83915262008-04-28 08:37:18 +0000236/*
237 * The prescaler compensates for any kind of boosts, to prevent clipping.
238 *
239 * It's basically just a measure to make sure that audio does not clip during
240 * tone controls processing, like if i want to boost bass 12 dB, i can decrease
241 * the audio amplitude by -12 dB before processing, then increase master gain
242 * by 12 dB after processing.
243 */
Jens Arnold12a0e222005-06-19 23:33:23 +0000244
245/* all values in tenth of dB MAS3507D UDA1380 */
246int current_volume = 0; /* -780..+180 -840.. 0 */
247int current_balance = 0; /* -960..+960 -840..+840 */
248int current_treble = 0; /* -150..+150 0.. +60 */
249int current_bass = 0; /* -150..+150 0..+240 */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000250
Jens Arnold4c7da882005-06-18 01:25:47 +0000251static void set_prescaled_volume(void)
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000252{
Thom Johansen2d7bb99c2007-03-07 15:00:29 +0000253 int prescale = 0;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000254 int l, r;
255
Thom Johansen2d7bb99c2007-03-07 15:00:29 +0000256/* The WM codecs listed don't have suitable prescaler functionality, so we let
257 * the prescaler stay at 0 for these unless SW tone controls are in use */
258#if defined(HAVE_SW_TONE_CONTROLS) || !(defined(HAVE_WM8975) \
Dan Evertond7e1f772007-11-24 07:51:00 +0000259 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
Jonathan Gordon6b9b5082008-04-27 14:07:57 +0000260 || defined(HAVE_WM8758) || defined(HAVE_WM8985)) || defined(HAVE_TSC2100)
Thom Johansen2d7bb99c2007-03-07 15:00:29 +0000261
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000262 prescale = MAX(current_bass, current_treble);
263 if (prescale < 0)
264 prescale = 0; /* no need to prescale if we don't boost
265 bass or treble */
266
Jens Arnold2993ae62005-12-07 23:07:07 +0000267 /* Gain up the analog volume to compensate the prescale gain reduction,
268 * but if this would push the volume over the top, reduce prescaling
269 * instead (might cause clipping). */
Jens Arnold12a0e222005-06-19 23:33:23 +0000270 if (current_volume + prescale > VOLUME_MAX)
271 prescale = VOLUME_MAX - current_volume;
Thom Johansen2d7bb99c2007-03-07 15:00:29 +0000272#endif
273
Christian Gmeiner05e84882008-05-14 21:35:19 +0000274#if defined(AUDIOHW_HAVE_PRESCALER)
275 audiohw_set_prescaler(prescale);
276#else
Thom Johansena7fabf02007-02-26 00:41:26 +0000277 dsp_callback(DSP_CALLBACK_SET_PRESCALE, prescale);
Jens Arnold2993ae62005-12-07 23:07:07 +0000278#endif
279
280 if (current_volume == VOLUME_MIN)
281 prescale = 0; /* Make sure the chip gets muted at VOLUME_MIN */
282
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000283 l = r = current_volume + prescale;
284
285 if (current_balance > 0)
286 {
287 l -= current_balance;
Jens Arnold12a0e222005-06-19 23:33:23 +0000288 if (l < VOLUME_MIN)
289 l = VOLUME_MIN;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000290 }
291 if (current_balance < 0)
292 {
293 r += current_balance;
Jens Arnold12a0e222005-06-19 23:33:23 +0000294 if (r < VOLUME_MIN)
295 r = VOLUME_MIN;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000296 }
297
Jens Arnold2993ae62005-12-07 23:07:07 +0000298#if CONFIG_CODEC == MAS3507D
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000299 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
Thom Johansena7fabf02007-02-26 00:41:26 +0000300#elif defined(HAVE_UDA1380) || defined(HAVE_WM8975) || defined(HAVE_WM8758) \
Daniel Ankersdfad4062007-03-11 17:38:08 +0000301 || defined(HAVE_WM8731) || defined(HAVE_WM8721) || defined(HAVE_WM8751) \
Jonathan Gordon6b9b5082008-04-27 14:07:57 +0000302 || defined(HAVE_AS3514) || defined(HAVE_TSC2100)
Marcoen Hirschberg77d039b2006-12-06 10:24:59 +0000303 audiohw_set_master_vol(tenthdb2master(l), tenthdb2master(r));
Mark Arigo8a7e6262008-02-06 05:15:06 +0000304#if defined(HAVE_WM8975) || defined(HAVE_WM8758) \
Jonathan Gordon6b9b5082008-04-27 14:07:57 +0000305 || (defined(HAVE_WM8751) && !defined(MROBE_100)) \
Rob Purchased6159ea2008-06-22 18:48:22 +0000306 || defined(HAVE_TSC2100) || defined(HAVE_WM8985)
Marcoen Hirschberg77d039b2006-12-06 10:24:59 +0000307 audiohw_set_lineout_vol(tenthdb2master(0), tenthdb2master(0));
Thom Johansen473fc2b2006-03-22 13:04:49 +0000308#endif
309
Rob Purchased6159ea2008-06-22 18:48:22 +0000310#elif defined(HAVE_TLV320) || defined(HAVE_WM8978) || defined(HAVE_WM8985)
Marcoen Hirschberg77d039b2006-12-06 10:24:59 +0000311 audiohw_set_headphone_vol(tenthdb2master(l), tenthdb2master(r));
Anton Oleynikov2654d912005-12-04 14:33:10 +0000312#endif
Anton Oleynikov2654d912005-12-04 14:33:10 +0000313}
Jens Arnoldd6c05452005-08-29 21:15:27 +0000314#endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000315#endif /* !SIMULATOR */
316
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000317
318#ifndef SIMULATOR
Thom Johansenb0960ae2006-03-21 23:20:17 +0000319
Jens Arnoldd6c05452005-08-29 21:15:27 +0000320#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000321unsigned long mdb_shape_shadow = 0;
322unsigned long loudness_shadow = 0;
323#endif
324
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000325void sound_set_volume(int value)
326{
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000327 if(!audio_is_initialized)
328 return;
Christian Gmeiner785e7762008-05-13 06:19:16 +0000329
330#if defined(AUDIOHW_HAVE_CLIPPING)
331 audiohw_set_volume(value);
Tomasz Malesinskic31d2f82006-02-03 23:14:42 +0000332#elif CONFIG_CPU == PNX0101
Tomasz Malesinski4e5f4ee2006-08-12 21:03:23 +0000333 int tmp = (60 - value * 4) & 0xff;
334 CODECVOL = tmp | (tmp << 8);
Christian Gmeiner785e7762008-05-13 06:19:16 +0000335#else
336 current_volume = value * 10; /* tenth of dB */
337 set_prescaled_volume();
Jens Arnold2993ae62005-12-07 23:07:07 +0000338#endif
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000339}
340
341void sound_set_balance(int value)
342{
343 if(!audio_is_initialized)
344 return;
Christian Gmeiner785e7762008-05-13 06:19:16 +0000345
346#ifdef AUDIOHW_HAVE_BALANCE
347 audiohw_set_balance(value);
348#else
Marcoen Hirschbergdf31f5f2007-12-10 11:14:28 +0000349 current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000350 set_prescaled_volume();
Jens Arnold2993ae62005-12-07 23:07:07 +0000351#endif
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000352}
353
354void sound_set_bass(int value)
355{
356 if(!audio_is_initialized)
357 return;
Christian Gmeiner83915262008-04-28 08:37:18 +0000358
Christian Gmeinerdfa28e62008-05-16 20:06:50 +0000359#if !defined(AUDIOHW_HAVE_CLIPPING)
360#if defined(HAVE_WM8751)
361 current_bass = value;
362#else
363 current_bass = value * 10;
364#endif
365#endif
366
Christian Gmeiner83915262008-04-28 08:37:18 +0000367#if defined(AUDIOHW_HAVE_BASS)
368 audiohw_set_bass(value);
369#else
Thom Johansena7fabf02007-02-26 00:41:26 +0000370 dsp_callback(DSP_CALLBACK_SET_BASS, current_bass);
Christian Gmeiner83915262008-04-28 08:37:18 +0000371#endif
372
Christian Gmeiner785e7762008-05-13 06:19:16 +0000373#if !defined(AUDIOHW_HAVE_CLIPPING)
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000374 set_prescaled_volume();
Christian Gmeiner83915262008-04-28 08:37:18 +0000375#endif
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000376}
377
378void sound_set_treble(int value)
379{
380 if(!audio_is_initialized)
381 return;
Christian Gmeiner83915262008-04-28 08:37:18 +0000382
Christian Gmeinerdfa28e62008-05-16 20:06:50 +0000383#if !defined(AUDIOHW_HAVE_CLIPPING)
384#if defined(HAVE_WM8751)
385 current_treble = value;
386#else
387 current_treble = value * 10;
388#endif
389#endif
390
Christian Gmeiner83915262008-04-28 08:37:18 +0000391#if defined(AUDIOHW_HAVE_TREBLE)
392 audiohw_set_treble(value);
393#else
Thom Johansena7fabf02007-02-26 00:41:26 +0000394 dsp_callback(DSP_CALLBACK_SET_TREBLE, current_treble);
Michael Sevakis040b6cc2008-04-15 14:44:32 +0000395#endif
Christian Gmeiner83915262008-04-28 08:37:18 +0000396
Christian Gmeiner785e7762008-05-13 06:19:16 +0000397#if !defined(AUDIOHW_HAVE_CLIPPING)
Christian Gmeiner83915262008-04-28 08:37:18 +0000398 set_prescaled_volume();
399#endif
Jens Arnold8051a0b2005-11-06 23:12:11 +0000400}
401
402void sound_set_channels(int value)
403{
Christian Gmeinerb1806b22008-04-22 13:43:01 +0000404 if(!audio_is_initialized)
405 return;
406
Thom Johansenb0960ae2006-03-21 23:20:17 +0000407#if CONFIG_CODEC == SWCODEC
Thom Johansen99b27422007-03-07 19:11:16 +0000408 dsp_callback(DSP_CALLBACK_SET_CHANNEL_CONFIG, value);
Thom Johansenb0960ae2006-03-21 23:20:17 +0000409#else
Christian Gmeinerb1806b22008-04-22 13:43:01 +0000410 audiohw_set_channel(value);
Thom Johansenb0960ae2006-03-21 23:20:17 +0000411#endif
Jens Arnold8051a0b2005-11-06 23:12:11 +0000412}
413
414void sound_set_stereo_width(int value)
415{
Christian Gmeinerb1806b22008-04-22 13:43:01 +0000416 if(!audio_is_initialized)
417 return;
418
Thom Johansenb0960ae2006-03-21 23:20:17 +0000419#if CONFIG_CODEC == SWCODEC
Thom Johansen99b27422007-03-07 19:11:16 +0000420 dsp_callback(DSP_CALLBACK_SET_STEREO_WIDTH, value);
Thom Johansenb0960ae2006-03-21 23:20:17 +0000421#else
Christian Gmeinerb1806b22008-04-22 13:43:01 +0000422 audiohw_set_stereo_width(value);
Thom Johansenb0960ae2006-03-21 23:20:17 +0000423#endif
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000424}
425
Christian Gmeiner59357d42008-05-16 19:28:45 +0000426#if defined(AUDIOHW_HAVE_BASS_CUTOFF)
Dan Evertond7e1f772007-11-24 07:51:00 +0000427void sound_set_bass_cutoff(int value)
428{
429 if(!audio_is_initialized)
430 return;
431
432 audiohw_set_bass_cutoff(value);
433}
Christian Gmeiner59357d42008-05-16 19:28:45 +0000434#endif
Dan Evertond7e1f772007-11-24 07:51:00 +0000435
Christian Gmeiner59357d42008-05-16 19:28:45 +0000436#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
Dan Evertond7e1f772007-11-24 07:51:00 +0000437void sound_set_treble_cutoff(int value)
438{
439 if(!audio_is_initialized)
440 return;
441
442 audiohw_set_treble_cutoff(value);
443}
444#endif
445
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000446#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
447void sound_set_loudness(int value)
448{
449 if(!audio_is_initialized)
450 return;
451 loudness_shadow = (loudness_shadow & 0x04) |
452 (MAX(MIN(value * 4, 0x44), 0) << 8);
453 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
454}
455
456void sound_set_avc(int value)
457{
458 if(!audio_is_initialized)
459 return;
460 int tmp;
461 switch (value) {
462 case 1: /* 20ms */
463 tmp = (0x1 << 8) | (0x8 << 12);
464 break;
465 case 2: /* 2s */
466 tmp = (0x2 << 8) | (0x8 << 12);
467 break;
468 case 3: /* 4s */
469 tmp = (0x4 << 8) | (0x8 << 12);
470 break;
471 case 4: /* 8s */
472 tmp = (0x8 << 8) | (0x8 << 12);
473 break;
474 case -1: /* turn off and then turn on again to decay quickly */
475 tmp = mas_codec_readreg(MAS_REG_KAVC);
476 mas_codec_writereg(MAS_REG_KAVC, 0);
477 break;
478 default: /* off */
479 tmp = 0;
480 break;
481 }
Jens Arnold8051a0b2005-11-06 23:12:11 +0000482 mas_codec_writereg(MAS_REG_KAVC, tmp);
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000483}
484
485void sound_set_mdb_strength(int value)
486{
487 if(!audio_is_initialized)
488 return;
Jens Arnold8051a0b2005-11-06 23:12:11 +0000489 mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8);
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000490}
491
492void sound_set_mdb_harmonics(int value)
493{
494 if(!audio_is_initialized)
495 return;
496 int tmp = value * 127 / 100;
497 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8);
498}
499
500void sound_set_mdb_center(int value)
501{
502 if(!audio_is_initialized)
503 return;
504 mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8);
505}
506
507void sound_set_mdb_shape(int value)
508{
509 if(!audio_is_initialized)
510 return;
511 mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8);
512 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
513}
514
515void sound_set_mdb_enable(int value)
516{
517 if(!audio_is_initialized)
518 return;
519 mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0);
520 mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow);
521}
522
523void sound_set_superbass(int value)
524{
525 if(!audio_is_initialized)
526 return;
527 loudness_shadow = (loudness_shadow & ~0x04) | (value?4:0);
528 mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow);
529}
530#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
531
Jens Arnold8051a0b2005-11-06 23:12:11 +0000532#else /* SIMULATOR */
Jonathan Gordon42e42222007-07-31 11:41:42 +0000533int sim_volume;
Jens Arnold8051a0b2005-11-06 23:12:11 +0000534void sound_set_volume(int value)
535{
Dan Everton003a4a12007-10-13 23:01:10 +0000536 /* 128 is SDL_MIX_MAXVOLUME */
Dan Evertona5371142007-10-13 23:18:30 +0000537 sim_volume = 128 * (value - VOLUME_MIN / 10) / (VOLUME_RANGE / 10);
Jens Arnold8051a0b2005-11-06 23:12:11 +0000538}
539
540void sound_set_balance(int value)
541{
542 (void)value;
543}
544
545void sound_set_bass(int value)
546{
547 (void)value;
548}
549
550void sound_set_treble(int value)
551{
552 (void)value;
553}
554
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000555void sound_set_channels(int value)
556{
Jens Arnold8051a0b2005-11-06 23:12:11 +0000557 (void)value;
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000558}
559
560void sound_set_stereo_width(int value)
561{
Jens Arnold8051a0b2005-11-06 23:12:11 +0000562 (void)value;
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000563}
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000564
Jens Arnoldd6c05452005-08-29 21:15:27 +0000565#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
Jens Arnold8051a0b2005-11-06 23:12:11 +0000566void sound_set_loudness(int value)
567{
568 (void)value;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000569}
570
Jens Arnold8051a0b2005-11-06 23:12:11 +0000571void sound_set_avc(int value)
572{
573 (void)value;
574}
575
576void sound_set_mdb_strength(int value)
577{
578 (void)value;
579}
580
581void sound_set_mdb_harmonics(int value)
582{
583 (void)value;
584}
585
586void sound_set_mdb_center(int value)
587{
588 (void)value;
589}
590
591void sound_set_mdb_shape(int value)
592{
593 (void)value;
594}
595
596void sound_set_mdb_enable(int value)
597{
598 (void)value;
599}
600
601void sound_set_superbass(int value)
602{
603 (void)value;
604}
605#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
Dan Evertond7e1f772007-11-24 07:51:00 +0000606
Rob Purchase159f8ee2008-04-09 22:20:04 +0000607#if defined(HAVE_WM8758) || defined(HAVE_WM8985)
Dan Evertond7e1f772007-11-24 07:51:00 +0000608void sound_set_bass_cutoff(int value)
609{
610 (void) value;
611}
612
613void sound_set_treble_cutoff(int value)
614{
615 (void) value;
616}
617#endif /* HAVE_WM8758 */
618
Jens Arnold8051a0b2005-11-06 23:12:11 +0000619#endif /* SIMULATOR */
620
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000621void sound_set(int setting, int value)
622{
Jens Arnold8051a0b2005-11-06 23:12:11 +0000623 sound_set_type* sound_set_val = sound_get_fn(setting);
624 if (sound_set_val)
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000625 sound_set_val(value);
626}
627
Jonathan Gordon6b9b5082008-04-27 14:07:57 +0000628#if (!defined(HAVE_AS3514) && !defined (HAVE_WM8731) && !defined(HAVE_TSC2100)) \
629 || defined(SIMULATOR)
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000630int sound_val2phys(int setting, int value)
631{
Jens Arnold8051a0b2005-11-06 23:12:11 +0000632#if CONFIG_CODEC == MAS3587F
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000633 int result = 0;
Jens Arnold8051a0b2005-11-06 23:12:11 +0000634
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000635 switch(setting)
636 {
637 case SOUND_LEFT_GAIN:
638 case SOUND_RIGHT_GAIN:
639 result = (value - 2) * 15;
640 break;
641
642 case SOUND_MIC_GAIN:
643 result = value * 15 + 210;
644 break;
645
646 default:
647 result = value;
648 break;
649 }
650 return result;
Andye6e54962005-11-12 04:00:56 +0000651#elif defined(HAVE_UDA1380)
652 int result = 0;
653
654 switch(setting)
655 {
656 case SOUND_LEFT_GAIN:
657 case SOUND_RIGHT_GAIN:
Andye6e54962005-11-12 04:00:56 +0000658 case SOUND_MIC_GAIN:
Jens Arnolda238ab92006-05-14 23:34:24 +0000659 result = value * 5; /* (1/2) * 10 */
Andye6e54962005-11-12 04:00:56 +0000660 break;
661
Jens Arnolda238ab92006-05-14 23:34:24 +0000662 default:
Andye6e54962005-11-12 04:00:56 +0000663 result = value;
664 break;
665 }
666 return result;
Michael Sevakisc9f69942007-10-02 08:15:47 +0000667#elif defined(HAVE_TLV320) || defined(HAVE_WM8731)
Linus Nielsen Feltzinged4d7a32006-07-21 08:42:28 +0000668 int result = 0;
669
670 switch(setting)
671 {
Christian Gmeiner2ea6da12008-05-16 20:51:56 +0000672#ifdef HAVE_RECORDING
Linus Nielsen Feltzinged4d7a32006-07-21 08:42:28 +0000673 case SOUND_LEFT_GAIN:
674 case SOUND_RIGHT_GAIN:
675 result = (value - 23) * 15; /* (x - 23)/1.5 *10 */
676 break;
677
678 case SOUND_MIC_GAIN:
679 result = value * 200; /* 0 or 20 dB */
680 break;
Christian Gmeiner2ea6da12008-05-16 20:51:56 +0000681#endif
Linus Nielsen Feltzinged4d7a32006-07-21 08:42:28 +0000682 default:
683 result = value;
684 break;
685 }
686 return result;
Michael Sevakis619d2222007-06-05 07:22:26 +0000687#elif defined(HAVE_AS3514)
688 /* This is here for the sim only and the audio driver has its own */
689 int result;
690
691 switch(setting)
692 {
693 case SOUND_LEFT_GAIN:
694 case SOUND_RIGHT_GAIN:
695 case SOUND_MIC_GAIN:
696 result = (value - 23) * 15;
697 break;
698
699 default:
700 result = value;
701 break;
702 }
703
704 return result;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000705#else
706 (void)setting;
707 return value;
708#endif
709}
Michael Sevakis619d2222007-06-05 07:22:26 +0000710#endif /* !defined(HAVE_AS3514) || defined(SIMULATOR) */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000711
Jens Arnoldd6c05452005-08-29 21:15:27 +0000712#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
Jens Arnold8051a0b2005-11-06 23:12:11 +0000713#ifndef SIMULATOR
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000714/* This function works by telling the decoder that we have another
715 crystal frequency than we actually have. It will adjust its internal
716 parameters and the result is that the audio is played at another pitch.
717
718 The pitch value is in tenths of percent.
719*/
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000720static int last_pitch = 1000;
721
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000722void sound_set_pitch(int pitch)
723{
724 unsigned long val;
725
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000726 if (pitch != last_pitch)
727 {
728 /* Calculate the new (bogus) frequency */
729 val = 18432 * 1000 / pitch;
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000730
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000731 mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1);
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000732
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000733 /* We must tell the MAS that the frequency has changed.
734 * This will unfortunately cause a short silence. */
735 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
Kevin Ferrare9b5264d2005-11-06 03:18:34 +0000736
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000737 last_pitch = pitch;
738 }
739}
740
741int sound_get_pitch(void)
742{
743 return last_pitch;
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000744}
Jens Arnold8051a0b2005-11-06 23:12:11 +0000745#else /* SIMULATOR */
Linus Nielsen Feltzing674eaca2005-04-01 13:41:03 +0000746void sound_set_pitch(int pitch)
747{
748 (void)pitch;
749}
Jens Arnoldb9ebe6a2005-05-22 12:45:35 +0000750
751int sound_get_pitch(void)
752{
753 return 1000;
754}
Jens Arnold8051a0b2005-11-06 23:12:11 +0000755#endif /* SIMULATOR */
756#endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */