bktr_audio.c revision 298955
1279377Simp/*- 2279377Simp * 1. Redistributions of source code must retain the 3279377Simp * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman 4279377Simp * All rights reserved. 5279377Simp * 6279377Simp * Redistribution and use in source and binary forms, with or without 7279377Simp * modification, are permitted provided that the following conditions 8279377Simp * are met: 9279377Simp * 1. Redistributions of source code must retain the above copyright 10279377Simp * notice, this list of conditions and the following disclaimer. 11279377Simp * 2. Redistributions in binary form must reproduce the above copyright 12279377Simp * notice, this list of conditions and the following disclaimer in the 13279377Simp * documentation and/or other materials provided with the distribution. 14279377Simp * 3. All advertising materials mentioning features or use of this software 15279377Simp * must display the following acknowledgement: 16279377Simp * This product includes software developed by Amancio Hasty and 17279377Simp * Roger Hardiman 18279377Simp * 4. The name of the author may not be used to endorse or promote products 19279377Simp * derived from this software without specific prior written permission. 20279377Simp * 21279377Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22279377Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23279377Simp * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24279377Simp * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 25279377Simp * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26279377Simp * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27279377Simp * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28279377Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29279377Simp * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30279377Simp * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31279377Simp * POSSIBILITY OF SUCH DAMAGE. 32279377Simp */ 33279377Simp 34279377Simp#include <sys/cdefs.h> 35279377Simp__FBSDID("$FreeBSD: head/sys/dev/bktr/bktr_audio.c 298955 2016-05-03 03:41:25Z pfg $"); 36279377Simp 37279377Simp/* 38279377Simp * This is part of the Driver for Video Capture Cards (Frame grabbers) 39279377Simp * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 40279377Simp * chipset. 41279377Simp * Copyright Roger Hardiman and Amancio Hasty. 42279377Simp * 43279377Simp * bktr_audio : This deals with controlling the audio on TV cards, 44279377Simp * controlling the Audio Multiplexer (audio source selector). 45279377Simp * controlling any MSP34xx stereo audio decoders. 46279377Simp * controlling any DPL35xx dolby surroud sound audio decoders. 47279377Simp * initialising TDA98xx audio devices. 48279377Simp * 49279377Simp */ 50279377Simp 51279377Simp#include "opt_bktr.h" /* Include any kernel config options */ 52279377Simp 53279377Simp#include <sys/param.h> 54279377Simp#include <sys/systm.h> 55279377Simp#include <sys/kernel.h> 56279377Simp 57279377Simp#ifdef __FreeBSD__ 58279377Simp 59279377Simp#if (__FreeBSD_version < 500000) 60279377Simp#include <machine/clock.h> /* for DELAY */ 61279377Simp#include <pci/pcivar.h> 62279377Simp#else 63279377Simp#include <sys/lock.h> 64279377Simp#include <sys/mutex.h> 65279377Simp#include <sys/selinfo.h> 66279377Simp#include <dev/pci/pcivar.h> 67279377Simp#endif 68279377Simp 69279377Simp#include <machine/bus.h> 70279377Simp#include <sys/bus.h> 71279377Simp#endif 72279377Simp 73279377Simp#ifdef __NetBSD__ 74279377Simp#include <sys/proc.h> 75279377Simp#include <dev/ic/bt8xx.h> /* NetBSD location of .h files */ 76279377Simp#include <dev/pci/bktr/bktr_reg.h> 77279377Simp#include <dev/pci/bktr/bktr_core.h> 78279377Simp#include <dev/pci/bktr/bktr_tuner.h> 79279377Simp#include <dev/pci/bktr/bktr_card.h> 80279377Simp#include <dev/pci/bktr/bktr_audio.h> 81279377Simp#else 82279377Simp#include <dev/bktr/ioctl_meteor.h> 83279377Simp#include <dev/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */ 84279377Simp#include <dev/bktr/bktr_reg.h> 85279377Simp#include <dev/bktr/bktr_core.h> 86279377Simp#include <dev/bktr/bktr_tuner.h> 87279377Simp#include <dev/bktr/bktr_card.h> 88279377Simp#include <dev/bktr/bktr_audio.h> 89279377Simp#endif 90279377Simp 91279377Simp/* 92279377Simp * Prototypes for the GV_BCTV2 specific functions. 93279377Simp */ 94279377Simpvoid set_bctv2_audio( bktr_ptr_t bktr ); 95279377Simpvoid bctv2_gpio_write( bktr_ptr_t bktr, int port, int val ); 96279377Simp/*int bctv2_gpio_read( bktr_ptr_t bktr, int port );*/ /* Not used */ 97279377Simp 98279377Simp/* 99279377Simp * init_audio_devices 100279377Simp * Reset any MSP34xx or TDA98xx audio devices. 101279377Simp */ 102279377Simpvoid init_audio_devices( bktr_ptr_t bktr ) { 103279377Simp 104279377Simp /* enable stereo if appropriate on TDA audio chip */ 105279377Simp if ( bktr->card.dbx ) 106279377Simp init_BTSC( bktr ); 107279377Simp 108279377Simp /* reset the MSP34xx stereo audio chip */ 109279377Simp if ( bktr->card.msp3400c ) 110279377Simp msp_dpl_reset( bktr, bktr->msp_addr ); 111279377Simp 112279377Simp /* reset the DPL35xx dolby audio chip */ 113279377Simp if ( bktr->card.dpl3518a ) 114279377Simp msp_dpl_reset( bktr, bktr->dpl_addr ); 115279377Simp 116279377Simp} 117279377Simp 118279377Simp 119279377Simp/* 120279377Simp * 121279377Simp */ 122279377Simp#define AUDIOMUX_DISCOVER_NOT 123279377Simpint 124279377Simpset_audio( bktr_ptr_t bktr, int cmd ) 125279377Simp{ 126279377Simp u_long temp; 127279377Simp volatile u_char idx; 128279377Simp 129279377Simp#if defined( AUDIOMUX_DISCOVER ) 130279377Simp if ( cmd >= 200 ) 131279377Simp cmd -= 200; 132279377Simp else 133279377Simp#endif /* AUDIOMUX_DISCOVER */ 134279377Simp 135279377Simp /* check for existence of audio MUXes */ 136279377Simp if ( !bktr->card.audiomuxs[ 4 ] ) 137279377Simp return( -1 ); 138279377Simp 139279377Simp switch (cmd) { 140279377Simp case AUDIO_TUNER: 141279377Simp#ifdef BKTR_REVERSEMUTE 142279377Simp bktr->audio_mux_select = 3; 143279377Simp#else 144279377Simp bktr->audio_mux_select = 0; 145279377Simp#endif 146279377Simp 147279377Simp if (bktr->reverse_mute ) 148279377Simp bktr->audio_mux_select = 0; 149279377Simp else 150279377Simp bktr->audio_mux_select = 3; 151279377Simp 152279377Simp break; 153279377Simp case AUDIO_EXTERN: 154279377Simp bktr->audio_mux_select = 1; 155279377Simp break; 156279377Simp case AUDIO_INTERN: 157279377Simp bktr->audio_mux_select = 2; 158279377Simp break; 159279377Simp case AUDIO_MUTE: 160279377Simp bktr->audio_mute_state = TRUE; /* set mute */ 161279377Simp break; 162279377Simp case AUDIO_UNMUTE: 163279377Simp bktr->audio_mute_state = FALSE; /* clear mute */ 164279377Simp break; 165279377Simp default: 166279377Simp printf("%s: audio cmd error %02x\n", bktr_name(bktr), 167279377Simp cmd); 168279377Simp return( -1 ); 169279377Simp } 170279377Simp 171279377Simp 172279377Simp /* Most cards have a simple audio multiplexer to select the 173279377Simp * audio source. The I/O_GV card has a more advanced multiplexer 174279377Simp * and requires special handling. 175279377Simp */ 176279377Simp if ( bktr->bt848_card == CARD_IO_BCTV2 ) { 177279377Simp set_bctv2_audio( bktr ); 178279377Simp return( 0 ); 179279377Simp } 180279377Simp 181279377Simp /* Proceed with the simpler audio multiplexer code for the majority 182279377Simp * of Bt848 cards. 183279377Simp */ 184279377Simp 185279377Simp /* 186279377Simp * Leave the upper bits of the GPIO port alone in case they control 187279377Simp * something like the dbx or teletext chips. This doesn't guarantee 188279377Simp * success, but follows the rule of least astonishment. 189279377Simp */ 190279377Simp 191279377Simp if ( bktr->audio_mute_state == TRUE ) { 192279377Simp#ifdef BKTR_REVERSEMUTE 193279377Simp idx = 0; 194279377Simp#else 195279377Simp idx = 3; 196279377Simp#endif 197279377Simp 198279377Simp if (bktr->reverse_mute ) 199279377Simp idx = 3; 200279377Simp else 201279377Simp idx = 0; 202279377Simp 203279377Simp } 204279377Simp else 205279377Simp idx = bktr->audio_mux_select; 206279377Simp 207279377Simp 208279377Simp temp = INL(bktr, BKTR_GPIO_DATA) & ~bktr->card.gpio_mux_bits; 209279377Simp#if defined( AUDIOMUX_DISCOVER ) 210279377Simp OUTL(bktr, BKTR_GPIO_DATA, temp | (cmd & 0xff)); 211279377Simp printf("%s: cmd: %d audio mux %x temp %x \n", bktr_name(bktr), 212279377Simp cmd, bktr->card.audiomuxs[ idx ], temp ); 213279377Simp#else 214279377Simp OUTL(bktr, BKTR_GPIO_DATA, temp | bktr->card.audiomuxs[ idx ]); 215279377Simp#endif /* AUDIOMUX_DISCOVER */ 216279377Simp 217279377Simp 218279377Simp 219279377Simp /* Some new Hauppauge cards do not have an audio mux */ 220279377Simp /* Instead we use the MSP34xx chip to select TV audio, Line-In */ 221279377Simp /* FM Radio and Mute */ 222279377Simp /* Examples of this are the Hauppauge 44xxx MSP34xx models */ 223279377Simp /* It is ok to drive both the mux and the MSP34xx chip. */ 224279377Simp /* If there is no mux, the MSP does the switching of the audio source */ 225279377Simp /* If there is a mux, it does the switching of the audio source */ 226279377Simp 227279377Simp if ((bktr->card.msp3400c) && (bktr->audio_mux_present == 0)) { 228279377Simp 229279377Simp if (bktr->audio_mute_state == TRUE ) { 230279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x0000); /* volume to MUTE */ 231279377Simp } else { 232279377Simp if(bktr->audio_mux_select == 0) { /* TV Tuner */ 233279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */ 234279377Simp if (bktr->msp_source_selected != 0) msp_autodetect(bktr); /* setup TV audio mode */ 235279377Simp bktr->msp_source_selected = 0; 236279377Simp } 237279377Simp if(bktr->audio_mux_select == 1) { /* Line In */ 238279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */ 239279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */ 240279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */ 241279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0000); /* DSP In = SC1_IN_L/R */ 242279377Simp bktr->msp_source_selected = 1; 243279377Simp } 244279377Simp 245279377Simp if(bktr->audio_mux_select == 2) { /* FM Radio */ 246279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */ 247279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */ 248279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */ 249279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0200); /* DSP In = SC2_IN_L/R */ 250279377Simp bktr->msp_source_selected = 2; 251279377Simp } 252279377Simp } 253279377Simp } 254279377Simp 255279377Simp 256279377Simp return( 0 ); 257279377Simp} 258279377Simp 259279377Simp 260279377Simp/* 261279377Simp * 262279377Simp */ 263279377Simpvoid 264279377Simptemp_mute( bktr_ptr_t bktr, int flag ) 265279377Simp{ 266279377Simp static int muteState = FALSE; 267279377Simp 268279377Simp if ( flag == TRUE ) { 269279377Simp muteState = bktr->audio_mute_state; 270279377Simp set_audio( bktr, AUDIO_MUTE ); /* prevent 'click' */ 271279377Simp } 272279377Simp else { 273279377Simp tsleep( BKTR_SLEEP, PZERO, "tuning", hz/8 ); 274279377Simp if ( muteState == FALSE ) 275279377Simp set_audio( bktr, AUDIO_UNMUTE ); 276279377Simp } 277279377Simp} 278279377Simp 279279377Simp/* address of BTSC/SAP decoder chip */ 280279377Simp#define TDA9850_WADDR 0xb6 281279377Simp#define TDA9850_RADDR 0xb7 282279377Simp 283279377Simp 284279377Simp/* registers in the TDA9850 BTSC/dbx chip */ 285279377Simp#define CON1ADDR 0x04 286279377Simp#define CON2ADDR 0x05 287279377Simp#define CON3ADDR 0x06 288279377Simp#define CON4ADDR 0x07 289279377Simp#define ALI1ADDR 0x08 290279377Simp#define ALI2ADDR 0x09 291279377Simp#define ALI3ADDR 0x0a 292279377Simp 293279377Simp/* 294279377Simp * initialise the dbx chip 295279377Simp * taken from the Linux bttv driver TDA9850 initialisation code 296279377Simp */ 297279377Simpvoid 298279377Simpinit_BTSC( bktr_ptr_t bktr ) 299279377Simp{ 300279377Simp i2cWrite(bktr, TDA9850_WADDR, CON1ADDR, 0x08); /* noise threshold st */ 301279377Simp i2cWrite(bktr, TDA9850_WADDR, CON2ADDR, 0x08); /* noise threshold sap */ 302279377Simp i2cWrite(bktr, TDA9850_WADDR, CON3ADDR, 0x40); /* stereo mode */ 303279377Simp i2cWrite(bktr, TDA9850_WADDR, CON4ADDR, 0x07); /* 0 dB input gain? */ 304279377Simp i2cWrite(bktr, TDA9850_WADDR, ALI1ADDR, 0x10); /* wideband alignment? */ 305279377Simp i2cWrite(bktr, TDA9850_WADDR, ALI2ADDR, 0x10); /* spectral alignment? */ 306279377Simp i2cWrite(bktr, TDA9850_WADDR, ALI3ADDR, 0x03); 307279377Simp} 308279377Simp 309279377Simp/* 310279377Simp * setup the dbx chip 311279377Simp * XXX FIXME: a lot of work to be done here, this merely unmutes it. 312279377Simp */ 313279377Simpint 314279377Simpset_BTSC( bktr_ptr_t bktr, int control ) 315279377Simp{ 316279377Simp return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) ); 317279377Simp} 318279377Simp 319279377Simp/* 320279377Simp * CARD_GV_BCTV2 specific functions. 321279377Simp */ 322279377Simp 323279377Simp#define BCTV2_AUDIO_MAIN 0x10 /* main audio program */ 324279377Simp#define BCTV2_AUDIO_SUB 0x20 /* sub audio program */ 325279377Simp#define BCTV2_AUDIO_BOTH 0x30 /* main(L) + sub(R) program */ 326279377Simp 327279377Simp#define BCTV2_GPIO_REG0 1 328279377Simp#define BCTV2_GPIO_REG1 3 329279377Simp 330279377Simp#define BCTV2_GR0_AUDIO_MODE 3 331279377Simp#define BCTV2_GR0_AUDIO_MAIN 0 /* main program */ 332279377Simp#define BCTV2_GR0_AUDIO_SUB 3 /* sub program */ 333279377Simp#define BCTV2_GR0_AUDIO_BOTH 1 /* main(L) + sub(R) */ 334279377Simp#define BCTV2_GR0_AUDIO_MUTE 4 /* audio mute */ 335279377Simp#define BCTV2_GR0_AUDIO_MONO 8 /* force mono */ 336279377Simp 337279377Simpvoid 338279377Simpset_bctv2_audio( bktr_ptr_t bktr ) 339279377Simp{ 340279377Simp int data; 341279377Simp 342279377Simp switch (bktr->audio_mux_select) { 343279377Simp case 1: /* external */ 344279377Simp case 2: /* internal */ 345279377Simp bctv2_gpio_write(bktr, BCTV2_GPIO_REG1, 0); 346279377Simp break; 347279377Simp default: /* tuner */ 348279377Simp bctv2_gpio_write(bktr, BCTV2_GPIO_REG1, 1); 349279377Simp break; 350279377Simp } 351279377Simp/* switch (bktr->audio_sap_select) { */ 352279377Simp switch (BCTV2_AUDIO_BOTH) { 353279377Simp case BCTV2_AUDIO_SUB: 354279377Simp data = BCTV2_GR0_AUDIO_SUB; 355279377Simp break; 356279377Simp case BCTV2_AUDIO_BOTH: 357279377Simp data = BCTV2_GR0_AUDIO_BOTH; 358279377Simp break; 359279377Simp case BCTV2_AUDIO_MAIN: 360279377Simp default: 361279377Simp data = BCTV2_GR0_AUDIO_MAIN; 362279377Simp break; 363279377Simp } 364279377Simp if (bktr->audio_mute_state == TRUE) 365279377Simp data |= BCTV2_GR0_AUDIO_MUTE; 366279377Simp 367279377Simp bctv2_gpio_write(bktr, BCTV2_GPIO_REG0, data); 368279377Simp 369279377Simp return; 370279377Simp} 371279377Simp 372279377Simp/* gpio_data bit assignment */ 373279377Simp#define BCTV2_GPIO_ADDR_MASK 0x000300 374279377Simp#define BCTV2_GPIO_WE 0x000400 375279377Simp#define BCTV2_GPIO_OE 0x000800 376279377Simp#define BCTV2_GPIO_VAL_MASK 0x00f000 377279377Simp 378279377Simp#define BCTV2_GPIO_PORT_MASK 3 379279377Simp#define BCTV2_GPIO_ADDR_SHIFT 8 380279377Simp#define BCTV2_GPIO_VAL_SHIFT 12 381279377Simp 382279377Simp/* gpio_out_en value for read/write */ 383279377Simp#define BCTV2_GPIO_OUT_RMASK 0x000f00 384279377Simp#define BCTV2_GPIO_OUT_WMASK 0x00ff00 385279377Simp 386279377Simp#define BCTV2_BITS 100 387279377Simp 388279377Simpvoid 389279377Simpbctv2_gpio_write( bktr_ptr_t bktr, int port, int val ) 390279377Simp{ 391279377Simp u_long data, outbits; 392279377Simp 393279377Simp port &= BCTV2_GPIO_PORT_MASK; 394279377Simp switch (port) { 395279377Simp case 1: 396279377Simp case 3: 397279377Simp data = ((val << BCTV2_GPIO_VAL_SHIFT) & BCTV2_GPIO_VAL_MASK) | 398279377Simp ((port << BCTV2_GPIO_ADDR_SHIFT) & BCTV2_GPIO_ADDR_MASK) | 399279377Simp BCTV2_GPIO_WE | BCTV2_GPIO_OE; 400279377Simp outbits = BCTV2_GPIO_OUT_WMASK; 401279377Simp break; 402279377Simp default: 403279377Simp return; 404279377Simp } 405279377Simp OUTL(bktr, BKTR_GPIO_OUT_EN, 0); 406279377Simp OUTL(bktr, BKTR_GPIO_DATA, data); 407279377Simp OUTL(bktr, BKTR_GPIO_OUT_EN, outbits); 408279377Simp DELAY(BCTV2_BITS); 409279377Simp OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV2_GPIO_WE); 410279377Simp DELAY(BCTV2_BITS); 411279377Simp OUTL(bktr, BKTR_GPIO_DATA, data); 412279377Simp DELAY(BCTV2_BITS); 413279377Simp OUTL(bktr, BKTR_GPIO_DATA, ~0); 414279377Simp OUTL(bktr, BKTR_GPIO_OUT_EN, 0); 415279377Simp} 416279377Simp 417279377Simp/* Not yet used 418279377Simpint 419279377Simpbctv2_gpio_read( bktr_ptr_t bktr, int port ) 420279377Simp{ 421279377Simp u_long data, outbits, ret; 422279377Simp 423279377Simp port &= BCTV2_GPIO_PORT_MASK; 424279377Simp switch (port) { 425279377Simp case 1: 426279377Simp case 3: 427279377Simp data = ((port << BCTV2_GPIO_ADDR_SHIFT) & BCTV2_GPIO_ADDR_MASK) | 428279377Simp BCTV2_GPIO_WE | BCTV2_GPIO_OE; 429279377Simp outbits = BCTV2_GPIO_OUT_RMASK; 430279377Simp break; 431279377Simp default: 432279377Simp return( -1 ); 433279377Simp } 434279377Simp OUTL(bktr, BKTR_GPIO_OUT_EN, 0); 435279377Simp OUTL(bktr, BKTR_GPIO_DATA, data); 436279377Simp OUTL(bktr, BKTR_GPIO_OUT_EN, outbits); 437279377Simp DELAY(BCTV2_BITS); 438279377Simp OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV2_GPIO_OE); 439279377Simp DELAY(BCTV2_BITS); 440279377Simp ret = INL(bktr, BKTR_GPIO_DATA); 441279377Simp DELAY(BCTV2_BITS); 442279377Simp OUTL(bktr, BKTR_GPIO_DATA, data); 443279377Simp DELAY(BCTV2_BITS); 444279377Simp OUTL(bktr, BKTR_GPIO_DATA, ~0); 445279377Simp OUTL(bktr, BKTR_GPIO_OUT_EN, 0); 446279377Simp return( (ret & BCTV2_GPIO_VAL_MASK) >> BCTV2_GPIO_VAL_SHIFT ); 447279377Simp} 448279377Simp*/ 449279377Simp 450279377Simp/* 451279377Simp * setup the MSP34xx Stereo Audio Chip 452279377Simp * This uses the Auto Configuration Option on MSP3410D and MSP3415D chips 453279377Simp * and DBX mode selection for MSP3430G chips. 454279377Simp * For MSP3400C support, the full programming sequence is required and is 455279377Simp * not yet supported. 456279377Simp */ 457279377Simp 458279377Simp/* Read the MSP version string */ 459279377Simpvoid msp_read_id( bktr_ptr_t bktr ){ 460279377Simp int rev1=0, rev2=0; 461279377Simp rev1 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001e); 462279377Simp rev2 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001f); 463279377Simp 464279377Simp sprintf(bktr->msp_version_string, "34%02d%c-%c%d", 465279377Simp (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); 466279377Simp 467279377Simp} 468279377Simp 469279377Simp 470279377Simp/* Configure the MSP chip to Auto-detect the audio format. 471279377Simp * For the MSP3430G, we use fast autodetect mode 472279377Simp * For the MSP3410/3415 there are two schemes for this 473279377Simp * a) Fast autodetection - the chip is put into autodetect mode, and the function 474279377Simp * returns immediately. This works in most cases and is the Default Mode. 475279377Simp * b) Slow mode. The function sets the MSP3410/3415 chip, then waits for feedback from 476279377Simp * the chip and re-programs it if needed. 477279377Simp */ 478279377Simpvoid msp_autodetect( bktr_ptr_t bktr ) { 479279377Simp 480279377Simp#ifdef BKTR_NEW_MSP34XX_DRIVER 481279377Simp 482279377Simp /* Just wake up the (maybe) sleeping thread, it'll do everything for us */ 483279377Simp msp_wake_thread(bktr); 484279377Simp 485279377Simp#else 486279377Simp int auto_detect, loops; 487279377Simp int stereo; 488279377Simp 489279377Simp /* MSP3430G - countries with mono and DBX stereo */ 490279377Simp if (strncmp("3430G", bktr->msp_version_string, 5) == 0){ 491279377Simp 492279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0030,0x2003);/* Enable Auto format detection */ 493279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0020);/* Standard Select Reg. = BTSC-Stereo*/ 494279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000E,0x2403);/* darned if I know */ 495279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0320);/* Source select = (St or A) */ 496279377Simp /* & Ch. Matrix = St */ 497279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */ 498279377Simp } 499279377Simp 500279377Simp 501279377Simp /* MSP3415D SPECIAL CASE Use the Tuner's Mono audio output for the MSP */ 502279377Simp /* (for Hauppauge 44xxx card with Tuner Type 0x2a) */ 503279377Simp else if ( ( (strncmp("3415D", bktr->msp_version_string, 5) == 0) 504279377Simp &&(bktr->msp_use_mono_source == 1) 505279377Simp ) 506279377Simp || (bktr->slow_msp_audio == 2) ){ 507279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */ 508279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */ 509279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */ 510279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0100); /* DSP In = MONO IN */ 511279377Simp } 512279377Simp 513279377Simp 514279377Simp /* MSP3410/MSP3415 - countries with mono, stereo using 2 FM channels and NICAM */ 515279377Simp /* FAST sound scheme */ 516279377Simp else if (bktr->slow_msp_audio == 0) { 517279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */ 518279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Spkr Source = default(FM/AM) */ 519279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */ 520279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */ 521279377Simp } 522279377Simp 523279377Simp 524279377Simp /* MSP3410/MSP3415 - European Countries where the fast MSP3410/3415 programming fails */ 525279377Simp /* SLOW sound scheme */ 526279377Simp else if ( bktr->slow_msp_audio == 1) { 527279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */ 528279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */ 529279377Simp 530279377Simp /* wait for 0.5s max for terrestrial sound autodetection */ 531279377Simp loops = 10; 532279377Simp do { 533279377Simp DELAY(100000); 534279377Simp auto_detect = msp_dpl_read(bktr, bktr->msp_addr, 0x10, 0x007e); 535279377Simp loops++; 536279377Simp } while (auto_detect > 0xff && loops < 50); 537279377Simp if (bootverbose)printf ("%s: Result of autodetect after %dms: %d\n", 538279377Simp bktr_name(bktr), loops*10, auto_detect); 539279377Simp 540279377Simp /* Now set the audio baseband processing */ 541279377Simp switch (auto_detect) { 542279377Simp case 0: /* no TV sound standard detected */ 543279377Simp break; 544279377Simp case 2: /* M Dual FM */ 545279377Simp break; 546279377Simp case 3: /* B/G Dual FM; German stereo */ 547279377Simp /* Read the stereo detection value from DSP reg 0x0018 */ 548279377Simp DELAY(20000); 549279377Simp stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018); 550279377Simp if (bootverbose)printf ("%s: Stereo reg 0x18 a: %d\n", 551279377Simp bktr_name(bktr), stereo); 552279377Simp DELAY(20000); 553279377Simp stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018); 554279377Simp if (bootverbose)printf ("%s: Stereo reg 0x18 b: %d\n", 555279377Simp bktr_name(bktr), stereo); 556279377Simp DELAY(20000); 557279377Simp stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018); 558279377Simp if (bootverbose)printf ("%s: Stereo reg 0x18 c: %d\n", 559279377Simp bktr_name(bktr), stereo); 560279377Simp if (stereo > 0x0100 && stereo < 0x8000) { /* Seems to be stereo */ 561279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker set stereo*/ 562279377Simp /* 563279377Simp set spatial effect strength to 50% enlargement 564279377Simp set spatial effect mode b, stereo basewidth enlargement only 565279377Simp */ 566279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f28); 567279377Simp } else if (stereo > 0x8000) { /* bilingual mode */ 568279377Simp if (bootverbose) printf ("%s: Bilingual mode detected\n", 569279377Simp bktr_name(bktr)); 570279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Loudspeaker */ 571279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x0000);/* all spatial effects off */ 572279377Simp } else { /* must be mono */ 573279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0030);/* Loudspeaker */ 574279377Simp /* 575279377Simp set spatial effect strength to 50% enlargement 576279377Simp set spatial effect mode a, stereo basewidth enlargement 577279377Simp and pseudo stereo effect with automatic high-pass filter 578279377Simp */ 579279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f08); 580279377Simp } 581279377Simp#if 0 582279377Simp /* The reset value for Channel matrix mode is FM/AM and SOUNDA/LEFT */ 583279377Simp /* We would like STEREO instead val: 0x0020 */ 584279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker */ 585279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0009,0x0020);/* Headphone */ 586279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000a,0x0020);/* SCART1 */ 587279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0041,0x0020);/* SCART2 */ 588279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000b,0x0020);/* I2S */ 589279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000c,0x0020);/* Quasi-Peak Detector Source */ 590279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000e,0x0001); 591279377Simp#endif 592279377Simp break; 593279377Simp case 8: /* B/G FM NICAM */ 594279377Simp msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */ 595279377Simp break; 596279377Simp case 9: /* L_AM NICAM or D/K*/ 597279377Simp case 10: /* i-FM NICAM */ 598279377Simp break; 599279377Simp default: 600279377Simp if (bootverbose) printf ("%s: Unknown autodetection result value: %d\n", 601279377Simp bktr_name(bktr), auto_detect); 602279377Simp } 603279377Simp 604279377Simp } 605279377Simp 606279377Simp 607279377Simp /* uncomment the following line to enable the MSP34xx 1Khz Tone Generator */ 608279377Simp /* turn your speaker volume down low before trying this */ 609279377Simp /* msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0014, 0x7f40); */ 610279377Simp 611279377Simp#endif /* BKTR_NEW_MSP34XX_DRIVER */ 612279377Simp} 613279377Simp 614279377Simp/* Read the DPL version string */ 615279377Simpvoid dpl_read_id( bktr_ptr_t bktr ){ 616279377Simp int rev1=0, rev2=0; 617279377Simp rev1 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001e); 618279377Simp rev2 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001f); 619279377Simp 620279377Simp sprintf(bktr->dpl_version_string, "34%02d%c-%c%d", 621279377Simp ((rev2>>8)&0xff)-1, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); 622279377Simp} 623279377Simp 624279377Simp/* Configure the DPL chip to Auto-detect the audio format */ 625279377Simpvoid dpl_autodetect( bktr_ptr_t bktr ) { 626279377Simp 627279377Simp /* The following are empiric values tried from the DPL35xx data sheet */ 628279377Simp msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x000c,0x0320); /* quasi peak detector source dolby 629279377Simp lr 0x03xx; quasi peak detector matrix 630279377Simp stereo 0xXX20 */ 631279377Simp msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0040,0x0060); /* Surround decoder mode; 632279377Simp ADAPTIVE/3D-PANORAMA, that means two 633279377Simp speakers and no center speaker, all 634279377Simp channels L/R/C/S mixed to L and R */ 635279377Simp msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0041,0x0620); /* surround source matrix;I2S2/STEREO*/ 636279377Simp msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0042,0x1F00); /* surround delay 31ms max */ 637279377Simp msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0043,0x0000); /* automatic surround input balance */ 638279377Simp msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0044,0x4000); /* surround spatial effect 50% 639279377Simp recommended*/ 640279377Simp msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0045,0x5400); /* surround panorama effect 66% 641279377Simp recommended with PANORAMA mode 642279377Simp in 0x0040 set to panorama */ 643279377Simp} 644279377Simp 645279377Simp