1 /* 2 * 1. Redistributions of source code must retain the 3 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Amancio Hasty and 17 * Roger Hardiman 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $FreeBSD: src/sys/dev/bktr/bktr_audio.c,v 1.13 2003/12/08 07:59:18 obrien Exp $ 34 * $DragonFly: src/sys/dev/video/bktr/bktr_audio.c,v 1.6 2004/05/15 17:54:12 joerg Exp $ 35 */ 36 37 /* 38 * This is part of the Driver for Video Capture Cards (Frame grabbers) 39 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 40 * chipset. 41 * Copyright Roger Hardiman and Amancio Hasty. 42 * 43 * bktr_audio : This deals with controlling the audio on TV cards, 44 * controlling the Audio Multiplexer (audio source selector). 45 * controlling any MSP34xx stereo audio decoders. 46 * controlling any DPL35xx dolby surroud sound audio decoders. 47 * initialising TDA98xx audio devices. 48 * 49 */ 50 51 #include "opt_bktr.h" /* Include any kernel config options */ 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/kernel.h> 56 #include <sys/vnode.h> 57 58 #include <bus/pci/pcivar.h> 59 #include <machine/bus_memio.h> /* for bus space */ 60 #include <machine/bus.h> 61 #include <sys/bus.h> 62 #include <dev/video/meteor/ioctl_meteor.h> 63 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */ 64 #include <dev/video/bktr/bktr_reg.h> 65 #include <dev/video/bktr/bktr_core.h> 66 #include <dev/video/bktr/bktr_tuner.h> 67 #include <dev/video/bktr/bktr_card.h> 68 #include <dev/video/bktr/bktr_audio.h> 69 70 /* 71 * Prototypes for the GV_BCTV2 specific functions. 72 */ 73 void set_bctv2_audio( bktr_ptr_t bktr ); 74 void bctv2_gpio_write( bktr_ptr_t bktr, int port, int val ); 75 /*int bctv2_gpio_read( bktr_ptr_t bktr, int port );*/ /* Not used */ 76 77 /* 78 * init_audio_devices 79 * Reset any MSP34xx or TDA98xx audio devices. 80 */ 81 void init_audio_devices( bktr_ptr_t bktr ) { 82 83 /* enable stereo if appropriate on TDA audio chip */ 84 if ( bktr->card.dbx ) 85 init_BTSC( bktr ); 86 87 /* reset the MSP34xx stereo audio chip */ 88 if ( bktr->card.msp3400c ) 89 msp_dpl_reset( bktr, bktr->msp_addr ); 90 91 /* reset the DPL35xx dolby audio chip */ 92 if ( bktr->card.dpl3518a ) 93 msp_dpl_reset( bktr, bktr->dpl_addr ); 94 95 } 96 97 98 /* 99 * 100 */ 101 #define AUDIOMUX_DISCOVER_NOT 102 int 103 set_audio( bktr_ptr_t bktr, int cmd ) 104 { 105 u_long temp; 106 volatile u_char idx; 107 108 #if defined( AUDIOMUX_DISCOVER ) 109 if ( cmd >= 200 ) 110 cmd -= 200; 111 else 112 #endif /* AUDIOMUX_DISCOVER */ 113 114 /* check for existance of audio MUXes */ 115 if ( !bktr->card.audiomuxs[ 4 ] ) 116 return( -1 ); 117 118 switch (cmd) { 119 case AUDIO_TUNER: 120 #ifdef BKTR_REVERSEMUTE 121 bktr->audio_mux_select = 3; 122 #else 123 bktr->audio_mux_select = 0; 124 #endif 125 126 if (bktr->reverse_mute ) 127 bktr->audio_mux_select = 0; 128 else 129 bktr->audio_mux_select = 3; 130 131 break; 132 case AUDIO_EXTERN: 133 bktr->audio_mux_select = 1; 134 break; 135 case AUDIO_INTERN: 136 bktr->audio_mux_select = 2; 137 break; 138 case AUDIO_MUTE: 139 bktr->audio_mute_state = TRUE; /* set mute */ 140 break; 141 case AUDIO_UNMUTE: 142 bktr->audio_mute_state = FALSE; /* clear mute */ 143 break; 144 default: 145 printf("%s: audio cmd error %02x\n", bktr_name(bktr), 146 cmd); 147 return( -1 ); 148 } 149 150 151 /* Most cards have a simple audio multiplexer to select the 152 * audio source. The I/O_GV card has a more advanced multiplexer 153 * and requires special handling. 154 */ 155 if ( bktr->bt848_card == CARD_IO_BCTV2 ) { 156 set_bctv2_audio( bktr ); 157 return( 0 ); 158 } 159 160 /* Proceed with the simpler audio multiplexer code for the majority 161 * of Bt848 cards. 162 */ 163 164 /* 165 * Leave the upper bits of the GPIO port alone in case they control 166 * something like the dbx or teletext chips. This doesn't guarantee 167 * success, but follows the rule of least astonishment. 168 */ 169 170 if ( bktr->audio_mute_state == TRUE ) { 171 #ifdef BKTR_REVERSEMUTE 172 idx = 0; 173 #else 174 idx = 3; 175 #endif 176 177 if (bktr->reverse_mute ) 178 idx = 3; 179 else 180 idx = 0; 181 182 } 183 else 184 idx = bktr->audio_mux_select; 185 186 187 temp = INL(bktr, BKTR_GPIO_DATA) & ~bktr->card.gpio_mux_bits; 188 #if defined( AUDIOMUX_DISCOVER ) 189 OUTL(bktr, BKTR_GPIO_DATA, temp | (cmd & 0xff)); 190 printf("%s: cmd: %d audio mux %x temp %x \n", bktr_name(bktr), 191 cmd, bktr->card.audiomuxs[ idx ], temp ); 192 #else 193 OUTL(bktr, BKTR_GPIO_DATA, temp | bktr->card.audiomuxs[ idx ]); 194 #endif /* AUDIOMUX_DISCOVER */ 195 196 197 198 /* Some new Hauppauge cards do not have an audio mux */ 199 /* Instead we use the MSP34xx chip to select TV audio, Line-In */ 200 /* FM Radio and Mute */ 201 /* Examples of this are the Hauppauge 44xxx MSP34xx models */ 202 /* It is ok to drive both the mux and the MSP34xx chip. */ 203 /* If there is no mux, the MSP does the switching of the audio source */ 204 /* If there is a mux, it does the switching of the audio source */ 205 206 if ((bktr->card.msp3400c) && (bktr->audio_mux_present == 0)) { 207 208 if (bktr->audio_mute_state == TRUE ) { 209 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x0000); /* volume to MUTE */ 210 } else { 211 if(bktr->audio_mux_select == 0) { /* TV Tuner */ 212 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */ 213 if (bktr->msp_source_selected != 0) msp_autodetect(bktr); /* setup TV audio mode */ 214 bktr->msp_source_selected = 0; 215 } 216 if(bktr->audio_mux_select == 1) { /* Line In */ 217 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */ 218 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */ 219 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */ 220 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0000); /* DSP In = SC1_IN_L/R */ 221 bktr->msp_source_selected = 1; 222 } 223 224 if(bktr->audio_mux_select == 2) { /* FM Radio */ 225 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */ 226 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */ 227 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */ 228 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0200); /* DSP In = SC2_IN_L/R */ 229 bktr->msp_source_selected = 2; 230 } 231 } 232 } 233 234 235 return( 0 ); 236 } 237 238 239 /* 240 * 241 */ 242 void 243 temp_mute( bktr_ptr_t bktr, int flag ) 244 { 245 static int muteState = FALSE; 246 247 if ( flag == TRUE ) { 248 muteState = bktr->audio_mute_state; 249 set_audio( bktr, AUDIO_MUTE ); /* prevent 'click' */ 250 } 251 else { 252 tsleep( BKTR_SLEEP, 0, "tuning", hz/8 ); 253 if ( muteState == FALSE ) 254 set_audio( bktr, AUDIO_UNMUTE ); 255 } 256 } 257 258 /* address of BTSC/SAP decoder chip */ 259 #define TDA9850_WADDR 0xb6 260 #define TDA9850_RADDR 0xb7 261 262 263 /* registers in the TDA9850 BTSC/dbx chip */ 264 #define CON1ADDR 0x04 265 #define CON2ADDR 0x05 266 #define CON3ADDR 0x06 267 #define CON4ADDR 0x07 268 #define ALI1ADDR 0x08 269 #define ALI2ADDR 0x09 270 #define ALI3ADDR 0x0a 271 272 /* 273 * initialise the dbx chip 274 * taken from the Linux bttv driver TDA9850 initialisation code 275 */ 276 void 277 init_BTSC( bktr_ptr_t bktr ) 278 { 279 i2cWrite(bktr, TDA9850_WADDR, CON1ADDR, 0x08); /* noise threshold st */ 280 i2cWrite(bktr, TDA9850_WADDR, CON2ADDR, 0x08); /* noise threshold sap */ 281 i2cWrite(bktr, TDA9850_WADDR, CON3ADDR, 0x40); /* stereo mode */ 282 i2cWrite(bktr, TDA9850_WADDR, CON4ADDR, 0x07); /* 0 dB input gain? */ 283 i2cWrite(bktr, TDA9850_WADDR, ALI1ADDR, 0x10); /* wideband alignment? */ 284 i2cWrite(bktr, TDA9850_WADDR, ALI2ADDR, 0x10); /* spectral alignment? */ 285 i2cWrite(bktr, TDA9850_WADDR, ALI3ADDR, 0x03); 286 } 287 288 /* 289 * setup the dbx chip 290 * XXX FIXME: alot of work to be done here, this merely unmutes it. 291 */ 292 int 293 set_BTSC( bktr_ptr_t bktr, int control ) 294 { 295 return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) ); 296 } 297 298 /* 299 * CARD_GV_BCTV2 specific functions. 300 */ 301 302 #define BCTV2_AUDIO_MAIN 0x10 /* main audio program */ 303 #define BCTV2_AUDIO_SUB 0x20 /* sub audio program */ 304 #define BCTV2_AUDIO_BOTH 0x30 /* main(L) + sub(R) program */ 305 306 #define BCTV2_GPIO_REG0 1 307 #define BCTV2_GPIO_REG1 3 308 309 #define BCTV2_GR0_AUDIO_MODE 3 310 #define BCTV2_GR0_AUDIO_MAIN 0 /* main program */ 311 #define BCTV2_GR0_AUDIO_SUB 3 /* sub program */ 312 #define BCTV2_GR0_AUDIO_BOTH 1 /* main(L) + sub(R) */ 313 #define BCTV2_GR0_AUDIO_MUTE 4 /* audio mute */ 314 #define BCTV2_GR0_AUDIO_MONO 8 /* force mono */ 315 316 void 317 set_bctv2_audio( bktr_ptr_t bktr ) 318 { 319 int data; 320 321 switch (bktr->audio_mux_select) { 322 case 1: /* external */ 323 case 2: /* internal */ 324 bctv2_gpio_write(bktr, BCTV2_GPIO_REG1, 0); 325 break; 326 default: /* tuner */ 327 bctv2_gpio_write(bktr, BCTV2_GPIO_REG1, 1); 328 break; 329 } 330 /* switch (bktr->audio_sap_select) { */ 331 switch (BCTV2_AUDIO_BOTH) { 332 case BCTV2_AUDIO_SUB: 333 data = BCTV2_GR0_AUDIO_SUB; 334 break; 335 case BCTV2_AUDIO_BOTH: 336 data = BCTV2_GR0_AUDIO_BOTH; 337 break; 338 case BCTV2_AUDIO_MAIN: 339 default: 340 data = BCTV2_GR0_AUDIO_MAIN; 341 break; 342 } 343 if (bktr->audio_mute_state == TRUE) 344 data |= BCTV2_GR0_AUDIO_MUTE; 345 346 bctv2_gpio_write(bktr, BCTV2_GPIO_REG0, data); 347 348 return; 349 } 350 351 /* gpio_data bit assignment */ 352 #define BCTV2_GPIO_ADDR_MASK 0x000300 353 #define BCTV2_GPIO_WE 0x000400 354 #define BCTV2_GPIO_OE 0x000800 355 #define BCTV2_GPIO_VAL_MASK 0x00f000 356 357 #define BCTV2_GPIO_PORT_MASK 3 358 #define BCTV2_GPIO_ADDR_SHIFT 8 359 #define BCTV2_GPIO_VAL_SHIFT 12 360 361 /* gpio_out_en value for read/write */ 362 #define BCTV2_GPIO_OUT_RMASK 0x000f00 363 #define BCTV2_GPIO_OUT_WMASK 0x00ff00 364 365 #define BCTV2_BITS 100 366 367 void 368 bctv2_gpio_write( bktr_ptr_t bktr, int port, int val ) 369 { 370 u_long data, outbits; 371 372 port &= BCTV2_GPIO_PORT_MASK; 373 switch (port) { 374 case 1: 375 case 3: 376 data = ((val << BCTV2_GPIO_VAL_SHIFT) & BCTV2_GPIO_VAL_MASK) | 377 ((port << BCTV2_GPIO_ADDR_SHIFT) & BCTV2_GPIO_ADDR_MASK) | 378 BCTV2_GPIO_WE | BCTV2_GPIO_OE; 379 outbits = BCTV2_GPIO_OUT_WMASK; 380 break; 381 default: 382 return; 383 } 384 OUTL(bktr, BKTR_GPIO_OUT_EN, 0); 385 OUTL(bktr, BKTR_GPIO_DATA, data); 386 OUTL(bktr, BKTR_GPIO_OUT_EN, outbits); 387 DELAY(BCTV2_BITS); 388 OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV2_GPIO_WE); 389 DELAY(BCTV2_BITS); 390 OUTL(bktr, BKTR_GPIO_DATA, data); 391 DELAY(BCTV2_BITS); 392 OUTL(bktr, BKTR_GPIO_DATA, ~0); 393 OUTL(bktr, BKTR_GPIO_OUT_EN, 0); 394 } 395 396 /* Not yet used 397 int 398 bctv2_gpio_read( bktr_ptr_t bktr, int port ) 399 { 400 u_long data, outbits, ret; 401 402 port &= BCTV2_GPIO_PORT_MASK; 403 switch (port) { 404 case 1: 405 case 3: 406 data = ((port << BCTV2_GPIO_ADDR_SHIFT) & BCTV2_GPIO_ADDR_MASK) | 407 BCTV2_GPIO_WE | BCTV2_GPIO_OE; 408 outbits = BCTV2_GPIO_OUT_RMASK; 409 break; 410 default: 411 return( -1 ); 412 } 413 OUTL(bktr, BKTR_GPIO_OUT_EN, 0); 414 OUTL(bktr, BKTR_GPIO_DATA, data); 415 OUTL(bktr, BKTR_GPIO_OUT_EN, outbits); 416 DELAY(BCTV2_BITS); 417 OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV2_GPIO_OE); 418 DELAY(BCTV2_BITS); 419 ret = INL(bktr, BKTR_GPIO_DATA); 420 DELAY(BCTV2_BITS); 421 OUTL(bktr, BKTR_GPIO_DATA, data); 422 DELAY(BCTV2_BITS); 423 OUTL(bktr, BKTR_GPIO_DATA, ~0); 424 OUTL(bktr, BKTR_GPIO_OUT_EN, 0); 425 return( (ret & BCTV2_GPIO_VAL_MASK) >> BCTV2_GPIO_VAL_SHIFT ); 426 } 427 */ 428 429 /* 430 * setup the MSP34xx Stereo Audio Chip 431 * This uses the Auto Configuration Option on MSP3410D and MSP3415D chips 432 * and DBX mode selection for MSP3430G chips. 433 * For MSP3400C support, the full programming sequence is required and is 434 * not yet supported. 435 */ 436 437 /* Read the MSP version string */ 438 void msp_read_id( bktr_ptr_t bktr ){ 439 int rev1=0, rev2=0; 440 rev1 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001e); 441 rev2 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001f); 442 443 sprintf(bktr->msp_version_string, "34%02d%c-%c%d", 444 (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); 445 446 } 447 448 449 /* Configure the MSP chip to Auto-detect the audio format. 450 * For the MSP3430G, we use fast autodetect mode 451 * For the MSP3410/3415 there are two schemes for this 452 * a) Fast autodetection - the chip is put into autodetect mode, and the function 453 * returns immediatly. This works in most cases and is the Default Mode. 454 * b) Slow mode. The function sets the MSP3410/3415 chip, then waits for feedback from 455 * the chip and re-programs it if needed. 456 */ 457 void msp_autodetect( bktr_ptr_t bktr ) { 458 459 #ifdef BKTR_NEW_MSP34XX_DRIVER 460 461 /* Just wake up the (maybe) sleeping thread, it'll do everything for us */ 462 msp_wake_thread(bktr); 463 464 #else 465 int auto_detect, loops; 466 int stereo; 467 468 /* MSP3430G - countries with mono and DBX stereo */ 469 if (strncmp("3430G", bktr->msp_version_string, 5) == 0){ 470 471 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0030,0x2003);/* Enable Auto format detection */ 472 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0020);/* Standard Select Reg. = BTSC-Stereo*/ 473 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000E,0x2403);/* darned if I know */ 474 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0320);/* Source select = (St or A) */ 475 /* & Ch. Matrix = St */ 476 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */ 477 } 478 479 480 /* MSP3415D SPECIAL CASE Use the Tuner's Mono audio ouput for the MSP */ 481 /* (for Hauppauge 44xxx card with Tuner Type 0x2a) */ 482 else if ( ( (strncmp("3415D", bktr->msp_version_string, 5) == 0) 483 &&(bktr->msp_use_mono_source == 1) 484 ) 485 || (bktr->slow_msp_audio == 2) ){ 486 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */ 487 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */ 488 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */ 489 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0100); /* DSP In = MONO IN */ 490 } 491 492 493 /* MSP3410/MSP3415 - countries with mono, stereo using 2 FM channels and NICAM */ 494 /* FAST sound scheme */ 495 else if (bktr->slow_msp_audio == 0) { 496 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */ 497 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Spkr Source = default(FM/AM) */ 498 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */ 499 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */ 500 } 501 502 503 /* MSP3410/MSP3415 - European Countries where the fast MSP3410/3415 programming fails */ 504 /* SLOW sound scheme */ 505 else if ( bktr->slow_msp_audio == 1) { 506 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */ 507 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */ 508 509 /* wait for 0.5s max for terrestrial sound autodetection */ 510 loops = 10; 511 do { 512 DELAY(100000); 513 auto_detect = msp_dpl_read(bktr, bktr->msp_addr, 0x10, 0x007e); 514 loops++; 515 } while (auto_detect > 0xff && loops < 50); 516 if (bootverbose)printf ("%s: Result of autodetect after %dms: %d\n", 517 bktr_name(bktr), loops*10, auto_detect); 518 519 /* Now set the audio baseband processing */ 520 switch (auto_detect) { 521 case 0: /* no TV sound standard detected */ 522 break; 523 case 2: /* M Dual FM */ 524 break; 525 case 3: /* B/G Dual FM; German stereo */ 526 /* Read the stereo detection value from DSP reg 0x0018 */ 527 DELAY(20000); 528 stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018); 529 if (bootverbose)printf ("%s: Stereo reg 0x18 a: %d\n", 530 bktr_name(bktr), stereo); 531 DELAY(20000); 532 stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018); 533 if (bootverbose)printf ("%s: Stereo reg 0x18 b: %d\n", 534 bktr_name(bktr), stereo); 535 DELAY(20000); 536 stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018); 537 if (bootverbose)printf ("%s: Stereo reg 0x18 c: %d\n", 538 bktr_name(bktr), stereo); 539 if (stereo > 0x0100 && stereo < 0x8000) { /* Seems to be stereo */ 540 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker set stereo*/ 541 /* 542 set spatial effect strength to 50% enlargement 543 set spatial effect mode b, stereo basewidth enlargment only 544 */ 545 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f28); 546 } else if (stereo > 0x8000) { /* bilingual mode */ 547 if (bootverbose) printf ("%s: Bilingual mode detected\n", 548 bktr_name(bktr)); 549 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Loudspeaker */ 550 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x0000);/* all spatial effects off */ 551 } else { /* must be mono */ 552 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0030);/* Loudspeaker */ 553 /* 554 set spatial effect strength to 50% enlargement 555 set spatial effect mode a, stereo basewidth enlargment 556 and pseudo stereo effect with automatic high-pass filter 557 */ 558 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f08); 559 } 560 #if 0 561 /* The reset value for Channel matrix mode is FM/AM and SOUNDA/LEFT */ 562 /* We would like STEREO instead val: 0x0020 */ 563 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker */ 564 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0009,0x0020);/* Headphone */ 565 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000a,0x0020);/* SCART1 */ 566 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0041,0x0020);/* SCART2 */ 567 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000b,0x0020);/* I2S */ 568 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000c,0x0020);/* Quasi-Peak Detector Source */ 569 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000e,0x0001); 570 #endif 571 break; 572 case 8: /* B/G FM NICAM */ 573 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */ 574 break; 575 case 9: /* L_AM NICAM or D/K*/ 576 case 10: /* i-FM NICAM */ 577 break; 578 default: 579 if (bootverbose) printf ("%s: Unknown autodetection result value: %d\n", 580 bktr_name(bktr), auto_detect); 581 } 582 583 } 584 585 586 /* uncomment the following line to enable the MSP34xx 1Khz Tone Generator */ 587 /* turn your speaker volume down low before trying this */ 588 /* msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0014, 0x7f40); */ 589 590 #endif /* BKTR_NEW_MSP34XX_DRIVER */ 591 } 592 593 /* Read the DPL version string */ 594 void dpl_read_id( bktr_ptr_t bktr ){ 595 int rev1=0, rev2=0; 596 rev1 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001e); 597 rev2 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001f); 598 599 sprintf(bktr->dpl_version_string, "34%02d%c-%c%d", 600 ((rev2>>8)&0xff)-1, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); 601 } 602 603 /* Configure the DPL chip to Auto-detect the audio format */ 604 void dpl_autodetect( bktr_ptr_t bktr ) { 605 606 /* The following are empiric values tried from the DPL35xx data sheet */ 607 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x000c,0x0320); /* quasi peak detector source dolby 608 lr 0x03xx; quasi peak detector matrix 609 stereo 0xXX20 */ 610 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0040,0x0060); /* Surround decoder mode; 611 ADAPTIVE/3D-PANORAMA, that means two 612 speakers and no center speaker, all 613 channels L/R/C/S mixed to L and R */ 614 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0041,0x0620); /* surround source matrix;I2S2/STEREO*/ 615 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0042,0x1F00); /* surround delay 31ms max */ 616 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0043,0x0000); /* automatic surround input balance */ 617 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0044,0x4000); /* surround spatial effect 50% 618 recommended*/ 619 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0045,0x5400); /* surround panorama effect 66% 620 recommended with PANORAMA mode 621 in 0x0040 set to panorama */ 622 } 623