Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 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 Feltzing | d6f297e | 2005-06-05 23:46:09 +0000 | [diff] [blame] | 20 | #include <stdio.h> |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 21 | #include "config.h" |
| 22 | #include "sound.h" |
| 23 | #ifndef SIMULATOR |
| 24 | #include "i2c.h" |
| 25 | #include "mas.h" |
Thom Johansen | 38c9d75 | 2005-06-15 19:56:44 +0000 | [diff] [blame] | 26 | #ifdef HAVE_UDA1380 |
| 27 | #include "uda1380.h" |
Christian Gmeiner | 14e8067 | 2005-08-06 10:12:19 +0000 | [diff] [blame] | 28 | #elif HAVE_TLV320 |
| 29 | #include "tlv320.h" |
Thom Johansen | 38c9d75 | 2005-06-15 19:56:44 +0000 | [diff] [blame] | 30 | #endif |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 31 | #include "dac.h" |
| 32 | #include "system.h" |
| 33 | #include "hwcompat.h" |
Linus Nielsen Feltzing | d6f297e | 2005-06-05 23:46:09 +0000 | [diff] [blame] | 34 | #if CONFIG_HWCODEC == MASNONE |
| 35 | #include "pcm_playback.h" |
| 36 | #endif |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 37 | #endif |
| 38 | |
| 39 | #ifndef SIMULATOR |
| 40 | extern bool audio_is_initialized; |
| 41 | #endif |
| 42 | |
| 43 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
| 44 | extern unsigned long shadow_io_control_main; |
| 45 | extern unsigned shadow_codec_reg0; |
| 46 | #endif |
| 47 | |
| 48 | static 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 | |
| 69 | static 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 | |
| 90 | static const int steps[] = |
| 91 | { |
| 92 | 1, /* Volume */ |
Thom Johansen | 38c9d75 | 2005-06-15 19:56:44 +0000 | [diff] [blame] | 93 | #ifdef HAVE_UDA1380 |
| 94 | 2, /* Bass */ |
| 95 | 2, /* Treble */ |
Thom Johansen | eadceed | 2005-06-15 20:09:09 +0000 | [diff] [blame] | 96 | #else |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 97 | 1, /* Bass */ |
| 98 | 1, /* Treble */ |
Thom Johansen | eadceed | 2005-06-15 20:09:09 +0000 | [diff] [blame] | 99 | #endif |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 100 | 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 | |
| 116 | static const int minval[] = |
| 117 | { |
| 118 | 0, /* Volume */ |
| 119 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
| 120 | -12, /* Bass */ |
| 121 | -12, /* Treble */ |
Thom Johansen | 38c9d75 | 2005-06-15 19:56:44 +0000 | [diff] [blame] | 122 | #elif defined(HAVE_UDA1380) |
| 123 | 0, /* Bass */ |
| 124 | 0, /* Treble */ |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 125 | #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 | |
| 145 | static const int maxval[] = |
| 146 | { |
| 147 | 100, /* Volume */ |
| 148 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
| 149 | 12, /* Bass */ |
| 150 | 12, /* Treble */ |
Thom Johansen | 38c9d75 | 2005-06-15 19:56:44 +0000 | [diff] [blame] | 151 | #elif defined(HAVE_UDA1380) |
| 152 | 24, /* Bass */ |
| 153 | 6, /* Treble */ |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 154 | #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 | |
| 174 | static const int defaultval[] = |
| 175 | { |
| 176 | 70, /* Volume */ |
| 177 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
| 178 | 6, /* Bass */ |
| 179 | 6, /* Treble */ |
Thom Johansen | eadceed | 2005-06-15 20:09:09 +0000 | [diff] [blame] | 180 | #elif defined(HAVE_UDA1380) |
| 181 | 0, /* Bass */ |
| 182 | 0, /* Treble */ |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 183 | #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 | |
| 203 | const char *sound_unit(int setting) |
| 204 | { |
| 205 | return units[setting]; |
| 206 | } |
| 207 | |
| 208 | int sound_numdecimals(int setting) |
| 209 | { |
| 210 | return numdecimals[setting]; |
| 211 | } |
| 212 | |
| 213 | int sound_steps(int setting) |
| 214 | { |
| 215 | return steps[setting]; |
| 216 | } |
| 217 | |
| 218 | int sound_min(int setting) |
| 219 | { |
| 220 | return minval[setting]; |
| 221 | } |
| 222 | |
| 223 | int sound_max(int setting) |
| 224 | { |
| 225 | return maxval[setting]; |
| 226 | } |
| 227 | |
| 228 | int sound_default(int setting) |
| 229 | { |
| 230 | return defaultval[setting]; |
| 231 | } |
| 232 | |
| 233 | #ifndef SIMULATOR |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 234 | #if CONFIG_HWCODEC == MAS3507D /* volume/balance/treble/bass interdependency */ |
| 235 | #define VOLUME_MIN -780 |
| 236 | #define VOLUME_MAX 180 |
| 237 | |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 238 | static 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 | |
| 273 | static 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 | |
| 308 | static 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 Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 328 | /* convert tenth of dB volume to dac3550 register value */ |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 329 | static int tenthdb2reg(int db) { |
| 330 | if (db < -540) |
| 331 | return (db + 780) / 30; |
| 332 | else |
| 333 | return (db + 660) / 15; |
| 334 | } |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 335 | #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 */ |
| 342 | static 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 */ |
| 359 | int current_volume = 0; /* -780..+180 -840.. 0 */ |
| 360 | int current_balance = 0; /* -960..+960 -840..+840 */ |
| 361 | int current_treble = 0; /* -150..+150 0.. +60 */ |
| 362 | int current_bass = 0; /* -150..+150 0..+240 */ |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 363 | |
Jens Arnold | 4c7da88 | 2005-06-18 01:25:47 +0000 | [diff] [blame] | 364 | static void set_prescaled_volume(void) |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 365 | { |
| 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 Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 374 | #if CONFIG_HWCODEC == MAS3507D |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 375 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 376 | #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 Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 380 | |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 381 | /* 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 Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 385 | l = r = current_volume + prescale; |
| 386 | |
| 387 | if (current_balance > 0) |
| 388 | { |
| 389 | l -= current_balance; |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 390 | if (l < VOLUME_MIN) |
| 391 | l = VOLUME_MIN; |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 392 | } |
| 393 | if (current_balance < 0) |
| 394 | { |
| 395 | r += current_balance; |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 396 | if (r < VOLUME_MIN) |
| 397 | r = VOLUME_MIN; |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 398 | } |
| 399 | |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 400 | #if CONFIG_HWCODEC == MAS3507D |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 401 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 402 | #else /* UDA1380 */ |
| 403 | uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); |
Jens Arnold | 4c7da88 | 2005-06-18 01:25:47 +0000 | [diff] [blame] | 404 | #endif |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 405 | } |
| 406 | #endif /* (CONFIG_HWCODEC == MAS3507D) || defined HAVE_UDA1380 */ |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 407 | #endif /* !SIMULATOR */ |
| 408 | |
| 409 | int channel_configuration = SOUND_CHAN_STEREO; |
| 410 | int stereo_width = 100; |
| 411 | |
| 412 | #ifndef SIMULATOR |
| 413 | static 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) |
| 493 | unsigned long mdb_shape_shadow = 0; |
| 494 | unsigned long loudness_shadow = 0; |
| 495 | #endif |
| 496 | |
| 497 | void 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 Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 515 | #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 Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 518 | #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 Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 525 | #elif CONFIG_HWCODEC == MAS3507D || defined HAVE_UDA1380 |
| 526 | current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 527 | 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 Arnold | 4c7da88 | 2005-06-18 01:25:47 +0000 | [diff] [blame] | 539 | #elif defined(HAVE_UDA1380) |
| 540 | uda1380_set_bass(value >> 1); |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 541 | current_bass = value * 10; |
| 542 | set_prescaled_volume(); |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 543 | #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 Arnold | 4c7da88 | 2005-06-18 01:25:47 +0000 | [diff] [blame] | 554 | #elif defined(HAVE_UDA1380) |
| 555 | uda1380_set_treble(value >> 1); |
Jens Arnold | 12a0e22 | 2005-06-19 23:33:23 +0000 | [diff] [blame] | 556 | current_treble = value * 10; |
| 557 | set_prescaled_volume(); |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 558 | #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 | |
| 636 | int 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 Arnold | b9ebe6a | 2005-05-22 12:45:35 +0000 | [diff] [blame] | 670 | static int last_pitch = 1000; |
| 671 | |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 672 | void sound_set_pitch(int pitch) |
| 673 | { |
| 674 | unsigned long val; |
| 675 | |
Jens Arnold | b9ebe6a | 2005-05-22 12:45:35 +0000 | [diff] [blame] | 676 | if (pitch != last_pitch) |
| 677 | { |
| 678 | /* Calculate the new (bogus) frequency */ |
| 679 | val = 18432 * 1000 / pitch; |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 680 | |
Jens Arnold | b9ebe6a | 2005-05-22 12:45:35 +0000 | [diff] [blame] | 681 | mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1); |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 682 | |
Jens Arnold | b9ebe6a | 2005-05-22 12:45:35 +0000 | [diff] [blame] | 683 | /* 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 | |
| 691 | int sound_get_pitch(void) |
| 692 | { |
| 693 | return last_pitch; |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 694 | } |
| 695 | #elif defined SIMULATOR |
| 696 | void sound_set_pitch(int pitch) |
| 697 | { |
| 698 | (void)pitch; |
| 699 | } |
Jens Arnold | b9ebe6a | 2005-05-22 12:45:35 +0000 | [diff] [blame] | 700 | |
| 701 | int sound_get_pitch(void) |
| 702 | { |
| 703 | return 1000; |
| 704 | } |
Linus Nielsen Feltzing | 674eaca | 2005-04-01 13:41:03 +0000 | [diff] [blame] | 705 | #endif |
| 706 | |