bktr_audio.c revision 52593
151694Sroger/* $FreeBSD: head/sys/dev/bktr/bktr_audio.c 52593 1999-10-28 13:58:17Z roger $ */
251694Sroger/*
351694Sroger * This is part of the Driver for Video Capture Cards (Frame grabbers)
451694Sroger * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
551694Sroger * chipset.
651694Sroger * Copyright Roger Hardiman and Amancio Hasty.
751694Sroger *
851694Sroger * bktr_audio : This deals with controlling the audio on TV cards,
951694Sroger *                controlling the Audio Multiplexer (audio source selector).
1051694Sroger *                controlling any MSP34xx stereo audio decoders.
1152593Sroger *                controlling any DPL35xx dolby surroud sound audio decoders.
1251694Sroger *                initialising TDA98xx audio devices.
1351694Sroger *
1451694Sroger */
1551694Sroger
1651694Sroger/*
1751694Sroger * 1. Redistributions of source code must retain the
1851694Sroger * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
1951694Sroger * All rights reserved.
2051694Sroger *
2151694Sroger * Redistribution and use in source and binary forms, with or without
2251694Sroger * modification, are permitted provided that the following conditions
2351694Sroger * are met:
2451694Sroger * 1. Redistributions of source code must retain the above copyright
2551694Sroger *    notice, this list of conditions and the following disclaimer.
2651694Sroger * 2. Redistributions in binary form must reproduce the above copyright
2751694Sroger *    notice, this list of conditions and the following disclaimer in the
2851694Sroger *    documentation and/or other materials provided with the distribution.
2951694Sroger * 3. All advertising materials mentioning features or use of this software
3051694Sroger *    must display the following acknowledgement:
3151694Sroger *      This product includes software developed by Amancio Hasty and
3251694Sroger *      Roger Hardiman
3351694Sroger * 4. The name of the author may not be used to endorse or promote products
3451694Sroger *    derived from this software without specific prior written permission.
3551694Sroger *
3651694Sroger * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
3751694Sroger * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3851694Sroger * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3951694Sroger * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
4051694Sroger * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
4151694Sroger * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
4251694Sroger * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4351694Sroger * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4451694Sroger * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
4551694Sroger * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4651694Sroger * POSSIBILITY OF SUCH DAMAGE.
4751694Sroger */
4851694Sroger
4951694Sroger#include <sys/param.h>
5051694Sroger#include <sys/systm.h>
5151694Sroger#include <sys/kernel.h>
5251694Sroger#include <sys/vnode.h>
5351694Sroger
5451694Sroger#include <machine/clock.h>		/* for DELAY */
5551694Sroger
5651694Sroger#include <pci/pcivar.h>
5751694Sroger
5851694Sroger#include <machine/ioctl_meteor.h>
5951694Sroger#include <machine/ioctl_bt848.h>        /* extensions to ioctl_meteor.h */
6051694Sroger#include <dev/bktr/bktr_reg.h>
6151694Sroger#include <dev/bktr/bktr_core.h>
6251694Sroger#include <dev/bktr/bktr_tuner.h>
6351694Sroger#include <dev/bktr/bktr_card.h>
6451694Sroger#include <dev/bktr/bktr_audio.h>
6551694Sroger
6651694Sroger
6751694Sroger/*
6851694Sroger * Prototypes for the GV_BCTV specific functions.
6951694Sroger */
7051694Srogervoid    set_bctv_audio( bktr_ptr_t bktr );
7151694Srogervoid    bctv_gpio_write( bktr_ptr_t bktr, int port, int val );
7251694Sroger/*int   bctv_gpio_read( bktr_ptr_t bktr, int port );*/ /* Not used */
7351694Sroger
7451694Sroger
7551694Sroger
7651694Sroger/*
7751694Sroger * init_audio_devices
7851694Sroger * Reset any MSP34xx or TDA98xx audio devices.
7951694Sroger */
8051694Srogervoid init_audio_devices( bktr_ptr_t bktr ) {
8151694Sroger
8251694Sroger        /* enable stereo if appropriate on TDA audio chip */
8351694Sroger        if ( bktr->card.dbx )
8451694Sroger                init_BTSC( bktr );
8551694Sroger
8651694Sroger        /* reset the MSP34xx stereo audio chip */
8751694Sroger        if ( bktr->card.msp3400c )
8852593Sroger                msp_dpl_reset( bktr, bktr->msp_addr );
8951694Sroger
9052593Sroger        /* reset the DPL35xx dolby audio chip */
9152593Sroger        if ( bktr->card.dpl3518a )
9252593Sroger                msp_dpl_reset( bktr, bktr->dpl_addr );
9352593Sroger
9451694Sroger}
9551694Sroger
9651694Sroger
9751694Sroger/*
9851694Sroger *
9951694Sroger */
10051694Sroger#define AUDIOMUX_DISCOVER_NOT
10151694Srogerint
10251694Srogerset_audio( bktr_ptr_t bktr, int cmd )
10351694Sroger{
10451694Sroger	bt848_ptr_t	bt848;
10551694Sroger	u_long		temp;
10651694Sroger	volatile u_char	idx;
10751694Sroger
10851694Sroger#if defined( AUDIOMUX_DISCOVER )
10951694Sroger	if ( cmd >= 200 )
11051694Sroger		cmd -= 200;
11151694Sroger	else
11251694Sroger#endif /* AUDIOMUX_DISCOVER */
11351694Sroger
11451694Sroger	/* check for existance of audio MUXes */
11551694Sroger	if ( !bktr->card.audiomuxs[ 4 ] )
11651694Sroger		return( -1 );
11751694Sroger
11851694Sroger	switch (cmd) {
11951694Sroger	case AUDIO_TUNER:
12051694Sroger#ifdef BKTR_REVERSEMUTE
12151694Sroger		bktr->audio_mux_select = 3;
12251694Sroger#else
12351694Sroger		bktr->audio_mux_select = 0;
12451694Sroger#endif
12551694Sroger
12651694Sroger		if (bktr->reverse_mute )
12751694Sroger		      bktr->audio_mux_select = 0;
12851694Sroger		else
12951694Sroger		    bktr->audio_mux_select = 3;
13051694Sroger
13151694Sroger		break;
13251694Sroger	case AUDIO_EXTERN:
13351694Sroger		bktr->audio_mux_select = 1;
13451694Sroger		break;
13551694Sroger	case AUDIO_INTERN:
13651694Sroger		bktr->audio_mux_select = 2;
13751694Sroger		break;
13851694Sroger	case AUDIO_MUTE:
13951694Sroger		bktr->audio_mute_state = TRUE;	/* set mute */
14051694Sroger		break;
14151694Sroger	case AUDIO_UNMUTE:
14251694Sroger		bktr->audio_mute_state = FALSE;	/* clear mute */
14351694Sroger		break;
14451694Sroger	default:
14551694Sroger		printf("bktr: audio cmd error %02x\n", cmd);
14651694Sroger		return( -1 );
14751694Sroger	}
14851694Sroger
14951694Sroger
15051694Sroger	/* Most cards have a simple audio multiplexer to select the
15151694Sroger	 * audio source. The I/O_GV card has a more advanced multiplexer
15251694Sroger	 * and requires special handling.
15351694Sroger	 */
15451694Sroger        if ( bktr->bt848_card == CARD_IO_GV ) {
15551694Sroger                set_bctv_audio( bktr );
15651694Sroger                return( 0 );
15751694Sroger	}
15851694Sroger
15951694Sroger	/* Proceed with the simpler audio multiplexer code for the majority
16051694Sroger	 * of Bt848 cards.
16151694Sroger	 */
16251694Sroger
16351694Sroger	bt848 =	bktr->base;
16451694Sroger
16551694Sroger	/*
16651694Sroger	 * Leave the upper bits of the GPIO port alone in case they control
16751694Sroger	 * something like the dbx or teletext chips.  This doesn't guarantee
16851694Sroger	 * success, but follows the rule of least astonishment.
16951694Sroger	 */
17051694Sroger
17151694Sroger	if ( bktr->audio_mute_state == TRUE ) {
17251694Sroger#ifdef BKTR_REVERSEMUTE
17351694Sroger		idx = 0;
17451694Sroger#else
17551694Sroger		idx = 3;
17651694Sroger#endif
17751694Sroger
17851694Sroger		if (bktr->reverse_mute )
17951694Sroger		  idx  = 3;
18051694Sroger		else
18151694Sroger		  idx  = 0;
18251694Sroger
18351694Sroger	}
18451694Sroger	else
18551694Sroger		idx = bktr->audio_mux_select;
18651694Sroger
18751694Sroger	temp = bt848->gpio_data & ~bktr->card.gpio_mux_bits;
18851694Sroger	bt848->gpio_data =
18951694Sroger#if defined( AUDIOMUX_DISCOVER )
19051694Sroger		bt848->gpio_data = temp | (cmd & 0xff);
19151694Sroger		printf("cmd: %d audio mux %x temp %x \n", cmd,bktr->card.audiomuxs[ idx ], temp );
19251694Sroger#else
19351694Sroger		temp | bktr->card.audiomuxs[ idx ];
19451694Sroger#endif /* AUDIOMUX_DISCOVER */
19551694Sroger
19651694Sroger	return( 0 );
19751694Sroger}
19851694Sroger
19951694Sroger
20051694Sroger/*
20151694Sroger *
20251694Sroger */
20351694Srogervoid
20451694Srogertemp_mute( bktr_ptr_t bktr, int flag )
20551694Sroger{
20651694Sroger	static int	muteState = FALSE;
20751694Sroger
20851694Sroger	if ( flag == TRUE ) {
20951694Sroger		muteState = bktr->audio_mute_state;
21051694Sroger		set_audio( bktr, AUDIO_MUTE );		/* prevent 'click' */
21151694Sroger	}
21251694Sroger	else {
21351694Sroger		tsleep( BKTR_SLEEP, PZERO, "tuning", hz/8 );
21451694Sroger		if ( muteState == FALSE )
21551694Sroger			set_audio( bktr, AUDIO_UNMUTE );
21651694Sroger	}
21751694Sroger}
21851694Sroger
21951694Sroger/* address of BTSC/SAP decoder chip */
22051694Sroger#define TDA9850_WADDR           0xb6
22151694Sroger#define TDA9850_RADDR           0xb7
22251694Sroger
22351694Sroger
22451694Sroger/* registers in the TDA9850 BTSC/dbx chip */
22551694Sroger#define CON1ADDR                0x04
22651694Sroger#define CON2ADDR                0x05
22751694Sroger#define CON3ADDR                0x06
22851694Sroger#define CON4ADDR                0x07
22951694Sroger#define ALI1ADDR                0x08
23051694Sroger#define ALI2ADDR                0x09
23151694Sroger#define ALI3ADDR                0x0a
23251694Sroger
23351694Sroger/*
23451694Sroger * initialise the dbx chip
23551694Sroger * taken from the Linux bttv driver TDA9850 initialisation code
23651694Sroger */
23751694Srogervoid
23851694Srogerinit_BTSC( bktr_ptr_t bktr )
23951694Sroger{
24051694Sroger    i2cWrite(bktr, TDA9850_WADDR, CON1ADDR, 0x08); /* noise threshold st */
24151694Sroger    i2cWrite(bktr, TDA9850_WADDR, CON2ADDR, 0x08); /* noise threshold sap */
24251694Sroger    i2cWrite(bktr, TDA9850_WADDR, CON3ADDR, 0x40); /* stereo mode */
24351694Sroger    i2cWrite(bktr, TDA9850_WADDR, CON4ADDR, 0x07); /* 0 dB input gain? */
24451694Sroger    i2cWrite(bktr, TDA9850_WADDR, ALI1ADDR, 0x10); /* wideband alignment? */
24551694Sroger    i2cWrite(bktr, TDA9850_WADDR, ALI2ADDR, 0x10); /* spectral alignment? */
24651694Sroger    i2cWrite(bktr, TDA9850_WADDR, ALI3ADDR, 0x03);
24751694Sroger}
24851694Sroger
24951694Sroger/*
25051694Sroger * setup the dbx chip
25151694Sroger * XXX FIXME: alot of work to be done here, this merely unmutes it.
25251694Sroger */
25351694Srogerint
25451694Srogerset_BTSC( bktr_ptr_t bktr, int control )
25551694Sroger{
25651694Sroger	return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) );
25751694Sroger}
25851694Sroger
25951694Sroger/*
26051694Sroger * CARD_GV_BCTV specific functions.
26151694Sroger */
26251694Sroger
26351694Sroger#define BCTV_AUDIO_MAIN              0x10    /* main audio program */
26451694Sroger#define BCTV_AUDIO_SUB               0x20    /* sub audio program */
26551694Sroger#define BCTV_AUDIO_BOTH              0x30    /* main(L) + sub(R) program */
26651694Sroger
26751694Sroger#define BCTV_GPIO_REG0          1
26851694Sroger#define BCTV_GPIO_REG1          3
26951694Sroger
27051694Sroger#define BCTV_GR0_AUDIO_MODE     3
27151694Sroger#define BCTV_GR0_AUDIO_MAIN     0       /* main program */
27251694Sroger#define BCTV_GR0_AUDIO_SUB      3       /* sub program */
27351694Sroger#define BCTV_GR0_AUDIO_BOTH     1       /* main(L) + sub(R) */
27451694Sroger#define BCTV_GR0_AUDIO_MUTE     4       /* audio mute */
27551694Sroger#define BCTV_GR0_AUDIO_MONO     8       /* force mono */
27651694Sroger
27751694Srogervoid
27851694Srogerset_bctv_audio( bktr_ptr_t bktr )
27951694Sroger{
28051694Sroger        int data;
28151694Sroger
28251694Sroger        switch (bktr->audio_mux_select) {
28351694Sroger        case 1:         /* external */
28451694Sroger        case 2:         /* internal */
28551694Sroger                bctv_gpio_write(bktr, BCTV_GPIO_REG1, 0);
28651694Sroger                break;
28751694Sroger        default:        /* tuner */
28851694Sroger                bctv_gpio_write(bktr, BCTV_GPIO_REG1, 1);
28951694Sroger                break;
29051694Sroger        }
29151694Sroger/*      switch (bktr->audio_sap_select) { */
29251694Sroger        switch (BCTV_AUDIO_BOTH) {
29351694Sroger        case BCTV_AUDIO_SUB:
29451694Sroger                data = BCTV_GR0_AUDIO_SUB;
29551694Sroger                break;
29651694Sroger        case BCTV_AUDIO_BOTH:
29751694Sroger                data = BCTV_GR0_AUDIO_BOTH;
29851694Sroger                break;
29951694Sroger        case BCTV_AUDIO_MAIN:
30051694Sroger        default:
30151694Sroger                data = BCTV_GR0_AUDIO_MAIN;
30251694Sroger                break;
30351694Sroger        }
30451694Sroger        if (bktr->audio_mute_state == TRUE)
30551694Sroger                data |= BCTV_GR0_AUDIO_MUTE;
30651694Sroger
30751694Sroger        bctv_gpio_write(bktr, BCTV_GPIO_REG0, data);
30851694Sroger
30951694Sroger        return;
31051694Sroger}
31151694Sroger
31251694Sroger/* gpio_data bit assignment */
31351694Sroger#define BCTV_GPIO_ADDR_MASK     0x000300
31451694Sroger#define BCTV_GPIO_WE            0x000400
31551694Sroger#define BCTV_GPIO_OE            0x000800
31651694Sroger#define BCTV_GPIO_VAL_MASK      0x00f000
31751694Sroger
31851694Sroger#define BCTV_GPIO_PORT_MASK     3
31951694Sroger#define BCTV_GPIO_ADDR_SHIFT    8
32051694Sroger#define BCTV_GPIO_VAL_SHIFT     12
32151694Sroger
32251694Sroger/* gpio_out_en value for read/write */
32351694Sroger#define BCTV_GPIO_OUT_RMASK     0x000f00
32451694Sroger#define BCTV_GPIO_OUT_WMASK     0x00ff00
32551694Sroger
32651694Sroger#define BCTV_BITS       100
32751694Sroger
32851694Srogervoid
32951694Srogerbctv_gpio_write( bktr_ptr_t bktr, int port, int val )
33051694Sroger{
33151694Sroger        bt848_ptr_t bt848 = bktr->base;
33251694Sroger        u_long data, outbits;
33351694Sroger
33451694Sroger        port &= BCTV_GPIO_PORT_MASK;
33551694Sroger        switch (port) {
33651694Sroger        case 1:
33751694Sroger        case 3:
33851694Sroger                data = ((val << BCTV_GPIO_VAL_SHIFT) & BCTV_GPIO_VAL_MASK) |
33951694Sroger                       ((port << BCTV_GPIO_ADDR_SHIFT) & BCTV_GPIO_ADDR_MASK) |
34051694Sroger                       BCTV_GPIO_WE | BCTV_GPIO_OE;
34151694Sroger                outbits = BCTV_GPIO_OUT_WMASK;
34251694Sroger                break;
34351694Sroger        default:
34451694Sroger                return;
34551694Sroger        }
34651694Sroger        bt848->gpio_out_en = 0;
34751694Sroger        bt848->gpio_data = data;
34851694Sroger        bt848->gpio_out_en = outbits;
34951694Sroger        DELAY(BCTV_BITS);
35051694Sroger        bt848->gpio_data = data & ~BCTV_GPIO_WE;
35151694Sroger        DELAY(BCTV_BITS);
35251694Sroger        bt848->gpio_data = data;
35351694Sroger        DELAY(BCTV_BITS);
35451694Sroger        bt848->gpio_data = ~0;
35551694Sroger        bt848->gpio_out_en = 0;
35651694Sroger}
35751694Sroger
35851694Sroger/* Not yet used
35951694Srogerint
36051694Srogerbctv_gpio_read( bktr_ptr_t bktr, int port )
36151694Sroger{
36251694Sroger        bt848_ptr_t bt848 = bktr->base;
36351694Sroger        u_long data, outbits, ret;
36451694Sroger
36551694Sroger        port &= BCTV_GPIO_PORT_MASK;
36651694Sroger        switch (port) {
36751694Sroger        case 1:
36851694Sroger        case 3:
36951694Sroger                data = ((port << BCTV_GPIO_ADDR_SHIFT) & BCTV_GPIO_ADDR_MASK) |
37051694Sroger                       BCTV_GPIO_WE | BCTV_GPIO_OE;
37151694Sroger                outbits = BCTV_GPIO_OUT_RMASK;
37251694Sroger                break;
37351694Sroger        default:
37451694Sroger                return( -1 );
37551694Sroger        }
37651694Sroger        bt848->gpio_out_en = 0;
37751694Sroger        bt848->gpio_data = data;
37851694Sroger        bt848->gpio_out_en = outbits;
37951694Sroger        DELAY(BCTV_BITS);
38051694Sroger        bt848->gpio_data = data & ~BCTV_GPIO_OE;
38151694Sroger        DELAY(BCTV_BITS);
38251694Sroger        ret = bt848->gpio_data;
38351694Sroger        DELAY(BCTV_BITS);
38451694Sroger        bt848->gpio_data = data;
38551694Sroger        DELAY(BCTV_BITS);
38651694Sroger        bt848->gpio_data = ~0;
38751694Sroger        bt848->gpio_out_en = 0;
38851694Sroger        return( (ret & BCTV_GPIO_VAL_MASK) >> BCTV_GPIO_VAL_SHIFT );
38951694Sroger}
39051694Sroger*/
39151694Sroger
39251694Sroger/*
39351694Sroger * setup the MSP34xx Stereo Audio Chip
39451694Sroger * This uses the Auto Configuration Option on MSP3410D and MSP3415D chips
39551694Sroger * and DBX mode selection for MSP3430G chips.
39651694Sroger * For MSP3400C support, the full programming sequence is required and is
39751694Sroger * not yet supported.
39851694Sroger */
39951694Sroger
40051694Sroger/* Read the MSP version string */
40151694Srogervoid msp_read_id( bktr_ptr_t bktr ){
40251694Sroger    int rev1=0, rev2=0;
40352593Sroger    rev1 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001e);
40452593Sroger    rev2 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001f);
40551694Sroger
40651694Sroger    sprintf(bktr->msp_version_string, "34%02d%c-%c%d",
40751694Sroger      (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
40851694Sroger
40951694Sroger}
41051694Sroger
41151694Sroger
41251694Sroger/* Configure the MSP chip to Auto-detect the audio format */
41351694Srogervoid msp_autodetect( bktr_ptr_t bktr ) {
41451694Sroger
41551694Sroger  if (strncmp("3430G", bktr->msp_version_string, 5) == 0){
41651694Sroger
41751694Sroger    /* For MSP3430G - countries with mono and DBX stereo */
41852593Sroger    msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0030,0x2003);/* Enable Auto format detection */
41952593Sroger    msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0020);/* Standard Select Reg. = BTSC-Stereo*/
42052593Sroger    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000E,0x2403);/* darned if I know */
42152593Sroger    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0320);/* Source select = (St or A) */
42251694Sroger					 /*   & Ch. Matrix = St */
42352593Sroger    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
42451694Sroger
42551694Sroger  } else {
42651694Sroger
42751694Sroger    /* For MSP3410 / 3415 - countries with mono, stereo using 2 FM channels
42851694Sroger       and NICAM */
42952593Sroger    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
43052593Sroger    msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */
43152593Sroger    msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */
43251694Sroger  }
43351694Sroger
43451694Sroger  /* uncomment the following line to enable the MSP34xx 1Khz Tone Generator */
43551694Sroger  /* turn your speaker volume down low before trying this */
43652593Sroger  /* msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0014, 0x7f40); */
43751694Sroger}
43852593Sroger
43952593Sroger/* Read the DPL version string */
44052593Srogervoid dpl_read_id( bktr_ptr_t bktr ){
44152593Sroger    int rev1=0, rev2=0;
44252593Sroger    rev1 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001e);
44352593Sroger    rev2 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001f);
44452593Sroger
44552593Sroger    sprintf(bktr->dpl_version_string, "34%02d%c-%c%d",
44652593Sroger      ((rev2>>8)&0xff)-1, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
44752593Sroger}
44852593Sroger
44952593Sroger/* Configure the DPL chip to Auto-detect the audio format */
45052593Srogervoid dpl_autodetect( bktr_ptr_t bktr ) {
45152593Sroger
45252593Sroger    /* The following are empiric values tried from the DPL35xx data sheet */
45352593Sroger    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x000c,0x0320);	/* quasi peak detector source dolby
45452593Sroger								lr 0x03xx; quasi peak detector matrix
45552593Sroger								stereo 0xXX20 */
45652593Sroger    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0040,0x0060);	/* Surround decoder mode;
45752593Sroger								ADAPTIVE/3D-PANORAMA, that means two
45852593Sroger								speakers and no center speaker, all
45952593Sroger								channels L/R/C/S mixed to L and R */
46052593Sroger    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0041,0x0620);	/* surround source matrix;I2S2/STEREO*/
46152593Sroger    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0042,0x1F00);	/* surround delay 31ms max */
46252593Sroger    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0043,0x0000);	/* automatic surround input balance */
46352593Sroger    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0044,0x4000);	/* surround spatial effect 50%
46452593Sroger								recommended*/
46552593Sroger    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0045,0x5400);	/* surround panorama effect 66%
46652593Sroger								recommended with PANORAMA mode
46752593Sroger								in 0x0040 set to panorama */
46852593Sroger}
46952593Sroger
470