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