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