bktr_audio.c revision 298955
1279377Simp/*-
2279377Simp * 1. Redistributions of source code must retain the
3279377Simp * Copyright (c) 1997 Amancio Hasty, 1999 Roger Hardiman
4279377Simp * All rights reserved.
5279377Simp *
6279377Simp * Redistribution and use in source and binary forms, with or without
7279377Simp * modification, are permitted provided that the following conditions
8279377Simp * are met:
9279377Simp * 1. Redistributions of source code must retain the above copyright
10279377Simp *    notice, this list of conditions and the following disclaimer.
11279377Simp * 2. Redistributions in binary form must reproduce the above copyright
12279377Simp *    notice, this list of conditions and the following disclaimer in the
13279377Simp *    documentation and/or other materials provided with the distribution.
14279377Simp * 3. All advertising materials mentioning features or use of this software
15279377Simp *    must display the following acknowledgement:
16279377Simp *      This product includes software developed by Amancio Hasty and
17279377Simp *      Roger Hardiman
18279377Simp * 4. The name of the author may not be used to endorse or promote products
19279377Simp *    derived from this software without specific prior written permission.
20279377Simp *
21279377Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22279377Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23279377Simp * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24279377Simp * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25279377Simp * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26279377Simp * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27279377Simp * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28279377Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29279377Simp * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30279377Simp * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31279377Simp * POSSIBILITY OF SUCH DAMAGE.
32279377Simp */
33279377Simp
34279377Simp#include <sys/cdefs.h>
35279377Simp__FBSDID("$FreeBSD: head/sys/dev/bktr/bktr_audio.c 298955 2016-05-03 03:41:25Z pfg $");
36279377Simp
37279377Simp/*
38279377Simp * This is part of the Driver for Video Capture Cards (Frame grabbers)
39279377Simp * and TV Tuner cards using the Brooktree Bt848, Bt848A, Bt849A, Bt878, Bt879
40279377Simp * chipset.
41279377Simp * Copyright Roger Hardiman and Amancio Hasty.
42279377Simp *
43279377Simp * bktr_audio : This deals with controlling the audio on TV cards,
44279377Simp *                controlling the Audio Multiplexer (audio source selector).
45279377Simp *                controlling any MSP34xx stereo audio decoders.
46279377Simp *                controlling any DPL35xx dolby surroud sound audio decoders.
47279377Simp *                initialising TDA98xx audio devices.
48279377Simp *
49279377Simp */
50279377Simp
51279377Simp#include "opt_bktr.h"               /* Include any kernel config options */
52279377Simp
53279377Simp#include <sys/param.h>
54279377Simp#include <sys/systm.h>
55279377Simp#include <sys/kernel.h>
56279377Simp
57279377Simp#ifdef __FreeBSD__
58279377Simp
59279377Simp#if (__FreeBSD_version < 500000)
60279377Simp#include <machine/clock.h>              /* for DELAY */
61279377Simp#include <pci/pcivar.h>
62279377Simp#else
63279377Simp#include <sys/lock.h>
64279377Simp#include <sys/mutex.h>
65279377Simp#include <sys/selinfo.h>
66279377Simp#include <dev/pci/pcivar.h>
67279377Simp#endif
68279377Simp
69279377Simp#include <machine/bus.h>
70279377Simp#include <sys/bus.h>
71279377Simp#endif
72279377Simp
73279377Simp#ifdef __NetBSD__
74279377Simp#include <sys/proc.h>
75279377Simp#include <dev/ic/bt8xx.h>	/* NetBSD location of .h files */
76279377Simp#include <dev/pci/bktr/bktr_reg.h>
77279377Simp#include <dev/pci/bktr/bktr_core.h>
78279377Simp#include <dev/pci/bktr/bktr_tuner.h>
79279377Simp#include <dev/pci/bktr/bktr_card.h>
80279377Simp#include <dev/pci/bktr/bktr_audio.h>
81279377Simp#else
82279377Simp#include <dev/bktr/ioctl_meteor.h>
83279377Simp#include <dev/bktr/ioctl_bt848.h>	/* extensions to ioctl_meteor.h */
84279377Simp#include <dev/bktr/bktr_reg.h>
85279377Simp#include <dev/bktr/bktr_core.h>
86279377Simp#include <dev/bktr/bktr_tuner.h>
87279377Simp#include <dev/bktr/bktr_card.h>
88279377Simp#include <dev/bktr/bktr_audio.h>
89279377Simp#endif
90279377Simp
91279377Simp/*
92279377Simp * Prototypes for the GV_BCTV2 specific functions.
93279377Simp */
94279377Simpvoid    set_bctv2_audio( bktr_ptr_t bktr );
95279377Simpvoid    bctv2_gpio_write( bktr_ptr_t bktr, int port, int val );
96279377Simp/*int   bctv2_gpio_read( bktr_ptr_t bktr, int port );*/ /* Not used */
97279377Simp
98279377Simp/*
99279377Simp * init_audio_devices
100279377Simp * Reset any MSP34xx or TDA98xx audio devices.
101279377Simp */
102279377Simpvoid init_audio_devices( bktr_ptr_t bktr ) {
103279377Simp
104279377Simp        /* enable stereo if appropriate on TDA audio chip */
105279377Simp        if ( bktr->card.dbx )
106279377Simp                init_BTSC( bktr );
107279377Simp
108279377Simp        /* reset the MSP34xx stereo audio chip */
109279377Simp        if ( bktr->card.msp3400c )
110279377Simp                msp_dpl_reset( bktr, bktr->msp_addr );
111279377Simp
112279377Simp        /* reset the DPL35xx dolby audio chip */
113279377Simp        if ( bktr->card.dpl3518a )
114279377Simp                msp_dpl_reset( bktr, bktr->dpl_addr );
115279377Simp
116279377Simp}
117279377Simp
118279377Simp
119279377Simp/*
120279377Simp *
121279377Simp */
122279377Simp#define AUDIOMUX_DISCOVER_NOT
123279377Simpint
124279377Simpset_audio( bktr_ptr_t bktr, int cmd )
125279377Simp{
126279377Simp	u_long		temp;
127279377Simp	volatile u_char	idx;
128279377Simp
129279377Simp#if defined( AUDIOMUX_DISCOVER )
130279377Simp	if ( cmd >= 200 )
131279377Simp		cmd -= 200;
132279377Simp	else
133279377Simp#endif /* AUDIOMUX_DISCOVER */
134279377Simp
135279377Simp	/* check for existence of audio MUXes */
136279377Simp	if ( !bktr->card.audiomuxs[ 4 ] )
137279377Simp		return( -1 );
138279377Simp
139279377Simp	switch (cmd) {
140279377Simp	case AUDIO_TUNER:
141279377Simp#ifdef BKTR_REVERSEMUTE
142279377Simp		bktr->audio_mux_select = 3;
143279377Simp#else
144279377Simp		bktr->audio_mux_select = 0;
145279377Simp#endif
146279377Simp
147279377Simp		if (bktr->reverse_mute )
148279377Simp		      bktr->audio_mux_select = 0;
149279377Simp		else
150279377Simp		    bktr->audio_mux_select = 3;
151279377Simp
152279377Simp		break;
153279377Simp	case AUDIO_EXTERN:
154279377Simp		bktr->audio_mux_select = 1;
155279377Simp		break;
156279377Simp	case AUDIO_INTERN:
157279377Simp		bktr->audio_mux_select = 2;
158279377Simp		break;
159279377Simp	case AUDIO_MUTE:
160279377Simp		bktr->audio_mute_state = TRUE;	/* set mute */
161279377Simp		break;
162279377Simp	case AUDIO_UNMUTE:
163279377Simp		bktr->audio_mute_state = FALSE;	/* clear mute */
164279377Simp		break;
165279377Simp	default:
166279377Simp		printf("%s: audio cmd error %02x\n", bktr_name(bktr),
167279377Simp		       cmd);
168279377Simp		return( -1 );
169279377Simp	}
170279377Simp
171279377Simp
172279377Simp	/* Most cards have a simple audio multiplexer to select the
173279377Simp	 * audio source. The I/O_GV card has a more advanced multiplexer
174279377Simp	 * and requires special handling.
175279377Simp	 */
176279377Simp        if ( bktr->bt848_card == CARD_IO_BCTV2 ) {
177279377Simp                set_bctv2_audio( bktr );
178279377Simp                return( 0 );
179279377Simp	}
180279377Simp
181279377Simp	/* Proceed with the simpler audio multiplexer code for the majority
182279377Simp	 * of Bt848 cards.
183279377Simp	 */
184279377Simp
185279377Simp	/*
186279377Simp	 * Leave the upper bits of the GPIO port alone in case they control
187279377Simp	 * something like the dbx or teletext chips.  This doesn't guarantee
188279377Simp	 * success, but follows the rule of least astonishment.
189279377Simp	 */
190279377Simp
191279377Simp	if ( bktr->audio_mute_state == TRUE ) {
192279377Simp#ifdef BKTR_REVERSEMUTE
193279377Simp		idx = 0;
194279377Simp#else
195279377Simp		idx = 3;
196279377Simp#endif
197279377Simp
198279377Simp		if (bktr->reverse_mute )
199279377Simp		  idx  = 3;
200279377Simp		else
201279377Simp		  idx  = 0;
202279377Simp
203279377Simp	}
204279377Simp	else
205279377Simp		idx = bktr->audio_mux_select;
206279377Simp
207279377Simp
208279377Simp	temp = INL(bktr, BKTR_GPIO_DATA) & ~bktr->card.gpio_mux_bits;
209279377Simp#if defined( AUDIOMUX_DISCOVER )
210279377Simp	OUTL(bktr, BKTR_GPIO_DATA, temp | (cmd & 0xff));
211279377Simp	printf("%s: cmd: %d audio mux %x temp %x \n", bktr_name(bktr),
212279377Simp	  	cmd, bktr->card.audiomuxs[ idx ], temp );
213279377Simp#else
214279377Simp	OUTL(bktr, BKTR_GPIO_DATA, temp | bktr->card.audiomuxs[ idx ]);
215279377Simp#endif /* AUDIOMUX_DISCOVER */
216279377Simp
217279377Simp
218279377Simp
219279377Simp	/* Some new Hauppauge cards do not have an audio mux */
220279377Simp	/* Instead we use the MSP34xx chip to select TV audio, Line-In */
221279377Simp	/* FM Radio and Mute */
222279377Simp	/* Examples of this are the Hauppauge 44xxx MSP34xx models */
223279377Simp	/* It is ok to drive both the mux and the MSP34xx chip. */
224279377Simp	/* If there is no mux, the MSP does the switching of the audio source */
225279377Simp	/* If there is a mux, it does the switching of the audio source */
226279377Simp
227279377Simp	if ((bktr->card.msp3400c) && (bktr->audio_mux_present == 0)) {
228279377Simp
229279377Simp	  if (bktr->audio_mute_state == TRUE ) {
230279377Simp		 msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x0000); /* volume to MUTE */
231279377Simp	  } else {
232279377Simp		 if(bktr->audio_mux_select == 0) { /* TV Tuner */
233279377Simp		    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
234279377Simp		    if (bktr->msp_source_selected != 0) msp_autodetect(bktr);  /* setup TV audio mode */
235279377Simp		    bktr->msp_source_selected = 0;
236279377Simp		 }
237279377Simp		 if(bktr->audio_mux_select == 1) { /* Line In */
238279377Simp		    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
239279377Simp		    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */
240279377Simp		    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */
241279377Simp		    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0000); /* DSP In = SC1_IN_L/R */
242279377Simp		    bktr->msp_source_selected = 1;
243279377Simp		 }
244279377Simp
245279377Simp		 if(bktr->audio_mux_select == 2) { /* FM Radio */
246279377Simp		    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
247279377Simp		    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */
248279377Simp		    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */
249279377Simp		    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0200); /* DSP In = SC2_IN_L/R */
250279377Simp		    bktr->msp_source_selected = 2;
251279377Simp		 }
252279377Simp	  }
253279377Simp	}
254279377Simp
255279377Simp
256279377Simp	return( 0 );
257279377Simp}
258279377Simp
259279377Simp
260279377Simp/*
261279377Simp *
262279377Simp */
263279377Simpvoid
264279377Simptemp_mute( bktr_ptr_t bktr, int flag )
265279377Simp{
266279377Simp	static int	muteState = FALSE;
267279377Simp
268279377Simp	if ( flag == TRUE ) {
269279377Simp		muteState = bktr->audio_mute_state;
270279377Simp		set_audio( bktr, AUDIO_MUTE );		/* prevent 'click' */
271279377Simp	}
272279377Simp	else {
273279377Simp		tsleep( BKTR_SLEEP, PZERO, "tuning", hz/8 );
274279377Simp		if ( muteState == FALSE )
275279377Simp			set_audio( bktr, AUDIO_UNMUTE );
276279377Simp	}
277279377Simp}
278279377Simp
279279377Simp/* address of BTSC/SAP decoder chip */
280279377Simp#define TDA9850_WADDR           0xb6
281279377Simp#define TDA9850_RADDR           0xb7
282279377Simp
283279377Simp
284279377Simp/* registers in the TDA9850 BTSC/dbx chip */
285279377Simp#define CON1ADDR                0x04
286279377Simp#define CON2ADDR                0x05
287279377Simp#define CON3ADDR                0x06
288279377Simp#define CON4ADDR                0x07
289279377Simp#define ALI1ADDR                0x08
290279377Simp#define ALI2ADDR                0x09
291279377Simp#define ALI3ADDR                0x0a
292279377Simp
293279377Simp/*
294279377Simp * initialise the dbx chip
295279377Simp * taken from the Linux bttv driver TDA9850 initialisation code
296279377Simp */
297279377Simpvoid
298279377Simpinit_BTSC( bktr_ptr_t bktr )
299279377Simp{
300279377Simp    i2cWrite(bktr, TDA9850_WADDR, CON1ADDR, 0x08); /* noise threshold st */
301279377Simp    i2cWrite(bktr, TDA9850_WADDR, CON2ADDR, 0x08); /* noise threshold sap */
302279377Simp    i2cWrite(bktr, TDA9850_WADDR, CON3ADDR, 0x40); /* stereo mode */
303279377Simp    i2cWrite(bktr, TDA9850_WADDR, CON4ADDR, 0x07); /* 0 dB input gain? */
304279377Simp    i2cWrite(bktr, TDA9850_WADDR, ALI1ADDR, 0x10); /* wideband alignment? */
305279377Simp    i2cWrite(bktr, TDA9850_WADDR, ALI2ADDR, 0x10); /* spectral alignment? */
306279377Simp    i2cWrite(bktr, TDA9850_WADDR, ALI3ADDR, 0x03);
307279377Simp}
308279377Simp
309279377Simp/*
310279377Simp * setup the dbx chip
311279377Simp * XXX FIXME: a lot of work to be done here, this merely unmutes it.
312279377Simp */
313279377Simpint
314279377Simpset_BTSC( bktr_ptr_t bktr, int control )
315279377Simp{
316279377Simp	return( i2cWrite( bktr, TDA9850_WADDR, CON3ADDR, control ) );
317279377Simp}
318279377Simp
319279377Simp/*
320279377Simp * CARD_GV_BCTV2 specific functions.
321279377Simp */
322279377Simp
323279377Simp#define BCTV2_AUDIO_MAIN              0x10    /* main audio program */
324279377Simp#define BCTV2_AUDIO_SUB               0x20    /* sub audio program */
325279377Simp#define BCTV2_AUDIO_BOTH              0x30    /* main(L) + sub(R) program */
326279377Simp
327279377Simp#define BCTV2_GPIO_REG0          1
328279377Simp#define BCTV2_GPIO_REG1          3
329279377Simp
330279377Simp#define BCTV2_GR0_AUDIO_MODE     3
331279377Simp#define BCTV2_GR0_AUDIO_MAIN     0       /* main program */
332279377Simp#define BCTV2_GR0_AUDIO_SUB      3       /* sub program */
333279377Simp#define BCTV2_GR0_AUDIO_BOTH     1       /* main(L) + sub(R) */
334279377Simp#define BCTV2_GR0_AUDIO_MUTE     4       /* audio mute */
335279377Simp#define BCTV2_GR0_AUDIO_MONO     8       /* force mono */
336279377Simp
337279377Simpvoid
338279377Simpset_bctv2_audio( bktr_ptr_t bktr )
339279377Simp{
340279377Simp        int data;
341279377Simp
342279377Simp        switch (bktr->audio_mux_select) {
343279377Simp        case 1:         /* external */
344279377Simp        case 2:         /* internal */
345279377Simp                bctv2_gpio_write(bktr, BCTV2_GPIO_REG1, 0);
346279377Simp                break;
347279377Simp        default:        /* tuner */
348279377Simp                bctv2_gpio_write(bktr, BCTV2_GPIO_REG1, 1);
349279377Simp                break;
350279377Simp        }
351279377Simp/*      switch (bktr->audio_sap_select) { */
352279377Simp        switch (BCTV2_AUDIO_BOTH) {
353279377Simp        case BCTV2_AUDIO_SUB:
354279377Simp                data = BCTV2_GR0_AUDIO_SUB;
355279377Simp                break;
356279377Simp        case BCTV2_AUDIO_BOTH:
357279377Simp                data = BCTV2_GR0_AUDIO_BOTH;
358279377Simp                break;
359279377Simp        case BCTV2_AUDIO_MAIN:
360279377Simp        default:
361279377Simp                data = BCTV2_GR0_AUDIO_MAIN;
362279377Simp                break;
363279377Simp        }
364279377Simp        if (bktr->audio_mute_state == TRUE)
365279377Simp                data |= BCTV2_GR0_AUDIO_MUTE;
366279377Simp
367279377Simp        bctv2_gpio_write(bktr, BCTV2_GPIO_REG0, data);
368279377Simp
369279377Simp        return;
370279377Simp}
371279377Simp
372279377Simp/* gpio_data bit assignment */
373279377Simp#define BCTV2_GPIO_ADDR_MASK     0x000300
374279377Simp#define BCTV2_GPIO_WE            0x000400
375279377Simp#define BCTV2_GPIO_OE            0x000800
376279377Simp#define BCTV2_GPIO_VAL_MASK      0x00f000
377279377Simp
378279377Simp#define BCTV2_GPIO_PORT_MASK     3
379279377Simp#define BCTV2_GPIO_ADDR_SHIFT    8
380279377Simp#define BCTV2_GPIO_VAL_SHIFT     12
381279377Simp
382279377Simp/* gpio_out_en value for read/write */
383279377Simp#define BCTV2_GPIO_OUT_RMASK     0x000f00
384279377Simp#define BCTV2_GPIO_OUT_WMASK     0x00ff00
385279377Simp
386279377Simp#define BCTV2_BITS       100
387279377Simp
388279377Simpvoid
389279377Simpbctv2_gpio_write( bktr_ptr_t bktr, int port, int val )
390279377Simp{
391279377Simp        u_long data, outbits;
392279377Simp
393279377Simp        port &= BCTV2_GPIO_PORT_MASK;
394279377Simp        switch (port) {
395279377Simp        case 1:
396279377Simp        case 3:
397279377Simp                data = ((val << BCTV2_GPIO_VAL_SHIFT) & BCTV2_GPIO_VAL_MASK) |
398279377Simp                       ((port << BCTV2_GPIO_ADDR_SHIFT) & BCTV2_GPIO_ADDR_MASK) |
399279377Simp                       BCTV2_GPIO_WE | BCTV2_GPIO_OE;
400279377Simp                outbits = BCTV2_GPIO_OUT_WMASK;
401279377Simp                break;
402279377Simp        default:
403279377Simp                return;
404279377Simp        }
405279377Simp        OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
406279377Simp        OUTL(bktr, BKTR_GPIO_DATA, data);
407279377Simp        OUTL(bktr, BKTR_GPIO_OUT_EN, outbits);
408279377Simp        DELAY(BCTV2_BITS);
409279377Simp        OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV2_GPIO_WE);
410279377Simp        DELAY(BCTV2_BITS);
411279377Simp        OUTL(bktr, BKTR_GPIO_DATA, data);
412279377Simp        DELAY(BCTV2_BITS);
413279377Simp        OUTL(bktr, BKTR_GPIO_DATA, ~0);
414279377Simp        OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
415279377Simp}
416279377Simp
417279377Simp/* Not yet used
418279377Simpint
419279377Simpbctv2_gpio_read( bktr_ptr_t bktr, int port )
420279377Simp{
421279377Simp        u_long data, outbits, ret;
422279377Simp
423279377Simp        port &= BCTV2_GPIO_PORT_MASK;
424279377Simp        switch (port) {
425279377Simp        case 1:
426279377Simp        case 3:
427279377Simp                data = ((port << BCTV2_GPIO_ADDR_SHIFT) & BCTV2_GPIO_ADDR_MASK) |
428279377Simp                       BCTV2_GPIO_WE | BCTV2_GPIO_OE;
429279377Simp                outbits = BCTV2_GPIO_OUT_RMASK;
430279377Simp                break;
431279377Simp        default:
432279377Simp                return( -1 );
433279377Simp        }
434279377Simp        OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
435279377Simp        OUTL(bktr, BKTR_GPIO_DATA, data);
436279377Simp        OUTL(bktr, BKTR_GPIO_OUT_EN, outbits);
437279377Simp        DELAY(BCTV2_BITS);
438279377Simp        OUTL(bktr, BKTR_GPIO_DATA, data & ~BCTV2_GPIO_OE);
439279377Simp        DELAY(BCTV2_BITS);
440279377Simp        ret = INL(bktr, BKTR_GPIO_DATA);
441279377Simp        DELAY(BCTV2_BITS);
442279377Simp        OUTL(bktr, BKTR_GPIO_DATA, data);
443279377Simp        DELAY(BCTV2_BITS);
444279377Simp        OUTL(bktr, BKTR_GPIO_DATA, ~0);
445279377Simp        OUTL(bktr, BKTR_GPIO_OUT_EN, 0);
446279377Simp        return( (ret & BCTV2_GPIO_VAL_MASK) >> BCTV2_GPIO_VAL_SHIFT );
447279377Simp}
448279377Simp*/
449279377Simp
450279377Simp/*
451279377Simp * setup the MSP34xx Stereo Audio Chip
452279377Simp * This uses the Auto Configuration Option on MSP3410D and MSP3415D chips
453279377Simp * and DBX mode selection for MSP3430G chips.
454279377Simp * For MSP3400C support, the full programming sequence is required and is
455279377Simp * not yet supported.
456279377Simp */
457279377Simp
458279377Simp/* Read the MSP version string */
459279377Simpvoid msp_read_id( bktr_ptr_t bktr ){
460279377Simp    int rev1=0, rev2=0;
461279377Simp    rev1 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001e);
462279377Simp    rev2 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001f);
463279377Simp
464279377Simp    sprintf(bktr->msp_version_string, "34%02d%c-%c%d",
465279377Simp      (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
466279377Simp
467279377Simp}
468279377Simp
469279377Simp
470279377Simp/* Configure the MSP chip to Auto-detect the audio format.
471279377Simp * For the MSP3430G, we use fast autodetect mode
472279377Simp * For the MSP3410/3415 there are two schemes for this
473279377Simp *  a) Fast autodetection - the chip is put into autodetect mode, and the function
474279377Simp *     returns immediately. This works in most cases and is the Default Mode.
475279377Simp *  b) Slow mode. The function sets the MSP3410/3415 chip, then waits for feedback from
476279377Simp *     the chip and re-programs it if needed.
477279377Simp */
478279377Simpvoid msp_autodetect( bktr_ptr_t bktr ) {
479279377Simp
480279377Simp#ifdef BKTR_NEW_MSP34XX_DRIVER
481279377Simp
482279377Simp  /* Just wake up the (maybe) sleeping thread, it'll do everything for us */
483279377Simp  msp_wake_thread(bktr);
484279377Simp
485279377Simp#else
486279377Simp  int auto_detect, loops;
487279377Simp  int stereo;
488279377Simp
489279377Simp  /* MSP3430G - countries with mono and DBX stereo */
490279377Simp  if (strncmp("3430G", bktr->msp_version_string, 5) == 0){
491279377Simp
492279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0030,0x2003);/* Enable Auto format detection */
493279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0020);/* Standard Select Reg. = BTSC-Stereo*/
494279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000E,0x2403);/* darned if I know */
495279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0320);/* Source select = (St or A) */
496279377Simp					                     /* & Ch. Matrix = St */
497279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
498279377Simp  }
499279377Simp
500279377Simp
501279377Simp  /* MSP3415D SPECIAL CASE Use the Tuner's Mono audio output for the MSP */
502279377Simp  /* (for Hauppauge 44xxx card with Tuner Type 0x2a) */
503279377Simp  else if (  ( (strncmp("3415D", bktr->msp_version_string, 5) == 0)
504279377Simp               &&(bktr->msp_use_mono_source == 1)
505279377Simp              )
506279377Simp           || (bktr->slow_msp_audio == 2) ){
507279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000, 0x7300); /* 0 db volume */
508279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000d, 0x1900); /* scart prescale */
509279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008, 0x0220); /* SCART | STEREO */
510279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0013, 0x0100); /* DSP In = MONO IN */
511279377Simp  }
512279377Simp
513279377Simp
514279377Simp  /* MSP3410/MSP3415 - countries with mono, stereo using 2 FM channels and NICAM */
515279377Simp  /* FAST sound scheme */
516279377Simp  else if (bktr->slow_msp_audio == 0) {
517279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
518279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Spkr Source = default(FM/AM) */
519279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */
520279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */
521279377Simp  }
522279377Simp
523279377Simp
524279377Simp  /* MSP3410/MSP3415 - European Countries where the fast MSP3410/3415 programming fails */
525279377Simp  /* SLOW sound scheme */
526279377Simp  else if ( bktr->slow_msp_audio == 1) {
527279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0000,0x7300);/* Set volume to 0db gain */
528279377Simp    msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0020,0x0001);/* Enable Auto format detection */
529279377Simp
530279377Simp    /* wait for 0.5s max for terrestrial sound autodetection */
531279377Simp    loops = 10;
532279377Simp    do {
533279377Simp      DELAY(100000);
534279377Simp      auto_detect = msp_dpl_read(bktr, bktr->msp_addr, 0x10, 0x007e);
535279377Simp      loops++;
536279377Simp    } while (auto_detect > 0xff && loops < 50);
537279377Simp    if (bootverbose)printf ("%s: Result of autodetect after %dms: %d\n",
538279377Simp			    bktr_name(bktr), loops*10, auto_detect);
539279377Simp
540279377Simp    /* Now set the audio baseband processing */
541279377Simp    switch (auto_detect) {
542279377Simp    case 0:                    /* no TV sound standard detected */
543279377Simp      break;
544279377Simp    case 2:                    /* M Dual FM */
545279377Simp      break;
546279377Simp    case 3:                    /* B/G Dual FM; German stereo */
547279377Simp      /* Read the stereo detection value from DSP reg 0x0018 */
548279377Simp      DELAY(20000);
549279377Simp      stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
550279377Simp      if (bootverbose)printf ("%s: Stereo reg 0x18 a: %d\n",
551279377Simp			      bktr_name(bktr), stereo);
552279377Simp      DELAY(20000);
553279377Simp      stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
554279377Simp      if (bootverbose)printf ("%s: Stereo reg 0x18 b: %d\n",
555279377Simp			      bktr_name(bktr), stereo);
556279377Simp      DELAY(20000);
557279377Simp      stereo = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x0018);
558279377Simp      if (bootverbose)printf ("%s: Stereo reg 0x18 c: %d\n",
559279377Simp			      bktr_name(bktr), stereo);
560279377Simp      if (stereo > 0x0100 && stereo < 0x8000) { /* Seems to be stereo */
561279377Simp        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker set stereo*/
562279377Simp        /*
563279377Simp          set spatial effect strength to 50% enlargement
564279377Simp          set spatial effect mode b, stereo basewidth enlargement only
565279377Simp        */
566279377Simp        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f28);
567279377Simp      } else if (stereo > 0x8000) {    /* bilingual mode */
568279377Simp        if (bootverbose) printf ("%s: Bilingual mode detected\n",
569279377Simp				 bktr_name(bktr));
570279377Simp        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0000);/* Loudspeaker */
571279377Simp        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x0000);/* all spatial effects off */
572279377Simp       } else {                 /* must be mono */
573279377Simp        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0030);/* Loudspeaker */
574279377Simp        /*
575279377Simp          set spatial effect strength to 50% enlargement
576279377Simp          set spatial effect mode a, stereo basewidth enlargement
577279377Simp          and pseudo stereo effect with automatic high-pass filter
578279377Simp        */
579279377Simp        msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0005,0x3f08);
580279377Simp      }
581279377Simp#if 0
582279377Simp       /* The reset value for Channel matrix mode is FM/AM and SOUNDA/LEFT */
583279377Simp       /* We would like STEREO instead val: 0x0020 */
584279377Simp       msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0008,0x0020);/* Loudspeaker */
585279377Simp       msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0009,0x0020);/* Headphone */
586279377Simp       msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000a,0x0020);/* SCART1 */
587279377Simp       msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0041,0x0020);/* SCART2 */
588279377Simp       msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000b,0x0020);/* I2S */
589279377Simp       msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000c,0x0020);/* Quasi-Peak Detector Source */
590279377Simp       msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x000e,0x0001);
591279377Simp#endif
592279377Simp      break;
593279377Simp    case 8:                    /* B/G FM NICAM */
594279377Simp       msp_dpl_write(bktr, bktr->msp_addr, 0x10, 0x0021,0x0001);/* Auto selection of NICAM/MONO mode */
595279377Simp       break;
596279377Simp     case 9:                    /* L_AM NICAM or D/K*/
597279377Simp     case 10:                   /* i-FM NICAM */
598279377Simp       break;
599279377Simp     default:
600279377Simp       if (bootverbose) printf ("%s: Unknown autodetection result value: %d\n",
601279377Simp				bktr_name(bktr), auto_detect);
602279377Simp     }
603279377Simp
604279377Simp  }
605279377Simp
606279377Simp
607279377Simp  /* uncomment the following line to enable the MSP34xx 1Khz Tone Generator */
608279377Simp  /* turn your speaker volume down low before trying this */
609279377Simp  /* msp_dpl_write(bktr, bktr->msp_addr, 0x12, 0x0014, 0x7f40); */
610279377Simp
611279377Simp#endif /* BKTR_NEW_MSP34XX_DRIVER */
612279377Simp}
613279377Simp
614279377Simp/* Read the DPL version string */
615279377Simpvoid dpl_read_id( bktr_ptr_t bktr ){
616279377Simp    int rev1=0, rev2=0;
617279377Simp    rev1 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001e);
618279377Simp    rev2 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001f);
619279377Simp
620279377Simp    sprintf(bktr->dpl_version_string, "34%02d%c-%c%d",
621279377Simp      ((rev2>>8)&0xff)-1, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
622279377Simp}
623279377Simp
624279377Simp/* Configure the DPL chip to Auto-detect the audio format */
625279377Simpvoid dpl_autodetect( bktr_ptr_t bktr ) {
626279377Simp
627279377Simp    /* The following are empiric values tried from the DPL35xx data sheet */
628279377Simp    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x000c,0x0320);	/* quasi peak detector source dolby
629279377Simp								lr 0x03xx; quasi peak detector matrix
630279377Simp								stereo 0xXX20 */
631279377Simp    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0040,0x0060);	/* Surround decoder mode;
632279377Simp								ADAPTIVE/3D-PANORAMA, that means two
633279377Simp								speakers and no center speaker, all
634279377Simp								channels L/R/C/S mixed to L and R */
635279377Simp    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0041,0x0620);	/* surround source matrix;I2S2/STEREO*/
636279377Simp    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0042,0x1F00);	/* surround delay 31ms max */
637279377Simp    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0043,0x0000);	/* automatic surround input balance */
638279377Simp    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0044,0x4000);	/* surround spatial effect 50%
639279377Simp								recommended*/
640279377Simp    msp_dpl_write(bktr, bktr->dpl_addr, 0x12, 0x0045,0x5400);	/* surround panorama effect 66%
641279377Simp								recommended with PANORAMA mode
642279377Simp								in 0x0040 set to panorama */
643279377Simp}
644279377Simp
645279377Simp