bktr_audio.c revision 52593
1/* $FreeBSD: head/sys/dev/bktr/bktr_audio.c 52593 1999-10-28 13:58:17Z roger $ */ 2/* 3 * This is part of the Driver for Video Capture Cards (Frame grabbers) 4 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 5 * chipset. 6 * Copyright Roger Hardiman and Amancio Hasty. 7 * 8 * bktr_audio : This deals with controlling the audio on TV cards, 9 * controlling the Audio Multiplexer (audio source selector). 10 * controlling any MSP34xx stereo audio decoders. 11 * controlling any DPL35xx dolby surroud sound audio decoders. 12 * initialising TDA98xx audio devices. 13 * 14 */ 15 16/* 17 * 1. Redistributions of source code must retain the 18 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman 19 * All rights reserved. 20 * 21 * Redistribution and use in source and binary forms, with or without 22 * modification, are permitted provided that the following conditions 23 * are met: 24 * 1. Redistributions of source code must retain the above copyright 25 * notice, this list of conditions and the following disclaimer. 26 * 2. Redistributions in binary form must reproduce the above copyright 27 * notice, this list of conditions and the following disclaimer in the 28 * documentation and/or other materials provided with the distribution. 29 * 3. All advertising materials mentioning features or use of this software 30 * must display the following acknowledgement: 31 * This product includes software developed by Amancio Hasty and 32 * Roger Hardiman 33 * 4. The name of the author may not be used to endorse or promote products 34 * derived from this software without specific prior written permission. 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 37 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 38 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 39 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 40 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 41 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 42 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 45 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 46 * POSSIBILITY OF SUCH DAMAGE. 47 */ 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/kernel.h> 52#include <sys/vnode.h> 53 54#include <machine/clock.h> /* for DELAY */ 55 56#include <pci/pcivar.h> 57 58#include <machine/ioctl_meteor.h> 59#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */ 60#include <dev/bktr/bktr_reg.h> 61#include <dev/bktr/bktr_core.h> 62#include <dev/bktr/bktr_tuner.h> 63#include <dev/bktr/bktr_card.h> 64#include <dev/bktr/bktr_audio.h> 65 66 67/* 68 * Prototypes for the GV_BCTV specific functions. 69 */ 70void set_bctv_audio( bktr_ptr_t bktr ); 71void bctv_gpio_write( bktr_ptr_t bktr, int port, int val ); 72/*int bctv_gpio_read( bktr_ptr_t bktr, int port );*/ /* Not used */ 73 74 75 76/* 77 * init_audio_devices 78 * Reset any MSP34xx or TDA98xx audio devices. 79 */ 80void init_audio_devices( bktr_ptr_t bktr ) { 81 82 /* enable stereo if appropriate on TDA audio chip */ 83 if ( bktr->card.dbx ) 84 init_BTSC( bktr ); 85 86 /* reset the MSP34xx stereo audio chip */ 87 if ( bktr->card.msp3400c ) 88 msp_dpl_reset( bktr, bktr->msp_addr ); 89 90 /* reset the DPL35xx dolby audio chip */ 91 if ( bktr->card.dpl3518a ) 92 msp_dpl_reset( bktr, bktr->dpl_addr ); 93 94} 95 96 97/* 98 * 99 */ 100#define AUDIOMUX_DISCOVER_NOT 101int 102set_audio( bktr_ptr_t bktr, int cmd ) 103{ 104 bt848_ptr_t bt848; 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("bktr: audio cmd error %02x\n", cmd); 146 return( -1 ); 147 } 148 149 150 /* Most cards have a simple audio multiplexer to select the 151 * audio source. The I/O_GV card has a more advanced multiplexer 152 * and requires special handling. 153 */ 154 if ( bktr->bt848_card == CARD_IO_GV ) { 155 set_bctv_audio( bktr ); 156 return( 0 ); 157 } 158 159 /* Proceed with the simpler audio multiplexer code for the majority 160 * of Bt848 cards. 161 */ 162 163 bt848 = bktr->base; 164 165 /* 166 * Leave the upper bits of the GPIO port alone in case they control 167 * something like the dbx or teletext chips. This doesn't guarantee 168 * success, but follows the rule of least astonishment. 169 */ 170 171 if ( bktr->audio_mute_state == TRUE ) { 172#ifdef BKTR_REVERSEMUTE 173 idx = 0; 174#else 175 idx = 3; 176#endif 177 178 if (bktr->reverse_mute ) 179 idx = 3; 180 else 181 idx = 0; 182 183 } 184 else 185 idx = bktr->audio_mux_select; 186 187 temp = bt848->gpio_data & ~bktr->card.gpio_mux_bits; 188 bt848->gpio_data = 189#if defined( AUDIOMUX_DISCOVER ) 190 bt848->gpio_data = temp | (cmd & 0xff); 191 printf("cmd: %d audio mux %x temp %x \n", cmd,bktr->card.audiomuxs[ idx ], temp ); 192#else 193 temp | bktr->card.audiomuxs[ idx ]; 194#endif /* AUDIOMUX_DISCOVER */ 195 196 return( 0 ); 197} 198 199 200/* 201 * 202 */ 203void 204temp_mute( bktr_ptr_t bktr, int flag ) 205{ 206 static int muteState = FALSE; 207 208 if ( flag == TRUE ) { 209 muteState = bktr->audio_mute_state; 210 set_audio( bktr, AUDIO_MUTE ); /* prevent 'click' */ 211 } 212 else { 213 tsleep( BKTR_SLEEP, PZERO, "tuning", hz/8 ); 214 if ( muteState == FALSE ) 215 set_audio( bktr, AUDIO_UNMUTE ); 216 } 217} 218 219/* address of BTSC/SAP decoder chip */ 220#define TDA9850_WADDR 0xb6 221#define TDA9850_RADDR 0xb7 222 223 224/* registers in the TDA9850 BTSC/dbx chip */ 225#define CON1ADDR 0x04 226#define CON2ADDR 0x05 227#define CON3ADDR 0x06 228#define CON4ADDR 0x07 229#define ALI1ADDR 0x08 230#define ALI2ADDR 0x09 231#define ALI3ADDR 0x0a 232 233/* 234 * initialise the dbx chip 235 * taken from the Linux bttv driver TDA9850 initialisation code 236 */ 237void 238init_BTSC( bktr_ptr_t bktr ) 239{ 240 i2cWrite(bktr, TDA9850_WADDR, CON1ADDR, 0x08); /* noise threshold st */ 241 i2cWrite(bktr, TDA9850_WADDR, CON2ADDR, 0x08); /* noise threshold sap */ 242 i2cWrite(bktr, TDA9850_WADDR, CON3ADDR, 0x40); /* stereo mode */ 243 i2cWrite(bktr, TDA9850_WADDR, CON4ADDR, 0x07); /* 0 dB input gain? */ 244 i2cWrite(bktr, TDA9850_WADDR, ALI1ADDR, 0x10); /* wideband alignment? */ 245 i2cWrite(bktr, TDA9850_WADDR, ALI2ADDR, 0x10); /* spectral alignment? */ 246 i2cWrite(bktr, TDA9850_WADDR, ALI3ADDR, 0x03); 247} 248 249/* 250 * setup the dbx chip 251 * XXX FIXME: alot of work to be done here, this merely unmutes it. 252 */ 253int 254set_BTSC( bktr_ptr_t bktr, int control ) 255{ 256 return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) ); 257} 258 259/* 260 * CARD_GV_BCTV specific functions. 261 */ 262 263#define BCTV_AUDIO_MAIN 0x10 /* main audio program */ 264#define BCTV_AUDIO_SUB 0x20 /* sub audio program */ 265#define BCTV_AUDIO_BOTH 0x30 /* main(L) + sub(R) program */ 266 267#define BCTV_GPIO_REG0 1 268#define BCTV_GPIO_REG1 3 269 270#define BCTV_GR0_AUDIO_MODE 3 271#define BCTV_GR0_AUDIO_MAIN 0 /* main program */ 272#define BCTV_GR0_AUDIO_SUB 3 /* sub program */ 273#define BCTV_GR0_AUDIO_BOTH 1 /* main(L) + sub(R) */ 274#define BCTV_GR0_AUDIO_MUTE 4 /* audio mute */ 275#define BCTV_GR0_AUDIO_MONO 8 /* force mono */ 276 277void 278set_bctv_audio( bktr_ptr_t bktr ) 279{ 280 int data; 281 282 switch (bktr->audio_mux_select) { 283 case 1: /* external */ 284 case 2: /* internal */ 285 bctv_gpio_write(bktr, BCTV_GPIO_REG1, 0); 286 break; 287 default: /* tuner */ 288 bctv_gpio_write(bktr, BCTV_GPIO_REG1, 1); 289 break; 290 } 291/* switch (bktr->audio_sap_select) { */ 292 switch (BCTV_AUDIO_BOTH) { 293 case BCTV_AUDIO_SUB: 294 data = BCTV_GR0_AUDIO_SUB; 295 break; 296 case BCTV_AUDIO_BOTH: 297 data = BCTV_GR0_AUDIO_BOTH; 298 break; 299 case BCTV_AUDIO_MAIN: 300 default: 301 data = BCTV_GR0_AUDIO_MAIN; 302 break; 303 } 304 if (bktr->audio_mute_state == TRUE) 305 data |= BCTV_GR0_AUDIO_MUTE; 306 307 bctv_gpio_write(bktr, BCTV_GPIO_REG0, data); 308 309 return; 310} 311 312/* gpio_data bit assignment */ 313#define BCTV_GPIO_ADDR_MASK 0x000300 314#define BCTV_GPIO_WE 0x000400 315#define BCTV_GPIO_OE 0x000800 316#define BCTV_GPIO_VAL_MASK 0x00f000 317 318#define BCTV_GPIO_PORT_MASK 3 319#define BCTV_GPIO_ADDR_SHIFT 8 320#define BCTV_GPIO_VAL_SHIFT 12 321 322/* gpio_out_en value for read/write */ 323#define BCTV_GPIO_OUT_RMASK 0x000f00 324#define BCTV_GPIO_OUT_WMASK 0x00ff00 325 326#define BCTV_BITS 100 327 328void 329bctv_gpio_write( bktr_ptr_t bktr, int port, int val ) 330{ 331 bt848_ptr_t bt848 = bktr->base; 332 u_long data, outbits; 333 334 port &= BCTV_GPIO_PORT_MASK; 335 switch (port) { 336 case 1: 337 case 3: 338 data = ((val << BCTV_GPIO_VAL_SHIFT) & BCTV_GPIO_VAL_MASK) | 339 ((port << BCTV_GPIO_ADDR_SHIFT) & BCTV_GPIO_ADDR_MASK) | 340 BCTV_GPIO_WE | BCTV_GPIO_OE; 341 outbits = BCTV_GPIO_OUT_WMASK; 342 break; 343 default: 344 return; 345 } 346 bt848->gpio_out_en = 0; 347 bt848->gpio_data = data; 348 bt848->gpio_out_en = outbits; 349 DELAY(BCTV_BITS); 350 bt848->gpio_data = data & ~BCTV_GPIO_WE; 351 DELAY(BCTV_BITS); 352 bt848->gpio_data = data; 353 DELAY(BCTV_BITS); 354 bt848->gpio_data = ~0; 355 bt848->gpio_out_en = 0; 356} 357 358/* Not yet used 359int 360bctv_gpio_read( bktr_ptr_t bktr, int port ) 361{ 362 bt848_ptr_t bt848 = bktr->base; 363 u_long data, outbits, ret; 364 365 port &= BCTV_GPIO_PORT_MASK; 366 switch (port) { 367 case 1: 368 case 3: 369 data = ((port << BCTV_GPIO_ADDR_SHIFT) & BCTV_GPIO_ADDR_MASK) | 370 BCTV_GPIO_WE | BCTV_GPIO_OE; 371 outbits = BCTV_GPIO_OUT_RMASK; 372 break; 373 default: 374 return( -1 ); 375 } 376 bt848->gpio_out_en = 0; 377 bt848->gpio_data = data; 378 bt848->gpio_out_en = outbits; 379 DELAY(BCTV_BITS); 380 bt848->gpio_data = data & ~BCTV_GPIO_OE; 381 DELAY(BCTV_BITS); 382 ret = bt848->gpio_data; 383 DELAY(BCTV_BITS); 384 bt848->gpio_data = data; 385 DELAY(BCTV_BITS); 386 bt848->gpio_data = ~0; 387 bt848->gpio_out_en = 0; 388 return( (ret & BCTV_GPIO_VAL_MASK) >> BCTV_GPIO_VAL_SHIFT ); 389} 390*/ 391 392/* 393 * setup the MSP34xx Stereo Audio Chip 394 * This uses the Auto Configuration Option on MSP3410D and MSP3415D chips 395 * and DBX mode selection for MSP3430G chips. 396 * For MSP3400C support, the full programming sequence is required and is 397 * not yet supported. 398 */ 399 400/* Read the MSP version string */ 401void msp_read_id( bktr_ptr_t bktr ){ 402 int rev1=0, rev2=0; 403 rev1 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001e); 404 rev2 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001f); 405 406 sprintf(bktr->msp_version_string, "34%02d%c-%c%d", 407 (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); 408 409} 410 411 412/* Configure the MSP chip to Auto-detect the audio format */ 413void msp_autodetect( bktr_ptr_t bktr ) { 414 415 if (strncmp("3430G", bktr->msp_version_string, 5) == 0){ 416 417 /* For MSP3430G - countries with mono and DBX stereo */ 418 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0030,0x2003);/* Enable Auto format detection */ 419 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0020);/* Standard Select Reg. = BTSC-Stereo*/ 420 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000E,0x2403);/* darned if I know */ 421 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0320);/* Source select = (St or A) */ 422 /* & Ch. Matrix = St */ 423 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */ 424 425 } else { 426 427 /* For MSP3410 / 3415 - countries with mono, stereo using 2 FM channels 428 and NICAM */ 429 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */ 430 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */ 431 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */ 432 } 433 434 /* uncomment the following line to enable the MSP34xx 1Khz Tone Generator */ 435 /* turn your speaker volume down low before trying this */ 436 /* msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0014, 0x7f40); */ 437} 438 439/* Read the DPL version string */ 440void dpl_read_id( bktr_ptr_t bktr ){ 441 int rev1=0, rev2=0; 442 rev1 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001e); 443 rev2 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001f); 444 445 sprintf(bktr->dpl_version_string, "34%02d%c-%c%d", 446 ((rev2>>8)&0xff)-1, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f); 447} 448 449/* Configure the DPL chip to Auto-detect the audio format */ 450void dpl_autodetect( bktr_ptr_t bktr ) { 451 452 /* The following are empiric values tried from the DPL35xx data sheet */ 453 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x000c,0x0320); /* quasi peak detector source dolby 454 lr 0x03xx; quasi peak detector matrix 455 stereo 0xXX20 */ 456 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0040,0x0060); /* Surround decoder mode; 457 ADAPTIVE/3D-PANORAMA, that means two 458 speakers and no center speaker, all 459 channels L/R/C/S mixed to L and R */ 460 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0041,0x0620); /* surround source matrix;I2S2/STEREO*/ 461 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0042,0x1F00); /* surround delay 31ms max */ 462 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0043,0x0000); /* automatic surround input balance */ 463 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0044,0x4000); /* surround spatial effect 50% 464 recommended*/ 465 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0045,0x5400); /* surround panorama effect 66% 466 recommended with PANORAMA mode 467 in 0x0040 set to panorama */ 468} 469 470