bktr_audio.c revision 51694
156160Sru/* $FreeBSD: head/sys/dev/bktr/bktr_audio.c 51694 1999-09-26 22:06:20Z roger $ */ 2146515Sru/* 321495Sjmacd * This is part of the Driver for Video Capture Cards (Frame grabbers) 4146515Sru * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879 5146515Sru * chipset. 621495Sjmacd * Copyright Roger Hardiman and Amancio Hasty. 721495Sjmacd * 821495Sjmacd * bktr_audio : This deals with controlling the audio on TV cards, 921495Sjmacd * controlling the Audio Multiplexer (audio source selector). 1021495Sjmacd * controlling any MSP34xx stereo audio decoders. 1121495Sjmacd * initialising TDA98xx audio devices. 1221495Sjmacd * 1321495Sjmacd */ 1421495Sjmacd 1521495Sjmacd/* 1621495Sjmacd * 1. Redistributions of source code must retain the 1721495Sjmacd * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman 1821495Sjmacd * All rights reserved. 1921495Sjmacd * 2021495Sjmacd * Redistribution and use in source and binary forms, with or without 2121495Sjmacd * modification, are permitted provided that the following conditions 2221495Sjmacd * are met: 2342660Smarkm * 1. Redistributions of source code must retain the above copyright 2442660Smarkm * notice, this list of conditions and the following disclaimer. 25146515Sru * 2. Redistributions in binary form must reproduce the above copyright 2621495Sjmacd * notice, this list of conditions and the following disclaimer in the 2721495Sjmacd * documentation and/or other materials provided with the distribution. 2821495Sjmacd * 3. All advertising materials mentioning features or use of this software 2921495Sjmacd * must display the following acknowledgement: 3021495Sjmacd * This product includes software developed by Amancio Hasty and 3121495Sjmacd * Roger Hardiman 3221495Sjmacd * 4. The name of the author may not be used to endorse or promote products 3321495Sjmacd * derived from this software without specific prior written permission. 3421495Sjmacd * 3521495Sjmacd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 3621495Sjmacd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 3721495Sjmacd * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 3821495Sjmacd * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 3921495Sjmacd * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 4021495Sjmacd * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 4121495Sjmacd * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4221495Sjmacd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4321495Sjmacd * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 4421495Sjmacd * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4521495Sjmacd * POSSIBILITY OF SUCH DAMAGE. 4621495Sjmacd */ 4721495Sjmacd 4821495Sjmacd#include <sys/param.h> 4921495Sjmacd#include <sys/systm.h> 5021495Sjmacd#include <sys/kernel.h> 5121495Sjmacd#include <sys/vnode.h> 5221495Sjmacd 5321495Sjmacd#include <machine/clock.h> /* for DELAY */ 5421495Sjmacd 5521495Sjmacd#include <pci/pcivar.h> 5621495Sjmacd 5721495Sjmacd#include <machine/ioctl_meteor.h> 5821495Sjmacd#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */ 5921495Sjmacd#include <dev/bktr/bktr_reg.h> 6021495Sjmacd#include <dev/bktr/bktr_core.h> 6121495Sjmacd#include <dev/bktr/bktr_tuner.h> 6221495Sjmacd#include <dev/bktr/bktr_card.h> 63146515Sru#include <dev/bktr/bktr_audio.h> 6421495Sjmacd 6521495Sjmacd 6621495Sjmacd/* 6721495Sjmacd * Prototypes for the GV_BCTV specific functions. 6821495Sjmacd */ 6921495Sjmacdvoid set_bctv_audio( bktr_ptr_t bktr ); 7021495Sjmacdvoid bctv_gpio_write( bktr_ptr_t bktr, int port, int val ); 7121495Sjmacd/*int bctv_gpio_read( bktr_ptr_t bktr, int port );*/ /* Not used */ 7221495Sjmacd 7321495Sjmacd 7421495Sjmacd 7521495Sjmacd/* 7621495Sjmacd * init_audio_devices 7742660Smarkm * Reset any MSP34xx or TDA98xx audio devices. 7842660Smarkm */ 7942660Smarkmvoid init_audio_devices( bktr_ptr_t bktr ) { 8042660Smarkm 8142660Smarkm /* enable stereo if appropriate on TDA audio chip */ 8242660Smarkm if ( bktr->card.dbx ) 8342660Smarkm init_BTSC( bktr ); 8442660Smarkm 8542660Smarkm /* reset the MSP34xx stereo audio chip */ 8642660Smarkm if ( bktr->card.msp3400c ) 8721495Sjmacd msp_reset( bktr ); 8821495Sjmacd 8921495Sjmacd} 9021495Sjmacd 9121495Sjmacd 9221495Sjmacd/* 9321495Sjmacd * 94146515Sru */ 9521495Sjmacd#define AUDIOMUX_DISCOVER_NOT 9621495Sjmacdint 9721495Sjmacdset_audio( bktr_ptr_t bktr, int cmd ) 9821495Sjmacd{ 9921495Sjmacd bt848_ptr_t bt848; 10021495Sjmacd u_long temp; 10121495Sjmacd volatile u_char idx; 10221495Sjmacd 10356160Sru#if defined( AUDIOMUX_DISCOVER ) 10442660Smarkm if ( cmd >= 200 ) 10521495Sjmacd cmd -= 200; 10621495Sjmacd else 10742660Smarkm#endif /* AUDIOMUX_DISCOVER */ 10842660Smarkm 10942660Smarkm /* check for existance of audio MUXes */ 11042660Smarkm if ( !bktr->card.audiomuxs[ 4 ] ) 11121495Sjmacd return( -1 ); 11221495Sjmacd 11321495Sjmacd switch (cmd) { 11421495Sjmacd case AUDIO_TUNER: 11521495Sjmacd#ifdef BKTR_REVERSEMUTE 11621495Sjmacd bktr->audio_mux_select = 3; 117146515Sru#else 11821495Sjmacd bktr->audio_mux_select = 0; 119146515Sru#endif 12021495Sjmacd 12121495Sjmacd if (bktr->reverse_mute ) 12221495Sjmacd bktr->audio_mux_select = 0; 12321495Sjmacd else 12421495Sjmacd bktr->audio_mux_select = 3; 12521495Sjmacd 12621495Sjmacd break; 12721495Sjmacd case AUDIO_EXTERN: 12821495Sjmacd bktr->audio_mux_select = 1; 12921495Sjmacd break; 13021495Sjmacd case AUDIO_INTERN: 13121495Sjmacd bktr->audio_mux_select = 2; 13221495Sjmacd break; 13321495Sjmacd case AUDIO_MUTE: 13421495Sjmacd bktr->audio_mute_state = TRUE; /* set mute */ 13521495Sjmacd break; 13621495Sjmacd case AUDIO_UNMUTE: 13742660Smarkm bktr->audio_mute_state = FALSE; /* clear mute */ 13821495Sjmacd break; 13921495Sjmacd default: 14021495Sjmacd printf("bktr: audio cmd error %02x\n", cmd); 14121495Sjmacd return( -1 ); 14221495Sjmacd } 14321495Sjmacd 14421495Sjmacd 14521495Sjmacd /* Most cards have a simple audio multiplexer to select the 14642660Smarkm * audio source. The I/O_GV card has a more advanced multiplexer 14721495Sjmacd * and requires special handling. 14821495Sjmacd */ 14921495Sjmacd if ( bktr->bt848_card == CARD_IO_GV ) { 15021495Sjmacd set_bctv_audio( bktr ); 15142660Smarkm return( 0 ); 15221495Sjmacd } 15321495Sjmacd 15421495Sjmacd /* Proceed with the simpler audio multiplexer code for the majority 15521495Sjmacd * of Bt848 cards. 15621495Sjmacd */ 15721495Sjmacd 15821495Sjmacd bt848 = bktr->base; 15921495Sjmacd 16021495Sjmacd /* 16121495Sjmacd * Leave the upper bits of the GPIO port alone in case they control 16221495Sjmacd * something like the dbx or teletext chips. This doesn't guarantee 16321495Sjmacd * success, but follows the rule of least astonishment. 16442660Smarkm */ 16521495Sjmacd 16621495Sjmacd if ( bktr->audio_mute_state == TRUE ) { 16721495Sjmacd#ifdef BKTR_REVERSEMUTE 16821495Sjmacd idx = 0; 16921495Sjmacd#else 17021495Sjmacd idx = 3; 17121495Sjmacd#endif 17221495Sjmacd 17321495Sjmacd if (bktr->reverse_mute ) 17421495Sjmacd idx = 3; 17521495Sjmacd else 17621495Sjmacd idx = 0; 17721495Sjmacd 17821495Sjmacd } 179146515Sru else 18021495Sjmacd idx = bktr->audio_mux_select; 18156160Sru 18221495Sjmacd temp = bt848->gpio_data & ~bktr->card.gpio_mux_bits; 18321495Sjmacd bt848->gpio_data = 18421495Sjmacd#if defined( AUDIOMUX_DISCOVER ) 18521495Sjmacd bt848->gpio_data = temp | (cmd & 0xff); 18656160Sru printf("cmd: %d audio mux %x temp %x \n", cmd,bktr->card.audiomuxs[ idx ], temp ); 18742660Smarkm#else 18842660Smarkm temp | bktr->card.audiomuxs[ idx ]; 18942660Smarkm#endif /* AUDIOMUX_DISCOVER */ 19021495Sjmacd 19142660Smarkm return( 0 ); 19242660Smarkm} 19342660Smarkm 19442660Smarkm 19542660Smarkm/* 19621495Sjmacd * 19742660Smarkm */ 19842660Smarkmvoid 19942660Smarkmtemp_mute( bktr_ptr_t bktr, int flag ) 20042660Smarkm{ 20121495Sjmacd static int muteState = FALSE; 20256160Sru 20356160Sru if ( flag == TRUE ) { 20442660Smarkm muteState = bktr->audio_mute_state; 20542660Smarkm set_audio( bktr, AUDIO_MUTE ); /* prevent 'click' */ 20656160Sru } 20756160Sru else { 20842660Smarkm tsleep( BKTR_SLEEP, PZERO, "tuning", hz/8 ); 20942660Smarkm if ( muteState == FALSE ) 21042660Smarkm set_audio( bktr, AUDIO_UNMUTE ); 21156160Sru } 21242660Smarkm} 21321495Sjmacd 21442660Smarkm/* address of BTSC/SAP decoder chip */ 21542660Smarkm#define TDA9850_WADDR 0xb6 21656160Sru#define TDA9850_RADDR 0xb7 21742660Smarkm 21821495Sjmacd 21942660Smarkm/* registers in the TDA9850 BTSC/dbx chip */ 22042660Smarkm#define CON1ADDR 0x04 22156160Sru#define CON2ADDR 0x05 22242660Smarkm#define CON3ADDR 0x06 22342660Smarkm#define CON4ADDR 0x07 22442660Smarkm#define ALI1ADDR 0x08 22542660Smarkm#define ALI2ADDR 0x09 22656160Sru#define ALI3ADDR 0x0a 22721495Sjmacd 22842660Smarkm/* 22942660Smarkm * initialise the dbx chip 23042660Smarkm * taken from the Linux bttv driver TDA9850 initialisation code 23142660Smarkm */ 23242660Smarkmvoid 23342660Smarkminit_BTSC( bktr_ptr_t bktr ) 23442660Smarkm{ 235146515Sru i2cWrite(bktr, TDA9850_WADDR, CON1ADDR, 0x08); /* noise threshold st */ 23621495Sjmacd i2cWrite(bktr, TDA9850_WADDR, CON2ADDR, 0x08); /* noise threshold sap */ 23742660Smarkm i2cWrite(bktr, TDA9850_WADDR, CON3ADDR, 0x40); /* stereo mode */ 23842660Smarkm i2cWrite(bktr, TDA9850_WADDR, CON4ADDR, 0x07); /* 0 dB input gain? */ 23956160Sru i2cWrite(bktr, TDA9850_WADDR, ALI1ADDR, 0x10); /* wideband alignment? */ 24056160Sru i2cWrite(bktr, TDA9850_WADDR, ALI2ADDR, 0x10); /* spectral alignment? */ 24142660Smarkm i2cWrite(bktr, TDA9850_WADDR, ALI3ADDR, 0x03); 24242660Smarkm} 24342660Smarkm 24442660Smarkm/* 24542660Smarkm * setup the dbx chip 24642660Smarkm * XXX FIXME: alot of work to be done here, this merely unmutes it. 24742660Smarkm */ 24842660Smarkmint 24942660Smarkmset_BTSC( bktr_ptr_t bktr, int control ) 25042660Smarkm{ 25156160Sru return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) ); 25256160Sru} 25342660Smarkm 25442660Smarkm/* 25556160Sru * CARD_GV_BCTV specific functions. 25642660Smarkm */ 25742660Smarkm 25842660Smarkm#define BCTV_AUDIO_MAIN 0x10 /* main audio program */ 25956160Sru#define BCTV_AUDIO_SUB 0x20 /* sub audio program */ 26042660Smarkm#define BCTV_AUDIO_BOTH 0x30 /* main(L) + sub(R) program */ 26156160Sru 26256160Sru#define BCTV_GPIO_REG0 1 26356160Sru#define BCTV_GPIO_REG1 3 26442660Smarkm 26521495Sjmacd#define BCTV_GR0_AUDIO_MODE 3 26656160Sru#define BCTV_GR0_AUDIO_MAIN 0 /* main program */ 26721495Sjmacd#define BCTV_GR0_AUDIO_SUB 3 /* sub program */ 26821495Sjmacd#define BCTV_GR0_AUDIO_BOTH 1 /* main(L) + sub(R) */ 26921495Sjmacd#define BCTV_GR0_AUDIO_MUTE 4 /* audio mute */ 27021495Sjmacd#define BCTV_GR0_AUDIO_MONO 8 /* force mono */ 27121495Sjmacd 27221495Sjmacdvoid 27321495Sjmacdset_bctv_audio( bktr_ptr_t bktr ) 27421495Sjmacd{ 27521495Sjmacd int data; 27621495Sjmacd 27721495Sjmacd switch (bktr->audio_mux_select) { 27821495Sjmacd case 1: /* external */ 27921495Sjmacd case 2: /* internal */ 28021495Sjmacd bctv_gpio_write(bktr, BCTV_GPIO_REG1, 0); 28121495Sjmacd break; 28221495Sjmacd default: /* tuner */ 28321495Sjmacd bctv_gpio_write(bktr, BCTV_GPIO_REG1, 1); 28421495Sjmacd break; 28521495Sjmacd } 28621495Sjmacd/* switch (bktr->audio_sap_select) { */ 28742660Smarkm switch (BCTV_AUDIO_BOTH) { 28821495Sjmacd case BCTV_AUDIO_SUB: 28921495Sjmacd data = BCTV_GR0_AUDIO_SUB; 29042660Smarkm break; 29142660Smarkm case BCTV_AUDIO_BOTH: 29242660Smarkm data = BCTV_GR0_AUDIO_BOTH; 29342660Smarkm break; 29442660Smarkm case BCTV_AUDIO_MAIN: 29542660Smarkm default: 29621495Sjmacd data = BCTV_GR0_AUDIO_MAIN; 29721495Sjmacd break; 29821495Sjmacd } 29921495Sjmacd if (bktr->audio_mute_state == TRUE) 30021495Sjmacd data |= BCTV_GR0_AUDIO_MUTE; 30156160Sru 30221495Sjmacd bctv_gpio_write(bktr, BCTV_GPIO_REG0, data); 30321495Sjmacd 30421495Sjmacd return; 30521495Sjmacd} 30621495Sjmacd 30721495Sjmacd/* gpio_data bit assignment */ 30821495Sjmacd#define BCTV_GPIO_ADDR_MASK 0x000300 30921495Sjmacd#define BCTV_GPIO_WE 0x000400 31021495Sjmacd#define BCTV_GPIO_OE 0x000800 31121495Sjmacd#define BCTV_GPIO_VAL_MASK 0x00f000 31221495Sjmacd 31321495Sjmacd#define BCTV_GPIO_PORT_MASK 3 31421495Sjmacd#define BCTV_GPIO_ADDR_SHIFT 8 31521495Sjmacd#define BCTV_GPIO_VAL_SHIFT 12 31621495Sjmacd 31721495Sjmacd/* gpio_out_en value for read/write */ 31821495Sjmacd#define BCTV_GPIO_OUT_RMASK 0x000f00 31921495Sjmacd#define BCTV_GPIO_OUT_WMASK 0x00ff00 32021495Sjmacd 32121495Sjmacd#define BCTV_BITS 100 32221495Sjmacd 32321495Sjmacdvoid 32421495Sjmacdbctv_gpio_write( bktr_ptr_t bktr, int port, int val ) 32521495Sjmacd{ 32621495Sjmacd bt848_ptr_t bt848 = bktr->base; 32721495Sjmacd u_long data, outbits; 32821495Sjmacd 32921495Sjmacd port &= BCTV_GPIO_PORT_MASK; 33021495Sjmacd switch (port) { 33121495Sjmacd case 1: 33221495Sjmacd case 3: 33321495Sjmacd data = ((val << BCTV_GPIO_VAL_SHIFT) & BCTV_GPIO_VAL_MASK) | 33421495Sjmacd ((port << BCTV_GPIO_ADDR_SHIFT) & BCTV_GPIO_ADDR_MASK) | 33521495Sjmacd BCTV_GPIO_WE | BCTV_GPIO_OE; 33621495Sjmacd outbits = BCTV_GPIO_OUT_WMASK; 33721495Sjmacd break; 33842660Smarkm default: 33921495Sjmacd return; 34021495Sjmacd } 34121495Sjmacd bt848->gpio_out_en = 0; 34221495Sjmacd 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