[BACK]Return to bktr_audio.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci / bktr

Annotation of sys/dev/pci/bktr/bktr_audio.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: bktr_audio.c,v 1.9 2007/06/11 08:10:22 robert Exp $   */
                      2: /* $FreeBSD: src/sys/dev/bktr/bktr_audio.c,v 1.8 2000/10/31 13:09:56 roger Exp $ */
                      3: /*
                      4:  * This is part of the Driver for Video Capture Cards (Frame grabbers)
                      5:  * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
                      6:  * chipset.
                      7:  * Copyright Roger Hardiman and Amancio Hasty.
                      8:  *
                      9:  * bktr_audio : This deals with controlling the audio on TV cards,
                     10:  *                controlling the Audio Multiplexer (audio source selector).
                     11:  *                controlling any MSP34xx stereo audio decoders.
                     12:  *                controlling any DPL35xx dolby surround sound audio decoders.
                     13:  *                initialising TDA98xx audio devices.
                     14:  *
                     15:  */
                     16:
                     17: /*
                     18:  * 1. Redistributions of source code must retain the
                     19:  * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
                     20:  * All rights reserved.
                     21:  *
                     22:  * Redistribution and use in source and binary forms, with or without
                     23:  * modification, are permitted provided that the following conditions
                     24:  * are met:
                     25:  * 1. Redistributions of source code must retain the above copyright
                     26:  *    notice, this list of conditions and the following disclaimer.
                     27:  * 2. Redistributions in binary form must reproduce the above copyright
                     28:  *    notice, this list of conditions and the following disclaimer in the
                     29:  *    documentation and/or other materials provided with the distribution.
                     30:  * 3. All advertising materials mentioning features or use of this software
                     31:  *    must display the following acknowledgement:
                     32:  *      This product includes software developed by Amancio Hasty and
                     33:  *      Roger Hardiman
                     34:  * 4. The name of the author may not be used to endorse or promote products
                     35:  *    derived from this software without specific prior written permission.
                     36:  *
                     37:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     38:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     39:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     40:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     41:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     42:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     43:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     44:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     45:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     46:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     47:  * POSSIBILITY OF SUCH DAMAGE.
                     48:  */
                     49:
                     50: #include <sys/param.h>
                     51: #include <sys/systm.h>
                     52: #include <sys/kernel.h>
                     53: #include <sys/vnode.h>
                     54: #include <sys/proc.h>
                     55:
                     56: #include <dev/ic/bt8xx.h>      /* OpenBSD location of .h files */
                     57: #include <dev/pci/bktr/bktr_reg.h>
                     58: #include <dev/pci/bktr/bktr_core.h>
                     59: #include <dev/pci/bktr/bktr_tuner.h>
                     60: #include <dev/pci/bktr/bktr_card.h>
                     61: #include <dev/pci/bktr/bktr_audio.h>
                     62:
                     63: /*
                     64:  * Prototypes for the GV_BCTV specific functions.
                     65:  */
                     66: void    set_bctv_audio( bktr_ptr_t bktr );
                     67: void    bctv_gpio_write( bktr_ptr_t bktr, int port, int val );
                     68: /*int   bctv_gpio_read( bktr_ptr_t bktr, int port );*/ /* Not used */
                     69:
                     70:
                     71:
                     72: /*
                     73:  * init_audio_devices
                     74:  * Reset any MSP34xx or TDA98xx audio devices.
                     75:  */
                     76: void init_audio_devices( bktr_ptr_t bktr ) {
                     77:
                     78:         /* enable stereo if appropriate on TDA audio chip */
                     79:         if ( bktr->card.dbx )
                     80:                 init_BTSC( bktr );
                     81:
                     82:         /* reset the MSP34xx stereo audio chip */
                     83:         if ( bktr->card.msp3400c )
                     84:                 msp_dpl_reset( bktr, bktr->msp_addr );
                     85:
                     86:         /* reset the DPL35xx dolby audio chip */
                     87:         if ( bktr->card.dpl3518a )
                     88:                 msp_dpl_reset( bktr, bktr->dpl_addr );
                     89:
                     90: }
                     91:
                     92:
                     93: /*
                     94:  *
                     95:  */
                     96: #define AUDIOMUX_DISCOVER_NOT
                     97: int
                     98: set_audio( bktr_ptr_t bktr, int cmd )
                     99: {
                    100:        u_int           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("%s: audio cmd error %02x\n", bktr_name(bktr),
                    141:                       cmd);
                    142:                return( -1 );
                    143:        }
                    144:
                    145:
                    146:        /* Most cards have a simple audio multiplexer to select the
                    147:         * audio source. The I/O_GV card has a more advanced multiplexer
                    148:         * and requires special handling.
                    149:         */
                    150:         if ( bktr->bt848_card == CARD_IO_GV ) {
                    151:                 set_bctv_audio( bktr );
                    152:                 return( 0 );
                    153:        }
                    154:
                    155:        /* Proceed with the simpler audio multiplexer code for the majority
                    156:         * of Bt848 cards.
                    157:         */
                    158:
                    159:        /*
                    160:         * Leave the upper bits of the GPIO port alone in case they control
                    161:         * something like the dbx or teletext chips.  This doesn't guarantee
                    162:         * success, but follows the rule of least astonishment.
                    163:         */
                    164:
                    165:        if ( bktr->audio_mute_state == TRUE ) {
                    166: #ifdef BKTR_REVERSEMUTE
                    167:                idx = 0;
                    168: #else
                    169:                idx = 3;
                    170: #endif
                    171:
                    172:                if (bktr->reverse_mute )
                    173:                  idx  = 3;
                    174:                else
                    175:                  idx  = 0;
                    176:
                    177:        }
                    178:        else
                    179:                idx = bktr->audio_mux_select;
                    180:
                    181:
                    182:        temp = INL(bktr, BKTR_GPIO_DATA) & ~bktr->card.gpio_mux_bits;
                    183: #if defined( AUDIOMUX_DISCOVER )
                    184:        OUTL(bktr, BKTR_GPIO_DATA, temp | (cmd & 0xff));
                    185:        printf("%s: cmd: %d audio mux %x temp %x \n", bktr_name(bktr),
                    186:                cmd, bktr->card.audiomuxs[ idx ], temp );
                    187: #else
                    188:        OUTL(bktr, BKTR_GPIO_DATA, temp | bktr->card.audiomuxs[ idx ]);
                    189: #endif /* AUDIOMUX_DISCOVER */
                    190:
                    191:
                    192:
                    193:        /* Some new Hauppauge cards do not have an audio mux */
                    194:        /* Instead we use the MSP34xx chip to select TV audio, Line-In */
                    195:        /* FM Radio and Mute */
                    196:        /* Examples of this are the Hauppauge 44xxx MSP34xx models */
                    197:        /* It is ok to drive both the mux and the MSP34xx chip. */
                    198:        /* If there is no mux, the MSP does the switching of the audio source */
                    199:        /* If there is a mux, it does the switching of the audio source */
                    200:
                    201:        if ((bktr->card.msp3400c) && (bktr->audio_mux_present == 0)) {
                    202:
                    203:          if (bktr->audio_mute_state == TRUE ) {
                    204:                 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x0000); /* volume to MUTE */
                    205:          } else {
                    206:                 if(bktr->audio_mux_select == 0) { /* TV Tuner */
                    207:                    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
                    208:                    if (bktr->msp_source_selected != 0) msp_autodetect(bktr);  /* setup TV audio mode */
                    209:                    bktr->msp_source_selected = 0;
                    210:                 }
                    211:                 if(bktr->audio_mux_select == 1) { /* Line In */
                    212:                    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
                    213:                    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */
                    214:                    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */
                    215:                    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0000); /* DSP In = SC1_IN_L/R */
                    216:                    bktr->msp_source_selected = 1;
                    217:                 }
                    218:
                    219:                 if(bktr->audio_mux_select == 2) { /* FM Radio */
                    220:                    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
                    221:                    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */
                    222:                    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */
                    223:                    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0200); /* DSP In = SC2_IN_L/R */
                    224:                    bktr->msp_source_selected = 2;
                    225:                 }
                    226:          }
                    227:        }
                    228:
                    229:
                    230:        return( 0 );
                    231: }
                    232:
                    233:
                    234: /*
                    235:  *
                    236:  */
                    237: void
                    238: temp_mute( bktr_ptr_t bktr, int flag )
                    239: {
                    240:        static int      muteState = FALSE;
                    241:
                    242:        if ( flag == TRUE ) {
                    243:                muteState = bktr->audio_mute_state;
                    244:                set_audio( bktr, AUDIO_MUTE );          /* prevent 'click' */
                    245:        }
                    246:        else {
                    247:                tsleep( BKTR_SLEEP, PZERO, "tuning", hz/8 );
                    248:                if ( muteState == FALSE )
                    249:                        set_audio( bktr, AUDIO_UNMUTE );
                    250:        }
                    251: }
                    252:
                    253: /* address of BTSC/SAP decoder chip */
                    254: #define TDA9850_WADDR           0xb6
                    255: #define TDA9850_RADDR           0xb7
                    256:
                    257:
                    258: /* registers in the TDA9850 BTSC/dbx chip */
                    259: #define CON1ADDR                0x04
                    260: #define CON2ADDR                0x05
                    261: #define CON3ADDR                0x06
                    262: #define CON4ADDR                0x07
                    263: #define ALI1ADDR                0x08
                    264: #define ALI2ADDR                0x09
                    265: #define ALI3ADDR                0x0a
                    266:
                    267: /*
                    268:  * initialise the dbx chip
                    269:  * taken from the Linux bttv driver TDA9850 initialisation code
                    270:  */
                    271: void
                    272: init_BTSC( bktr_ptr_t bktr )
                    273: {
                    274:     i2cWrite(bktr, TDA9850_WADDR, CON1ADDR, 0x08); /* noise threshold st */
                    275:     i2cWrite(bktr, TDA9850_WADDR, CON2ADDR, 0x08); /* noise threshold sap */
                    276:     i2cWrite(bktr, TDA9850_WADDR, CON3ADDR, 0x40); /* stereo mode */
                    277:     i2cWrite(bktr, TDA9850_WADDR, CON4ADDR, 0x07); /* 0 dB input gain? */
                    278:     i2cWrite(bktr, TDA9850_WADDR, ALI1ADDR, 0x10); /* wideband alignment? */
                    279:     i2cWrite(bktr, TDA9850_WADDR, ALI2ADDR, 0x10); /* spectral alignment? */
                    280:     i2cWrite(bktr, TDA9850_WADDR, ALI3ADDR, 0x03);
                    281: }
                    282:
                    283: /*
                    284:  * setup the dbx chip
                    285:  * XXX FIXME: alot of work to be done here, this merely unmutes it.
                    286:  */
                    287: int
                    288: set_BTSC( bktr_ptr_t bktr, int control )
                    289: {
                    290:        return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) );
                    291: }
                    292:
                    293: /*
                    294:  * CARD_GV_BCTV specific functions.
                    295:  */
                    296:
                    297: #define BCTV_AUDIO_MAIN              0x10    /* main audio program */
                    298: #define BCTV_AUDIO_SUB               0x20    /* sub audio program */
                    299: #define BCTV_AUDIO_BOTH              0x30    /* main(L) + sub(R) program */
                    300:
                    301: #define BCTV_GPIO_REG0          1
                    302: #define BCTV_GPIO_REG1          3
                    303:
                    304: #define BCTV_GR0_AUDIO_MODE     3
                    305: #define BCTV_GR0_AUDIO_MAIN     0       /* main program */
                    306: #define BCTV_GR0_AUDIO_SUB      3       /* sub program */
                    307: #define BCTV_GR0_AUDIO_BOTH     1       /* main(L) + sub(R) */
                    308: #define BCTV_GR0_AUDIO_MUTE     4       /* audio mute */
                    309: #define BCTV_GR0_AUDIO_MONO     8       /* force mono */
                    310:
                    311: void
                    312: set_bctv_audio( bktr_ptr_t bktr )
                    313: {
                    314:         int data;
                    315:
                    316:         switch (bktr->audio_mux_select) {
                    317:         case 1:         /* external */
                    318:         case 2:         /* internal */
                    319:                 bctv_gpio_write(bktr, BCTV_GPIO_REG1, 0);
                    320:                 break;
                    321:         default:        /* tuner */
                    322:                 bctv_gpio_write(bktr, BCTV_GPIO_REG1, 1);
                    323:                 break;
                    324:         }
                    325: /*      switch (bktr->audio_sap_select) { */
                    326:         switch (BCTV_AUDIO_BOTH) {
                    327:         case BCTV_AUDIO_SUB:
                    328:                 data = BCTV_GR0_AUDIO_SUB;
                    329:                 break;
                    330:         case BCTV_AUDIO_BOTH:
                    331:                 data = BCTV_GR0_AUDIO_BOTH;
                    332:                 break;
                    333:         case BCTV_AUDIO_MAIN:
                    334:         default:
                    335:                 data = BCTV_GR0_AUDIO_MAIN;
                    336:                 break;
                    337:         }
                    338:         if (bktr->audio_mute_state == TRUE)
                    339:                 data |= BCTV_GR0_AUDIO_MUTE;
                    340:
                    341:         bctv_gpio_write(bktr, BCTV_GPIO_REG0, data);
                    342:
                    343:         return;
                    344: }
                    345:
                    346: /* gpio_data bit assignment */
                    347: #define BCTV_GPIO_ADDR_MASK     0x000300
                    348: #define BCTV_GPIO_WE            0x000400
                    349: #define BCTV_GPIO_OE            0x000800
                    350: #define BCTV_GPIO_VAL_MASK      0x00f000
                    351:
                    352: #define BCTV_GPIO_PORT_MASK     3
                    353: #define BCTV_GPIO_ADDR_SHIFT    8
                    354: #define BCTV_GPIO_VAL_SHIFT     12
                    355:
                    356: /* gpio_out_en value for read/write */
                    357: #define BCTV_GPIO_OUT_RMASK     0x000f00
                    358: #define BCTV_GPIO_OUT_WMASK     0x00ff00
                    359:
                    360: #define BCTV_BITS       100
                    361:
                    362: void
                    363: bctv_gpio_write( bktr_ptr_t bktr, int port, int val )
                    364: {
                    365:         u_int data, outbits;
                    366:
                    367:         port &= BCTV_GPIO_PORT_MASK;
                    368:         switch (port) {
                    369:         case 1:
                    370:         case 3:
                    371:                 data = ((val << BCTV_GPIO_VAL_SHIFT) & BCTV_GPIO_VAL_MASK) |
                    372:                        ((port << BCTV_GPIO_ADDR_SHIFT) & BCTV_GPIO_ADDR_MASK) |
                    373:                        BCTV_GPIO_WE | BCTV_GPIO_OE;
                    374:                 outbits = BCTV_GPIO_OUT_WMASK;
                    375:                 break;
                    376:         default:
                    377:                 return;
                    378:         }
                    379:         OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
                    380:         OUTL(bktr, BKTR_GPIO_DATA, data);
                    381:         OUTL(bktr, BKTR_GPIO_OUT_EN, outbits);
                    382:         DELAY(BCTV_BITS);
                    383:         OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV_GPIO_WE);
                    384:         DELAY(BCTV_BITS);
                    385:         OUTL(bktr, BKTR_GPIO_DATA, data);
                    386:         DELAY(BCTV_BITS);
                    387:         OUTL(bktr, BKTR_GPIO_DATA, ~0);
                    388:         OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
                    389: }
                    390:
                    391: /* Not yet used
                    392: int
                    393: bctv_gpio_read( bktr_ptr_t bktr, int port )
                    394: {
                    395:         u_int data, outbits, ret;
                    396:
                    397:         port &= BCTV_GPIO_PORT_MASK;
                    398:         switch (port) {
                    399:         case 1:
                    400:         case 3:
                    401:                 data = ((port << BCTV_GPIO_ADDR_SHIFT) & BCTV_GPIO_ADDR_MASK) |
                    402:                        BCTV_GPIO_WE | BCTV_GPIO_OE;
                    403:                 outbits = BCTV_GPIO_OUT_RMASK;
                    404:                 break;
                    405:         default:
                    406:                 return( -1 );
                    407:         }
                    408:         OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
                    409:         OUTL(bktr, BKTR_GPIO_DATA, data);
                    410:         OUTL(bktr, BKTR_GPIO_OUT_EN, outbits);
                    411:         DELAY(BCTV_BITS);
                    412:         OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV_GPIO_OE);
                    413:         DELAY(BCTV_BITS);
                    414:         ret = INL(bktr, BKTR_GPIO_DATA);
                    415:         DELAY(BCTV_BITS);
                    416:         OUTL(bktr, BKTR_GPIO_DATA, data);
                    417:         DELAY(BCTV_BITS);
                    418:         OUTL(bktr, BKTR_GPIO_DATA, ~0);
                    419:         OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
                    420:         return( (ret & BCTV_GPIO_VAL_MASK) >> BCTV_GPIO_VAL_SHIFT );
                    421: }
                    422: */
                    423:
                    424: /*
                    425:  * setup the MSP34xx Stereo Audio Chip
                    426:  * This uses the Auto Configuration Option on MSP3410D and MSP3415D chips
                    427:  * and DBX mode selection for MSP3430G chips.
                    428:  * For MSP3400C support, the full programming sequence is required and is
                    429:  * not yet supported.
                    430:  */
                    431:
                    432: /* Read the MSP version string */
                    433: void msp_read_id( bktr_ptr_t bktr ){
                    434:     int rev1=0, rev2=0;
                    435:     rev1 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001e);
                    436:     rev2 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001f);
                    437:
                    438:     snprintf(bktr->msp_version_string, sizeof bktr->msp_version_string,
                    439:       "34%02d%c-%c%d", (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@',
                    440:       rev2&0x1f);
                    441:
                    442: }
                    443:
                    444:
                    445: /* Configure the MSP chip to Auto-detect the audio format.
                    446:  * For the MSP3430G, we use fast autodetect mode
                    447:  * For the MSP3410/3415 there are two schemes for this
                    448:  *  a) Fast autodetection - the chip is put into autodetect mode, and the function
                    449:  *     returns immediately. This works in most cases and is the Default Mode.
                    450:  *  b) Slow mode. The function sets the MSP3410/3415 chip, then waits for feedback from
                    451:  *     the chip and re-programs it if needed.
                    452:  */
                    453: void msp_autodetect( bktr_ptr_t bktr ) {
                    454:   int auto_detect, loops;
                    455:   int stereo;
                    456:
                    457:   /* MSP3430G - countries with mono and DBX stereo */
                    458:   if (strncmp("3430G", bktr->msp_version_string, 5) == 0 ||
                    459:       strncmp("3435G", bktr->msp_version_string, 5) == 0) {
                    460:
                    461:     msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0030,0x2003);/* Enable Auto format detection */
                    462:     msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0020);/* Standard Select Reg. = BTSC-Stereo*/
                    463:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000E,0x2403);/* darned if I know */
                    464:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0320);/* Source select = (St or A) */
                    465:                                                             /* & Ch. Matrix = St */
                    466:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
                    467:   }
                    468:
                    469:
                    470:   /* MSP3415D SPECIAL CASE Use the Tuner's Mono audio output for the MSP */
                    471:   /* (for Hauppauge 44xxx card with Tuner Type 0x2a) */
                    472:   else if (  ( (strncmp("3415D", bktr->msp_version_string, 5) == 0)
                    473:                &&(bktr->msp_use_mono_source == 1)
                    474:               )
                    475:            || (bktr->slow_msp_audio == 2) ){
                    476:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
                    477:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */
                    478:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */
                    479:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0100); /* DSP In = MONO IN */
                    480:   }
                    481:
                    482:
                    483:   /* MSP3410/MSP3415 - countries with mono, stereo using 2 FM channels and NICAM */
                    484:   /* FAST sound scheme */
                    485:   else if (bktr->slow_msp_audio == 0) {
                    486:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
                    487:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Spkr Source = default(FM/AM) */
                    488:     msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */
                    489:     msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */
                    490:   }
                    491:
                    492:
                    493:   /* MSP3410/MSP3415 - European Countries where the fast MSP3410/3415 programming fails */
                    494:   /* SLOW sound scheme */
                    495:   else if ( bktr->slow_msp_audio == 1) {
                    496:     msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
                    497:     msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */
                    498:
                    499:     /* wait for 0.5s max for terrestrial sound autodetection */
                    500:     loops = 10;
                    501:     do {
                    502:       DELAY(100000);
                    503:       auto_detect = msp_dpl_read(bktr, bktr->msp_addr, 0x10, 0x007e);
                    504:       loops++;
                    505:     } while (auto_detect > 0xff && loops < 50);
                    506:     if (bootverbose)printf ("%s: Result of autodetect after %dms: %d\n",
                    507:                            bktr_name(bktr), loops*10, auto_detect);
                    508:
                    509:     /* Now set the audio baseband processing */
                    510:     switch (auto_detect) {
                    511:     case 0:                    /* no TV sound standard detected */
                    512:       break;
                    513:     case 2:                    /* M Dual FM */
                    514:       break;
                    515:     case 3:                    /* B/G Dual FM; German stereo */
                    516:       /* Read the stereo detection value from DSP reg 0x0018 */
                    517:       DELAY(20000);
                    518:       stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
                    519:       if (bootverbose)printf ("%s: Stereo reg 0x18 a: %d\n",
                    520:                              bktr_name(bktr), stereo);
                    521:       DELAY(20000);
                    522:       stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
                    523:       if (bootverbose)printf ("%s: Stereo reg 0x18 b: %d\n",
                    524:                              bktr_name(bktr), stereo);
                    525:       DELAY(20000);
                    526:       stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
                    527:       if (bootverbose)printf ("%s: Stereo reg 0x18 c: %d\n",
                    528:                              bktr_name(bktr), stereo);
                    529:       if (stereo > 0x0100 && stereo < 0x8000) { /* Seems to be stereo */
                    530:         msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker set stereo*/
                    531:         /*
                    532:           set spatial effect strength to 50% enlargement
                    533:           set spatial effect mode b, stereo basewidth enlargment only
                    534:         */
                    535:         msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f28);
                    536:       } else if (stereo > 0x8000) {    /* bilingual mode */
                    537:         if (bootverbose) printf ("%s: Bilingual mode detected\n",
                    538:                                 bktr_name(bktr));
                    539:         msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Loudspeaker */
                    540:         msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x0000);/* all spatial effects off */
                    541:        } else {                 /* must be mono */
                    542:         msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0030);/* Loudspeaker */
                    543:         /*
                    544:           set spatial effect strength to 50% enlargement
                    545:           set spatial effect mode a, stereo basewidth enlargment
                    546:           and pseudo stereo effect with automatic high-pass filter
                    547:         */
                    548:         msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f08);
                    549:       }
                    550: #if 0
                    551:        /* The reset value for Channel matrix mode is FM/AM and SOUNDA/LEFT */
                    552:        /* We would like STEREO instead val: 0x0020 */
                    553:        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker */
                    554:        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0009,0x0020);/* Headphone */
                    555:        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000a,0x0020);/* SCART1 */
                    556:        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0041,0x0020);/* SCART2 */
                    557:        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000b,0x0020);/* I2S */
                    558:        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000c,0x0020);/* Quasi-Peak Detector Source */
                    559:        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000e,0x0001);
                    560: #endif
                    561:       break;
                    562:     case 8:                    /* B/G FM NICAM */
                    563:        msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */
                    564:        break;
                    565:      case 9:                    /* L_AM NICAM or D/K*/
                    566:      case 10:                   /* i-FM NICAM */
                    567:        break;
                    568:      default:
                    569:        if (bootverbose) printf ("%s: Unknown autodetection result value: %d\n",
                    570:                                bktr_name(bktr), auto_detect);
                    571:      }
                    572:
                    573:   }
                    574:
                    575:
                    576:   /* uncomment the following line to enable the MSP34xx 1KHz Tone Generator */
                    577:   /* turn your speaker volume down low before trying this */
                    578:   /* msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0014, 0x7f40); */
                    579: }
                    580:
                    581: /* Read the DPL version string */
                    582: void dpl_read_id( bktr_ptr_t bktr ){
                    583:     int rev1=0, rev2=0;
                    584:     rev1 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001e);
                    585:     rev2 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001f);
                    586:
                    587:     snprintf(bktr->dpl_version_string, sizeof bktr->dpl_version_string,
                    588:       "34%02d%c-%c%d", ((rev2>>8)&0xff)-1, (rev1&0xff)+'@',
                    589:       ((rev1>>8)&0xff)+'@', rev2&0x1f);
                    590: }
                    591:
                    592: /* Configure the DPL chip to Auto-detect the audio format */
                    593: void dpl_autodetect( bktr_ptr_t bktr ) {
                    594:
                    595:     /* The following are empiric values tried from the DPL35xx data sheet */
                    596:     msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x000c,0x0320);  /* quasi peak detector source dolby
                    597:                                                                lr 0x03xx; quasi peak detector matrix
                    598:                                                                stereo 0xXX20 */
                    599:     msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0040,0x0060);  /* Surround decoder mode;
                    600:                                                                ADAPTIVE/3D-PANORAMA, that means two
                    601:                                                                speakers and no center speaker, all
                    602:                                                                channels L/R/C/S mixed to L and R */
                    603:     msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0041,0x0620);  /* surround source matrix;I2S2/STEREO*/
                    604:     msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0042,0x1F00);  /* surround delay 31ms max */
                    605:     msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0043,0x0000);  /* automatic surround input balance */
                    606:     msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0044,0x4000);  /* surround spatial effect 50%
                    607:                                                                recommended*/
                    608:     msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0045,0x5400);  /* surround panorama effect 66%
                    609:                                                                recommended with PANORAMA mode
                    610:                                                                in 0x0040 set to panorama */
                    611: }
                    612:

CVSweb