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