GNU Linux-libre 4.9.317-gnu1
[releases.git] / Documentation / sound / oss / MultiSound
1 #! /bin/sh
2 #
3 #  Turtle Beach MultiSound Driver Notes
4 #  -- Andrew Veliath <andrewtv@usa.net>
5 #
6 #  Last update:                      September 10, 1998
7 #  Corresponding msnd driver:        0.8.3
8 #
9 # ** This file is a README (top part) and shell archive (bottom part).
10 #    The corresponding archived utility sources can be unpacked by
11 #    running `sh MultiSound' (the utilities are only needed for the
12 #    Pinnacle and Fiji cards). **
13 #
14 #
15 #  -=-=- Getting Firmware -=-=-
16 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 #  
18 #  See the section `Obtaining and Creating Firmware Files' in this
19 #  document for instructions on obtaining the necessary firmware
20 #  files.
21 #  
22 #  
23 #  Supported Features
24 #  ~~~~~~~~~~~~~~~~~~
25 #  
26 #  Currently, full-duplex digital audio (/dev/dsp only, /dev/audio is
27 #  not currently available) and mixer functionality (/dev/mixer) are
28 #  supported (memory mapped digital audio is not yet supported).
29 #  Digital transfers and monitoring can be done as well if you have
30 #  the digital daughterboard (see the section on using the S/PDIF port
31 #  for more information).
32 #
33 #  Support for the Turtle Beach MultiSound Hurricane architecture is
34 #  composed of the following modules (these can also operate compiled
35 #  into the kernel):
36 #  
37 #  msnd               - MultiSound base (requires soundcore)
38 #
39 #  msnd_classic       - Base audio/mixer support for Classic, Monetery and
40 #                       Tahiti cards
41 #
42 #  msnd_pinnacle      - Base audio/mixer support for Pinnacle and Fiji cards
43 #  
44 #  
45 # /*(DEBLOBBED)*/
46 #
47 #
48 #  *** PnP mode
49 #  
50 #  Use pnpdump to obtain a sample configuration if you can; I was able
51 #  to obtain one with the command `pnpdump 1 0x203' -- this may vary
52 #  for you (running pnpdump by itself did not work for me).  Then,
53 #  edit this file and use isapnp to uncomment and set the card values.
54 #  Use these values when inserting the msnd_pinnacle module.  Using
55 #  this method, you can set the resources for the DSP and the Kurzweil
56 #  synth (Pinnacle).  Since Linux does not directly support PnP
57 #  devices, you may have difficulty when using the card in PnP mode
58 #  when it the driver is compiled into the kernel.  Using non-PnP mode
59 #  is preferable in this case.
60 #
61 #  Here is an example mypinnacle.conf for isapnp that sets the card to
62 #  io base 0x210, irq 5 and mem 0xd8000, and also sets the Kurzweil
63 #  synth to 0x330 and irq 9 (may need editing for your system):
64 #
65 #  (READPORT 0x0203)
66 #  (CSN 2)
67 #  (IDENTIFY *)
68 #  
69 #  # DSP
70 #  (CONFIGURE BVJ0440/-1 (LD 0
71 #          (INT 0 (IRQ 5 (MODE +E))) (IO 0 (BASE 0x0210)) (MEM 0 (BASE 0x0d8000))
72 #          (ACT Y)))
73 #  
74 #  # Kurzweil Synth (Pinnacle Only)
75 #  (CONFIGURE BVJ0440/-1 (LD 1
76 #          (IO 0 (BASE 0x0330)) (INT 0 (IRQ 9 (MODE +E)))
77 #          (ACT Y)))
78 #  
79 #  (WAITFORKEY)
80 #
81 #
82 #  *** Non-PnP mode
83 #  
84 #  The second way is by running the card in non-PnP mode.  This
85 #  actually has some advantages in that you can access some other
86 #  devices on the card, such as the joystick and IDE controller.  To
87 #  configure the card, unpack this shell archive and build the
88 #  pinnaclecfg program.  Using this program, you can assign the
89 #  resource values to the card's devices, or disable the devices.  As
90 #  an alternative to using pinnaclecfg, you can specify many of the
91 #  configuration values when loading the msnd_pinnacle module (or
92 #  during kernel configuration when compiling the driver into the
93 #  kernel).
94 #
95 #  If you specify cfg=0x250 for the msnd_pinnacle module, it
96 #  automatically configure the card to the given io, irq and memory
97 #  values using that config port (the config port is jumper selectable
98 #  on the card to 0x250, 0x260 or 0x270).
99 #
100 #  See the `msnd_pinnacle Additional Options' section below for more
101 #  information on these parameters (also, if you compile the driver
102 #  directly into the kernel, these extra parameters can be useful
103 #  here).
104 #
105 #
106 # ** It is very easy to cause problems in your machine if you choose a
107 #    resource value which is incorrect. **
108 #  
109 #
110 #  Examples
111 #  ~~~~~~~~
112 #  
113 #  * MultiSound Classic/Monterey/Tahiti:
114 #  
115 #  modprobe soundcore
116 #  insmod msnd
117 #  insmod msnd_classic io=0x290 irq=7 mem=0xd0000
118 #  
119 #  * MultiSound Pinnacle in PnP mode:
120 #  
121 #  modprobe soundcore
122 #  insmod msnd
123 #  isapnp mypinnacle.conf
124 #  insmod msnd_pinnacle io=0x210 irq=5 mem=0xd8000 <-- match mypinnacle.conf values
125 #  
126 #  * MultiSound Pinnacle in non-PnP mode (replace 0x250 with your configuration port,
127 #    one of 0x250, 0x260 or 0x270):
128 #  
129 #  insmod soundcore
130 #  insmod msnd
131 #  insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000
132 #  
133 # * To use the MPU-compatible Kurzweil synth on the Pinnacle in PnP
134 #   mode, add the following (assumes you did `isapnp mypinnacle.conf'):
135 #  
136 #  insmod sound
137 #  insmod mpu401 io=0x330 irq=9                    <-- match mypinnacle.conf values
138 #  
139 # * To use the MPU-compatible Kurzweil synth on the Pinnacle in non-PnP
140 #   mode, add the following.  Note how we first configure the peripheral's
141 #   resources, _then_ install a Linux driver for it:
142 #  
143 #  insmod sound
144 #  pinnaclecfg 0x250 mpu 0x330 9
145 #  insmod mpu401 io=0x330 irq=9
146 #
147 #  -- OR you can use the following sequence without pinnaclecfg in non-PnP mode:
148 #
149 #  insmod soundcore
150 #  insmod msnd
151 #  insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 mpu_io=0x330 mpu_irq=9
152 #  insmod sound
153 #  insmod mpu401 io=0x330 irq=9
154 #
155 # * To setup the joystick port on the Pinnacle in non-PnP mode (though
156 #   you have to find the actual Linux joystick driver elsewhere), you
157 #   can use pinnaclecfg:
158 #
159 #   pinnaclecfg 0x250 joystick 0x200
160 #
161 #  -- OR you can configure this using msnd_pinnacle with the following:
162 #
163 #  insmod soundcore
164 #  insmod msnd
165 #  insmod msnd_pinnacle cfg=0x250 io=0x290 irq=5 mem=0xd0000 joystick_io=0x200
166 #
167 #  
168 #  msnd_classic, msnd_pinnacle Required Options
169 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
170 #  
171 #  If the following options are not given, the module will not load.
172 #  Examine the kernel message log for informative error messages.
173 #  WARNING--probing isn't supported so try to make sure you have the
174 #  correct shared memory area, otherwise you may experience problems.
175 #  
176 #  io                   I/O base of DSP, e.g. io=0x210
177 #  irq                  IRQ number, e.g. irq=5
178 #  mem                  Shared memory area, e.g. mem=0xd8000
179 #  
180 #  
181 #  msnd_classic, msnd_pinnacle Additional Options
182 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183 #  
184 #  fifosize             The digital audio FIFOs, in kilobytes.  If not
185 #                       specified, the default will be used.  Increasing
186 #                       this value will reduce the chance of a FIFO
187 #                       underflow at the expense of increasing overall
188 #                       latency.  For example, fifosize=512 will
189 #                       allocate 512kB read and write FIFOs (1MB total).
190 #                       While this may reduce dropouts, a heavy machine
191 #                       load will undoubtedly starve the FIFO of data
192 #                       and you will eventually get dropouts.  One
193 #                       option is to alter the scheduling priority of
194 #                       the playback process, using `nice' or some form
195 #                       of POSIX soft real-time scheduling.
196 #
197 #  calibrate_signal     Setting this to one calibrates the ADCs to the
198 #                       signal, zero calibrates to the card (defaults
199 #                       to zero).
200 #  
201 #  
202 #  msnd_pinnacle Additional Options
203 #  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204 #
205 #  digital              Specify digital=1 to enable the S/PDIF input
206 #                       if you have the digital daughterboard
207 #                       adapter. This will enable access to the
208 #                       DIGITAL1 input for the soundcard in the mixer.
209 #                       Some mixer programs might have trouble setting
210 #                       the DIGITAL1 source as an input.  If you have
211 #                       trouble, you can try the setdigital.c program
212 #                       at the bottom of this document.
213 #
214 #  cfg                  Non-PnP configuration port for the Pinnacle
215 #                       and Fiji (typically 0x250, 0x260 or 0x270,
216 #                       depending on the jumper configuration).  If
217 #                       this option is omitted, then it is assumed
218 #                       that the card is in PnP mode, and that the
219 #                       specified DSP resource values are already
220 #                       configured with PnP (i.e. it won't attempt to
221 #                       do any sort of configuration).
222 #
223 #  When the Pinnacle is in non-PnP mode, you can use the following
224 #  options to configure particular devices.  If a full specification
225 #  for a device is not given, then the device is not configured.  Note
226 #  that you still must use a Linux driver for any of these devices
227 #  once their resources are setup (such as the Linux joystick driver,
228 #  or the MPU401 driver from OSS for the Kurzweil synth).
229 #
230 #  mpu_io               I/O port of MPU (on-board Kurzweil synth)
231 #  mpu_irq              IRQ of MPU (on-board Kurzweil synth)
232 #  ide_io0              First I/O port of IDE controller
233 #  ide_io1              Second I/O port of IDE controller
234 #  ide_irq              IRQ IDE controller
235 #  joystick_io          I/O port of joystick
236 #  
237 #  
238 # /*(DEBLOBBED)*/
239 #
240 #
241 #  -- Shell archive attached below, just run `sh MultiSound' to extract.
242 #     Contains Pinnacle/Fiji utilities to convert firmware, configure
243 #     in non-PnP mode, and select the DIGITAL1 input for the mixer.
244 #
245 #
246 #!/bin/sh
247 # This is a shell archive (produced by GNU sharutils 4.2).
248 # To extract the files from this archive, save it to some FILE, remove
249 # everything before the `!/bin/sh' line above, then type `sh FILE'.
250 #
251 # Made on 1998-12-04 10:07 EST by <andrewtv@ztransform.velsoft.com>.
252 # Source directory was `/home/andrewtv/programming/pinnacle/pinnacle'.
253 #
254 # Existing files will *not* be overwritten unless `-c' is specified.
255 #
256 # This shar contains:
257 # length mode       name
258 # ------ ---------- ------------------------------------------
259 #   2046 -rw-rw-r-- MultiSound.d/setdigital.c
260 #  10235 -rw-rw-r-- MultiSound.d/pinnaclecfg.c
261 #    106 -rw-rw-r-- MultiSound.d/Makefile
262 #    141 -rw-rw-r-- MultiSound.d/conv.l
263 #   1472 -rw-rw-r-- MultiSound.d/msndreset.c
264 #
265 save_IFS="${IFS}"
266 IFS="${IFS}:"
267 gettext_dir=FAILED
268 locale_dir=FAILED
269 first_param="$1"
270 for dir in $PATH
271 do
272   if test "$gettext_dir" = FAILED && test -f $dir/gettext \
273      && ($dir/gettext --version >/dev/null 2>&1)
274   then
275     set `$dir/gettext --version 2>&1`
276     if test "$3" = GNU
277     then
278       gettext_dir=$dir
279     fi
280   fi
281   if test "$locale_dir" = FAILED && test -f $dir/shar \
282      && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
283   then
284     locale_dir=`$dir/shar --print-text-domain-dir`
285   fi
286 done
287 IFS="$save_IFS"
288 if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
289 then
290   echo=echo
291 else
292   TEXTDOMAINDIR=$locale_dir
293   export TEXTDOMAINDIR
294   TEXTDOMAIN=sharutils
295   export TEXTDOMAIN
296   echo="$gettext_dir/gettext -s"
297 fi
298 touch -am 1231235999 $$.touch >/dev/null 2>&1
299 if test ! -f 1231235999 && test -f $$.touch; then
300   shar_touch=touch
301 else
302   shar_touch=:
303   echo
304   $echo 'WARNING: not restoring timestamps.  Consider getting and'
305   $echo "installing GNU \`touch', distributed in GNU File Utilities..."
306   echo
307 fi
308 rm -f 1231235999 $$.touch
309 #
310 if mkdir _sh01426; then
311   $echo 'x -' 'creating lock directory'
312 else
313   $echo 'failed to create lock directory'
314   exit 1
315 fi
316 # ============= MultiSound.d/setdigital.c ==============
317 if test ! -d 'MultiSound.d'; then
318   $echo 'x -' 'creating directory' 'MultiSound.d'
319   mkdir 'MultiSound.d'
320 fi
321 if test -f 'MultiSound.d/setdigital.c' && test "$first_param" != -c; then
322   $echo 'x -' SKIPPING 'MultiSound.d/setdigital.c' '(file already exists)'
323 else
324   $echo 'x -' extracting 'MultiSound.d/setdigital.c' '(text)'
325   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/setdigital.c' &&
326 /*********************************************************************
327 X *
328 X * setdigital.c - sets the DIGITAL1 input for a mixer
329 X *
330 X * Copyright (C) 1998 Andrew Veliath
331 X *
332 X * This program is free software; you can redistribute it and/or modify
333 X * it under the terms of the GNU General Public License as published by
334 X * the Free Software Foundation; either version 2 of the License, or
335 X * (at your option) any later version.
336 X *
337 X * This program is distributed in the hope that it will be useful,
338 X * but WITHOUT ANY WARRANTY; without even the implied warranty of
339 X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
340 X * GNU General Public License for more details.
341 X *
342 X * You should have received a copy of the GNU General Public License
343 X * along with this program; if not, write to the Free Software
344 X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
345 X *
346 X ********************************************************************/
347 X
348 #include <stdio.h>
349 #include <unistd.h>
350 #include <fcntl.h>
351 #include <sys/types.h>
352 #include <sys/stat.h>
353 #include <sys/ioctl.h>
354 #include <sys/soundcard.h>
355 X
356 int main(int argc, char *argv[])
357 {
358 X       int fd;
359 X       unsigned long recmask, recsrc;
360 X
361 X       if (argc != 2) {
362 X               fprintf(stderr, "usage: setdigital <mixer device>\n");
363 X               exit(1);
364 X       }
365 X
366 X       if ((fd = open(argv[1], O_RDWR)) < 0) {
367 X               perror(argv[1]);
368 X               exit(1);
369 X       }
370 X
371 X       if (ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask) < 0) {
372 X               fprintf(stderr, "error: ioctl read recording mask failed\n");
373 X               perror("ioctl");
374 X               close(fd);
375 X               exit(1);
376 X       }
377 X
378 X       if (!(recmask & SOUND_MASK_DIGITAL1)) {
379 X               fprintf(stderr, "error: cannot find DIGITAL1 device in mixer\n");
380 X               close(fd);
381 X               exit(1);
382 X       }
383 X
384 X       if (ioctl(fd, SOUND_MIXER_READ_RECSRC, &recsrc) < 0) {
385 X               fprintf(stderr, "error: ioctl read recording source failed\n");
386 X               perror("ioctl");
387 X               close(fd);
388 X               exit(1);
389 X       }
390 X
391 X       recsrc |= SOUND_MASK_DIGITAL1;
392 X       
393 X       if (ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &recsrc) < 0) {
394 X               fprintf(stderr, "error: ioctl write recording source failed\n");
395 X               perror("ioctl");
396 X               close(fd);
397 X               exit(1);
398 X       }
399 X
400 X       close(fd);
401 X       
402 X       return 0;
403 }
404 SHAR_EOF
405   $shar_touch -am 1204092598 'MultiSound.d/setdigital.c' &&
406   chmod 0664 'MultiSound.d/setdigital.c' ||
407   $echo 'restore of' 'MultiSound.d/setdigital.c' 'failed'
408   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
409   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
410     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
411     || $echo 'MultiSound.d/setdigital.c:' 'MD5 check failed'
412 e87217fc3e71288102ba41fd81f71ec4  MultiSound.d/setdigital.c
413 SHAR_EOF
414   else
415     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/setdigital.c'`"
416     test 2046 -eq "$shar_count" ||
417     $echo 'MultiSound.d/setdigital.c:' 'original size' '2046,' 'current size' "$shar_count!"
418   fi
419 fi
420 # ============= MultiSound.d/pinnaclecfg.c ==============
421 if test -f 'MultiSound.d/pinnaclecfg.c' && test "$first_param" != -c; then
422   $echo 'x -' SKIPPING 'MultiSound.d/pinnaclecfg.c' '(file already exists)'
423 else
424   $echo 'x -' extracting 'MultiSound.d/pinnaclecfg.c' '(text)'
425   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/pinnaclecfg.c' &&
426 /*********************************************************************
427 X *
428 X * pinnaclecfg.c - Pinnacle/Fiji Device Configuration Program
429 X *
430 X * This is for NON-PnP mode only.  For PnP mode, use isapnptools.
431 X *
432 X * This is Linux-specific, and must be run with root permissions.
433 X *
434 X * Part of the Turtle Beach MultiSound Sound Card Driver for Linux
435 X *
436 X * Copyright (C) 1998 Andrew Veliath
437 X *
438 X * This program is free software; you can redistribute it and/or modify
439 X * it under the terms of the GNU General Public License as published by
440 X * the Free Software Foundation; either version 2 of the License, or
441 X * (at your option) any later version.
442 X *
443 X * This program is distributed in the hope that it will be useful,
444 X * but WITHOUT ANY WARRANTY; without even the implied warranty of
445 X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
446 X * GNU General Public License for more details.
447 X *
448 X * You should have received a copy of the GNU General Public License
449 X * along with this program; if not, write to the Free Software
450 X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
451 X *
452 X ********************************************************************/
453 X
454 #include <stdio.h>
455 #include <stdlib.h>
456 #include <string.h>
457 #include <errno.h>
458 #include <unistd.h>
459 #include <asm/io.h>
460 #include <asm/types.h>
461 X
462 #define IREG_LOGDEVICE          0x07
463 #define IREG_ACTIVATE           0x30
464 #define LD_ACTIVATE             0x01
465 #define LD_DISACTIVATE          0x00
466 #define IREG_EECONTROL          0x3F
467 #define IREG_MEMBASEHI          0x40
468 #define IREG_MEMBASELO          0x41
469 #define IREG_MEMCONTROL         0x42
470 #define IREG_MEMRANGEHI         0x43
471 #define IREG_MEMRANGELO         0x44
472 #define MEMTYPE_8BIT            0x00
473 #define MEMTYPE_16BIT           0x02
474 #define MEMTYPE_RANGE           0x00
475 #define MEMTYPE_HIADDR          0x01
476 #define IREG_IO0_BASEHI         0x60
477 #define IREG_IO0_BASELO         0x61
478 #define IREG_IO1_BASEHI         0x62
479 #define IREG_IO1_BASELO         0x63
480 #define IREG_IRQ_NUMBER         0x70
481 #define IREG_IRQ_TYPE           0x71
482 #define IRQTYPE_HIGH            0x02
483 #define IRQTYPE_LOW             0x00
484 #define IRQTYPE_LEVEL           0x01
485 #define IRQTYPE_EDGE            0x00
486 X
487 #define HIBYTE(w)               ((BYTE)(((WORD)(w) >> 8) & 0xFF))
488 #define LOBYTE(w)               ((BYTE)(w))
489 #define MAKEWORD(low,hi)        ((WORD)(((BYTE)(low))|(((WORD)((BYTE)(hi)))<<8)))
490 X
491 typedef __u8                    BYTE;
492 typedef __u16                   USHORT;
493 typedef __u16                   WORD;
494 X
495 static int config_port = -1;
496 X
497 static int msnd_write_cfg(int cfg, int reg, int value)
498 {
499 X       outb(reg, cfg);
500 X       outb(value, cfg + 1);
501 X       if (value != inb(cfg + 1)) {
502 X               fprintf(stderr, "error: msnd_write_cfg: I/O error\n");
503 X               return -EIO;
504 X       }
505 X       return 0;
506 }
507 X
508 static int msnd_read_cfg(int cfg, int reg)
509 {
510 X       outb(reg, cfg);
511 X       return inb(cfg + 1);
512 }
513 X
514 static int msnd_write_cfg_io0(int cfg, int num, WORD io)
515 {
516 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
517 X               return -EIO;
518 X       if (msnd_write_cfg(cfg, IREG_IO0_BASEHI, HIBYTE(io)))
519 X               return -EIO;
520 X       if (msnd_write_cfg(cfg, IREG_IO0_BASELO, LOBYTE(io)))
521 X               return -EIO;
522 X       return 0;
523 }
524 X
525 static int msnd_read_cfg_io0(int cfg, int num, WORD *io)
526 {
527 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
528 X               return -EIO;
529 X       
530 X       *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO0_BASELO),
531 X                      msnd_read_cfg(cfg, IREG_IO0_BASEHI));
532 X
533 X       return 0;
534 }
535 X
536 static int msnd_write_cfg_io1(int cfg, int num, WORD io)
537 {
538 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
539 X               return -EIO;
540 X       if (msnd_write_cfg(cfg, IREG_IO1_BASEHI, HIBYTE(io)))
541 X               return -EIO;
542 X       if (msnd_write_cfg(cfg, IREG_IO1_BASELO, LOBYTE(io)))
543 X               return -EIO;
544 X       return 0;
545 }
546 X
547 static int msnd_read_cfg_io1(int cfg, int num, WORD *io)
548 {
549 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
550 X               return -EIO;
551 X       
552 X       *io = MAKEWORD(msnd_read_cfg(cfg, IREG_IO1_BASELO),
553 X                      msnd_read_cfg(cfg, IREG_IO1_BASEHI));
554 X
555 X       return 0;
556 }
557 X
558 static int msnd_write_cfg_irq(int cfg, int num, WORD irq)
559 {
560 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
561 X               return -EIO;
562 X       if (msnd_write_cfg(cfg, IREG_IRQ_NUMBER, LOBYTE(irq)))
563 X               return -EIO;
564 X       if (msnd_write_cfg(cfg, IREG_IRQ_TYPE, IRQTYPE_EDGE))
565 X               return -EIO;
566 X       return 0;
567 }
568 X
569 static int msnd_read_cfg_irq(int cfg, int num, WORD *irq)
570 {
571 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
572 X               return -EIO;
573 X       
574 X       *irq = msnd_read_cfg(cfg, IREG_IRQ_NUMBER);
575 X
576 X       return 0;
577 }
578 X
579 static int msnd_write_cfg_mem(int cfg, int num, int mem)
580 {
581 X       WORD wmem;
582 X
583 X       mem >>= 8;
584 X       mem &= 0xfff;
585 X       wmem = (WORD)mem;
586 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
587 X               return -EIO;
588 X       if (msnd_write_cfg(cfg, IREG_MEMBASEHI, HIBYTE(wmem)))
589 X               return -EIO;
590 X       if (msnd_write_cfg(cfg, IREG_MEMBASELO, LOBYTE(wmem)))
591 X               return -EIO;
592 X       if (wmem && msnd_write_cfg(cfg, IREG_MEMCONTROL, (MEMTYPE_HIADDR | MEMTYPE_16BIT)))
593 X               return -EIO;
594 X       return 0;
595 }
596 X
597 static int msnd_read_cfg_mem(int cfg, int num, int *mem)
598 {
599 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
600 X               return -EIO;
601 X       
602 X       *mem = MAKEWORD(msnd_read_cfg(cfg, IREG_MEMBASELO),
603 X                       msnd_read_cfg(cfg, IREG_MEMBASEHI));
604 X       *mem <<= 8;
605 X
606 X       return 0;
607 }
608 X
609 static int msnd_activate_logical(int cfg, int num)
610 {
611 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
612 X               return -EIO;
613 X       if (msnd_write_cfg(cfg, IREG_ACTIVATE, LD_ACTIVATE))
614 X               return -EIO;
615 X       return 0;
616 }
617 X
618 static int msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem)
619 {
620 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
621 X               return -EIO;
622 X       if (msnd_write_cfg_io0(cfg, num, io0))
623 X               return -EIO;
624 X       if (msnd_write_cfg_io1(cfg, num, io1))
625 X               return -EIO;
626 X       if (msnd_write_cfg_irq(cfg, num, irq))
627 X               return -EIO;
628 X       if (msnd_write_cfg_mem(cfg, num, mem))
629 X               return -EIO;
630 X       if (msnd_activate_logical(cfg, num))
631 X               return -EIO;
632 X       return 0;
633 }
634 X
635 static int msnd_read_cfg_logical(int cfg, int num, WORD *io0, WORD *io1, WORD *irq, int *mem)
636 {
637 X       if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
638 X               return -EIO;
639 X       if (msnd_read_cfg_io0(cfg, num, io0))
640 X               return -EIO;
641 X       if (msnd_read_cfg_io1(cfg, num, io1))
642 X               return -EIO;
643 X       if (msnd_read_cfg_irq(cfg, num, irq))
644 X               return -EIO;
645 X       if (msnd_read_cfg_mem(cfg, num, mem))
646 X               return -EIO;
647 X       return 0;
648 }
649 X
650 static void usage(void)
651 {
652 X       fprintf(stderr,
653 X               "\n"
654 X               "pinnaclecfg 1.0\n"
655 X               "\n"
656 X               "usage: pinnaclecfg <config port> [device config]\n"
657 X               "\n"
658 X               "This is for use with the card in NON-PnP mode only.\n"
659 X               "\n"
660 X               "Available devices (not all available for Fiji):\n"
661 X               "\n"
662 X               "        Device                       Description\n"
663 X               "        -------------------------------------------------------------------\n"
664 X               "        reset                        Reset all devices (i.e. disable)\n"
665 X               "        show                         Display current device configurations\n"
666 X               "\n"
667 X               "        dsp <io> <irq> <mem>         Audio device\n"
668 X               "        mpu <io> <irq>               Internal Kurzweil synth\n"
669 X               "        ide <io0> <io1> <irq>        On-board IDE controller\n"
670 X               "        joystick <io>                Joystick port\n"
671 X               "\n");
672 X       exit(1);
673 }
674 X
675 static int cfg_reset(void)
676 {
677 X       int i;
678 X
679 X       for (i = 0; i < 4; ++i)
680 X               msnd_write_cfg_logical(config_port, i, 0, 0, 0, 0);
681 X       
682 X       return 0;
683 }
684 X
685 static int cfg_show(void)
686 {
687 X       int i;
688 X       int count = 0;
689 X
690 X       for (i = 0; i < 4; ++i) {
691 X               WORD io0, io1, irq;
692 X               int mem;
693 X               msnd_read_cfg_logical(config_port, i, &io0, &io1, &irq, &mem);
694 X               switch (i) {
695 X               case 0:
696 X                       if (io0 || irq || mem) {
697 X                               printf("dsp 0x%x %d 0x%x\n", io0, irq, mem);
698 X                               ++count;
699 X                       }
700 X                       break;
701 X               case 1:
702 X                       if (io0 || irq) {
703 X                               printf("mpu 0x%x %d\n", io0, irq);
704 X                               ++count;
705 X                       }
706 X                       break;
707 X               case 2:
708 X                       if (io0 || io1 || irq) {
709 X                               printf("ide 0x%x 0x%x %d\n", io0, io1, irq);
710 X                               ++count;
711 X                       }
712 X                       break;
713 X               case 3:
714 X                       if (io0) {
715 X                               printf("joystick 0x%x\n", io0);
716 X                               ++count;
717 X                       }
718 X                       break;
719 X               }
720 X       }
721 X
722 X       if (count == 0)
723 X               fprintf(stderr, "no devices configured\n");
724 X       
725 X       return 0;
726 }
727 X
728 static int cfg_dsp(int argc, char *argv[])
729 {
730 X       int io, irq, mem;
731 X
732 X       if (argc < 3 ||
733 X           sscanf(argv[0], "0x%x", &io) != 1 ||
734 X           sscanf(argv[1], "%d", &irq) != 1 ||
735 X           sscanf(argv[2], "0x%x", &mem) != 1)
736 X               usage();
737 X
738 X       if (!(io == 0x290 ||
739 X             io == 0x260 ||
740 X             io == 0x250 ||
741 X             io == 0x240 ||
742 X             io == 0x230 ||
743 X             io == 0x220 ||
744 X             io == 0x210 ||
745 X             io == 0x3e0)) {
746 X               fprintf(stderr, "error: io must be one of "
747 X                       "210, 220, 230, 240, 250, 260, 290, or 3E0\n");
748 X               usage();
749 X       }
750 X       
751 X       if (!(irq == 5 ||
752 X             irq == 7 ||
753 X             irq == 9 ||
754 X             irq == 10 ||
755 X             irq == 11 ||
756 X             irq == 12)) {
757 X               fprintf(stderr, "error: irq must be one of "
758 X                       "5, 7, 9, 10, 11 or 12\n");
759 X               usage();
760 X       }
761 X
762 X       if (!(mem == 0xb0000 ||
763 X             mem == 0xc8000 ||
764 X             mem == 0xd0000 ||
765 X             mem == 0xd8000 ||
766 X             mem == 0xe0000 ||
767 X             mem == 0xe8000)) {
768 X               fprintf(stderr, "error: mem must be one of "
769 X                       "0xb0000, 0xc8000, 0xd0000, 0xd8000, 0xe0000 or 0xe8000\n");
770 X               usage();
771 X       }
772 X
773 X       return msnd_write_cfg_logical(config_port, 0, io, 0, irq, mem);
774 }
775 X
776 static int cfg_mpu(int argc, char *argv[])
777 {
778 X       int io, irq;
779 X
780 X       if (argc < 2 ||
781 X           sscanf(argv[0], "0x%x", &io) != 1 ||
782 X           sscanf(argv[1], "%d", &irq) != 1)
783 X               usage();
784 X       
785 X       return msnd_write_cfg_logical(config_port, 1, io, 0, irq, 0);
786 }
787 X
788 static int cfg_ide(int argc, char *argv[])
789 {
790 X       int io0, io1, irq;
791 X
792 X       if (argc < 3 ||
793 X           sscanf(argv[0], "0x%x", &io0) != 1 ||
794 X           sscanf(argv[0], "0x%x", &io1) != 1 ||
795 X           sscanf(argv[1], "%d", &irq) != 1)
796 X               usage();
797 X       
798 X       return msnd_write_cfg_logical(config_port, 2, io0, io1, irq, 0);
799 }
800 X
801 static int cfg_joystick(int argc, char *argv[])
802 {
803 X       int io;
804 X
805 X       if (argc < 1 ||
806 X           sscanf(argv[0], "0x%x", &io) != 1)
807 X               usage();
808 X       
809 X       return msnd_write_cfg_logical(config_port, 3, io, 0, 0, 0);
810 }
811 X
812 int main(int argc, char *argv[])
813 {
814 X       char *device;
815 X       int rv = 0;
816 X
817 X       --argc; ++argv;
818 X
819 X       if (argc < 2)
820 X               usage();
821 X
822 X       sscanf(argv[0], "0x%x", &config_port);
823 X       if (config_port != 0x250 && config_port != 0x260 && config_port != 0x270) {
824 X               fprintf(stderr, "error: <config port> must be 0x250, 0x260 or 0x270\n");
825 X               exit(1);
826 X       }
827 X       if (ioperm(config_port, 2, 1)) {
828 X               perror("ioperm");
829 X               fprintf(stderr, "note: pinnaclecfg must be run as root\n");
830 X               exit(1);
831 X       }
832 X       device = argv[1];
833 X
834 X       argc -= 2; argv += 2;
835 X
836 X       if (strcmp(device, "reset") == 0)
837 X               rv = cfg_reset();
838 X       else if (strcmp(device, "show") == 0)
839 X               rv = cfg_show();
840 X       else if (strcmp(device, "dsp") == 0)
841 X               rv = cfg_dsp(argc, argv);
842 X       else if (strcmp(device, "mpu") == 0)
843 X               rv = cfg_mpu(argc, argv);
844 X       else if (strcmp(device, "ide") == 0)
845 X               rv = cfg_ide(argc, argv);
846 X       else if (strcmp(device, "joystick") == 0)
847 X               rv = cfg_joystick(argc, argv);
848 X       else {
849 X               fprintf(stderr, "error: unknown device %s\n", device);
850 X               usage();
851 X       }
852 X
853 X       if (rv)
854 X               fprintf(stderr, "error: device configuration failed\n");
855 X       
856 X       return 0;
857 }
858 SHAR_EOF
859   $shar_touch -am 1204092598 'MultiSound.d/pinnaclecfg.c' &&
860   chmod 0664 'MultiSound.d/pinnaclecfg.c' ||
861   $echo 'restore of' 'MultiSound.d/pinnaclecfg.c' 'failed'
862   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
863   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
864     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
865     || $echo 'MultiSound.d/pinnaclecfg.c:' 'MD5 check failed'
866 366bdf27f0db767a3c7921d0a6db20fe  MultiSound.d/pinnaclecfg.c
867 SHAR_EOF
868   else
869     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/pinnaclecfg.c'`"
870     test 10235 -eq "$shar_count" ||
871     $echo 'MultiSound.d/pinnaclecfg.c:' 'original size' '10235,' 'current size' "$shar_count!"
872   fi
873 fi
874 # ============= MultiSound.d/Makefile ==============
875 if test -f 'MultiSound.d/Makefile' && test "$first_param" != -c; then
876   $echo 'x -' SKIPPING 'MultiSound.d/Makefile' '(file already exists)'
877 else
878   $echo 'x -' extracting 'MultiSound.d/Makefile' '(text)'
879   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/Makefile' &&
880 CC      = gcc
881 CFLAGS  = -O
882 PROGS   = setdigital msndreset pinnaclecfg conv
883 X
884 all: $(PROGS)
885 X
886 clean:
887 X       rm -f $(PROGS)
888 SHAR_EOF
889   $shar_touch -am 1204092398 'MultiSound.d/Makefile' &&
890   chmod 0664 'MultiSound.d/Makefile' ||
891   $echo 'restore of' 'MultiSound.d/Makefile' 'failed'
892   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
893   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
894     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
895     || $echo 'MultiSound.d/Makefile:' 'MD5 check failed'
896 76ca8bb44e3882edcf79c97df6c81845  MultiSound.d/Makefile
897 SHAR_EOF
898   else
899     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/Makefile'`"
900     test 106 -eq "$shar_count" ||
901     $echo 'MultiSound.d/Makefile:' 'original size' '106,' 'current size' "$shar_count!"
902   fi
903 fi
904 # ============= MultiSound.d/conv.l ==============
905 if test -f 'MultiSound.d/conv.l' && test "$first_param" != -c; then
906   $echo 'x -' SKIPPING 'MultiSound.d/conv.l' '(file already exists)'
907 else
908   $echo 'x -' extracting 'MultiSound.d/conv.l' '(text)'
909   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/conv.l' &&
910 %%
911 [ \n\t,\r]
912 \;.*
913 DB
914 [0-9A-Fa-f]+H   { int n; sscanf(yytext, "%xH", &n); printf("%c", n); }
915 %%
916 int yywrap() { return 1; }
917 main() { yylex(); }
918 SHAR_EOF
919   $shar_touch -am 0828231798 'MultiSound.d/conv.l' &&
920   chmod 0664 'MultiSound.d/conv.l' ||
921   $echo 'restore of' 'MultiSound.d/conv.l' 'failed'
922   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
923   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
924     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
925     || $echo 'MultiSound.d/conv.l:' 'MD5 check failed'
926 d2411fc32cd71a00dcdc1f009e858dd2  MultiSound.d/conv.l
927 SHAR_EOF
928   else
929     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/conv.l'`"
930     test 141 -eq "$shar_count" ||
931     $echo 'MultiSound.d/conv.l:' 'original size' '141,' 'current size' "$shar_count!"
932   fi
933 fi
934 # ============= MultiSound.d/msndreset.c ==============
935 if test -f 'MultiSound.d/msndreset.c' && test "$first_param" != -c; then
936   $echo 'x -' SKIPPING 'MultiSound.d/msndreset.c' '(file already exists)'
937 else
938   $echo 'x -' extracting 'MultiSound.d/msndreset.c' '(text)'
939   sed 's/^X//' << 'SHAR_EOF' > 'MultiSound.d/msndreset.c' &&
940 /*********************************************************************
941 X *
942 X * msndreset.c - resets the MultiSound card
943 X *
944 X * Copyright (C) 1998 Andrew Veliath
945 X *
946 X * This program is free software; you can redistribute it and/or modify
947 X * it under the terms of the GNU General Public License as published by
948 X * the Free Software Foundation; either version 2 of the License, or
949 X * (at your option) any later version.
950 X *
951 X * This program is distributed in the hope that it will be useful,
952 X * but WITHOUT ANY WARRANTY; without even the implied warranty of
953 X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
954 X * GNU General Public License for more details.
955 X *
956 X * You should have received a copy of the GNU General Public License
957 X * along with this program; if not, write to the Free Software
958 X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
959 X *
960 X ********************************************************************/
961 X
962 #include <stdio.h>
963 #include <unistd.h>
964 #include <fcntl.h>
965 #include <sys/types.h>
966 #include <sys/stat.h>
967 #include <sys/ioctl.h>
968 #include <sys/soundcard.h>
969 X
970 int main(int argc, char *argv[])
971 {
972 X       int fd;
973 X
974 X       if (argc != 2) {
975 X               fprintf(stderr, "usage: msndreset <mixer device>\n");
976 X               exit(1);
977 X       }
978 X
979 X       if ((fd = open(argv[1], O_RDWR)) < 0) {
980 X               perror(argv[1]);
981 X               exit(1);
982 X       }
983 X
984 X       if (ioctl(fd, SOUND_MIXER_PRIVATE1, 0) < 0) {
985 X               fprintf(stderr, "error: msnd ioctl reset failed\n");
986 X               perror("ioctl");
987 X               close(fd);
988 X               exit(1);
989 X       }
990 X
991 X       close(fd);
992 X       
993 X       return 0;
994 }
995 SHAR_EOF
996   $shar_touch -am 1204100698 'MultiSound.d/msndreset.c' &&
997   chmod 0664 'MultiSound.d/msndreset.c' ||
998   $echo 'restore of' 'MultiSound.d/msndreset.c' 'failed'
999   if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
1000   && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
1001     md5sum -c << SHAR_EOF >/dev/null 2>&1 \
1002     || $echo 'MultiSound.d/msndreset.c:' 'MD5 check failed'
1003 c52f876521084e8eb25e12e01dcccb8a  MultiSound.d/msndreset.c
1004 SHAR_EOF
1005   else
1006     shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'MultiSound.d/msndreset.c'`"
1007     test 1472 -eq "$shar_count" ||
1008     $echo 'MultiSound.d/msndreset.c:' 'original size' '1472,' 'current size' "$shar_count!"
1009   fi
1010 fi
1011 rm -fr _sh01426
1012 exit 0