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