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