2 * 1. Redistributions of source code must retain the
3 * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Amancio Hasty and
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
33 * $FreeBSD: src/sys/dev/bktr/bktr_audio.c,v 1.13 2003/12/08 07:59:18 obrien Exp $
34 * $DragonFly: src/sys/dev/video/bktr/bktr_audio.c,v 1.6 2004/05/15 17:54:12 joerg Exp $
38 * This is part of the Driver for Video Capture Cards (Frame grabbers)
39 * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
41 * Copyright Roger Hardiman and Amancio Hasty.
43 * bktr_audio : This deals with controlling the audio on TV cards,
44 * controlling the Audio Multiplexer (audio source selector).
45 * controlling any MSP34xx stereo audio decoders.
46 * controlling any DPL35xx dolby surroud sound audio decoders.
47 * initialising TDA98xx audio devices.
51 #include "opt_bktr.h" /* Include any kernel config options */
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/kernel.h>
56 #include <sys/vnode.h>
58 #include <bus/pci/pcivar.h>
59 #include <machine/bus_memio.h> /* for bus space */
60 #include <machine/bus.h>
62 #include <dev/video/meteor/ioctl_meteor.h>
63 #include <dev/video/bktr/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
64 #include <dev/video/bktr/bktr_reg.h>
65 #include <dev/video/bktr/bktr_core.h>
66 #include <dev/video/bktr/bktr_tuner.h>
67 #include <dev/video/bktr/bktr_card.h>
68 #include <dev/video/bktr/bktr_audio.h>
71 * Prototypes for the GV_BCTV2 specific functions.
73 void set_bctv2_audio( bktr_ptr_t bktr );
74 void bctv2_gpio_write( bktr_ptr_t bktr, int port, int val );
75 /*int bctv2_gpio_read( bktr_ptr_t bktr, int port );*/ /* Not used */
79 * Reset any MSP34xx or TDA98xx audio devices.
81 void init_audio_devices( bktr_ptr_t bktr ) {
83 /* enable stereo if appropriate on TDA audio chip */
87 /* reset the MSP34xx stereo audio chip */
88 if ( bktr->card.msp3400c )
89 msp_dpl_reset( bktr, bktr->msp_addr );
91 /* reset the DPL35xx dolby audio chip */
92 if ( bktr->card.dpl3518a )
93 msp_dpl_reset( bktr, bktr->dpl_addr );
101 #define AUDIOMUX_DISCOVER_NOT
103 set_audio( bktr_ptr_t bktr, int cmd )
108 #if defined( AUDIOMUX_DISCOVER )
112 #endif /* AUDIOMUX_DISCOVER */
114 /* check for existance of audio MUXes */
115 if ( !bktr->card.audiomuxs[ 4 ] )
120 #ifdef BKTR_REVERSEMUTE
121 bktr->audio_mux_select = 3;
123 bktr->audio_mux_select = 0;
126 if (bktr->reverse_mute )
127 bktr->audio_mux_select = 0;
129 bktr->audio_mux_select = 3;
133 bktr->audio_mux_select = 1;
136 bktr->audio_mux_select = 2;
139 bktr->audio_mute_state = TRUE; /* set mute */
142 bktr->audio_mute_state = FALSE; /* clear mute */
145 printf("%s: audio cmd error %02x\n", bktr_name(bktr),
151 /* Most cards have a simple audio multiplexer to select the
152 * audio source. The I/O_GV card has a more advanced multiplexer
153 * and requires special handling.
155 if ( bktr->bt848_card == CARD_IO_BCTV2 ) {
156 set_bctv2_audio( bktr );
160 /* Proceed with the simpler audio multiplexer code for the majority
165 * Leave the upper bits of the GPIO port alone in case they control
166 * something like the dbx or teletext chips. This doesn't guarantee
167 * success, but follows the rule of least astonishment.
170 if ( bktr->audio_mute_state == TRUE ) {
171 #ifdef BKTR_REVERSEMUTE
177 if (bktr->reverse_mute )
184 idx = bktr->audio_mux_select;
187 temp = INL(bktr, BKTR_GPIO_DATA) & ~bktr->card.gpio_mux_bits;
188 #if defined( AUDIOMUX_DISCOVER )
189 OUTL(bktr, BKTR_GPIO_DATA, temp | (cmd & 0xff));
190 printf("%s: cmd: %d audio mux %x temp %x \n", bktr_name(bktr),
191 cmd, bktr->card.audiomuxs[ idx ], temp );
193 OUTL(bktr, BKTR_GPIO_DATA, temp | bktr->card.audiomuxs[ idx ]);
194 #endif /* AUDIOMUX_DISCOVER */
198 /* Some new Hauppauge cards do not have an audio mux */
199 /* Instead we use the MSP34xx chip to select TV audio, Line-In */
200 /* FM Radio and Mute */
201 /* Examples of this are the Hauppauge 44xxx MSP34xx models */
202 /* It is ok to drive both the mux and the MSP34xx chip. */
203 /* If there is no mux, the MSP does the switching of the audio source */
204 /* If there is a mux, it does the switching of the audio source */
206 if ((bktr->card.msp3400c) && (bktr->audio_mux_present == 0)) {
208 if (bktr->audio_mute_state == TRUE ) {
209 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x0000); /* volume to MUTE */
211 if(bktr->audio_mux_select == 0) { /* TV Tuner */
212 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
213 if (bktr->msp_source_selected != 0) msp_autodetect(bktr); /* setup TV audio mode */
214 bktr->msp_source_selected = 0;
216 if(bktr->audio_mux_select == 1) { /* Line In */
217 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
218 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */
219 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */
220 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0000); /* DSP In = SC1_IN_L/R */
221 bktr->msp_source_selected = 1;
224 if(bktr->audio_mux_select == 2) { /* FM Radio */
225 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
226 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */
227 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */
228 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0200); /* DSP In = SC2_IN_L/R */
229 bktr->msp_source_selected = 2;
243 temp_mute( bktr_ptr_t bktr, int flag )
245 static int muteState = FALSE;
247 if ( flag == TRUE ) {
248 muteState = bktr->audio_mute_state;
249 set_audio( bktr, AUDIO_MUTE ); /* prevent 'click' */
252 tsleep( BKTR_SLEEP, 0, "tuning", hz/8 );
253 if ( muteState == FALSE )
254 set_audio( bktr, AUDIO_UNMUTE );
258 /* address of BTSC/SAP decoder chip */
259 #define TDA9850_WADDR 0xb6
260 #define TDA9850_RADDR 0xb7
263 /* registers in the TDA9850 BTSC/dbx chip */
264 #define CON1ADDR 0x04
265 #define CON2ADDR 0x05
266 #define CON3ADDR 0x06
267 #define CON4ADDR 0x07
268 #define ALI1ADDR 0x08
269 #define ALI2ADDR 0x09
270 #define ALI3ADDR 0x0a
273 * initialise the dbx chip
274 * taken from the Linux bttv driver TDA9850 initialisation code
277 init_BTSC( bktr_ptr_t bktr )
279 i2cWrite(bktr, TDA9850_WADDR, CON1ADDR, 0x08); /* noise threshold st */
280 i2cWrite(bktr, TDA9850_WADDR, CON2ADDR, 0x08); /* noise threshold sap */
281 i2cWrite(bktr, TDA9850_WADDR, CON3ADDR, 0x40); /* stereo mode */
282 i2cWrite(bktr, TDA9850_WADDR, CON4ADDR, 0x07); /* 0 dB input gain? */
283 i2cWrite(bktr, TDA9850_WADDR, ALI1ADDR, 0x10); /* wideband alignment? */
284 i2cWrite(bktr, TDA9850_WADDR, ALI2ADDR, 0x10); /* spectral alignment? */
285 i2cWrite(bktr, TDA9850_WADDR, ALI3ADDR, 0x03);
290 * XXX FIXME: alot of work to be done here, this merely unmutes it.
293 set_BTSC( bktr_ptr_t bktr, int control )
295 return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) );
299 * CARD_GV_BCTV2 specific functions.
302 #define BCTV2_AUDIO_MAIN 0x10 /* main audio program */
303 #define BCTV2_AUDIO_SUB 0x20 /* sub audio program */
304 #define BCTV2_AUDIO_BOTH 0x30 /* main(L) + sub(R) program */
306 #define BCTV2_GPIO_REG0 1
307 #define BCTV2_GPIO_REG1 3
309 #define BCTV2_GR0_AUDIO_MODE 3
310 #define BCTV2_GR0_AUDIO_MAIN 0 /* main program */
311 #define BCTV2_GR0_AUDIO_SUB 3 /* sub program */
312 #define BCTV2_GR0_AUDIO_BOTH 1 /* main(L) + sub(R) */
313 #define BCTV2_GR0_AUDIO_MUTE 4 /* audio mute */
314 #define BCTV2_GR0_AUDIO_MONO 8 /* force mono */
317 set_bctv2_audio( bktr_ptr_t bktr )
321 switch (bktr->audio_mux_select) {
322 case 1: /* external */
323 case 2: /* internal */
324 bctv2_gpio_write(bktr, BCTV2_GPIO_REG1, 0);
327 bctv2_gpio_write(bktr, BCTV2_GPIO_REG1, 1);
330 /* switch (bktr->audio_sap_select) { */
331 switch (BCTV2_AUDIO_BOTH) {
332 case BCTV2_AUDIO_SUB:
333 data = BCTV2_GR0_AUDIO_SUB;
335 case BCTV2_AUDIO_BOTH:
336 data = BCTV2_GR0_AUDIO_BOTH;
338 case BCTV2_AUDIO_MAIN:
340 data = BCTV2_GR0_AUDIO_MAIN;
343 if (bktr->audio_mute_state == TRUE)
344 data |= BCTV2_GR0_AUDIO_MUTE;
346 bctv2_gpio_write(bktr, BCTV2_GPIO_REG0, data);
351 /* gpio_data bit assignment */
352 #define BCTV2_GPIO_ADDR_MASK 0x000300
353 #define BCTV2_GPIO_WE 0x000400
354 #define BCTV2_GPIO_OE 0x000800
355 #define BCTV2_GPIO_VAL_MASK 0x00f000
357 #define BCTV2_GPIO_PORT_MASK 3
358 #define BCTV2_GPIO_ADDR_SHIFT 8
359 #define BCTV2_GPIO_VAL_SHIFT 12
361 /* gpio_out_en value for read/write */
362 #define BCTV2_GPIO_OUT_RMASK 0x000f00
363 #define BCTV2_GPIO_OUT_WMASK 0x00ff00
365 #define BCTV2_BITS 100
368 bctv2_gpio_write( bktr_ptr_t bktr, int port, int val )
370 u_long data, outbits;
372 port &= BCTV2_GPIO_PORT_MASK;
376 data = ((val << BCTV2_GPIO_VAL_SHIFT) & BCTV2_GPIO_VAL_MASK) |
377 ((port << BCTV2_GPIO_ADDR_SHIFT) & BCTV2_GPIO_ADDR_MASK) |
378 BCTV2_GPIO_WE | BCTV2_GPIO_OE;
379 outbits = BCTV2_GPIO_OUT_WMASK;
384 OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
385 OUTL(bktr, BKTR_GPIO_DATA, data);
386 OUTL(bktr, BKTR_GPIO_OUT_EN, outbits);
388 OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV2_GPIO_WE);
390 OUTL(bktr, BKTR_GPIO_DATA, data);
392 OUTL(bktr, BKTR_GPIO_DATA, ~0);
393 OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
398 bctv2_gpio_read( bktr_ptr_t bktr, int port )
400 u_long data, outbits, ret;
402 port &= BCTV2_GPIO_PORT_MASK;
406 data = ((port << BCTV2_GPIO_ADDR_SHIFT) & BCTV2_GPIO_ADDR_MASK) |
407 BCTV2_GPIO_WE | BCTV2_GPIO_OE;
408 outbits = BCTV2_GPIO_OUT_RMASK;
413 OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
414 OUTL(bktr, BKTR_GPIO_DATA, data);
415 OUTL(bktr, BKTR_GPIO_OUT_EN, outbits);
417 OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV2_GPIO_OE);
419 ret = INL(bktr, BKTR_GPIO_DATA);
421 OUTL(bktr, BKTR_GPIO_DATA, data);
423 OUTL(bktr, BKTR_GPIO_DATA, ~0);
424 OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
425 return( (ret & BCTV2_GPIO_VAL_MASK) >> BCTV2_GPIO_VAL_SHIFT );
430 * setup the MSP34xx Stereo Audio Chip
431 * This uses the Auto Configuration Option on MSP3410D and MSP3415D chips
432 * and DBX mode selection for MSP3430G chips.
433 * For MSP3400C support, the full programming sequence is required and is
437 /* Read the MSP version string */
438 void msp_read_id( bktr_ptr_t bktr ){
440 rev1 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001e);
441 rev2 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001f);
443 sprintf(bktr->msp_version_string, "34%02d%c-%c%d",
444 (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
449 /* Configure the MSP chip to Auto-detect the audio format.
450 * For the MSP3430G, we use fast autodetect mode
451 * For the MSP3410/3415 there are two schemes for this
452 * a) Fast autodetection - the chip is put into autodetect mode, and the function
453 * returns immediatly. This works in most cases and is the Default Mode.
454 * b) Slow mode. The function sets the MSP3410/3415 chip, then waits for feedback from
455 * the chip and re-programs it if needed.
457 void msp_autodetect( bktr_ptr_t bktr ) {
459 #ifdef BKTR_NEW_MSP34XX_DRIVER
461 /* Just wake up the (maybe) sleeping thread, it'll do everything for us */
462 msp_wake_thread(bktr);
465 int auto_detect, loops;
468 /* MSP3430G - countries with mono and DBX stereo */
469 if (strncmp("3430G", bktr->msp_version_string, 5) == 0){
471 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0030,0x2003);/* Enable Auto format detection */
472 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0020);/* Standard Select Reg. = BTSC-Stereo*/
473 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000E,0x2403);/* darned if I know */
474 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0320);/* Source select = (St or A) */
475 /* & Ch. Matrix = St */
476 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
480 /* MSP3415D SPECIAL CASE Use the Tuner's Mono audio ouput for the MSP */
481 /* (for Hauppauge 44xxx card with Tuner Type 0x2a) */
482 else if ( ( (strncmp("3415D", bktr->msp_version_string, 5) == 0)
483 &&(bktr->msp_use_mono_source == 1)
485 || (bktr->slow_msp_audio == 2) ){
486 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
487 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */
488 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */
489 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0100); /* DSP In = MONO IN */
493 /* MSP3410/MSP3415 - countries with mono, stereo using 2 FM channels and NICAM */
494 /* FAST sound scheme */
495 else if (bktr->slow_msp_audio == 0) {
496 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
497 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Spkr Source = default(FM/AM) */
498 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */
499 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */
503 /* MSP3410/MSP3415 - European Countries where the fast MSP3410/3415 programming fails */
504 /* SLOW sound scheme */
505 else if ( bktr->slow_msp_audio == 1) {
506 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
507 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */
509 /* wait for 0.5s max for terrestrial sound autodetection */
513 auto_detect = msp_dpl_read(bktr, bktr->msp_addr, 0x10, 0x007e);
515 } while (auto_detect > 0xff && loops < 50);
516 if (bootverbose)printf ("%s: Result of autodetect after %dms: %d\n",
517 bktr_name(bktr), loops*10, auto_detect);
519 /* Now set the audio baseband processing */
520 switch (auto_detect) {
521 case 0: /* no TV sound standard detected */
523 case 2: /* M Dual FM */
525 case 3: /* B/G Dual FM; German stereo */
526 /* Read the stereo detection value from DSP reg 0x0018 */
528 stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
529 if (bootverbose)printf ("%s: Stereo reg 0x18 a: %d\n",
530 bktr_name(bktr), stereo);
532 stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
533 if (bootverbose)printf ("%s: Stereo reg 0x18 b: %d\n",
534 bktr_name(bktr), stereo);
536 stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
537 if (bootverbose)printf ("%s: Stereo reg 0x18 c: %d\n",
538 bktr_name(bktr), stereo);
539 if (stereo > 0x0100 && stereo < 0x8000) { /* Seems to be stereo */
540 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker set stereo*/
542 set spatial effect strength to 50% enlargement
543 set spatial effect mode b, stereo basewidth enlargment only
545 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f28);
546 } else if (stereo > 0x8000) { /* bilingual mode */
547 if (bootverbose) printf ("%s: Bilingual mode detected\n",
549 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Loudspeaker */
550 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x0000);/* all spatial effects off */
551 } else { /* must be mono */
552 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0030);/* Loudspeaker */
554 set spatial effect strength to 50% enlargement
555 set spatial effect mode a, stereo basewidth enlargment
556 and pseudo stereo effect with automatic high-pass filter
558 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f08);
561 /* The reset value for Channel matrix mode is FM/AM and SOUNDA/LEFT */
562 /* We would like STEREO instead val: 0x0020 */
563 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker */
564 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0009,0x0020);/* Headphone */
565 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000a,0x0020);/* SCART1 */
566 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0041,0x0020);/* SCART2 */
567 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000b,0x0020);/* I2S */
568 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000c,0x0020);/* Quasi-Peak Detector Source */
569 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000e,0x0001);
572 case 8: /* B/G FM NICAM */
573 msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */
575 case 9: /* L_AM NICAM or D/K*/
576 case 10: /* i-FM NICAM */
579 if (bootverbose) printf ("%s: Unknown autodetection result value: %d\n",
580 bktr_name(bktr), auto_detect);
586 /* uncomment the following line to enable the MSP34xx 1Khz Tone Generator */
587 /* turn your speaker volume down low before trying this */
588 /* msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0014, 0x7f40); */
590 #endif /* BKTR_NEW_MSP34XX_DRIVER */
593 /* Read the DPL version string */
594 void dpl_read_id( bktr_ptr_t bktr ){
596 rev1 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001e);
597 rev2 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001f);
599 sprintf(bktr->dpl_version_string, "34%02d%c-%c%d",
600 ((rev2>>8)&0xff)-1, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
603 /* Configure the DPL chip to Auto-detect the audio format */
604 void dpl_autodetect( bktr_ptr_t bktr ) {
606 /* The following are empiric values tried from the DPL35xx data sheet */
607 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x000c,0x0320); /* quasi peak detector source dolby
608 lr 0x03xx; quasi peak detector matrix
610 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0040,0x0060); /* Surround decoder mode;
611 ADAPTIVE/3D-PANORAMA, that means two
612 speakers and no center speaker, all
613 channels L/R/C/S mixed to L and R */
614 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0041,0x0620); /* surround source matrix;I2S2/STEREO*/
615 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0042,0x1F00); /* surround delay 31ms max */
616 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0043,0x0000); /* automatic surround input balance */
617 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0044,0x4000); /* surround spatial effect 50%
619 msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0045,0x5400); /* surround panorama effect 66%
620 recommended with PANORAMA mode
621 in 0x0040 set to panorama */