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